From 1fda3d02841994c6705588a3c9739c38aeaf97d0 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Sun, 30 May 2021 11:06:17 -0500 Subject: [PATCH 01/93] Document null support in NumberToLocalizedStringTransformer --- .../DataTransformer/MoneyToLocalizedStringTransformer.php | 4 ++-- .../DataTransformer/NumberToLocalizedStringTransformer.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php index ca341ac7120a0..18341b06775c1 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php @@ -45,7 +45,7 @@ public function __construct(?int $scale = 2, ?bool $grouping = true, ?int $round /** * Transforms a normalized format into a localized money string. * - * @param int|float $value Normalized number + * @param int|float|null $value Normalized number * * @return string Localized money string * @@ -69,7 +69,7 @@ public function transform($value) * * @param string $value Localized money string * - * @return int|float Normalized number + * @return int|float|null Normalized number * * @throws TransformationFailedException if the given value is not a string * or if the value can not be transformed diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php index 84ad6d18e1344..7cf46d17c3478 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php @@ -98,7 +98,7 @@ public function __construct(int $scale = null, ?bool $grouping = false, ?int $ro /** * Transforms a number type into localized number. * - * @param int|float $value Number value + * @param int|float|null $value Number value * * @return string Localized value * @@ -133,7 +133,7 @@ public function transform($value) * * @param string $value The localized value * - * @return int|float The numeric value + * @return int|float|null The numeric value * * @throws TransformationFailedException if the given value is not a string * or if the value can not be transformed From ca61cd64b126379ae278ab204545341b5ac546e2 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Jun 2021 11:02:47 +0200 Subject: [PATCH 02/93] Bump Symfony version to 4.4.26 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 82ee8b26b9716..819c60538fc41 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,12 +76,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - public const VERSION = '4.4.25'; - public const VERSION_ID = 40425; + public const VERSION = '4.4.26-DEV'; + public const VERSION_ID = 40426; public const MAJOR_VERSION = 4; public const MINOR_VERSION = 4; - public const RELEASE_VERSION = 25; - public const EXTRA_VERSION = ''; + public const RELEASE_VERSION = 26; + public const EXTRA_VERSION = 'DEV'; public const END_OF_MAINTENANCE = '11/2022'; public const END_OF_LIFE = '11/2023'; From 8954b4f92209a877efdeed706ba27febd8b5c905 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 1 Jun 2021 15:34:54 +0200 Subject: [PATCH 03/93] [HttpFoundation] Add ReturnTypeWillChange to SessionHandlers --- .../Storage/Handler/AbstractSessionHandler.php | 5 +++++ .../Session/Storage/Handler/StrictSessionHandler.php | 7 ++++++- .../Session/Storage/Proxy/SessionHandlerProxy.php | 12 ++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php index 42c3df54a2840..3ae8b9ea443de 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php @@ -31,6 +31,7 @@ abstract class AbstractSessionHandler implements \SessionHandlerInterface, \Sess /** * @return bool */ + #[\ReturnTypeWillChange] public function open($savePath, $sessionName) { $this->sessionName = $sessionName; @@ -66,6 +67,7 @@ abstract protected function doDestroy($sessionId); /** * @return bool */ + #[\ReturnTypeWillChange] public function validateId($sessionId) { $this->prefetchData = $this->read($sessionId); @@ -86,6 +88,7 @@ public function validateId($sessionId) /** * @return string */ + #[\ReturnTypeWillChange] public function read($sessionId) { if (null !== $this->prefetchId) { @@ -109,6 +112,7 @@ public function read($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function write($sessionId, $data) { if (null === $this->igbinaryEmptyData) { @@ -126,6 +130,7 @@ public function write($sessionId, $data) /** * @return bool */ + #[\ReturnTypeWillChange] public function destroy($sessionId) { if (!headers_sent() && filter_var(ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOLEAN)) { diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/StrictSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/StrictSessionHandler.php index 3144ea597ea6b..627bcfa1dfa84 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/StrictSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/StrictSessionHandler.php @@ -33,6 +33,7 @@ public function __construct(\SessionHandlerInterface $handler) /** * @return bool */ + #[\ReturnTypeWillChange] public function open($savePath, $sessionName) { parent::open($savePath, $sessionName); @@ -51,6 +52,7 @@ protected function doRead($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function updateTimestamp($sessionId, $data) { return $this->write($sessionId, $data); @@ -67,6 +69,7 @@ protected function doWrite($sessionId, $data) /** * @return bool */ + #[\ReturnTypeWillChange] public function destroy($sessionId) { $this->doDestroy = true; @@ -88,14 +91,16 @@ protected function doDestroy($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function close() { return $this->handler->close(); } /** - * @return bool + * @return int|false */ + #[\ReturnTypeWillChange] public function gc($maxlifetime) { return $this->handler->gc($maxlifetime); diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php index de4f550badbc5..5535bc96441db 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php @@ -38,6 +38,7 @@ public function getHandler() /** * @return bool */ + #[\ReturnTypeWillChange] public function open($savePath, $sessionName) { return (bool) $this->handler->open($savePath, $sessionName); @@ -46,6 +47,7 @@ public function open($savePath, $sessionName) /** * @return bool */ + #[\ReturnTypeWillChange] public function close() { return (bool) $this->handler->close(); @@ -54,6 +56,7 @@ public function close() /** * @return string */ + #[\ReturnTypeWillChange] public function read($sessionId) { return (string) $this->handler->read($sessionId); @@ -62,6 +65,7 @@ public function read($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function write($sessionId, $data) { return (bool) $this->handler->write($sessionId, $data); @@ -70,22 +74,25 @@ public function write($sessionId, $data) /** * @return bool */ + #[\ReturnTypeWillChange] public function destroy($sessionId) { return (bool) $this->handler->destroy($sessionId); } /** - * @return bool + * @return int|false */ + #[\ReturnTypeWillChange] public function gc($maxlifetime) { - return (bool) $this->handler->gc($maxlifetime); + return $this->handler->gc($maxlifetime); } /** * @return bool */ + #[\ReturnTypeWillChange] public function validateId($sessionId) { return !$this->handler instanceof \SessionUpdateTimestampHandlerInterface || $this->handler->validateId($sessionId); @@ -94,6 +101,7 @@ public function validateId($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function updateTimestamp($sessionId, $data) { return $this->handler instanceof \SessionUpdateTimestampHandlerInterface ? $this->handler->updateTimestamp($sessionId, $data) : $this->write($sessionId, $data); From 960cb520dfcb26b8409d0e2b0011dfb547852754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4dlich?= Date: Sun, 23 May 2021 17:28:21 +0200 Subject: [PATCH 04/93] [Console] Escape synopsis output --- src/Symfony/Component/Console/Application.php | 2 +- .../Component/Console/Tests/ApplicationTest.php | 17 +++++++++++++++++ .../Console/Tests/Command/CommandTest.php | 3 ++- .../application_rendersynopsis_escapesline.txt | 7 +++++++ 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Component/Console/Tests/Fixtures/application_rendersynopsis_escapesline.txt diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index e71a16d109035..ed6d00190ee83 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -833,7 +833,7 @@ public function renderThrowable(\Throwable $e, OutputInterface $output): void private function finishRenderThrowableOrException(OutputInterface $output): void { if (null !== $this->runningCommand) { - $output->writeln(sprintf('%s', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET); + $output->writeln(sprintf('%s', OutputFormatter::escape(sprintf($this->runningCommand->getSynopsis(), $this->getName()))), OutputInterface::VERBOSITY_QUIET); $output->writeln('', OutputInterface::VERBOSITY_QUIET); } } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index d293697d422c5..1634c01991b0a 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -940,6 +940,23 @@ public function testRenderExceptionStackTraceContainsRootException() $this->assertStringContainsString('Dummy type "class@anonymous" is invalid.', $tester->getDisplay(true)); } + public function testRenderExceptionEscapesLinesOfSynopsis() + { + $application = new Application(); + $application->setAutoExit(false); + $application + ->register('foo') + ->setCode(function () { + throw new \Exception('some exception'); + }) + ->addArgument('info') + ; + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false]); + $this->assertStringMatchesFormatFile(self::$fixturesPath.'/application_rendersynopsis_escapesline.txt', $tester->getDisplay(true), '->renderException() escapes lines containing formatting of synopsis'); + } + public function testRun() { $application = new Application(); diff --git a/src/Symfony/Component/Console/Tests/Command/CommandTest.php b/src/Symfony/Component/Console/Tests/Command/CommandTest.php index 10a476d192e31..7648b80ff0f08 100644 --- a/src/Symfony/Component/Console/Tests/Command/CommandTest.php +++ b/src/Symfony/Component/Console/Tests/Command/CommandTest.php @@ -192,7 +192,8 @@ public function testGetSynopsis() $command = new \TestCommand(); $command->addOption('foo'); $command->addArgument('bar'); - $this->assertEquals('namespace:name [--foo] [--] []', $command->getSynopsis(), '->getSynopsis() returns the synopsis'); + $command->addArgument('info'); + $this->assertEquals('namespace:name [--foo] [--] [ []]', $command->getSynopsis(), '->getSynopsis() returns the synopsis'); } public function testAddGetUsages() diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_rendersynopsis_escapesline.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_rendersynopsis_escapesline.txt new file mode 100644 index 0000000000000..a781326c621be --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/application_rendersynopsis_escapesline.txt @@ -0,0 +1,7 @@ + +In ApplicationTest.php line %d: + + some exception + + +foo [] From 21c0829a25410434f08fdb8f8ab40505dcaaa40f Mon Sep 17 00:00:00 2001 From: Oleg Zhulnev Date: Tue, 1 Jun 2021 14:01:19 +0300 Subject: [PATCH 05/93] [Serializer] Do not allow to denormalize string with spaces only to valid a DateTime object --- .../Serializer/Normalizer/DateTimeNormalizer.php | 2 +- .../Tests/Normalizer/DateTimeNormalizerTest.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index 8bdfc977efd5d..f48745031e8b7 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -97,7 +97,7 @@ public function denormalize($data, $type, $format = null, array $context = []) $dateTimeFormat = $context[self::FORMAT_KEY] ?? null; $timezone = $this->getTimezone($context); - if ('' === $data || null === $data) { + if (null === $data || (\is_string($data) && '' === trim($data))) { throw new NotNormalizableValueException('The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.'); } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php index 576d5eb03f105..51fc17d85afea 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php @@ -201,6 +201,7 @@ public function testDenormalize() $this->assertEquals(new \DateTimeImmutable('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeInterface::class)); $this->assertEquals(new \DateTimeImmutable('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeImmutable::class)); $this->assertEquals(new \DateTime('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTime::class)); + $this->assertEquals(new \DateTime('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize(' 2016-01-01T00:00:00+00:00 ', \DateTime::class)); } public function testDenormalizeUsingTimezonePassedInConstructor() @@ -290,6 +291,20 @@ public function testDenormalizeEmptyStringThrowsException() $this->normalizer->denormalize('', \DateTimeInterface::class); } + public function testDenormalizeStringWithSpacesOnlyThrowsAnException() + { + $this->expectException(UnexpectedValueException::class); + $this->expectExceptionMessage('The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.'); + $this->normalizer->denormalize(' ', \DateTimeInterface::class); + } + + public function testDenormalizeDateTimeStringWithSpacesUsingFormatPassedInContextThrowsAnException() + { + $this->expectException(UnexpectedValueException::class); + $this->expectExceptionMessage("Parsing datetime string \" 2016.01.01 \" using format \"Y.m.d|\" resulted in 2 errors: \nat position 0: Unexpected data found.\nat position 12: Trailing data"); + $this->normalizer->denormalize(' 2016.01.01 ', \DateTime::class, null, [DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|']); + } + public function testDenormalizeFormatMismatchThrowsException() { $this->expectException(UnexpectedValueException::class); From b10b6951a64c29aa2e109805ca12f4de9b7ad11f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 5 Jun 2021 00:24:11 +0200 Subject: [PATCH 06/93] Fix opcache preload with alias classes --- .../Core/Authorization/TraceableAccessDecisionManager.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php b/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php index 7a9c4d0cfb23a..3b5004edf2fcd 100644 --- a/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php +++ b/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php @@ -107,4 +107,6 @@ public function getDecisionLog(): array } } -class_alias(TraceableAccessDecisionManager::class, DebugAccessDecisionManager::class); +if (!class_exists(DebugAccessDecisionManager::class, false)) { + class_alias(TraceableAccessDecisionManager::class, DebugAccessDecisionManager::class); +} From 0bce1f6de1581eae94fdf1f8f43b22adbc1daccd Mon Sep 17 00:00:00 2001 From: HypeMC Date: Thu, 3 Jun 2021 22:06:42 +0200 Subject: [PATCH 07/93] Add missing security translations --- .../Security/Core/Resources/translations/security.hr.xlf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.hr.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.hr.xlf index e193dcb500032..d46be51682e36 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.hr.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.hr.xlf @@ -70,6 +70,14 @@ Invalid or expired login link. Link za prijavu je isteako ili je neispravan. + + Too many failed login attempts, please try again in %minutes% minute. + Previše neuspjelih pokušaja prijave, molim pokušajte ponovo za %minutes% minutu. + + + Too many failed login attempts, please try again in %minutes% minutes. + Previše neuspjelih pokušaja prijave, molim pokušajte ponovo za %minutes% minutu.|Previše neuspjelih pokušaja prijave, molim pokušajte ponovo za %minutes% minute.|Previše neuspjelih pokušaja prijave, molim pokušajte ponovo za %minutes% minuta. + From 48e76fafc6acd3aa62396c8b979cd9f935706563 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 5 Jun 2021 18:29:25 +0200 Subject: [PATCH 08/93] Fix Serializable deprecations triggered by token mocks --- src/Symfony/Bridge/Twig/Tests/AppVariableTest.php | 2 +- .../Bridge/Twig/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../FrameworkBundle/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../Tests/Templating/GlobalVariablesTest.php | 2 +- .../SecurityBundle/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../Tests/Functional/EventAliasTest.php | 2 +- .../Tests/SecurityUserValueResolverTest.php | 2 +- .../AuthenticationProviderManagerTest.php | 2 +- .../AuthenticationTrustResolverTest.php | 2 +- .../Provider/AnonymousAuthenticationProviderTest.php | 2 +- .../PreAuthenticatedAuthenticationProviderTest.php | 2 +- .../Provider/RememberMeAuthenticationProviderTest.php | 2 +- .../Provider/SimpleAuthenticationProviderTest.php | 2 +- .../Provider/UserAuthenticationProviderTest.php | 2 +- .../Token/Storage/UsageTrackingTokenStorageTest.php | 2 +- .../Tests/Authorization/AccessDecisionManagerTest.php | 2 +- .../TraceableAccessDecisionManagerTest.php | 2 +- .../Authorization/Voter/AuthenticatedVoterTest.php | 2 +- .../Tests/Authorization/Voter/ExpressionVoterTest.php | 2 +- .../Core/Tests/Authorization/Voter/RoleVoterTest.php | 2 +- .../Tests/Authorization/Voter/TraceableVoterTest.php | 2 +- .../Core/Tests/Authorization/Voter/VoterTest.php | 3 ++- .../Security/Core/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../Security/Core/Tests/Role/SwitchUserRoleTest.php | 2 +- .../Component/Security/Core/Tests/SecurityTest.php | 2 +- .../Constraints/UserPasswordValidatorTest.php | 2 +- .../Firewall/GuardAuthenticationListenerTest.php | 2 +- .../Guard/Tests/Fixtures/GuardTokenInterface.php | 11 +++++++++++ .../Security/Guard/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../Guard/Tests/GuardAuthenticatorHandlerTest.php | 2 +- .../Provider/GuardAuthenticationProviderTest.php | 2 +- .../DefaultAuthenticationSuccessHandlerTest.php | 2 +- .../SimpleAuthenticationHandlerTest.php | 2 +- .../Firewall/AbstractPreAuthenticatedListenerTest.php | 2 +- .../Http/Tests/Firewall/AccessListenerTest.php | 2 +- .../Firewall/AnonymousAuthenticationListenerTest.php | 2 +- .../Firewall/BasicAuthenticationListenerTest.php | 2 +- .../Http/Tests/Firewall/ExceptionListenerTest.php | 2 +- .../Http/Tests/Firewall/LogoutListenerTest.php | 2 +- .../Http/Tests/Firewall/RememberMeListenerTest.php | 2 +- .../Firewall/SimplePreAuthenticationListenerTest.php | 2 +- ...UsernamePasswordJsonAuthenticationListenerTest.php | 3 ++- .../Security/Http/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../Tests/Logout/CookieClearingLogoutHandlerTest.php | 2 +- .../Logout/CsrfTokenClearingLogoutHandlerTest.php | 2 +- .../Http/Tests/Logout/SessionLogoutHandlerTest.php | 2 +- .../RememberMe/AbstractRememberMeServicesTest.php | 2 +- .../PersistentTokenBasedRememberMeServicesTest.php | 2 +- .../RememberMe/TokenBasedRememberMeServicesTest.php | 2 +- .../Session/SessionAuthenticationStrategyTest.php | 2 +- 50 files changed, 122 insertions(+), 43 deletions(-) create mode 100644 src/Symfony/Bridge/Twig/Tests/Fixtures/TokenInterface.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TokenInterface.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/TokenInterface.php create mode 100644 src/Symfony/Component/Security/Core/Tests/Fixtures/TokenInterface.php create mode 100644 src/Symfony/Component/Security/Guard/Tests/Fixtures/GuardTokenInterface.php create mode 100644 src/Symfony/Component/Security/Guard/Tests/Fixtures/TokenInterface.php create mode 100644 src/Symfony/Component/Security/Http/Tests/Fixtures/TokenInterface.php diff --git a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php index f5fcbeada6562..58c3cfde4beab 100644 --- a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php +++ b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php @@ -4,12 +4,12 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Twig\AppVariable; +use Symfony\Bridge\Twig\Tests\Fixtures\TokenInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\User\UserInterface; class AppVariableTest extends TestCase diff --git a/src/Symfony/Bridge/Twig/Tests/Fixtures/TokenInterface.php b/src/Symfony/Bridge/Twig/Tests/Fixtures/TokenInterface.php new file mode 100644 index 0000000000000..b22e99e66d22b --- /dev/null +++ b/src/Symfony/Bridge/Twig/Tests/Fixtures/TokenInterface.php @@ -0,0 +1,11 @@ +token = $this->createMock(TokenInterface::class); + $this->token = $this->createMock(StrictTokenInterface::class); } public function getTests() diff --git a/src/Symfony/Component/Security/Core/Tests/Fixtures/TokenInterface.php b/src/Symfony/Component/Security/Core/Tests/Fixtures/TokenInterface.php new file mode 100644 index 0000000000000..32a83deeb6800 --- /dev/null +++ b/src/Symfony/Component/Security/Core/Tests/Fixtures/TokenInterface.php @@ -0,0 +1,11 @@ + @@ -50,7 +51,7 @@ private function createListener(array $options = [], $success = true, $matchChec ; $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticatedToken = $this->createMock(TokenInterface::class); + $authenticatedToken = $this->createMock(StrictTokenInterface::class); if ($success) { $authenticationManager->method('authenticate')->willReturn($authenticatedToken); diff --git a/src/Symfony/Component/Security/Http/Tests/Fixtures/TokenInterface.php b/src/Symfony/Component/Security/Http/Tests/Fixtures/TokenInterface.php new file mode 100644 index 0000000000000..254381cb23203 --- /dev/null +++ b/src/Symfony/Component/Security/Http/Tests/Fixtures/TokenInterface.php @@ -0,0 +1,11 @@ + Date: Sat, 5 Jun 2021 22:21:26 +0200 Subject: [PATCH 09/93] Add return types to JsonSerializable implementations --- .../HttpFoundation/Tests/JsonResponseTest.php | 13 ++++--------- .../Tests/Fixtures/JsonSerializableDummy.php | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php index 664f577b1765c..9cd63da728f84 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -224,9 +224,6 @@ public function testSetContentJsonSerializeError() { $this->expectException(\Exception::class); $this->expectExceptionMessage('This error is expected'); - if (!interface_exists(\JsonSerializable::class, false)) { - $this->markTestSkipped('JsonSerializable is required.'); - } $serializable = new JsonSerializableObject(); @@ -280,12 +277,10 @@ public function testConstructorWithObjectWithoutToStringMethodThrowsAnException( } } -if (interface_exists(\JsonSerializable::class, false)) { - class JsonSerializableObject implements \JsonSerializable +class JsonSerializableObject implements \JsonSerializable +{ + public function jsonSerialize(): array { - public function jsonSerialize() - { - throw new \Exception('This error is expected'); - } + throw new \Exception('This error is expected'); } } diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/JsonSerializableDummy.php b/src/Symfony/Component/Serializer/Tests/Fixtures/JsonSerializableDummy.php index 958200fdc74e7..ed4fd7e5e7b9b 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/JsonSerializableDummy.php +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/JsonSerializableDummy.php @@ -13,7 +13,7 @@ class JsonSerializableDummy implements \JsonSerializable { - public function jsonSerialize() + public function jsonSerialize(): array { return [ 'foo' => 'a', From e14dd67e85e455d34ea5373ea01835068efe370f Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 00:53:17 +0200 Subject: [PATCH 10/93] [DependencyInjection] Don't pass null to trim() --- .../Component/DependencyInjection/Dumper/PhpDumper.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index ea11778a640e9..c38d3eb3d5ffa 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -2147,7 +2147,9 @@ private function getClasses(Definition $definition): array $classes = []; while ($definition instanceof Definition) { - $classes[] = trim($definition->getClass(), '\\'); + if ($class = $definition->getClass()) { + $classes[] = trim($class, '\\'); + } $factory = $definition->getFactory(); if (!\is_array($factory)) { From 40992f001bb65e8ff759d6702c56c2f418ca44f8 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 6 Jun 2021 10:41:27 +0200 Subject: [PATCH 11/93] cs fix --- src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index c38d3eb3d5ffa..711b631d54590 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -2166,6 +2166,6 @@ private function getClasses(Definition $definition): array $definition = $factory[0]; } - return array_filter($classes); + return $classes; } } From 3c8cf9a3d4f525954692ca49e05d96e4706e10ad Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 10:50:48 +0200 Subject: [PATCH 12/93] [Translation] Don't pass null to strtoupper() Signed-off-by: Alexander M. Turek --- src/Symfony/Component/Translation/Loader/XliffFileLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php index a949e59ce4030..35e2d9c10c181 100644 --- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php @@ -76,7 +76,7 @@ private function extract($resource, MessageCatalogue $catalogue, string $domain) private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain) { $xml = simplexml_import_dom($dom); - $encoding = strtoupper($dom->encoding); + $encoding = $dom->encoding ? strtoupper($dom->encoding) : null; $namespace = 'urn:oasis:names:tc:xliff:document:1.2'; $xml->registerXPathNamespace('xliff', $namespace); From fc7447681cff7e5bcad42d3b349db34626c7910c Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 5 Jun 2021 22:03:01 +0200 Subject: [PATCH 13/93] Fix incompatible implicit float-to-int conversions Signed-off-by: Alexander M. Turek --- .../Component/Console/Helper/ProgressBar.php | 4 ++-- .../Component/Console/Helper/Table.php | 2 +- .../Console/Tests/Helper/ProgressBarTest.php | 2 +- .../Lock/Tests/Store/PdoStoreTest.php | 2 +- .../Command/Descriptor/CliDescriptor.php | 2 +- .../Command/Descriptor/HtmlDescriptor.php | 2 +- .../Component/Yaml/Tests/InlineTest.php | 20 +++++++++---------- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Symfony/Component/Console/Helper/ProgressBar.php b/src/Symfony/Component/Console/Helper/ProgressBar.php index 5049c7dae0636..1de9b7b3cfe92 100644 --- a/src/Symfony/Component/Console/Helper/ProgressBar.php +++ b/src/Symfony/Component/Console/Helper/ProgressBar.php @@ -193,7 +193,7 @@ public function getProgressPercent(): float public function getBarOffset(): int { - return floor($this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? min(5, $this->barWidth / 15) * $this->writeCount : $this->step) % $this->barWidth); + return floor($this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? (int) (min(5, $this->barWidth / 15) * $this->writeCount) : $this->step) % $this->barWidth); } public function setBarWidth(int $size) @@ -249,7 +249,7 @@ public function setFormat(string $format) /** * Sets the redraw frequency. * - * @param int|float $freq The frequency in steps + * @param int|null $freq The frequency in steps */ public function setRedrawFrequency(?int $freq) { diff --git a/src/Symfony/Component/Console/Helper/Table.php b/src/Symfony/Component/Console/Helper/Table.php index 329f240827a11..d51aee98908b3 100644 --- a/src/Symfony/Component/Console/Helper/Table.php +++ b/src/Symfony/Component/Console/Helper/Table.php @@ -454,7 +454,7 @@ private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $tit $formattedTitle = sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3).'...'); } - $titleStart = ($markupLength - $titleLength) / 2; + $titleStart = intdiv($markupLength - $titleLength, 2); if (false === mb_detect_encoding($markup, null, true)) { $markup = substr_replace($markup, $formattedTitle, $titleStart, $titleLength); } else { diff --git a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php index 2d32e1c3d512a..9fdaa570d3100 100644 --- a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php @@ -535,7 +535,7 @@ public function testRedrawFrequencyIsAtLeastOneIfZeroGiven() public function testRedrawFrequencyIsAtLeastOneIfSmallerOneGiven() { $bar = new ProgressBar($output = $this->getOutputStream(), 0, 0); - $bar->setRedrawFrequency(0.9); + $bar->setRedrawFrequency(0); $bar->start(); $bar->advance(); diff --git a/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php index 2d7cf1035ebc2..082f50aa75e63 100644 --- a/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php @@ -72,7 +72,7 @@ public function testInvalidTtlConstruct() { $this->expectException(InvalidTtlException::class); - return new PdoStore('sqlite:'.self::$dbFile, [], 0.1, 0.1); + return new PdoStore('sqlite:'.self::$dbFile, [], 0.1, 0); } /** diff --git a/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php b/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php index dc77d03ecd80c..7d9ec0e7ee614 100644 --- a/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php +++ b/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php @@ -42,7 +42,7 @@ public function describe(OutputInterface $output, Data $data, array $context, in $io = $output instanceof SymfonyStyle ? $output : new SymfonyStyle(new ArrayInput([]), $output); $this->dumper->setColors($output->isDecorated()); - $rows = [['date', date('r', $context['timestamp'])]]; + $rows = [['date', date('r', (int) $context['timestamp'])]]; $lastIdentifier = $this->lastIdentifier; $this->lastIdentifier = $clientId; diff --git a/src/Symfony/Component/VarDumper/Command/Descriptor/HtmlDescriptor.php b/src/Symfony/Component/VarDumper/Command/Descriptor/HtmlDescriptor.php index 35a203b0000a5..636b61828d140 100644 --- a/src/Symfony/Component/VarDumper/Command/Descriptor/HtmlDescriptor.php +++ b/src/Symfony/Component/VarDumper/Command/Descriptor/HtmlDescriptor.php @@ -94,7 +94,7 @@ public function describe(OutputInterface $output, Data $data, array $context, in private function extractDate(array $context, string $format = 'r'): string { - return date($format, $context['timestamp']); + return date($format, (int) $context['timestamp']); } private function renderTags(array $tags): string diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index b1f0206d547db..b4b8520642628 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -523,7 +523,7 @@ public function getTestsForDump() /** * @dataProvider getTimestampTests */ - public function testParseTimestampAsUnixTimestampByDefault($yaml, $year, $month, $day, $hour, $minute, $second) + public function testParseTimestampAsUnixTimestampByDefault(string $yaml, int $year, int $month, int $day, int $hour, int $minute, int $second) { $this->assertSame(gmmktime($hour, $minute, $second, $month, $day, $year), Inline::parse($yaml)); } @@ -531,37 +531,37 @@ public function testParseTimestampAsUnixTimestampByDefault($yaml, $year, $month, /** * @dataProvider getTimestampTests */ - public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second, $timezone) + public function testParseTimestampAsDateTimeObject(string $yaml, int $year, int $month, int $day, int $hour, int $minute, int $second, int $microsecond, string $timezone) { $expected = new \DateTime($yaml); $expected->setTimeZone(new \DateTimeZone('UTC')); $expected->setDate($year, $month, $day); - $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); + $expected->setTime($hour, $minute, $second, $microsecond); $date = Inline::parse($yaml, Yaml::PARSE_DATETIME); $this->assertEquals($expected, $date); $this->assertSame($timezone, $date->format('O')); } - public function getTimestampTests() + public function getTimestampTests(): array { return [ - 'canonical' => ['2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43.1, '+0000'], - 'ISO-8601' => ['2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43.1, '-0500'], - 'spaced' => ['2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43.1, '-0500'], - 'date' => ['2001-12-15', 2001, 12, 15, 0, 0, 0, '+0000'], + 'canonical' => ['2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43, 100000, '+0000'], + 'ISO-8601' => ['2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43, 100000, '-0500'], + 'spaced' => ['2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43, 100000, '-0500'], + 'date' => ['2001-12-15', 2001, 12, 15, 0, 0, 0, 0, '+0000'], ]; } /** * @dataProvider getTimestampTests */ - public function testParseNestedTimestampListAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second) + public function testParseNestedTimestampListAsDateTimeObject(string $yaml, int $year, int $month, int $day, int $hour, int $minute, int $second, int $microsecond) { $expected = new \DateTime($yaml); $expected->setTimeZone(new \DateTimeZone('UTC')); $expected->setDate($year, $month, $day); - $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); + $expected->setTime($hour, $minute, $second, $microsecond); $expectedNested = ['nested' => [$expected]]; $yamlNested = "{nested: [$yaml]}"; From 5af6edae62dbbd5885c62059c2b864e54e97af47 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 14:37:28 +0200 Subject: [PATCH 14/93] [FrameworkBundle][WebProfilerBundle] Don't pass null to string parameters Signed-off-by: Alexander M. Turek --- .../FrameworkBundle/Console/Descriptor/XmlDescriptor.php | 4 ++-- .../FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php | 6 ++++-- .../EventListener/WebDebugToolbarListener.php | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php index b11674a31b113..e0ea8233f16ea 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php @@ -285,7 +285,7 @@ private function getContainerDefinitionDocument(Definition $definition, string $ $descriptionXML->appendChild($dom->createCDATASection($classDescription)); } - $serviceXML->setAttribute('class', $definition->getClass()); + $serviceXML->setAttribute('class', $definition->getClass() ?? ''); if ($factory = $definition->getFactory()) { $serviceXML->appendChild($factoryXML = $dom->createElement('factory')); @@ -311,7 +311,7 @@ private function getContainerDefinitionDocument(Definition $definition, string $ $serviceXML->setAttribute('abstract', $definition->isAbstract() ? 'true' : 'false'); $serviceXML->setAttribute('autowired', $definition->isAutowired() ? 'true' : 'false'); $serviceXML->setAttribute('autoconfigured', $definition->isAutoconfigured() ? 'true' : 'false'); - $serviceXML->setAttribute('file', $definition->getFile()); + $serviceXML->setAttribute('file', $definition->getFile() ?? ''); $calls = $definition->getMethodCalls(); if (\count($calls) > 0) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php index b2a84ed536863..6eb02fa11a8d9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php @@ -76,8 +76,10 @@ public function __wakeup() public function __destruct() { - $fs = new Filesystem(); - $fs->remove($this->cacheDir); + if ($this->cacheDir) { + $fs = new Filesystem(); + $fs->remove($this->cacheDir); + } } protected function configureRoutes(RouteCollectionBuilder $routes) diff --git a/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php b/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php index 7f41db3052f40..a681f5d2427a6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php +++ b/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php @@ -103,7 +103,7 @@ public function onKernelResponse(FilterResponseEvent $event) || $response->isRedirection() || ($response->headers->has('Content-Type') && false === strpos($response->headers->get('Content-Type'), 'html')) || 'html' !== $request->getRequestFormat() - || false !== stripos($response->headers->get('Content-Disposition'), 'attachment;') + || false !== stripos($response->headers->get('Content-Disposition', ''), 'attachment;') ) { return; } From 8fbf3bb3c7903be23afa0482e0b46f387390aaa3 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 14:53:30 +0200 Subject: [PATCH 15/93] [Security] Fix SerializableUser fixture Signed-off-by: Alexander M. Turek --- .../Authentication/Token/AbstractTokenTest.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php index b1e7993de70ae..fccc7768ffb28 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php @@ -322,12 +322,22 @@ public function getSalt() public function serialize(): string { - return serialize($this->name); + return serialize($this->__serialize()); } public function unserialize($serialized): void { - $this->name = unserialize($serialized); + $this->__unserialize(unserialize($serialized)); + } + + public function __serialize(): array + { + return ['name' => $this->name]; + } + + public function __unserialize(array $data): void + { + ['name' => $this->name] = $data; } } From a245efb6045aaf9368ef5522d2791572ecf24e33 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 6 Jun 2021 16:23:08 +0200 Subject: [PATCH 16/93] [travis] fix travis hopefuly --- .travis.yml | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1b9678a7b6388..d7752d038ac29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: php -dist: xenial +dist: bionic git: depth: 2 @@ -11,6 +11,9 @@ addons: - language-pack-fr-base - zookeeperd - libzookeeper-mt-dev + - librabbitmq-dev + - libsodium-dev + - libtidy-dev env: global: @@ -36,15 +39,6 @@ cache: - ~/php-ext before_install: - - | - # Enable Sury ppa - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6B05F25D762E3157 - sudo add-apt-repository -y ppa:ondrej/php - sudo rm /etc/apt/sources.list.d/google-chrome.list - sudo rm /etc/apt/sources.list.d/mongodb-3.4.list - sudo apt update - sudo apt install -y librabbitmq-dev libsodium-dev - - | # General configuration set -e @@ -123,8 +117,13 @@ before_install: - | # php.ini configuration + ( + for PHP in $TRAVIS_PHP_VERSION $php_extra; do + phpenv global $PHP 2>/dev/null || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & + done + wait + ) for PHP in $TRAVIS_PHP_VERSION $php_extra; do - phpenv global $PHP 2>/dev/null || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/16.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini echo date.timezone = Europe/Paris >> $INI echo memory_limit = -1 >> $INI @@ -132,34 +131,30 @@ before_install: echo session.gc_probability = 0 >> $INI echo opcache.enable_cli = 1 >> $INI echo apc.enable_cli = 1 >> $INI - if [[ $PHP != 8.* ]]; then - echo extension = memcached.so >> $INI - fi done find ~/.phpenv -name xdebug.ini -delete + composer self-update + composer self-update --2 + - | # Install extra PHP extensions for PHP in $TRAVIS_PHP_VERSION $php_extra; do export PHP=$PHP phpenv global $PHP - composer self-update - composer self-update --2 INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini if ! php --ri sodium > /dev/null; then tfold ext.libsodium tpecl libsodium sodium.so $INI fi - if [[ $PHP = 8.* ]]; then - tfold ext.memcached tpecl memcached-3.1.5 memcached.so $INI - else + if [[ $PHP != 8.* ]]; then tfold ext.zookeeper tpecl zookeeper-0.7.2 zookeeper.so $INI - tfold ext.amqp tpecl amqp-1.10.2 amqp.so $INI fi - - tfold ext.mongodb tpecl mongodb-1.9.0 mongodb.so $INI + tfold ext.memcached tpecl memcached-3.1.5 memcached.so $INI + tfold ext.amqp tpecl amqp-1.11.0beta amqp.so $INI tfold ext.apcu tpecl apcu-5.1.19 apcu.so $INI tfold ext.igbinary tpecl igbinary-3.1.6 igbinary.so $INI tfold ext.redis tpecl redis-5.2.3 redis.so $INI "no" + tfold ext.mongodb tpecl mongodb-1.9.1 mongodb.so $INI done install: From 7341e29f2f87c8932baea93895e5ded4c482bf49 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Jun 2021 11:04:09 +0200 Subject: [PATCH 17/93] Fix tests (bis) --- src/Symfony/Component/HttpClient/composer.json | 1 + .../Tests/File/MimeType/MimeTypeTest.php | 3 ++- .../Mime/Tests/FileBinaryMimeTypeGuesserTest.php | 5 +++++ .../HttpClient/Test/Fixtures/web/index.php | 5 +++-- .../HttpClient/Test/HttpClientTestCase.php | 14 +++++++++----- .../Contracts/HttpClient/Test/TestHttpServer.php | 5 +++-- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index a6209060a5548..6c45b6dee3032 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -33,6 +33,7 @@ "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", "symfony/dependency-injection": "^4.3|^5.0", + "symfony/http-client-contracts": "^1.1.11|~2.1.4|~2.2.1|~2.3.2|^2.4.1", "symfony/http-kernel": "^4.4.13", "symfony/process": "^4.2|^5.0" }, diff --git a/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php b/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php index bbc74e74a6975..42d5c436cdc84 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php @@ -65,7 +65,8 @@ public function testGuessFileWithUnknownExtension() public function testGuessWithDuplicatedFileType() { - $this->assertSame('application/vnd.openxmlformats-officedocument.wordprocessingml.document', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.docx')); + $type = MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.docx'); + $this->assertTrue(\in_array($type, ['application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip'], true)); } public function testGuessWithIncorrectPath() diff --git a/src/Symfony/Component/Mime/Tests/FileBinaryMimeTypeGuesserTest.php b/src/Symfony/Component/Mime/Tests/FileBinaryMimeTypeGuesserTest.php index 0742732895e52..5d225038d4336 100644 --- a/src/Symfony/Component/Mime/Tests/FileBinaryMimeTypeGuesserTest.php +++ b/src/Symfony/Component/Mime/Tests/FileBinaryMimeTypeGuesserTest.php @@ -20,4 +20,9 @@ protected function getGuesser(): MimeTypeGuesserInterface { return new FileBinaryMimeTypeGuesser(); } + + public function testGuessWithDuplicatedFileType() + { + $this->markTestSkipped('Result varies depending on the OS'); + } } diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index 30a7049758d0d..a5cf236a35cfd 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -30,6 +30,7 @@ } $json = json_encode($vars, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); +$localhost = gethostbyname('localhost'); switch ($vars['REQUEST_URI']) { default: @@ -41,7 +42,7 @@ case '/': case '/?a=a&b=b': - case 'http://127.0.0.1:8057/': + case "http://$localhost:8057/": case 'http://localhost:8057/': ob_start('ob_gzhandler'); break; @@ -74,7 +75,7 @@ case '/301': if ('Basic Zm9vOmJhcg==' === $vars['HTTP_AUTHORIZATION']) { - header('Location: http://127.0.0.1:8057/302', true, 301); + header("Location: http://$localhost:8057/302", true, 301); } break; diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index f3e75c9337c2c..af19e387f8a75 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -335,6 +335,7 @@ public function test304() public function testRedirects() { $client = $this->getHttpClient(__FUNCTION__); + $localhost = gethostbyname('localhost'); $response = $client->request('POST', 'http://localhost:8057/301', [ 'auth_basic' => 'foo:bar', 'body' => function () { @@ -352,7 +353,7 @@ public function testRedirects() $expected = [ 'HTTP/1.1 301 Moved Permanently', - 'Location: http://127.0.0.1:8057/302', + "Location: http://$localhost:8057/302", 'Content-Type: application/json', 'HTTP/1.1 302 Found', 'Location: http://localhost:8057/', @@ -425,6 +426,7 @@ public function testRedirect307() public function testMaxRedirects() { $client = $this->getHttpClient(__FUNCTION__); + $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://localhost:8057/301', [ 'max_redirects' => 1, 'auth_basic' => 'foo:bar', @@ -442,7 +444,7 @@ public function testMaxRedirects() $expected = [ 'HTTP/1.1 301 Moved Permanently', - 'Location: http://127.0.0.1:8057/302', + "Location: http://$localhost:8057/302", 'Content-Type: application/json', 'HTTP/1.1 302 Found', 'Location: http://localhost:8057/', @@ -691,8 +693,9 @@ public function testOnProgressError() public function testResolve() { $client = $this->getHttpClient(__FUNCTION__); + $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://symfony.com:8057/', [ - 'resolve' => ['symfony.com' => '127.0.0.1'], + 'resolve' => ['symfony.com' => $localhost], ]); $this->assertSame(200, $response->getStatusCode()); @@ -706,15 +709,16 @@ public function testResolve() public function testIdnResolve() { $client = $this->getHttpClient(__FUNCTION__); + $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://0-------------------------------------------------------------0.com:8057/', [ - 'resolve' => ['0-------------------------------------------------------------0.com' => '127.0.0.1'], + 'resolve' => ['0-------------------------------------------------------------0.com' => $localhost], ]); $this->assertSame(200, $response->getStatusCode()); $response = $client->request('GET', 'http://Bücher.example:8057/', [ - 'resolve' => ['xn--bcher-kva.example' => '127.0.0.1'], + 'resolve' => ['xn--bcher-kva.example' => $localhost], ]); $this->assertSame(200, $response->getStatusCode()); diff --git a/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php b/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php index 06a11444e35e4..a521a96683a2e 100644 --- a/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php +++ b/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php @@ -31,15 +31,16 @@ public static function start(int $port = 8057) }); } + $localhost = gethostbyname('localhost'); $finder = new PhpExecutableFinder(); - $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', '127.0.0.1:'.$port])); + $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', "$localhost:$port"])); $process->setWorkingDirectory(__DIR__.'/Fixtures/web'); $process->start(); self::$process[$port] = $process; do { usleep(50000); - } while (!@fopen('http://127.0.0.1:'.$port, 'r')); + } while (!@fopen("http://$localhost:$port", 'r')); return $process; } From a71fb4b8f2fc78670cc1af8bd4f7f286ad470262 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Jun 2021 15:37:24 +0200 Subject: [PATCH 18/93] fix tests (ter) --- .github/workflows/tests.yml | 18 +++++++++--------- .../HttpClient/Tests/CurlHttpClientTest.php | 11 +++++++---- src/Symfony/Component/HttpClient/composer.json | 3 +-- .../HttpClient/Test/HttpClientTestCase.php | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3f5e8ef78fbc7..1e5bffaca5171 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - php: ['7.1', '7.4'] + php: ['7.1', '8.0'] services: ldap: @@ -106,14 +106,14 @@ jobs: LDAP_HOST: localhost LDAP_PORT: 3389 - - name: Run HTTP push tests - if: matrix.php == '7.4' - run: | - [ -d .phpunit ] && mv .phpunit .phpunit.bak - wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/vulcain_0.1.3_Linux_x86_64.tar.gz -O - | tar xz && mv vulcain /usr/local/bin - docker run --rm -e COMPOSER_ROOT_VERSION -v $(pwd):/app -v $(which composer):/usr/local/bin/composer -v /usr/local/bin/vulcain:/usr/local/bin/vulcain -w /app php:7.4-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push - sudo rm -rf .phpunit - [ -d .phpunit.bak ] && mv .phpunit.bak .phpunit + #- name: Run HTTP push tests + # if: matrix.php == '8.0' + # run: | + # [ -d .phpunit ] && mv .phpunit .phpunit.bak + # wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/vulcain_0.1.3_Linux_x86_64.tar.gz -O - | tar xz && mv vulcain /usr/local/bin + # docker run --rm -e COMPOSER_ROOT_VERSION -v $(pwd):/app -v $(which composer):/usr/local/bin/composer -v $(which vulcain):/usr/local/bin/vulcain -w /app php:8.0-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push + # sudo rm -rf .phpunit + # [ -d .phpunit.bak ] && mv .phpunit.bak .phpunit nightly: name: PHPUnit on PHP nightly diff --git a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php index 269705a3f4b9b..8875f60628a0d 100644 --- a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php @@ -38,7 +38,8 @@ protected function getHttpClient(string $testCase): HttpClientInterface public function testBindToPort() { $client = $this->getHttpClient(__FUNCTION__); - $response = $client->request('GET', 'http://localhost:8057', ['bindto' => '127.0.0.1:9876']); + $localhost = gethostbyname('localhost'); + $response = $client->request('GET', "http://$localhost:8057", ['bindto' => "$localhost:9876"]); $response->getStatusCode(); $r = new \ReflectionProperty($response, 'handle'); @@ -46,7 +47,7 @@ public function testBindToPort() $curlInfo = curl_getinfo($r->getValue($response)); - self::assertSame('127.0.0.1', $curlInfo['local_ip']); + self::assertSame($localhost, $curlInfo['local_ip']); self::assertSame(9876, $curlInfo['local_port']); } @@ -152,13 +153,15 @@ private function getVulcainClient(): CurlHttpClient return $client; } - if (['application/json'] !== $client->request('GET', 'http://127.0.0.1:8057/json')->getHeaders()['content-type']) { + $localhost = gethostbyname('localhost'); + + if (['application/json'] !== $client->request('GET', "http://$localhost:8057/json")->getHeaders()['content-type']) { $this->markTestSkipped('symfony/http-client-contracts >= 2.0.1 required'); } $process = new Process(['vulcain'], null, [ 'DEBUG' => 1, - 'UPSTREAM' => 'http://127.0.0.1:8057', + 'UPSTREAM' => "http://$localhost:8057", 'ADDR' => ':3000', 'KEY_FILE' => __DIR__.'/Fixtures/tls/server.key', 'CERT_FILE' => __DIR__.'/Fixtures/tls/server.crt', diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index 6c45b6dee3032..0e4af20f44da8 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -23,7 +23,7 @@ "require": { "php": ">=7.1.3", "psr/log": "^1.0", - "symfony/http-client-contracts": "^1.1.10|^2", + "symfony/http-client-contracts": "^1.1.11|~2.1.4|~2.2.1|~2.3.2|^2.4.1", "symfony/polyfill-php73": "^1.11", "symfony/service-contracts": "^1.0|^2" }, @@ -33,7 +33,6 @@ "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", "symfony/dependency-injection": "^4.3|^5.0", - "symfony/http-client-contracts": "^1.1.11|~2.1.4|~2.2.1|~2.3.2|^2.4.1", "symfony/http-kernel": "^4.4.13", "symfony/process": "^4.2|^5.0" }, diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index af19e387f8a75..77329af8c8ced 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -860,7 +860,7 @@ public function testProxy() $body = $response->toArray(); $this->assertSame('localhost:8057', $body['HTTP_HOST']); - $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.0\.1):8057/$#', $body['REQUEST_URI']); + $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.\d+\.1):8057/$#', $body['REQUEST_URI']); $response = $client->request('GET', 'http://localhost:8057/', [ 'proxy' => 'http://foo:b%3Dar@localhost:8057', From 65e96dd13f65ce13ab485dc758d1e3779f66de3c Mon Sep 17 00:00:00 2001 From: Kien Nguyen Date: Mon, 7 Jun 2021 22:03:43 +0700 Subject: [PATCH 19/93] Add missing translations for Swedish --- .../Security/Core/Resources/translations/security.sv.xlf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.sv.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.sv.xlf index a2bbf44e3ea0d..6d7b248499bb3 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.sv.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.sv.xlf @@ -70,6 +70,14 @@ Invalid or expired login link. Ogiltig eller utgången inloggningslänk. + + Too many failed login attempts, please try again in %minutes% minute. + För många misslyckade inloggningsförsök, försök igen om %minutes% minut. + + + Too many failed login attempts, please try again in %minutes% minutes. + För många misslyckade inloggningsförsök, försök igen om %minutes% minuter. + From a1f376b276b7276611c59b81ed3e2b82899773ca Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Jun 2021 17:05:04 +0200 Subject: [PATCH 20/93] bump ext-mongodb --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d7752d038ac29..311b10c7c82de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -154,7 +154,7 @@ before_install: tfold ext.apcu tpecl apcu-5.1.19 apcu.so $INI tfold ext.igbinary tpecl igbinary-3.1.6 igbinary.so $INI tfold ext.redis tpecl redis-5.2.3 redis.so $INI "no" - tfold ext.mongodb tpecl mongodb-1.9.1 mongodb.so $INI + tfold ext.mongodb tpecl mongodb-1.10.0alpha1 mongodb.so $INI done install: From d3249baa06230558fc2e5b690b71b18955d88c7b Mon Sep 17 00:00:00 2001 From: Kien Nguyen Date: Mon, 7 Jun 2021 21:45:36 +0700 Subject: [PATCH 21/93] Add missing translations for Thai --- .../Security/Core/Resources/translations/security.th.xlf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf index 2b2f1e068ba76..658fcbf99eae4 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf @@ -70,6 +70,14 @@ Invalid or expired login link. ลิงค์เข้าสู่ระบบไม่ถูกต้องหรือหมดอายุไปแล้ว + + Too many failed login attempts, please try again in %minutes% minute. + มีความพยายามเข้าสู่ระบบล้มเหลวมากเกินไป โปรดลองอีกครั้งใน %minutes% นาที + + + Too many failed login attempts, please try again in %minutes% minutes. + มีความพยายามเข้าสู่ระบบล้มเหลวมากเกินไป โปรดลองอีกครั้งใน %minutes% นาที + From e705a66a7f9363e5cc106c9d171a44ffac661b63 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Jun 2021 17:35:37 +0200 Subject: [PATCH 22/93] fix tests (quater) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 311b10c7c82de..044f209268474 100644 --- a/.travis.yml +++ b/.travis.yml @@ -119,7 +119,7 @@ before_install: # php.ini configuration ( for PHP in $TRAVIS_PHP_VERSION $php_extra; do - phpenv global $PHP 2>/dev/null || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & + (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & done wait ) From a70b537fbc5331616434b43fef5341e315499fe7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Jun 2021 20:50:09 +0200 Subject: [PATCH 23/93] fix tests (quinter) --- .travis.yml | 1 + .../HttpClient/Tests/CurlHttpClientTest.php | 11 ++++------- src/Symfony/Component/HttpClient/composer.json | 2 +- .../HttpClient/Test/Fixtures/web/index.php | 5 ++--- .../HttpClient/Test/HttpClientTestCase.php | 16 ++++++---------- .../Contracts/HttpClient/Test/TestHttpServer.php | 5 ++--- 6 files changed, 16 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index 044f209268474..738f4fc2b3a73 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,7 @@ before_install: # General configuration set -e stty cols 120 + sudo sed -i 's/127\.0\.1\.1 localhost/127.0.0.1 localhost/' /etc/hosts cp .github/composer-config.json "$(composer config home)/config.json" git config --global user.email "" git config --global user.name "Symfony" diff --git a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php index 8875f60628a0d..269705a3f4b9b 100644 --- a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php @@ -38,8 +38,7 @@ protected function getHttpClient(string $testCase): HttpClientInterface public function testBindToPort() { $client = $this->getHttpClient(__FUNCTION__); - $localhost = gethostbyname('localhost'); - $response = $client->request('GET', "http://$localhost:8057", ['bindto' => "$localhost:9876"]); + $response = $client->request('GET', 'http://localhost:8057', ['bindto' => '127.0.0.1:9876']); $response->getStatusCode(); $r = new \ReflectionProperty($response, 'handle'); @@ -47,7 +46,7 @@ public function testBindToPort() $curlInfo = curl_getinfo($r->getValue($response)); - self::assertSame($localhost, $curlInfo['local_ip']); + self::assertSame('127.0.0.1', $curlInfo['local_ip']); self::assertSame(9876, $curlInfo['local_port']); } @@ -153,15 +152,13 @@ private function getVulcainClient(): CurlHttpClient return $client; } - $localhost = gethostbyname('localhost'); - - if (['application/json'] !== $client->request('GET', "http://$localhost:8057/json")->getHeaders()['content-type']) { + if (['application/json'] !== $client->request('GET', 'http://127.0.0.1:8057/json')->getHeaders()['content-type']) { $this->markTestSkipped('symfony/http-client-contracts >= 2.0.1 required'); } $process = new Process(['vulcain'], null, [ 'DEBUG' => 1, - 'UPSTREAM' => "http://$localhost:8057", + 'UPSTREAM' => 'http://127.0.0.1:8057', 'ADDR' => ':3000', 'KEY_FILE' => __DIR__.'/Fixtures/tls/server.key', 'CERT_FILE' => __DIR__.'/Fixtures/tls/server.crt', diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index 0e4af20f44da8..a6209060a5548 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -23,7 +23,7 @@ "require": { "php": ">=7.1.3", "psr/log": "^1.0", - "symfony/http-client-contracts": "^1.1.11|~2.1.4|~2.2.1|~2.3.2|^2.4.1", + "symfony/http-client-contracts": "^1.1.10|^2", "symfony/polyfill-php73": "^1.11", "symfony/service-contracts": "^1.0|^2" }, diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index a5cf236a35cfd..30a7049758d0d 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -30,7 +30,6 @@ } $json = json_encode($vars, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); -$localhost = gethostbyname('localhost'); switch ($vars['REQUEST_URI']) { default: @@ -42,7 +41,7 @@ case '/': case '/?a=a&b=b': - case "http://$localhost:8057/": + case 'http://127.0.0.1:8057/': case 'http://localhost:8057/': ob_start('ob_gzhandler'); break; @@ -75,7 +74,7 @@ case '/301': if ('Basic Zm9vOmJhcg==' === $vars['HTTP_AUTHORIZATION']) { - header("Location: http://$localhost:8057/302", true, 301); + header('Location: http://127.0.0.1:8057/302', true, 301); } break; diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index 77329af8c8ced..f3e75c9337c2c 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -335,7 +335,6 @@ public function test304() public function testRedirects() { $client = $this->getHttpClient(__FUNCTION__); - $localhost = gethostbyname('localhost'); $response = $client->request('POST', 'http://localhost:8057/301', [ 'auth_basic' => 'foo:bar', 'body' => function () { @@ -353,7 +352,7 @@ public function testRedirects() $expected = [ 'HTTP/1.1 301 Moved Permanently', - "Location: http://$localhost:8057/302", + 'Location: http://127.0.0.1:8057/302', 'Content-Type: application/json', 'HTTP/1.1 302 Found', 'Location: http://localhost:8057/', @@ -426,7 +425,6 @@ public function testRedirect307() public function testMaxRedirects() { $client = $this->getHttpClient(__FUNCTION__); - $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://localhost:8057/301', [ 'max_redirects' => 1, 'auth_basic' => 'foo:bar', @@ -444,7 +442,7 @@ public function testMaxRedirects() $expected = [ 'HTTP/1.1 301 Moved Permanently', - "Location: http://$localhost:8057/302", + 'Location: http://127.0.0.1:8057/302', 'Content-Type: application/json', 'HTTP/1.1 302 Found', 'Location: http://localhost:8057/', @@ -693,9 +691,8 @@ public function testOnProgressError() public function testResolve() { $client = $this->getHttpClient(__FUNCTION__); - $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://symfony.com:8057/', [ - 'resolve' => ['symfony.com' => $localhost], + 'resolve' => ['symfony.com' => '127.0.0.1'], ]); $this->assertSame(200, $response->getStatusCode()); @@ -709,16 +706,15 @@ public function testResolve() public function testIdnResolve() { $client = $this->getHttpClient(__FUNCTION__); - $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://0-------------------------------------------------------------0.com:8057/', [ - 'resolve' => ['0-------------------------------------------------------------0.com' => $localhost], + 'resolve' => ['0-------------------------------------------------------------0.com' => '127.0.0.1'], ]); $this->assertSame(200, $response->getStatusCode()); $response = $client->request('GET', 'http://Bücher.example:8057/', [ - 'resolve' => ['xn--bcher-kva.example' => $localhost], + 'resolve' => ['xn--bcher-kva.example' => '127.0.0.1'], ]); $this->assertSame(200, $response->getStatusCode()); @@ -860,7 +856,7 @@ public function testProxy() $body = $response->toArray(); $this->assertSame('localhost:8057', $body['HTTP_HOST']); - $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.\d+\.1):8057/$#', $body['REQUEST_URI']); + $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.0\.1):8057/$#', $body['REQUEST_URI']); $response = $client->request('GET', 'http://localhost:8057/', [ 'proxy' => 'http://foo:b%3Dar@localhost:8057', diff --git a/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php b/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php index a521a96683a2e..06a11444e35e4 100644 --- a/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php +++ b/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php @@ -31,16 +31,15 @@ public static function start(int $port = 8057) }); } - $localhost = gethostbyname('localhost'); $finder = new PhpExecutableFinder(); - $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', "$localhost:$port"])); + $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', '127.0.0.1:'.$port])); $process->setWorkingDirectory(__DIR__.'/Fixtures/web'); $process->start(); self::$process[$port] = $process; do { usleep(50000); - } while (!@fopen("http://$localhost:$port", 'r')); + } while (!@fopen('http://127.0.0.1:'.$port, 'r')); return $process; } From 32cac1c6f2e541c89b3bebe16d25b3309dc152e6 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Jun 2021 21:46:40 +0200 Subject: [PATCH 24/93] Remove duplicate catch block --- .../Tests/Functional/CachePoolsTest.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php index e6f6bbb3158d8..fc5d64f4d2fed 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php @@ -39,11 +39,6 @@ public function testRedisCachePools() throw $e; } $this->markTestSkipped($e->getMessage()); - } catch (\PHPUnit\Framework\Error\Warning $e) { - if (0 !== strpos($e->getMessage(), 'unable to connect to')) { - throw $e; - } - $this->markTestSkipped($e->getMessage()); } catch (InvalidArgumentException $e) { if (0 !== strpos($e->getMessage(), 'Redis connection ')) { throw $e; @@ -67,11 +62,6 @@ public function testRedisCustomCachePools() throw $e; } $this->markTestSkipped($e->getMessage()); - } catch (\PHPUnit\Framework\Error\Warning $e) { - if (0 !== strpos($e->getMessage(), 'unable to connect to')) { - throw $e; - } - $this->markTestSkipped($e->getMessage()); } } From bc383215a38798f2de140df7f6685cb54f2c6097 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Mon, 7 Jun 2021 18:31:40 +0200 Subject: [PATCH 25/93] [MonologBridge] Fix the server:log help --filter sample --- src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php | 5 ++--- .../Bundle/WebServerBundle/Command/ServerLogCommand.php | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php b/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php index f2ad907d76978..977be786e5b71 100644 --- a/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php +++ b/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php @@ -67,10 +67,9 @@ protected function configure() php %command.full_name% -To get the information as a machine readable format, use the ---filter option: +To filter the log messages using any ExpressionLanguage compatible expression, use the --filter option: -php %command.full_name% --filter=port +php %command.full_name% --filter="level > 200 or channel in ['app', 'doctrine']" EOF ) ; diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php index b21368a4f99df..586f0747f30ac 100644 --- a/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php +++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php @@ -69,10 +69,9 @@ protected function configure() php %command.full_name% -To get the information as a machine readable format, use the ---filter option: +To filter the log messages using any ExpressionLanguage compatible expression, use the --filter option: -php %command.full_name% --filter=port +php %command.full_name% --filter="level > 200 or channel in ['app', 'doctrine']" EOF ) ; From a5be1968278dc956dd9e9d8775fc34bdc97202bf Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Tue, 8 Jun 2021 09:24:10 +0200 Subject: [PATCH 26/93] [DependencyInjection] Fix testServiceSubscriber for PHP 8.1 --- .../Tests/Dumper/PhpDumperTest.php | 6 +- .../php/services_subscriber_php81.php | 111 ++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index f088bcf3c36f0..b46fbf937b910 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -950,7 +950,11 @@ public function process(ContainerBuilder $container) $dumper = new PhpDumper($container); - $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_subscriber.php', $dumper->dump()); + if (80100 <= \PHP_VERSION_ID) { + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_subscriber_php81.php', $dumper->dump()); + } else { + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_subscriber.php', $dumper->dump()); + } } public function testPrivateWithIgnoreOnInvalidReference() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php new file mode 100644 index 0000000000000..e897fa53a8e31 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php @@ -0,0 +1,111 @@ +getService = \Closure::fromCallable([$this, 'getService']); + $this->services = $this->privates = []; + $this->methodMap = [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'getTestServiceSubscriberService', + 'foo_service' => 'getFooServiceService', + 'late_alias' => 'getLateAliasService', + ]; + $this->aliases = [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestDefinition1' => 'late_alias', + ]; + } + + public function compile(): void + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled(): bool + { + return true; + } + + public function getRemovedIds(): array + { + return [ + '.service_locator.Txga9_U' => true, + '.service_locator.Txga9_U.foo_service' => true, + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true, + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestDefinition1' => true, + 'late_alias' => true, + ]; + } + + /** + * Gets the public 'Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber + */ + protected function getTestServiceSubscriberService() + { + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber(); + } + + /** + * Gets the public 'foo_service' shared autowired service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber + */ + protected function getFooServiceService() + { + return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber((new \Symfony\Component\DependencyInjection\Argument\ServiceLocator($this->getService, [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => ['privates', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', 'getCustomDefinitionService', false], + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', false], + 'bar' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', false], + 'baz' => ['privates', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', 'getCustomDefinitionService', false], + 'late_alias' => ['services', 'late_alias', 'getLateAliasService', false], + ], [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', + 'bar' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', + 'baz' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', + 'late_alias' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestDefinition1', + ]))->withContext('foo_service', $this)); + } + + /** + * Gets the public 'late_alias' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1 + */ + protected function getLateAliasService() + { + return $this->services['late_alias'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1(); + } + + /** + * Gets the private 'Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition + */ + protected function getCustomDefinitionService() + { + return $this->privates['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition(); + } +} From 117cb8f085d7736a61cfd6cc43e64842056e3d8e Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Tue, 8 Jun 2021 13:19:15 +0200 Subject: [PATCH 27/93] [DependencyInjection] Fix CSV file mime type guess test for PHP 8.1 --- src/Symfony/Component/Mime/Tests/MimeTypesTest.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Mime/Tests/MimeTypesTest.php b/src/Symfony/Component/Mime/Tests/MimeTypesTest.php index 9b16ff6807046..50d99ae5159a7 100644 --- a/src/Symfony/Component/Mime/Tests/MimeTypesTest.php +++ b/src/Symfony/Component/Mime/Tests/MimeTypesTest.php @@ -75,7 +75,12 @@ public function testCustomMimeTypes() } /** - * PHP 8 detects .csv files as "application/csv" while PHP 7 returns "text/plain". + * PHP 8 detects .csv files as "application/csv" (or "text/csv", depending + * on your system) while PHP 7 returns "text/plain". + * + * "text/csv" is described by RFC 7111. + * + * @see https://datatracker.ietf.org/doc/html/rfc7111 * * @requires PHP 8 */ @@ -84,7 +89,7 @@ public function testCsvExtension() $mt = new MimeTypes(); $mime = $mt->guessMimeType(__DIR__.'/Fixtures/mimetypes/abc.csv'); - $this->assertSame('application/csv', $mime); + $this->assertContains($mime, ['application/csv', 'text/csv']); $this->assertSame(['csv'], $mt->getExtensions($mime)); } } From fe51b80903546f7cc1bd0c6997ca7f08d2fe2a34 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 8 Jun 2021 11:28:08 +0200 Subject: [PATCH 28/93] Optimize travis file a bit --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 738f4fc2b3a73..d0dd9bb830613 100644 --- a/.travis.yml +++ b/.travis.yml @@ -120,7 +120,7 @@ before_install: # php.ini configuration ( for PHP in $TRAVIS_PHP_VERSION $php_extra; do - (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & + ([[ $PHP != 7.4 ]] && phpenv global $PHP 2>/dev/null) || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & done wait ) From e9afce33341e1576c6726e9c0f5115d5cf86b260 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 8 Jun 2021 18:37:25 +0200 Subject: [PATCH 29/93] [HttpClient] Revert bindto workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … for unaffected PHP versions Signed-off-by: Alexander M. Turek --- src/Symfony/Component/HttpClient/NativeHttpClient.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpClient/NativeHttpClient.php b/src/Symfony/Component/HttpClient/NativeHttpClient.php index 18bf8f569bbbf..381202de2320f 100644 --- a/src/Symfony/Component/HttpClient/NativeHttpClient.php +++ b/src/Symfony/Component/HttpClient/NativeHttpClient.php @@ -193,6 +193,11 @@ public function request(string $method, string $url, array $options = []): Respo $options['timeout'] = min($options['max_duration'], $options['timeout']); } + $bindto = $options['bindto']; + if (!$bindto && (70322 === \PHP_VERSION_ID || 70410 === \PHP_VERSION_ID)) { + $bindto = '0:0'; + } + $context = [ 'http' => [ 'protocol_version' => min($options['http_version'] ?: '1.1', '1.1'), @@ -221,7 +226,7 @@ public function request(string $method, string $url, array $options = []): Respo 'disable_compression' => true, ], static function ($v) { return null !== $v; }), 'socket' => [ - 'bindto' => $options['bindto'] ?: '0:0', + 'bindto' => $bindto, 'tcp_nodelay' => true, ], ]; From 56359cb999764c2e8f98c507dd309156db7b72d4 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 8 Jun 2021 19:35:06 +0200 Subject: [PATCH 30/93] [VarExporter] Fix test on PHP 8.1 Signed-off-by: Alexander M. Turek --- src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php b/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php index ab225a6f55135..744e576c0a0c9 100644 --- a/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php +++ b/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php @@ -55,7 +55,10 @@ public function testInstantiate() "\0".__NAMESPACE__."\Foo\0priv" => 234, ]; - $this->assertSame($expected, (array) Instantiator::instantiate(Bar::class, ['priv' => 123], [Foo::class => ['priv' => 234]])); + $actual = (array) Instantiator::instantiate(Bar::class, ['priv' => 123], [Foo::class => ['priv' => 234]]); + ksort($actual); + + $this->assertSame($expected, $actual); $e = Instantiator::instantiate('Exception', ['foo' => 123, 'trace' => [234]]); From 46e18aff9b09bdc7ab91994fe4e6bcb7ab3f029c Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 8 Jun 2021 23:07:02 +0200 Subject: [PATCH 31/93] [Config] Backport type declarations Signed-off-by: Alexander M. Turek --- .../Component/Config/Definition/ArrayNode.php | 25 ++------ .../Builder/ArrayNodeDefinition.php | 2 +- .../Config/Definition/Builder/ExprBuilder.php | 6 +- .../Builder/NumericNodeDefinition.php | 4 +- .../Definition/Dumper/XmlReferenceDumper.php | 2 +- .../Component/Config/Definition/EnumNode.php | 3 + .../Config/Definition/NumericNode.php | 4 ++ .../Config/Definition/PrototypedArrayNode.php | 26 +------- .../Config/Tests/ConfigCacheTest.php | 6 +- .../Config/Tests/Definition/ArrayNodeTest.php | 26 ++++---- .../Config/Tests/Definition/BaseNodeTest.php | 4 +- .../Tests/Definition/BooleanNodeTest.php | 10 ++- .../Builder/ArrayNodeDefinitionTest.php | 19 +++--- .../Definition/Builder/ExprBuilderTest.php | 31 +++++----- .../Dumper/YamlReferenceDumperTest.php | 6 +- .../Config/Tests/Definition/FloatNodeTest.php | 8 ++- .../Tests/Definition/IntegerNodeTest.php | 10 ++- .../Tests/Definition/NormalizationTest.php | 16 ++--- .../Definition/PrototypedArrayNodeTest.php | 8 +-- .../Tests/Definition/ScalarNodeTest.php | 8 +-- .../Config/Tests/FileLocatorTest.php | 4 +- .../Tests/Fixtures/Builder/NodeBuilder.php | 6 +- .../Fixtures/Configuration/CustomNode.php | 8 +-- .../Config/Tests/Loader/FileLoaderTest.php | 14 +---- .../Tests/Resource/DirectoryResourceTest.php | 2 +- .../Resource/ReflectionClassResourceTest.php | 62 +++++++++---------- .../Config/Tests/Resource/ResourceStub.php | 2 +- .../Config/Tests/Util/XmlUtilsTest.php | 6 +- 28 files changed, 144 insertions(+), 184 deletions(-) diff --git a/src/Symfony/Component/Config/Definition/ArrayNode.php b/src/Symfony/Component/Config/Definition/ArrayNode.php index 96f38dcc9250d..c3c837a4129ea 100644 --- a/src/Symfony/Component/Config/Definition/ArrayNode.php +++ b/src/Symfony/Component/Config/Definition/ArrayNode.php @@ -203,11 +203,7 @@ public function addChild(NodeInterface $node) } /** - * Finalizes the value of this node. - * - * @param mixed $value - * - * @return mixed The finalised value + * {@inheritdoc} * * @throws UnsetKeyException * @throws InvalidConfigurationException if the node doesn't have enough children @@ -249,11 +245,7 @@ protected function finalizeValue($value) } /** - * Validates the type of the value. - * - * @param mixed $value - * - * @throws InvalidTypeException + * {@inheritdoc} */ protected function validateType($value) { @@ -269,11 +261,7 @@ protected function validateType($value) } /** - * Normalizes the value. - * - * @param mixed $value The value to normalize - * - * @return mixed The normalized value + * {@inheritdoc} * * @throws InvalidConfigurationException */ @@ -355,12 +343,7 @@ protected function remapXml($value) } /** - * Merges values together. - * - * @param mixed $leftSide The left side to merge - * @param mixed $rightSide The right side to merge - * - * @return mixed The merged values + * {@inheritdoc} * * @throws InvalidConfigurationException * @throws \RuntimeException diff --git a/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php index bec08b0db653b..61348387be2d3 100644 --- a/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php @@ -280,7 +280,7 @@ public function canBeEnabled() ->treatNullLike(['enabled' => true]) ->beforeNormalization() ->ifArray() - ->then(function ($v) { + ->then(function (array $v) { $v['enabled'] = $v['enabled'] ?? true; return $v; diff --git a/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php b/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php index 5db229dccab7f..0cf47c162c938 100644 --- a/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php +++ b/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php @@ -37,7 +37,7 @@ public function __construct(NodeDefinition $node) */ public function always(\Closure $then = null) { - $this->ifPart = function ($v) { return true; }; + $this->ifPart = function () { return true; }; if (null !== $then) { $this->thenPart = $then; @@ -168,7 +168,7 @@ public function then(\Closure $closure) */ public function thenEmptyArray() { - $this->thenPart = function ($v) { return []; }; + $this->thenPart = function () { return []; }; return $this; } @@ -200,7 +200,7 @@ public function thenInvalid($message) */ public function thenUnset() { - $this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key.'); }; + $this->thenPart = function () { throw new UnsetKeyException('Unsetting key.'); }; return $this; } diff --git a/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php index 390b1136567e6..c4bff1756fb0d 100644 --- a/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php @@ -26,7 +26,7 @@ abstract class NumericNodeDefinition extends ScalarNodeDefinition /** * Ensures that the value is smaller than the given reference. * - * @param mixed $max + * @param int|float $max * * @return $this * @@ -45,7 +45,7 @@ public function max($max) /** * Ensures that the value is bigger than the given reference. * - * @param mixed $min + * @param int|float $min * * @return $this * diff --git a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php index 29e4076f97ae8..a6b6240c77a54 100644 --- a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php +++ b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php @@ -49,7 +49,7 @@ private function writeNode(NodeInterface $node, int $depth = 0, bool $root = fal // xml remapping if ($node->getParent()) { - $remapping = array_filter($node->getParent()->getXmlRemappings(), function ($mapping) use ($rootName) { + $remapping = array_filter($node->getParent()->getXmlRemappings(), function (array $mapping) use ($rootName) { return $rootName === $mapping[1]; }); diff --git a/src/Symfony/Component/Config/Definition/EnumNode.php b/src/Symfony/Component/Config/Definition/EnumNode.php index 23fc508a78fa9..822e6b57f1642 100644 --- a/src/Symfony/Component/Config/Definition/EnumNode.php +++ b/src/Symfony/Component/Config/Definition/EnumNode.php @@ -38,6 +38,9 @@ public function getValues() return $this->values; } + /** + * {@inheritdoc} + */ protected function finalizeValue($value) { $value = parent::finalizeValue($value); diff --git a/src/Symfony/Component/Config/Definition/NumericNode.php b/src/Symfony/Component/Config/Definition/NumericNode.php index 19c96e8af764c..50d137c2d71fb 100644 --- a/src/Symfony/Component/Config/Definition/NumericNode.php +++ b/src/Symfony/Component/Config/Definition/NumericNode.php @@ -23,6 +23,10 @@ class NumericNode extends ScalarNode protected $min; protected $max; + /** + * @param int|float|null $min + * @param int|float|null $max + */ public function __construct(?string $name, NodeInterface $parent = null, $min = null, $max = null, string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR) { parent::__construct($name, $parent, $pathSeparator); diff --git a/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php b/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php index 72d3578be7a09..03822236772f8 100644 --- a/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php +++ b/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php @@ -173,14 +173,7 @@ public function addChild(NodeInterface $node) } /** - * Finalizes the value of this node. - * - * @param mixed $value - * - * @return mixed The finalized value - * - * @throws UnsetKeyException - * @throws InvalidConfigurationException if the node doesn't have enough children + * {@inheritdoc} */ protected function finalizeValue($value) { @@ -208,13 +201,8 @@ protected function finalizeValue($value) } /** - * Normalizes the value. - * - * @param mixed $value The value to normalize - * - * @return mixed The normalized value + * {@inheritdoc} * - * @throws InvalidConfigurationException * @throws DuplicateKeyException */ protected function normalizeValue($value) @@ -282,15 +270,7 @@ protected function normalizeValue($value) } /** - * Merges values together. - * - * @param mixed $leftSide The left side to merge - * @param mixed $rightSide The right side to merge - * - * @return mixed The merged values - * - * @throws InvalidConfigurationException - * @throws \RuntimeException + * {@inheritdoc} */ protected function mergeValues($leftSide, $rightSide) { diff --git a/src/Symfony/Component/Config/Tests/ConfigCacheTest.php b/src/Symfony/Component/Config/Tests/ConfigCacheTest.php index cfb2403a82a6c..ff72302a46406 100644 --- a/src/Symfony/Component/Config/Tests/ConfigCacheTest.php +++ b/src/Symfony/Component/Config/Tests/ConfigCacheTest.php @@ -38,7 +38,7 @@ protected function tearDown(): void /** * @dataProvider debugModes */ - public function testCacheIsNotValidIfNothingHasBeenCached($debug) + public function testCacheIsNotValidIfNothingHasBeenCached(bool $debug) { unlink($this->cacheFile); // remove tempnam() side effect $cache = new ConfigCache($this->cacheFile, $debug); @@ -60,7 +60,7 @@ public function testIsAlwaysFreshInProduction() /** * @dataProvider debugModes */ - public function testIsFreshWhenNoResourceProvided($debug) + public function testIsFreshWhenNoResourceProvided(bool $debug) { $cache = new ConfigCache($this->cacheFile, $debug); $cache->write('', []); @@ -89,7 +89,7 @@ public function testStaleResourceInDebug() $this->assertFalse($cache->isFresh()); } - public function debugModes() + public function debugModes(): array { return [ [true], diff --git a/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php index 54a966f1779f7..95f8480316b44 100644 --- a/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php @@ -55,7 +55,7 @@ public function testNormalizeWithoutProposals() $node->normalize(['beta' => 'foo']); } - public function ignoreAndRemoveMatrixProvider() + public function ignoreAndRemoveMatrixProvider(): array { $unrecognizedOptionException = new InvalidConfigurationException('Unrecognized option "foo" under "root"'); @@ -68,9 +68,11 @@ public function ignoreAndRemoveMatrixProvider() } /** + * @param array|\Exception $expected + * * @dataProvider ignoreAndRemoveMatrixProvider */ - public function testIgnoreAndRemoveBehaviors($ignore, $remove, $expected, $message = '') + public function testIgnoreAndRemoveBehaviors(bool $ignore, bool $remove, $expected, string $message = '') { if ($expected instanceof \Exception) { $this->expectException(\get_class($expected)); @@ -85,7 +87,7 @@ public function testIgnoreAndRemoveBehaviors($ignore, $remove, $expected, $messa /** * @dataProvider getPreNormalizationTests */ - public function testPreNormalize($denormalized, $normalized) + public function testPreNormalize(array $denormalized, array $normalized) { $node = new ArrayNode('foo'); @@ -95,7 +97,7 @@ public function testPreNormalize($denormalized, $normalized) $this->assertSame($normalized, $r->invoke($node, $denormalized)); } - public function getPreNormalizationTests() + public function getPreNormalizationTests(): array { return [ [ @@ -120,7 +122,7 @@ public function getPreNormalizationTests() /** * @dataProvider getZeroNamedNodeExamplesData */ - public function testNodeNameCanBeZero($denormalized, $normalized) + public function testNodeNameCanBeZero(array $denormalized, array $normalized) { $zeroNode = new ArrayNode(0); $zeroNode->addChild(new ScalarNode('name')); @@ -137,7 +139,7 @@ public function testNodeNameCanBeZero($denormalized, $normalized) $this->assertSame($normalized, $r->invoke($rootNode, $denormalized)); } - public function getZeroNamedNodeExamplesData() + public function getZeroNamedNodeExamplesData(): array { return [ [ @@ -168,7 +170,7 @@ public function getZeroNamedNodeExamplesData() /** * @dataProvider getPreNormalizedNormalizedOrderedData */ - public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized) + public function testChildrenOrderIsMaintainedOnNormalizeValue(array $prenormalized, array $normalized) { $scalar1 = new ScalarNode('1'); $scalar2 = new ScalarNode('2'); @@ -184,7 +186,7 @@ public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $n $this->assertSame($normalized, $r->invoke($node, $prenormalized)); } - public function getPreNormalizedNormalizedOrderedData() + public function getPreNormalizedNormalizedOrderedData(): array { return [ [ @@ -260,7 +262,7 @@ public function testSetDeprecated() /** * @dataProvider getDataWithIncludedExtraKeys */ - public function testMergeWithoutIgnoringExtraKeys($prenormalizeds, $merged) + public function testMergeWithoutIgnoringExtraKeys(array $prenormalizeds) { $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('merge() expects a normalized config array.'); @@ -278,7 +280,7 @@ public function testMergeWithoutIgnoringExtraKeys($prenormalizeds, $merged) /** * @dataProvider getDataWithIncludedExtraKeys */ - public function testMergeWithIgnoringAndRemovingExtraKeys($prenormalizeds, $merged) + public function testMergeWithIgnoringAndRemovingExtraKeys(array $prenormalizeds) { $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('merge() expects a normalized config array.'); @@ -296,7 +298,7 @@ public function testMergeWithIgnoringAndRemovingExtraKeys($prenormalizeds, $merg /** * @dataProvider getDataWithIncludedExtraKeys */ - public function testMergeWithIgnoringExtraKeys($prenormalizeds, $merged) + public function testMergeWithIgnoringExtraKeys(array $prenormalizeds, array $merged) { $node = new ArrayNode('root'); $node->addChild(new ScalarNode('foo')); @@ -309,7 +311,7 @@ public function testMergeWithIgnoringExtraKeys($prenormalizeds, $merged) $this->assertEquals($merged, $r->invoke($node, ...$prenormalizeds)); } - public function getDataWithIncludedExtraKeys() + public function getDataWithIncludedExtraKeys(): array { return [ [ diff --git a/src/Symfony/Component/Config/Tests/Definition/BaseNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/BaseNodeTest.php index ea2ed639ff383..afe3cdf691a90 100644 --- a/src/Symfony/Component/Config/Tests/Definition/BaseNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/BaseNodeTest.php @@ -20,7 +20,7 @@ class BaseNodeTest extends TestCase /** * @dataProvider providePath */ - public function testGetPathForChildNode($expected, array $params) + public function testGetPathForChildNode(string $expected, array $params) { $constructorArgs = []; $constructorArgs[] = $params[0]; @@ -41,7 +41,7 @@ public function testGetPathForChildNode($expected, array $params) $this->assertSame($expected, $node->getPath()); } - public function providePath() + public function providePath(): array { return [ 'name only' => ['root', ['root']], diff --git a/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php index 3a05e3efd8159..bec3b5996dd08 100644 --- a/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php @@ -20,7 +20,7 @@ class BooleanNodeTest extends TestCase /** * @dataProvider getValidValues */ - public function testNormalize($value) + public function testNormalize(bool $value) { $node = new BooleanNode('test'); $this->assertSame($value, $node->normalize($value)); @@ -28,10 +28,8 @@ public function testNormalize($value) /** * @dataProvider getValidValues - * - * @param bool $value */ - public function testValidNonEmptyValues($value) + public function testValidNonEmptyValues(bool $value) { $node = new BooleanNode('test'); $node->setAllowEmptyValue(false); @@ -39,7 +37,7 @@ public function testValidNonEmptyValues($value) $this->assertSame($value, $node->finalize($value)); } - public function getValidValues() + public function getValidValues(): array { return [ [false], @@ -57,7 +55,7 @@ public function testNormalizeThrowsExceptionOnInvalidValues($value) $node->normalize($value); } - public function getInvalidValues() + public function getInvalidValues(): array { return [ [null], diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php index 0e489ac910973..0f111826d35f6 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php @@ -42,7 +42,7 @@ public function testAppendingSomeNode() /** * @dataProvider providePrototypeNodeSpecificCalls */ - public function testPrototypeNodeSpecificOption($method, $args) + public function testPrototypeNodeSpecificOption(string $method, array $args) { $this->expectException(InvalidDefinitionException::class); $node = new ArrayNodeDefinition('root'); @@ -52,7 +52,7 @@ public function testPrototypeNodeSpecificOption($method, $args) $node->getNode(); } - public function providePrototypeNodeSpecificCalls() + public function providePrototypeNodeSpecificCalls(): array { return [ ['defaultValue', [[]]], @@ -98,9 +98,11 @@ public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren() } /** + * @param int|array|string|null $args + * * @dataProvider providePrototypedArrayNodeDefaults */ - public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults) + public function testPrototypedArrayNodeDefault($args, bool $shouldThrowWhenUsingAttrAsKey, bool $shouldThrowWhenNotUsingAttrAsKey, array $defaults) { $node = new ArrayNodeDefinition('root'); $node @@ -132,7 +134,7 @@ public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrA } } - public function providePrototypedArrayNodeDefaults() + public function providePrototypedArrayNodeDefaults(): array { return [ [null, true, false, [[]]], @@ -173,7 +175,7 @@ public function testEnabledNodeDefaults() /** * @dataProvider getEnableableNodeFixtures */ - public function testTrueEnableEnabledNode($expected, $config, $message) + public function testTrueEnableEnabledNode(array $expected, array $config, string $message) { $processor = new Processor(); $node = new ArrayNodeDefinition('root'); @@ -293,7 +295,7 @@ public function testPrototypeEnum() $this->assertEquals($node->prototype('enum'), $node->enumPrototype()); } - public function getEnableableNodeFixtures() + public function getEnableableNodeFixtures(): array { return [ [['enabled' => true, 'foo' => 'bar'], [true], 'true enables an enableable node'], @@ -432,7 +434,10 @@ protected function assertNode(string $expectedName, string $expectedType, NodeDe $this->assertSame($expectedName, $this->getField($actualNode, 'name')); } - protected function getField($object, $field) + /** + * @param object $object + */ + protected function getField($object, string $field) { $reflection = new \ReflectionProperty($object, $field); $reflection->setAccessible(true); diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php index c634f0887714c..74ae972e54aab 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Definition\Builder\ExprBuilder; +use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; @@ -36,13 +37,13 @@ public function testIfTrueExpression() $this->assertFinalizedValueIs('new_value', $test, ['key' => true]); $test = $this->getTestBuilder() - ->ifTrue(function ($v) { return true; }) + ->ifTrue(function () { return true; }) ->then($this->returnClosure('new_value')) ->end(); $this->assertFinalizedValueIs('new_value', $test); $test = $this->getTestBuilder() - ->ifTrue(function ($v) { return false; }) + ->ifTrue(function () { return false; }) ->then($this->returnClosure('new_value')) ->end(); $this->assertFinalizedValueIs('value', $test); @@ -150,7 +151,7 @@ public function testThenEmptyArrayExpression() /** * @dataProvider castToArrayValues */ - public function testCastToArrayExpression($configValue, $expectedValue) + public function testCastToArrayExpression($configValue, array $expectedValue) { $test = $this->getTestBuilder() ->castToArray() @@ -158,7 +159,7 @@ public function testCastToArrayExpression($configValue, $expectedValue) $this->assertFinalizedValueIs($expectedValue, $test, ['key' => $configValue]); } - public function castToArrayValues() + public function castToArrayValues(): iterable { yield ['value', ['value']]; yield [-3.14, [-3.14]]; @@ -219,20 +220,19 @@ protected function getTestBuilder(): ExprBuilder /** * Close the validation process and finalize with the given config. * - * @param TreeBuilder $testBuilder The tree builder to finalize - * @param array $config The config you want to use for the finalization, if nothing provided - * a simple ['key'=>'value'] will be used + * @param array|null $config The config you want to use for the finalization, if nothing provided + * a simple ['key'=>'value'] will be used * * @return array The finalized config values */ - protected function finalizeTestBuilder($testBuilder, $config = null): array + protected function finalizeTestBuilder(NodeDefinition $nodeDefinition, ?array $config = null): array { - return $testBuilder + return $nodeDefinition ->end() ->end() ->end() ->buildTree() - ->finalize(null === $config ? ['key' => 'value'] : $config) + ->finalize($config ?? ['key' => 'value']) ; } @@ -243,7 +243,7 @@ protected function finalizeTestBuilder($testBuilder, $config = null): array */ protected function returnClosure($val): \Closure { - return function ($v) use ($val) { + return function () use ($val) { return $val; }; } @@ -251,12 +251,11 @@ protected function returnClosure($val): \Closure /** * Assert that the given test builder, will return the given value. * - * @param mixed $value The value to test - * @param TreeBuilder $treeBuilder The tree builder to finalize - * @param mixed $config The config values that new to be finalized + * @param mixed $value The value to test + * @param mixed $config The config values that new to be finalized */ - protected function assertFinalizedValueIs($value, $treeBuilder, $config = null) + protected function assertFinalizedValueIs($value, NodeDefinition $nodeDefinition, $config = null) { - $this->assertEquals(['key' => $value], $this->finalizeTestBuilder($treeBuilder, $config)); + $this->assertEquals(['key' => $value], $this->finalizeTestBuilder($nodeDefinition, $config)); } } diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php index 146917aaa7084..f1871d49725c8 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php @@ -26,7 +26,7 @@ public function testDumper() $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration)); } - public function provideDumpAtPath() + public function provideDumpAtPath(): array { return [ 'Regular node' => ['scalar_true', <<assertSame(trim($expected), trim($dumper->dumpAtPath($configuration, $path))); } - private function getConfigurationAsString() + private function getConfigurationAsString(): string { return <<<'EOL' acme_root: diff --git a/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php index 68ed8a752120a..d675f47046f90 100644 --- a/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php @@ -19,6 +19,8 @@ class FloatNodeTest extends TestCase { /** * @dataProvider getValidValues + * + * @param int|float $value */ public function testNormalize($value) { @@ -29,7 +31,7 @@ public function testNormalize($value) /** * @dataProvider getValidValues * - * @param int $value + * @param int|float $value */ public function testValidNonEmptyValues($value) { @@ -39,7 +41,7 @@ public function testValidNonEmptyValues($value) $this->assertSame($value, $node->finalize($value)); } - public function getValidValues() + public function getValidValues(): array { return [ [1798.0], @@ -63,7 +65,7 @@ public function testNormalizeThrowsExceptionOnInvalidValues($value) $node->normalize($value); } - public function getInvalidValues() + public function getInvalidValues(): array { return [ [null], diff --git a/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php index c4dd57b8f45f4..7c843b38f3716 100644 --- a/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php @@ -20,7 +20,7 @@ class IntegerNodeTest extends TestCase /** * @dataProvider getValidValues */ - public function testNormalize($value) + public function testNormalize(int $value) { $node = new IntegerNode('test'); $this->assertSame($value, $node->normalize($value)); @@ -28,10 +28,8 @@ public function testNormalize($value) /** * @dataProvider getValidValues - * - * @param int $value */ - public function testValidNonEmptyValues($value) + public function testValidNonEmptyValues(int $value) { $node = new IntegerNode('test'); $node->setAllowEmptyValue(false); @@ -39,7 +37,7 @@ public function testValidNonEmptyValues($value) $this->assertSame($value, $node->finalize($value)); } - public function getValidValues() + public function getValidValues(): array { return [ [1798], @@ -58,7 +56,7 @@ public function testNormalizeThrowsExceptionOnInvalidValues($value) $node->normalize($value); } - public function getInvalidValues() + public function getInvalidValues(): array { return [ [null], diff --git a/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php b/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php index 3fecac2e3e7e2..0b497707e4604 100644 --- a/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php @@ -51,7 +51,7 @@ public function testNormalizeEncoders($denormalized) $this->assertNormalized($tree, $denormalized, $normalized); } - public function getEncoderTests() + public function getEncoderTests(): array { $configs = []; @@ -120,7 +120,7 @@ public function testAnonymousKeysArray($denormalized) $this->assertNormalized($tree, $denormalized, $normalized); } - public function getAnonymousKeysTests() + public function getAnonymousKeysTests(): array { $configs = []; @@ -151,7 +151,7 @@ public function testNumericKeysAsAttributes($denormalized) $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, $normalized); } - public function getNumericKeysTests() + public function getNumericKeysTests(): array { $configs = []; @@ -233,10 +233,9 @@ public static function assertNormalized(NodeInterface $tree, $denormalized, $nor self::assertSame($normalized, $tree->normalize($denormalized)); } - private function getNumericKeysTestTree() + private function getNumericKeysTestTree(): NodeInterface { - $tb = new TreeBuilder('root', 'array'); - $tree = $tb + return (new TreeBuilder('root', 'array')) ->getRootNode() ->children() ->node('thing', 'array') @@ -247,9 +246,6 @@ private function getNumericKeysTestTree() ->end() ->end() ->end() - ->buildTree() - ; - - return $tree; + ->buildTree(); } } diff --git a/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php index 58d2408a71c90..b02d6ce6df2d4 100644 --- a/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php @@ -264,7 +264,7 @@ protected function getPrototypeNodeWithDefaultChildren() * * @dataProvider getDataForKeyRemovedLeftValueOnly */ - public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, $expected) + public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, array $expected) { $node = new PrototypedArrayNode('root'); $node->setKeyAttribute('id', true); @@ -280,7 +280,7 @@ public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, $this->assertEquals($expected, $normalized); } - public function getDataForKeyRemovedLeftValueOnly() + public function getDataForKeyRemovedLeftValueOnly(): array { $scalarValue = new ScalarNode('value'); @@ -342,7 +342,7 @@ public function getDataForKeyRemovedLeftValueOnly() /** * @dataProvider getPrototypedArrayNodeDataToMerge */ - public function testPrototypedArrayNodeMerge($left, $right, $expected) + public function testPrototypedArrayNodeMerge(array $left, array $right, array $expected) { $node = new PrototypedArrayNode('options'); $node->setNormalizeKeys(false); @@ -354,7 +354,7 @@ public function testPrototypedArrayNodeMerge($left, $right, $expected) self::assertSame($result, $expected); } - public function getPrototypedArrayNodeDataToMerge() + public function getPrototypedArrayNodeDataToMerge(): array { return [ // data to merged is a plain array diff --git a/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php index 0eb66963ebe58..0ddd1104faaa0 100644 --- a/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php @@ -28,7 +28,7 @@ public function testNormalize($value) $this->assertSame($value, $node->normalize($value)); } - public function getValidValues() + public function getValidValues(): array { return [ [false], @@ -84,7 +84,7 @@ public function testNormalizeThrowsExceptionOnInvalidValues($value) $node->normalize($value); } - public function getInvalidValues() + public function getInvalidValues(): array { return [ [[]], @@ -127,7 +127,7 @@ public function testValidNonEmptyValues($value) $this->assertSame($value, $node->finalize($value)); } - public function getValidNonEmptyValues() + public function getValidNonEmptyValues(): array { return [ [false], @@ -153,7 +153,7 @@ public function testNotAllowedEmptyValuesThrowException($value) $node->finalize($value); } - public function getEmptyValues() + public function getEmptyValues(): array { return [ [null], diff --git a/src/Symfony/Component/Config/Tests/FileLocatorTest.php b/src/Symfony/Component/Config/Tests/FileLocatorTest.php index 44ef5ac9e3ebe..b8419d9a1ad01 100644 --- a/src/Symfony/Component/Config/Tests/FileLocatorTest.php +++ b/src/Symfony/Component/Config/Tests/FileLocatorTest.php @@ -20,7 +20,7 @@ class FileLocatorTest extends TestCase /** * @dataProvider getIsAbsolutePathTests */ - public function testIsAbsolutePath($path) + public function testIsAbsolutePath(string $path) { $loader = new FileLocator([]); $r = new \ReflectionObject($loader); @@ -30,7 +30,7 @@ public function testIsAbsolutePath($path) $this->assertTrue($m->invoke($loader, $path), '->isAbsolutePath() returns true for an absolute path'); } - public function getIsAbsolutePathTests() + public function getIsAbsolutePathTests(): array { return [ ['/foo.xml'], diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php b/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php index 26323e9805d64..5a0a8fe6f3375 100644 --- a/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php +++ b/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php @@ -12,10 +12,11 @@ namespace Symfony\Component\Config\Tests\Fixtures\Builder; use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder; +use Symfony\Component\Config\Definition\Builder\NodeDefinition; class NodeBuilder extends BaseNodeBuilder { - public function barNode($name) + public function barNode($name): NodeDefinition { return $this->node($name, 'bar'); } @@ -23,9 +24,8 @@ public function barNode($name) protected function getNodeClass($type): string { switch ($type) { - case 'variable': - return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition'; case 'bar': + case 'variable': return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition'; default: return parent::getNodeClass($type); diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Configuration/CustomNode.php b/src/Symfony/Component/Config/Tests/Fixtures/Configuration/CustomNode.php index 1270eb6a68323..f6c53ceeeb88f 100644 --- a/src/Symfony/Component/Config/Tests/Fixtures/Configuration/CustomNode.php +++ b/src/Symfony/Component/Config/Tests/Fixtures/Configuration/CustomNode.php @@ -7,22 +7,22 @@ class CustomNode implements NodeInterface { - public function getName() + public function getName(): string { return 'custom_node'; } - public function getPath() + public function getPath(): string { return 'custom'; } - public function isRequired() + public function isRequired(): bool { return false; } - public function hasDefaultValue() + public function hasDefaultValue(): bool { return true; } diff --git a/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php b/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php index 023bbe0f31ea6..9c74f6d60a379 100644 --- a/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php +++ b/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php @@ -165,22 +165,12 @@ public function supports($resource, $type = null): bool return $this->supports; } - public function addLoading($resource) + public function addLoading(string $resource): void { self::$loading[$resource] = true; } - public function removeLoading($resource) - { - unset(self::$loading[$resource]); - } - - public function clearLoading() - { - self::$loading = []; - } - - public function setSupports($supports) + public function setSupports(bool $supports): void { $this->supports = $supports; } diff --git a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php index 3de58f4be0a01..a114f214ab1ad 100644 --- a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -35,7 +35,7 @@ protected function tearDown(): void $this->removeDirectory($this->directory); } - protected function removeDirectory($directory) + protected function removeDirectory(string $directory): void { $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::CHILD_FIRST); foreach ($iterator as $path) { diff --git a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php index af0c2cd2c905e..64cfbf129a990 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php @@ -64,7 +64,7 @@ public function testIsFreshForDeletedResources() /** * @dataProvider provideHashedSignature */ - public function testHashedSignature($changeExpected, $changedLine, $changedCode, $setContext = null) + public function testHashedSignature(bool $changeExpected, int $changedLine, ?string $changedCode, ?\Closure $setContext = null) { if ($setContext) { $setContext(); @@ -117,43 +117,43 @@ public function testHashedSignature($changeExpected, $changedLine, $changedCode, } } - public function provideHashedSignature() + public function provideHashedSignature(): iterable { - yield [0, 0, "// line change\n\n"]; - yield [1, 0, '/** class docblock */']; - yield [1, 1, 'abstract class %s']; - yield [1, 1, 'final class %s']; - yield [1, 1, 'class %s extends Exception']; - yield [1, 1, 'class %s implements '.DummyInterface::class]; - yield [1, 3, 'const FOO = 456;']; - yield [1, 3, 'const BAR = 123;']; - yield [1, 4, '/** pub docblock */']; - yield [1, 5, 'protected $pub = [];']; - yield [1, 5, 'public $pub = [123];']; - yield [1, 6, '/** prot docblock */']; - yield [1, 7, 'private $prot;']; - yield [0, 8, '/** priv docblock */']; - yield [0, 9, 'private $priv = 123;']; - yield [1, 10, '/** pub docblock */']; - yield [1, 11, 'public function pub(...$arg) {}']; - yield [1, 11, 'public function pub($arg = null): Foo {}']; - yield [0, 11, "public function pub(\$arg = null) {\nreturn 123;\n}"]; - yield [1, 12, '/** prot docblock */']; - yield [1, 13, 'protected function prot($a = [123]) {}']; - yield [0, 14, '/** priv docblock */']; - yield [0, 15, '']; + yield [false, 0, "// line change\n\n"]; + yield [true, 0, '/** class docblock */']; + yield [true, 1, 'abstract class %s']; + yield [true, 1, 'final class %s']; + yield [true, 1, 'class %s extends Exception']; + yield [true, 1, 'class %s implements '.DummyInterface::class]; + yield [true, 3, 'const FOO = 456;']; + yield [true, 3, 'const BAR = 123;']; + yield [true, 4, '/** pub docblock */']; + yield [true, 5, 'protected $pub = [];']; + yield [true, 5, 'public $pub = [123];']; + yield [true, 6, '/** prot docblock */']; + yield [true, 7, 'private $prot;']; + yield [false, 8, '/** priv docblock */']; + yield [false, 9, 'private $priv = 123;']; + yield [true, 10, '/** pub docblock */']; + yield [true, 11, 'public function pub(...$arg) {}']; + yield [true, 11, 'public function pub($arg = null): Foo {}']; + yield [false, 11, "public function pub(\$arg = null) {\nreturn 123;\n}"]; + yield [true, 12, '/** prot docblock */']; + yield [true, 13, 'protected function prot($a = [123]) {}']; + yield [false, 14, '/** priv docblock */']; + yield [false, 15, '']; if (\PHP_VERSION_ID >= 70400) { // PHP7.4 typed properties without default value are // undefined, make sure this doesn't throw an error - yield [1, 5, 'public array $pub;']; - yield [0, 7, 'protected int $prot;']; - yield [0, 9, 'private string $priv;']; + yield [true, 5, 'public array $pub;']; + yield [false, 7, 'protected int $prot;']; + yield [false, 9, 'private string $priv;']; } - yield [1, 17, 'public function ccc($bar = 187) {}']; - yield [1, 17, 'public function ccc($bar = ANOTHER_ONE_THAT_WILL_NEVER_BE_DEFINED_CCCCCCCCC) {}']; - yield [1, 17, null, static function () { \define('A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC', 'foo'); }]; + yield [true, 17, 'public function ccc($bar = 187) {}']; + yield [true, 17, 'public function ccc($bar = ANOTHER_ONE_THAT_WILL_NEVER_BE_DEFINED_CCCCCCCCC) {}']; + yield [true, 17, null, static function () { \define('A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC', 'foo'); }]; } public function testEventSubscriber() diff --git a/src/Symfony/Component/Config/Tests/Resource/ResourceStub.php b/src/Symfony/Component/Config/Tests/Resource/ResourceStub.php index 959b00290ed6d..4073566d19f2a 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ResourceStub.php +++ b/src/Symfony/Component/Config/Tests/Resource/ResourceStub.php @@ -17,7 +17,7 @@ class ResourceStub implements SelfCheckingResourceInterface { private $fresh = true; - public function setFresh($isFresh) + public function setFresh(bool $isFresh): void { $this->fresh = $isFresh; } diff --git a/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php b/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php index 481603763aa25..a7a8ae980d597 100644 --- a/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php +++ b/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php @@ -116,7 +116,7 @@ public function testLoadFileWithInternalErrorsEnabled() /** * @dataProvider getDataForConvertDomToArray */ - public function testConvertDomToArray($expected, $xml, $root = false, $checkPrefix = true) + public function testConvertDomToArray($expected, string $xml, bool $root = false, bool $checkPrefix = true) { $dom = new \DOMDocument(); $dom->loadXML($root ? $xml : ''.$xml.''); @@ -124,7 +124,7 @@ public function testConvertDomToArray($expected, $xml, $root = false, $checkPref $this->assertSame($expected, XmlUtils::convertDomElementToArray($dom->documentElement, $checkPrefix)); } - public function getDataForConvertDomToArray() + public function getDataForConvertDomToArray(): array { return [ [null, ''], @@ -155,7 +155,7 @@ public function testPhpize($expected, $value) $this->assertSame($expected, XmlUtils::phpize($value)); } - public function getDataForPhpize() + public function getDataForPhpize(): array { return [ ['', ''], From 1d24bce18fd3db62dfb6583d0a83ff0538e933ee Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 8 Jun 2021 19:11:04 +0200 Subject: [PATCH 32/93] [HttpFoundation] Handle tentative return types Signed-off-by: Alexander M. Turek --- .../Storage/Handler/MigratingSessionHandler.php | 8 ++++++++ .../Session/Storage/Handler/NullSessionHandler.php | 4 ++++ .../Session/Storage/Handler/PdoSessionHandler.php | 5 +++++ .../Handler/MigratingSessionHandlerTest.php | 5 ++--- .../Storage/Handler/PdoSessionHandlerTest.php | 14 ++++++++++++-- .../Storage/Handler/StrictSessionHandlerTest.php | 4 ++-- .../Storage/Proxy/SessionHandlerProxyTest.php | 8 ++++++-- 7 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MigratingSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MigratingSessionHandler.php index c6b16d11c8544..c3e7ef6e60a30 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MigratingSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MigratingSessionHandler.php @@ -41,6 +41,7 @@ public function __construct(\SessionHandlerInterface $currentHandler, \SessionHa /** * @return bool */ + #[\ReturnTypeWillChange] public function close() { $result = $this->currentHandler->close(); @@ -52,6 +53,7 @@ public function close() /** * @return bool */ + #[\ReturnTypeWillChange] public function destroy($sessionId) { $result = $this->currentHandler->destroy($sessionId); @@ -63,6 +65,7 @@ public function destroy($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function gc($maxlifetime) { $result = $this->currentHandler->gc($maxlifetime); @@ -74,6 +77,7 @@ public function gc($maxlifetime) /** * @return bool */ + #[\ReturnTypeWillChange] public function open($savePath, $sessionName) { $result = $this->currentHandler->open($savePath, $sessionName); @@ -85,6 +89,7 @@ public function open($savePath, $sessionName) /** * @return string */ + #[\ReturnTypeWillChange] public function read($sessionId) { // No reading from new handler until switch-over @@ -94,6 +99,7 @@ public function read($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function write($sessionId, $sessionData) { $result = $this->currentHandler->write($sessionId, $sessionData); @@ -105,6 +111,7 @@ public function write($sessionId, $sessionData) /** * @return bool */ + #[\ReturnTypeWillChange] public function validateId($sessionId) { // No reading from new handler until switch-over @@ -114,6 +121,7 @@ public function validateId($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function updateTimestamp($sessionId, $sessionData) { $result = $this->currentHandler->updateTimestamp($sessionId, $sessionData); diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php index 0634e46dd53f4..c34c25edbb38b 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php @@ -21,6 +21,7 @@ class NullSessionHandler extends AbstractSessionHandler /** * @return bool */ + #[\ReturnTypeWillChange] public function close() { return true; @@ -29,6 +30,7 @@ public function close() /** * @return bool */ + #[\ReturnTypeWillChange] public function validateId($sessionId) { return true; @@ -45,6 +47,7 @@ protected function doRead($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function updateTimestamp($sessionId, $data) { return true; @@ -69,6 +72,7 @@ protected function doDestroy($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function gc($maxlifetime) { return true; diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php index db741877602dc..d3c5651d41300 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php @@ -262,6 +262,7 @@ public function isSessionExpired() /** * @return bool */ + #[\ReturnTypeWillChange] public function open($savePath, $sessionName) { $this->sessionExpired = false; @@ -276,6 +277,7 @@ public function open($savePath, $sessionName) /** * @return string */ + #[\ReturnTypeWillChange] public function read($sessionId) { try { @@ -290,6 +292,7 @@ public function read($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function gc($maxlifetime) { // We delay gc() to close() so that it is executed outside the transactional and blocking read-write process. @@ -369,6 +372,7 @@ protected function doWrite($sessionId, $data) /** * @return bool */ + #[\ReturnTypeWillChange] public function updateTimestamp($sessionId, $data) { $expiry = time() + (int) ini_get('session.gc_maxlifetime'); @@ -393,6 +397,7 @@ public function updateTimestamp($sessionId, $data) /** * @return bool */ + #[\ReturnTypeWillChange] public function close() { $this->commit(); diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MigratingSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MigratingSessionHandlerTest.php index 01615e6b1f2eb..f56f753af6c85 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MigratingSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MigratingSessionHandlerTest.php @@ -75,15 +75,14 @@ public function testGc() $this->currentHandler->expects($this->once()) ->method('gc') ->with($maxlifetime) - ->willReturn(true); + ->willReturn(1); $this->writeOnlyHandler->expects($this->once()) ->method('gc') ->with($maxlifetime) ->willReturn(false); - $result = $this->dualHandler->gc($maxlifetime); - $this->assertTrue($result); + $this->assertSame(1, $this->dualHandler->gc($maxlifetime)); } public function testOpen() diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php index c73118091636b..79ab73c1a4d1f 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php @@ -371,6 +371,10 @@ public function __construct(string $driverName = null, int $errorMode = null) $this->errorMode = null !== $errorMode ?: \PDO::ERRMODE_EXCEPTION; } + /** + * @return mixed + */ + #[\ReturnTypeWillChange] public function getAttribute($attribute) { if (\PDO::ATTR_ERRMODE === $attribute) { @@ -384,6 +388,10 @@ public function getAttribute($attribute) return parent::getAttribute($attribute); } + /** + * @return false|\PDOStatement + */ + #[\ReturnTypeWillChange] public function prepare($statement, $driverOptions = []) { return \is_callable($this->prepareResult) @@ -391,11 +399,13 @@ public function prepare($statement, $driverOptions = []) : $this->prepareResult; } - public function beginTransaction() + public function beginTransaction(): bool { + return true; } - public function rollBack() + public function rollBack(): bool { + return true; } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php index 353b1a02ec993..4f91016ac5cd8 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php @@ -181,9 +181,9 @@ public function testGc() { $handler = $this->createMock(\SessionHandlerInterface::class); $handler->expects($this->once())->method('gc') - ->with(123)->willReturn(true); + ->with(123)->willReturn(1); $proxy = new StrictSessionHandler($handler); - $this->assertTrue($proxy->gc(123)); + $this->assertSame(1, $proxy->gc(123)); } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php index 27bf3e27a6de9..1422eccfbc049 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php @@ -93,7 +93,9 @@ public function testCloseFalse() public function testRead() { $this->mock->expects($this->once()) - ->method('read'); + ->method('read') + ->willReturn('foo') + ; $this->proxy->read('id'); } @@ -117,7 +119,9 @@ public function testDestroy() public function testGc() { $this->mock->expects($this->once()) - ->method('gc'); + ->method('gc') + ->willReturn(1) + ; $this->proxy->gc(86400); } From d1579a2922bb2ad608673697c3a41a23eeeaec8a Mon Sep 17 00:00:00 2001 From: bch36 <31776675+bch36@users.noreply.github.com> Date: Tue, 8 Jun 2021 11:05:01 -0500 Subject: [PATCH 33/93] [Process] Fix incorrect parameter type --- src/Symfony/Component/Process/Pipes/WindowsPipes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Process/Pipes/WindowsPipes.php b/src/Symfony/Component/Process/Pipes/WindowsPipes.php index b2c3f4f4f3732..3a1ef405f6814 100644 --- a/src/Symfony/Component/Process/Pipes/WindowsPipes.php +++ b/src/Symfony/Component/Process/Pipes/WindowsPipes.php @@ -71,7 +71,7 @@ public function __construct($input, bool $haveReadSupport) } $this->lockHandles[$pipe] = $h; - if (!fclose(fopen($file, 'w')) || !$h = fopen($file, 'r')) { + if (!($h = fopen($file, 'w')) || !fclose($h) || !$h = fopen($file, 'r')) { flock($this->lockHandles[$pipe], \LOCK_UN); fclose($this->lockHandles[$pipe]); unset($this->lockHandles[$pipe]); From 7ad82474223e5951db3f9844b07a2afe8d16a9cd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 9 Jun 2021 17:56:09 +0200 Subject: [PATCH 34/93] [Config] fix tracking attributes in ReflectionClassResource --- .../Resource/ReflectionClassResource.php | 33 +++++++++++++++++++ .../Resource/ReflectionClassResourceTest.php | 11 +++++++ 2 files changed, 44 insertions(+) diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index 2b58bd663258d..a0aeb354c74ff 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -119,6 +119,15 @@ private function computeHash(): string private function generateSignature(\ReflectionClass $class): iterable { + if (\PHP_VERSION_ID >= 80000) { + $attributes = []; + foreach ($class->getAttributes() as $a) { + $attributes[] = [$a->getName(), $a->getArguments()]; + } + yield print_r($attributes, true); + $attributes = []; + } + yield $class->getDocComment(); yield (int) $class->isFinal(); yield (int) $class->isAbstract(); @@ -135,6 +144,14 @@ private function generateSignature(\ReflectionClass $class): iterable $defaults = $class->getDefaultProperties(); foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED) as $p) { + if (\PHP_VERSION_ID >= 80000) { + foreach ($p->getAttributes() as $a) { + $attributes[] = [$a->getName(), $a->getArguments()]; + } + yield print_r($attributes, true); + $attributes = []; + } + yield $p->getDocComment(); yield $p->isDefault() ? '' : ''; yield $p->isPublic() ? 'public' : 'protected'; @@ -145,9 +162,25 @@ private function generateSignature(\ReflectionClass $class): iterable } foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) { + if (\PHP_VERSION_ID >= 80000) { + foreach ($m->getAttributes() as $a) { + $attributes[] = [$a->getName(), $a->getArguments()]; + } + yield print_r($attributes, true); + $attributes = []; + } + $defaults = []; $parametersWithUndefinedConstants = []; foreach ($m->getParameters() as $p) { + if (\PHP_VERSION_ID >= 80000) { + foreach ($p->getAttributes() as $a) { + $attributes[] = [$a->getName(), $a->getArguments()]; + } + yield print_r($attributes, true); + $attributes = []; + } + if (!$p->isDefaultValueAvailable()) { $defaults[$p->name] = null; diff --git a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php index 64cfbf129a990..4f61c5bbd7c61 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php @@ -121,6 +121,11 @@ public function provideHashedSignature(): iterable { yield [false, 0, "// line change\n\n"]; yield [true, 0, '/** class docblock */']; + + if (\PHP_VERSION_ID >= 80000) { + yield [true, 0, '#[Foo]']; + } + yield [true, 1, 'abstract class %s']; yield [true, 1, 'final class %s']; yield [true, 1, 'class %s extends Exception']; @@ -140,6 +145,12 @@ public function provideHashedSignature(): iterable yield [false, 11, "public function pub(\$arg = null) {\nreturn 123;\n}"]; yield [true, 12, '/** prot docblock */']; yield [true, 13, 'protected function prot($a = [123]) {}']; + + if (\PHP_VERSION_ID >= 80000) { + yield [true, 13, '#[Foo] protected function prot($a = []) {}']; + yield [true, 13, 'protected function prot(#[Foo] $a = []) {}']; + } + yield [false, 14, '/** priv docblock */']; yield [false, 15, '']; From 608a3e596a2d576fac1014825319f8c12058eaee Mon Sep 17 00:00:00 2001 From: David Maicher Date: Thu, 10 Jun 2021 15:25:38 +0200 Subject: [PATCH 35/93] [Mailer] fix encoding of addresses using SmtpTransport --- .../Transport/Smtp/SmtpTransportTest.php | 19 +++++++++++++++++++ .../Mailer/Transport/Smtp/SmtpTransport.php | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Mailer/Tests/Transport/Smtp/SmtpTransportTest.php b/src/Symfony/Component/Mailer/Tests/Transport/Smtp/SmtpTransportTest.php index 72130dcee4037..956d3e269ef46 100644 --- a/src/Symfony/Component/Mailer/Tests/Transport/Smtp/SmtpTransportTest.php +++ b/src/Symfony/Component/Mailer/Tests/Transport/Smtp/SmtpTransportTest.php @@ -114,6 +114,25 @@ public function testSendInvalidMessage() $this->assertNotContains("\r\n.\r\n", $stream->getCommands()); $this->assertTrue($stream->isClosed()); } + + public function testWriteEncodedRecipientAndSenderAddresses() + { + $stream = new DummyStream(); + + $transport = new SmtpTransport($stream); + + $message = new Email(); + $message->from('sender@exämple.org'); + $message->addTo('recipient@exämple.org'); + $message->addTo('recipient2@example.org'); + $message->text('.'); + + $transport->send($message); + + $this->assertContains("MAIL FROM:\r\n", $stream->getCommands()); + $this->assertContains("RCPT TO:\r\n", $stream->getCommands()); + $this->assertContains("RCPT TO:\r\n", $stream->getCommands()); + } } class DummyStream extends AbstractStream diff --git a/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php b/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php index 2e1448f39a896..ac81d81a12e27 100644 --- a/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php +++ b/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php @@ -194,9 +194,9 @@ protected function doSend(SentMessage $message): void try { $envelope = $message->getEnvelope(); - $this->doMailFromCommand($envelope->getSender()->getAddress()); + $this->doMailFromCommand($envelope->getSender()->getEncodedAddress()); foreach ($envelope->getRecipients() as $recipient) { - $this->doRcptToCommand($recipient->getAddress()); + $this->doRcptToCommand($recipient->getEncodedAddress()); } $this->executeCommand("DATA\r\n", [354]); From 8df2ea12d356af736a416efc939b339f7f02e428 Mon Sep 17 00:00:00 2001 From: George Yiannoulopoulos <47791082+simplegr@users.noreply.github.com> Date: Tue, 15 Jun 2021 11:42:13 +0300 Subject: [PATCH 36/93] Fix some typos in Greek language --- .../Resources/translations/validators.el.xlf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf index c8882d2ae6667..3dded07760de0 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf @@ -68,7 +68,7 @@ The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. - Ο τύπος mime του αρχείου δεν είναι έγκυρος ({{ type }}). Οι έγκρυοι τύποι mime είναι {{ types }}. + Ο τύπος mime του αρχείου δεν είναι έγκυρος ({{ type }}). Οι έγκυροι τύποι mime είναι {{ types }}. This value should be {{ limit }} or less. @@ -144,7 +144,7 @@ This value is not a valid locale. - Αυτή η τιμή δεν αντιστοιχεί σε έκγυρο κωδικό τοποθεσίας. + Αυτή η τιμή δεν αντιστοιχεί σε έγκυρο κωδικό τοποθεσίας. This value is not a valid country. @@ -224,7 +224,7 @@ This is not a valid International Bank Account Number (IBAN). - Αυτό δεν αντιστοιχεί σε έκγυρο διεθνή αριθμό τραπεζικού λογαριασμού (IBAN). + Αυτό δεν αντιστοιχεί σε έγκυρο διεθνή αριθμό τραπεζικού λογαριασμού (IBAN). This value is not a valid ISBN-10. @@ -312,7 +312,7 @@ This is not a valid Business Identifier Code (BIC). - Αυτός δεν έιναι ένας έγκυρος κωδικός BIC. + Αυτός δεν είναι ένας έγκυρος κωδικός BIC. Error @@ -356,11 +356,11 @@ This value is not a valid timezone. - Αυτή η τιμή θα δέν είναι έγκυρη ζώνη ώρας. + Αυτή η τιμή θα δεν είναι έγκυρη ζώνη ώρας. This password has been leaked in a data breach, it must not be used. Please use another password. - Αυτός ο κωδικός πρόσβασης έχει διερρεύσει σε παραβίαση δεδομένων. Παρακαλούμε να χρησιμοποιήσετε έναν άλλο κωδικό. + Αυτός ο κωδικός πρόσβασης έχει διαρρεύσει σε παραβίαση δεδομένων. Παρακαλούμε να χρησιμοποιήσετε έναν άλλο κωδικό. This value should be between {{ min }} and {{ max }}. @@ -368,7 +368,7 @@ This value is not a valid hostname. - Αυτή η τιμή δέν είναι έγκυρο όνομα υποδοχής. + Αυτή η τιμή δεν είναι έγκυρο όνομα υποδοχής. The number of elements in this collection should be a multiple of {{ compared_value }}. @@ -376,7 +376,7 @@ This value should satisfy at least one of the following constraints: - Αυτή η τιμή θα πρέπει να ικανοποιεί τουλάχιστον έναν απο τους παρακάτω περιορισμούς: + Αυτή η τιμή θα πρέπει να ικανοποιεί τουλάχιστον έναν από τους παρακάτω περιορισμούς: Each element of this collection should satisfy its own set of constraints. @@ -384,7 +384,7 @@ This value is not a valid International Securities Identification Number (ISIN). - Αυτή η τιμή δέν είναι έγυρο International Securities Identification Number (ISIN). + Αυτή η τιμή δεν είναι έγκυρο International Securities Identification Number (ISIN). From f2b0822401952362b9029a603b392ecc2461863f Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Mon, 14 Jun 2021 16:11:26 +0200 Subject: [PATCH 37/93] [VarDumper] Fix tests for PHP 8.1 --- .../Tests/Caster/ReflectionCasterTest.php | 78 +++++++++++++++++-- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php index 3f5497573afed..f9a8bd94400d7 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php @@ -122,8 +122,9 @@ public function testReflectionParameter() { $var = new \ReflectionParameter(reflectionParameterFixture::class, 0); - $this->assertDumpMatchesFormat( - <<<'EOTXT' + if (\PHP_VERSION_ID < 80100) { + $this->assertDumpMatchesFormat( + <<<'EOTXT' ReflectionParameter { +name: "arg1" position: 0 @@ -131,8 +132,21 @@ public function testReflectionParameter() default: null } EOTXT - , $var - ); + , $var + ); + } else { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +ReflectionParameter { + +name: "arg1" + position: 0 + allowsNull: true + typeHint: "Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass" +} +EOTXT + , $var + ); + } } public function testReflectionParameterScalar() @@ -406,7 +420,8 @@ public function testGenerator() $generator = new GeneratorDemo(); $generator = $generator->baz(); - $expectedDump = <<<'EODUMP' + if (\PHP_VERSION_ID < 80100) { + $expectedDump = <<<'EODUMP' Generator { this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …} executing: { @@ -420,6 +435,23 @@ public function testGenerator() closed: false } EODUMP; + } else { + $expectedDump = <<<'EODUMP' +Generator { + this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …} + trace: { + ./src/Symfony/Component/VarDumper/Tests/Fixtures/GeneratorDemo.php:13 { + Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz() + › public function baz() + › { + › yield from bar(); + } + Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz() {} + } + closed: false +} +EODUMP; + } $this->assertDumpMatchesFormat($expectedDump, $generator); @@ -427,7 +459,8 @@ public function testGenerator() break; } - $expectedDump = <<<'EODUMP' + if (\PHP_VERSION_ID < 80100) { + $expectedDump = <<<'EODUMP' array:2 [ 0 => ReflectionGenerator { this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …} @@ -456,6 +489,39 @@ public function testGenerator() } ] EODUMP; + } else { + $expectedDump = <<<'EODUMP' +array:2 [ + 0 => ReflectionGenerator { + this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …} + trace: { + %s%eTests%eFixtures%eGeneratorDemo.php:9 { + Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo() + › { + › yield 1; + › } + } + %s%eTests%eFixtures%eGeneratorDemo.php:20 { …} + %s%eTests%eFixtures%eGeneratorDemo.php:14 { …} + Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz() {} + } + closed: false + } + 1 => Generator { + trace: { + ./src/Symfony/Component/VarDumper/Tests/Fixtures/GeneratorDemo.php:9 { + Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo() + › { + › yield 1; + › } + } + Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo() {} + } + closed: false + } +] +EODUMP; + } $r = new \ReflectionGenerator($generator); $this->assertDumpMatchesFormat($expectedDump, [$r, $r->getExecutingGenerator()]); From f8a082daebdd4e02e74eba0861dc6e160cdfc18c Mon Sep 17 00:00:00 2001 From: "simon.chrzanowski" Date: Fri, 18 Jun 2021 10:57:27 +0200 Subject: [PATCH 38/93] [HttpFoundation] allow savePath of NativeFileSessionHandler to be null --- .../Storage/Handler/SessionHandlerFactory.php | 4 +- .../Handler/SessionHandlerFactoryTest.php | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/SessionHandlerFactoryTest.php diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php index a5ebd29ebaa73..33453c320840f 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php @@ -48,7 +48,9 @@ public static function createHandler($connection): AbstractSessionHandler case !\is_string($connection): throw new \InvalidArgumentException(sprintf('Unsupported Connection: "%s".', \get_class($connection))); case 0 === strpos($connection, 'file://'): - return new StrictSessionHandler(new NativeFileSessionHandler(substr($connection, 7))); + $savePath = substr($connection, 7); + + return new StrictSessionHandler(new NativeFileSessionHandler('' === $savePath ? null : $savePath)); case 0 === strpos($connection, 'redis:'): case 0 === strpos($connection, 'rediss:'): diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/SessionHandlerFactoryTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/SessionHandlerFactoryTest.php new file mode 100644 index 0000000000000..46d6cd40151d5 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/SessionHandlerFactoryTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpFoundation\Session\Storage\Handler\SessionHandlerFactory; +use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler; + +/** + * Test class for SessionHandlerFactory. + * + * @author Simon + * + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled + */ +class SessionHandlerFactoryTest extends TestCase +{ + /** + * @dataProvider provideConnectionDSN + */ + public function testCreateHandler(string $connectionDSN, string $expectedPath, string $expectedHandlerType) + { + $handler = SessionHandlerFactory::createHandler($connectionDSN); + + $this->assertInstanceOf($expectedHandlerType, $handler); + $this->assertEquals($expectedPath, ini_get('session.save_path')); + } + + public function provideConnectionDSN(): array + { + $base = sys_get_temp_dir(); + + return [ + 'native file handler using save_path from php.ini' => ['connectionDSN' => 'file://', 'expectedPath' => ini_get('session.save_path'), 'expectedHandlerType' => StrictSessionHandler::class], + 'native file handler using provided save_path' => ['connectionDSN' => 'file://'.$base.'/session/storage', 'expectedPath' => $base.'/session/storage', 'expectedHandlerType' => StrictSessionHandler::class], + ]; + } +} From 67fae67a9adc3c234366fb779bc13f1916ad5e20 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 21 Jun 2021 14:28:32 +0200 Subject: [PATCH 39/93] [DependencyInjection] fix accepted types on FactoryTrait::factory() --- .../Loader/Configurator/Traits/FactoryTrait.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/FactoryTrait.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/FactoryTrait.php index 3834d72acada1..9968d77ae916d 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/FactoryTrait.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/FactoryTrait.php @@ -12,13 +12,14 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator; trait FactoryTrait { /** * Sets a factory. * - * @param string|array $factory A PHP callable reference + * @param string|array|ReferenceConfigurator $factory A PHP callable reference * * @return $this */ From 978747e6eaf2510e50f02d20c1878b6f88014a9d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 21 Jun 2021 16:51:25 +0200 Subject: [PATCH 40/93] [Config] fix tracking default values that reference the parent class --- .../Component/Config/Resource/ReflectionClassResource.php | 4 +++- .../Config/Tests/Resource/ReflectionClassResourceTest.php | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index a0aeb354c74ff..051158b2413f3 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -161,6 +161,8 @@ private function generateSignature(\ReflectionClass $class): iterable } } + $defined = \Closure::bind(static function ($c) { return \defined($c); }, null, $class->name); + foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) { if (\PHP_VERSION_ID >= 80000) { foreach ($m->getAttributes() as $a) { @@ -187,7 +189,7 @@ private function generateSignature(\ReflectionClass $class): iterable continue; } - if (!$p->isDefaultValueConstant() || \defined($p->getDefaultValueConstantName())) { + if (!$p->isDefaultValueConstant() || $defined($p->getDefaultValueConstantName())) { $defaults[$p->name] = $p->getDefaultValue(); continue; diff --git a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php index 4f61c5bbd7c61..8ba3a8c2c93cf 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php @@ -164,6 +164,7 @@ public function provideHashedSignature(): iterable yield [true, 17, 'public function ccc($bar = 187) {}']; yield [true, 17, 'public function ccc($bar = ANOTHER_ONE_THAT_WILL_NEVER_BE_DEFINED_CCCCCCCCC) {}']; + yield [true, 17, 'public function ccc($bar = parent::BOOM) {}']; yield [true, 17, null, static function () { \define('A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC', 'foo'); }]; } From 8451a14cf6dcbc8f11f0d8f45860a0c3997103c1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 21 Jun 2021 17:14:10 +0200 Subject: [PATCH 41/93] [DependencyInjection] Fix binding "iterable $foo" when using the PHP-DSL --- .../DependencyInjection/Compiler/ResolveBindingsPass.php | 2 +- .../Loader/Configurator/Traits/BindTrait.php | 2 +- .../DependencyInjection/Tests/Fixtures/Prototype/Foo.php | 2 +- .../Tests/Fixtures/config/defaults.expected.yml | 3 ++- .../DependencyInjection/Tests/Fixtures/config/defaults.php | 1 + 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php index 70dd04601cba4..695a916f867fc 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php @@ -134,7 +134,7 @@ protected function processValue($value, $isRoot = false) } if (null !== $bindingValue && !$bindingValue instanceof Reference && !$bindingValue instanceof Definition && !$bindingValue instanceof TaggedIteratorArgument && !$bindingValue instanceof ServiceLocatorArgument) { - throw new InvalidArgumentException(sprintf('Invalid value for binding key "%s" for service "%s": expected null, "%s", "%s", "%s" or ServiceLocatorArgument, "%s" given.', $key, $this->currentId, Reference::class, Definition::class, TaggedIteratorArgument::class, \gettype($bindingValue))); + throw new InvalidArgumentException(sprintf('Invalid value for binding key "%s" for service "%s": expected "%s", "%s", "%s", "%s" or null, "%s" given.', $key, $this->currentId, Reference::class, Definition::class, TaggedIteratorArgument::class, ServiceLocatorArgument::class, \gettype($bindingValue))); } } diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/BindTrait.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/BindTrait.php index 3d16ad6f01c24..573b6f53a291d 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/BindTrait.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/BindTrait.php @@ -34,7 +34,7 @@ trait BindTrait final public function bind(string $nameOrFqcn, $valueOrRef): self { $valueOrRef = static::processValue($valueOrRef, true); - if (!preg_match('/^(?:(?:array|bool|float|int|string)[ \t]*+)?\$/', $nameOrFqcn) && !$valueOrRef instanceof Reference) { + if (!preg_match('/^(?:(?:array|bool|float|int|string|iterable)[ \t]*+)?\$/', $nameOrFqcn) && !$valueOrRef instanceof Reference) { throw new InvalidArgumentException(sprintf('Invalid binding for service "%s": named arguments must start with a "$", and FQCN must map to references. Neither applies to binding "%s".', $this->id, $nameOrFqcn)); } $bindings = $this->definition->getBindings(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php index b6690a8d2680a..862e1b9cd9cec 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php @@ -4,7 +4,7 @@ class Foo implements FooInterface, Sub\BarInterface { - public function __construct($bar = null) + public function __construct($bar = null, iterable $foo) { } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.expected.yml index 2b389b694590a..13321967e3d6c 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.expected.yml @@ -15,13 +15,14 @@ services: - { name: t, a: b } autowire: true autoconfigure: true - arguments: ['@bar'] + arguments: ['@bar', !tagged_iterator foo] bar: class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo public: true tags: - { name: t, a: b } autowire: true + arguments: [null, !tagged_iterator foo] calls: - [setFoo, ['@bar']] diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.php index b04413d2102f3..6123403394917 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.php @@ -14,6 +14,7 @@ ->autowire() ->tag('t', ['a' => 'b']) ->bind(Foo::class, ref('bar')) + ->bind('iterable $foo', tagged_iterator('foo')) ->public(); $s->set(Foo::class)->args([ref('bar')])->public(); From dffde22329a583a1f837487083fcd107feaded4d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 21 Jun 2021 18:18:56 +0200 Subject: [PATCH 42/93] [Cache] Disable locking on Windows by default --- src/Symfony/Component/Cache/LockRegistry.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Cache/LockRegistry.php b/src/Symfony/Component/Cache/LockRegistry.php index d480257d3db71..70fcac9cc12af 100644 --- a/src/Symfony/Component/Cache/LockRegistry.php +++ b/src/Symfony/Component/Cache/LockRegistry.php @@ -27,7 +27,7 @@ final class LockRegistry { private static $openedFiles = []; - private static $lockedFiles = []; + private static $lockedFiles; /** * The number of items in this list controls the max number of concurrent processes. @@ -81,6 +81,11 @@ public static function setFiles(array $files): array public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata = null, LoggerInterface $logger = null) { + if ('\\' === \DIRECTORY_SEPARATOR && null === self::$lockedFiles) { + // disable locking on Windows by default + self::$files = self::$lockedFiles = []; + } + $key = self::$files ? abs(crc32($item->getKey())) % \count(self::$files) : -1; if ($key < 0 || (self::$lockedFiles[$key] ?? false) || !$lock = self::open($key)) { From 9ed93df77ae0c1b199e36769e308e0fec2b548cc Mon Sep 17 00:00:00 2001 From: Pierrick Charron Date: Mon, 21 Jun 2021 16:27:34 -0400 Subject: [PATCH 43/93] [ErrorHandler][DebugClassLoader] Do not check Phake mocks classes --- src/Symfony/Component/ErrorHandler/DebugClassLoader.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php index 36fb2ded75b3e..0668489104625 100644 --- a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php +++ b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php @@ -15,6 +15,7 @@ use Doctrine\Common\Persistence\Proxy as LegacyProxy; use Doctrine\Persistence\Proxy; use Mockery\MockInterface; +use Phake\IMock; use PHPUnit\Framework\MockObject\Matcher\StatelessInvocation; use PHPUnit\Framework\MockObject\MockObject; use Prophecy\Prophecy\ProphecySubjectInterface; @@ -310,6 +311,7 @@ public static function checkClasses(): bool && !is_subclass_of($symbols[$i], ProxyInterface::class) && !is_subclass_of($symbols[$i], LegacyProxy::class) && !is_subclass_of($symbols[$i], MockInterface::class) + && !is_subclass_of($symbols[$i], IMock::class) ) { $loader->checkClass($symbols[$i]); } From 29903e2c35f3f9f20e2a3bdef761edbb2b274c27 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 21 Jun 2021 15:22:37 +0200 Subject: [PATCH 44/93] [WebLink] fix types on Link::withAttribute() --- src/Symfony/Component/WebLink/Link.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/WebLink/Link.php b/src/Symfony/Component/WebLink/Link.php index c0402c6dc0952..55a66e075b4b2 100644 --- a/src/Symfony/Component/WebLink/Link.php +++ b/src/Symfony/Component/WebLink/Link.php @@ -46,7 +46,7 @@ class Link implements EvolvableLinkInterface private $rel = []; /** - * @var string[] + * @var array */ private $attributes = []; @@ -132,6 +132,8 @@ public function withoutRel($rel) /** * {@inheritdoc} * + * @param string|bool|string[] $value + * * @return static */ public function withAttribute($attribute, $value) From 63e42698d95ea220d25d8c4f64566187713173d2 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 22 Jun 2021 09:44:52 +0200 Subject: [PATCH 45/93] [WebLink] Sync type with parent interface --- src/Symfony/Component/WebLink/Link.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/WebLink/Link.php b/src/Symfony/Component/WebLink/Link.php index 55a66e075b4b2..ad4e7230741d4 100644 --- a/src/Symfony/Component/WebLink/Link.php +++ b/src/Symfony/Component/WebLink/Link.php @@ -132,7 +132,7 @@ public function withoutRel($rel) /** * {@inheritdoc} * - * @param string|bool|string[] $value + * @param string|\Stringable|int|float|bool|string[] $value * * @return static */ From b763a2951402a20cb93e183e095792f3ff500aef Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 22 Jun 2021 10:35:27 +0200 Subject: [PATCH 46/93] [DependencyInjection] throw proper exception when decorating a synthetic service --- .../Compiler/DecoratorServicePass.php | 7 +++++++ .../Compiler/DecoratorServicePassTest.php | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php index fed2916f34def..af7c957a308a2 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -14,6 +14,7 @@ use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Symfony\Component\DependencyInjection\Reference; @@ -59,6 +60,7 @@ public function process(ContainerBuilder $container) $public = $alias->isPublic(); $private = $alias->isPrivate(); $container->setAlias($renamedId, new Alias((string) $alias, false)); + $decoratedDefinition = $container->findDefinition($alias); } elseif ($container->hasDefinition($inner)) { $decoratedDefinition = $container->getDefinition($inner); $public = $decoratedDefinition->isPublic(); @@ -72,10 +74,15 @@ public function process(ContainerBuilder $container) } elseif (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { $public = $definition->isPublic(); $private = $definition->isPrivate(); + $decoratedDefinition = null; } else { throw new ServiceNotFoundException($inner, $id); } + if ($decoratedDefinition && $decoratedDefinition->isSynthetic()) { + throw new InvalidArgumentException(sprintf('A synthetic service cannot be decorated: service "%s" cannot decorate "%s".', $id, $inner)); + } + if (isset($decoratingDefinitions[$inner])) { $decoratingDefinition = $decoratingDefinitions[$inner]; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php index a739dda3a679a..9a456335569d4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php @@ -16,6 +16,7 @@ use Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; class DecoratorServicePassTest extends TestCase @@ -262,6 +263,23 @@ public function testProcessLeavesServiceSubscriberTagOnOriginalDefinition() $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar']], $container->getDefinition('baz')->getTags()); } + public function testCannotDecorateSyntheticService() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setSynthetic(true) + ; + $container + ->register('baz') + ->setDecoratedService('foo') + ; + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('A synthetic service cannot be decorated: service "baz" cannot decorate "foo".'); + $this->process($container); + } + protected function process(ContainerBuilder $container) { $repeatedPass = new DecoratorServicePass(); From 9589b52a78bbb21602043511209f46a37e9fc886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baptiste=20Clavi=C3=A9?= Date: Tue, 22 Jun 2021 10:57:19 +0200 Subject: [PATCH 47/93] Reapply the change to allow to set the composer binary path This change was somehow changed back during the renaming of the file I think. So this is just restoring the change. --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php index e9088bfe44f74..6558f910b0a3b 100644 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php @@ -150,12 +150,14 @@ putenv('SYMFONY_DEPRECATIONS_HELPER=disabled'); } -$COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') - || ($COMPOSER = rtrim((string) ('\\' === \DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar 2> NUL`) : `which composer.phar 2> /dev/null`))) - || ($COMPOSER = rtrim((string) ('\\' === \DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer 2> NUL`) : `which composer 2> /dev/null`))) - || file_exists($COMPOSER = rtrim((string) ('\\' === \DIRECTORY_SEPARATOR ? `git rev-parse --show-toplevel 2> NUL` : `git rev-parse --show-toplevel 2> /dev/null`)).\DIRECTORY_SEPARATOR.'composer.phar') - ? ('#!/usr/bin/env php' === file_get_contents($COMPOSER, false, null, 0, 18) ? $PHP : '').' '.escapeshellarg($COMPOSER) // detect shell wrappers by looking at the shebang - : 'composer'; +if (false === $COMPOSER = getenv('COMPOSER_BINARY')) { + $COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') + || ($COMPOSER = rtrim((string) ('\\' === \DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar 2> NUL`) : `which composer.phar 2> /dev/null`))) + || ($COMPOSER = rtrim((string) ('\\' === \DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer 2> NUL`) : `which composer 2> /dev/null`))) + || file_exists($COMPOSER = rtrim((string) ('\\' === \DIRECTORY_SEPARATOR ? `git rev-parse --show-toplevel 2> NUL` : `git rev-parse --show-toplevel 2> /dev/null`)).\DIRECTORY_SEPARATOR.'composer.phar') + ? ('#!/usr/bin/env php' === file_get_contents($COMPOSER, false, null, 0, 18) ? $PHP : '').' '.escapeshellarg($COMPOSER) // detect shell wrappers by looking at the shebang + : 'composer'; +} $prevCacheDir = getenv('COMPOSER_CACHE_DIR'); if ($prevCacheDir) { From 9c69e7780518740403ca3f2239b0871bf0add504 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 22 Jun 2021 17:42:29 +0200 Subject: [PATCH 48/93] Pin masterminds/html5 to the master branch for PHP 8.1 Signed-off-by: Alexander M. Turek --- .github/workflows/tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1e5bffaca5171..4b4f0ad84a048 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -141,6 +141,8 @@ jobs: run: | echo "::group::fake PHP version" composer config platform.php 8.0.99 + echo "::group::Adjust dependencies" + composer require --dev --no-update masterminds/html5:~2.7.5@dev echo "::group::composer update" composer update --no-progress --ansi echo "::endgroup::" From 7f1c76212fba0c0047e5362c518d89662cae1c04 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Tue, 22 Jun 2021 20:21:40 +0200 Subject: [PATCH 49/93] [FrameworkBundle] Replace var_export with VarExporter to use array short syntax --- src/Symfony/Bundle/FrameworkBundle/Secrets/SodiumVault.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Secrets/SodiumVault.php b/src/Symfony/Bundle/FrameworkBundle/Secrets/SodiumVault.php index 8b83224305221..b93c2d30a4348 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Secrets/SodiumVault.php +++ b/src/Symfony/Bundle/FrameworkBundle/Secrets/SodiumVault.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\FrameworkBundle\Secrets; use Symfony\Component\DependencyInjection\EnvVarLoaderInterface; +use Symfony\Component\VarExporter\VarExporter; /** * @author Tobias Schultze @@ -89,7 +90,7 @@ public function seal(string $name, string $value): void $list = $this->list(); $list[$name] = null; uksort($list, 'strnatcmp'); - file_put_contents($this->pathPrefix.'list.php', sprintf("pathPrefix.'list.php', sprintf("lastMessage = sprintf('Secret "%s" encrypted in "%s"; you can commit it.', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); } @@ -141,7 +142,7 @@ public function remove(string $name): bool $list = $this->list(); unset($list[$name]); - file_put_contents($this->pathPrefix.'list.php', sprintf("pathPrefix.'list.php', sprintf("lastMessage = sprintf('Secret "%s" removed from "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); From ee7bc0272e68fc85f5cabb6ad320cccc70fc0f7f Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Thu, 10 Jun 2021 20:42:23 +0000 Subject: [PATCH 50/93] [HttpKernel] [HttpCache] Keep s-maxage=0 from ESI sub-responses --- .../HttpCache/ResponseCacheStrategy.php | 6 ++++-- .../HttpCache/ResponseCacheStrategyTest.php | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php index 1f099468464d2..47bbbb74317e8 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php @@ -81,8 +81,10 @@ public function add(Response $response) return; } - $this->storeRelativeAgeDirective('max-age', $response->headers->getCacheControlDirective('max-age'), $age); - $this->storeRelativeAgeDirective('s-maxage', $response->headers->getCacheControlDirective('s-maxage') ?: $response->headers->getCacheControlDirective('max-age'), $age); + $maxAge = $response->headers->hasCacheControlDirective('max-age') ? (int) $response->headers->getCacheControlDirective('max-age') : null; + $this->storeRelativeAgeDirective('max-age', $maxAge, $age); + $sharedMaxAge = $response->headers->hasCacheControlDirective('s-maxage') ? (int) $response->headers->getCacheControlDirective('s-maxage') : $maxAge; + $this->storeRelativeAgeDirective('s-maxage', $sharedMaxAge, $age); $expires = $response->getExpires(); $expires = null !== $expires ? (int) $expires->format('U') - (int) $response->getDate()->format('U') : null; diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php index 62179ba154fcd..4875870eef34c 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php @@ -377,6 +377,22 @@ public function cacheControlMergingProvider() ], ]; + yield 's-maxage may be set to 0' => [ + ['public' => true, 's-maxage' => '0', 'max-age' => null], + ['public' => true, 's-maxage' => '0'], + [ + ['public' => true, 's-maxage' => '60'], + ], + ]; + + yield 's-maxage may be set to 0, and works independently from maxage' => [ + ['public' => true, 's-maxage' => '0', 'max-age' => '30'], + ['public' => true, 's-maxage' => '0', 'max-age' => '30'], + [ + ['public' => true, 'max-age' => '60'], + ], + ]; + yield 'result is private when combining private responses' => [ ['no-cache' => false, 'must-revalidate' => false, 'private' => true], ['s-maxage' => 60, 'private' => true], From 5f15f5d65d01d73f0510ee5e338c62ea2c40279f Mon Sep 17 00:00:00 2001 From: Mathieu Piot Date: Thu, 20 May 2021 13:47:07 +0200 Subject: [PATCH 51/93] [Validator][Translation] Add ExpressionLanguageSyntax en and fr --- .../Validator/Resources/translations/validators.en.xlf | 4 ++++ .../Validator/Resources/translations/validators.fr.xlf | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf index ecc73e48aa1ef..84cd9b9dcd9c2 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). This value is not a valid International Securities Identification Number (ISIN). + + This value should be a valid expression. + This value should be a valid expression. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf index a4dd54295b46a..c61ff92c6d473 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). Cette valeur n'est pas un code international de sécurité valide (ISIN). + + This value should be a valid expression. + Cette valeur doit être une expression valide. + From 5f2d5e043757437beaa2a87f344a9ae1cc26bd08 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 22 Jun 2021 17:28:51 +0200 Subject: [PATCH 52/93] [Cache] fix eventual consistency when using RedisTagAwareAdapter with a cluster --- .../Cache/Adapter/RedisTagAwareAdapter.php | 148 +++++++++--------- .../Tests/Adapter/TagAwareAdapterTest.php | 5 + .../Cache/Tests/LockRegistryTest.php | 3 + .../Component/Cache/Traits/RedisTrait.php | 18 ++- 4 files changed, 88 insertions(+), 86 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php index 9409c346fb817..6f4b75d313d72 100644 --- a/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php @@ -23,17 +23,13 @@ use Symfony\Component\Cache\Traits\RedisTrait; /** - * Stores tag id <> cache id relationship as a Redis Set, lookup on invalidation using RENAME+SMEMBERS. + * Stores tag id <> cache id relationship as a Redis Set. * * Set (tag relation info) is stored without expiry (non-volatile), while cache always gets an expiry (volatile) even * if not set by caller. Thus if you configure redis with the right eviction policy you can be safe this tag <> cache * relationship survives eviction (cache cleanup when Redis runs out of memory). * - * Requirements: - * - Client: PHP Redis or Predis - * Note: Due to lack of RENAME support it is NOT recommended to use Cluster on Predis, instead use phpredis. - * - Server: Redis 2.8+ - * Configured with any `volatile-*` eviction policy, OR `noeviction` if it will NEVER fill up memory + * Redis server 2.8+ with any `volatile-*` eviction policy, OR `noeviction` if you're sure memory will NEVER fill up * * Design limitations: * - Max 4 billion cache keys per cache tag as limited by Redis Set datatype. @@ -49,11 +45,6 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter { use RedisTrait; - /** - * Limits for how many keys are deleted in batch. - */ - private const BULK_DELETE_LIMIT = 10000; - /** * On cache items without a lifetime set, we set it to 100 days. This is to make sure cache items are * preferred to be evicted over tag Sets, if eviction policy is configured according to requirements. @@ -96,7 +87,7 @@ protected function doSave(array $values, int $lifetime, array $addTagData = [], { $eviction = $this->getRedisEvictionPolicy(); if ('noeviction' !== $eviction && 0 !== strpos($eviction, 'volatile-')) { - throw new LogicException(sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or "volatile-*" eviction policies.', $eviction)); + throw new LogicException(sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or "volatile-*" eviction policies.', $eviction)); } // serialize values @@ -159,15 +150,9 @@ protected function doDeleteYieldTags(array $ids): iterable return v:sub(14, 13 + v:byte(13) + v:byte(12) * 256 + v:byte(11) * 65536) EOLUA; - if ($this->redis instanceof \Predis\ClientInterface) { - $evalArgs = [$lua, 1, &$id]; - } else { - $evalArgs = [$lua, [&$id], 1]; - } - - $results = $this->pipeline(function () use ($ids, &$id, $evalArgs) { + $results = $this->pipeline(function () use ($ids, $lua) { foreach ($ids as $id) { - yield 'eval' => $evalArgs; + yield 'eval' => $this->redis instanceof \Predis\ClientInterface ? [$lua, 1, $id] : [$lua, [$id], 1]; } }); @@ -185,12 +170,15 @@ protected function doDeleteYieldTags(array $ids): iterable */ protected function doDeleteTagRelations(array $tagData): bool { - $this->pipeline(static function () use ($tagData) { + $results = $this->pipeline(static function () use ($tagData) { foreach ($tagData as $tagId => $idList) { array_unshift($idList, $tagId); yield 'sRem' => $idList; } - })->rewind(); + }); + foreach ($results as $result) { + // no-op + } return true; } @@ -200,77 +188,81 @@ protected function doDeleteTagRelations(array $tagData): bool */ protected function doInvalidate(array $tagIds): bool { - if (!$this->redis instanceof \Predis\ClientInterface || !$this->redis->getConnection() instanceof PredisCluster) { - $movedTagSetIds = $this->renameKeys($this->redis, $tagIds); - } else { - $clusterConnection = $this->redis->getConnection(); - $tagIdsByConnection = new \SplObjectStorage(); - $movedTagSetIds = []; + // This script scans the set of items linked to tag: it empties the set + // and removes the linked items. When the set is still not empty after + // the scan, it means we're in cluster mode and that the linked items + // are on other nodes: we move the links to a temporary set and we + // gargage collect that set from the client side. - foreach ($tagIds as $id) { - $connection = $clusterConnection->getConnectionByKey($id); - $slot = $tagIdsByConnection[$connection] ?? $tagIdsByConnection[$connection] = new \ArrayObject(); - $slot[] = $id; - } + $lua = <<<'EOLUA' + local cursor = '0' + local id = KEYS[1] + repeat + local result = redis.call('SSCAN', id, cursor, 'COUNT', 5000); + cursor = result[1]; + local rems = {} + + for _, v in ipairs(result[2]) do + local ok, _ = pcall(redis.call, 'DEL', ARGV[1]..v) + if ok then + table.insert(rems, v) + end + end + if 0 < #rems then + redis.call('SREM', id, unpack(rems)) + end + until '0' == cursor; + + redis.call('SUNIONSTORE', '{'..id..'}'..id, id) + redis.call('DEL', id) + + return redis.call('SSCAN', '{'..id..'}'..id, '0', 'COUNT', 5000) +EOLUA; - foreach ($tagIdsByConnection as $connection) { - $slot = $tagIdsByConnection[$connection]; - $movedTagSetIds = array_merge($movedTagSetIds, $this->renameKeys(new $this->redis($connection, $this->redis->getOptions()), $slot->getArrayCopy())); + $results = $this->pipeline(function () use ($tagIds, $lua) { + if ($this->redis instanceof \Predis\ClientInterface) { + $prefix = $this->redis->getOptions()->prefix ? $this->redis->getOptions()->prefix->getPrefix() : ''; + } elseif (\is_array($prefix = $this->redis->getOption(\Redis::OPT_PREFIX) ?? '')) { + $prefix = current($prefix); } - } - // No Sets found - if (!$movedTagSetIds) { - return false; - } - - // Now safely take the time to read the keys in each set and collect ids we need to delete - $tagIdSets = $this->pipeline(static function () use ($movedTagSetIds) { - foreach ($movedTagSetIds as $movedTagId) { - yield 'sMembers' => [$movedTagId]; + foreach ($tagIds as $id) { + yield 'eval' => $this->redis instanceof \Predis\ClientInterface ? [$lua, 1, $id, $prefix] : [$lua, [$id, $prefix], 1]; } }); - // Return combination of the temporary Tag Set ids and their values (cache ids) - $ids = array_merge($movedTagSetIds, ...iterator_to_array($tagIdSets, false)); + $lua = <<<'EOLUA' + local id = KEYS[1] + local cursor = table.remove(ARGV) + redis.call('SREM', '{'..id..'}'..id, unpack(ARGV)) - // Delete cache in chunks to avoid overloading the connection - foreach (array_chunk(array_unique($ids), self::BULK_DELETE_LIMIT) as $chunkIds) { - $this->doDelete($chunkIds); - } + return redis.call('SSCAN', '{'..id..'}'..id, cursor, 'COUNT', 5000) +EOLUA; - return true; - } + foreach ($results as $id => [$cursor, $ids]) { + while ($ids || '0' !== $cursor) { + $this->doDelete($ids); - /** - * Renames several keys in order to be able to operate on them without risk of race conditions. - * - * Filters out keys that do not exist before returning new keys. - * - * @see https://redis.io/commands/rename - * @see https://redis.io/topics/cluster-spec#keys-hash-tags - * - * @return array Filtered list of the valid moved keys (only those that existed) - */ - private function renameKeys($redis, array $ids): array - { - $newIds = []; - $uniqueToken = bin2hex(random_bytes(10)); + $evalArgs = [$id, $cursor]; + array_splice($evalArgs, 1, 0, $ids); - $results = $this->pipeline(static function () use ($ids, $uniqueToken) { - foreach ($ids as $id) { - yield 'rename' => [$id, '{'.$id.'}'.$uniqueToken]; - } - }, $redis); + if ($this->redis instanceof \Predis\ClientInterface) { + array_unshift($evalArgs, $lua, 1); + } else { + $evalArgs = [$lua, $evalArgs, 1]; + } - foreach ($results as $id => $result) { - if (true === $result || ($result instanceof Status && Status::get('OK') === $result)) { - // Only take into account if ok (key existed), will be false on phpredis if it did not exist - $newIds[] = '{'.$id.'}'.$uniqueToken; + $results = $this->pipeline(function () use ($evalArgs) { + yield 'eval' => $evalArgs; + }); + + foreach ($results as [$cursor, $ids]) { + // no-op + } } } - return $newIds; + return true; } private function getRedisEvictionPolicy(): string diff --git a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php index adef44b2c3d28..de7b81149d774 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php @@ -19,6 +19,7 @@ use Symfony\Component\Cache\Adapter\ArrayAdapter; use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Component\Cache\Adapter\TagAwareAdapter; +use Symfony\Component\Cache\LockRegistry; use Symfony\Component\Cache\Tests\Fixtures\PrunableAdapter; /** @@ -199,6 +200,8 @@ public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags public function testLog() { + $lockFiles = LockRegistry::setFiles([__FILE__]); + $logger = $this->createMock(LoggerInterface::class); $logger ->expects($this->atLeastOnce()) @@ -209,6 +212,8 @@ public function testLog() // Computing will produce at least one log $cache->get('foo', static function (): string { return 'ccc'; }); + + LockRegistry::setFiles($lockFiles); } /** diff --git a/src/Symfony/Component/Cache/Tests/LockRegistryTest.php b/src/Symfony/Component/Cache/Tests/LockRegistryTest.php index 0771347ed6fe3..30ff6774047a5 100644 --- a/src/Symfony/Component/Cache/Tests/LockRegistryTest.php +++ b/src/Symfony/Component/Cache/Tests/LockRegistryTest.php @@ -18,6 +18,9 @@ class LockRegistryTest extends TestCase { public function testFiles() { + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('LockRegistry is disabled on Windows'); + } $lockFiles = LockRegistry::setFiles([]); LockRegistry::setFiles($lockFiles); $expected = array_map('realpath', glob(__DIR__.'/../Adapter/*')); diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php index 7aaca38292006..fcca8d652f33c 100644 --- a/src/Symfony/Component/Cache/Traits/RedisTrait.php +++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php @@ -363,12 +363,6 @@ protected function doHave($id) protected function doClear($namespace) { $cleared = true; - if ($this->redis instanceof \Predis\ClientInterface) { - $evalArgs = [0, $namespace]; - } else { - $evalArgs = [[$namespace], 0]; - } - $hosts = $this->getHosts(); $host = reset($hosts); if ($host instanceof \Predis\Client && $host->getConnection() instanceof ReplicationInterface) { @@ -385,17 +379,20 @@ protected function doClear($namespace) $info = $host->info('Server'); $info = $info['Server'] ?? $info; + $pattern = $namespace.'*'; + if (!version_compare($info['redis_version'], '2.8', '>=')) { // As documented in Redis documentation (http://redis.io/commands/keys) using KEYS // can hang your server when it is executed against large databases (millions of items). // Whenever you hit this scale, you should really consider upgrading to Redis 2.8 or above. - $cleared = $host->eval("local keys=redis.call('KEYS',ARGV[1]..'*') for i=1,#keys,5000 do redis.call('DEL',unpack(keys,i,math.min(i+4999,#keys))) end return 1", $evalArgs[0], $evalArgs[1]) && $cleared; + $args = $this->redis instanceof \Predis\ClientInterface ? [0, $pattern] : [[$pattern], 0]; + $cleared = $host->eval("local keys=redis.call('KEYS',ARGV[1]) for i=1,#keys,5000 do redis.call('DEL',unpack(keys,i,math.min(i+4999,#keys))) end return 1", $args[0], $args[1]) && $cleared; continue; } $cursor = null; do { - $keys = $host instanceof \Predis\ClientInterface ? $host->scan($cursor, 'MATCH', $namespace.'*', 'COUNT', 1000) : $host->scan($cursor, $namespace.'*', 1000); + $keys = $host instanceof \Predis\ClientInterface ? $host->scan($cursor, 'MATCH', $pattern, 'COUNT', 1000) : $host->scan($cursor, $pattern, 1000); if (isset($keys[1]) && \is_array($keys[1])) { $cursor = $keys[0]; $keys = $keys[1]; @@ -507,6 +504,11 @@ private function pipeline(\Closure $generator, $redis = null): \Generator $results = $redis->exec(); } + if (!$redis instanceof \Predis\ClientInterface && 'eval' === $command && $redis->getLastError()) { + $e = new \RedisException($redis->getLastError()); + $results = array_map(function ($v) use ($e) { return false === $v ? $e : $v; }, $results); + } + foreach ($ids as $k => $id) { yield $id => $results[$k]; } From 7527b5a4f9ca79aac6dd9525f3c123ba992988d7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 22 Jun 2021 17:28:51 +0200 Subject: [PATCH 53/93] [Cache] handle prefixed redis connections when clearing pools --- .../Tests/Adapter/AbstractRedisAdapterTest.php | 16 +++++++++++++++- .../Cache/Tests/Adapter/PredisAdapterTest.php | 2 +- .../Tests/Adapter/PredisClusterAdapterTest.php | 2 +- .../Adapter/PredisRedisClusterAdapterTest.php | 2 +- .../Tests/Adapter/PredisTagAwareAdapterTest.php | 2 +- .../Adapter/PredisTagAwareClusterAdapterTest.php | 2 +- .../Tests/Adapter/RedisAdapterSentinelTest.php | 2 +- .../Cache/Tests/Adapter/RedisAdapterTest.php | 8 ++++++-- .../Tests/Adapter/RedisArrayAdapterTest.php | 1 + .../Tests/Adapter/RedisClusterAdapterTest.php | 7 ++++++- .../Tests/Adapter/RedisTagAwareAdapterTest.php | 6 +++++- .../Adapter/RedisTagAwareArrayAdapterTest.php | 6 +++++- .../Adapter/RedisTagAwareClusterAdapterTest.php | 6 +++++- .../Cache/Traits/RedisClusterNodeProxy.php | 5 +++++ .../Component/Cache/Traits/RedisTrait.php | 16 +++++++++++++++- 15 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Cache/Tests/Adapter/AbstractRedisAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/AbstractRedisAdapterTest.php index 994ae81d5b3a6..9d14007fde75f 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/AbstractRedisAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/AbstractRedisAdapterTest.php @@ -24,7 +24,7 @@ abstract class AbstractRedisAdapterTest extends AdapterTestCase protected static $redis; - public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface + public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface { return new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); } @@ -45,4 +45,18 @@ public static function tearDownAfterClass(): void { self::$redis = null; } + + /** + * @runInSeparateProcess + */ + public function testClearWithPrefix() + { + $cache = $this->createCachePool(0, __FUNCTION__); + + $cache->save($cache->getItem('foo')->set('bar')); + $this->assertTrue($cache->hasItem('foo')); + + $cache->clear(); + $this->assertFalse($cache->hasItem('foo')); + } } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PredisAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PredisAdapterTest.php index e19f74f6745c2..a1a2b4dda3fc8 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PredisAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PredisAdapterTest.php @@ -22,7 +22,7 @@ class PredisAdapterTest extends AbstractRedisAdapterTest public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); - self::$redis = new \Predis\Client(['host' => getenv('REDIS_HOST')]); + self::$redis = new \Predis\Client(['host' => getenv('REDIS_HOST')], ['prefix' => 'prefix_']); } public function testCreateConnection() diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PredisClusterAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PredisClusterAdapterTest.php index e6989be292334..e2f09cd23ae44 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PredisClusterAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PredisClusterAdapterTest.php @@ -19,7 +19,7 @@ class PredisClusterAdapterTest extends AbstractRedisAdapterTest public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); - self::$redis = new \Predis\Client([['host' => getenv('REDIS_HOST')]]); + self::$redis = new \Predis\Client([['host' => getenv('REDIS_HOST')]], ['prefix' => 'prefix_']); } public static function tearDownAfterClass(): void diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PredisRedisClusterAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PredisRedisClusterAdapterTest.php index 81dd0bc2a04cc..9db83c0db4126 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PredisRedisClusterAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PredisRedisClusterAdapterTest.php @@ -24,7 +24,7 @@ public static function setUpBeforeClass(): void self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); } - self::$redis = RedisAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['class' => \Predis\Client::class, 'redis_cluster' => true]); + self::$redis = RedisAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['class' => \Predis\Client::class, 'redis_cluster' => true, 'prefix' => 'prefix_']); } public static function tearDownAfterClass(): void diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PredisTagAwareAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PredisTagAwareAdapterTest.php index 6cffbde7926f1..0971f80c553e5 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PredisTagAwareAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PredisTagAwareAdapterTest.php @@ -27,7 +27,7 @@ protected function setUp(): void $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite'; } - public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface + public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface { $this->assertInstanceOf(\Predis\Client::class, self::$redis); $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PredisTagAwareClusterAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PredisTagAwareClusterAdapterTest.php index 21120d606ac18..af25b2df52c45 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PredisTagAwareClusterAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PredisTagAwareClusterAdapterTest.php @@ -27,7 +27,7 @@ protected function setUp(): void $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite'; } - public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface + public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface { $this->assertInstanceOf(\Predis\Client::class, self::$redis); $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php index 0eb407bafa5b9..20f0811863aaa 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php @@ -32,7 +32,7 @@ public static function setUpBeforeClass(): void self::markTestSkipped('REDIS_SENTINEL_SERVICE env var is not defined.'); } - self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['redis_sentinel' => $service]); + self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['redis_sentinel' => $service, 'prefix' => 'prefix_']); } public function testInvalidDSNHasBothClusterAndSentinel() diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterTest.php index b54a5acc84260..d961187aeca3a 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterTest.php @@ -28,9 +28,13 @@ public static function setUpBeforeClass(): void self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), ['lazy' => true]); } - public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface + public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface { - $adapter = parent::createCachePool($defaultLifetime); + if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) { + self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX); + } + + $adapter = parent::createCachePool($defaultLifetime, $testMethod); $this->assertInstanceOf(RedisProxy::class, self::$redis); return $adapter; diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisArrayAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisArrayAdapterTest.php index 70afe6dac97c9..6e0b448746e86 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/RedisArrayAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisArrayAdapterTest.php @@ -23,5 +23,6 @@ public static function setUpBeforeClass(): void self::markTestSkipped('The RedisArray class is required.'); } self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]); + self::$redis->setOption(\Redis::OPT_PREFIX, 'prefix_'); } } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisClusterAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisClusterAdapterTest.php index 1253aeb5007a7..011a36b338229 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/RedisClusterAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisClusterAdapterTest.php @@ -32,10 +32,15 @@ public static function setUpBeforeClass(): void } self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['lazy' => true, 'redis_cluster' => true]); + self::$redis->setOption(\Redis::OPT_PREFIX, 'prefix_'); } - public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface + public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface { + if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) { + self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX); + } + $this->assertInstanceOf(RedisClusterProxy::class, self::$redis); $adapter = new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareAdapterTest.php index 5c82016be2adb..12e3b6ff55365 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareAdapterTest.php @@ -28,8 +28,12 @@ protected function setUp(): void $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite'; } - public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface + public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface { + if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) { + self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX); + } + $this->assertInstanceOf(RedisProxy::class, self::$redis); $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareArrayAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareArrayAdapterTest.php index 3ec500a9010e9..b5823711dc858 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareArrayAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareArrayAdapterTest.php @@ -27,8 +27,12 @@ protected function setUp(): void $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite'; } - public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface + public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface { + if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) { + self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX); + } + $this->assertInstanceOf(\RedisArray::class, self::$redis); $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareClusterAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareClusterAdapterTest.php index 50f078c04d4b0..d4a1bc97779ca 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareClusterAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisTagAwareClusterAdapterTest.php @@ -28,8 +28,12 @@ protected function setUp(): void $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite'; } - public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface + public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface { + if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) { + self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX); + } + $this->assertInstanceOf(RedisClusterProxy::class, self::$redis); $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); diff --git a/src/Symfony/Component/Cache/Traits/RedisClusterNodeProxy.php b/src/Symfony/Component/Cache/Traits/RedisClusterNodeProxy.php index 7818f0b8df9c9..deba74f6a3b7d 100644 --- a/src/Symfony/Component/Cache/Traits/RedisClusterNodeProxy.php +++ b/src/Symfony/Component/Cache/Traits/RedisClusterNodeProxy.php @@ -45,4 +45,9 @@ public function scan(&$iIterator, $strPattern = null, $iCount = null) { return $this->redis->scan($iIterator, $this->host, $strPattern, $iCount); } + + public function getOption($name) + { + return $this->redis->getOption($name); + } } diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php index fcca8d652f33c..aaf4f1bd00e46 100644 --- a/src/Symfony/Component/Cache/Traits/RedisTrait.php +++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php @@ -362,6 +362,11 @@ protected function doHave($id) */ protected function doClear($namespace) { + if ($this->redis instanceof \Predis\ClientInterface) { + $prefix = $this->redis->getOptions()->prefix ? $this->redis->getOptions()->prefix->getPrefix() : ''; + $prefixLen = \strlen($prefix); + } + $cleared = true; $hosts = $this->getHosts(); $host = reset($hosts); @@ -379,7 +384,11 @@ protected function doClear($namespace) $info = $host->info('Server'); $info = $info['Server'] ?? $info; - $pattern = $namespace.'*'; + if (!$host instanceof \Predis\ClientInterface) { + $prefix = \defined('Redis::SCAN_PREFIX') && (\Redis::SCAN_PREFIX & $host->getOption(\Redis::OPT_SCAN)) ? '' : $host->getOption(\Redis::OPT_PREFIX); + $prefixLen = \strlen($host->getOption(\Redis::OPT_PREFIX) ?? ''); + } + $pattern = $prefix.$namespace.'*'; if (!version_compare($info['redis_version'], '2.8', '>=')) { // As documented in Redis documentation (http://redis.io/commands/keys) using KEYS @@ -398,6 +407,11 @@ protected function doClear($namespace) $keys = $keys[1]; } if ($keys) { + if ($prefixLen) { + foreach ($keys as $i => $key) { + $keys[$i] = substr($key, $prefixLen); + } + } $this->doDelete($keys); } } while ($cursor = (int) $cursor); From 88c69c0ec02fb35ff7e9da9f4c76218857f256a9 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Thu, 10 Jun 2021 09:06:30 +0200 Subject: [PATCH 54/93] [DependencyInjection] Add support of PHP enumerations --- .../DependencyInjection/Dumper/PhpDumper.php | 2 ++ .../DependencyInjection/Dumper/XmlDumper.php | 5 ++++ .../DependencyInjection/Dumper/YamlDumper.php | 2 ++ .../Tests/Dumper/PhpDumperTest.php | 25 ++++++++++++++++ .../Tests/Dumper/XmlDumperTest.php | 19 ++++++++++++ .../Tests/Dumper/YamlDumperTest.php | 19 ++++++++++++ .../Fixtures/FooClassWithEnumAttribute.php | 18 ++++++++++++ .../Tests/Fixtures/FooUnitEnum.php | 8 +++++ .../xml/services_with_enumeration.xml | 9 ++++++ .../xml/services_with_invalid_enumeration.xml | 9 ++++++ .../yaml/services_with_enumeration.yml | 10 +++++++ .../services_with_invalid_enumeration.yml | 10 +++++++ .../Tests/Loader/XmlFileLoaderTest.php | 28 ++++++++++++++++++ .../Tests/Loader/YamlFileLoaderTest.php | 29 +++++++++++++++++++ src/Symfony/Component/Yaml/Inline.php | 2 ++ .../Yaml/Tests/Fixtures/FooUnitEnum.php | 8 +++++ .../Component/Yaml/Tests/InlineTest.php | 9 ++++++ 17 files changed, 212 insertions(+) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooClassWithEnumAttribute.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooUnitEnum.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_enumeration.xml create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_invalid_enumeration.xml create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_enumeration.yml create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_invalid_enumeration.yml create mode 100644 src/Symfony/Component/Yaml/Tests/Fixtures/FooUnitEnum.php diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 711b631d54590..3ea0b1b93f731 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1812,6 +1812,8 @@ private function dumpValue($value, bool $interpolate = true): string return $code; } + } elseif ($value instanceof \UnitEnum) { + return sprintf('\%s::%s', \get_class($value), $value->name); } elseif (\is_object($value) || \is_resource($value)) { throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); } diff --git a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php index 02a501bd2c34c..8017fc579aaa2 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php @@ -313,6 +313,9 @@ private function convertParameters(array $parameters, string $type, \DOMElement $element->setAttribute('type', 'binary'); $text = $this->document->createTextNode(self::phpToXml(base64_encode($value))); $element->appendChild($text); + } elseif ($value instanceof \UnitEnum) { + $element->setAttribute('type', 'constant'); + $element->appendChild($this->document->createTextNode(self::phpToXml($value))); } else { if (\in_array($value, ['null', 'true', 'false'], true)) { $element->setAttribute('type', 'string'); @@ -366,6 +369,8 @@ public static function phpToXml($value): string return 'false'; case $value instanceof Parameter: return '%'.$value.'%'; + case $value instanceof \UnitEnum: + return sprintf('%s::%s', \get_class($value), $value->name); case \is_object($value) || \is_resource($value): throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); default: diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php index c055a686128c2..5dce997d9df9d 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -286,6 +286,8 @@ private function dumpValue($value) return $this->getExpressionCall((string) $value); } elseif ($value instanceof Definition) { return new TaggedValue('service', (new Parser())->parse("_:\n".$this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']); + } elseif ($value instanceof \UnitEnum) { + return new TaggedValue('php/const', sprintf('%s::%s', \get_class($value), $value->name)); } elseif (\is_object($value) || \is_resource($value)) { throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index b46fbf937b910..3468e35a944c1 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -40,6 +40,8 @@ use Symfony\Component\DependencyInjection\Tests\Compiler\Foo; use Symfony\Component\DependencyInjection\Tests\Compiler\Wither; use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum; use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory; use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator; use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1; @@ -1208,6 +1210,29 @@ public function testDumpHandlesObjectClassNames() $this->assertInstanceOf(\stdClass::class, $container->get('bar')); } + /** + * @requires PHP 8.1 + */ + public function testDumpHandlesEnumeration() + { + $container = new ContainerBuilder(); + $container + ->register('foo', FooClassWithEnumAttribute::class) + ->setPublic(true) + ->addArgument(FooUnitEnum::BAR); + + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump([ + 'class' => 'Symfony_DI_PhpDumper_Test_Enumeration', + ])); + + $container = new \Symfony_DI_PhpDumper_Test_Enumeration(); + + $this->assertSame(FooUnitEnum::BAR, $container->get('foo')->getBar()); + } + public function testUninitializedSyntheticReference() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php index dda18a306207e..18caa150f278e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php @@ -21,6 +21,8 @@ use Symfony\Component\DependencyInjection\Dumper\XmlDumper; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum; class XmlDumperTest extends TestCase { @@ -249,4 +251,21 @@ public function testDumpAbstractServices() $this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_abstract.xml'), $dumper->dump()); } + + /** + * @requires PHP 8.1 + */ + public function testDumpHandlesEnumeration() + { + $container = new ContainerBuilder(); + $container + ->register(FooClassWithEnumAttribute::class, FooClassWithEnumAttribute::class) + ->setPublic(true) + ->addArgument(FooUnitEnum::BAR); + + $container->compile(); + $dumper = new XmlDumper($container); + + $this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_with_enumeration.xml'), $dumper->dump()); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php index b359f668d7758..9a973afe69df7 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php @@ -22,6 +22,8 @@ use Symfony\Component\DependencyInjection\Dumper\YamlDumper; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum; use Symfony\Component\Yaml\Parser; use Symfony\Component\Yaml\Yaml; @@ -129,6 +131,23 @@ public function testServiceClosure() $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_service_closure.yml', $dumper->dump()); } + /** + * @requires PHP 8.1 + */ + public function testDumpHandlesEnumeration() + { + $container = new ContainerBuilder(); + $container + ->register(FooClassWithEnumAttribute::class, FooClassWithEnumAttribute::class) + ->setPublic(true) + ->addArgument(FooUnitEnum::BAR); + + $container->compile(); + $dumper = new YamlDumper($container); + + $this->assertEquals(file_get_contents(self::$fixturesPath.'/yaml/services_with_enumeration.yml'), $dumper->dump()); + } + private function assertEqualYamlStructure(string $expected, string $yaml, string $message = '') { $parser = new Parser(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooClassWithEnumAttribute.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooClassWithEnumAttribute.php new file mode 100644 index 0000000000000..3b2235efdd76b --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooClassWithEnumAttribute.php @@ -0,0 +1,18 @@ +bar = $bar; + } + + public function getBar(): FooUnitEnum + { + return $this->bar; + } +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooUnitEnum.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooUnitEnum.php new file mode 100644 index 0000000000000..d51cf9c995e26 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/FooUnitEnum.php @@ -0,0 +1,8 @@ + + + + + + Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAR + + + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_invalid_enumeration.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_invalid_enumeration.xml new file mode 100644 index 0000000000000..8864e6d892857 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_invalid_enumeration.xml @@ -0,0 +1,9 @@ + + + + + + Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAZ + + + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_enumeration.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_enumeration.yml new file mode 100644 index 0000000000000..46bf505d44b80 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_enumeration.yml @@ -0,0 +1,10 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute + public: true + arguments: [!php/const 'Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAR'] diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_invalid_enumeration.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_invalid_enumeration.yml new file mode 100644 index 0000000000000..b9f74e0f468ab --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_invalid_enumeration.yml @@ -0,0 +1,10 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute + public: true + arguments: [!php/const 'Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAZ'] diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 80d3393010602..ef00b2f721608 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -37,6 +37,8 @@ use Symfony\Component\DependencyInjection\Tests\Fixtures\Bar; use Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface; use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum; use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy; use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype; use Symfony\Component\ExpressionLanguage\Expression; @@ -827,6 +829,32 @@ public function testInstanceof() $this->assertSame(['foo' => [[]], 'bar' => [[]]], $definition->getTags()); } + /** + * @requires PHP 8.1 + */ + public function testEnumeration() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_with_enumeration.xml'); + $container->compile(); + + $definition = $container->getDefinition(FooClassWithEnumAttribute::class); + $this->assertSame([FooUnitEnum::BAR], $definition->getArguments()); + } + + /** + * @requires PHP 8.1 + */ + public function testInvalidEnumeration() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + + $this->expectException(\Error::class); + $loader->load('services_with_invalid_enumeration.xml'); + } + public function testInstanceOfAndChildDefinitionNotAllowed() { $this->expectException(InvalidArgumentException::class); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index f367bf3452384..910e7b2a243e5 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -37,6 +37,8 @@ use Symfony\Component\DependencyInjection\Tests\Fixtures\Bar; use Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface; use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum; use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy; use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype; use Symfony\Component\ExpressionLanguage\Expression; @@ -909,6 +911,33 @@ public function testDefaultValueOfTagged() $this->assertNull($iteratorArgument->getIndexAttribute()); } + /** + * @requires PHP 8.1 + */ + public function testEnumeration() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_with_enumeration.yml'); + $container->compile(); + + $definition = $container->getDefinition(FooClassWithEnumAttribute::class); + $this->assertSame([FooUnitEnum::BAR], $definition->getArguments()); + } + + /** + * @requires PHP 8.1 + */ + public function testInvalidEnumeration() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The constant "Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAZ" is not defined'); + $loader->load('services_with_invalid_enumeration.yml'); + } + public function testReturnsClone() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index a317bb0438e5f..10ed14fe5116b 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -127,6 +127,8 @@ public static function dump($value, int $flags = 0): string return self::dumpNull($flags); case $value instanceof \DateTimeInterface: return $value->format('c'); + case $value instanceof \UnitEnum: + return sprintf('!php/const %s::%s', \get_class($value), $value->name); case \is_object($value): if ($value instanceof TaggedValue) { return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags); diff --git a/src/Symfony/Component/Yaml/Tests/Fixtures/FooUnitEnum.php b/src/Symfony/Component/Yaml/Tests/Fixtures/FooUnitEnum.php new file mode 100644 index 0000000000000..59092e27e8728 --- /dev/null +++ b/src/Symfony/Component/Yaml/Tests/Fixtures/FooUnitEnum.php @@ -0,0 +1,8 @@ +assertSame($expected, Inline::dump($dateTime)); } + /** + * @requires PHP 8.1 + */ + public function testDumpUnitEnum() + { + $this->assertSame("!php/const Symfony\Component\Yaml\Tests\Fixtures\FooUnitEnum::BAR", Inline::dump(FooUnitEnum::BAR)); + } + public function getDateTimeDumpTests() { $tests = []; From 974516133a21390e4f8e2b57c40863054cb858a2 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 23 Jun 2021 22:56:48 +0200 Subject: [PATCH 55/93] [HttpClient] fix Psr18Client when allow_url_fopen=0 --- src/Symfony/Component/HttpClient/Response/StreamWrapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpClient/Response/StreamWrapper.php b/src/Symfony/Component/HttpClient/Response/StreamWrapper.php index 83f1562e84e35..644f2ee190f57 100644 --- a/src/Symfony/Component/HttpClient/Response/StreamWrapper.php +++ b/src/Symfony/Component/HttpClient/Response/StreamWrapper.php @@ -53,7 +53,7 @@ public static function createResource(ResponseInterface $response, HttpClientInt throw new \InvalidArgumentException(sprintf('Providing a client to "%s()" is required when the response doesn\'t have any "stream()" method.', __CLASS__)); } - if (false === stream_wrapper_register('symfony', __CLASS__, \STREAM_IS_URL)) { + if (false === stream_wrapper_register('symfony', __CLASS__)) { throw new \RuntimeException(error_get_last()['message'] ?? 'Registering the "symfony" stream wrapper failed.'); } From 07407c74cabe1a22199a5a27e2ccf47ded580a5f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 21 Jun 2021 14:19:38 +0200 Subject: [PATCH 56/93] [ErrorHandler] fix handling buffered SilencedErrorContext --- .../Component/ErrorHandler/Resources/views/logs.html.php | 2 +- src/Symfony/Component/ErrorHandler/ThrowableUtils.php | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/ErrorHandler/Resources/views/logs.html.php b/src/Symfony/Component/ErrorHandler/Resources/views/logs.html.php index f886200fb3b5b..bd2dbe2feebd1 100644 --- a/src/Symfony/Component/ErrorHandler/Resources/views/logs.html.php +++ b/src/Symfony/Component/ErrorHandler/Resources/views/logs.html.php @@ -17,7 +17,7 @@ $status = 'warning'; } else { $severity = 0; - if (($exception = $log['context']['exception'] ?? null) instanceof \ErrorException) { + if (($exception = $log['context']['exception'] ?? null) instanceof \ErrorException || $exception instanceof \Symfony\Component\ErrorHandler\Exception\SilencedErrorContext) { $severity = $exception->getSeverity(); } $status = \E_DEPRECATED === $severity || \E_USER_DEPRECATED === $severity ? 'warning' : 'normal'; diff --git a/src/Symfony/Component/ErrorHandler/ThrowableUtils.php b/src/Symfony/Component/ErrorHandler/ThrowableUtils.php index d6efcbefa0cc0..18d04988ac342 100644 --- a/src/Symfony/Component/ErrorHandler/ThrowableUtils.php +++ b/src/Symfony/Component/ErrorHandler/ThrowableUtils.php @@ -11,14 +11,19 @@ namespace Symfony\Component\ErrorHandler; +use Symfony\Component\ErrorHandler\Exception\SilencedErrorContext; + /** * @internal */ class ThrowableUtils { - public static function getSeverity(\Throwable $throwable): int + /** + * @param SilencedErrorContext|\Throwable + */ + public static function getSeverity($throwable): int { - if ($throwable instanceof \ErrorException) { + if ($throwable instanceof \ErrorException || $throwable instanceof SilencedErrorContext) { return $throwable->getSeverity(); } From 9f6a9bbda20369bfae476c49f8475a618fd65554 Mon Sep 17 00:00:00 2001 From: Mamikon Arakelyan Date: Thu, 24 Jun 2021 01:43:12 +0400 Subject: [PATCH 57/93] [Security]Added missing translations for Armenian (hy) --- .../Security/Core/Resources/translations/security.hy.xlf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.hy.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.hy.xlf index da63a0047c664..459c292be31a6 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.hy.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.hy.xlf @@ -36,7 +36,7 @@ No session available, it either timed out or cookies are not enabled. - No session available, it either timed out or cookies are not enabled. + Հասանելի սեսիա չկա, կամ այն սպառվել է կամ cookie-ները անջատված են: No token could be found. From ad1f057ce208b507c18fbcd28907a0cf70ae1c6a Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Fri, 11 Jun 2021 05:58:59 +0000 Subject: [PATCH 58/93] Public responses without lifetime should not remove lifetime for the resulting response --- .../HttpCache/ResponseCacheStrategy.php | 29 +++++++++++++++---- .../HttpCache/ResponseCacheStrategyTest.php | 26 ++++++++++++++++- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php index 47bbbb74317e8..17a7e87fe95e1 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php @@ -81,14 +81,15 @@ public function add(Response $response) return; } + $isHeuristicallyCacheable = $response->headers->hasCacheControlDirective('public'); $maxAge = $response->headers->hasCacheControlDirective('max-age') ? (int) $response->headers->getCacheControlDirective('max-age') : null; - $this->storeRelativeAgeDirective('max-age', $maxAge, $age); + $this->storeRelativeAgeDirective('max-age', $maxAge, $age, $isHeuristicallyCacheable); $sharedMaxAge = $response->headers->hasCacheControlDirective('s-maxage') ? (int) $response->headers->getCacheControlDirective('s-maxage') : $maxAge; - $this->storeRelativeAgeDirective('s-maxage', $sharedMaxAge, $age); + $this->storeRelativeAgeDirective('s-maxage', $sharedMaxAge, $age, $isHeuristicallyCacheable); $expires = $response->getExpires(); $expires = null !== $expires ? (int) $expires->format('U') - (int) $response->getDate()->format('U') : null; - $this->storeRelativeAgeDirective('expires', $expires >= 0 ? $expires : null, 0); + $this->storeRelativeAgeDirective('expires', $expires >= 0 ? $expires : null, 0, $isHeuristicallyCacheable); } /** @@ -199,11 +200,29 @@ private function willMakeFinalResponseUncacheable(Response $response): bool * we have to subtract the age so that the value is normalized for an age of 0. * * If the value is lower than the currently stored value, we update the value, to keep a rolling - * minimal value of each instruction. If the value is NULL, the directive will not be set on the final response. + * minimal value of each instruction. + * + * If the value is NULL and the isHeuristicallyCacheable parameter is false, the directive will + * not be set on the final response. In this case, not all responses had the directive set and no + * value can be found that satisfies the requirements of all responses. The directive will be dropped + * from the final response. + * + * If the isHeuristicallyCacheable parameter is true, however, the current response has been marked + * as cacheable in a public (shared) cache, but did not provide an explicit lifetime that would serve + * as an upper bound. In this case, we can proceed and possibly keep the directive on the final response. */ - private function storeRelativeAgeDirective(string $directive, ?int $value, int $age) + private function storeRelativeAgeDirective(string $directive, ?int $value, int $age, bool $isHeuristicallyCacheable) { if (null === $value) { + if ($isHeuristicallyCacheable) { + /* + * See https://datatracker.ietf.org/doc/html/rfc7234#section-4.2.2 + * This particular response does not require maximum lifetime; heuristics might be applied. + * Other responses, however, might have more stringent requirements on maximum lifetime. + * So, return early here so that the final response can have the more limiting value set. + */ + return; + } $this->ageDirectives[$directive] = false; } diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php index 4875870eef34c..4d56b2428583c 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php @@ -370,7 +370,7 @@ public function cacheControlMergingProvider() ]; yield 'merge max-age and s-maxage' => [ - ['public' => true, 's-maxage' => '60', 'max-age' => null], + ['public' => true, 'max-age' => '60'], ['public' => true, 's-maxage' => 3600], [ ['public' => true, 'max-age' => 60], @@ -393,6 +393,30 @@ public function cacheControlMergingProvider() ], ]; + yield 'public subresponse without lifetime does not remove lifetime for main response' => [ + ['public' => true, 's-maxage' => '30', 'max-age' => null], + ['public' => true, 's-maxage' => '30'], + [ + ['public' => true], + ], + ]; + + yield 'lifetime for subresponse is kept when main response has no lifetime' => [ + ['public' => true, 'max-age' => '30'], + ['public' => true], + [ + ['public' => true, 'max-age' => '30'], + ], + ]; + + yield 's-maxage on the subresponse implies public, so the result is public as well' => [ + ['public' => true, 'max-age' => '10', 's-maxage' => null], + ['public' => true, 'max-age' => '10'], + [ + ['max-age' => '30', 's-maxage' => '20'], + ], + ]; + yield 'result is private when combining private responses' => [ ['no-cache' => false, 'must-revalidate' => false, 'private' => true], ['s-maxage' => 60, 'private' => true], From 7685645b463e6a8f8ffef486e555f6ac48dcb362 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 24 Jun 2021 10:08:16 +0200 Subject: [PATCH 59/93] [DI] fix fixture --- .../DependencyInjection/Tests/Fixtures/Prototype/Foo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php index 862e1b9cd9cec..1544dfd12c670 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php @@ -4,7 +4,7 @@ class Foo implements FooInterface, Sub\BarInterface { - public function __construct($bar = null, iterable $foo) + public function __construct($bar = null, iterable $foo = null) { } From 0c97c8ac84f6dddd847b01de1b9db54f04280d7f Mon Sep 17 00:00:00 2001 From: Ana Raro Date: Thu, 24 Jun 2021 11:04:45 +0100 Subject: [PATCH 60/93] (#41826) missing translations for portuguese --- .../Validator/Resources/translations/validators.pt.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf index 71bdaf8bc19f1..5caa804dd1712 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.pt.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). Este valor não é um Número Internacional de Identificação de Segurança (ISIN) válido. + + This value should be a valid expression. + Este valor deve ser uma expressão válida. + From b244cc994eecd4573eeae87663c4faa212bb8714 Mon Sep 17 00:00:00 2001 From: Storkeus Date: Thu, 24 Jun 2021 21:15:04 +0200 Subject: [PATCH 61/93] Add missing translation for Polish --- .../Validator/Resources/translations/validators.pl.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.pl.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.pl.xlf index 561a7d40500b5..0881f3167293a 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.pl.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.pl.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). Ta wartość nie jest prawidłowym Międzynarodowym Numerem Identyfikacyjnym Papierów Wartościowych (ISIN). + + This value should be a valid expression. + Ta wartość powinna być prawidłowym wyrażeniem. + From 52807cbdfc8545350d96a7e903250cbda973e7ce Mon Sep 17 00:00:00 2001 From: Marcos Rezende Date: Fri, 25 Jun 2021 13:42:34 +0100 Subject: [PATCH 62/93] [Validator] Missing translations for Brazilian Portuguese (pt_BR) --- .../Validator/Resources/translations/validators.pt_BR.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.pt_BR.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.pt_BR.xlf index 2dbd009ccdd53..c6297ca90157a 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.pt_BR.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.pt_BR.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). Este valor não é um Número de Identificação de Títulos Internacionais (ISIN) válido. + + This value should be a valid expression. + Este valor deve ser uma expressão válida. + From e89b823c12fac5d4410dfdf0b47aace5faae8c86 Mon Sep 17 00:00:00 2001 From: Petr Duda Date: Fri, 25 Jun 2021 18:48:41 +0200 Subject: [PATCH 63/93] [Validator] Add missing Czech translations --- .../Validator/Resources/translations/validators.cs.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf index 0cf53015addb6..4d990e4d49358 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). Tato hodnota není platné mezinárodní identifikační číslo cenného papíru (ISIN). + + This value should be a valid expression. + Tato hodnota musí být platný výraz. + From e52ecc759017db010cf16991cf845a75a487a53b Mon Sep 17 00:00:00 2001 From: zors1 <78965690+zors1@users.noreply.github.com> Date: Fri, 25 Jun 2021 21:33:17 +0300 Subject: [PATCH 64/93] [Validator] Add missing translations for Russian --- .../Validator/Resources/translations/validators.ru.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf index 516fa2cf2a8bb..fe2bd4ef91c3b 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). Значение не является корректным международным идентификационным номером ценных бумаг (ISIN). + + This value should be a valid expression. + Это значение должно быть корректным выражением. + From 69781f764b2ef79d31038decf001e788e6b5b423 Mon Sep 17 00:00:00 2001 From: Vasilij Dusko Date: Sat, 26 Jun 2021 06:12:56 +0300 Subject: [PATCH 65/93] * validators.lt.xlf - added missing 100 message --- .../Validator/Resources/translations/validators.lt.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf index fef436539f296..5f0e680cc0872 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). Ši reišmė neatitinka tarptautinio vertybinių popierių identifikavimo numerio formato (ISIN). + + This value should be a valid expression. + Ši vertė turėtų būti teisinga išraiška. + From b91d488ce60a29d3562043de1eaf978135204c07 Mon Sep 17 00:00:00 2001 From: "Phil E. Taylor" Date: Thu, 24 Jun 2021 19:27:39 +0100 Subject: [PATCH 66/93] Closing tag typo --- .../DependencyInjection/Fixtures/xml/logout_delete_cookies.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/logout_delete_cookies.xml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/logout_delete_cookies.xml index 34b4a429e5fc3..6b4f60560e64f 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/logout_delete_cookies.xml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/logout_delete_cookies.xml @@ -18,5 +18,5 @@ - + From 6713ab3291b3ce41eb7ab5d702000239a460c1e7 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 26 Jun 2021 13:19:39 +0200 Subject: [PATCH 67/93] [#41846] Revert change in closing tag --- .../DependencyInjection/Fixtures/xml/logout_delete_cookies.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/logout_delete_cookies.xml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/logout_delete_cookies.xml index 6b4f60560e64f..34b4a429e5fc3 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/logout_delete_cookies.xml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/logout_delete_cookies.xml @@ -18,5 +18,5 @@ - + From b8182a8eccd57bf3f4f771a941b6faafd7516b5c Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 10 Jun 2021 22:12:04 +0200 Subject: [PATCH 68/93] PHPUnit on GitHub Actions --- .github/workflows/tests.yml | 98 +++++++++++++++---- .travis.yml | 50 ++-------- .../VarExporter/Tests/VarExporterTest.php | 18 ++-- 3 files changed, 100 insertions(+), 66 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4b4f0ad84a048..c5233c0c11a8a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -77,12 +77,19 @@ jobs: entrypoint: /bin/bash args: -c "(/opt/bitnami/openldap/bin/ldapwhoami -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony||sleep 5) && /opt/bitnami/openldap/bin/ldapadd -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif && /opt/bitnami/openldap/bin/ldapdelete -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony cn=a,ou=users,dc=symfony,dc=com" + - name: Detect Symfony version + id: symfony-versions + run: | + echo "::set-output name=symfony-major-version::$(grep "const MAJOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" + echo "::set-output name=symfony-minor-version::$(grep "const MINOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" + echo "::set-output name=symfony-version::$(grep "const MAJOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+').$(grep "const MINOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" + - name: Configure composer run: | COMPOSER_HOME="$(composer config home)" - composer self-update ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" - echo "COMPOSER_ROOT_VERSION=$(grep -m1 SYMFONY_VERSION .travis.yml | grep -o '[0-9.x]*').x-dev" >> $GITHUB_ENV + + echo "COMPOSER_ROOT_VERSION=${{ steps.symfony-versions.outputs.symfony-version }}.x-dev" >> $GITHUB_ENV - name: Install dependencies run: | @@ -115,41 +122,82 @@ jobs: # sudo rm -rf .phpunit # [ -d .phpunit.bak ] && mv .phpunit.bak .phpunit - nightly: - name: PHPUnit on PHP nightly + phpunit: + name: PHPUnit runs-on: Ubuntu-20.04 + env: + extensions: amqp,apcu,igbinary,intl,mbstring,memcached,mongodb,redis + EXCLUDE_GROUPS: benchmark,intl-data,tty,integration + + strategy: + matrix: + php: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] + fail-fast: false + steps: - name: Checkout uses: actions/checkout@v2 + - name: Configure extensions + if: "${{ matrix.php == '8.0' }}" + # TODO: memcached is excluded because of compatibility issues with PHP 8 + run: echo "extensions=amqp,apcu,igbinary,intl,mbstring,:memcached,mongodb,redis" >> $GITHUB_ENV + + - name: Configure extensions + if: "${{ matrix.php == '8.1' }}" + # Test on PHP 8.1 with bundled extensions only and allow tests to fail for now. + run: | + echo "extensions=mbstring" >> $GITHUB_ENV + echo "ALLOW_FAILURE=yes" >> $GITHUB_ENV + - name: Setup PHP uses: shivammathur/setup-php@v2 with: coverage: "none" - ini-values: "memory_limit=-1" - php-version: "8.1" + ini-values: date.timezone=Europe/Paris,memory_limit=-1,default_socket_timeout=10,session.gc_probability=0,apc.enable_cli=1 + php-version: "${{ matrix.php }}" + extensions: "${{ env.extensions }}" + tools: flex + + - name: Fake PHP version + if: "${{ matrix.php == '8.1' }}" + run: composer config platform.php 8.0.99 + + - name: Detect Symfony version + id: symfony-versions + run: | + echo "::set-output name=symfony-major-version::$(grep "const MAJOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" + echo "::set-output name=symfony-minor-version::$(grep "const MINOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" + echo "::set-output name=symfony-version::$(grep "const MAJOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+').$(grep "const MINOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" - name: Configure composer run: | COMPOSER_HOME="$(composer config home)" - composer self-update ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" - echo "COMPOSER_ROOT_VERSION=$(grep -m1 SYMFONY_VERSION .travis.yml | grep -o '[0-9.x]*').x-dev" >> $GITHUB_ENV + + echo 'COMPOSER_ROOT_VERSION=${{ steps.symfony-versions.outputs.symfony-version }}.x-dev' >> $GITHUB_ENV + echo 'SYMFONY_REQUIRE=>=${{ steps.symfony-versions.outputs.symfony-version }}' >> $GITHUB_ENV - name: Install dependencies run: | - echo "::group::fake PHP version" - composer config platform.php 8.0.99 - echo "::group::Adjust dependencies" - composer require --dev --no-update masterminds/html5:~2.7.5@dev echo "::group::composer update" + composer require --dev --no-update masterminds/html5:~2.7.5@dev composer update --no-progress --ansi echo "::endgroup::" echo "::group::install phpunit" ./phpunit install echo "::endgroup::" + - name: Patch return types + if: "${{ matrix.php == '8.0' }}" + run: | + sed -i 's/"\*\*\/Tests\/"//' composer.json + composer install --optimize-autoloader + SYMFONY_PATCH_TYPE_DECLARATIONS=force=1 php .github/patch-types.php + SYMFONY_PATCH_TYPE_DECLARATIONS=force=1 php .github/patch-types.php # ensure the script is idempotent + echo EXCLUDE_GROUPS="$EXCLUDE_GROUPS,legacy" >> $GITHUB_ENV + - name: Run tests run: | _run_tests() { @@ -157,17 +205,33 @@ jobs: echo "::group::$1" # Run the tests - ./phpunit --colors=always --exclude-group tty,benchmark,intl-data ./$1 2>&1 || ok=1 - echo ::endgroup:: + ./phpunit --colors=always --exclude-group $EXCLUDE_GROUPS ./$1 2>&1 || ok=1 + + echo "" + echo "::endgroup::" if [ $ok -ne 0 ]; then echo "::error::$1 failed" fi - # Make the tests always pass because we don't want the build to fail (yet). - return 0 - #return $ok + if [ "$ALLOW_FAILURE" = "yes" ]; then + # Make the tests always pass because we don't want the build to fail (yet). + return 0 + fi + + return $ok } export -f _run_tests find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -not -wholename '*/Bridge/PhpUnit/*' -print0 | xargs -0 -n1 dirname | sort | parallel _run_tests + + - name: Run tests with SIGCHLD enabled PHP + if: "${{ matrix.php == '7.1' }}" + run: | + mkdir build + cd build + wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/php-7.1.3-pcntl-sigchild.tar.bz2 + tar -xjf php-7.1.3-pcntl-sigchild.tar.bz2 + cd .. + + ./build/php/bin/php ./phpunit --colors=always src/Symfony/Component/Process diff --git a/.travis.yml b/.travis.yml index d0dd9bb830613..bdb4861074d66 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,8 +24,6 @@ env: matrix: include: - - php: 7.1 - env: php_extra="7.2 7.3 8.0" - php: 7.4 env: deps=high - php: 8.0 @@ -109,22 +107,13 @@ before_install: } export -f tpecl - - | - # Install sigchild-enabled PHP to test the Process component on the lowest PHP matrix line - if [[ ! $deps && $TRAVIS_PHP_VERSION = ${MIN_PHP%.*} && ! -d php-$MIN_PHP/sapi ]]; then - wget http://php.net/get/php-$MIN_PHP.tar.bz2/from/this/mirror -O - | tar -xj && - (cd php-$MIN_PHP && ./configure --enable-sigchild --enable-pcntl && make -j2) - fi - - | # php.ini configuration ( - for PHP in $TRAVIS_PHP_VERSION $php_extra; do - ([[ $PHP != 7.4 ]] && phpenv global $PHP 2>/dev/null) || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & - done + ([[ $TRAVIS_PHP_VERSION != 7.4 ]] && phpenv global $TRAVIS_PHP_VERSION 2>/dev/null) || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$TRAVIS_PHP_VERSION.tar.bz2 -O - | tar -xj) & wait ) - for PHP in $TRAVIS_PHP_VERSION $php_extra; do + for PHP in $TRAVIS_PHP_VERSION; do INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini echo date.timezone = Europe/Paris >> $INI echo memory_limit = -1 >> $INI @@ -140,7 +129,7 @@ before_install: - | # Install extra PHP extensions - for PHP in $TRAVIS_PHP_VERSION $php_extra; do + for PHP in $TRAVIS_PHP_VERSION; do export PHP=$PHP phpenv global $PHP INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini @@ -203,12 +192,6 @@ install: export COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n' | sort) fi - - | - # Skip the phpunit-bridge on bugfix-branches when $deps is empty - if [[ ! $deps && $SYMFONY_VERSION != $SYMFONY_FEATURE_BRANCH ]]; then - export COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -not -wholename '*/Bridge/PhpUnit/*' -printf '%h\n' | sort) - fi - - | # Install symfony/flex if [[ $deps = low ]]; then @@ -223,7 +206,7 @@ install: [[ $deps = high && $SYMFONY_VERSION = *.4 ]] && export LEGACY=,legacy export COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev - if [[ $deps ]]; then mv composer.json.phpunit composer.json; fi + mv composer.json.phpunit composer.json - | # phpinfo @@ -234,7 +217,7 @@ install: } export -f phpinfo - for PHP in $TRAVIS_PHP_VERSION $php_extra; do + for PHP in $TRAVIS_PHP_VERSION; do tfold phpinfo phpinfo $PHP done @@ -249,7 +232,7 @@ install: fi phpenv global $PHP rm vendor/composer/package-versions-deprecated -Rf - ([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb) + cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb tfold 'composer update' $COMPOSER_UP tfold 'phpunit install' ./phpunit install if [[ $deps = high ]]; then @@ -274,28 +257,9 @@ install: [[ ! $X ]] || (exit 1) elif [[ $deps = low ]]; then echo "$COMPONENTS" | parallel --gnu "tfold {} 'cd {} && $COMPOSER_UP --prefer-lowest --prefer-stable && $PHPUNIT_X'" - else - if [[ $PHP = 8.0* ]]; then - # add return types before running the test suite - sed -i 's/"\*\*\/Tests\/"//' composer.json - composer install --optimize-autoloader - SYMFONY_PATCH_TYPE_DECLARATIONS=force=1 php .github/patch-types.php - SYMFONY_PATCH_TYPE_DECLARATIONS=force=1 php .github/patch-types.php # ensure the script is idempotent - PHPUNIT_X="$PHPUNIT_X,legacy" - fi - - echo "$COMPONENTS" | parallel --gnu "tfold {} $PHPUNIT_X {}" - - tfold src/Symfony/Component/Console.tty $PHPUNIT src/Symfony/Component/Console --group tty - tfold src/Symfony/Bridge/Twig.tty $PHPUNIT src/Symfony/Bridge/Twig --group tty - - if [[ $PHP = ${MIN_PHP%.*} ]]; then - export PHP=$MIN_PHP - tfold src/Symfony/Component/Process.sigchild SYMFONY_DEPRECATIONS_HELPER=weak php-$MIN_PHP/sapi/cli/php ./phpunit --colors=always src/Symfony/Component/Process/ - fi fi } export -f run_tests script: - echo $TRAVIS_PHP_VERSION $php_extra | xargs -n1 bash -c '( Date: Sat, 26 Jun 2021 11:34:46 -0700 Subject: [PATCH 69/93] [Validator] Added missing spanish translation --- .../Validator/Resources/translations/validators.es.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf index 2c586ca4a2571..c73138b0ee277 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). Este valor no es un número de identificación internacional de valores (ISIN) válido. + + This value should be a valid expression. + Este valor debería ser una expresión válida. + From 78745133b39e6d340a300e0e4f79a0b4f8261309 Mon Sep 17 00:00:00 2001 From: Daniel Tiringer Date: Sat, 26 Jun 2021 22:36:12 +0200 Subject: [PATCH 70/93] Add new translation in Hungarian --- .../Validator/Resources/translations/validators.hu.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf index acd69a1009c13..a3264d5543af4 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.hu.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). Ez az érték nem egy érvényes nemzetközi értékpapír-azonosító szám (ISIN). + + This value should be a valid expression. + Ennek az értéknek érvényes kifejezésnek kell lennie. + From fa5ed19ab8a601f5832605ca57277c3c6147befb Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 25 Jun 2021 10:27:06 +0200 Subject: [PATCH 71/93] - --- .appveyor.yml | 2 +- .github/workflows/integration-tests.yml | 119 +++++++++ .github/workflows/intl-data-tests.yml | 4 +- .github/workflows/psalm.yml | 13 +- .github/workflows/tests.yml | 237 ------------------ .github/workflows/unit-tests.yml | 214 ++++++++++++++++ .travis.yml | 161 +----------- .../Handler/MemcachedSessionHandlerTest.php | 10 +- .../Tests/Command/DebugCommandTest.php | 2 +- .../Translation/Test/TranslatorTest.php | 5 +- 10 files changed, 363 insertions(+), 404 deletions(-) create mode 100644 .github/workflows/integration-tests.yml delete mode 100644 .github/workflows/tests.yml create mode 100644 .github/workflows/unit-tests.yml diff --git a/.appveyor.yml b/.appveyor.yml index 5077eea33d60a..38f7468b9a99a 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -51,7 +51,7 @@ install: - php composer.phar global require --no-progress --no-scripts --no-plugins symfony/flex - git config --global user.email "" - git config --global user.name "Symfony" - - FOR /F "tokens=* USEBACKQ" %%F IN (`bash -c "grep -m1 SYMFONY_VERSION .travis.yml | grep -o '[0-9.x]*'"`) DO (SET SYMFONY_VERSION=%%F) + - FOR /F "tokens=* USEBACKQ" %%F IN (`bash -c "grep ' VERSION = ' src/Symfony/Component/HttpKernel/Kernel.php | grep -P -o '[0-9]+\.[0-9]+'"`) DO (SET SYMFONY_VERSION=%%F) - php .github/build-packages.php HEAD^ %SYMFONY_VERSION% src\Symfony\Bridge\PhpUnit - SET "SYMFONY_REQUIRE=>=%SYMFONY_VERSION%" - SET COMPOSER_ROOT_VERSION=%SYMFONY_VERSION%.x-dev diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 0000000000000..97946446e959b --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,119 @@ +name: Integration + +on: + push: + pull_request: + +defaults: + run: + shell: bash + +jobs: + + tests: + name: Tests + runs-on: Ubuntu-20.04 + + strategy: + matrix: + php: ['7.1', '8.0'] + + services: + ldap: + image: bitnami/openldap + ports: + - 3389:3389 + env: + LDAP_ADMIN_USERNAME: admin + LDAP_ADMIN_PASSWORD: symfony + LDAP_ROOT: dc=symfony,dc=com + LDAP_PORT_NUMBER: 3389 + LDAP_USERS: a + LDAP_PASSWORDS: a + redis: + image: redis:6.0.0 + ports: + - 6379:6379 + redis-cluster: + image: grokzen/redis-cluster:5.0.4 + ports: + - 7000:7000 + - 7001:7001 + - 7002:7002 + - 7003:7003 + - 7004:7004 + - 7005:7005 + - 7006:7006 + env: + STANDALONE: 1 + redis-sentinel: + image: bitnami/redis-sentinel:6.0 + ports: + - 26379:26379 + env: + REDIS_MASTER_HOST: redis + REDIS_MASTER_SET: redis_sentinel + REDIS_SENTINEL_QUORUM: 1 + memcached: + image: memcached:1.6.5 + ports: + - 11211:11211 + rabbitmq: + image: rabbitmq:3.8.3 + ports: + - 5672:5672 + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + coverage: "none" + extensions: "memcached,redis,xsl,ldap" + ini-values: "memory_limit=-1" + php-version: "${{ matrix.php }}" + + - name: Load fixtures + uses: docker://bitnami/openldap + with: + entrypoint: /bin/bash + args: -c "(/opt/bitnami/openldap/bin/ldapwhoami -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony||sleep 5) && /opt/bitnami/openldap/bin/ldapadd -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif && /opt/bitnami/openldap/bin/ldapdelete -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony cn=a,ou=users,dc=symfony,dc=com" + + - name: Install dependencies + run: | + COMPOSER_HOME="$(composer config home)" + ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" + export COMPOSER_ROOT_VERSION=$(grep ' VERSION = ' src/Symfony/Component/HttpKernel/Kernel.php | grep -P -o '[0-9]+\.[0-9]+').x-dev + echo COMPOSER_ROOT_VERSION=$COMPOSER_ROOT_VERSION >> $GITHUB_ENV + + echo "::group::composer update" + composer update --no-progress --ansi + echo "::endgroup::" + + echo "::group::install phpunit" + ./phpunit install + echo "::endgroup::" + + - name: Run tests + run: ./phpunit --group integration -v + env: + REDIS_HOST: localhost + REDIS_CLUSTER_HOSTS: 'localhost:7000 localhost:7001 localhost:7002 localhost:7003 localhost:7004 localhost:7005' + REDIS_SENTINEL_HOSTS: 'localhost:26379' + REDIS_SENTINEL_SERVICE: redis_sentinel + MESSENGER_REDIS_DSN: redis://127.0.0.1:7006/messages + MESSENGER_AMQP_DSN: amqp://localhost/%2f/messages + MEMCACHED_HOST: localhost + LDAP_HOST: localhost + LDAP_PORT: 3389 + + #- name: Run HTTP push tests + # if: matrix.php == '8.0' + # run: | + # [ -d .phpunit ] && mv .phpunit .phpunit.bak + # wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/vulcain_0.1.3_Linux_x86_64.tar.gz -O - | tar xz && mv vulcain /usr/local/bin + # docker run --rm -e COMPOSER_ROOT_VERSION -v $(pwd):/app -v $(which composer):/usr/local/bin/composer -v $(which vulcain):/usr/local/bin/vulcain -w /app php:8.0-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push + # sudo rm -rf .phpunit + # [ -d .phpunit.bak ] && mv .phpunit.bak .phpunit diff --git a/.github/workflows/intl-data-tests.yml b/.github/workflows/intl-data-tests.yml index 0ca0322281448..f695bca201426 100644 --- a/.github/workflows/intl-data-tests.yml +++ b/.github/workflows/intl-data-tests.yml @@ -1,4 +1,4 @@ -name: Intl data tests +name: Intl data on: push: @@ -14,7 +14,7 @@ defaults: jobs: tests: - name: Tests (intl-data) + name: Tests runs-on: Ubuntu-20.04 steps: diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml index 3a2ec919a49ad..f5807849e6f3e 100644 --- a/.github/workflows/psalm.yml +++ b/.github/workflows/psalm.yml @@ -13,7 +13,7 @@ jobs: runs-on: Ubuntu-20.04 steps: - - name: Set up PHP + - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.0' @@ -29,22 +29,19 @@ jobs: - name: Checkout PR uses: actions/checkout@v2 - - name: Configure composer + - name: Install dependencies run: | COMPOSER_HOME="$(composer config home)" ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" - echo "COMPOSER_ROOT_VERSION=$(grep -m1 SYMFONY_VERSION .travis.yml | grep -o '[0-9.x]*').x-dev" >> $GITHUB_ENV - - - name: Install Psalm - run: | - echo "::group::modify composer.json" + export COMPOSER_ROOT_VERSION=$(grep ' VERSION = ' src/Symfony/Component/HttpKernel/Kernel.php | grep -P -o '[0-9]+\.[0-9]+').x-dev composer remove --no-update --no-interaction symfony/phpunit-bridge composer require --no-update psalm/phar phpunit/phpunit:^9.5 php-http/discovery psr/event-dispatcher - echo "::endgroup::" + echo "::group::composer update" composer update --no-progress --ansi git checkout composer.json echo "::endgroup::" + ./vendor/bin/psalm.phar --version - name: Generate Psalm baseline diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index c5233c0c11a8a..0000000000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,237 +0,0 @@ -name: Tests - -on: - push: - pull_request: - -jobs: - - integration: - name: Integration - runs-on: Ubuntu-20.04 - - strategy: - matrix: - php: ['7.1', '8.0'] - - services: - ldap: - image: bitnami/openldap - ports: - - 3389:3389 - env: - LDAP_ADMIN_USERNAME: admin - LDAP_ADMIN_PASSWORD: symfony - LDAP_ROOT: dc=symfony,dc=com - LDAP_PORT_NUMBER: 3389 - LDAP_USERS: a - LDAP_PASSWORDS: a - redis: - image: redis:6.0.0 - ports: - - 6379:6379 - redis-cluster: - image: grokzen/redis-cluster:5.0.4 - ports: - - 7000:7000 - - 7001:7001 - - 7002:7002 - - 7003:7003 - - 7004:7004 - - 7005:7005 - - 7006:7006 - env: - STANDALONE: 1 - redis-sentinel: - image: bitnami/redis-sentinel:6.0 - ports: - - 26379:26379 - env: - REDIS_MASTER_HOST: redis - REDIS_MASTER_SET: redis_sentinel - REDIS_SENTINEL_QUORUM: 1 - memcached: - image: memcached:1.6.5 - ports: - - 11211:11211 - rabbitmq: - image: rabbitmq:3.8.3 - ports: - - 5672:5672 - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - coverage: "none" - extensions: "memcached,redis,xsl,ldap" - ini-values: "memory_limit=-1" - php-version: "${{ matrix.php }}" - - - name: Load fixtures - uses: docker://bitnami/openldap - with: - entrypoint: /bin/bash - args: -c "(/opt/bitnami/openldap/bin/ldapwhoami -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony||sleep 5) && /opt/bitnami/openldap/bin/ldapadd -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif && /opt/bitnami/openldap/bin/ldapdelete -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony cn=a,ou=users,dc=symfony,dc=com" - - - name: Detect Symfony version - id: symfony-versions - run: | - echo "::set-output name=symfony-major-version::$(grep "const MAJOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" - echo "::set-output name=symfony-minor-version::$(grep "const MINOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" - echo "::set-output name=symfony-version::$(grep "const MAJOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+').$(grep "const MINOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" - - - name: Configure composer - run: | - COMPOSER_HOME="$(composer config home)" - ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" - - echo "COMPOSER_ROOT_VERSION=${{ steps.symfony-versions.outputs.symfony-version }}.x-dev" >> $GITHUB_ENV - - - name: Install dependencies - run: | - echo "::group::composer update" - composer update --no-progress --ansi - echo "::endgroup::" - echo "::group::install phpunit" - ./phpunit install - echo "::endgroup::" - - - name: Run tests - run: ./phpunit --group integration -v - env: - REDIS_HOST: localhost - REDIS_CLUSTER_HOSTS: 'localhost:7000 localhost:7001 localhost:7002 localhost:7003 localhost:7004 localhost:7005' - REDIS_SENTINEL_HOSTS: 'localhost:26379' - REDIS_SENTINEL_SERVICE: redis_sentinel - MESSENGER_REDIS_DSN: redis://127.0.0.1:7006/messages - MESSENGER_AMQP_DSN: amqp://localhost/%2f/messages - MEMCACHED_HOST: localhost - LDAP_HOST: localhost - LDAP_PORT: 3389 - - #- name: Run HTTP push tests - # if: matrix.php == '8.0' - # run: | - # [ -d .phpunit ] && mv .phpunit .phpunit.bak - # wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/vulcain_0.1.3_Linux_x86_64.tar.gz -O - | tar xz && mv vulcain /usr/local/bin - # docker run --rm -e COMPOSER_ROOT_VERSION -v $(pwd):/app -v $(which composer):/usr/local/bin/composer -v $(which vulcain):/usr/local/bin/vulcain -w /app php:8.0-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push - # sudo rm -rf .phpunit - # [ -d .phpunit.bak ] && mv .phpunit.bak .phpunit - - phpunit: - name: PHPUnit - runs-on: Ubuntu-20.04 - - env: - extensions: amqp,apcu,igbinary,intl,mbstring,memcached,mongodb,redis - EXCLUDE_GROUPS: benchmark,intl-data,tty,integration - - strategy: - matrix: - php: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] - fail-fast: false - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Configure extensions - if: "${{ matrix.php == '8.0' }}" - # TODO: memcached is excluded because of compatibility issues with PHP 8 - run: echo "extensions=amqp,apcu,igbinary,intl,mbstring,:memcached,mongodb,redis" >> $GITHUB_ENV - - - name: Configure extensions - if: "${{ matrix.php == '8.1' }}" - # Test on PHP 8.1 with bundled extensions only and allow tests to fail for now. - run: | - echo "extensions=mbstring" >> $GITHUB_ENV - echo "ALLOW_FAILURE=yes" >> $GITHUB_ENV - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - coverage: "none" - ini-values: date.timezone=Europe/Paris,memory_limit=-1,default_socket_timeout=10,session.gc_probability=0,apc.enable_cli=1 - php-version: "${{ matrix.php }}" - extensions: "${{ env.extensions }}" - tools: flex - - - name: Fake PHP version - if: "${{ matrix.php == '8.1' }}" - run: composer config platform.php 8.0.99 - - - name: Detect Symfony version - id: symfony-versions - run: | - echo "::set-output name=symfony-major-version::$(grep "const MAJOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" - echo "::set-output name=symfony-minor-version::$(grep "const MINOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" - echo "::set-output name=symfony-version::$(grep "const MAJOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+').$(grep "const MINOR_VERSION =" ./src/Symfony/Component/HttpKernel/Kernel.php | egrep -o '[0-9]+')" - - - name: Configure composer - run: | - COMPOSER_HOME="$(composer config home)" - ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" - - echo 'COMPOSER_ROOT_VERSION=${{ steps.symfony-versions.outputs.symfony-version }}.x-dev' >> $GITHUB_ENV - echo 'SYMFONY_REQUIRE=>=${{ steps.symfony-versions.outputs.symfony-version }}' >> $GITHUB_ENV - - - name: Install dependencies - run: | - echo "::group::composer update" - composer require --dev --no-update masterminds/html5:~2.7.5@dev - composer update --no-progress --ansi - echo "::endgroup::" - echo "::group::install phpunit" - ./phpunit install - echo "::endgroup::" - - - name: Patch return types - if: "${{ matrix.php == '8.0' }}" - run: | - sed -i 's/"\*\*\/Tests\/"//' composer.json - composer install --optimize-autoloader - SYMFONY_PATCH_TYPE_DECLARATIONS=force=1 php .github/patch-types.php - SYMFONY_PATCH_TYPE_DECLARATIONS=force=1 php .github/patch-types.php # ensure the script is idempotent - echo EXCLUDE_GROUPS="$EXCLUDE_GROUPS,legacy" >> $GITHUB_ENV - - - name: Run tests - run: | - _run_tests() { - ok=0 - echo "::group::$1" - - # Run the tests - ./phpunit --colors=always --exclude-group $EXCLUDE_GROUPS ./$1 2>&1 || ok=1 - - echo "" - echo "::endgroup::" - - if [ $ok -ne 0 ]; then - echo "::error::$1 failed" - fi - - if [ "$ALLOW_FAILURE" = "yes" ]; then - # Make the tests always pass because we don't want the build to fail (yet). - return 0 - fi - - return $ok - } - export -f _run_tests - - find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -not -wholename '*/Bridge/PhpUnit/*' -print0 | xargs -0 -n1 dirname | sort | parallel _run_tests - - - name: Run tests with SIGCHLD enabled PHP - if: "${{ matrix.php == '7.1' }}" - run: | - mkdir build - cd build - wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/php-7.1.3-pcntl-sigchild.tar.bz2 - tar -xjf php-7.1.3-pcntl-sigchild.tar.bz2 - cd .. - - ./build/php/bin/php ./phpunit --colors=always src/Symfony/Component/Process diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 0000000000000..b7fd0de88c307 --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,214 @@ +name: PHPUnit + +on: + push: + pull_request: + +defaults: + run: + shell: bash + +jobs: + + tests: + name: Tests + runs-on: Ubuntu-20.04 + + env: + extensions: amqp,apcu,igbinary,intl,mbstring,memcached,mongodb,redis + + strategy: + matrix: + include: + - php: '7.2' + - php: '8.0' + - php: '7.4' + mode: high-deps + - php: '8.0' + mode: low-deps + - php: '8.1' + mode: experimental + fail-fast: false + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 2 + + - name: Configure for PHP 8.1 + if: "${{ matrix.php == '8.1' }}" + run: | + echo "extensions=mbstring" >> $GITHUB_ENV + composer config platform.php 8.0.99 + composer require --dev --no-update masterminds/html5:~2.7.5@dev + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + coverage: "none" + ini-values: date.timezone=Europe/Paris,memory_limit=-1,default_socket_timeout=10,session.gc_probability=0,apc.enable_cli=1 + php-version: "${{ matrix.php }}" + extensions: "${{ env.extensions }}" + tools: flex + + - name: Configure environment + run: | + git config --global user.email "" + git config --global user.name "Symfony" + git config --global init.defaultBranch main + + COMPOSER_HOME="$(composer config home)" + ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" + + echo COLUMNS=120 >> $GITHUB_ENV + echo PHPUNIT="$(readlink -f ./phpunit) --exclude-group tty,benchmark,intl-data" >> $GITHUB_ENV + echo COMPOSER_UP='composer update --no-progress --ansi' >> $GITHUB_ENV + + SYMFONY_VERSIONS=$(git ls-remote -q --heads | cut -f2 | grep -o '/[1-9][0-9]*\.[0-9].*' | sort -V) + SYMFONY_VERSION=$(grep ' VERSION = ' src/Symfony/Component/HttpKernel/Kernel.php | grep -P -o '[0-9]+\.[0-9]+') + SYMFONY_FEATURE_BRANCH=$(curl -s https://flex.symfony.com/versions.json | jq -r '."dev-name"') + + # Install the phpunit-bridge from a PR if required + # + # To run a PR with a patched phpunit-bridge, first submit the patch for the + # phpunit-bridge as a separate PR against the next feature-branch then + # uncomment and update the following line with that PR number + #SYMFONY_PHPUNIT_BRIDGE_PR=32886 + + if [[ $SYMFONY_PHPUNIT_BRIDGE_PR ]]; then + git fetch --depth=2 origin refs/pull/$SYMFONY_PHPUNIT_BRIDGE_PR/head + git rm -rq src/Symfony/Bridge/PhpUnit + git checkout -q FETCH_HEAD -- src/Symfony/Bridge/PhpUnit + SYMFONY_PHPUNIT_BRIDGE_REF=$(curl -s https://api.github.com/repos/symfony/symfony/pulls/$SYMFONY_PHPUNIT_BRIDGE_PR | jq -r .base.ref) + sed -i 's/"symfony\/phpunit-bridge": ".*"/"symfony\/phpunit-bridge": "'$SYMFONY_PHPUNIT_BRIDGE_REF'.x@dev"/' composer.json + rm -rf .phpunit + fi + + # Create local composer packages for each patched components and reference them in composer.json files when cross-testing components + if [[ ! "${{ matrix.mode }}" = *-deps ]]; then + php .github/build-packages.php HEAD^ $SYMFONY_VERSION src/Symfony/Bridge/PhpUnit + else + echo SYMFONY_DEPRECATIONS_HELPER=weak >> $GITHUB_ENV + cp composer.json composer.json.orig + echo -e '{\n"require":{'"$(grep phpunit-bridge composer.json)"'"php":"*"},"minimum-stability":"dev"}' > composer.json + php .github/build-packages.php HEAD^ $SYMFONY_VERSION $(find src/Symfony -mindepth 2 -type f -name composer.json -printf '%h\n') + mv composer.json composer.json.phpunit + mv composer.json.orig composer.json + fi + if [[ $SYMFONY_PHPUNIT_BRIDGE_PR ]]; then + git rm -fq -- src/Symfony/Bridge/PhpUnit/composer.json + git diff --staged -- src/Symfony/Bridge/PhpUnit/ | git apply -R --index + fi + + # For the highest branch, in high-deps mode, the version before it is checked out and tested with the locally patched components + if [[ "${{ matrix.mode }}" = high-deps && $SYMFONY_VERSION = $(echo "$SYMFONY_VERSIONS" | tail -n 1 | sed s/.//) ]]; then + echo FLIP='🙃' >> $GITHUB_ENV + SYMFONY_VERSION=$(echo "$SYMFONY_VERSIONS" | grep -FB1 /$SYMFONY_VERSION | head -n 1 | sed s/.//) + git fetch --depth=2 origin $SYMFONY_VERSION + git checkout -m FETCH_HEAD + echo COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h ') >> $GITHUB_ENV + fi + + # Skip the phpunit-bridge on bugfix-branches when not in *-deps mode + if [[ ! "${{ matrix.mode }}" = *-deps && $SYMFONY_VERSION != $SYMFONY_FEATURE_BRANCH ]]; then + echo COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -not -wholename '*/Bridge/PhpUnit/*' -printf '%h ') >> $GITHUB_ENV + else + echo COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h ') >> $GITHUB_ENV + fi + + # Legacy tests are skipped when deps=high and when the current branch version has not the same major version number as the next one + [[ "${{ matrix.mode }}" = high-deps && $SYMFONY_VERSION = *.4 ]] && echo LEGACY=,legacy >> $GITHUB_ENV || true + + echo SYMFONY_VERSION=$SYMFONY_VERSION >> $GITHUB_ENV + echo COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev >> $GITHUB_ENV + echo SYMFONY_REQUIRE=">=$([ '${{ matrix.mode }}' = low-deps ] && echo 3.4 || echo $SYMFONY_VERSION)" >> $GITHUB_ENV + [[ "${{ matrix.mode }}" = *-deps ]] && mv composer.json.phpunit composer.json || true + + - name: Install dependencies + run: | + echo "::group::composer update" + $COMPOSER_UP + echo "::endgroup::" + + echo "::group::install phpunit" + ./phpunit install + echo "::endgroup::" + + - name: Patch return types + if: "${{ matrix.php == '8.0' && ! matrix.mode }}" + run: | + sed -i 's/"\*\*\/Tests\/"//' composer.json + composer install --optimize-autoloader + SYMFONY_PATCH_TYPE_DECLARATIONS=force=1 php .github/patch-types.php + SYMFONY_PATCH_TYPE_DECLARATIONS=force=1 php .github/patch-types.php # ensure the script is idempotent + echo PHPUNIT="$PHPUNIT,legacy" >> $GITHUB_ENV + + - name: Run tests + run: | + _run_tests() { + local ok=0 + local title="$1 $FLIP" + local start=$(date -u +%s) + OUTPUT=$(bash -xc "$2" 2>&1) || ok=1 + local end=$(date -u +%s) + + if [[ $ok -ne 0 ]]; then + printf "\n%-70s%10s\n" $title $(($end-$start))s + echo "$OUTPUT" + echo -e "\n\\e[41mKO\\e[0m $title\\n" + else + printf "::group::%-68s%10s\n" $title $(($end-$start))s + echo "$OUTPUT" + echo -e "\n\\e[32mOK\\e[0m $title\\n\\n::endgroup::" + fi + + [[ "${{ matrix.mode }}" = experimental ]] || (exit $ok) + } + export -f _run_tests + + if [[ ! "${{ matrix.mode }}" = *-deps ]]; then + echo "$COMPONENTS" | xargs -n1 | parallel -j +3 "_run_tests {} '$PHPUNIT {}'" + + exit 0 + fi + + (cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb) + + if [[ "${{ matrix.mode }}" = low-deps ]]; then + echo "$COMPONENTS" | xargs -n1 | parallel -j +3 "_run_tests {} 'cd {} && $COMPOSER_UP --prefer-lowest --prefer-stable && $PHPUNIT'" + + exit 0 + fi + + # matrix.mode = high-deps + echo "$COMPONENTS" | xargs -n1 | parallel -j +3 "_run_tests {} 'cd {} && $COMPOSER_UP && $PHPUNIT$LEGACY'" || X=1 + + (cd src/Symfony/Component/HttpFoundation; mv composer.bak composer.json) + COMPONENTS=$(git diff --name-only src/ | grep composer.json || true) + + if [[ $COMPONENTS && $SYMFONY_VERSION = *.4 ]]; then + export FLIP='🙃' + SYMFONY_VERSION=$(echo $SYMFONY_VERSION | awk '{print $1 - 1}') + echo -e "\\n\\e[33;1mChecking out Symfony $SYMFONY_VERSION and running tests with patched components as deps\\e[0m" + export COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev + export SYMFONY_REQUIRE=">=$SYMFONY_VERSION" + git fetch --depth=2 origin $SYMFONY_VERSION + git checkout -m FETCH_HEAD + COMPONENTS=$(echo "$COMPONENTS" | xargs dirname | xargs -n1 -I{} bash -c "[ -e '{}/phpunit.xml.dist' ] && echo '{}'" | sort || true) + (cd src/Symfony/Component/HttpFoundation; composer require --dev --no-update mongodb/mongodb) + [[ ! $COMPONENTS ]] || echo "$COMPONENTS" | parallel -j +3 "_run_tests {} 'cd {} && rm composer.lock vendor/ -Rf && $COMPOSER_UP && $PHPUNIT$LEGACY'" || X=1 + fi + + [[ ! $X ]] || (exit 1) + + - name: Run tests with SIGCHLD enabled PHP + if: "${{ matrix.php == '7.1' }}" + run: | + mkdir build + cd build + wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/php-7.1.3-pcntl-sigchild.tar.bz2 + tar -xjf php-7.1.3-pcntl-sigchild.tar.bz2 + cd .. + + ./build/php/bin/php ./phpunit --colors=always src/Symfony/Component/Process diff --git a/.travis.yml b/.travis.yml index bdb4861074d66..f6abaa2eadd8e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,37 +3,22 @@ language: php dist: bionic git: - depth: 2 + depth: 1 addons: apt_packages: - parallel - - language-pack-fr-base - zookeeperd - libzookeeper-mt-dev - - librabbitmq-dev - - libsodium-dev - - libtidy-dev - -env: - global: - - SYMFONY_VERSION=4.4 - - MIN_PHP=7.1.3 - - SYMFONY_PROCESS_PHP_TEST_BINARY=~/.phpenv/shims/php - - SYMFONY_PHPUNIT_DISABLE_RESULT_CACHE=1 matrix: include: - - php: 7.4 - env: deps=high - - php: 8.0 - env: deps=low + - php: 7.3 fast_finish: true cache: directories: - .phpunit - - php-$MIN_PHP - ~/php-ext before_install: @@ -43,14 +28,6 @@ before_install: stty cols 120 sudo sed -i 's/127\.0\.1\.1 localhost/127.0.0.1 localhost/' /etc/hosts cp .github/composer-config.json "$(composer config home)/config.json" - git config --global user.email "" - git config --global user.name "Symfony" - export PHPUNIT=$(readlink -f ./phpunit) - export PHPUNIT_X="$PHPUNIT --exclude-group tty,benchmark,intl-data" - export COMPOSER_UP='composer update --no-progress --ansi' - export COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n' | sort) - export SYMFONY_FEATURE_BRANCH=$(curl -s https://flex.symfony.com/versions.json | jq -r '."dev-name"') - export SYMFONY_VERSIONS=$(git ls-remote -q --heads | cut -f2 | grep -o '/[1-9][0-9]*\.[0-9].*' | sort -V) nanoseconds () { local cmd="date" @@ -109,11 +86,7 @@ before_install: - | # php.ini configuration - ( - ([[ $TRAVIS_PHP_VERSION != 7.4 ]] && phpenv global $TRAVIS_PHP_VERSION 2>/dev/null) || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$TRAVIS_PHP_VERSION.tar.bz2 -O - | tar -xj) & - wait - ) - for PHP in $TRAVIS_PHP_VERSION; do + for PHP in $TRAVIS_PHP_VERSION $php_extra; do INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini echo date.timezone = Europe/Paris >> $INI echo memory_limit = -1 >> $INI @@ -129,7 +102,7 @@ before_install: - | # Install extra PHP extensions - for PHP in $TRAVIS_PHP_VERSION; do + for PHP in $TRAVIS_PHP_VERSION $php_extra; do export PHP=$PHP phpenv global $PHP INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini @@ -139,127 +112,15 @@ before_install: if [[ $PHP != 8.* ]]; then tfold ext.zookeeper tpecl zookeeper-0.7.2 zookeeper.so $INI fi - tfold ext.memcached tpecl memcached-3.1.5 memcached.so $INI - tfold ext.amqp tpecl amqp-1.11.0beta amqp.so $INI - tfold ext.apcu tpecl apcu-5.1.19 apcu.so $INI - tfold ext.igbinary tpecl igbinary-3.1.6 igbinary.so $INI - tfold ext.redis tpecl redis-5.2.3 redis.so $INI "no" - tfold ext.mongodb tpecl mongodb-1.10.0alpha1 mongodb.so $INI done install: - - | - # Install the phpunit-bridge from a PR if required - # - # To run a PR with a patched phpunit-bridge, first submit the patch for the - # phpunit-bridge as a separate PR against the next feature-branch then - # uncomment and update the following line with that PR number - #SYMFONY_PHPUNIT_BRIDGE_PR=32886 - - if [[ $SYMFONY_PHPUNIT_BRIDGE_PR ]]; then - git fetch --depth=2 origin refs/pull/$SYMFONY_PHPUNIT_BRIDGE_PR/head - git rm -rq src/Symfony/Bridge/PhpUnit - git checkout -q FETCH_HEAD -- src/Symfony/Bridge/PhpUnit - SYMFONY_PHPUNIT_BRIDGE_REF=$(curl -s https://api.github.com/repos/symfony/symfony/pulls/$SYMFONY_PHPUNIT_BRIDGE_PR | jq -r .base.ref) - sed -i 's/"symfony\/phpunit-bridge": ".*"/"symfony\/phpunit-bridge": "'$SYMFONY_PHPUNIT_BRIDGE_REF'.x@dev"/' composer.json - rm -rf .phpunit - fi - - - | - # Create local composer packages for each patched components and reference them in composer.json files when cross-testing components - if [[ ! $deps ]]; then - php .github/build-packages.php HEAD^ $SYMFONY_VERSION src/Symfony/Bridge/PhpUnit - else - export SYMFONY_DEPRECATIONS_HELPER=weak && - cp composer.json composer.json.orig && - echo -e '{\n"require":{'"$(grep phpunit-bridge composer.json)"'"php":"*"},"minimum-stability":"dev"}' > composer.json && - php .github/build-packages.php HEAD^ $SYMFONY_VERSION $(find src/Symfony -mindepth 2 -type f -name composer.json -printf '%h\n' | sort) && - mv composer.json composer.json.phpunit && - mv composer.json.orig composer.json - fi - if [[ $SYMFONY_PHPUNIT_BRIDGE_PR ]]; then - git rm -fq -- src/Symfony/Bridge/PhpUnit/composer.json - git diff --staged -- src/Symfony/Bridge/PhpUnit/ | git apply -R --index - fi - - - | - # For the highest branch, when deps=high, the version before it is checked out and tested with the locally patched components - if [[ $deps = high && $SYMFONY_VERSION = $(echo "$SYMFONY_VERSIONS" | tail -n 1 | sed s/.//) ]]; then - export FLIP='^' - export SYMFONY_VERSION=$(echo "$SYMFONY_VERSIONS" | grep -FB1 /$SYMFONY_VERSION | head -n 1 | sed s/.//) && - git fetch --depth=2 origin $SYMFONY_VERSION && - git checkout -m FETCH_HEAD && - export COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n' | sort) - fi - - - | - # Install symfony/flex - if [[ $deps = low ]]; then - export SYMFONY_REQUIRE='>=2.3' - else - export SYMFONY_REQUIRE=">=$SYMFONY_VERSION" - fi - composer global require --no-progress --no-scripts --no-plugins symfony/flex - - - | - # Legacy tests are skipped when deps=high and when the current branch version has not the same major version number as the next one - [[ $deps = high && $SYMFONY_VERSION = *.4 ]] && export LEGACY=,legacy - - export COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev - mv composer.json.phpunit composer.json - - - | - # phpinfo - phpinfo() { - phpenv global $1 - php -r 'foreach (get_loaded_extensions() as $extension) echo $extension . " " . phpversion($extension) . PHP_EOL;' - php -i - } - export -f phpinfo - - for PHP in $TRAVIS_PHP_VERSION; do - tfold phpinfo phpinfo $PHP - done - - - | - run_tests () { - set -e - export PHP=$1 - - if [[ $PHP != 8.0* && $PHP != $TRAVIS_PHP_VERSION && $TRAVIS_PULL_REQUEST != false ]]; then - echo -e "\\n\\e[33;1mIntermediate PHP version $PHP is skipped for pull requests.\\e[0m" - return - fi - phpenv global $PHP - rm vendor/composer/package-versions-deprecated -Rf - cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb - tfold 'composer update' $COMPOSER_UP - tfold 'phpunit install' ./phpunit install - if [[ $deps = high ]]; then - echo "$COMPONENTS" | parallel --gnu "tfold {} 'cd {} && $COMPOSER_UP && $PHPUNIT_X$LEGACY'" || X=1 - (cd src/Symfony/Component/HttpFoundation; mv composer.bak composer.json) - COMPONENTS=$(git diff --name-only src/ | grep composer.json || true) - - if [[ $COMPONENTS && $SYMFONY_VERSION = *.4 && $TRAVIS_PULL_REQUEST != false ]]; then - export FLIP='^' - SYMFONY_VERSION=$(echo $SYMFONY_VERSION | awk '{print $1 - 1}') - echo -e "\\n\\e[33;1mChecking out Symfony $SYMFONY_VERSION and running tests with patched components as deps\\e[0m" - export COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev - export SYMFONY_REQUIRE=">=$SYMFONY_VERSION" - git fetch --depth=2 origin $SYMFONY_VERSION - git checkout -m FETCH_HEAD - COMPONENTS=$(echo "$COMPONENTS" | xargs dirname | xargs -n1 -I{} bash -c "[ -e '{}/phpunit.xml.dist' ] && echo '{}'" | sort) - (cd src/Symfony/Component/HttpFoundation; composer require --dev --no-update mongodb/mongodb) - [[ ! $COMPONENTS ]] || tfold 'phpunit install' SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 ./phpunit install - [[ ! $COMPONENTS ]] || echo "$COMPONENTS" | parallel --gnu "tfold {} 'cd {} && rm composer.lock vendor/ -Rf && $COMPOSER_UP && $PHPUNIT_X$LEGACY'" || X=1 - fi - - [[ ! $X ]] || (exit 1) - elif [[ $deps = low ]]; then - echo "$COMPONENTS" | parallel --gnu "tfold {} 'cd {} && $COMPOSER_UP --prefer-lowest --prefer-stable && $PHPUNIT_X'" - fi - } - export -f run_tests + - export COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -not -wholename '*/Bridge/PhpUnit/*' -printf '%h\n' | sort) + - export COMPOSER_ROOT_VERSION=$(grep ' VERSION = ' src/Symfony/Component/HttpKernel/Kernel.php | grep -P -o '[0-9]+\.[0-9]+').x-dev + - composer update --no-progress --ansi + - ./phpunit install script: - run_tests $TRAVIS_PHP_VERSION + - echo "$COMPONENTS" | parallel --gnu "tfold {} ./phpunit --exclude-group tty,benchmark,intl-data {}" + - tfold src/Symfony/Component/Console.tty ./phpunit src/Symfony/Component/Console --group tty + - tfold src/Symfony/Bridge/Twig.tty ./phpunit src/Symfony/Bridge/Twig --group tty diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php index 2663fba6b4b69..a7f7e8f81751e 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php @@ -38,7 +38,15 @@ protected function setUp(): void $this->markTestSkipped('Tests can only be run with memcached extension 2.1.0 or lower, or 3.0.0b1 or higher'); } - $this->memcached = $this->createMock(\Memcached::class); + $r = new \ReflectionClass(\Memcached::class); + $methodsToMock = array_map(function ($m) { return $m->name; }, $r->getMethods(\ReflectionMethod::IS_PUBLIC)); + $methodsToMock = array_diff($methodsToMock, ['getDelayed','getDelayedByKey']); + + $this->memcached = $this->getMockBuilder(\Memcached::class) + ->disableOriginalConstructor() + ->setMethods($methodsToMock) + ->getMock(); + $this->storage = new MemcachedSessionHandler( $this->memcached, ['prefix' => self::PREFIX, 'expiretime' => self::TTL] diff --git a/src/Symfony/Component/Messenger/Tests/Command/DebugCommandTest.php b/src/Symfony/Component/Messenger/Tests/Command/DebugCommandTest.php index 790f1b462026c..90fcdb3311649 100644 --- a/src/Symfony/Component/Messenger/Tests/Command/DebugCommandTest.php +++ b/src/Symfony/Component/Messenger/Tests/Command/DebugCommandTest.php @@ -34,7 +34,7 @@ protected function setUp(): void protected function tearDown(): void { - putenv('COLUMNS='); + putenv('COLUMNS'); } public function testOutput() diff --git a/src/Symfony/Contracts/Translation/Test/TranslatorTest.php b/src/Symfony/Contracts/Translation/Test/TranslatorTest.php index 89d9fc06d159b..196ec1859f812 100644 --- a/src/Symfony/Contracts/Translation/Test/TranslatorTest.php +++ b/src/Symfony/Contracts/Translation/Test/TranslatorTest.php @@ -35,6 +35,7 @@ class TranslatorTest extends TestCase protected function setUp(): void { $this->defaultLocale = \Locale::getDefault(); + \Locale::setDefault('en'); } protected function tearDown(): void @@ -65,7 +66,6 @@ public function testTrans($expected, $id, $parameters) public function testTransChoiceWithExplicitLocale($expected, $id, $number) { $translator = $this->getTranslator(); - $translator->setLocale('en'); $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number])); } @@ -75,8 +75,6 @@ public function testTransChoiceWithExplicitLocale($expected, $id, $number) */ public function testTransChoiceWithDefaultLocale($expected, $id, $number) { - \Locale::setDefault('en'); - $translator = $this->getTranslator(); $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number])); @@ -85,7 +83,6 @@ public function testTransChoiceWithDefaultLocale($expected, $id, $number) public function testGetSetLocale() { $translator = $this->getTranslator(); - $translator->setLocale('en'); $this->assertEquals('en', $translator->getLocale()); } From 5b56d05ce180b601e9eac4bc11a7ab5279cf5cac Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Jun 2021 11:17:32 +0200 Subject: [PATCH 72/93] - --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f6abaa2eadd8e..bad53d76b76c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ addons: - parallel - zookeeperd - libzookeeper-mt-dev + - libsodium-dev matrix: include: From 9a20e25ba944cb5b81831adbb51ff5bfda108e35 Mon Sep 17 00:00:00 2001 From: Vasilij Dusko Date: Sun, 27 Jun 2021 08:52:30 +0300 Subject: [PATCH 73/93] * validators.(ru|lt).xlf - wrong trans-unit ids --- .../Resources/translations/validators.lt.xlf | 14 +++++++------- .../Resources/translations/validators.ru.xlf | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf index 5f0e680cc0872..eeb0727349573 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf @@ -131,25 +131,25 @@ Ši reikšmė turi būti skaičius. - This value is not a valid country. - Ši reikšmė nėra tinkama šalis. - - This file is not a valid image. Byla nėra paveikslėlis. - + This is not a valid IP address. Ši reikšmė nėra tinkamas IP adresas. - + This value is not a valid language. Ši reikšmė nėra tinkama kalba. - + This value is not a valid locale. Ši reikšmė nėra tinkama lokalė. + + This value is not a valid country. + Ši reikšmė nėra tinkama šalis. + This value is already used. Ši reikšmė jau yra naudojama. diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf index fe2bd4ef91c3b..2c7a0444ef51e 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf @@ -131,25 +131,25 @@ Значение должно быть числом. - This value is not a valid country. - Значение не является допустимой страной. - - This file is not a valid image. Файл не является допустимым форматом изображения. - + This is not a valid IP address. Значение не является допустимым IP адресом. - + This value is not a valid language. Значение не является допустимым языком. - + This value is not a valid locale. Значение не является допустимой локалью. + + This value is not a valid country. + Значение не является допустимой страной. + This value is already used. Это значение уже используется. From bb59651e4804fe8eb934ddb56afe1505fa768d95 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Jun 2021 13:30:21 +0200 Subject: [PATCH 74/93] Fix CI --- .github/workflows/unit-tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index b7fd0de88c307..5aa50094bff97 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -203,12 +203,12 @@ jobs: [[ ! $X ]] || (exit 1) - name: Run tests with SIGCHLD enabled PHP - if: "${{ matrix.php == '7.1' }}" + if: "${{ matrix.php == '7.2' && ! matrix.mode }}" run: | mkdir build cd build - wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/php-7.1.3-pcntl-sigchild.tar.bz2 - tar -xjf php-7.1.3-pcntl-sigchild.tar.bz2 + wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/php-7.2.5-pcntl-sigchild.tar.bz2 + tar -xjf php-7.2.5-pcntl-sigchild.tar.bz2 cd .. ./build/php/bin/php ./phpunit --colors=always src/Symfony/Component/Process From aecaf6b49d2db03c17f3f95a1d9a1bc6777f012e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Jun 2021 13:47:28 +0200 Subject: [PATCH 75/93] [travis] raise concurrency --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bad53d76b76c2..065a71677ff0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -122,6 +122,6 @@ install: - ./phpunit install script: - - echo "$COMPONENTS" | parallel --gnu "tfold {} ./phpunit --exclude-group tty,benchmark,intl-data {}" + - echo "$COMPONENTS" | parallel --gnu -j +3 "tfold {} ./phpunit --exclude-group tty,benchmark,intl-data {}" - tfold src/Symfony/Component/Console.tty ./phpunit src/Symfony/Component/Console --group tty - tfold src/Symfony/Bridge/Twig.tty ./phpunit src/Symfony/Bridge/Twig --group tty From c2e4ac613ca5dfcc60cc56f492ee04b52f010e4d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Jun 2021 13:58:40 +0200 Subject: [PATCH 76/93] - --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 5aa50094bff97..6baa73e8fc02d 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -61,7 +61,6 @@ jobs: COMPOSER_HOME="$(composer config home)" ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" - echo COLUMNS=120 >> $GITHUB_ENV echo PHPUNIT="$(readlink -f ./phpunit) --exclude-group tty,benchmark,intl-data" >> $GITHUB_ENV echo COMPOSER_UP='composer update --no-progress --ansi' >> $GITHUB_ENV @@ -150,6 +149,7 @@ jobs: local ok=0 local title="$1 $FLIP" local start=$(date -u +%s) + export COLUMNS=120 OUTPUT=$(bash -xc "$2" 2>&1) || ok=1 local end=$(date -u +%s) From 0ef5ec8f8101750873e59f2f9e7313c884e4c48a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Jun 2021 14:04:45 +0200 Subject: [PATCH 77/93] - --- .github/workflows/intl-data-tests.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/intl-data-tests.yml b/.github/workflows/intl-data-tests.yml index f695bca201426..a449e9c91fc73 100644 --- a/.github/workflows/intl-data-tests.yml +++ b/.github/workflows/intl-data-tests.yml @@ -36,9 +36,15 @@ jobs: - name: Install dependencies run: | + COMPOSER_HOME="$(composer config home)" + ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" + export COMPOSER_ROOT_VERSION=$(grep ' VERSION = ' src/Symfony/Component/HttpKernel/Kernel.php | grep -P -o '[0-9]+\.[0-9]+').x-dev + echo COMPOSER_ROOT_VERSION=$COMPOSER_ROOT_VERSION >> $GITHUB_ENV + echo "::group::composer update" - composer update --no-progress --no-suggest --ansi + composer update --no-progress --ansi echo "::endgroup::" + echo "::group::install phpunit" ./phpunit install echo "::endgroup::" From fdb8b9e64cac2fa782d2a2ffe44a9c84c6d27990 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Jun 2021 14:09:48 +0200 Subject: [PATCH 78/93] [travis] keep compiling sodium --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 065a71677ff0c..c07e7cc6775b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,6 @@ addons: - parallel - zookeeperd - libzookeeper-mt-dev - - libsodium-dev matrix: include: @@ -107,9 +106,6 @@ before_install: export PHP=$PHP phpenv global $PHP INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini - if ! php --ri sodium > /dev/null; then - tfold ext.libsodium tpecl libsodium sodium.so $INI - fi if [[ $PHP != 8.* ]]; then tfold ext.zookeeper tpecl zookeeper-0.7.2 zookeeper.so $INI fi From 058168e2ed0e45027f20e3d59da2be42d3155aa8 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Jun 2021 14:13:22 +0200 Subject: [PATCH 79/93] [gha] Define COLUMNS properly This reverts commit c2e4ac613ca5dfcc60cc56f492ee04b52f010e4d. --- .github/workflows/unit-tests.yml | 2 +- .../Console/Descriptor/TextDescriptorTest.php | 7 +++++-- .../UserPasswordEncoderCommandTest.php | 17 ++++++++++++----- .../Console/Descriptor/JsonDescriptorTest.php | 7 +++++-- .../Console/Descriptor/TextDescriptorTest.php | 7 +++++-- .../Tests/Command/DebugCommandTest.php | 5 ++++- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 6baa73e8fc02d..5aa50094bff97 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -61,6 +61,7 @@ jobs: COMPOSER_HOME="$(composer config home)" ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" + echo COLUMNS=120 >> $GITHUB_ENV echo PHPUNIT="$(readlink -f ./phpunit) --exclude-group tty,benchmark,intl-data" >> $GITHUB_ENV echo COMPOSER_UP='composer update --no-progress --ansi' >> $GITHUB_ENV @@ -149,7 +150,6 @@ jobs: local ok=0 local title="$1 $FLIP" local start=$(date -u +%s) - export COLUMNS=120 OUTPUT=$(bash -xc "$2" 2>&1) || ok=1 local end=$(date -u +%s) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/TextDescriptorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/TextDescriptorTest.php index 4ed0446320c1c..5a57a6f0c2423 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/TextDescriptorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/TextDescriptorTest.php @@ -15,14 +15,17 @@ class TextDescriptorTest extends AbstractDescriptorTest { + private $colSize; + protected function setUp(): void { - putenv('COLUMNS=121'); + $this->colSize = getenv('COLUMNS'); + putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); } protected function tearDown(): void { - putenv('COLUMNS'); + putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); } protected function getDescriptor() diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php index 5846f386b7fca..e8481f31c539b 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php @@ -29,6 +29,18 @@ class UserPasswordEncoderCommandTest extends AbstractWebTestCase { /** @var CommandTester */ private $passwordEncoderCommandTester; + private $colSize; + + protected function setUp(): void + { + $this->colSize = getenv('COLUMNS'); + putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); + } + + protected function tearDown(): void + { + putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); + } public function testEncodePasswordEmptySalt() { @@ -314,7 +326,6 @@ public function testThrowsExceptionOnNoConfiguredEncoders() protected function setUp(): void { - putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); $kernel = $this->createKernel(['test_case' => 'PasswordEncode']); $kernel->boot(); @@ -332,7 +343,6 @@ protected function tearDown(): void private function setupArgon2i() { - putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); $kernel = $this->createKernel(['test_case' => 'PasswordEncode', 'root_config' => 'argon2i.yml']); $kernel->boot(); @@ -345,7 +355,6 @@ private function setupArgon2i() private function setupArgon2id() { - putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); $kernel = $this->createKernel(['test_case' => 'PasswordEncode', 'root_config' => 'argon2id.yml']); $kernel->boot(); @@ -358,7 +367,6 @@ private function setupArgon2id() private function setupBcrypt() { - putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); $kernel = $this->createKernel(['test_case' => 'PasswordEncode', 'root_config' => 'bcrypt.yml']); $kernel->boot(); @@ -371,7 +379,6 @@ private function setupBcrypt() private function setupSodium() { - putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); $kernel = $this->createKernel(['test_case' => 'PasswordEncode', 'root_config' => 'sodium.yml']); $kernel->boot(); diff --git a/src/Symfony/Component/Form/Tests/Console/Descriptor/JsonDescriptorTest.php b/src/Symfony/Component/Form/Tests/Console/Descriptor/JsonDescriptorTest.php index 5926fe527738f..8aa46f714d759 100644 --- a/src/Symfony/Component/Form/Tests/Console/Descriptor/JsonDescriptorTest.php +++ b/src/Symfony/Component/Form/Tests/Console/Descriptor/JsonDescriptorTest.php @@ -15,14 +15,17 @@ class JsonDescriptorTest extends AbstractDescriptorTest { + private $colSize; + protected function setUp(): void { - putenv('COLUMNS=121'); + $this->colSize = getenv('COLUMNS'); + putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); } protected function tearDown(): void { - putenv('COLUMNS'); + putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); } protected function getDescriptor() diff --git a/src/Symfony/Component/Form/Tests/Console/Descriptor/TextDescriptorTest.php b/src/Symfony/Component/Form/Tests/Console/Descriptor/TextDescriptorTest.php index ed1582e6b21ba..b3bfbaa5388ca 100644 --- a/src/Symfony/Component/Form/Tests/Console/Descriptor/TextDescriptorTest.php +++ b/src/Symfony/Component/Form/Tests/Console/Descriptor/TextDescriptorTest.php @@ -15,14 +15,17 @@ class TextDescriptorTest extends AbstractDescriptorTest { + private $colSize; + protected function setUp(): void { - putenv('COLUMNS=121'); + $this->colSize = getenv('COLUMNS'); + putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); } protected function tearDown(): void { - putenv('COLUMNS'); + putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); } protected function getDescriptor() diff --git a/src/Symfony/Component/Messenger/Tests/Command/DebugCommandTest.php b/src/Symfony/Component/Messenger/Tests/Command/DebugCommandTest.php index 90fcdb3311649..dc06144df4cc4 100644 --- a/src/Symfony/Component/Messenger/Tests/Command/DebugCommandTest.php +++ b/src/Symfony/Component/Messenger/Tests/Command/DebugCommandTest.php @@ -27,14 +27,17 @@ */ class DebugCommandTest extends TestCase { + private $colSize; + protected function setUp(): void { + $this->colSize = getenv('COLUMNS'); putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); } protected function tearDown(): void { - putenv('COLUMNS'); + putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); } public function testOutput() From decf443a204a13e431a05cb921cb59d473451ad7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Jun 2021 14:24:10 +0200 Subject: [PATCH 80/93] - --- .../Functional/UserPasswordEncoderCommandTest.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php index e8481f31c539b..78864da648876 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php @@ -31,17 +31,6 @@ class UserPasswordEncoderCommandTest extends AbstractWebTestCase private $passwordEncoderCommandTester; private $colSize; - protected function setUp(): void - { - $this->colSize = getenv('COLUMNS'); - putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); - } - - protected function tearDown(): void - { - putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); - } - public function testEncodePasswordEmptySalt() { $this->passwordEncoderCommandTester->execute([ @@ -326,6 +315,9 @@ public function testThrowsExceptionOnNoConfiguredEncoders() protected function setUp(): void { + $this->colSize = getenv('COLUMNS'); + putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); + $kernel = $this->createKernel(['test_case' => 'PasswordEncode']); $kernel->boot(); @@ -339,6 +331,7 @@ protected function setUp(): void protected function tearDown(): void { $this->passwordEncoderCommandTester = null; + putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); } private function setupArgon2i() From c6193bf85d78f2b71cdcede2d70bcf0975152123 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Jun 2021 14:32:53 +0200 Subject: [PATCH 81/93] - --- .../Console/Descriptor/AbstractDescriptorTest.php | 13 +++++++++++++ .../Tests/Console/Descriptor/TextDescriptorTest.php | 13 ------------- .../Console/Descriptor/AbstractDescriptorTest.php | 13 +++++++++++++ .../Tests/Console/Descriptor/JsonDescriptorTest.php | 13 ------------- .../Tests/Console/Descriptor/TextDescriptorTest.php | 13 ------------- 5 files changed, 26 insertions(+), 39 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php index c4c3f7df03cbc..30cc22e2039de 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php @@ -25,6 +25,19 @@ abstract class AbstractDescriptorTest extends TestCase { + private $colSize; + + protected function setUp(): void + { + $this->colSize = getenv('COLUMNS'); + putenv('COLUMNS=121'); + } + + protected function tearDown(): void + { + putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); + } + /** @dataProvider getDescribeRouteCollectionTestData */ public function testDescribeRouteCollection(RouteCollection $routes, $expectedDescription) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/TextDescriptorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/TextDescriptorTest.php index 5a57a6f0c2423..ce4f377c508fd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/TextDescriptorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/TextDescriptorTest.php @@ -15,19 +15,6 @@ class TextDescriptorTest extends AbstractDescriptorTest { - private $colSize; - - protected function setUp(): void - { - $this->colSize = getenv('COLUMNS'); - putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); - } - - protected function tearDown(): void - { - putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); - } - protected function getDescriptor() { return new TextDescriptor(); diff --git a/src/Symfony/Component/Form/Tests/Console/Descriptor/AbstractDescriptorTest.php b/src/Symfony/Component/Form/Tests/Console/Descriptor/AbstractDescriptorTest.php index f50a79ec00fcf..78e0f0bbda34e 100644 --- a/src/Symfony/Component/Form/Tests/Console/Descriptor/AbstractDescriptorTest.php +++ b/src/Symfony/Component/Form/Tests/Console/Descriptor/AbstractDescriptorTest.php @@ -28,6 +28,19 @@ abstract class AbstractDescriptorTest extends TestCase { + private $colSize; + + protected function setUp(): void + { + $this->colSize = getenv('COLUMNS'); + putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); + } + + protected function tearDown(): void + { + putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); + } + /** @dataProvider getDescribeDefaultsTestData */ public function testDescribeDefaults($object, array $options, $fixtureName) { diff --git a/src/Symfony/Component/Form/Tests/Console/Descriptor/JsonDescriptorTest.php b/src/Symfony/Component/Form/Tests/Console/Descriptor/JsonDescriptorTest.php index 8aa46f714d759..c035be6bcd9cf 100644 --- a/src/Symfony/Component/Form/Tests/Console/Descriptor/JsonDescriptorTest.php +++ b/src/Symfony/Component/Form/Tests/Console/Descriptor/JsonDescriptorTest.php @@ -15,19 +15,6 @@ class JsonDescriptorTest extends AbstractDescriptorTest { - private $colSize; - - protected function setUp(): void - { - $this->colSize = getenv('COLUMNS'); - putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); - } - - protected function tearDown(): void - { - putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); - } - protected function getDescriptor() { return new JsonDescriptor(); diff --git a/src/Symfony/Component/Form/Tests/Console/Descriptor/TextDescriptorTest.php b/src/Symfony/Component/Form/Tests/Console/Descriptor/TextDescriptorTest.php index b3bfbaa5388ca..c970eba96e62f 100644 --- a/src/Symfony/Component/Form/Tests/Console/Descriptor/TextDescriptorTest.php +++ b/src/Symfony/Component/Form/Tests/Console/Descriptor/TextDescriptorTest.php @@ -15,19 +15,6 @@ class TextDescriptorTest extends AbstractDescriptorTest { - private $colSize; - - protected function setUp(): void - { - $this->colSize = getenv('COLUMNS'); - putenv('COLUMNS='.(119 + \strlen(\PHP_EOL))); - } - - protected function tearDown(): void - { - putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); - } - protected function getDescriptor() { return new TextDescriptor(); From bd412f2616ab63d9741cd977d23a82a44af0276d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Jun 2021 18:37:09 +0200 Subject: [PATCH 82/93] Tweak GHA --- .github/workflows/unit-tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 5aa50094bff97..68a48d226695e 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -57,6 +57,7 @@ jobs: git config --global user.email "" git config --global user.name "Symfony" git config --global init.defaultBranch main + git config --global advice.detachedHead false COMPOSER_HOME="$(composer config home)" ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" @@ -148,7 +149,7 @@ jobs: run: | _run_tests() { local ok=0 - local title="$1 $FLIP" + local title="$1$FLIP" local start=$(date -u +%s) OUTPUT=$(bash -xc "$2" 2>&1) || ok=1 local end=$(date -u +%s) From ab2a0fe653851718ff5dc6c3e935cffb63ae78f6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 28 Jun 2021 11:03:12 +0200 Subject: [PATCH 83/93] Tweak CI --- .appveyor.yml | 2 +- .github/workflows/unit-tests.yml | 4 ++-- .travis.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 38f7468b9a99a..d3d4660290489 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -51,7 +51,7 @@ install: - php composer.phar global require --no-progress --no-scripts --no-plugins symfony/flex - git config --global user.email "" - git config --global user.name "Symfony" - - FOR /F "tokens=* USEBACKQ" %%F IN (`bash -c "grep ' VERSION = ' src/Symfony/Component/HttpKernel/Kernel.php | grep -P -o '[0-9]+\.[0-9]+'"`) DO (SET SYMFONY_VERSION=%%F) + - FOR /F "tokens=* USEBACKQ" %%F IN (`bash -c "grep ' VERSION = ' src/Symfony/Component/HttpKernel/Kernel.php | grep -o '[0-9][0-9]*\.[0-9]'"`) DO (SET SYMFONY_VERSION=%%F) - php .github/build-packages.php HEAD^ %SYMFONY_VERSION% src\Symfony\Bridge\PhpUnit - SET "SYMFONY_REQUIRE=>=%SYMFONY_VERSION%" - SET COMPOSER_ROOT_VERSION=%SYMFONY_VERSION%.x-dev diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 68a48d226695e..db8acbc3dc8dd 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -104,7 +104,7 @@ jobs: # For the highest branch, in high-deps mode, the version before it is checked out and tested with the locally patched components if [[ "${{ matrix.mode }}" = high-deps && $SYMFONY_VERSION = $(echo "$SYMFONY_VERSIONS" | tail -n 1 | sed s/.//) ]]; then - echo FLIP='🙃' >> $GITHUB_ENV + echo FLIP='^' >> $GITHUB_ENV SYMFONY_VERSION=$(echo "$SYMFONY_VERSIONS" | grep -FB1 /$SYMFONY_VERSION | head -n 1 | sed s/.//) git fetch --depth=2 origin $SYMFONY_VERSION git checkout -m FETCH_HEAD @@ -189,7 +189,7 @@ jobs: COMPONENTS=$(git diff --name-only src/ | grep composer.json || true) if [[ $COMPONENTS && $SYMFONY_VERSION = *.4 ]]; then - export FLIP='🙃' + export FLIP='^' SYMFONY_VERSION=$(echo $SYMFONY_VERSION | awk '{print $1 - 1}') echo -e "\\n\\e[33;1mChecking out Symfony $SYMFONY_VERSION and running tests with patched components as deps\\e[0m" export COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev diff --git a/.travis.yml b/.travis.yml index c07e7cc6775b7..2836521932ddf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,7 +44,7 @@ before_install: # tfold is a helper to create folded reports tfold () { - local title="$PHP $1 $FLIP" + local title="$PHP $1" local fold=$(echo $title | sed -r 's/[^-_A-Za-z0-9]+/./g') shift local id=$(printf %08x $(( RANDOM * RANDOM ))) From ac2c3a936d0bb33e1cc868ba28a2437f88f69f00 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 28 Jun 2021 11:04:43 +0200 Subject: [PATCH 84/93] Tweak CI --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index db8acbc3dc8dd..9607f1810a8ce 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -157,7 +157,7 @@ jobs: if [[ $ok -ne 0 ]]; then printf "\n%-70s%10s\n" $title $(($end-$start))s echo "$OUTPUT" - echo -e "\n\\e[41mKO\\e[0m $title\\n" + echo -e "\n::error::\\e[41mKO\\e[0m $title\\n" else printf "::group::%-68s%10s\n" $title $(($end-$start))s echo "$OUTPUT" From 21621ab78361c90c56cfb0571a08a23aabf5672b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 28 Jun 2021 17:26:46 +0200 Subject: [PATCH 85/93] [FrameworkBundle] fix tests --- .github/workflows/unit-tests.yml | 7 ++++++- .../Tests/Console/Descriptor/ObjectsProvider.php | 2 +- .../Descriptor/event_dispatcher_1_event1.json | 2 +- .../Fixtures/Descriptor/event_dispatcher_1_event1.md | 2 +- .../Descriptor/event_dispatcher_1_event1.txt | 12 ++++++------ .../Descriptor/event_dispatcher_1_event1.xml | 2 +- .../Descriptor/event_dispatcher_1_events.json | 2 +- .../Fixtures/Descriptor/event_dispatcher_1_events.md | 2 +- .../Descriptor/event_dispatcher_1_events.txt | 12 ++++++------ .../Descriptor/event_dispatcher_1_events.xml | 2 +- .../Bundle/TwigBundle/Resources/config/twig.xml | 2 +- 11 files changed, 26 insertions(+), 21 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 9607f1810a8ce..7a8998a51ba99 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -198,7 +198,12 @@ jobs: git checkout -m FETCH_HEAD COMPONENTS=$(echo "$COMPONENTS" | xargs dirname | xargs -n1 -I{} bash -c "[ -e '{}/phpunit.xml.dist' ] && echo '{}'" | sort || true) (cd src/Symfony/Component/HttpFoundation; composer require --dev --no-update mongodb/mongodb) - [[ ! $COMPONENTS ]] || echo "$COMPONENTS" | parallel -j +3 "_run_tests {} 'cd {} && rm composer.lock vendor/ -Rf && $COMPOSER_UP && $PHPUNIT$LEGACY'" || X=1 + if [[ $COMPONENTS ]]; then + echo "::group::install phpunit" + ./phpunit install + echo "::endgroup::" + echo "$COMPONENTS" | parallel -j +3 "_run_tests {} 'cd {} && rm composer.lock vendor/ -Rf && $COMPOSER_UP && $PHPUNIT$LEGACY'" || X=1 + fi fi [[ ! $X ]] || (exit 1) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php index 84f05c64874ea..071ca83ca68b3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php @@ -200,7 +200,7 @@ public static function getEventDispatchers() { $eventDispatcher = new EventDispatcher(); - $eventDispatcher->addListener('event1', 'global_function', 255); + $eventDispatcher->addListener('event1', 'var_dump', 255); $eventDispatcher->addListener('event1', function () { return 'Closure'; }, -1); $eventDispatcher->addListener('event2', new CallableClass()); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.json index 4b68f0cefc0e4..dc9957f7141e5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.json +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.json @@ -1,7 +1,7 @@ [ { "type": "function", - "name": "global_function", + "name": "var_dump", "priority": 255 }, { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.md index 98b81ecdce422..826ab219ed1fa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.md +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.md @@ -3,7 +3,7 @@ ## Listener 1 - Type: `function` -- Name: `global_function` +- Name: `var_dump` - Priority: `255` ## Listener 2 diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.txt b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.txt index f7a3cb0bd90ca..0f0879f421b05 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.txt +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.txt @@ -2,10 +2,10 @@ Registered Listeners for "event1" Event ======================================= - ------- ------------------- ---------- -  Order   Callable   Priority  - ------- ------------------- ---------- - #1 global_function() 255 - #2 Closure() -1 - ------- ------------------- ---------- + ------- ------------ ---------- +  Order   Callable   Priority  + ------- ------------ ---------- + #1 var_dump() 255 + #2 Closure() -1 + ------- ------------ ---------- diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.xml index bc03189af7b80..3d387b44bbf27 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_event1.xml @@ -1,5 +1,5 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.json index 30772d9a4a212..f79f79f99e21d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.json +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.json @@ -2,7 +2,7 @@ "event1": [ { "type": "function", - "name": "global_function", + "name": "var_dump", "priority": 255 }, { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.md index eb809789d5f17..ba407bef0c09d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.md +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.md @@ -5,7 +5,7 @@ ### Listener 1 - Type: `function` -- Name: `global_function` +- Name: `var_dump` - Priority: `255` ### Listener 2 diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.txt b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.txt index 475ad24cfda20..35c68295b8bfa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.txt +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.txt @@ -5,12 +5,12 @@ "event1" event -------------- - ------- ------------------- ---------- -  Order   Callable   Priority  - ------- ------------------- ---------- - #1 global_function() 255 - #2 Closure() -1 - ------- ------------------- ---------- + ------- ------------ ---------- +  Order   Callable   Priority  + ------- ------------ ---------- + #1 var_dump() 255 + #2 Closure() -1 + ------- ------------ ---------- "event2" event -------------- diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.xml index d7443f9743666..57a4b3a5cf6cd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/event_dispatcher_1_events.xml @@ -1,7 +1,7 @@ - + diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index 9a7dc42e77967..709522e44dcaf 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -166,7 +166,7 @@ - + %kernel.debug% From f549d9cd9c809bc6027e683fed79cf020fcda7fe Mon Sep 17 00:00:00 2001 From: elattariyassine <45572720+ELATTARIYassine@users.noreply.github.com> Date: Mon, 28 Jun 2021 19:06:40 +0100 Subject: [PATCH 86/93] added missing Arabic translations --- .../Validator/Resources/translations/validators.ar.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.ar.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.ar.xlf index fa87a3753de67..c6a38c57dab7e 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.ar.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.ar.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). صالح (ISIN) هذه القيمة ليست رقم تعريف الأوراق المالية الدولي. + + This value should be a valid expression. + يجب أن تكون هذه القيمة تعبيرًا صالحًا. + From edf74fa9ab419dff1f6cd3860ec530b68a803509 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 29 Jun 2021 11:23:13 +0200 Subject: [PATCH 87/93] Tweak GHA --- .github/workflows/psalm.yml | 4 ++-- .github/workflows/unit-tests.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml index f5807849e6f3e..a9adb8e7cf532 100644 --- a/.github/workflows/psalm.yml +++ b/.github/workflows/psalm.yml @@ -34,8 +34,8 @@ jobs: COMPOSER_HOME="$(composer config home)" ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" export COMPOSER_ROOT_VERSION=$(grep ' VERSION = ' src/Symfony/Component/HttpKernel/Kernel.php | grep -P -o '[0-9]+\.[0-9]+').x-dev - composer remove --no-update --no-interaction symfony/phpunit-bridge - composer require --no-update psalm/phar phpunit/phpunit:^9.5 php-http/discovery psr/event-dispatcher + composer remove --dev --no-update --no-interaction symfony/phpunit-bridge + composer require --no-update psalm/phar phpunit/phpunit:^9.5 php-http/discovery psr/event-dispatcher mongodb/mongodb echo "::group::composer update" composer update --no-progress --ansi diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 7a8998a51ba99..ceffbe310240c 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -157,7 +157,7 @@ jobs: if [[ $ok -ne 0 ]]; then printf "\n%-70s%10s\n" $title $(($end-$start))s echo "$OUTPUT" - echo -e "\n::error::\\e[41mKO\\e[0m $title\\n" + echo -e "\n::error::KO $title\\n" else printf "::group::%-68s%10s\n" $title $(($end-$start))s echo "$OUTPUT" From 18bf1bf44c7a0f5297facdcfc3d53da89cf434e9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 29 Jun 2021 11:23:13 +0200 Subject: [PATCH 88/93] update Italian translation --- .../Validator/Resources/translations/validators.it.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf index 1af8185e80e16..bca112204ddc8 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf @@ -386,6 +386,10 @@ This value is not a valid International Securities Identification Number (ISIN). Questo valore non è un codice identificativo internazionale di valori mobiliari (ISIN) valido. + + This value should be a valid expression. + Questo valore dovrebbe essere un'espressione valida. + From 62183afac46b9dab7a7c9b34c6f4b449a4d11e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E8=81=8A=E7=9A=84=E6=9D=B0=E5=9F=BA?= Date: Wed, 30 Jun 2021 13:40:44 +0800 Subject: [PATCH 89/93] Missing translations for Chinese (zh_CN) #41814 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. change "数值" to "值" in some tokens.("数值" in Chinese means an numeric value, but some tokens not declare it's value is a number); 2. add the id=100 translation. --- .../Resources/translations/validators.zh_CN.xlf | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf index 43ac9143bb963..3b5a16bd5fcd5 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf @@ -368,7 +368,7 @@ This value is not a valid hostname. - 该数值不是有效的主机名称。 + 该值不是有效的主机名称。 The number of elements in this collection should be a multiple of {{ compared_value }}. @@ -376,7 +376,7 @@ This value should satisfy at least one of the following constraints: - 该数值需符合以下其中一个约束: + 该值需符合以下其中一个约束: Each element of this collection should satisfy its own set of constraints. @@ -384,7 +384,11 @@ This value is not a valid International Securities Identification Number (ISIN). - 该数值不是有效的国际证券识别码 (ISIN)。 + 该值不是有效的国际证券识别码 (ISIN)。 + + + This value should be a valid expression. + 该值需为一个有效的表达式。 From 4b9b68c0235d587a328de67e122e166e5bd55be7 Mon Sep 17 00:00:00 2001 From: Arne Groskurth Date: Tue, 29 Jun 2021 10:47:48 +0200 Subject: [PATCH 90/93] [Filesystem] Workaround cannot dumpFile into "protected" folders on Windows --- .../Component/Filesystem/Filesystem.php | 8 ------- .../Filesystem/Tests/FilesystemTest.php | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 483c0b4261bfa..dfb1394add28c 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -678,10 +678,6 @@ public function dumpFile($filename, $content) $this->mkdir($dir); } - if (!is_writable($dir)) { - throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir); - } - // Will create a temp file with 0600 access rights // when the filesystem supports chmod. $tmpFile = $this->tempnam($dir, basename($filename)); @@ -721,10 +717,6 @@ public function appendToFile($filename, $content) $this->mkdir($dir); } - if (!is_writable($dir)) { - throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir); - } - if (false === @file_put_contents($filename, $content, \FILE_APPEND)) { throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename); } diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 77f780127e050..5639c220c735d 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1751,6 +1751,27 @@ public function testCopyShouldKeepExecutionPermission() $this->assertFilePermissions(767, $targetFilePath); } + public function testDumpToProtectedDirectory() + { + if (\DIRECTORY_SEPARATOR !== '\\') { + $this->markTestSkipped('This test is specific to Windows.'); + } + + if (($userProfilePath = getenv('USERPROFILE')) === false || !is_dir($userProfilePath)) { + throw new \RuntimeException('Failed to retrieve user profile path.'); + } + + $targetPath = implode(\DIRECTORY_SEPARATOR, [$userProfilePath, 'Downloads', '__test_file.ext']); + + try { + $this->assertFileDoesNotExist($targetPath); + $this->filesystem->dumpFile($targetPath, 'foobar'); + $this->assertFileExists($targetPath); + } finally { + $this->filesystem->remove($targetPath); + } + } + /** * Normalize the given path (transform each forward slash into a real directory separator). */ From 36dece58f7885bc83217f1a5e00f2fbaf6342889 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 30 Jun 2021 10:15:30 +0200 Subject: [PATCH 91/93] Update CHANGELOG for 4.4.26 --- CHANGELOG-4.4.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG-4.4.md b/CHANGELOG-4.4.md index 87e51995fca8b..d31628e66bc8a 100644 --- a/CHANGELOG-4.4.md +++ b/CHANGELOG-4.4.md @@ -7,6 +7,34 @@ in 4.4 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.4.0...v4.4.1 +* 4.4.26 (2021-06-30) + + * bug #41893 [Filesystem] Workaround cannot dumpFile into "protected" folders on Windows (arnegroskurth) + * bug #41665 [HttpKernel] Keep max lifetime also when part of the responses don't set it (mpdude) + * bug #41760 [ErrorHandler] fix handling buffered SilencedErrorContext (nicolas-grekas) + * bug #41807 [HttpClient] fix Psr18Client when allow_url_fopen=0 (nicolas-grekas) + * bug #40857 [DependencyInjection] Add support of PHP enumerations (alexandre-daubois) + * bug #41767 [Config] fix tracking default values that reference the parent class (nicolas-grekas) + * bug #41768 [DependencyInjection] Fix binding "iterable $foo" when using the PHP-DSL (nicolas-grekas) + * bug #41793 [Cache] handle prefixed redis connections when clearing pools (nicolas-grekas) + * bug #41804 [Cache] fix eventual consistency when using RedisTagAwareAdapter with a cluster (nicolas-grekas) + * bug #41773 [Cache] Disable locking on Windows by default (nicolas-grekas) + * bug #41655 [Mailer] fix encoding of addresses using SmtpTransport (dmaicher) + * bug #41663 [HttpKernel] [HttpCache] Keep s-maxage=0 from ESI sub-responses (mpdude) + * bug #41701 [VarDumper] Fix tests for PHP 8.1 (alexandre-daubois) + * bug #41795 [FrameworkBundle] Replace var_export with VarExporter to use array short syntax in secrets list files (alexandre-daubois) + * bug #41779 [DependencyInjection] throw proper exception when decorating a synthetic service (nicolas-grekas) + * bug #41776 [ErrorHandler] [DebugClassLoader] Do not check Phake mocks classes (adoy) + * bug #41780 [PhpUnitBridge] fix handling the COMPOSER_BINARY env var when using simple-phpunit (Taluu) + * bug #41670 [HttpFoundation] allow savePath of NativeFileSessionHandler to be null (simon.chrzanowski) + * bug #41644 [Config] fix tracking attributes in ReflectionClassResource (nicolas-grekas) + * bug #41621 [Process] Fix incorrect parameter type (bch36) + * bug #41624 [HttpClient] Revert bindto workaround for unaffected PHP versions (derrabus) + * bug #41549 [Security] Fix opcache preload with alias classes (jderusse) + * bug #41491 [Serializer] Do not allow to denormalize string with spaces only to valid a DateTime object (sidz) + * bug #41386 [Console] Escape synopsis output (jschaedl) + * bug #41495 [HttpFoundation] Add ReturnTypeWillChange to SessionHandlers (nikic) + * 4.4.25 (2021-06-01) * bug #41000 [Form] Use !isset for checks cause this doesn't falsely include 0 (Kai Dederichs) From f5a5e5b108bda4c586b9d104ba4e0d9a253920b5 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 30 Jun 2021 10:17:21 +0200 Subject: [PATCH 92/93] Update CONTRIBUTORS for 4.4.26 --- CONTRIBUTORS.md | 53 ++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 311957098418a..275042f9e08f6 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -13,8 +13,8 @@ The Symfony Connect username in parenthesis allows to get more information - Robin Chalas (chalas_r) - Christophe Coevoet (stof) - Maxime Steinhausser (ogizanagi) - - Kévin Dunglas (dunglas) - Jérémy DERUSSÉ (jderusse) + - Kévin Dunglas (dunglas) - Grégoire Pineau (lyrixx) - Wouter De Jong (wouterj) - Jordi Boggiano (seldaek) @@ -43,8 +43,8 @@ The Symfony Connect username in parenthesis allows to get more information - Jeremy Mikola (jmikola) - Jean-François Simon (jfsimon) - Benjamin Eberlei (beberlei) - - Igor Wiedler (igorw) - Jan Schädlich (jschaedl) + - Igor Wiedler (igorw) - Eriksen Costa (eriksencosta) - Ener-Getick (energetick) - Sarah Khalil (saro0h) @@ -112,10 +112,10 @@ The Symfony Connect username in parenthesis allows to get more information - Bart van den Burg (burgov) - Jordan Alliot (jalliot) - John Wards (johnwards) + - Baptiste Clavié (talus) - Antoine Hérault (herzult) - Paráda József (paradajozsef) - Alexander Schranz (alexander-schranz) - - Baptiste Clavié (talus) - Arnaud Le Blanc (arnaud-lb) - Przemysław Bogusz (przemyslaw-bogusz) - Maxime STEINHAUSSER @@ -138,6 +138,7 @@ The Symfony Connect username in parenthesis allows to get more information - Włodzimierz Gajda (gajdaw) - Christian Scheb - Adrien Brault (adrienbrault) + - Tomas Norkūnas (norkunas) - Julien Falque (julienfalque) - Jacob Dreesen (jdreesen) - Malte Schlüter (maltemaltesich) @@ -147,21 +148,20 @@ The Symfony Connect username in parenthesis allows to get more information - Colin Frei - Javier Spagnoletti (phansys) - Joshua Thijssen - - Tomas Norkūnas (norkunas) - Yanick Witschi (toflar) - Daniel Wehner (dawehner) - Tugdual Saunier (tucksaun) - excelwebzone - Gordon Franke (gimler) - Saif Eddin Gmati (azjezz) + - HypeMC (hypemc) - Jesse Rushlow (geeshoe) - Fabien Pennequin (fabienpennequin) - Théo FIDRY (theofidry) + - Olivier Dolbeau (odolbeau) - Eric GELOEN (gelo) - Matthieu Napoli (mnapoli) - - HypeMC (hypemc) - Jannik Zschiesche (apfelbox) - - Olivier Dolbeau (odolbeau) - Robert Schönthal (digitalkaoz) - Florian Lonqueu-Brochard (florianlb) - Tigran Azatyan (tigranazatyan) @@ -202,12 +202,14 @@ The Symfony Connect username in parenthesis allows to get more information - Andreas Schempp (aschempp) - Romaric Drigon (romaricdrigon) - Arman Hosseini (arman) + - Alexandre Daubois (alexandre-daubois) - Niels Keurentjes (curry684) - Vyacheslav Pavlov - Richard Shank (iampersistent) - Wouter J - Thomas Rabaix (rande) - Chi-teck + - Mathieu Santostefano (welcomattic) - Jeroen Spee (jeroens) - Timo Bakx (timobakx) - Marco Pivetta (ocramius) @@ -233,9 +235,9 @@ The Symfony Connect username in parenthesis allows to get more information - GDIBass - Samuel NELA (snela) - David Prévot - - Mathieu Santostefano - Dmitrii Poddubnyi (karser) - Joe Bennett (kralos) + - Michael Babker (mbabker) - Tien Vo (tienvx) - Timothée Barray (tyx) - James Halsall (jaitsu) @@ -244,6 +246,7 @@ The Symfony Connect username in parenthesis allows to get more information - Benjamin Leveque (benji07) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) + - Mathieu Lechat (mat_the_cat) - Marek Štípek (maryo) - Daniel Espendiller - Possum @@ -257,6 +260,7 @@ The Symfony Connect username in parenthesis allows to get more information - Christopher Hertel (chertel) - DQNEO - Hidde Wieringa (hiddewie) + - Hugo Monteiro (monteiro) - Antonio Pauletich (x-coder264) - Andre Rømcke (andrerom) - Nate Wiebe (natewiebe13) @@ -275,7 +279,6 @@ The Symfony Connect username in parenthesis allows to get more information - Tom Van Looy (tvlooy) - Guillaume Pédelagrabe - Noel Guilbert (noel) - - Mathieu Lechat (mat_the_cat) - Anthony GRASSIOT (antograssiot) - Stadly - Stepan Anchugov (kix) @@ -296,12 +299,10 @@ The Symfony Connect username in parenthesis allows to get more information - Pierre Minnieur (pminnieur) - fivestar - Dominique Bongiraud - - Hugo Monteiro (monteiro) - dFayet - Jeremy Livingston (jeremylivingston) - Michael Lee (zerustech) - Matthieu Auger (matthieuauger) - - Michael Babker (mbabker) - Leszek Prabucki (l3l0) - Nicolas Philippe (nikophil) - Colin O'Dell (colinodell) @@ -312,15 +313,17 @@ The Symfony Connect username in parenthesis allows to get more information - John Kary (johnkary) - Justin Hileman (bobthecow) - Blanchon Vincent (blanchonvincent) + - Denis Brumann (dbrumann) - Michele Orselli (orso) - Sven Paulus (subsven) - Daniel STANCU - Maxime Veber (nek-) + - Ion Bazan (ionbazan) - Loick Piera (pyrech) - Clara van Miert + - Valentine Boineau (valentineboineau) - Bastien Jaillot (bastnic) - Rui Marinho (ruimarinho) - - Alexandre Daubois (alexandre-daubois) - Eugene Wissner - Bohan Yang (brentybh) - Pascal Montoya @@ -363,7 +366,6 @@ The Symfony Connect username in parenthesis allows to get more information - Roman Marintšenko (inori) - Xavier Montaña Carreras (xmontana) - Mickaël Andrieu (mickaelandrieu) - - Ion Bazan (ionbazan) - Xavier Perez - Arjen Brouwer (arjenjb) - Katsuhiro OGAWA @@ -374,7 +376,6 @@ The Symfony Connect username in parenthesis allows to get more information - Anton Chernikov (anton_ch1989) - Kristen Gilden (kgilden) - Pierre-Yves LEBECQ (pylebecq) - - Denis Brumann (dbrumann) - Jordan Samouh (jordansamouh) - Jakub Kucharovic (jkucharovic) - Sullivan SENECHAL (soullivaneuh) @@ -489,6 +490,7 @@ The Symfony Connect username in parenthesis allows to get more information - Loïc Frémont (loic425) - Oleksandr Barabolia (oleksandrbarabolia) - ivan + - Artem Henvald (artemgenvald) - Greg Anderson - Tri Pham (phamuyentri) - BoShurik @@ -523,6 +525,7 @@ The Symfony Connect username in parenthesis allows to get more information - Terje Bråten - Renan Gonçalves (renan_saddam) - Marco Petersen (ocrampete16) + - Tarmo Leppänen (tarlepp) - Martin Auswöger - Robbert Klarenbeek (robbertkl) - Eric Masoero (eric-masoero) @@ -556,7 +559,6 @@ The Symfony Connect username in parenthesis allows to get more information - Tamas Szijarto - Michele Locati - Pavel Volokitin (pvolok) - - Valentine Boineau (valentineboineau) - Gijs van Lammeren - Arthur de Moulins (4rthem) - Matthias Althaus (althaus) @@ -616,7 +618,6 @@ The Symfony Connect username in parenthesis allows to get more information - Christopher Davis (chrisguitarguy) - Andrey Sevastianov - Webnet team (webnet) - - Artem Henvald (artemgenvald) - marie - Jan Schumann - Noémi Salaün (noemi-salaun) @@ -643,6 +644,7 @@ The Symfony Connect username in parenthesis allows to get more information - Xavier Briand (xavierbriand) - Asmir Mustafic (goetas) - DerManoMann + - Stefan Gehrig (sgehrig) - vagrant - Aurimas Niekis (gcds) - EdgarPE @@ -674,7 +676,6 @@ The Symfony Connect username in parenthesis allows to get more information - Soner Sayakci - Tobias Weichart - Miro Michalicka - - Tarmo Leppänen (tarlepp) - Marcin Sikoń (marphi) - M. Vondano - Dominik Zogg (dominik.zogg) @@ -786,6 +787,7 @@ The Symfony Connect username in parenthesis allows to get more information - Joachim Løvgaard (loevgaard) - jhonnyL - sasezaki + - Jonathan Scheiber (jmsche) - Kristof Van Cauwenbergh (kristofvc) - Dawid Pakuła (zulusx) - Marco Lipparini (liarco) @@ -832,6 +834,7 @@ The Symfony Connect username in parenthesis allows to get more information - Pablo Lozano (arkadis) - Thiago Cordeiro (thiagocordeiro) - Jan Behrens + - Dragos Protung (dragosprotung) - Mantas Var (mvar) - Terje Bråten - Yann LUCAS (drixs6o9) @@ -912,7 +915,6 @@ The Symfony Connect username in parenthesis allows to get more information - Julien Fredon - Jacek Wilczyński (jacekwilczynski) - Xavier Leune (xleune) - - Stefan Gehrig (sgehrig) - Hany el-Kerdany - Wang Jingyu - Åsmund Garfors @@ -1075,6 +1077,7 @@ The Symfony Connect username in parenthesis allows to get more information - Andrea Sprega (asprega) - Alexander Volochnev (exelenz) - Viktor Bajraktar (njutn95) + - SiD (plbsid) - Mbechezi Nawo - Michael Piecko - Toni Peric (tperic) @@ -1223,7 +1226,6 @@ The Symfony Connect username in parenthesis allows to get more information - Bernhard Rusch - Ivan - Quentin Schuler - - Jonathan Scheiber (jmsche) - Pierre Vanliefland (pvanliefland) - Roy Klutman (royklutman) - Sofiane HADDAG (sofhad) @@ -1231,6 +1233,7 @@ The Symfony Connect username in parenthesis allows to get more information - Taylor Otwell - Dries Vints - Sami Mussbach + - Kien Nguyen - Foxprodev - Eric Hertwig - Niels Robin-Aubertin @@ -1391,7 +1394,6 @@ The Symfony Connect username in parenthesis allows to get more information - Andre Johnson - Marco Pfeiffer - Rootie - - Dragos Protung (dragosprotung) - Gabriel Solomon (gabrielsolomon) - Daniel Alejandro Castro Arellano (lexcast) - Aleksandar Dimitrov (netbull) @@ -1454,6 +1456,7 @@ The Symfony Connect username in parenthesis allows to get more information - Amirreza Shafaat (amirrezashafaat) - Adoni Pavlakis (adoni) - Nicolas Le Goff (nlegoff) + - Maarten Nusteling (nusje2000) - Ahmed EBEN HASSINE (famas23) - Ben Oman - Chris de Kok @@ -1464,6 +1467,7 @@ The Symfony Connect username in parenthesis allows to get more information - Irmantas Šiupšinskas (irmantas) - Danilo Silva - Giuseppe Campanelli + - Matthieu Calie (matth--) - Arnaud PETITPAS (apetitpa) - Ken Stanley - ivan @@ -1651,6 +1655,7 @@ The Symfony Connect username in parenthesis allows to get more information - Loïc Ovigne (oviglo) - Artem Kolesnikov (tyomo4ka) - Markkus Millend + - Clément - Gustavo Adrian - Jorrit Schippers (jorrit) - Yannick @@ -1664,6 +1669,7 @@ The Symfony Connect username in parenthesis allows to get more information - Amine Yakoubi - Eduardo García Sanz (coma) - Sergio (deverad) + - simon chrzanowski (simonch) - Makdessi Alex - James Gilliland - fduch (fduch) @@ -1677,7 +1683,6 @@ The Symfony Connect username in parenthesis allows to get more information - arnaud (arnooo999) - Gilles Doge (gido) - Oscar Esteve (oesteve) - - SiD (plbsid) - abulford - Philipp Kretzschmar - antograssiot @@ -1901,6 +1906,7 @@ The Symfony Connect username in parenthesis allows to get more information - Daniel González Zaballos (dem3trio) - Emmanuel Vella (emmanuel.vella) - Guillaume BRETOU (guiguiboy) + - Nikita Popov (nikic) - Carsten Nielsen (phreaknerd) - Jay Severson - Benny Born @@ -1938,6 +1944,7 @@ The Symfony Connect username in parenthesis allows to get more information - r1pp3rj4ck - phydevs - mmokhi + - Serhii Smirnov - Robert Queck - Peter Bouwdewijn - mlively @@ -1961,6 +1968,7 @@ The Symfony Connect username in parenthesis allows to get more information - Matthew J Mucklo - AnrDaemon - Emre Akinci (emre) + - Chris Maiden (matason) - fdgdfg (psampaz) - Andrea Ruggiero (pupax) - Stéphane Seng @@ -1976,6 +1984,7 @@ The Symfony Connect username in parenthesis allows to get more information - Valentin VALCIU - Jeremiah VALERIE - Julien Menth + - George Yiannoulopoulos - Yannick Snobbert - Kevin Dew - James Cowgill @@ -2516,6 +2525,7 @@ The Symfony Connect username in parenthesis allows to get more information - Youpie - Jason Stephens - srsbiz + - Tinjo Schöni - Taylan Kasap - Michael Orlitzky - Nicolas A. Bérard-Nault @@ -2625,6 +2635,7 @@ The Symfony Connect username in parenthesis allows to get more information - Michal Forbak - Drew Butler - Alexey Berezuev + - Pierrick Charron - Steve Müller - Andras Ratz - andreabreu98 @@ -2636,10 +2647,12 @@ The Symfony Connect username in parenthesis allows to get more information - Anatol Belski - Şəhriyar İmanov - Alexis BOYER + - bch36 - Kaipi Yann - adam-mospan - Steve Hyde - Sam Williams + - Ettore Del Negro - Guillaume Aveline - Adrian Philipp - James Michael DuPont From 689e2967e5073d60e8b1017e70aa0fac7d533777 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 30 Jun 2021 10:18:06 +0200 Subject: [PATCH 93/93] Update VERSION for 4.4.26 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 819c60538fc41..1275f12e7ac31 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,12 +76,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - public const VERSION = '4.4.26-DEV'; + public const VERSION = '4.4.26'; public const VERSION_ID = 40426; public const MAJOR_VERSION = 4; public const MINOR_VERSION = 4; public const RELEASE_VERSION = 26; - public const EXTRA_VERSION = 'DEV'; + public const EXTRA_VERSION = ''; public const END_OF_MAINTENANCE = '11/2022'; public const END_OF_LIFE = '11/2023';