From b71d589071aa91e7d761032a4faf4727849da4e7 Mon Sep 17 00:00:00 2001 From: Bill Hance Date: Wed, 24 Apr 2019 00:12:49 -0700 Subject: [PATCH 001/106] Added FormInterface to @return Form::getClickedButton docblock --- src/Symfony/Component/Form/Form.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 5f417d6d90901..3e8d632d939a0 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -89,7 +89,7 @@ class Form implements \IteratorAggregate, FormInterface private $submitted = false; /** - * @var ClickableInterface|null The button that was used to submit the form + * @var FormInterface|ClickableInterface|null The button that was used to submit the form */ private $clickedButton; @@ -749,7 +749,7 @@ public function isValid() /** * Returns the button that was used to submit the form. * - * @return ClickableInterface|null + * @return FormInterface|ClickableInterface|null */ public function getClickedButton() { From 07800fc3e4175a367148cf77c353b3ee420417a6 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 6 Jun 2019 15:31:25 +0200 Subject: [PATCH 002/106] bumped Symfony version to 4.3.2 --- 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 9c62c087ec73c..b9edce2354d63 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -73,12 +73,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '4.3.1'; - const VERSION_ID = 40301; + const VERSION = '4.3.2-DEV'; + const VERSION_ID = 40302; const MAJOR_VERSION = 4; const MINOR_VERSION = 3; - const RELEASE_VERSION = 1; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 2; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '01/2020'; const END_OF_LIFE = '07/2020'; From 0041cd9828d91f5647342f256b74aab7e6df0cb2 Mon Sep 17 00:00:00 2001 From: Andrii Dembitskyi Date: Thu, 6 Jun 2019 17:13:36 +0300 Subject: [PATCH 003/106] [HttpKernel] Fix missing use for request and response classes --- src/Symfony/Component/HttpKernel/HttpKernelBrowser.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php b/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php index ab52df14edfe3..e413634755da5 100644 --- a/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php +++ b/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php @@ -11,6 +11,9 @@ namespace Symfony\Component\HttpKernel; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + /** * Client simulates a browser and makes requests to an HttpKernel instance. * From 154ce81519446261900e167e65cf3c587ee17dea Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 6 Jun 2019 19:00:17 +0200 Subject: [PATCH 004/106] [Validator] fix deprecation layer of ValidatorBuilder --- UPGRADE-4.2.md | 2 +- UPGRADE-5.0.md | 2 +- src/Symfony/Component/Validator/CHANGELOG.md | 2 +- src/Symfony/Component/Validator/ValidatorBuilder.php | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/UPGRADE-4.2.md b/UPGRADE-4.2.md index 90cd04d01e69a..3b1f238fa6f84 100644 --- a/UPGRADE-4.2.md +++ b/UPGRADE-4.2.md @@ -385,7 +385,7 @@ Validator * The `symfony/translation` dependency has been removed - run `composer require symfony/translation` if you need the component * The `checkMX` and `checkHost` options of the `Email` constraint are deprecated * The component is now decoupled from `symfony/translation` and uses `Symfony\Contracts\Translation\TranslatorInterface` instead - * The `ValidatorBuilderInterface` has been deprecated and `ValidatorBuilder` made final + * The `ValidatorBuilderInterface` has been deprecated and `ValidatorBuilder::setTranslator()` has been made final * Deprecated validating instances of `\DateTimeInterface` in `DateTimeValidator`, `DateValidator` and `TimeValidator`. Use `Type` instead or remove the constraint if the underlying model is type hinted to `\DateTimeInterface` already. * Using the `Bic`, `Country`, `Currency`, `Language` and `Locale` constraints without `symfony/intl` is deprecated * Using the `Email` constraint in strict mode without `egulias/email-validator` is deprecated diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 4ec9e24f4f0ce..a8e7d0aec3f91 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -259,7 +259,7 @@ Validator * Calling `EmailValidator::__construct()` method with a boolean parameter has been removed, use `EmailValidator("strict")` instead. * Removed the `checkDNS` and `dnsMessage` options from the `Url` constraint. * The component is now decoupled from `symfony/translation` and uses `Symfony\Contracts\Translation\TranslatorInterface` instead - * The `ValidatorBuilderInterface` has been removed and `ValidatorBuilder` is now final + * The `ValidatorBuilderInterface` has been removed * Removed support for validating instances of `\DateTimeInterface` in `DateTimeValidator`, `DateValidator` and `TimeValidator`. Use `Type` instead or remove the constraint if the underlying model is type hinted to `\DateTimeInterface` already. * The `symfony/intl` component is now required for using the `Bic`, `Country`, `Currency`, `Language` and `Locale` constraints * The `egulias/email-validator` component is now required for using the `Email` constraint in strict mode diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index 3863b5717a1fe..2d24f7c69cd3d 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -9,7 +9,7 @@ CHANGELOG * added `DivisibleBy` constraint * decoupled from `symfony/translation` by using `Symfony\Contracts\Translation\TranslatorInterface` * deprecated `ValidatorBuilderInterface` - * made `ValidatorBuilder` final + * made `ValidatorBuilder::setTranslator()` final * marked `format` the default option in `DateTime` constraint * deprecated validating instances of `\DateTimeInterface` in `DateTimeValidator`, `DateValidator` and `TimeValidator`. * deprecated using the `Bic`, `Country`, `Currency`, `Language` and `Locale` constraints without `symfony/intl` diff --git a/src/Symfony/Component/Validator/ValidatorBuilder.php b/src/Symfony/Component/Validator/ValidatorBuilder.php index 0766a2e9f399a..a65cca4c3d921 100644 --- a/src/Symfony/Component/Validator/ValidatorBuilder.php +++ b/src/Symfony/Component/Validator/ValidatorBuilder.php @@ -38,8 +38,6 @@ * The default implementation of {@link ValidatorBuilderInterface}. * * @author Bernhard Schussek - * - * @final since Symfony 4.2 */ class ValidatorBuilder implements ValidatorBuilderInterface { @@ -255,6 +253,8 @@ public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterfac /** * {@inheritdoc} + * + * @final since Symfony 4.2 */ public function setTranslator(LegacyTranslatorInterface $translator) { From 51b6bd886ac495a00655664fbf94d14b5f230deb Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Fri, 7 Jun 2019 10:45:31 +0200 Subject: [PATCH 005/106] [Serializer] Fix DataUriNormalizer docblock & composer suggest section --- .../Component/Serializer/Normalizer/DataUriNormalizer.php | 2 +- src/Symfony/Component/Serializer/composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php index 0284ca6ebcc41..185b44be4eeaa 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php @@ -32,7 +32,7 @@ class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface ]; /** - * @var MimeTypeGuesserInterface + * @var MimeTypeGuesserInterface|null */ private $mimeTypeGuesser; diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index e6282b14debe1..964f1b7bfd6ba 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -44,7 +44,7 @@ "symfony/yaml": "For using the default YAML mapping loader.", "symfony/config": "For using the XML mapping loader.", "symfony/property-access": "For using the ObjectNormalizer.", - "symfony/http-foundation": "To use the DataUriNormalizer.", + "symfony/http-foundation": "For using a MIME type guesser within the DataUriNormalizer.", "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", "doctrine/cache": "For using the default cached annotation reader and metadata cache." }, From 0fbfefe8697187b8714db76f56566bedae50eaad Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 7 Jun 2019 11:18:15 +0200 Subject: [PATCH 006/106] [Form] fix usage of legacy TranslatorInterface --- .../Component/Form/Extension/Core/Type/FileType.php | 11 +++++++++-- .../Form/Tests/Extension/Core/Type/FileTypeTest.php | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index f8afce2ee5a4d..bb1c448098997 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -20,7 +20,8 @@ use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Translation\TranslatorInterface; +use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class FileType extends AbstractType { @@ -35,8 +36,14 @@ class FileType extends AbstractType private $translator; - public function __construct(TranslatorInterface $translator = null) + /** + * @param TranslatorInterface|null $translator + */ + public function __construct($translator = null) { + if (null !== $translator && !$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) { + throw new \TypeError(sprintf('Argument 1 passed to %s() must be an instance of %s, %s given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator))); + } $this->translator = $translator; } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php index 311529c294799..0731942c8960a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php @@ -17,7 +17,7 @@ use Symfony\Component\Form\RequestHandlerInterface; use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\Translation\TranslatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class FileTypeTest extends BaseTypeTest { From 5ce0edeb12bfe65698c661e93e9f10a4919bf55f Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 7 Jun 2019 12:57:51 +0200 Subject: [PATCH 007/106] avoid service id conflicts with Swiftmailer --- .../DependencyInjection/FrameworkExtension.php | 2 +- .../Bundle/FrameworkBundle/Resources/config/mailer.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index c0266b1a7bd85..98c94f2a21ccc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1916,7 +1916,7 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co } $loader->load('mailer.xml'); - $container->getDefinition('mailer.transport')->setArgument(0, $config['dsn']); + $container->getDefinition('mailer.default_transport')->setArgument(0, $config['dsn']); } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.xml index d39899c0a9736..1f567a6c93a78 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.xml @@ -6,23 +6,23 @@ - + - + - + - + From caabd92f89944baf768bc5c1d90a5c07b629ce16 Mon Sep 17 00:00:00 2001 From: Amrouche Hamza Date: Fri, 7 Jun 2019 16:04:41 +0200 Subject: [PATCH 008/106] [DependencyInjection] fix the ValidateEnvPlaceHolderPassTest that was using a deprecated path for TreeBuilder --- .../Tests/Compiler/ValidateEnvPlaceholdersPassTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php index b57fb66bff043..1a198bca5df30 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php @@ -332,7 +332,7 @@ class EnvConfigurationWithoutRootNode implements ConfigurationInterface { public function getConfigTreeBuilder() { - return new TreeBuilder(); + return new TreeBuilder('env_extension'); } } @@ -340,8 +340,8 @@ class ConfigurationWithArrayNodeRequiringOneElement implements ConfigurationInte { public function getConfigTreeBuilder() { - $treeBuilder = new TreeBuilder(); - $treeBuilder->root('env_extension') + $treeBuilder = new TreeBuilder('env_extension'); + $treeBuilder->getRootNode() ->children() ->arrayNode('nodes') ->isRequired() From 2740bd1a9d38fb23cd66b5e0284c519e99531d82 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Fri, 7 Jun 2019 09:42:04 +0200 Subject: [PATCH 009/106] [Serializer] Fix DataUriNormalizer deprecation (MIME type guesser is optional) --- .../Serializer/Normalizer/DataUriNormalizer.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php index 111f3f2ff48d1..a6ca7223b0b91 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php @@ -39,7 +39,7 @@ class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface, C private $mimeTypeGuesser; /** - * @param MimeTypeGuesserInterface + * @param MimeTypeGuesserInterface|null $mimeTypeGuesser */ public function __construct($mimeTypeGuesser = null) { @@ -48,8 +48,8 @@ public function __construct($mimeTypeGuesser = null) } elseif (null === $mimeTypeGuesser) { if (class_exists(MimeTypes::class)) { $mimeTypeGuesser = MimeTypes::getDefault(); - } else { - @trigger_error(sprintf('Passing null to "%s()" without symfony/mime installed is deprecated since Symfony 4.3, install symfony/mime.', __METHOD__), E_USER_DEPRECATED); + } elseif (class_exists(MimeTypeGuesser::class)) { + @trigger_error(sprintf('Passing null to "%s()" to use a default MIME type guesser without Symfony Mime installed is deprecated since Symfony 4.3. Try running "composer require symfony/mime".', __METHOD__), E_USER_DEPRECATED); $mimeTypeGuesser = MimeTypeGuesser::getInstance(); } } elseif (!$mimeTypeGuesser instanceof MimeTypes) { @@ -156,7 +156,9 @@ private function getMimeType(\SplFileInfo $object) if ($this->mimeTypeGuesser instanceof DeprecatedMimeTypeGuesserInterface && $mimeType = $this->mimeTypeGuesser->guess($object->getPathname())) { return $mimeType; - } elseif ($this->mimeTypeGuesser && $mimeType = $this->mimeTypeGuesser->guessMimeType($object->getPathname())) { + } + + if ($this->mimeTypeGuesser && $mimeType = $this->mimeTypeGuesser->guessMimeType($object->getPathname())) { return $mimeType; } From 5e1ffb8d7ff3c043fa4e32e94dcf82338b2c78bf Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 7 Jun 2019 19:50:04 +0200 Subject: [PATCH 010/106] [travis] increase concurrency --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 405eb68e90ac2..3a022159513e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -260,12 +260,12 @@ install: tfold 'phpunit install' ./phpunit install fi if [[ $deps = high ]]; then - echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP && $PHPUNIT_X$LEGACY'" + echo "$COMPONENTS" | parallel --gnu "tfold {} 'cd {} && $COMPOSER_UP && $PHPUNIT_X$LEGACY'" elif [[ $deps = low ]]; then [[ -e ~/php-ext/composer-lowest.lock.tar ]] && tar -xf ~/php-ext/composer-lowest.lock.tar tar -cf ~/php-ext/composer-lowest.lock.tar --files-from /dev/null php .github/rm-invalid-lowest-lock-files.php $COMPONENTS - echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && ([ -e composer.lock ] && ${COMPOSER_UP/update/install} || $COMPOSER_UP --prefer-lowest --prefer-stable) && $PHPUNIT_X'" + echo "$COMPONENTS" | parallel --gnu "tfold {} 'cd {} && ([ -e composer.lock ] && ${COMPOSER_UP/update/install} || $COMPOSER_UP --prefer-lowest --prefer-stable) && $PHPUNIT_X'" echo "$COMPONENTS" | xargs -n1 -I{} tar --append -f ~/php-ext/composer-lowest.lock.tar {}/composer.lock elif [[ $PHP = hhvm* ]]; then rm src/Symfony/Bridge/PhpUnit -Rf From 5b2991804372d7f54829128d902dd04241c8df69 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 7 Jun 2019 20:09:56 +0200 Subject: [PATCH 011/106] [TwigBundle] fix tests --- .../TwigBundle/Tests/Loader/FilesystemLoaderTest.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php b/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php index 697e6ceb66711..b19a1180fcc4c 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php @@ -11,10 +11,13 @@ namespace Symfony\Bundle\TwigBundle\Tests\Loader; -use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; use Symfony\Bundle\TwigBundle\Loader\FilesystemLoader; use Symfony\Bundle\TwigBundle\Tests\TestCase; +use Symfony\Component\Templating\TemplateReferenceInterface; +/** + * @group legacy + */ class FilesystemLoaderTest extends TestCase { public function testGetSourceContext() @@ -61,7 +64,7 @@ public function testTwigErrorIfLocatorThrowsInvalid() ->expects($this->once()) ->method('parse') ->with('name.format.engine') - ->willReturn(new TemplateReference('', '', 'name', 'format', 'engine')) + ->willReturn($this->getMockBuilder(TemplateReferenceInterface::class)->getMock()) ; $locator = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock(); @@ -85,7 +88,7 @@ public function testTwigErrorIfLocatorReturnsFalse() ->expects($this->once()) ->method('parse') ->with('name.format.engine') - ->willReturn(new TemplateReference('', '', 'name', 'format', 'engine')) + ->willReturn($this->getMockBuilder(TemplateReferenceInterface::class)->getMock()) ; $locator = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock(); From b702598b0bb0d03b994b567156bb584003f23388 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Fri, 7 Jun 2019 11:25:07 -0400 Subject: [PATCH 012/106] Fixing bug where PropertyInfoLoader tried to add validation to non-existent properties --- .../Component/Validator/Mapping/Loader/PropertyInfoLoader.php | 4 ++++ .../Validator/Tests/Fixtures/PropertyInfoLoaderEntity.php | 4 ++++ .../Validator/Tests/Mapping/Loader/PropertyInfoLoaderTest.php | 1 + 3 files changed, 9 insertions(+) diff --git a/src/Symfony/Component/Validator/Mapping/Loader/PropertyInfoLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/PropertyInfoLoader.php index df3878d6e2bfc..7ddd534275294 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/PropertyInfoLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/PropertyInfoLoader.php @@ -60,6 +60,10 @@ public function loadClassMetadata(ClassMetadata $metadata) continue; } + if (!property_exists($className, $property)) { + continue; + } + $types = $this->typeExtractor->getTypes($className, $property); if (null === $types) { continue; diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderEntity.php b/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderEntity.php index 42f048c5d8c49..5f2a37179d2e1 100644 --- a/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderEntity.php +++ b/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderEntity.php @@ -48,4 +48,8 @@ class PropertyInfoLoaderEntity public $alreadyPartiallyMappedCollection; public $readOnly; + + public function setNonExistentField() + { + } } diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/PropertyInfoLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/PropertyInfoLoaderTest.php index 71b2691ee5489..f87b19f795f4b 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/PropertyInfoLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/PropertyInfoLoaderTest.php @@ -46,6 +46,7 @@ public function testLoadClassMetadata() 'alreadyMappedNotBlank', 'alreadyPartiallyMappedCollection', 'readOnly', + 'nonExistentField', ]) ; $propertyInfoStub From 07ca9f4831a1a77329d75ff4f85a0584db79795d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 7 Jun 2019 22:38:23 +0200 Subject: [PATCH 013/106] [SecurityBundle] add missing contraint for symfony/config dep --- src/Symfony/Bundle/SecurityBundle/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 57d313d87142c..6faf93306230c 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -18,6 +18,7 @@ "require": { "php": "^5.5.9|>=7.0.8", "ext-xml": "*", + "symfony/config": "~3.4|~4.0", "symfony/security": "~3.4.15|~4.0.15|^4.1.4", "symfony/dependency-injection": "^3.4.3|^4.0.3", "symfony/http-kernel": "~3.4|~4.0", From 25b961aadc51ceda84eb99cba74145cae94651ad Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Fri, 7 Jun 2019 22:39:31 +0200 Subject: [PATCH 014/106] [DI] Fix suspicious test --- .../Exception/TreeWithoutRootNodeException.php | 2 ++ .../Tests/Compiler/ValidateEnvPlaceholdersPassTest.php | 9 ++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Config/Definition/Exception/TreeWithoutRootNodeException.php b/src/Symfony/Component/Config/Definition/Exception/TreeWithoutRootNodeException.php index 67b0c4bb2e084..04406fc90b416 100644 --- a/src/Symfony/Component/Config/Definition/Exception/TreeWithoutRootNodeException.php +++ b/src/Symfony/Component/Config/Definition/Exception/TreeWithoutRootNodeException.php @@ -13,6 +13,8 @@ /** * @author Roland Franssen + * + * @internal */ class TreeWithoutRootNodeException extends \RuntimeException { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php index 1a198bca5df30..7e1de8f08374e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php @@ -226,16 +226,15 @@ public function testEnvWithVariableNode(): void /** * @group legacy + * @expectedDeprecation A tree builder without a root node is deprecated since Symfony 4.2 and will not be supported anymore in 5.0. */ public function testConfigurationWithoutRootNode(): void { $container = new ContainerBuilder(); $container->registerExtension(new EnvExtension(new EnvConfigurationWithoutRootNode())); - $container->loadFromExtension('env_extension'); + $container->loadFromExtension('env_extension', ['foo' => 'bar']); - $this->doProcess($container); - - $this->addToAssertionCount(1); + (new ValidateEnvPlaceholdersPass())->process($container); } public function testEmptyConfigFromMoreThanOneSource() @@ -332,7 +331,7 @@ class EnvConfigurationWithoutRootNode implements ConfigurationInterface { public function getConfigTreeBuilder() { - return new TreeBuilder('env_extension'); + return new TreeBuilder(); } } From 2b8e44164e45e6f3905292b5a6e1d56dd98c7db1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 8 Jun 2019 08:34:08 +0200 Subject: [PATCH 015/106] [Serializer] add missing "internal" annotation --- .../Serializer/Normalizer/AbstractObjectNormalizer.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index 7f22a1df1971e..5f0fc24a1fd30 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -561,6 +561,8 @@ private function isMaxDepthReached(array $attributesMetadata, string $class, str * {@inheritdoc} * * @param string|null $format + * + * @internal */ protected function createChildContext(array $parentContext, $attribute/*, ?string $format */) { From 37efa4bb8ca52651f34aa5282068e69b4cecceb4 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 8 Jun 2019 11:24:26 +0200 Subject: [PATCH 016/106] fix handling nested embeddables --- .../Tests/Fixtures/DoctrineLoaderEmbed.php | 5 ++++ .../Fixtures/DoctrineLoaderNestedEmbed.php | 25 +++++++++++++++++++ .../Tests/Validator/DoctrineLoaderTest.php | 15 +++++++++++ .../Doctrine/Validator/DoctrineLoader.php | 2 +- 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderNestedEmbed.php diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEmbed.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEmbed.php index 7985b9c4c613c..fc16f1cc135bc 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEmbed.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEmbed.php @@ -22,4 +22,9 @@ class DoctrineLoaderEmbed * @ORM\Column(length=25) */ public $embeddedMaxLength; + + /** + * @ORM\Embedded(class=DoctrineLoaderNestedEmbed::class) + */ + public $nestedEmbedded; } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderNestedEmbed.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderNestedEmbed.php new file mode 100644 index 0000000000000..fbf41555a1316 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderNestedEmbed.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping as ORM; + +/** + * @ORM\Embeddable() + */ +class DoctrineLoaderNestedEmbed +{ + /** + * @ORM\Column(length=27) + */ + public $nestedEmbeddedMaxLength; +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php index c4c0d75fa7073..2dcab2533d375 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php @@ -16,6 +16,7 @@ use Symfony\Bridge\Doctrine\Tests\Fixtures\BaseUser; use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderEmbed; use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderNestedEmbed; use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderParentEntity; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Bridge\Doctrine\Validator\DoctrineLoader; @@ -109,6 +110,20 @@ public function testLoadClassMetadata() $this->assertInstanceOf(Length::class, $embeddedMaxLengthConstraints[0]); $this->assertSame(25, $embeddedMaxLengthConstraints[0]->max); + $nestedEmbeddedMetadata = $embeddedClassMetadata->getPropertyMetadata('nestedEmbedded'); + $this->assertCount(1, $nestedEmbeddedMetadata); + $this->assertSame(CascadingStrategy::CASCADE, $nestedEmbeddedMetadata[0]->getCascadingStrategy()); + $this->assertSame(TraversalStrategy::IMPLICIT, $nestedEmbeddedMetadata[0]->getTraversalStrategy()); + + $nestedEmbeddedClassMetadata = $validator->getMetadataFor(new DoctrineLoaderNestedEmbed()); + + $nestedEmbeddedMaxLengthMetadata = $nestedEmbeddedClassMetadata->getPropertyMetadata('nestedEmbeddedMaxLength'); + $this->assertCount(1, $nestedEmbeddedMaxLengthMetadata); + $nestedEmbeddedMaxLengthConstraints = $nestedEmbeddedMaxLengthMetadata[0]->getConstraints(); + $this->assertCount(1, $nestedEmbeddedMaxLengthConstraints); + $this->assertInstanceOf(Length::class, $nestedEmbeddedMaxLengthConstraints[0]); + $this->assertSame(27, $nestedEmbeddedMaxLengthConstraints[0]->max); + $this->assertCount(0, $classMetadata->getPropertyMetadata('guidField')); $this->assertCount(0, $classMetadata->getPropertyMetadata('simpleArrayField')); diff --git a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php index 53bf606ac36df..76a2b4d8b0288 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php +++ b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php @@ -79,7 +79,7 @@ public function loadClassMetadata(ClassMetadata $metadata): bool $constraint = $this->getLengthConstraint($metadata, $mapping['fieldName']); if (null === $constraint) { - if (isset($mapping['originalClass'])) { + if (isset($mapping['originalClass']) && false === strpos($mapping['declaredField'], '.')) { $metadata->addPropertyConstraint($mapping['declaredField'], new Valid()); } elseif (property_exists($className, $mapping['fieldName'])) { $metadata->addPropertyConstraint($mapping['fieldName'], new Length(['max' => $mapping['length']])); From 48093f4a13cf42540356442f53ebfa6c309630bc Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 9 Jun 2019 16:27:26 +0200 Subject: [PATCH 017/106] Fix reporting unsilenced deprecations from insulated tests --- .../Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php | 3 ++- src/Symfony/Component/BrowserKit/Client.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php index 2c7391a00bbda..481a860aab132 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php @@ -284,7 +284,8 @@ public function endTest($test, $time) foreach ($deprecations ? unserialize($deprecations) : array() as $deprecation) { $error = serialize(array('deprecation' => $deprecation[1], 'class' => $className, 'method' => $test->getName(false), 'triggering_file' => isset($deprecation[2]) ? $deprecation[2] : null)); if ($deprecation[0]) { - @trigger_error($error, E_USER_DEPRECATED); + // unsilenced on purpose + trigger_error($error, E_USER_DEPRECATED); } else { @trigger_error($error, E_USER_DEPRECATED); } diff --git a/src/Symfony/Component/BrowserKit/Client.php b/src/Symfony/Component/BrowserKit/Client.php index 98553353d8ce3..6c3bcc1663981 100644 --- a/src/Symfony/Component/BrowserKit/Client.php +++ b/src/Symfony/Component/BrowserKit/Client.php @@ -361,7 +361,8 @@ protected function doRequestInProcess($request) unlink($deprecationsFile); foreach ($deprecations ? unserialize($deprecations) : [] as $deprecation) { if ($deprecation[0]) { - @trigger_error($deprecation[1], E_USER_DEPRECATED); + // unsilenced on purpose + trigger_error($deprecation[1], E_USER_DEPRECATED); } else { @trigger_error($deprecation[1], E_USER_DEPRECATED); } From 9ad324ba2979fba6481dfc76258b8872a684ad0a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 9 Jun 2019 16:44:28 +0200 Subject: [PATCH 018/106] [Form] test case is not legacy --- .../Form/Tests/Extension/Core/Type/ChoiceTypeTest.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php index 4a7f006f6f2ec..bb7cc0ca7f757 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -725,10 +725,7 @@ public function testSubmitMultipleChoiceExpandedWithEmptyDataAndInitialData() $this->assertSame(['test'], $form->getData()); } - /** - * @group legacy - */ - public function testLegacyNullChoices() + public function testNullChoices() { $form = $this->factory->create(static::TESTED_TYPE, null, [ 'multiple' => false, From adc7e6ab7cd70f9faaec5b2ab6cf1dd9b350f0eb Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 8 Jun 2019 10:05:38 +0200 Subject: [PATCH 019/106] [OptionsResolver] fix adding $triggerDeprecation to Options::offsetGet() --- src/Symfony/Component/OptionsResolver/Options.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Symfony/Component/OptionsResolver/Options.php b/src/Symfony/Component/OptionsResolver/Options.php index d18374cb91f6b..d444ec4230d51 100644 --- a/src/Symfony/Component/OptionsResolver/Options.php +++ b/src/Symfony/Component/OptionsResolver/Options.php @@ -16,8 +16,6 @@ * * @author Bernhard Schussek * @author Tobias Schultze - * - * @method mixed offsetGet(string $option, bool $triggerDeprecation = true) */ interface Options extends \ArrayAccess, \Countable { From 1872a5af3940fa94a3cd404f17ad36bf9a4d5a21 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 9 Jun 2019 18:36:33 +0200 Subject: [PATCH 020/106] [WebProfilerBundle] fix FC with HttpFoundation v5 --- .../Controller/ProfilerController.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php index d798c03214556..8021451601b38 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php @@ -140,9 +140,7 @@ public function toolbarAction(Request $request, $token) throw new NotFoundHttpException('The profiler must be enabled.'); } - $session = $request->getSession(); - - if (null !== $session && $session->isStarted() && $session->getFlashBag() instanceof AutoExpireFlashBag) { + if ($request->hasSession() && ($session = $request->getSession()) && $session->isStarted() && $session->getFlashBag() instanceof AutoExpireFlashBag) { // keep current flashes for one more request if using AutoExpireFlashBag $session->getFlashBag()->setAll($session->getFlashBag()->peekAll()); } @@ -199,7 +197,7 @@ public function searchBarAction(Request $request) $this->cspHandler->disableCsp(); } - if (null === $session = $request->getSession()) { + if (!$request->hasSession()) { $ip = $method = $statusCode = @@ -209,6 +207,8 @@ public function searchBarAction(Request $request) $limit = $token = null; } else { + $session = $request->getSession(); + $ip = $request->query->get('ip', $session->get('_profiler_search_ip')); $method = $request->query->get('method', $session->get('_profiler_search_method')); $statusCode = $request->query->get('status_code', $session->get('_profiler_search_status_code')); @@ -308,7 +308,9 @@ public function searchAction(Request $request) $limit = $request->query->get('limit'); $token = $request->query->get('token'); - if (null !== $session = $request->getSession()) { + if ($request->hasSession()) { + $session = $request->getSession(); + $session->set('_profiler_search_ip', $ip); $session->set('_profiler_search_method', $method); $session->set('_profiler_search_status_code', $statusCode); From 3aec2acce5607b649bbad305f20c5acfc30e41b5 Mon Sep 17 00:00:00 2001 From: Timo Bakx Date: Sun, 9 Jun 2019 21:04:57 +0200 Subject: [PATCH 021/106] [Messenger] Doctrine Connection find and findAll now correctly decode headers --- .../Transport/Doctrine/ConnectionTest.php | 86 +++++++++++++++++++ .../Transport/Doctrine/Connection.php | 17 +++- 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php index 1196be9f081e3..766be32f332a0 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php @@ -230,4 +230,90 @@ public function testItThrowsAnExceptionIfAnExtraOptionsInDefinedInDSN() { Connection::buildConfiguration('doctrine://default?new_option=woops'); } + + public function testFind() + { + $queryBuilder = $this->getQueryBuilderMock(); + $driverConnection = $this->getDBALConnectionMock(); + $schemaSynchronizer = $this->getSchemaSynchronizerMock(); + $id = 1; + $stmt = $this->getStatementMock([ + 'id' => $id, + 'body' => '{"message":"Hi"}', + 'headers' => \json_encode(['type' => DummyMessage::class]), + ]); + + $driverConnection + ->method('createQueryBuilder') + ->willReturn($queryBuilder); + $queryBuilder + ->method('where') + ->willReturn($queryBuilder); + $queryBuilder + ->method('getSQL') + ->willReturn(''); + $queryBuilder + ->method('getParameters') + ->willReturn([]); + $driverConnection + ->method('prepare') + ->willReturn($stmt); + + $connection = new Connection([], $driverConnection, $schemaSynchronizer); + $doctrineEnvelope = $connection->find($id); + $this->assertEquals(1, $doctrineEnvelope['id']); + $this->assertEquals('{"message":"Hi"}', $doctrineEnvelope['body']); + $this->assertEquals(['type' => DummyMessage::class], $doctrineEnvelope['headers']); + } + + public function testFindAll() + { + $queryBuilder = $this->getQueryBuilderMock(); + $driverConnection = $this->getDBALConnectionMock(); + $schemaSynchronizer = $this->getSchemaSynchronizerMock(); + $message1 = [ + 'id' => 1, + 'body' => '{"message":"Hi"}', + 'headers' => \json_encode(['type' => DummyMessage::class]), + ]; + $message2 = [ + 'id' => 2, + 'body' => '{"message":"Hi again"}', + 'headers' => \json_encode(['type' => DummyMessage::class]), + ]; + + $stmt = $this->getMockBuilder(Statement::class) + ->disableOriginalConstructor() + ->getMock(); + $stmt->expects($this->once()) + ->method('fetchAll') + ->willReturn([$message1, $message2]); + + $driverConnection + ->method('createQueryBuilder') + ->willReturn($queryBuilder); + $queryBuilder + ->method('where') + ->willReturn($queryBuilder); + $queryBuilder + ->method('getSQL') + ->willReturn(''); + $queryBuilder + ->method('getParameters') + ->willReturn([]); + $driverConnection + ->method('prepare') + ->willReturn($stmt); + + $connection = new Connection([], $driverConnection, $schemaSynchronizer); + $doctrineEnvelopes = $connection->findAll(); + + $this->assertEquals(1, $doctrineEnvelopes[0]['id']); + $this->assertEquals('{"message":"Hi"}', $doctrineEnvelopes[0]['body']); + $this->assertEquals(['type' => DummyMessage::class], $doctrineEnvelopes[0]['headers']); + + $this->assertEquals(2, $doctrineEnvelopes[1]['id']); + $this->assertEquals('{"message":"Hi again"}', $doctrineEnvelopes[1]['body']); + $this->assertEquals(['type' => DummyMessage::class], $doctrineEnvelopes[1]['headers']); + } } diff --git a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php index bd528b5b431b0..9918b25e16df6 100644 --- a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php @@ -155,7 +155,7 @@ public function get(): ?array return null; } - $doctrineEnvelope['headers'] = \json_decode($doctrineEnvelope['headers'], true); + $doctrineEnvelope = $this->decodeEnvelopeHeaders($doctrineEnvelope); $queryBuilder = $this->driverConnection->createQueryBuilder() ->update($this->configuration['table_name']) @@ -238,7 +238,11 @@ public function findAll(int $limit = null): array $queryBuilder->setMaxResults($limit); } - return $this->executeQuery($queryBuilder->getSQL(), $queryBuilder->getParameters())->fetchAll(); + $data = $this->executeQuery($queryBuilder->getSQL(), $queryBuilder->getParameters())->fetchAll(); + + return \array_map(function ($doctrineEnvelope) { + return $this->decodeEnvelopeHeaders($doctrineEnvelope); + }, $data); } public function find($id): ?array @@ -254,7 +258,7 @@ public function find($id): ?array 'id' => $id, ])->fetch(); - return false === $data ? null : $data; + return false === $data ? null : $this->decodeEnvelopeHeaders($data); } private function createAvailableMessagesQueryBuilder(): QueryBuilder @@ -332,4 +336,11 @@ public static function formatDateTime(\DateTimeInterface $dateTime) { return $dateTime->format('Y-m-d\TH:i:s'); } + + private function decodeEnvelopeHeaders(array $doctrineEnvelope): array + { + $doctrineEnvelope['headers'] = \json_decode($doctrineEnvelope['headers'], true); + + return $doctrineEnvelope; + } } From ff5517e554bdd15c543930edf0ec25819dca3bc9 Mon Sep 17 00:00:00 2001 From: Alexandre Segura Date: Mon, 10 Jun 2019 10:21:04 +0200 Subject: [PATCH 022/106] Add missing rendering of form help block. --- .../Twig/Resources/views/Form/bootstrap_3_layout.html.twig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig index 11e8f3f70b590..09d21809940cf 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig @@ -114,6 +114,7 @@
{{- form_label(form) }} {# -#} {{ form_widget(form, widget_attr) }} {# -#} + {{- form_help(form) -}} {{ form_errors(form) }} {# -#}
{# -#} {%- endblock form_row %} From 4a7989456bfd37d3ccb1ff28b2b91290e5e2e18f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 10 Jun 2019 19:33:26 +0200 Subject: [PATCH 023/106] [HttpClient] fix Psr18Client handling of non-200 response codes --- src/Symfony/Component/HttpClient/Psr18Client.php | 4 ++-- .../Component/HttpClient/Tests/Psr18ClientTest.php | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Psr18Client.php b/src/Symfony/Component/HttpClient/Psr18Client.php index 17a3d3bd116ac..a438b7ce94ee4 100644 --- a/src/Symfony/Component/HttpClient/Psr18Client.php +++ b/src/Symfony/Component/HttpClient/Psr18Client.php @@ -73,13 +73,13 @@ public function sendRequest(RequestInterface $request): ResponseInterface $psrResponse = $this->responseFactory->createResponse($response->getStatusCode()); - foreach ($response->getHeaders() as $name => $values) { + foreach ($response->getHeaders(false) as $name => $values) { foreach ($values as $value) { $psrResponse = $psrResponse->withAddedHeader($name, $value); } } - return $psrResponse->withBody($this->streamFactory->createStream($response->getContent())); + return $psrResponse->withBody($this->streamFactory->createStream($response->getContent(false))); } catch (TransportExceptionInterface $e) { if ($e instanceof \InvalidArgumentException) { throw new Psr18RequestException($e, $request); diff --git a/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php b/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php index edb2891a374ff..87b2a7ce0bd16 100644 --- a/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php @@ -74,4 +74,13 @@ public function testRequestException() $this->expectException(Psr18RequestException::class); $client->sendRequest($factory->createRequest('BAD.METHOD', 'http://localhost:8057')); } + + public function test404() + { + $factory = new Psr17Factory(); + $client = new Psr18Client(new NativeHttpClient()); + + $response = $client->sendRequest($factory->createRequest('GET', 'http://localhost:8057/404')); + $this->assertSame(404, $response->getStatusCode()); + } } From 87c1d19e72cb15f401eb2f67a0b733c11f755728 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 11 Jun 2019 09:45:15 +0200 Subject: [PATCH 024/106] add back possibility to use form themes without translations --- src/Symfony/Bridge/Twig/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index c5dbb1247a07c..bd6a61f4ee104 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -17,6 +17,7 @@ ], "require": { "php": "^7.1.3", + "symfony/translation-contracts": "^1.1", "twig/twig": "^1.41|^2.10" }, "require-dev": { From 48be09f37eb61226e4e388c74771b1b9229d29c7 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 11 Jun 2019 12:48:01 +0200 Subject: [PATCH 025/106] [HttpKernel] Remove TestEventDispatcher. --- .../Tests/Fixtures/TestEventDispatcher.php | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 src/Symfony/Component/HttpKernel/Tests/Fixtures/TestEventDispatcher.php diff --git a/src/Symfony/Component/HttpKernel/Tests/Fixtures/TestEventDispatcher.php b/src/Symfony/Component/HttpKernel/Tests/Fixtures/TestEventDispatcher.php deleted file mode 100644 index dc9c9166f9f25..0000000000000 --- a/src/Symfony/Component/HttpKernel/Tests/Fixtures/TestEventDispatcher.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Tests\Fixtures; - -use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface; -use Symfony\Component\EventDispatcher\EventDispatcher; - -class TestEventDispatcher extends EventDispatcher implements TraceableEventDispatcherInterface -{ - public function getCalledListeners() - { - return ['foo']; - } - - public function getNotCalledListeners() - { - return ['bar']; - } - - public function reset() - { - } -} From 3eba36c0887f79b67bff0fb0fd0d66ec8e045389 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 11 Jun 2019 12:37:46 +0200 Subject: [PATCH 026/106] [Mailer] Catch missing scheme in DSN. --- src/Symfony/Component/Mailer/Tests/TransportTest.php | 11 +++++++++-- src/Symfony/Component/Mailer/Transport.php | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Mailer/Tests/TransportTest.php b/src/Symfony/Component/Mailer/Tests/TransportTest.php index 0d1f14326256f..9f014c6fa504e 100644 --- a/src/Symfony/Component/Mailer/Tests/TransportTest.php +++ b/src/Symfony/Component/Mailer/Tests/TransportTest.php @@ -69,11 +69,18 @@ public function testFromInvalidDsn() Transport::fromDsn('some://'); } + public function testNoScheme() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The "//sendmail" mailer DSN must contain a transport scheme.'); + Transport::fromDsn('//sendmail'); + } + public function testFromInvalidDsnNoHost() { $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('The "?!" mailer DSN must contain a mailer name.'); - Transport::fromDsn('?!'); + $this->expectExceptionMessage('The "file:///some/path" mailer DSN must contain a mailer name.'); + Transport::fromDsn('file:///some/path'); } public function testFromInvalidTransportName() diff --git a/src/Symfony/Component/Mailer/Transport.php b/src/Symfony/Component/Mailer/Transport.php index eeb1892fe8b3c..c27dd35614939 100644 --- a/src/Symfony/Component/Mailer/Transport.php +++ b/src/Symfony/Component/Mailer/Transport.php @@ -64,6 +64,10 @@ private static function createTransport(string $dsn, EventDispatcherInterface $d throw new InvalidArgumentException(sprintf('The "%s" mailer DSN is invalid.', $dsn)); } + if (!isset($parsedDsn['scheme'])) { + throw new InvalidArgumentException(sprintf('The "%s" mailer DSN must contain a transport scheme.', $dsn)); + } + if (!isset($parsedDsn['host'])) { throw new InvalidArgumentException(sprintf('The "%s" mailer DSN must contain a mailer name.', $dsn)); } From 284262a21930d84f3202681b20516a8d203a0b30 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 11 Jun 2019 10:50:51 +0200 Subject: [PATCH 027/106] collect called listeners information only once --- .../Debug/TraceableEventDispatcher.php | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php index 7716d8663177e..8768d7b14145f 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php @@ -224,22 +224,22 @@ public function getNotCalledListeners(/* Request $request = null */) } $hash = 1 <= \func_num_args() && null !== ($request = \func_get_arg(0)) ? spl_object_hash($request) : null; + $calledListeners = []; + + if (null !== $this->callStack) { + foreach ($this->callStack as $calledListener) { + list(, $requestHash) = $this->callStack->getInfo(); + + if (null === $hash || $hash === $requestHash) { + $calledListeners[] = $calledListener->getWrappedListener(); + } + } + } + $notCalled = []; foreach ($allListeners as $eventName => $listeners) { foreach ($listeners as $listener) { - $called = false; - if (null !== $this->callStack) { - foreach ($this->callStack as $calledListener) { - list(, $requestHash) = $this->callStack->getInfo(); - if ((null === $hash || $hash === $requestHash) && $calledListener->getWrappedListener() === $listener) { - $called = true; - - break; - } - } - } - - if (!$called) { + if (!\in_array($listener, $calledListeners, true)) { if (!$listener instanceof WrappedListener) { $listener = new WrappedListener($listener, null, $this->stopwatch, $this); } From 7a2f9bf134fae35bda7451d24f9056cc26fdbd9e Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 11 Jun 2019 11:52:08 +0200 Subject: [PATCH 028/106] fixed sender/recipients in SMTP Envelope --- .../Component/Mailer/DelayedSmtpEnvelope.php | 6 ++++-- .../Component/Mailer/Tests/SmtpEnvelopeTest.php | 15 +++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Mailer/DelayedSmtpEnvelope.php b/src/Symfony/Component/Mailer/DelayedSmtpEnvelope.php index ef677d7de8a86..479fc5be42161 100644 --- a/src/Symfony/Component/Mailer/DelayedSmtpEnvelope.php +++ b/src/Symfony/Component/Mailer/DelayedSmtpEnvelope.php @@ -47,7 +47,7 @@ public function getSender(): Address return parent::getSender(); } - return self::getSenderFromHeaders($this->message->getHeaders()); + return new Address(self::getSenderFromHeaders($this->message->getHeaders())->getAddress()); } public function setRecipients(array $recipients): void @@ -74,7 +74,9 @@ private static function getRecipientsFromHeaders(Headers $headers): array $recipients = []; foreach (['to', 'cc', 'bcc'] as $name) { foreach ($headers->getAll($name) as $header) { - $recipients = array_merge($recipients, $header->getAddresses()); + foreach ($header->getAddresses() as $address) { + $recipients[] = new Address($address->getAddress()); + } } } diff --git a/src/Symfony/Component/Mailer/Tests/SmtpEnvelopeTest.php b/src/Symfony/Component/Mailer/Tests/SmtpEnvelopeTest.php index e64be3100bb12..7b32ed4d73703 100644 --- a/src/Symfony/Component/Mailer/Tests/SmtpEnvelopeTest.php +++ b/src/Symfony/Component/Mailer/Tests/SmtpEnvelopeTest.php @@ -17,7 +17,6 @@ use Symfony\Component\Mime\Header\Headers; use Symfony\Component\Mime\Message; use Symfony\Component\Mime\NamedAddress; -use Symfony\Component\Mime\RawMessage; class SmtpEnvelopeTest extends TestCase { @@ -54,19 +53,19 @@ public function testConstructorWithWrongRecipients() public function testSenderFromHeaders() { $headers = new Headers(); - $headers->addPathHeader('Return-Path', 'return@symfony.com'); + $headers->addPathHeader('Return-Path', new NamedAddress('return@symfony.com', 'return')); $headers->addMailboxListHeader('To', ['from@symfony.com']); $e = SmtpEnvelope::create(new Message($headers)); $this->assertEquals('return@symfony.com', $e->getSender()->getAddress()); $headers = new Headers(); - $headers->addMailboxHeader('Sender', 'sender@symfony.com'); + $headers->addMailboxHeader('Sender', new NamedAddress('sender@symfony.com', 'sender')); $headers->addMailboxListHeader('To', ['from@symfony.com']); $e = SmtpEnvelope::create(new Message($headers)); $this->assertEquals('sender@symfony.com', $e->getSender()->getAddress()); $headers = new Headers(); - $headers->addMailboxListHeader('From', ['from@symfony.com', 'some@symfony.com']); + $headers->addMailboxListHeader('From', [new NamedAddress('from@symfony.com', 'from'), 'some@symfony.com']); $headers->addMailboxListHeader('To', ['from@symfony.com']); $e = SmtpEnvelope::create(new Message($headers)); $this->assertEquals('from@symfony.com', $e->getSender()->getAddress()); @@ -77,7 +76,7 @@ public function testSenderFromHeadersWithoutFrom() $headers = new Headers(); $headers->addMailboxListHeader('To', ['from@symfony.com']); $e = SmtpEnvelope::create($message = new Message($headers)); - $message->getHeaders()->addMailboxListHeader('From', ['from@symfony.com']); + $message->getHeaders()->addMailboxListHeader('From', [new NamedAddress('from@symfony.com', 'from')]); $this->assertEquals('from@symfony.com', $e->getSender()->getAddress()); } @@ -85,9 +84,9 @@ public function testRecipientsFromHeaders() { $headers = new Headers(); $headers->addPathHeader('Return-Path', 'return@symfony.com'); - $headers->addMailboxListHeader('To', ['to@symfony.com']); - $headers->addMailboxListHeader('Cc', ['cc@symfony.com']); - $headers->addMailboxListHeader('Bcc', ['bcc@symfony.com']); + $headers->addMailboxListHeader('To', [new NamedAddress('to@symfony.com', 'to')]); + $headers->addMailboxListHeader('Cc', [new NamedAddress('cc@symfony.com', 'cc')]); + $headers->addMailboxListHeader('Bcc', [new NamedAddress('bcc@symfony.com', 'bcc')]); $e = SmtpEnvelope::create(new Message($headers)); $this->assertEquals([new Address('to@symfony.com'), new Address('cc@symfony.com'), new Address('bcc@symfony.com')], $e->getRecipients()); } From 496c118c3ac9303666ef0921c50873115d2e9695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Tue, 11 Jun 2019 23:42:17 +0200 Subject: [PATCH 029/106] Restore compatibility with php 5.5 The ARRAY_FILTER_USE_KEY constant was introduced in php 5.6, let us avoid it for now. See https://www.php.net/manual/en/function.array-filter.php#refsect1-function.array-filter-changelog --- .../PhpUnit/DeprecationErrorHandler/Configuration.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php index 44f0341205aa7..6b42814bbc906 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php @@ -90,9 +90,12 @@ public function isEnabled() */ public function tolerates(array $deprecations) { - $deprecationCounts = array_filter($deprecations, function ($key) { - return false !== strpos($key, 'Count') && false === strpos($key, 'legacy'); - }, ARRAY_FILTER_USE_KEY); + $deprecationCounts = []; + foreach ($deprecations as $key => $deprecation) { + if (false !== strpos($key, 'Count') && false === strpos($key, 'legacy')) { + $deprecationCounts[$key] = $deprecation; + } + } if (array_sum($deprecationCounts) > $this->thresholds['total']) { return false; From 8e04222976043af4b5a23c63ecbc3f35891d7db0 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Wed, 12 Jun 2019 03:01:18 +0200 Subject: [PATCH 030/106] [Routing] fix absolute url generation when scheme is not known --- .../Routing/Generator/UrlGenerator.php | 20 ++++---- .../Tests/Generator/UrlGeneratorTest.php | 48 +++++++++++++++---- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/Symfony/Component/Routing/Generator/UrlGenerator.php b/src/Symfony/Component/Routing/Generator/UrlGenerator.php index b87f4bb5c45f7..3a826d86f60a9 100644 --- a/src/Symfony/Component/Routing/Generator/UrlGenerator.php +++ b/src/Symfony/Component/Routing/Generator/UrlGenerator.php @@ -222,16 +222,18 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa } } - if ((self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) && !empty($host)) { - $port = ''; - if ('http' === $scheme && 80 != $this->context->getHttpPort()) { - $port = ':'.$this->context->getHttpPort(); - } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) { - $port = ':'.$this->context->getHttpsPort(); - } + if (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) { + if ('' !== $host || ('' !== $scheme && 'http' !== $scheme && 'https' !== $scheme)) { + $port = ''; + if ('http' === $scheme && 80 !== $this->context->getHttpPort()) { + $port = ':'.$this->context->getHttpPort(); + } elseif ('https' === $scheme && 443 !== $this->context->getHttpsPort()) { + $port = ':'.$this->context->getHttpsPort(); + } - $schemeAuthority = self::NETWORK_PATH === $referenceType ? '//' : "$scheme://"; - $schemeAuthority .= $host.$port; + $schemeAuthority = self::NETWORK_PATH === $referenceType || '' === $scheme ? '//' : "$scheme://"; + $schemeAuthority .= $host.$port; + } } if (self::RELATIVE_PATH === $referenceType) { diff --git a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php index 7f64a1f378326..a4d754cb14a6c 100644 --- a/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php +++ b/src/Symfony/Component/Routing/Tests/Generator/UrlGeneratorTest.php @@ -480,28 +480,27 @@ public function testHostIsCaseInsensitive() public function testDefaultHostIsUsedWhenContextHostIsEmpty() { - $routes = $this->getRoutes('test', new Route('/route', ['domain' => 'my.fallback.host'], ['domain' => '.+'], [], '{domain}', ['http'])); + $routes = $this->getRoutes('test', new Route('/path', ['domain' => 'my.fallback.host'], ['domain' => '.+'], [], '{domain}')); $generator = $this->getGenerator($routes); $generator->getContext()->setHost(''); - $this->assertSame('http://my.fallback.host/app.php/route', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL)); + $this->assertSame('http://my.fallback.host/app.php/path', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL)); } - public function testDefaultHostIsUsedWhenContextHostIsEmptyAndSchemeIsNot() + public function testDefaultHostIsUsedWhenContextHostIsEmptyAndPathReferenceType() { - $routes = $this->getRoutes('test', new Route('/route', ['domain' => 'my.fallback.host'], ['domain' => '.+'], [], '{domain}', ['http', 'https'])); + $routes = $this->getRoutes('test', new Route('/path', ['domain' => 'my.fallback.host'], ['domain' => '.+'], [], '{domain}')); $generator = $this->getGenerator($routes); $generator->getContext()->setHost(''); - $generator->getContext()->setScheme('https'); - $this->assertSame('https://my.fallback.host/app.php/route', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL)); + $this->assertSame('//my.fallback.host/app.php/path', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_PATH)); } - public function testAbsoluteUrlFallbackToRelativeIfHostIsEmptyAndSchemeIsNot() + public function testAbsoluteUrlFallbackToPathIfHostIsEmptyAndSchemeIsHttp() { - $routes = $this->getRoutes('test', new Route('/route', [], [], [], '', ['http', 'https'])); + $routes = $this->getRoutes('test', new Route('/route')); $generator = $this->getGenerator($routes); $generator->getContext()->setHost(''); @@ -510,6 +509,39 @@ public function testAbsoluteUrlFallbackToRelativeIfHostIsEmptyAndSchemeIsNot() $this->assertSame('/app.php/route', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL)); } + public function testAbsoluteUrlFallbackToNetworkIfSchemeIsEmptyAndHostIsNot() + { + $routes = $this->getRoutes('test', new Route('/path')); + + $generator = $this->getGenerator($routes); + $generator->getContext()->setHost('example.com'); + $generator->getContext()->setScheme(''); + + $this->assertSame('//example.com/app.php/path', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL)); + } + + public function testAbsoluteUrlFallbackToPathIfSchemeAndHostAreEmpty() + { + $routes = $this->getRoutes('test', new Route('/path')); + + $generator = $this->getGenerator($routes); + $generator->getContext()->setHost(''); + $generator->getContext()->setScheme(''); + + $this->assertSame('/app.php/path', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL)); + } + + public function testAbsoluteUrlWithNonHttpSchemeAndEmptyHost() + { + $routes = $this->getRoutes('test', new Route('/path', [], [], [], '', ['file'])); + + $generator = $this->getGenerator($routes); + $generator->getContext()->setBaseUrl(''); + $generator->getContext()->setHost(''); + + $this->assertSame('file:///path', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL)); + } + public function testGenerateNetworkPath() { $routes = $this->getRoutes('test', new Route('/{name}', [], [], [], '{locale}.example.com', ['http'])); From a9705a014393be7e789643aef621147126e8d627 Mon Sep 17 00:00:00 2001 From: Tomas Date: Wed, 12 Jun 2019 07:10:29 +0300 Subject: [PATCH 031/106] Fix AuthenticationException::getToken typehint --- .../Security/Core/Exception/AuthenticationException.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php b/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php index 2c6c7344a467f..f79cf3ecf2ac9 100644 --- a/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php +++ b/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php @@ -26,7 +26,7 @@ class AuthenticationException extends \RuntimeException implements \Serializable /** * Get the token. * - * @return TokenInterface + * @return TokenInterface|null */ public function getToken() { From 8bdc6596ef1509b256bae8bb31d066252fa92417 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 12 Jun 2019 06:53:11 +0200 Subject: [PATCH 032/106] [Mailer] made code more robust --- src/Symfony/Component/Mailer/SmtpEnvelope.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Mailer/SmtpEnvelope.php b/src/Symfony/Component/Mailer/SmtpEnvelope.php index 7f1458d0f8bda..cf8e08285c7e1 100644 --- a/src/Symfony/Component/Mailer/SmtpEnvelope.php +++ b/src/Symfony/Component/Mailer/SmtpEnvelope.php @@ -13,7 +13,6 @@ use Symfony\Component\Mailer\Exception\InvalidArgumentException; use Symfony\Component\Mime\Address; -use Symfony\Component\Mime\NamedAddress; use Symfony\Component\Mime\RawMessage; /** @@ -42,7 +41,7 @@ public static function create(RawMessage $message): self public function setSender(Address $sender): void { - $this->sender = $sender instanceof NamedAddress ? new Address($sender->getAddress()) : $sender; + $this->sender = new Address($sender->getAddress()); } public function getSender(): Address @@ -50,6 +49,9 @@ public function getSender(): Address return $this->sender; } + /** + * @param Address[] $recipients + */ public function setRecipients(array $recipients): void { if (!$recipients) { @@ -58,12 +60,10 @@ public function setRecipients(array $recipients): void $this->recipients = []; foreach ($recipients as $recipient) { - if ($recipient instanceof NamedAddress) { - $recipient = new Address($recipient->getAddress()); - } elseif (!$recipient instanceof Address) { + if (!$recipient instanceof Address) { throw new InvalidArgumentException(sprintf('A recipient must be an instance of "%s" (got "%s").', Address::class, \is_object($recipient) ? \get_class($recipient) : \gettype($recipient))); } - $this->recipients[] = $recipient; + $this->recipients[] = new Address($recipient->getAddress()); } } From b9eab4282315f0af0dcf56c0d054f9d97c4d9182 Mon Sep 17 00:00:00 2001 From: Mateusz Lerczak Date: Wed, 12 Jun 2019 12:36:09 +0200 Subject: [PATCH 033/106] Add statement to fileLink to ignore href code when no fileLink. --- .../FrameworkBundle/Console/Descriptor/TextDescriptor.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php index 323f9ae250bd2..796beaee01441 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -557,8 +557,11 @@ private function formatControllerLink($controller, string $anchorText): string } $fileLink = $this->fileLinkFormatter->format($r->getFileName(), $r->getStartLine()); + if ($fileLink) { + return sprintf('%s', $fileLink, $anchorText); + } - return sprintf('%s', $fileLink, $anchorText); + return $anchorText; } private function formatCallable($callable): string From 21857a1edb5a69f16fb72cf2a90af7ef86606142 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 12 Jun 2019 15:33:27 +0200 Subject: [PATCH 034/106] [HttpClient] fix closing debug stream prematurely --- src/Symfony/Component/HttpClient/Response/CurlResponse.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 1c5114e92f461..0c615bab04514 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -168,8 +168,8 @@ public function getInfo(string $type = null) rewind($this->debugBuffer); $info['debug'] = stream_get_contents($this->debugBuffer); curl_setopt($this->handle, CURLOPT_VERBOSE, false); - fclose($this->debugBuffer); - $this->debugBuffer = null; + rewind($this->debugBuffer); + ftruncate($this->debugBuffer, 0); $this->finalInfo = $info; } } From 9cbeb63613bae183c396b7b7e54f61306a8db4e7 Mon Sep 17 00:00:00 2001 From: Michael Bessolov Date: Wed, 12 Jun 2019 23:04:51 -0700 Subject: [PATCH 035/106] Added missing required dependencies on psr/cache and psr/container in symfony/cache-contracts and symfony/service-contracts respectively. --- src/Symfony/Contracts/Cache/composer.json | 4 ++-- src/Symfony/Contracts/Service/composer.json | 4 ++-- src/Symfony/Contracts/composer.json | 8 +++----- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Contracts/Cache/composer.json b/src/Symfony/Contracts/Cache/composer.json index d5d7e99b9ffef..4e0bd1a422700 100644 --- a/src/Symfony/Contracts/Cache/composer.json +++ b/src/Symfony/Contracts/Cache/composer.json @@ -16,10 +16,10 @@ } ], "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "psr/cache": "^1.0" }, "suggest": { - "psr/cache": "", "symfony/cache-implementation": "" }, "autoload": { diff --git a/src/Symfony/Contracts/Service/composer.json b/src/Symfony/Contracts/Service/composer.json index 54341174ceb98..f4209cc41c48f 100644 --- a/src/Symfony/Contracts/Service/composer.json +++ b/src/Symfony/Contracts/Service/composer.json @@ -16,10 +16,10 @@ } ], "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "psr/container": "^1.0" }, "suggest": { - "psr/container": "", "symfony/service-implementation": "" }, "autoload": { diff --git a/src/Symfony/Contracts/composer.json b/src/Symfony/Contracts/composer.json index f78ba697db26e..b9277e1dd1615 100644 --- a/src/Symfony/Contracts/composer.json +++ b/src/Symfony/Contracts/composer.json @@ -16,11 +16,11 @@ } ], "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "psr/cache": "^1.0", + "psr/container": "^1.0" }, "require-dev": { - "psr/cache": "^1.0", - "psr/container": "^1.0", "symfony/polyfill-intl-idn": "^1.10" }, "replace": { @@ -31,8 +31,6 @@ "symfony/translation-contracts": "self.version" }, "suggest": { - "psr/cache": "When using the Cache contracts", - "psr/container": "When using the Service contracts", "psr/event-dispatcher": "When using the EventDispatcher contracts", "symfony/cache-implementation": "", "symfony/event-dispatcher-implementation": "", From 31bdfb372c408f64592f17d1c720899c852df6a1 Mon Sep 17 00:00:00 2001 From: Mponos George Date: Wed, 12 Jun 2019 17:14:20 +0300 Subject: [PATCH 036/106] Do not log or call the proxy function when the locale is the same --- src/Symfony/Component/Translation/LoggingTranslator.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Translation/LoggingTranslator.php b/src/Symfony/Component/Translation/LoggingTranslator.php index 3a84bf117050c..2996167d08918 100644 --- a/src/Symfony/Component/Translation/LoggingTranslator.php +++ b/src/Symfony/Component/Translation/LoggingTranslator.php @@ -84,6 +84,10 @@ public function setLocale($locale) { $prev = $this->translator->getLocale(); $this->translator->setLocale($locale); + if ($prev === $locale) { + return; + } + $this->logger->debug(sprintf('The locale of the translator has changed from "%s" to "%s".', $prev, $locale)); } From 106b348d3d2ead35e7f9121b94558666992e07db Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 13 Jun 2019 12:34:15 +0200 Subject: [PATCH 037/106] fixed CS --- .php_cs.dist | 2 +- .../Doctrine/Test/DoctrineTestHelper.php | 2 +- .../Constraints/UniqueEntityValidator.php | 2 +- .../LazyProxy/PhpDumper/ProxyDumper.php | 4 +-- .../LazyProxy/PhpDumper/ProxyDumperTest.php | 2 +- .../Twig/Tests/Command/DebugCommandTest.php | 8 +++--- .../Bridge/Twig/UndefinedCallableHandler.php | 2 +- .../Component/Cache/Traits/PhpArrayTrait.php | 2 +- .../Component/Cache/Traits/PhpFilesTrait.php | 2 +- .../Component/Debug/DebugClassLoader.php | 26 +++++++++---------- .../Component/Filesystem/Filesystem.php | 6 ++--- .../Storage/Handler/PdoSessionHandler.php | 2 +- .../DataCollector/TimeDataCollector.php | 2 +- .../HttpCache/ResponseCacheStrategy.php | 6 ++--- .../HttpCache/SubRequestHandler.php | 2 +- .../DataCollector/TimeDataCollectorTest.php | 2 +- .../Authentication/Token/AbstractToken.php | 2 +- .../Authentication/Token/AnonymousToken.php | 2 +- .../Token/PreAuthenticatedToken.php | 2 +- .../Authentication/Token/RememberMeToken.php | 2 +- .../Token/UsernamePasswordToken.php | 2 +- .../Core/Encoder/Argon2iPasswordEncoder.php | 10 +++---- .../Core/Exception/AccountStatusException.php | 2 +- .../Exception/AuthenticationException.php | 2 +- ...stomUserMessageAuthenticationException.php | 2 +- .../Exception/UsernameNotFoundException.php | 2 +- .../Token/AbstractTokenTest.php | 2 +- .../Token/PostAuthenticationGuardToken.php | 2 +- .../SimpleFormAuthenticationListener.php | 2 +- ...namePasswordFormAuthenticationListener.php | 2 +- .../Normalizer/AbstractNormalizer.php | 2 +- .../Normalizer/AbstractObjectNormalizer.php | 2 +- .../Normalizer/ObjectNormalizer.php | 2 +- .../Component/Serializer/Serializer.php | 8 +++--- .../Resources/bin/translation-status.php | 8 +++--- .../Component/VarDumper/Cloner/VarCloner.php | 20 +++++++------- 36 files changed, 75 insertions(+), 75 deletions(-) diff --git a/.php_cs.dist b/.php_cs.dist index 8523be670698e..85c75692eb44f 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -15,7 +15,7 @@ return PhpCsFixer\Config::create() 'ordered_imports' => true, 'protected_to_private' => false, // Part of @Symfony:risky in PHP-CS-Fixer 2.13.0. To be removed from the config file once upgrading - 'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'namespaced'], + 'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'namespaced', 'strict' => true], // Part of future @Symfony ruleset in PHP-CS-Fixer To be removed from the config file once upgrading 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], ]) diff --git a/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php b/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php index 3f6ffeebb6e2d..24da0b8deec02 100644 --- a/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php +++ b/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php @@ -58,7 +58,7 @@ public static function createTestConfiguration() $config = new Configuration(); $config->setEntityNamespaces(['SymfonyTestsDoctrine' => 'Symfony\Bridge\Doctrine\Tests\Fixtures']); $config->setAutoGenerateProxyClasses(true); - $config->setProxyDir(\sys_get_temp_dir()); + $config->setProxyDir(sys_get_temp_dir()); $config->setProxyNamespace('SymfonyTests\Doctrine'); $config->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader())); $config->setQueryCacheImpl(new ArrayCache()); diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index 47cb2bd730317..cf0ed8c962101 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -186,7 +186,7 @@ private function formatWithIdentifiers(ObjectManager $em, ClassMetadata $class, return $this->formatValue($value, self::PRETTY_DATE); } - if (\method_exists($value, '__toString')) { + if (method_exists($value, '__toString')) { return (string) $value; } diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index 7c12b7015e620..7acc1c65420b7 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -58,7 +58,7 @@ public function getProxyFactoryCode(Definition $definition, $id, $factoryCode = $instantiation = 'return'; if ($definition->isShared()) { - $instantiation .= sprintf(' $this->%s[%s] =', \method_exists(ContainerBuilder::class, 'addClassResource') || ($definition->isPublic() && !$definition->isPrivate()) ? 'services' : 'privates', var_export($id, true)); + $instantiation .= sprintf(' $this->%s[%s] =', method_exists(ContainerBuilder::class, 'addClassResource') || ($definition->isPublic() && !$definition->isPrivate()) ? 'services' : 'privates', var_export($id, true)); } if (null === $factoryCode) { @@ -120,7 +120,7 @@ public function getProxyCode(Definition $definition) */ private static function getProxyManagerVersion() { - if (!\class_exists(Version::class)) { + if (!class_exists(Version::class)) { return '0.0.1'; } diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php index f0822d4616422..5328c9ae1227d 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php @@ -103,7 +103,7 @@ public function getPrivatePublicDefinitions() [ (new Definition(__CLASS__)) ->setPublic(false), - \method_exists(ContainerBuilder::class, 'addClassResource') ? 'services' : 'privates', + method_exists(ContainerBuilder::class, 'addClassResource') ? 'services' : 'privates', ], [ (new Definition(__CLASS__)) diff --git a/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php b/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php index 3b9e479da0791..2f4cc9cd870f7 100644 --- a/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php @@ -70,7 +70,7 @@ public function testWithGlobals() $display = $tester->getDisplay(); - $this->assertContains(\json_encode($message), $display); + $this->assertContains(json_encode($message), $display); } public function testWithGlobalsJson() @@ -81,7 +81,7 @@ public function testWithGlobalsJson() $tester->execute(['--format' => 'json'], ['decorated' => true]); $display = $tester->getDisplay(); - $display = \json_decode($display, true); + $display = json_decode($display, true); $this->assertSame($globals, $display['globals']); } @@ -91,11 +91,11 @@ public function testWithFilter() $tester = $this->createCommandTester([]); $tester->execute(['--format' => 'json'], ['decorated' => false]); $display = $tester->getDisplay(); - $display1 = \json_decode($display, true); + $display1 = json_decode($display, true); $tester->execute(['filter' => 'date', '--format' => 'json'], ['decorated' => false]); $display = $tester->getDisplay(); - $display2 = \json_decode($display, true); + $display2 = json_decode($display, true); $this->assertNotSame($display1, $display2); } diff --git a/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php b/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php index 8476e89cab0ee..9c2d18b4a4d6e 100644 --- a/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php +++ b/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php @@ -84,7 +84,7 @@ public static function onUndefinedFunction($name) private static function onUndefined($name, $type, $component) { - if (\class_exists(FullStack::class) && isset(self::$fullStackEnable[$component])) { + if (class_exists(FullStack::class) && isset(self::$fullStackEnable[$component])) { throw new SyntaxError(sprintf('Did you forget to %s? Unknown %s "%s".', self::$fullStackEnable[$component], $type, $name)); } diff --git a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php index e96462abf7e53..ea996a217cf13 100644 --- a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php @@ -90,7 +90,7 @@ public function warmUp(array $values) if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) { $value = serialize($value); } - } elseif (!\is_scalar($value)) { + } elseif (!is_scalar($value)) { throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, \gettype($value))); } diff --git a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php index 36c614fe65bc6..3cc02b2428486 100644 --- a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php @@ -136,7 +136,7 @@ protected function doSave(array $values, $lifetime) if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) { $value = serialize($value); } - } elseif (!\is_scalar($value)) { + } elseif (!is_scalar($value)) { throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, \gettype($value))); } diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index b728b9b90fee2..9ceac9af162b0 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -168,7 +168,7 @@ public function loadClass($class) private function checkClass($class, $file = null) { - $exists = null === $file || \class_exists($class, false) || \interface_exists($class, false) || \trait_exists($class, false); + $exists = null === $file || class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false); if (null !== $file && $class && '\\' === $class[0]) { $class = substr($class, 1); @@ -186,13 +186,13 @@ private function checkClass($class, $file = null) } $name = $refl->getName(); - if ($name !== $class && 0 === \strcasecmp($name, $class)) { + if ($name !== $class && 0 === strcasecmp($name, $class)) { throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: "%s" vs "%s".', $class, $name)); } $deprecations = $this->checkAnnotations($refl, $name); - if (isset(self::$php7Reserved[\strtolower($refl->getShortName())])) { + if (isset(self::$php7Reserved[strtolower($refl->getShortName())])) { $deprecations[] = sprintf('The "%s" class uses the reserved name "%s", it will break on PHP 7 and higher', $name, $refl->getShortName()); } @@ -223,23 +223,23 @@ public function checkAnnotations(\ReflectionClass $refl, $class) $deprecations = []; // Don't trigger deprecations for classes in the same vendor - if (2 > $len = 1 + (\strpos($class, '\\') ?: \strpos($class, '_'))) { + if (2 > $len = 1 + (strpos($class, '\\') ?: strpos($class, '_'))) { $len = 0; $ns = ''; } else { - $ns = \str_replace('_', '\\', \substr($class, 0, $len)); + $ns = str_replace('_', '\\', substr($class, 0, $len)); } // Detect annotations on the class if (false !== $doc = $refl->getDocComment()) { foreach (['final', 'deprecated', 'internal'] as $annotation) { - if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { + if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : ''; } } } - $parent = \get_parent_class($class); + $parent = get_parent_class($class); $parentAndOwnInterfaces = $this->getOwnInterfaces($class, $parent); if ($parent) { $parentAndOwnInterfaces[$parent] = $parent; @@ -254,22 +254,22 @@ public function checkAnnotations(\ReflectionClass $refl, $class) } // Detect if the parent is annotated - foreach ($parentAndOwnInterfaces + \class_uses($class, false) as $use) { + foreach ($parentAndOwnInterfaces + class_uses($class, false) as $use) { if (!isset(self::$checkedClasses[$use])) { $this->checkClass($use); } - if (isset(self::$deprecated[$use]) && \strncmp($ns, \str_replace('_', '\\', $use), $len) && !isset(self::$deprecated[$class])) { + if (isset(self::$deprecated[$use]) && strncmp($ns, str_replace('_', '\\', $use), $len) && !isset(self::$deprecated[$class])) { $type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait'); $verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses'); $deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s.', $class, $type, $verb, $use, self::$deprecated[$use]); } - if (isset(self::$internal[$use]) && \strncmp($ns, \str_replace('_', '\\', $use), $len)) { + if (isset(self::$internal[$use]) && strncmp($ns, str_replace('_', '\\', $use), $len)) { $deprecations[] = sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $class); } } - if (\trait_exists($class)) { + if (trait_exists($class)) { return $deprecations; } @@ -296,7 +296,7 @@ public function checkAnnotations(\ReflectionClass $refl, $class) if (isset(self::$internalMethods[$class][$method->name])) { list($declaringClass, $message) = self::$internalMethods[$class][$method->name]; - if (\strncmp($ns, $declaringClass, $len)) { + if (strncmp($ns, $declaringClass, $len)) { $deprecations[] = sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class); } } @@ -307,7 +307,7 @@ public function checkAnnotations(\ReflectionClass $refl, $class) } foreach (['final', 'internal'] as $annotation) { - if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { + if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { $message = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : ''; self::${$annotation.'Methods'}[$class][$method->name] = [$class, $message]; } diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 3c61fc15048fe..a6e372ebf15a3 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -746,16 +746,16 @@ private function getSchemeAndHierarchy($filename) private static function box($func) { self::$lastError = null; - \set_error_handler(__CLASS__.'::handleError'); + set_error_handler(__CLASS__.'::handleError'); try { $result = \call_user_func_array($func, \array_slice(\func_get_args(), 1)); - \restore_error_handler(); + restore_error_handler(); return $result; } catch (\Throwable $e) { } catch (\Exception $e) { } - \restore_error_handler(); + restore_error_handler(); throw $e; } diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php index bc088e7740bc8..9369740eb6dd5 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php @@ -683,7 +683,7 @@ private function doAdvisoryLock($sessionId) switch ($this->driver) { case 'mysql': // MySQL 5.7.5 and later enforces a maximum length on lock names of 64 characters. Previously, no limit was enforced. - $lockId = \substr($sessionId, 0, 64); + $lockId = substr($sessionId, 0, 64); // should we handle the return value? 0 on timeout, null on error // we use a timeout of 50 seconds which is also the default for innodb_lock_wait_timeout $stmt = $this->pdo->prepare('SELECT GET_LOCK(:key, 50)'); diff --git a/src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php index f48db705686b6..7ab14b7cb856a 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php @@ -47,7 +47,7 @@ public function collect(Request $request, Response $response, \Exception $except 'token' => $response->headers->get('X-Debug-Token'), 'start_time' => $startTime * 1000, 'events' => [], - 'stopwatch_installed' => \class_exists(Stopwatch::class, false), + 'stopwatch_installed' => class_exists(Stopwatch::class, false), ]; } diff --git a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php index 1efad607e8277..7037c497cc9c6 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php @@ -132,12 +132,12 @@ public function update(Response $response) $maxAge = null; $sMaxage = null; - if (\is_numeric($this->ageDirectives['max-age'])) { + if (is_numeric($this->ageDirectives['max-age'])) { $maxAge = $this->ageDirectives['max-age'] + $this->age; $response->headers->addCacheControlDirective('max-age', $maxAge); } - if (\is_numeric($this->ageDirectives['s-maxage'])) { + if (is_numeric($this->ageDirectives['s-maxage'])) { $sMaxage = $this->ageDirectives['s-maxage'] + $this->age; if ($maxAge !== $sMaxage) { @@ -145,7 +145,7 @@ public function update(Response $response) } } - if (\is_numeric($this->ageDirectives['expires'])) { + if (is_numeric($this->ageDirectives['expires'])) { $date = clone $response->getDate(); $date->modify('+'.($this->ageDirectives['expires'] + $this->age).' seconds'); $response->setExpires($date); diff --git a/src/Symfony/Component/HttpKernel/HttpCache/SubRequestHandler.php b/src/Symfony/Component/HttpKernel/HttpCache/SubRequestHandler.php index a701b235464ba..895207152bd19 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/SubRequestHandler.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/SubRequestHandler.php @@ -31,7 +31,7 @@ public static function handle(HttpKernelInterface $kernel, Request $request, $ty // save global state related to trusted headers and proxies $trustedProxies = Request::getTrustedProxies(); $trustedHeaderSet = Request::getTrustedHeaderSet(); - if (\method_exists(Request::class, 'getTrustedHeaderName')) { + if (method_exists(Request::class, 'getTrustedHeaderName')) { Request::setTrustedProxies($trustedProxies, -1); $trustedHeaders = [ Request::HEADER_FORWARDED => Request::getTrustedHeaderName(Request::HEADER_FORWARDED, false), diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/TimeDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/TimeDataCollectorTest.php index 6756f3de42647..e044e5e1add53 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/TimeDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/TimeDataCollectorTest.php @@ -52,6 +52,6 @@ public function testCollect() $c->collect($request, new Response()); $this->assertEquals(123456000, $c->getStartTime()); - $this->assertSame(\class_exists(Stopwatch::class, false), $c->isStopwatchInstalled()); + $this->assertSame(class_exists(Stopwatch::class, false), $c->isStopwatchInstalled()); } } diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php index f3f5b4e51f1ad..83f85abda2a12 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php @@ -139,7 +139,7 @@ public function serialize() { $serialized = [$this->user, $this->authenticated, $this->roles, $this->attributes]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } /** diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php index 1ee85363c4925..7677b90d274df 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php @@ -61,7 +61,7 @@ public function serialize() { $serialized = [$this->secret, parent::serialize(true)]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } /** diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php index ddad0a539cd30..7ff0cfe8a5ba4 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php @@ -81,7 +81,7 @@ public function serialize() { $serialized = [$this->credentials, $this->providerKey, parent::serialize(true)]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } /** diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php index 031e4c6b98c76..6e846dd27c18d 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php @@ -96,7 +96,7 @@ public function serialize() { $serialized = [$this->secret, $this->providerKey, parent::serialize(true)]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } /** diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php index 3c052722bee38..9b71520a2b1c0 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php @@ -93,7 +93,7 @@ public function serialize() { $serialized = [$this->credentials, $this->providerKey, parent::serialize(true)]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } /** diff --git a/src/Symfony/Component/Security/Core/Encoder/Argon2iPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/Argon2iPasswordEncoder.php index 6f8a43b014531..53c016397632d 100644 --- a/src/Symfony/Component/Security/Core/Encoder/Argon2iPasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/Argon2iPasswordEncoder.php @@ -26,7 +26,7 @@ public static function isSupported() return true; } - if (\class_exists('ParagonIE_Sodium_Compat') && \method_exists('ParagonIE_Sodium_Compat', 'crypto_pwhash_is_available')) { + if (class_exists('ParagonIE_Sodium_Compat') && method_exists('ParagonIE_Sodium_Compat', 'crypto_pwhash_is_available')) { return \ParagonIE_Sodium_Compat::crypto_pwhash_is_available(); } @@ -66,8 +66,8 @@ public function isPasswordValid($encoded, $raw, $salt) return !$this->isPasswordTooLong($raw) && password_verify($raw, $encoded); } if (\function_exists('sodium_crypto_pwhash_str_verify')) { - $valid = !$this->isPasswordTooLong($raw) && \sodium_crypto_pwhash_str_verify($encoded, $raw); - \sodium_memzero($raw); + $valid = !$this->isPasswordTooLong($raw) && sodium_crypto_pwhash_str_verify($encoded, $raw); + sodium_memzero($raw); return $valid; } @@ -88,12 +88,12 @@ private function encodePasswordNative($raw) private function encodePasswordSodiumFunction($raw) { - $hash = \sodium_crypto_pwhash_str( + $hash = sodium_crypto_pwhash_str( $raw, \SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, \SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE ); - \sodium_memzero($raw); + sodium_memzero($raw); return $hash; } diff --git a/src/Symfony/Component/Security/Core/Exception/AccountStatusException.php b/src/Symfony/Component/Security/Core/Exception/AccountStatusException.php index cb91b42364bc4..60aea70269a68 100644 --- a/src/Symfony/Component/Security/Core/Exception/AccountStatusException.php +++ b/src/Symfony/Component/Security/Core/Exception/AccountStatusException.php @@ -46,7 +46,7 @@ public function serialize() { $serialized = [$this->user, parent::serialize(true)]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } /** diff --git a/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php b/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php index 2c6c7344a467f..032156e263bc9 100644 --- a/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php +++ b/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php @@ -51,7 +51,7 @@ public function serialize() $this->line, ]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } /** diff --git a/src/Symfony/Component/Security/Core/Exception/CustomUserMessageAuthenticationException.php b/src/Symfony/Component/Security/Core/Exception/CustomUserMessageAuthenticationException.php index ed9fb1bd339b9..9cf253b309238 100644 --- a/src/Symfony/Component/Security/Core/Exception/CustomUserMessageAuthenticationException.php +++ b/src/Symfony/Component/Security/Core/Exception/CustomUserMessageAuthenticationException.php @@ -62,7 +62,7 @@ public function serialize() { $serialized = [parent::serialize(true), $this->messageKey, $this->messageData]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } /** diff --git a/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php b/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php index b4b8047f341f9..c5e517d01d612 100644 --- a/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php +++ b/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php @@ -56,7 +56,7 @@ public function serialize() { $serialized = [$this->username, parent::serialize(true)]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } /** 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 7516759c0aa8e..564ca872401a6 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php @@ -50,7 +50,7 @@ public function serialize() { $serialized = [$this->credentials, parent::serialize(true)]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } public function unserialize($serialized) diff --git a/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php b/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php index 00048226b6aa3..fbdcca1fe8312 100644 --- a/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php +++ b/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php @@ -78,7 +78,7 @@ public function serialize() { $serialized = [$this->providerKey, parent::serialize(true)]; - return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null); + return $this->doSerialize($serialized, \func_num_args() ? func_get_arg(0) : null); } /** diff --git a/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php index 99c8fcab4e645..de985fb3155da 100644 --- a/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php @@ -107,7 +107,7 @@ protected function attemptAuthentication(Request $request) $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']); } - if (!\is_string($username) && (!\is_object($username) || !\method_exists($username, '__toString'))) { + if (!\is_string($username) && (!\is_object($username) || !method_exists($username, '__toString'))) { throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username))); } diff --git a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php index 2f54156732948..37bdfdcafb327 100644 --- a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php @@ -85,7 +85,7 @@ protected function attemptAuthentication(Request $request) $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']); } - if (!\is_string($username) && (!\is_object($username) || !\method_exists($username, '__toString'))) { + if (!\is_string($username) && (!\is_object($username) || !method_exists($username, '__toString'))) { throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username))); } diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 00bd8a2a52faf..b6aea185e789b 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -313,7 +313,7 @@ protected function getConstructor(array &$data, $class, array &$context, \Reflec protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes/*, string $format = null*/) { if (\func_num_args() >= 6) { - $format = \func_get_arg(5); + $format = func_get_arg(5); } else { if (__CLASS__ !== \get_class($this)) { $r = new \ReflectionMethod($this, __FUNCTION__); diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index 38908a9323ba1..7201e5c095751 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -380,7 +380,7 @@ private function isMaxDepthReached(array $attributesMetadata, $class, $attribute protected function createChildContext(array $parentContext, $attribute/*, string $format = null */) { if (\func_num_args() >= 3) { - $format = \func_get_arg(2); + $format = func_get_arg(2); } else { // will be deprecated in version 4 $format = null; diff --git a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php index 854962da6c94d..c1b3dd260e243 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php @@ -30,7 +30,7 @@ class ObjectNormalizer extends AbstractObjectNormalizer public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null) { - if (!\class_exists(PropertyAccess::class)) { + if (!class_exists(PropertyAccess::class)) { throw new RuntimeException('The ObjectNormalizer class requires the "PropertyAccess" component. Install "symfony/property-access" to use it.'); } diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index 4528e385a7ff6..f63cf67bdf7ed 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -191,7 +191,7 @@ public function denormalize($data, $type, $format = null, array $context = []) public function supportsNormalization($data, $format = null/*, array $context = []*/) { if (\func_num_args() > 2) { - $context = \func_get_arg(2); + $context = func_get_arg(2); } else { if (__CLASS__ !== \get_class($this)) { $r = new \ReflectionMethod($this, __FUNCTION__); @@ -212,7 +212,7 @@ public function supportsNormalization($data, $format = null/*, array $context = public function supportsDenormalization($data, $type, $format = null/*, array $context = []*/) { if (\func_num_args() > 3) { - $context = \func_get_arg(3); + $context = func_get_arg(3); } else { if (__CLASS__ !== \get_class($this)) { $r = new \ReflectionMethod($this, __FUNCTION__); @@ -286,7 +286,7 @@ final public function decode($data, $format, array $context = []) public function supportsEncoding($format/*, array $context = []*/) { if (\func_num_args() > 1) { - $context = \func_get_arg(1); + $context = func_get_arg(1); } else { if (__CLASS__ !== \get_class($this)) { $r = new \ReflectionMethod($this, __FUNCTION__); @@ -307,7 +307,7 @@ public function supportsEncoding($format/*, array $context = []*/) public function supportsDecoding($format/*, array $context = []*/) { if (\func_num_args() > 1) { - $context = \func_get_arg(1); + $context = func_get_arg(1); } else { if (__CLASS__ !== \get_class($this)) { $r = new \ReflectionMethod($this, __FUNCTION__); diff --git a/src/Symfony/Component/Translation/Resources/bin/translation-status.php b/src/Symfony/Component/Translation/Resources/bin/translation-status.php index 0d37c3e0aa38b..96ccc105741b7 100644 --- a/src/Symfony/Component/Translation/Resources/bin/translation-status.php +++ b/src/Symfony/Component/Translation/Resources/bin/translation-status.php @@ -73,7 +73,7 @@ $translationStatus = calculateTranslationStatus($originalFilePath, $translationFilePaths); $totalMissingTranslations += array_sum(array_map(function ($translation) { - return \count($translation['missingKeys']); + return count($translation['missingKeys']); }, array_values($translationStatus))); printTranslationStatus($originalFilePath, $translationStatus, $config['verbose_output']); @@ -113,8 +113,8 @@ function calculateTranslationStatus($originalFilePath, $translationFilePaths) $missingKeys = array_diff_key($allTranslationKeys, $translatedKeys); $translationStatus[$locale] = [ - 'total' => \count($allTranslationKeys), - 'translated' => \count($translatedKeys), + 'total' => count($allTranslationKeys), + 'translated' => count($translatedKeys), 'missingKeys' => $missingKeys, ]; } @@ -176,7 +176,7 @@ function printTable($translations, $verboseOutput) textColorNormal(); - if (true === $verboseOutput && \count($translation['missingKeys']) > 0) { + if (true === $verboseOutput && count($translation['missingKeys']) > 0) { echo str_repeat('-', 80).PHP_EOL; echo '| Missing Translations:'.PHP_EOL; diff --git a/src/Symfony/Component/VarDumper/Cloner/VarCloner.php b/src/Symfony/Component/VarDumper/Cloner/VarCloner.php index f418aa089488d..9e50f23501154 100644 --- a/src/Symfony/Component/VarDumper/Cloner/VarCloner.php +++ b/src/Symfony/Component/VarDumper/Cloner/VarCloner.php @@ -79,7 +79,7 @@ protected function doClone($var) } if ($gk !== $k) { $fromObjCast = true; - $refs = $vals = \array_values($queue[$i]); + $refs = $vals = array_values($queue[$i]); break; } } @@ -90,7 +90,7 @@ protected function doClone($var) if ($zvalIsRef = $vals[$k] === $cookie) { $vals[$k] = &$stub; // Break hard references to make $queue completely unset($stub); // independent from the original structure - if ($v instanceof Stub && isset($hardRefs[\spl_object_hash($v)])) { + if ($v instanceof Stub && isset($hardRefs[spl_object_hash($v)])) { $vals[$k] = $refs[$k] = $v; if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) { ++$v->value->refCount; @@ -100,7 +100,7 @@ protected function doClone($var) } $refs[$k] = $vals[$k] = new Stub(); $refs[$k]->value = $v; - $h = \spl_object_hash($refs[$k]); + $h = spl_object_hash($refs[$k]); $hardRefs[$h] = &$refs[$k]; $values[$h] = $v; $vals[$k]->handle = ++$refsCounter; @@ -118,22 +118,22 @@ protected function doClone($var) if ('' === $v) { continue 2; } - if (!\preg_match('//u', $v)) { + if (!preg_match('//u', $v)) { $stub = new Stub(); $stub->type = Stub::TYPE_STRING; $stub->class = Stub::STRING_BINARY; if (0 <= $maxString && 0 < $cut = \strlen($v) - $maxString) { $stub->cut = $cut; - $stub->value = \substr($v, 0, -$cut); + $stub->value = substr($v, 0, -$cut); } else { $stub->value = $v; } - } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = \mb_strlen($v, 'UTF-8') - $maxString) { + } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = mb_strlen($v, 'UTF-8') - $maxString) { $stub = new Stub(); $stub->type = Stub::TYPE_STRING; $stub->class = Stub::STRING_UTF8; $stub->cut = $cut; - $stub->value = \mb_substr($v, 0, $maxString, 'UTF-8'); + $stub->value = mb_substr($v, 0, $maxString, 'UTF-8'); } else { continue 2; } @@ -179,7 +179,7 @@ protected function doClone($var) case \is_object($v): case $v instanceof \__PHP_Incomplete_Class: - if (empty($objRefs[$h = $hashMask ^ \hexdec(\substr(\spl_object_hash($v), $hashOffset, \PHP_INT_SIZE))])) { + if (empty($objRefs[$h = $hashMask ^ hexdec(substr(spl_object_hash($v), $hashOffset, \PHP_INT_SIZE))])) { $stub = new Stub(); $stub->type = Stub::TYPE_OBJECT; $stub->class = \get_class($v); @@ -190,7 +190,7 @@ protected function doClone($var) if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) { break; } - $h = $hashMask ^ \hexdec(\substr(\spl_object_hash($stub->value), $hashOffset, \PHP_INT_SIZE)); + $h = $hashMask ^ hexdec(substr(spl_object_hash($stub->value), $hashOffset, \PHP_INT_SIZE)); $stub->handle = $h; } $stub->value = null; @@ -213,7 +213,7 @@ protected function doClone($var) if (empty($resRefs[$h = (int) $v])) { $stub = new Stub(); $stub->type = Stub::TYPE_RESOURCE; - if ('Unknown' === $stub->class = @\get_resource_type($v)) { + if ('Unknown' === $stub->class = @get_resource_type($v)) { $stub->class = 'Closed'; } $stub->value = $v; From 37fa45bbd1553ee5ce6efdb79bd003b7327f7376 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 13 Jun 2019 12:57:15 +0200 Subject: [PATCH 038/106] fixed CS --- .../Monolog/Processor/DebugProcessor.php | 4 +-- .../Legacy/SymfonyTestsListenerTrait.php | 2 +- .../LazyProxy/PhpDumper/ProxyDumper.php | 2 +- .../Twig/Tests/Command/DebugCommandTest.php | 8 +++--- .../CacheWarmer/AnnotationsCacheWarmer.php | 2 +- .../CacheWarmer/SerializerCacheWarmer.php | 2 +- .../CacheWarmer/ValidatorCacheWarmer.php | 2 +- .../Cache/Adapter/AbstractAdapter.php | 4 +-- .../Component/Cache/Adapter/ProxyAdapter.php | 4 +-- src/Symfony/Component/Cache/CacheItem.php | 2 +- .../Component/Cache/Traits/ArrayTrait.php | 2 +- .../Component/Cache/Traits/PhpArrayTrait.php | 2 +- .../Component/Cache/Traits/PhpFilesTrait.php | 2 +- src/Symfony/Component/Console/Application.php | 2 +- .../Console/Helper/ProcessHelper.php | 2 +- .../Console/Output/ConsoleSectionOutput.php | 2 +- .../Tests/Helper/ProcessHelperTest.php | 4 +-- .../Component/Debug/DebugClassLoader.php | 26 +++++++++---------- .../Debug/Exception/FlattenException.php | 2 +- .../Tests/Loader/XmlFileLoaderTest.php | 2 +- .../Tests/Loader/YamlFileLoaderTest.php | 2 +- .../DependencyInjection/TypedReference.php | 2 +- src/Symfony/Component/DomCrawler/Crawler.php | 2 +- src/Symfony/Component/Dotenv/Dotenv.php | 2 +- .../Component/Filesystem/Filesystem.php | 6 ++--- src/Symfony/Component/Finder/Finder.php | 12 ++++----- .../Data/Generator/LocaleDataGenerator.php | 4 +-- .../Intl/Data/Util/LocaleScanner.php | 4 +-- .../Component/Lock/Store/ZookeeperStore.php | 4 +-- .../AmqpExt/Fixtures/long_receiver.php | 2 +- .../Transport/AmqpExt/Connection.php | 2 +- .../StopWhenMemoryUsageIsExceededReceiver.php | 2 +- .../OptionsResolver/OptionsResolver.php | 2 +- .../Mapping/Factory/ClassMetadataFactory.php | 2 +- .../Normalizer/AbstractObjectNormalizer.php | 2 +- .../Normalizer/CustomNormalizer.php | 2 +- .../Normalizer/ObjectNormalizer.php | 2 +- .../Component/Serializer/Serializer.php | 4 +-- .../Translation/PluralizationRules.php | 2 +- .../Component/Translation/Translator.php | 2 +- .../Component/VarDumper/Caster/ClassStub.php | 2 +- .../VarDumper/Caster/ExceptionCaster.php | 2 +- .../VarDumper/Caster/ProxyManagerCaster.php | 2 +- .../Component/VarDumper/Cloner/VarCloner.php | 20 +++++++------- .../VarExporter/Internal/Exporter.php | 8 +++--- .../VarExporter/Internal/Hydrator.php | 2 +- .../VarExporter/Internal/Registry.php | 8 +++--- .../Workflow/Dumper/GraphvizDumper.php | 2 +- .../Workflow/Tests/StateMachineTest.php | 2 +- .../Contracts/Translation/TranslatorTrait.php | 4 +-- 50 files changed, 96 insertions(+), 96 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php b/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php index 24a670de79630..f4e37ff44e739 100644 --- a/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php @@ -67,7 +67,7 @@ public function getLogs(/* Request $request = null */) @trigger_error(sprintf('The "%s()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); } - if (1 <= \func_num_args() && null !== $request = \func_get_arg(0)) { + if (1 <= \func_num_args() && null !== $request = func_get_arg(0)) { return $this->records[spl_object_hash($request)] ?? []; } @@ -89,7 +89,7 @@ public function countErrors(/* Request $request = null */) @trigger_error(sprintf('The "%s()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); } - if (1 <= \func_num_args() && null !== $request = \func_get_arg(0)) { + if (1 <= \func_num_args() && null !== $request = func_get_arg(0)) { return $this->errorCount[spl_object_hash($request)] ?? 0; } diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php index 632a4ca878997..bb1e8ab4c2f0a 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php @@ -53,7 +53,7 @@ public function __construct(array $mockedNamespaces = array()) Blacklist::$blacklistedClassNames['\Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait'] = 2; } - $enableDebugClassLoader = \class_exists('Symfony\Component\Debug\DebugClassLoader'); + $enableDebugClassLoader = class_exists('Symfony\Component\Debug\DebugClassLoader'); foreach ($mockedNamespaces as $type => $namespaces) { if (!\is_array($namespaces)) { diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index 70ca302affeb4..e09d54074862d 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -99,7 +99,7 @@ public function getProxyCode(Definition $definition) private static function getProxyManagerVersion(): string { - if (!\class_exists(Version::class)) { + if (!class_exists(Version::class)) { return '0.0.1'; } diff --git a/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php b/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php index cf46c8e620069..ed76f2e380d2c 100644 --- a/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php @@ -295,7 +295,7 @@ public function testWithGlobals() $tester = $this->createCommandTester([], [], null, null, false, ['message' => $message]); $tester->execute([], ['decorated' => true]); $display = $tester->getDisplay(); - $this->assertContains(\json_encode($message), $display); + $this->assertContains(json_encode($message), $display); } public function testWithGlobalsJson() @@ -304,7 +304,7 @@ public function testWithGlobalsJson() $tester = $this->createCommandTester([], [], null, null, false, $globals); $tester->execute(['--format' => 'json'], ['decorated' => true]); $display = $tester->getDisplay(); - $display = \json_decode($display, true); + $display = json_decode($display, true); $this->assertSame($globals, $display['globals']); } @@ -313,10 +313,10 @@ public function testWithFilter() $tester = $this->createCommandTester(); $tester->execute(['--format' => 'json'], ['decorated' => false]); $display = $tester->getDisplay(); - $display1 = \json_decode($display, true); + $display1 = json_decode($display, true); $tester->execute(['--filter' => 'date', '--format' => 'json'], ['decorated' => false]); $display = $tester->getDisplay(); - $display2 = \json_decode($display, true); + $display2 = json_decode($display, true); $this->assertNotSame($display1, $display2); } diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php index f3d6a875e0274..340198e5e2c1b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php @@ -40,7 +40,7 @@ public function __construct(Reader $annotationReader, string $phpArrayFile, $exc if ($excludeRegexp instanceof CacheItemPoolInterface) { @trigger_error(sprintf('The CacheItemPoolInterface $fallbackPool argument of "%s()" is deprecated since Symfony 4.2, you should not pass it anymore.', __METHOD__), E_USER_DEPRECATED); $excludeRegexp = $debug; - $debug = 4 < \func_num_args() && \func_get_arg(4); + $debug = 4 < \func_num_args() && func_get_arg(4); } parent::__construct($phpArrayFile); $this->annotationReader = $annotationReader; diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/SerializerCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/SerializerCacheWarmer.php index 535161b1197e1..41a8aaa04de2a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/SerializerCacheWarmer.php +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/SerializerCacheWarmer.php @@ -36,7 +36,7 @@ class SerializerCacheWarmer extends AbstractPhpFileCacheWarmer */ public function __construct(array $loaders, string $phpArrayFile) { - if (2 < \func_num_args() && \func_get_arg(2) instanceof CacheItemPoolInterface) { + if (2 < \func_num_args() && func_get_arg(2) instanceof CacheItemPoolInterface) { @trigger_error(sprintf('The CacheItemPoolInterface $fallbackPool argument of "%s()" is deprecated since Symfony 4.2, you should not pass it anymore.', __METHOD__), E_USER_DEPRECATED); } parent::__construct($phpArrayFile); diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php index d617f7df9d1d1..bd1e559a361d0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php @@ -37,7 +37,7 @@ class ValidatorCacheWarmer extends AbstractPhpFileCacheWarmer */ public function __construct(ValidatorBuilderInterface $validatorBuilder, string $phpArrayFile) { - if (2 < \func_num_args() && \func_get_arg(2) instanceof CacheItemPoolInterface) { + if (2 < \func_num_args() && func_get_arg(2) instanceof CacheItemPoolInterface) { @trigger_error(sprintf('The CacheItemPoolInterface $fallbackPool argument of "%s()" is deprecated since Symfony 4.2, you should not pass it anymore.', __METHOD__), E_USER_DEPRECATED); } parent::__construct($phpArrayFile); diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index 6897fbceee530..ff680a46e8e19 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -52,9 +52,9 @@ function ($key, $value, $isHit) use ($defaultLifetime) { // Detect wrapped values that encode for their expiry and creation duration // For compactness, these values are packed in the key of an array using // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F - if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = \key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) { + if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) { $item->value = $v[$k]; - $v = \unpack('Ve/Nc', \substr($k, 1, -1)); + $v = unpack('Ve/Nc', substr($k, 1, -1)); $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET; $item->metadata[CacheItem::METADATA_CTIME] = $v['c']; } diff --git a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php index cf51b90d8d859..bccafcf47ef1b 100644 --- a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php @@ -58,9 +58,9 @@ function ($key, $innerItem) use ($defaultLifetime, $poolHash) { // Detect wrapped values that encode for their expiry and creation duration // For compactness, these values are packed in the key of an array using // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F - if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = \key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) { + if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) { $item->value = $v[$k]; - $v = \unpack('Ve/Nc', \substr($k, 1, -1)); + $v = unpack('Ve/Nc', substr($k, 1, -1)); $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET; $item->metadata[CacheItem::METADATA_CTIME] = $v['c']; } elseif ($innerItem instanceof CacheItem) { diff --git a/src/Symfony/Component/Cache/CacheItem.php b/src/Symfony/Component/Cache/CacheItem.php index 92eb9c39dfa32..3cc3fb8f2e477 100644 --- a/src/Symfony/Component/Cache/CacheItem.php +++ b/src/Symfony/Component/Cache/CacheItem.php @@ -110,7 +110,7 @@ public function tag($tags): ItemInterface if (!$this->isTaggable) { throw new LogicException(sprintf('Cache item "%s" comes from a non tag-aware pool: you cannot tag it.', $this->key)); } - if (!\is_iterable($tags)) { + if (!is_iterable($tags)) { $tags = [$tags]; } foreach ($tags as $tag) { diff --git a/src/Symfony/Component/Cache/Traits/ArrayTrait.php b/src/Symfony/Component/Cache/Traits/ArrayTrait.php index e585c3d48cb52..4d67c2df5a238 100644 --- a/src/Symfony/Component/Cache/Traits/ArrayTrait.php +++ b/src/Symfony/Component/Cache/Traits/ArrayTrait.php @@ -123,7 +123,7 @@ private function freeze($value, $key) if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) { return serialize($value); } - } elseif (!\is_scalar($value)) { + } elseif (!is_scalar($value)) { try { $serialized = serialize($value); } catch (\Exception $e) { diff --git a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php index 0bec18a07aa56..4395de0252894 100644 --- a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php @@ -86,7 +86,7 @@ public function warmUp(array $values) $isStaticValue = false; } $value = var_export($value, true); - } elseif (!\is_scalar($value)) { + } elseif (!is_scalar($value)) { throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, \gettype($value))); } else { $value = var_export($value, true); diff --git a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php index 37d25f87a98fa..6afdd8c3a5425 100644 --- a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php @@ -182,7 +182,7 @@ protected function doSave(array $values, $lifetime) $isStaticValue = false; } $value = var_export($value, true); - } elseif (!\is_scalar($value)) { + } elseif (!is_scalar($value)) { throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, \gettype($value))); } else { $value = var_export($value, true); diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 7522cef8f2fe6..5c0faa5fe9a4d 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -779,7 +779,7 @@ protected function doRenderException(\Exception $e, OutputInterface $output) if (false !== strpos($message, "class@anonymous\0")) { $message = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) { - return \class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; }, $message); } diff --git a/src/Symfony/Component/Console/Helper/ProcessHelper.php b/src/Symfony/Component/Console/Helper/ProcessHelper.php index e3a7c77b35816..41f128bb49318 100644 --- a/src/Symfony/Component/Console/Helper/ProcessHelper.php +++ b/src/Symfony/Component/Console/Helper/ProcessHelper.php @@ -51,7 +51,7 @@ public function run(OutputInterface $output, $cmd, $error = null, callable $call if (!\is_array($cmd)) { @trigger_error(sprintf('Passing a command as a string to "%s()" is deprecated since Symfony 4.2, pass it the command as an array of arguments instead.', __METHOD__), E_USER_DEPRECATED); - $cmd = [\method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline($cmd) : new Process($cmd)]; + $cmd = [method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline($cmd) : new Process($cmd)]; } if (\is_string($cmd[0] ?? null)) { diff --git a/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php b/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php index 4ada2e86739b8..ce2c28ba1a715 100644 --- a/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php +++ b/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php @@ -50,7 +50,7 @@ public function clear(int $lines = null) } if ($lines) { - \array_splice($this->content, -($lines * 2)); // Multiply lines by 2 to cater for each new line added between content + array_splice($this->content, -($lines * 2)); // Multiply lines by 2 to cater for each new line added between content } else { $lines = $this->lines; $this->content = []; diff --git a/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php index 5387a9e3c2ed5..82c6b445175d5 100644 --- a/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php @@ -26,7 +26,7 @@ class ProcessHelperTest extends TestCase public function testVariousProcessRuns($expected, $cmd, $verbosity, $error) { if (\is_string($cmd)) { - $cmd = \method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline($cmd) : new Process($cmd); + $cmd = method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline($cmd) : new Process($cmd); } $helper = new ProcessHelper(); @@ -99,7 +99,7 @@ public function provideCommandsAndOutput() $args = new Process(['php', '-r', 'echo 42;']); $args = $args->getCommandLine(); $successOutputProcessDebug = str_replace("'php' '-r' 'echo 42;'", $args, $successOutputProcessDebug); - $fromShellCommandline = \method_exists(Process::class, 'fromShellCommandline') ? [Process::class, 'fromShellCommandline'] : function ($cmd) { return new Process($cmd); }; + $fromShellCommandline = method_exists(Process::class, 'fromShellCommandline') ? [Process::class, 'fromShellCommandline'] : function ($cmd) { return new Process($cmd); }; return [ ['', 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERBOSE, null], diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index e648bf60c5375..55fd0df694e4d 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -171,7 +171,7 @@ public function loadClass($class) private function checkClass($class, $file = null) { - $exists = null === $file || \class_exists($class, false) || \interface_exists($class, false) || \trait_exists($class, false); + $exists = null === $file || class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false); if (null !== $file && $class && '\\' === $class[0]) { $class = substr($class, 1); @@ -189,7 +189,7 @@ private function checkClass($class, $file = null) } $name = $refl->getName(); - if ($name !== $class && 0 === \strcasecmp($name, $class)) { + if ($name !== $class && 0 === strcasecmp($name, $class)) { throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: "%s" vs "%s".', $class, $name)); } @@ -222,23 +222,23 @@ public function checkAnnotations(\ReflectionClass $refl, $class) $deprecations = []; // Don't trigger deprecations for classes in the same vendor - if (2 > $len = 1 + (\strpos($class, '\\') ?: \strpos($class, '_'))) { + if (2 > $len = 1 + (strpos($class, '\\') ?: strpos($class, '_'))) { $len = 0; $ns = ''; } else { - $ns = \str_replace('_', '\\', \substr($class, 0, $len)); + $ns = str_replace('_', '\\', substr($class, 0, $len)); } // Detect annotations on the class if (false !== $doc = $refl->getDocComment()) { foreach (['final', 'deprecated', 'internal'] as $annotation) { - if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { + if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : ''; } } } - $parent = \get_parent_class($class); + $parent = get_parent_class($class); $parentAndOwnInterfaces = $this->getOwnInterfaces($class, $parent); if ($parent) { $parentAndOwnInterfaces[$parent] = $parent; @@ -253,22 +253,22 @@ public function checkAnnotations(\ReflectionClass $refl, $class) } // Detect if the parent is annotated - foreach ($parentAndOwnInterfaces + \class_uses($class, false) as $use) { + foreach ($parentAndOwnInterfaces + class_uses($class, false) as $use) { if (!isset(self::$checkedClasses[$use])) { $this->checkClass($use); } - if (isset(self::$deprecated[$use]) && \strncmp($ns, \str_replace('_', '\\', $use), $len) && !isset(self::$deprecated[$class])) { + if (isset(self::$deprecated[$use]) && strncmp($ns, str_replace('_', '\\', $use), $len) && !isset(self::$deprecated[$class])) { $type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait'); $verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses'); $deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s.', $class, $type, $verb, $use, self::$deprecated[$use]); } - if (isset(self::$internal[$use]) && \strncmp($ns, \str_replace('_', '\\', $use), $len)) { + if (isset(self::$internal[$use]) && strncmp($ns, str_replace('_', '\\', $use), $len)) { $deprecations[] = sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $class); } } - if (\trait_exists($class)) { + if (trait_exists($class)) { return $deprecations; } @@ -296,7 +296,7 @@ public function checkAnnotations(\ReflectionClass $refl, $class) if (isset(self::$internalMethods[$class][$method->name])) { list($declaringClass, $message) = self::$internalMethods[$class][$method->name]; - if (\strncmp($ns, $declaringClass, $len)) { + if (strncmp($ns, $declaringClass, $len)) { $deprecations[] = sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class); } } @@ -324,14 +324,14 @@ public function checkAnnotations(\ReflectionClass $refl, $class) $finalOrInternal = false; foreach (['final', 'internal'] as $annotation) { - if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { + if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) { $message = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : ''; self::${$annotation.'Methods'}[$class][$method->name] = [$class, $message]; $finalOrInternal = true; } } - if ($finalOrInternal || $method->isConstructor() || false === \strpos($doc, '@param') || StatelessInvocation::class === $class) { + if ($finalOrInternal || $method->isConstructor() || false === strpos($doc, '@param') || StatelessInvocation::class === $class) { continue; } if (!preg_match_all('#\n\s+\* @param (.*?)(?<= )\$([a-zA-Z0-9_\x7f-\xff]++)#', $doc, $matches, PREG_SET_ORDER)) { diff --git a/src/Symfony/Component/Debug/Exception/FlattenException.php b/src/Symfony/Component/Debug/Exception/FlattenException.php index d016bb2fb45cc..ed8a4e87384bc 100644 --- a/src/Symfony/Component/Debug/Exception/FlattenException.php +++ b/src/Symfony/Component/Debug/Exception/FlattenException.php @@ -172,7 +172,7 @@ public function setMessage($message) { if (false !== strpos($message, "class@anonymous\0")) { $message = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) { - return \class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; }, $message); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 57b9c11bf6ff9..620a5d775877d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -614,7 +614,7 @@ public function testPrototype() $fixturesDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR; $this->assertContains((string) new FileResource($fixturesDir.'xml'.\DIRECTORY_SEPARATOR.'services_prototype.xml'), $resources); - $prototypeRealPath = \realpath(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR.'Prototype'); + $prototypeRealPath = realpath(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR.'Prototype'); $globResource = new GlobResource( $fixturesDir.'Prototype', '/*', diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index 836ce993c1da8..4351e3c0c1e7c 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -367,7 +367,7 @@ public function testPrototype() $fixturesDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR; $this->assertContains((string) new FileResource($fixturesDir.'yaml'.\DIRECTORY_SEPARATOR.'services_prototype.yml'), $resources); - $prototypeRealPath = \realpath(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR.'Prototype'); + $prototypeRealPath = realpath(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR.'Prototype'); $globResource = new GlobResource( $fixturesDir.'Prototype', '', diff --git a/src/Symfony/Component/DependencyInjection/TypedReference.php b/src/Symfony/Component/DependencyInjection/TypedReference.php index f80ac50563972..56a878874e2df 100644 --- a/src/Symfony/Component/DependencyInjection/TypedReference.php +++ b/src/Symfony/Component/DependencyInjection/TypedReference.php @@ -34,7 +34,7 @@ public function __construct(string $id, string $type, $invalidBehavior = Contain @trigger_error(sprintf('The $requiringClass argument of "%s()" is deprecated since Symfony 4.1.', __METHOD__), E_USER_DEPRECATED); $this->requiringClass = $invalidBehavior; - $invalidBehavior = 3 < \func_num_args() ? \func_get_arg(3) : ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + $invalidBehavior = 3 < \func_num_args() ? func_get_arg(3) : ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; } else { $this->name = $type === $id ? $name : null; } diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index 5dbffe42c609a..1c99293c0d213 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -1165,7 +1165,7 @@ private function createSubCrawler($nodes) */ private function createCssSelectorConverter(): CssSelectorConverter { - if (!\class_exists(CssSelectorConverter::class)) { + if (!class_exists(CssSelectorConverter::class)) { throw new \LogicException('To filter with a CSS selector, install the CssSelector component ("composer require symfony/css-selector"). Or use filterXpath instead.'); } diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index fa9a2ee931a77..dbb70c4730aa8 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -382,7 +382,7 @@ private function resolveCommands($value) throw new \LogicException('Resolving commands requires the Symfony Process component.'); } - $process = \method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline('echo '.$matches[0]) : new Process('echo '.$matches[0]); + $process = method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline('echo '.$matches[0]) : new Process('echo '.$matches[0]); $process->inheritEnvironmentVariables(true); $process->setEnv($this->values); try { diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 9ec1e943546fa..dc3290c9aff6d 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -743,15 +743,15 @@ private function getSchemeAndHierarchy(string $filename): array private static function box($func) { self::$lastError = null; - \set_error_handler(__CLASS__.'::handleError'); + set_error_handler(__CLASS__.'::handleError'); try { $result = $func(...\array_slice(\func_get_args(), 1)); - \restore_error_handler(); + restore_error_handler(); return $result; } catch (\Throwable $e) { } - \restore_error_handler(); + restore_error_handler(); throw $e; } diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index 83163f51d52eb..7b7b1152efc03 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -172,7 +172,7 @@ public function date($dates) */ public function name($patterns) { - $this->names = \array_merge($this->names, (array) $patterns); + $this->names = array_merge($this->names, (array) $patterns); return $this; } @@ -188,7 +188,7 @@ public function name($patterns) */ public function notName($patterns) { - $this->notNames = \array_merge($this->notNames, (array) $patterns); + $this->notNames = array_merge($this->notNames, (array) $patterns); return $this; } @@ -210,7 +210,7 @@ public function notName($patterns) */ public function contains($patterns) { - $this->contains = \array_merge($this->contains, (array) $patterns); + $this->contains = array_merge($this->contains, (array) $patterns); return $this; } @@ -232,7 +232,7 @@ public function contains($patterns) */ public function notContains($patterns) { - $this->notContains = \array_merge($this->notContains, (array) $patterns); + $this->notContains = array_merge($this->notContains, (array) $patterns); return $this; } @@ -256,7 +256,7 @@ public function notContains($patterns) */ public function path($patterns) { - $this->paths = \array_merge($this->paths, (array) $patterns); + $this->paths = array_merge($this->paths, (array) $patterns); return $this; } @@ -280,7 +280,7 @@ public function path($patterns) */ public function notPath($patterns) { - $this->notPaths = \array_merge($this->notPaths, (array) $patterns); + $this->notPaths = array_merge($this->notPaths, (array) $patterns); return $this; } diff --git a/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php b/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php index 9d57b070696e3..eda413a12b14f 100644 --- a/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php +++ b/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php @@ -65,9 +65,9 @@ protected function compileTemporaryBundles(BundleCompilerInterface $compiler, $s protected function preGenerate() { // Write parents locale file for the Translation component - \file_put_contents( + file_put_contents( __DIR__.'/../../../Translation/Resources/data/parents.json', - \json_encode($this->localeParents, \JSON_PRETTY_PRINT).\PHP_EOL + json_encode($this->localeParents, \JSON_PRETTY_PRINT).\PHP_EOL ); } diff --git a/src/Symfony/Component/Intl/Data/Util/LocaleScanner.php b/src/Symfony/Component/Intl/Data/Util/LocaleScanner.php index 2d56ff9d0cf1f..49aec06b1fdfc 100644 --- a/src/Symfony/Component/Intl/Data/Util/LocaleScanner.php +++ b/src/Symfony/Component/Intl/Data/Util/LocaleScanner.php @@ -92,10 +92,10 @@ public function scanParents(string $sourceDir): array $fallbacks = []; foreach ($locales as $locale) { - $content = \file_get_contents($sourceDir.'/'.$locale.'.txt'); + $content = file_get_contents($sourceDir.'/'.$locale.'.txt'); // Aliases contain the text "%%PARENT" followed by the aliased locale - if (\preg_match('/%%Parent{"([^"]+)"}/', $content, $matches)) { + if (preg_match('/%%Parent{"([^"]+)"}/', $content, $matches)) { $fallbacks[$locale] = $matches[1]; } } diff --git a/src/Symfony/Component/Lock/Store/ZookeeperStore.php b/src/Symfony/Component/Lock/Store/ZookeeperStore.php index c755ce1a1c4a3..4f8b4ee374e86 100644 --- a/src/Symfony/Component/Lock/Store/ZookeeperStore.php +++ b/src/Symfony/Component/Lock/Store/ZookeeperStore.php @@ -127,8 +127,8 @@ private function getKeyResource(Key $key): string // For example: foo/bar will become /foo-bar and /foo/bar will become /-foo-bar $resource = (string) $key; - if (false !== \strpos($resource, '/')) { - $resource = \strtr($resource, ['/' => '-']).'-'.sha1($resource); + if (false !== strpos($resource, '/')) { + $resource = strtr($resource, ['/' => '-']).'-'.sha1($resource); } if ('' === $resource) { diff --git a/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/Fixtures/long_receiver.php b/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/Fixtures/long_receiver.php index a7d4d8dcd758c..92897d2b357d3 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/Fixtures/long_receiver.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/Fixtures/long_receiver.php @@ -32,7 +32,7 @@ $worker = new Worker($receiver, new class() implements MessageBusInterface { public function dispatch($envelope): Envelope { - echo 'Get envelope with message: '.\get_class($envelope->getMessage())."\n"; + echo 'Get envelope with message: '.get_class($envelope->getMessage())."\n"; echo sprintf("with stamps: %s\n", json_encode(array_keys($envelope->all()), JSON_PRETTY_PRINT)); sleep(30); diff --git a/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php b/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php index 19415c7aede7c..abe383c9e344f 100644 --- a/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php @@ -114,7 +114,7 @@ private static function normalizeQueueArguments(array $arguments): array continue; } - if (!\is_numeric($arguments[$key])) { + if (!is_numeric($arguments[$key])) { throw new InvalidArgumentException(sprintf('Integer expected for queue argument "%s", %s given.', $key, \gettype($arguments[$key]))); } diff --git a/src/Symfony/Component/Messenger/Transport/Receiver/StopWhenMemoryUsageIsExceededReceiver.php b/src/Symfony/Component/Messenger/Transport/Receiver/StopWhenMemoryUsageIsExceededReceiver.php index e61fe5937af78..929d4e43b281a 100644 --- a/src/Symfony/Component/Messenger/Transport/Receiver/StopWhenMemoryUsageIsExceededReceiver.php +++ b/src/Symfony/Component/Messenger/Transport/Receiver/StopWhenMemoryUsageIsExceededReceiver.php @@ -32,7 +32,7 @@ public function __construct(ReceiverInterface $decoratedReceiver, int $memoryLim $this->memoryLimit = $memoryLimit; $this->logger = $logger; $this->memoryResolver = $memoryResolver ?: function () { - return \memory_get_usage(true); + return memory_get_usage(true); }; } diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index eb0a6c2480601..7b9adc44f2d4f 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -797,7 +797,7 @@ public function offsetGet($option/*, bool $triggerDeprecation = true*/) throw new AccessException('Array access is only supported within closures of lazy options and normalizers.'); } - $triggerDeprecation = 1 === \func_num_args() || \func_get_arg(1); + $triggerDeprecation = 1 === \func_num_args() || func_get_arg(1); // Shortcut for resolved options if (isset($this->resolved[$option]) || \array_key_exists($option, $this->resolved)) { diff --git a/src/Symfony/Component/Serializer/Mapping/Factory/ClassMetadataFactory.php b/src/Symfony/Component/Serializer/Mapping/Factory/ClassMetadataFactory.php index 882091dca8260..b55c070fb8ae2 100644 --- a/src/Symfony/Component/Serializer/Mapping/Factory/ClassMetadataFactory.php +++ b/src/Symfony/Component/Serializer/Mapping/Factory/ClassMetadataFactory.php @@ -69,6 +69,6 @@ public function getMetadataFor($value) */ public function hasMetadataFor($value) { - return \is_object($value) || (\is_string($value) && (\class_exists($value) || \interface_exists($value, false))); + return \is_object($value) || (\is_string($value) && (class_exists($value) || interface_exists($value, false))); } } diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index a629920bb8a1c..620fa8a626abf 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -263,7 +263,7 @@ public function setMaxDepthHandler(?callable $handler): void */ public function supportsDenormalization($data, $type, $format = null) { - return \class_exists($type) || (\interface_exists($type, false) && $this->classDiscriminatorResolver && null !== $this->classDiscriminatorResolver->getMappingForClass($type)); + return class_exists($type) || (interface_exists($type, false) && $this->classDiscriminatorResolver && null !== $this->classDiscriminatorResolver->getMappingForClass($type)); } /** diff --git a/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php index d5a1990f0b805..dcf2deef806d9 100644 --- a/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php @@ -65,7 +65,7 @@ public function supportsNormalization($data, $format = null) */ public function supportsDenormalization($data, $type, $format = null) { - return \is_subclass_of($type, DenormalizableInterface::class); + return is_subclass_of($type, DenormalizableInterface::class); } /** diff --git a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php index f766286b2b11a..118e9856f5e9a 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php @@ -36,7 +36,7 @@ class ObjectNormalizer extends AbstractObjectNormalizer public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null, ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, callable $objectClassResolver = null, array $defaultContext = []) { - if (!\class_exists(PropertyAccess::class)) { + if (!class_exists(PropertyAccess::class)) { throw new LogicException('The ObjectNormalizer class requires the "PropertyAccess" component. Install "symfony/property-access" to use it.'); } diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index b950ba58b0a19..c7ccd9fd9fa2b 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -84,7 +84,7 @@ public function __construct(array $normalizers = [], array $encoders = []) } if (!($normalizer instanceof NormalizerInterface || $normalizer instanceof DenormalizerInterface)) { - @trigger_error(\sprintf('Passing normalizers ("%s") which do not implement either "%s" or "%s" has been deprecated since Symfony 4.2.', \get_class($normalizer), NormalizerInterface::class, DenormalizerInterface::class), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing normalizers ("%s") which do not implement either "%s" or "%s" has been deprecated since Symfony 4.2.', \get_class($normalizer), NormalizerInterface::class, DenormalizerInterface::class), E_USER_DEPRECATED); // throw new \InvalidArgumentException(\sprintf('The class "%s" does not implement "%s" or "%s".', \get_class($normalizer), NormalizerInterface::class, DenormalizerInterface::class)); } } @@ -104,7 +104,7 @@ public function __construct(array $normalizers = [], array $encoders = []) } if (!($encoder instanceof EncoderInterface || $encoder instanceof DecoderInterface)) { - @trigger_error(\sprintf('Passing encoders ("%s") which do not implement either "%s" or "%s" has been deprecated since Symfony 4.2.', \get_class($encoder), EncoderInterface::class, DecoderInterface::class), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing encoders ("%s") which do not implement either "%s" or "%s" has been deprecated since Symfony 4.2.', \get_class($encoder), EncoderInterface::class, DecoderInterface::class), E_USER_DEPRECATED); // throw new \InvalidArgumentException(\sprintf('The class "%s" does not implement "%s" or "%s".', \get_class($normalizer), EncoderInterface::class, DecoderInterface::class)); } } diff --git a/src/Symfony/Component/Translation/PluralizationRules.php b/src/Symfony/Component/Translation/PluralizationRules.php index ee8609fadabfa..77c276073f3f0 100644 --- a/src/Symfony/Component/Translation/PluralizationRules.php +++ b/src/Symfony/Component/Translation/PluralizationRules.php @@ -32,7 +32,7 @@ class PluralizationRules */ public static function get($number, $locale/*, bool $triggerDeprecation = true*/) { - if (3 > \func_num_args() || \func_get_arg(2)) { + if (3 > \func_num_args() || func_get_arg(2)) { @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2.', __CLASS__), E_USER_DEPRECATED); } diff --git a/src/Symfony/Component/Translation/Translator.php b/src/Symfony/Component/Translation/Translator.php index 8a2b2dd9d0c60..ec312ae787301 100644 --- a/src/Symfony/Component/Translation/Translator.php +++ b/src/Symfony/Component/Translation/Translator.php @@ -430,7 +430,7 @@ private function loadFallbackCatalogues($locale): void protected function computeFallbackLocales($locale) { if (null === $this->parentLocales) { - $parentLocales = \json_decode(\file_get_contents(__DIR__.'/Resources/data/parents.json'), true); + $parentLocales = json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true); } $locales = []; diff --git a/src/Symfony/Component/VarDumper/Caster/ClassStub.php b/src/Symfony/Component/VarDumper/Caster/ClassStub.php index b655ae960e16f..0b9329dbe903f 100644 --- a/src/Symfony/Component/VarDumper/Caster/ClassStub.php +++ b/src/Symfony/Component/VarDumper/Caster/ClassStub.php @@ -57,7 +57,7 @@ public function __construct(string $identifier, $callable = null) if (false !== strpos($identifier, "class@anonymous\0")) { $this->value = $identifier = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) { - return \class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; }, $identifier); } diff --git a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php index 06cd11e63dd50..83296bbc1a74b 100644 --- a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php @@ -283,7 +283,7 @@ private static function filterExceptionArray($xClass, array $a, $xPrefix, $filte if (isset($a[Caster::PREFIX_PROTECTED.'message']) && false !== strpos($a[Caster::PREFIX_PROTECTED.'message'], "class@anonymous\0")) { $a[Caster::PREFIX_PROTECTED.'message'] = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) { - return \class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; }, $a[Caster::PREFIX_PROTECTED.'message']); } diff --git a/src/Symfony/Component/VarDumper/Caster/ProxyManagerCaster.php b/src/Symfony/Component/VarDumper/Caster/ProxyManagerCaster.php index da037b6b3e8b3..d8afd704006a8 100644 --- a/src/Symfony/Component/VarDumper/Caster/ProxyManagerCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ProxyManagerCaster.php @@ -21,7 +21,7 @@ class ProxyManagerCaster { public static function castProxy(ProxyInterface $c, array $a, Stub $stub, $isNested) { - if ($parent = \get_parent_class($c)) { + if ($parent = get_parent_class($c)) { $stub->class .= ' - '.$parent; } $stub->class .= '@proxy'; diff --git a/src/Symfony/Component/VarDumper/Cloner/VarCloner.php b/src/Symfony/Component/VarDumper/Cloner/VarCloner.php index b8318c514ffbf..58c2117737f99 100644 --- a/src/Symfony/Component/VarDumper/Cloner/VarCloner.php +++ b/src/Symfony/Component/VarDumper/Cloner/VarCloner.php @@ -73,7 +73,7 @@ protected function doClone($var) } if ($gk !== $k) { $fromObjCast = true; - $refs = $vals = \array_values($queue[$i]); + $refs = $vals = array_values($queue[$i]); break; } } @@ -84,7 +84,7 @@ protected function doClone($var) if ($zvalIsRef = $vals[$k] === $cookie) { $vals[$k] = &$stub; // Break hard references to make $queue completely unset($stub); // independent from the original structure - if ($v instanceof Stub && isset($hardRefs[\spl_object_id($v)])) { + if ($v instanceof Stub && isset($hardRefs[spl_object_id($v)])) { $vals[$k] = $refs[$k] = $v; if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) { ++$v->value->refCount; @@ -94,7 +94,7 @@ protected function doClone($var) } $refs[$k] = $vals[$k] = new Stub(); $refs[$k]->value = $v; - $h = \spl_object_id($refs[$k]); + $h = spl_object_id($refs[$k]); $hardRefs[$h] = &$refs[$k]; $values[$h] = $v; $vals[$k]->handle = ++$refsCounter; @@ -112,22 +112,22 @@ protected function doClone($var) if ('' === $v) { continue 2; } - if (!\preg_match('//u', $v)) { + if (!preg_match('//u', $v)) { $stub = new Stub(); $stub->type = Stub::TYPE_STRING; $stub->class = Stub::STRING_BINARY; if (0 <= $maxString && 0 < $cut = \strlen($v) - $maxString) { $stub->cut = $cut; - $stub->value = \substr($v, 0, -$cut); + $stub->value = substr($v, 0, -$cut); } else { $stub->value = $v; } - } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = \mb_strlen($v, 'UTF-8') - $maxString) { + } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = mb_strlen($v, 'UTF-8') - $maxString) { $stub = new Stub(); $stub->type = Stub::TYPE_STRING; $stub->class = Stub::STRING_UTF8; $stub->cut = $cut; - $stub->value = \mb_substr($v, 0, $maxString, 'UTF-8'); + $stub->value = mb_substr($v, 0, $maxString, 'UTF-8'); } else { continue 2; } @@ -173,7 +173,7 @@ protected function doClone($var) case \is_object($v): case $v instanceof \__PHP_Incomplete_Class: - if (empty($objRefs[$h = \spl_object_id($v)])) { + if (empty($objRefs[$h = spl_object_id($v)])) { $stub = new Stub(); $stub->type = Stub::TYPE_OBJECT; $stub->class = \get_class($v); @@ -184,7 +184,7 @@ protected function doClone($var) if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) { break; } - $stub->handle = $h = \spl_object_id($stub->value); + $stub->handle = $h = spl_object_id($stub->value); } $stub->value = null; if (0 <= $maxItems && $maxItems <= $pos && $minimumDepthReached) { @@ -206,7 +206,7 @@ protected function doClone($var) if (empty($resRefs[$h = (int) $v])) { $stub = new Stub(); $stub->type = Stub::TYPE_RESOURCE; - if ('Unknown' === $stub->class = @\get_resource_type($v)) { + if ('Unknown' === $stub->class = @get_resource_type($v)) { $stub->class = 'Closed'; } $stub->value = $v; diff --git a/src/Symfony/Component/VarExporter/Internal/Exporter.php b/src/Symfony/Component/VarExporter/Internal/Exporter.php index 74a324691ea06..87b3156d41efd 100644 --- a/src/Symfony/Component/VarExporter/Internal/Exporter.php +++ b/src/Symfony/Component/VarExporter/Internal/Exporter.php @@ -40,7 +40,7 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount $refs = $values; foreach ($values as $k => $value) { if (\is_resource($value)) { - throw new NotInstantiableTypeException(\get_resource_type($value).' resource'); + throw new NotInstantiableTypeException(get_resource_type($value).' resource'); } $refs[$k] = $objectsPool; @@ -115,14 +115,14 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount goto handle_value; } - if (\method_exists($class, '__sleep')) { + if (method_exists($class, '__sleep')) { if (!\is_array($sleep = $value->__sleep())) { trigger_error('serialize(): __sleep should return an array only containing the names of instance-variables to serialize', E_USER_NOTICE); $value = null; goto handle_value; } foreach ($sleep as $name) { - if (\property_exists($value, $name) && !$reflector->hasProperty($name)) { + if (property_exists($value, $name) && !$reflector->hasProperty($name)) { $arrayValue[$name] = $value->$name; } } @@ -171,7 +171,7 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount $objectsPool[$value] = [$id = \count($objectsPool)]; $properties = self::prepare($properties, $objectsPool, $refsPool, $objectsCount, $valueIsStatic); ++$objectsCount; - $objectsPool[$value] = [$id, $class, $properties, \method_exists($class, '__unserialize') ? -$objectsCount : (\method_exists($class, '__wakeup') ? $objectsCount : 0)]; + $objectsPool[$value] = [$id, $class, $properties, method_exists($class, '__unserialize') ? -$objectsCount : (method_exists($class, '__wakeup') ? $objectsCount : 0)]; $value = new Reference($id); diff --git a/src/Symfony/Component/VarExporter/Internal/Hydrator.php b/src/Symfony/Component/VarExporter/Internal/Hydrator.php index 5f64adf96fb53..364d292d916e7 100644 --- a/src/Symfony/Component/VarExporter/Internal/Hydrator.php +++ b/src/Symfony/Component/VarExporter/Internal/Hydrator.php @@ -65,7 +65,7 @@ public static function getHydrator($class) }; } - if (!\class_exists($class) && !\interface_exists($class, false) && !\trait_exists($class, false)) { + if (!class_exists($class) && !interface_exists($class, false) && !trait_exists($class, false)) { throw new ClassNotFoundException($class); } $classReflector = new \ReflectionClass($class); diff --git a/src/Symfony/Component/VarExporter/Internal/Registry.php b/src/Symfony/Component/VarExporter/Internal/Registry.php index b5069dd16aa84..dd2792133e425 100644 --- a/src/Symfony/Component/VarExporter/Internal/Registry.php +++ b/src/Symfony/Component/VarExporter/Internal/Registry.php @@ -65,7 +65,7 @@ public static function f($class) public static function getClassReflector($class, $instantiableWithoutConstructor = false, $cloneable = null) { - if (!($isClass = \class_exists($class)) && !\interface_exists($class, false) && !\trait_exists($class, false)) { + if (!($isClass = class_exists($class)) && !interface_exists($class, false) && !trait_exists($class, false)) { throw new ClassNotFoundException($class); } $reflector = new \ReflectionClass($class); @@ -86,14 +86,14 @@ public static function getClassReflector($class, $instantiableWithoutConstructor $proto = $reflector->newInstanceWithoutConstructor(); $instantiableWithoutConstructor = true; } catch (\ReflectionException $e) { - $proto = $reflector->implementsInterface('Serializable') && (\PHP_VERSION_ID < 70400 || !\method_exists($class, '__unserialize')) ? 'C:' : 'O:'; + $proto = $reflector->implementsInterface('Serializable') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__unserialize')) ? 'C:' : 'O:'; if ('C:' === $proto && !$reflector->getMethod('unserialize')->isInternal()) { $proto = null; } elseif (false === $proto = @unserialize($proto.\strlen($class).':"'.$class.'":0:{}')) { throw new NotInstantiableTypeException($class); } } - if (null !== $proto && !$proto instanceof \Throwable && !$proto instanceof \Serializable && !\method_exists($class, '__sleep') && (\PHP_VERSION_ID < 70400 || !\method_exists($class, '__serialize'))) { + if (null !== $proto && !$proto instanceof \Throwable && !$proto instanceof \Serializable && !method_exists($class, '__sleep') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__serialize'))) { try { serialize($proto); } catch (\Exception $e) { @@ -103,7 +103,7 @@ public static function getClassReflector($class, $instantiableWithoutConstructor } if (null === $cloneable) { - if (($proto instanceof \Reflector || $proto instanceof \ReflectionGenerator || $proto instanceof \ReflectionType || $proto instanceof \IteratorIterator || $proto instanceof \RecursiveIteratorIterator) && (!$proto instanceof \Serializable && !\method_exists($proto, '__wakeup') && (\PHP_VERSION_ID < 70400 || !\method_exists($class, '__unserialize')))) { + if (($proto instanceof \Reflector || $proto instanceof \ReflectionGenerator || $proto instanceof \ReflectionType || $proto instanceof \IteratorIterator || $proto instanceof \RecursiveIteratorIterator) && (!$proto instanceof \Serializable && !method_exists($proto, '__wakeup') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__unserialize')))) { throw new NotInstantiableTypeException($class); } diff --git a/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php b/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php index 5a1654ae5503e..c0247014e7fcd 100644 --- a/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php +++ b/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php @@ -213,7 +213,7 @@ protected function dotize($id) */ protected function escape($value): string { - return \is_bool($value) ? ($value ? '1' : '0') : \addslashes($value); + return \is_bool($value) ? ($value ? '1' : '0') : addslashes($value); } private function addAttributes(array $attributes): string diff --git a/src/Symfony/Component/Workflow/Tests/StateMachineTest.php b/src/Symfony/Component/Workflow/Tests/StateMachineTest.php index 7f76c4a70b1ea..8354229a35af1 100644 --- a/src/Symfony/Component/Workflow/Tests/StateMachineTest.php +++ b/src/Symfony/Component/Workflow/Tests/StateMachineTest.php @@ -78,7 +78,7 @@ public function testBuildTransitionBlockerListReturnsExpectedReasonOnBranchMerge $net = new StateMachine($definition, null, $dispatcher); $dispatcher->addListener('workflow.guard', function (GuardEvent $event) { - $event->addTransitionBlocker(new TransitionBlocker(\sprintf('Transition blocker of place %s', $event->getTransition()->getFroms()[0]), 'blocker')); + $event->addTransitionBlocker(new TransitionBlocker(sprintf('Transition blocker of place %s', $event->getTransition()->getFroms()[0]), 'blocker')); }); $subject = new \stdClass(); diff --git a/src/Symfony/Contracts/Translation/TranslatorTrait.php b/src/Symfony/Contracts/Translation/TranslatorTrait.php index c1021923c835a..488b4f4f23974 100644 --- a/src/Symfony/Contracts/Translation/TranslatorTrait.php +++ b/src/Symfony/Contracts/Translation/TranslatorTrait.php @@ -91,7 +91,7 @@ public function trans($id, array $parameters = [], $domain = null, $locale = nul } } else { $leftNumber = '-Inf' === $matches['left'] ? -INF : (float) $matches['left']; - $rightNumber = \is_numeric($matches['right']) ? (float) $matches['right'] : INF; + $rightNumber = is_numeric($matches['right']) ? (float) $matches['right'] : INF; if (('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber) && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber) @@ -117,7 +117,7 @@ public function trans($id, array $parameters = [], $domain = null, $locale = nul $message = sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $id, $locale, $number); - if (\class_exists(InvalidArgumentException::class)) { + if (class_exists(InvalidArgumentException::class)) { throw new InvalidArgumentException($message); } From 9526988eca09d0ace3330edcf2403a94a3903b0f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 13 Jun 2019 13:03:18 +0200 Subject: [PATCH 039/106] fixed CS --- src/Symfony/Bridge/PhpUnit/ClassExistsMock.php | 6 +++--- .../Twig/Extension/HttpFoundationExtension.php | 2 +- .../DependencyInjection/FrameworkExtension.php | 12 ++++++------ .../FrameworkBundle/Test/WebTestAssertionsTrait.php | 2 +- .../Cache/Adapter/AbstractTagAwareAdapter.php | 12 ++++++------ .../Cache/Adapter/FilesystemTagAwareAdapter.php | 2 +- .../Component/Cache/Adapter/RedisTagAwareAdapter.php | 10 +++++----- src/Symfony/Component/Console/Helper/ProgressBar.php | 2 +- .../Console/Tests/Helper/ProgressBarTest.php | 4 ++-- src/Symfony/Component/Debug/DebugClassLoader.php | 2 +- src/Symfony/Component/Debug/ExceptionHandler.php | 4 ++-- .../Component/DependencyInjection/Definition.php | 2 +- src/Symfony/Component/DomCrawler/Crawler.php | 4 ++-- .../Test/Constraint/CrawlerSelectorTextContains.php | 2 +- .../Debug/TraceableEventDispatcher.php | 8 ++++---- .../Component/EventDispatcher/EventDispatcher.php | 2 +- .../EventDispatcher/ImmutableEventDispatcher.php | 4 ++-- .../EventDispatcher/LegacyEventDispatcherProxy.php | 2 +- src/Symfony/Component/Finder/SplFileInfo.php | 2 +- src/Symfony/Component/Form/ButtonBuilder.php | 2 +- .../ChoiceList/Factory/DefaultChoiceListFactory.php | 2 +- .../Component/HttpClient/CachingHttpClient.php | 2 +- src/Symfony/Component/HttpClient/CurlHttpClient.php | 2 +- src/Symfony/Component/HttpClient/HttpClientTrait.php | 2 +- src/Symfony/Component/HttpClient/MockHttpClient.php | 2 +- .../Component/HttpClient/NativeHttpClient.php | 2 +- .../Component/HttpClient/Response/MockResponse.php | 2 +- .../HttpClient/Tests/HttpClientTraitTest.php | 2 +- src/Symfony/Component/Lock/Store/StoreFactory.php | 2 +- .../Component/Lock/Tests/Store/StoreFactoryTest.php | 10 +++++----- .../Mailer/Bridge/Amazon/Http/Api/SesTransport.php | 2 +- .../Mailer/Bridge/Amazon/Http/SesTransport.php | 2 +- .../Mailer/Bridge/Amazon/Smtp/SesTransport.php | 2 +- .../Bridge/Sendgrid/Http/Api/SendgridTransport.php | 2 +- src/Symfony/Component/Mailer/Transport.php | 6 +++--- .../Component/Mailer/Transport/AbstractTransport.php | 2 +- .../Transport/Http/Api/AbstractApiTransport.php | 4 ++-- src/Symfony/Component/Messenger/Envelope.php | 2 +- .../SendFailedMessageToFailureTransportListener.php | 2 +- .../Messenger/Middleware/StackMiddleware.php | 2 +- .../Tests/Transport/Doctrine/ConnectionTest.php | 2 +- .../Transport/Doctrine/DoctrineReceiverTest.php | 2 +- .../Messenger/Transport/Doctrine/Connection.php | 4 ++-- .../Messenger/Transport/RedisExt/Connection.php | 2 +- .../PropertyInfo/PropertyInfoCacheExtractor.php | 2 +- .../Core/Authentication/Token/AbstractToken.php | 2 +- .../Security/Core/Encoder/SodiumPasswordEncoder.php | 6 +++--- .../Core/Exception/AuthenticationException.php | 2 +- .../DependencyInjection/TranslatorPathsPass.php | 2 +- .../Component/Translation/Extractor/PhpExtractor.php | 2 +- .../Contracts/HttpClient/Test/Fixtures/web/index.php | 2 +- 51 files changed, 84 insertions(+), 84 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/ClassExistsMock.php b/src/Symfony/Bridge/PhpUnit/ClassExistsMock.php index e8ca4ac9402a8..fbd0a4fa4d5a7 100644 --- a/src/Symfony/Bridge/PhpUnit/ClassExistsMock.php +++ b/src/Symfony/Bridge/PhpUnit/ClassExistsMock.php @@ -30,17 +30,17 @@ public static function withMockedClasses(array $classes) public static function class_exists($name, $autoload = true) { - return (bool) (self::$classes[ltrim($name, '\\')] ?? \class_exists($name, $autoload)); + return (bool) (self::$classes[ltrim($name, '\\')] ?? class_exists($name, $autoload)); } public static function interface_exists($name, $autoload = true) { - return (bool) (self::$classes[ltrim($name, '\\')] ?? \interface_exists($name, $autoload)); + return (bool) (self::$classes[ltrim($name, '\\')] ?? interface_exists($name, $autoload)); } public static function trait_exists($name, $autoload = true) { - return (bool) (self::$classes[ltrim($name, '\\')] ?? \trait_exists($name, $autoload)); + return (bool) (self::$classes[ltrim($name, '\\')] ?? trait_exists($name, $autoload)); } public static function register($class) diff --git a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php index a72339e1243e1..e7421b16d72e3 100644 --- a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php @@ -46,7 +46,7 @@ public function __construct($urlHelper) $requestContext = null; if (2 === \func_num_args()) { - $requestContext = \func_get_arg(1); + $requestContext = func_get_arg(1); if (null !== $requestContext && !$requestContext instanceof RequestContext) { throw new \TypeError(sprintf('The second argument must be an instance of "%s".', RequestContext::class)); } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 98c94f2a21ccc..1c3cb5311c8ca 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1115,12 +1115,12 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder $defaultDir = $container->getParameterBag()->resolveValue($config['default_path']); $rootDir = $container->getParameter('kernel.root_dir'); foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) { - if (\is_dir($dir = $bundle['path'].'/Resources/translations')) { + if (is_dir($dir = $bundle['path'].'/Resources/translations')) { $dirs[] = $dir; } else { $nonExistingDirs[] = $dir; } - if (\is_dir($dir = $rootDir.sprintf('/Resources/%s/translations', $name))) { + if (is_dir($dir = $rootDir.sprintf('/Resources/%s/translations', $name))) { @trigger_error(sprintf('Translations directory "%s" is deprecated since Symfony 4.2, use "%s" instead.', $dir, $defaultDir), E_USER_DEPRECATED); $dirs[] = $dir; } else { @@ -1129,7 +1129,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder } foreach ($config['paths'] as $dir) { - if (\is_dir($dir)) { + if (is_dir($dir)) { $dirs[] = $transPaths[] = $dir; } else { throw new \UnexpectedValueException(sprintf('%s defined in translator.paths does not exist or is not a directory', $dir)); @@ -1144,13 +1144,13 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder $container->getDefinition('console.command.translation_update')->replaceArgument(6, $transPaths); } - if (\is_dir($defaultDir)) { + if (is_dir($defaultDir)) { $dirs[] = $defaultDir; } else { $nonExistingDirs[] = $defaultDir; } - if (\is_dir($dir = $rootDir.'/Resources/translations')) { + if (is_dir($dir = $rootDir.'/Resources/translations')) { if ($dir !== $defaultDir) { @trigger_error(sprintf('Translations directory "%s" is deprecated since Symfony 4.2, use "%s" instead.', $dir, $defaultDir), E_USER_DEPRECATED); } @@ -1186,7 +1186,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder $translator->getArgument(4), [ 'resource_files' => $files, - 'scanned_directories' => \array_merge($dirs, $nonExistingDirs), + 'scanned_directories' => array_merge($dirs, $nonExistingDirs), ] ); diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php index e3e37a535931b..f820e8d0802ae 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php @@ -195,7 +195,7 @@ private static function getClient(KernelBrowser $newClient = null): ?KernelBrows } if (!$client instanceof KernelBrowser) { - static::fail(\sprintf('A client must be set to make assertions on it. Did you forget to call "%s::createClient()"?', __CLASS__)); + static::fail(sprintf('A client must be set to make assertions on it. Did you forget to call "%s::createClient()"?', __CLASS__)); } return $client; diff --git a/src/Symfony/Component/Cache/Adapter/AbstractTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractTagAwareAdapter.php index 2eb5ce8c6ea54..97476a8a71845 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractTagAwareAdapter.php @@ -60,7 +60,7 @@ static function ($key, $value, $isHit) use ($defaultLifetime) { $item->metadata[CacheItem::METADATA_TAGS] = $value['tags'] ?? []; if (isset($value['meta'])) { // For compactness these values are packed, & expiry is offset to reduce size - $v = \unpack('Ve/Nc', $value['meta']); + $v = unpack('Ve/Nc', $value['meta']); $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET; $item->metadata[CacheItem::METADATA_CTIME] = $v['c']; } @@ -96,16 +96,16 @@ static function ($deferred, &$expiredIds) use ($getId, $tagPrefix) { if ($metadata) { // For compactness, expiry and creation duration are packed, using magic numbers as separators - $value['meta'] = \pack('VN', (int) $metadata[CacheItem::METADATA_EXPIRY] - CacheItem::METADATA_EXPIRY_OFFSET, $metadata[CacheItem::METADATA_CTIME]); + $value['meta'] = pack('VN', (int) $metadata[CacheItem::METADATA_EXPIRY] - CacheItem::METADATA_EXPIRY_OFFSET, $metadata[CacheItem::METADATA_CTIME]); } // Extract tag changes, these should be removed from values in doSave() $value['tag-operations'] = ['add' => [], 'remove' => []]; $oldTags = $item->metadata[CacheItem::METADATA_TAGS] ?? []; - foreach (\array_diff($value['tags'], $oldTags) as $addedTag) { + foreach (array_diff($value['tags'], $oldTags) as $addedTag) { $value['tag-operations']['add'][] = $getId($tagPrefix.$addedTag); } - foreach (\array_diff($oldTags, $value['tags']) as $removedTag) { + foreach (array_diff($oldTags, $value['tags']) as $removedTag) { $value['tag-operations']['remove'][] = $getId($tagPrefix.$removedTag); } @@ -236,7 +236,7 @@ public function deleteItems(array $keys) } try { - if ($this->doDelete(\array_values($ids), $tagData)) { + if ($this->doDelete(array_values($ids), $tagData)) { return true; } } catch (\Exception $e) { @@ -271,7 +271,7 @@ public function invalidateTags(array $tags) } $tagIds = []; - foreach (\array_unique($tags) as $tag) { + foreach (array_unique($tags) as $tag) { $tagIds[] = $this->getId(self::TAGS_PREFIX.$tag); } diff --git a/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php index f96c670ae92e8..0dd81a99704ed 100644 --- a/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php @@ -126,7 +126,7 @@ protected function doInvalidate(array $tagIds): bool } $valueFile = $itemLink->getRealPath(); - if ($valueFile && \file_exists($valueFile)) { + if ($valueFile && file_exists($valueFile)) { @unlink($valueFile); } diff --git a/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php index 4e093872138fb..382defcd2c8e7 100644 --- a/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php @@ -82,7 +82,7 @@ public function __construct($redisClient, string $namespace = '', int $defaultLi $this->init($redisClient, $namespace, $defaultLifetime, $marshaller); // Make sure php-redis is 3.1.3 or higher configured for Redis classes - if (!$this->redis instanceof Predis\Client && \version_compare(\phpversion('redis'), '3.1.3', '<')) { + if (!$this->redis instanceof Predis\Client && version_compare(phpversion('redis'), '3.1.3', '<')) { throw new LogicException('RedisTagAwareAdapter requires php-redis 3.1.3 or higher, alternatively use predis/predis'); } } @@ -120,7 +120,7 @@ protected function doSave(array $values, ?int $lifetime, array $addTagData = [], foreach ($results as $id => $result) { // Skip results of SADD/SREM operations, they'll be 1 or 0 depending on if set value already existed or not - if (\is_numeric($result)) { + if (is_numeric($result)) { continue; } // setEx results @@ -152,7 +152,7 @@ protected function doDelete(array $ids, array $tagData = []): bool } foreach ($tagData as $tagId => $idList) { - yield 'sRem' => \array_merge([$tagId], $idList); + yield 'sRem' => array_merge([$tagId], $idList); } })->rewind(); @@ -178,10 +178,10 @@ protected function doInvalidate(array $tagIds): bool }); // Flatten generator result from pipeline, ignore keys (tag ids) - $ids = \array_unique(\array_merge(...\iterator_to_array($tagIdSets, false))); + $ids = array_unique(array_merge(...iterator_to_array($tagIdSets, false))); // Delete cache in chunks to avoid overloading the connection - foreach (\array_chunk($ids, self::BULK_DELETE_LIMIT) as $chunkIds) { + foreach (array_chunk($ids, self::BULK_DELETE_LIMIT) as $chunkIds) { $this->doDelete($chunkIds); } diff --git a/src/Symfony/Component/Console/Helper/ProgressBar.php b/src/Symfony/Component/Console/Helper/ProgressBar.php index 34e6aa5d2bac9..e30fe786e3ab6 100644 --- a/src/Symfony/Component/Console/Helper/ProgressBar.php +++ b/src/Symfony/Component/Console/Helper/ProgressBar.php @@ -250,7 +250,7 @@ public function setRedrawFrequency(int $freq) */ public function iterate(iterable $iterable, ?int $max = null): iterable { - $this->start($max ?? (\is_countable($iterable) ? \count($iterable) : 0)); + $this->start($max ?? (is_countable($iterable) ? \count($iterable) : 0)); foreach ($iterable as $key => $value) { yield $key => $value; diff --git a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php index 8d37d3af047a6..2dcd51f7b18c8 100644 --- a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php @@ -884,7 +884,7 @@ public function testIterate(): void { $bar = new ProgressBar($output = $this->getOutputStream()); - $this->assertEquals([1, 2], \iterator_to_array($bar->iterate([1, 2]))); + $this->assertEquals([1, 2], iterator_to_array($bar->iterate([1, 2]))); rewind($output->getStream()); $this->assertEquals( @@ -900,7 +900,7 @@ public function testIterateUncountable(): void { $bar = new ProgressBar($output = $this->getOutputStream()); - $this->assertEquals([1, 2], \iterator_to_array($bar->iterate((function () { + $this->assertEquals([1, 2], iterator_to_array($bar->iterate((function () { yield 1; yield 2; })()))); diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index b78e608985b32..ff9a8d72f903f 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -238,7 +238,7 @@ public function checkAnnotations(\ReflectionClass $refl, $class) } } - if ($refl->isInterface() && false !== \strpos($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+(?:[\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, PREG_SET_ORDER)) { + if ($refl->isInterface() && false !== strpos($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+(?:[\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, PREG_SET_ORDER)) { foreach ($notice as $method) { $static = '' !== $method[1]; $name = $method[2]; diff --git a/src/Symfony/Component/Debug/ExceptionHandler.php b/src/Symfony/Component/Debug/ExceptionHandler.php index 7ae85eebb7f7c..743de65622d44 100644 --- a/src/Symfony/Component/Debug/ExceptionHandler.php +++ b/src/Symfony/Component/Debug/ExceptionHandler.php @@ -457,10 +457,10 @@ private function getSymfonyGhostAsSvg() private function addElementToGhost() { - if (!isset(self::GHOST_ADDONS[\date('m-d')])) { + if (!isset(self::GHOST_ADDONS[date('m-d')])) { return ''; } - return ''; + return ''; } } diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php index 2700f88c47a31..ff41c1a7eb5c2 100644 --- a/src/Symfony/Component/DependencyInjection/Definition.php +++ b/src/Symfony/Component/DependencyInjection/Definition.php @@ -354,7 +354,7 @@ public function addMethodCall($method, array $arguments = []/*, bool $returnsClo if (empty($method)) { throw new InvalidArgumentException('Method name cannot be empty.'); } - $this->calls[] = 2 < \func_num_args() && \func_get_arg(2) ? [$method, $arguments, true] : [$method, $arguments]; + $this->calls[] = 2 < \func_num_args() && func_get_arg(2) ? [$method, $arguments, true] : [$method, $arguments]; return $this; } diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index 13dab5e84ff08..d44540722cae9 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -566,7 +566,7 @@ public function text(/* $default = null */) { if (!$this->nodes) { if (0 < \func_num_args()) { - return \func_get_arg(0); + return func_get_arg(0); } throw new \InvalidArgumentException('The current node list is empty.'); @@ -588,7 +588,7 @@ public function html(/* $default = null */) { if (!$this->nodes) { if (0 < \func_num_args()) { - return \func_get_arg(0); + return func_get_arg(0); } throw new \InvalidArgumentException('The current node list is empty.'); diff --git a/src/Symfony/Component/DomCrawler/Test/Constraint/CrawlerSelectorTextContains.php b/src/Symfony/Component/DomCrawler/Test/Constraint/CrawlerSelectorTextContains.php index 260ec57b07504..0ddca408697fb 100644 --- a/src/Symfony/Component/DomCrawler/Test/Constraint/CrawlerSelectorTextContains.php +++ b/src/Symfony/Component/DomCrawler/Test/Constraint/CrawlerSelectorTextContains.php @@ -45,7 +45,7 @@ protected function matches($crawler): bool return false; } - return false !== \mb_strpos($crawler->text(), $this->expectedText); + return false !== mb_strpos($crawler->text(), $this->expectedText); } /** diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php index 8768d7b14145f..2da03e82c12ee 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php @@ -140,7 +140,7 @@ public function dispatch($event/*, string $eventName = null*/) } $currentRequestHash = $this->currentRequestHash = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_hash($request) : ''; - $eventName = 1 < \func_num_args() ? \func_get_arg(1) : null; + $eventName = 1 < \func_num_args() ? func_get_arg(1) : null; if (\is_object($event)) { $eventName = $eventName ?? \get_class($event); @@ -193,7 +193,7 @@ public function getCalledListeners(/* Request $request = null */) return []; } - $hash = 1 <= \func_num_args() && null !== ($request = \func_get_arg(0)) ? spl_object_hash($request) : null; + $hash = 1 <= \func_num_args() && null !== ($request = func_get_arg(0)) ? spl_object_hash($request) : null; $called = []; foreach ($this->callStack as $listener) { list($eventName, $requestHash) = $this->callStack->getInfo(); @@ -223,7 +223,7 @@ public function getNotCalledListeners(/* Request $request = null */) return []; } - $hash = 1 <= \func_num_args() && null !== ($request = \func_get_arg(0)) ? spl_object_hash($request) : null; + $hash = 1 <= \func_num_args() && null !== ($request = func_get_arg(0)) ? spl_object_hash($request) : null; $calledListeners = []; if (null !== $this->callStack) { @@ -258,7 +258,7 @@ public function getNotCalledListeners(/* Request $request = null */) */ public function getOrphanedEvents(/* Request $request = null */): array { - if (1 <= \func_num_args() && null !== $request = \func_get_arg(0)) { + if (1 <= \func_num_args() && null !== $request = func_get_arg(0)) { return $this->orphanedEvents[spl_object_hash($request)] ?? []; } diff --git a/src/Symfony/Component/EventDispatcher/EventDispatcher.php b/src/Symfony/Component/EventDispatcher/EventDispatcher.php index e68918c31c680..304caec1d1a79 100644 --- a/src/Symfony/Component/EventDispatcher/EventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/EventDispatcher.php @@ -50,7 +50,7 @@ public function __construct() */ public function dispatch($event/*, string $eventName = null*/) { - $eventName = 1 < \func_num_args() ? \func_get_arg(1) : null; + $eventName = 1 < \func_num_args() ? func_get_arg(1) : null; if (\is_object($event)) { $eventName = $eventName ?? \get_class($event); diff --git a/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php index 082e2a05d48f9..75a7d7318187b 100644 --- a/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php @@ -32,9 +32,9 @@ public function __construct(EventDispatcherInterface $dispatcher) */ public function dispatch($event/*, string $eventName = null*/) { - $eventName = 1 < \func_num_args() ? \func_get_arg(1) : null; + $eventName = 1 < \func_num_args() ? func_get_arg(1) : null; - if (\is_scalar($event)) { + if (is_scalar($event)) { // deprecated $swap = $event; $event = $eventName ?? new Event(); diff --git a/src/Symfony/Component/EventDispatcher/LegacyEventDispatcherProxy.php b/src/Symfony/Component/EventDispatcher/LegacyEventDispatcherProxy.php index 3ae3735e23e52..534eec98a5b63 100644 --- a/src/Symfony/Component/EventDispatcher/LegacyEventDispatcherProxy.php +++ b/src/Symfony/Component/EventDispatcher/LegacyEventDispatcherProxy.php @@ -53,7 +53,7 @@ public static function decorate(?ContractsEventDispatcherInterface $dispatcher): */ public function dispatch($event/*, string $eventName = null*/) { - $eventName = 1 < \func_num_args() ? \func_get_arg(1) : null; + $eventName = 1 < \func_num_args() ? func_get_arg(1) : null; if (\is_object($event)) { $eventName = $eventName ?? \get_class($event); diff --git a/src/Symfony/Component/Finder/SplFileInfo.php b/src/Symfony/Component/Finder/SplFileInfo.php index ee798dc703f00..65d7423e0da32 100644 --- a/src/Symfony/Component/Finder/SplFileInfo.php +++ b/src/Symfony/Component/Finder/SplFileInfo.php @@ -61,7 +61,7 @@ public function getFilenameWithoutExtension(): string { $filename = $this->getFilename(); - return \pathinfo($filename, PATHINFO_FILENAME); + return pathinfo($filename, PATHINFO_FILENAME); } /** diff --git a/src/Symfony/Component/Form/ButtonBuilder.php b/src/Symfony/Component/Form/ButtonBuilder.php index 46ca01c6d435b..19196729f1cb0 100644 --- a/src/Symfony/Component/Form/ButtonBuilder.php +++ b/src/Symfony/Component/Form/ButtonBuilder.php @@ -61,7 +61,7 @@ public function __construct(?string $name, array $options = []) $this->name = $name; $this->options = $options; - if (\preg_match('/^([^a-z0-9_].*)?(.*[^a-zA-Z0-9_\-:].*)?$/D', $name, $matches)) { + if (preg_match('/^([^a-z0-9_].*)?(.*[^a-zA-Z0-9_\-:].*)?$/D', $name, $matches)) { if (isset($matches[1])) { @trigger_error(sprintf('Using names for buttons that do not start with a letter, a digit, or an underscore is deprecated since Symfony 4.3 and will throw an exception in 5.0 ("%s" given).', $name), E_USER_DEPRECATED); } diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php index e7100d22374c5..68da1b2516b8d 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php @@ -236,7 +236,7 @@ private static function addChoiceViewsGroupedByCallable($groupBy, $choice, $valu return; } - $groupLabels = \is_array($groupLabels) ? \array_map('strval', $groupLabels) : [(string) $groupLabels]; + $groupLabels = \is_array($groupLabels) ? array_map('strval', $groupLabels) : [(string) $groupLabels]; foreach ($groupLabels as $groupLabel) { // Initialize the group views if necessary. Unnecessarily built group diff --git a/src/Symfony/Component/HttpClient/CachingHttpClient.php b/src/Symfony/Component/HttpClient/CachingHttpClient.php index 7cf28a28fc75b..65426ef647437 100644 --- a/src/Symfony/Component/HttpClient/CachingHttpClient.php +++ b/src/Symfony/Component/HttpClient/CachingHttpClient.php @@ -109,7 +109,7 @@ public function stream($responses, float $timeout = null): ResponseStreamInterfa { if ($responses instanceof ResponseInterface) { $responses = [$responses]; - } elseif (!\is_iterable($responses)) { + } elseif (!is_iterable($responses)) { throw new \TypeError(sprintf('%s() expects parameter 1 to be an iterable of ResponseInterface objects, %s given.', __METHOD__, \is_object($responses) ? \get_class($responses) : \gettype($responses))); } diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index 9f7401b0aa466..199a3b4ea17f7 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -284,7 +284,7 @@ public function stream($responses, float $timeout = null): ResponseStreamInterfa { if ($responses instanceof CurlResponse) { $responses = [$responses]; - } elseif (!\is_iterable($responses)) { + } elseif (!is_iterable($responses)) { throw new \TypeError(sprintf('%s() expects parameter 1 to be an iterable of CurlResponse objects, %s given.', __METHOD__, \is_object($responses) ? \get_class($responses) : \gettype($responses))); } diff --git a/src/Symfony/Component/HttpClient/HttpClientTrait.php b/src/Symfony/Component/HttpClient/HttpClientTrait.php index 2df830e111304..4d263f46db7de 100644 --- a/src/Symfony/Component/HttpClient/HttpClientTrait.php +++ b/src/Symfony/Component/HttpClient/HttpClientTrait.php @@ -200,7 +200,7 @@ private static function normalizeHeaders(array $headers): array if (\is_int($name)) { [$name, $values] = explode(':', $values, 2); $values = [ltrim($values)]; - } elseif (!\is_iterable($values)) { + } elseif (!is_iterable($values)) { $values = (array) $values; } diff --git a/src/Symfony/Component/HttpClient/MockHttpClient.php b/src/Symfony/Component/HttpClient/MockHttpClient.php index 987f04211fbdf..cb3cb969b06ba 100644 --- a/src/Symfony/Component/HttpClient/MockHttpClient.php +++ b/src/Symfony/Component/HttpClient/MockHttpClient.php @@ -78,7 +78,7 @@ public function stream($responses, float $timeout = null): ResponseStreamInterfa { if ($responses instanceof ResponseInterface) { $responses = [$responses]; - } elseif (!\is_iterable($responses)) { + } elseif (!is_iterable($responses)) { throw new \TypeError(sprintf('%s() expects parameter 1 to be an iterable of MockResponse objects, %s given.', __METHOD__, \is_object($responses) ? \get_class($responses) : \gettype($responses))); } diff --git a/src/Symfony/Component/HttpClient/NativeHttpClient.php b/src/Symfony/Component/HttpClient/NativeHttpClient.php index 55313b1ccc740..068f3eb7bad31 100644 --- a/src/Symfony/Component/HttpClient/NativeHttpClient.php +++ b/src/Symfony/Component/HttpClient/NativeHttpClient.php @@ -220,7 +220,7 @@ public function stream($responses, float $timeout = null): ResponseStreamInterfa { if ($responses instanceof NativeResponse) { $responses = [$responses]; - } elseif (!\is_iterable($responses)) { + } elseif (!is_iterable($responses)) { throw new \TypeError(sprintf('%s() expects parameter 1 to be an iterable of NativeResponse objects, %s given.', __METHOD__, \is_object($responses) ? \get_class($responses) : \gettype($responses))); } diff --git a/src/Symfony/Component/HttpClient/Response/MockResponse.php b/src/Symfony/Component/HttpClient/Response/MockResponse.php index 04b33a143aa20..47fc084d376f3 100644 --- a/src/Symfony/Component/HttpClient/Response/MockResponse.php +++ b/src/Symfony/Component/HttpClient/Response/MockResponse.php @@ -44,7 +44,7 @@ class MockResponse implements ResponseInterface */ public function __construct($body = '', array $info = []) { - $this->body = \is_iterable($body) ? $body : (string) $body; + $this->body = is_iterable($body) ? $body : (string) $body; $this->info = $info + $this->info; if (!isset($info['response_headers'])) { diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php index 056181e30ea1b..4948822c5e43e 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php +++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php @@ -232,7 +232,7 @@ public function testPrepareAuthBasic($arg, $result) public function provideFingerprints() { foreach (['md5', 'sha1', 'sha256'] as $algo) { - $hash = \hash($algo, $algo); + $hash = hash($algo, $algo); yield [$hash, [$algo => $hash]]; } diff --git a/src/Symfony/Component/Lock/Store/StoreFactory.php b/src/Symfony/Component/Lock/Store/StoreFactory.php index b702b81b70e0c..5d9335db34744 100644 --- a/src/Symfony/Component/Lock/Store/StoreFactory.php +++ b/src/Symfony/Component/Lock/Store/StoreFactory.php @@ -58,7 +58,7 @@ public static function createStore($connection) return new FlockStore(substr($connection, 8)); case 'semaphore' === $connection: return new SemaphoreStore(); - case \class_exists(AbstractAdapter::class) && preg_match('#^[a-z]++://#', $connection): + case class_exists(AbstractAdapter::class) && preg_match('#^[a-z]++://#', $connection): return static::createStore(AbstractAdapter::createConnection($connection)); default: throw new InvalidArgumentException(sprintf('Unsupported Connection: %s.', $connection)); diff --git a/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php b/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php index 4edb4d361a450..3291b14f4e2c2 100644 --- a/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php @@ -38,23 +38,23 @@ public function testCreateStore($connection, string $expectedStoreClass) public function validConnections() { - if (\class_exists(\Redis::class)) { + if (class_exists(\Redis::class)) { yield [$this->createMock(\Redis::class), RedisStore::class]; } - if (\class_exists(RedisProxy::class)) { + if (class_exists(RedisProxy::class)) { yield [$this->createMock(RedisProxy::class), RedisStore::class]; } yield [new \Predis\Client(), RedisStore::class]; - if (\class_exists(\Memcached::class)) { + if (class_exists(\Memcached::class)) { yield [new \Memcached(), MemcachedStore::class]; } - if (\class_exists(\Zookeeper::class)) { + if (class_exists(\Zookeeper::class)) { yield [$this->createMock(\Zookeeper::class), ZookeeperStore::class]; } if (\extension_loaded('sysvsem')) { yield ['semaphore', SemaphoreStore::class]; } - if (\class_exists(\Memcached::class) && \class_exists(AbstractAdapter::class)) { + if (class_exists(\Memcached::class) && class_exists(AbstractAdapter::class)) { yield ['memcached://server.com', MemcachedStore::class]; } diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Http/Api/SesTransport.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Http/Api/SesTransport.php index 0bd4b5aa1db46..c10b8df3ae90d 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Http/Api/SesTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Http/Api/SesTransport.php @@ -76,7 +76,7 @@ private function getPayload(Email $email, SmtpEnvelope $envelope): array if ($email->getAttachments()) { return [ 'Action' => 'SendRawEmail', - 'RawMessage.Data' => \base64_encode($email->toString()), + 'RawMessage.Data' => base64_encode($email->toString()), ]; } diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Http/SesTransport.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Http/SesTransport.php index fd3787a5c2314..edca32c58fb3a 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Http/SesTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Http/SesTransport.php @@ -56,7 +56,7 @@ protected function doSend(SentMessage $message): void ], 'body' => [ 'Action' => 'SendRawEmail', - 'RawMessage.Data' => \base64_encode($message->toString()), + 'RawMessage.Data' => base64_encode($message->toString()), ], ]); diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Smtp/SesTransport.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Smtp/SesTransport.php index dc72f959c4d3f..e17de68f8e33d 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Smtp/SesTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Smtp/SesTransport.php @@ -27,7 +27,7 @@ class SesTransport extends EsmtpTransport */ public function __construct(string $username, string $password, string $region = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) { - parent::__construct(\sprintf('email-smtp.%s.amazonaws.com', $region ?: 'eu-west-1'), 587, 'tls', null, $dispatcher, $logger); + parent::__construct(sprintf('email-smtp.%s.amazonaws.com', $region ?: 'eu-west-1'), 587, 'tls', null, $dispatcher, $logger); $this->setUsername($username); $this->setPassword($password); diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Http/Api/SendgridTransport.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Http/Api/SendgridTransport.php index e45db91181f3c..8369d4e2775a0 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Http/Api/SendgridTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Http/Api/SendgridTransport.php @@ -67,7 +67,7 @@ private function getPayload(Email $email, SmtpEnvelope $envelope): array } $personalization = [ - 'to' => \array_map($addressStringifier, $this->getRecipients($email, $envelope)), + 'to' => array_map($addressStringifier, $this->getRecipients($email, $envelope)), 'subject' => $email->getSubject(), ]; if ($emails = array_map($addressStringifier, $email->getCc())) { diff --git a/src/Symfony/Component/Mailer/Transport.php b/src/Symfony/Component/Mailer/Transport.php index eeb1892fe8b3c..326452ede9de8 100644 --- a/src/Symfony/Component/Mailer/Transport.php +++ b/src/Symfony/Component/Mailer/Transport.php @@ -68,9 +68,9 @@ private static function createTransport(string $dsn, EventDispatcherInterface $d throw new InvalidArgumentException(sprintf('The "%s" mailer DSN must contain a mailer name.', $dsn)); } - $user = \urldecode($parsedDsn['user'] ?? ''); - $pass = \urldecode($parsedDsn['pass'] ?? ''); - \parse_str($parsedDsn['query'] ?? '', $query); + $user = urldecode($parsedDsn['user'] ?? ''); + $pass = urldecode($parsedDsn['pass'] ?? ''); + parse_str($parsedDsn['query'] ?? '', $query); switch ($parsedDsn['host']) { case 'null': diff --git a/src/Symfony/Component/Mailer/Transport/AbstractTransport.php b/src/Symfony/Component/Mailer/Transport/AbstractTransport.php index 748743fa8a307..2b1fd87b748e8 100644 --- a/src/Symfony/Component/Mailer/Transport/AbstractTransport.php +++ b/src/Symfony/Component/Mailer/Transport/AbstractTransport.php @@ -93,7 +93,7 @@ abstract protected function doSend(SentMessage $message): void; */ protected function stringifyAddresses(array $addresses): array { - return \array_map(function (Address $a) { + return array_map(function (Address $a) { return $a->toString(); }, $addresses); } diff --git a/src/Symfony/Component/Mailer/Transport/Http/Api/AbstractApiTransport.php b/src/Symfony/Component/Mailer/Transport/Http/Api/AbstractApiTransport.php index 89c25ca37661d..f844267fede15 100644 --- a/src/Symfony/Component/Mailer/Transport/Http/Api/AbstractApiTransport.php +++ b/src/Symfony/Component/Mailer/Transport/Http/Api/AbstractApiTransport.php @@ -61,8 +61,8 @@ protected function doSend(SentMessage $message): void protected function getRecipients(Email $email, SmtpEnvelope $envelope): array { - return \array_filter($envelope->getRecipients(), function (Address $address) use ($email) { - return false === \in_array($address, \array_merge($email->getCc(), $email->getBcc()), true); + return array_filter($envelope->getRecipients(), function (Address $address) use ($email) { + return false === \in_array($address, array_merge($email->getCc(), $email->getBcc()), true); }); } } diff --git a/src/Symfony/Component/Messenger/Envelope.php b/src/Symfony/Component/Messenger/Envelope.php index be012fba944d4..a876a3c3ae430 100644 --- a/src/Symfony/Component/Messenger/Envelope.php +++ b/src/Symfony/Component/Messenger/Envelope.php @@ -88,7 +88,7 @@ public function withoutStampsOfType(string $type): self $cloned = clone $this; foreach ($cloned->stamps as $class => $stamps) { - if ($class === $type || \is_subclass_of($class, $type)) { + if ($class === $type || is_subclass_of($class, $type)) { unset($cloned->stamps[$class]); } } diff --git a/src/Symfony/Component/Messenger/EventListener/SendFailedMessageToFailureTransportListener.php b/src/Symfony/Component/Messenger/EventListener/SendFailedMessageToFailureTransportListener.php index 431d9ca97f2b8..d9f607140cb84 100644 --- a/src/Symfony/Component/Messenger/EventListener/SendFailedMessageToFailureTransportListener.php +++ b/src/Symfony/Component/Messenger/EventListener/SendFailedMessageToFailureTransportListener.php @@ -61,7 +61,7 @@ public function onMessageFailed(WorkerMessageFailedEvent $event) $throwable = $throwable->getNestedExceptions()[0]; } - $flattenedException = \class_exists(FlattenException::class) ? FlattenException::createFromThrowable($throwable) : null; + $flattenedException = class_exists(FlattenException::class) ? FlattenException::createFromThrowable($throwable) : null; $envelope = $envelope->withoutAll(ReceivedStamp::class) ->withoutAll(TransportMessageIdStamp::class) ->with(new SentToFailureTransportStamp($event->getReceiverName())) diff --git a/src/Symfony/Component/Messenger/Middleware/StackMiddleware.php b/src/Symfony/Component/Messenger/Middleware/StackMiddleware.php index 864a8612a178b..4efad45cb9fe7 100644 --- a/src/Symfony/Component/Messenger/Middleware/StackMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/StackMiddleware.php @@ -38,7 +38,7 @@ public function __construct($middlewareIterator = null) $this->stack->iterator = $middlewareIterator; } elseif ($middlewareIterator instanceof MiddlewareInterface) { $this->stack->stack[] = $middlewareIterator; - } elseif (!\is_iterable($middlewareIterator)) { + } elseif (!is_iterable($middlewareIterator)) { throw new \TypeError(sprintf('Argument 1 passed to %s() must be iterable of %s, %s given.', __METHOD__, MiddlewareInterface::class, \is_object($middlewareIterator) ? \get_class($middlewareIterator) : \gettype($middlewareIterator))); } else { $this->stack->iterator = (function () use ($middlewareIterator) { diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php index 1196be9f081e3..9393e210b7b75 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php @@ -30,7 +30,7 @@ public function testGetAMessageWillChangeItsStatus() $stmt = $this->getStatementMock([ 'id' => 1, 'body' => '{"message":"Hi"}', - 'headers' => \json_encode(['type' => DummyMessage::class]), + 'headers' => json_encode(['type' => DummyMessage::class]), ]); $driverConnection diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineReceiverTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineReceiverTest.php index 3a250fddbc4ec..43a0ad9fe64e6 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineReceiverTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineReceiverTest.php @@ -80,7 +80,7 @@ public function testAll() $connection->method('findAll')->with(50)->willReturn([$doctrineEnvelope1, $doctrineEnvelope2]); $receiver = new DoctrineReceiver($connection, $serializer); - $actualEnvelopes = \iterator_to_array($receiver->all(50)); + $actualEnvelopes = iterator_to_array($receiver->all(50)); $this->assertCount(2, $actualEnvelopes); $this->assertEquals(new DummyMessage('Hi'), $actualEnvelopes[0]->getMessage()); } diff --git a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php index bd528b5b431b0..5b3a31c9ec61e 100644 --- a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php @@ -123,7 +123,7 @@ public function send(string $body, array $headers, int $delay = 0): string $this->executeQuery($queryBuilder->getSQL(), [ ':body' => $body, - ':headers' => \json_encode($headers), + ':headers' => json_encode($headers), ':queue_name' => $this->configuration['queue_name'], ':created_at' => self::formatDateTime($now), ':available_at' => self::formatDateTime($availableAt), @@ -155,7 +155,7 @@ public function get(): ?array return null; } - $doctrineEnvelope['headers'] = \json_decode($doctrineEnvelope['headers'], true); + $doctrineEnvelope['headers'] = json_decode($doctrineEnvelope['headers'], true); $queryBuilder = $this->driverConnection->createQueryBuilder() ->update($this->configuration['table_name']) diff --git a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php index 7688503264d55..18b6091e9c64f 100644 --- a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php @@ -124,7 +124,7 @@ public function get(): ?array } foreach ($messages[$this->stream] ?? [] as $key => $message) { - $redisEnvelope = \json_decode($message['message'], true); + $redisEnvelope = json_decode($message['message'], true); return [ 'id' => $key, diff --git a/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php b/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php index d75bf91a94a4f..5731cf445808f 100644 --- a/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php +++ b/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php @@ -110,7 +110,7 @@ private function extract(string $method, array $arguments) } // Calling rawurlencode escapes special characters not allowed in PSR-6's keys - $encodedMethod = \rawurlencode($method); + $encodedMethod = rawurlencode($method); if (\array_key_exists($encodedMethod, $this->arrayCache) && \array_key_exists($serializedArguments, $this->arrayCache[$encodedMethod])) { return $this->arrayCache[$encodedMethod][$serializedArguments]; } diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php index b30d136821539..ce16144639856 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php @@ -173,7 +173,7 @@ public function serialize() { $serialized = $this->__serialize(); - if (null === $isCalledFromOverridingMethod = \func_num_args() ? \func_get_arg(0) : null) { + if (null === $isCalledFromOverridingMethod = \func_num_args() ? func_get_arg(0) : null) { $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2); $isCalledFromOverridingMethod = isset($trace[1]['function'], $trace[1]['object']) && 'serialize' === $trace[1]['function'] && $this === $trace[1]['object']; } diff --git a/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php index e9bd6a63c94d2..7c6ae62f6359c 100644 --- a/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php @@ -48,7 +48,7 @@ public function __construct(int $opsLimit = null, int $memLimit = null) public static function isSupported(): bool { - if (\class_exists('ParagonIE_Sodium_Compat') && \method_exists('ParagonIE_Sodium_Compat', 'crypto_pwhash_is_available')) { + if (class_exists('ParagonIE_Sodium_Compat') && method_exists('ParagonIE_Sodium_Compat', 'crypto_pwhash_is_available')) { return \ParagonIE_Sodium_Compat::crypto_pwhash_is_available(); } @@ -65,7 +65,7 @@ public function encodePassword($raw, $salt) } if (\function_exists('sodium_crypto_pwhash_str')) { - return \sodium_crypto_pwhash_str($raw, $this->opsLimit, $this->memLimit); + return sodium_crypto_pwhash_str($raw, $this->opsLimit, $this->memLimit); } if (\extension_loaded('libsodium')) { @@ -90,7 +90,7 @@ public function isPasswordValid($encoded, $raw, $salt) } if (\function_exists('sodium_crypto_pwhash_str_verify')) { - return \sodium_crypto_pwhash_str_verify($encoded, $raw); + return sodium_crypto_pwhash_str_verify($encoded, $raw); } if (\extension_loaded('libsodium')) { diff --git a/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php b/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php index 0caa0563fd83b..9b1d8dbb29ec7 100644 --- a/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php +++ b/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php @@ -69,7 +69,7 @@ public function serialize() { $serialized = $this->__serialize(); - if (null === $isCalledFromOverridingMethod = \func_num_args() ? \func_get_arg(0) : null) { + if (null === $isCalledFromOverridingMethod = \func_num_args() ? func_get_arg(0) : null) { $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2); $isCalledFromOverridingMethod = isset($trace[1]['function'], $trace[1]['object']) && 'serialize' === $trace[1]['function'] && $this === $trace[1]['object']; } diff --git a/src/Symfony/Component/Translation/DependencyInjection/TranslatorPathsPass.php b/src/Symfony/Component/Translation/DependencyInjection/TranslatorPathsPass.php index d9fc71911fedb..8ff2587dd53e1 100644 --- a/src/Symfony/Component/Translation/DependencyInjection/TranslatorPathsPass.php +++ b/src/Symfony/Component/Translation/DependencyInjection/TranslatorPathsPass.php @@ -46,7 +46,7 @@ public function process(ContainerBuilder $container) } foreach ($this->findControllerArguments($container) as $controller => $argument) { - $id = \substr($controller, 0, \strpos($controller, ':') ?: \strlen($controller)); + $id = substr($controller, 0, strpos($controller, ':') ?: \strlen($controller)); if ($container->hasDefinition($id)) { list($locatorRef) = $argument->getValues(); $this->controllers[(string) $locatorRef][$container->getDefinition($id)->getClass()] = true; diff --git a/src/Symfony/Component/Translation/Extractor/PhpExtractor.php b/src/Symfony/Component/Translation/Extractor/PhpExtractor.php index 84fd7400f8da0..3e1a152533b59 100644 --- a/src/Symfony/Component/Translation/Extractor/PhpExtractor.php +++ b/src/Symfony/Component/Translation/Extractor/PhpExtractor.php @@ -204,7 +204,7 @@ protected function parseTokens($tokens, MessageCatalogue $catalog/*, string $fil if (\func_num_args() < 3 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) { @trigger_error(sprintf('The "%s()" method will have a new "string $filename" argument in version 5.0, not defining it is deprecated since Symfony 4.3.', __METHOD__), E_USER_DEPRECATED); } - $filename = 2 < \func_num_args() ? \func_get_arg(2) : ''; + $filename = 2 < \func_num_args() ? func_get_arg(2) : ''; $tokenIterator = new \ArrayIterator($tokens); diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index 6763198937916..8d1762913cf50 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -80,7 +80,7 @@ case '/post': $output = json_encode($_POST + ['REQUEST_METHOD' => $vars['REQUEST_METHOD']], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); header('Content-Type: application/json', true); - header('Content-Length: '.\strlen($output)); + header('Content-Length: '.strlen($output)); echo $output; exit; From a2960a3318743cc4ea85c868c9c9b6d4ce692a55 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 13 Jun 2019 13:53:55 +0200 Subject: [PATCH 040/106] [HttpClient] Don't use CurlHttpClient on Windows when curl.cainfo is not set --- src/Symfony/Component/HttpClient/HttpClient.php | 6 +++++- src/Symfony/Component/HttpClient/Response/CurlResponse.php | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpClient/HttpClient.php b/src/Symfony/Component/HttpClient/HttpClient.php index 25d3f6f87425c..f4da6ba6863c5 100644 --- a/src/Symfony/Component/HttpClient/HttpClient.php +++ b/src/Symfony/Component/HttpClient/HttpClient.php @@ -32,7 +32,11 @@ final class HttpClient public static function create(array $defaultOptions = [], int $maxHostConnections = 6, int $maxPendingPushes = 50): HttpClientInterface { if (\extension_loaded('curl')) { - return new CurlHttpClient($defaultOptions, $maxHostConnections, $maxPendingPushes); + if ('\\' !== \DIRECTORY_SEPARATOR || ini_get('curl.cainfo') || ini_get('openssl.cafile') || ini_get('openssl.capath')) { + return new CurlHttpClient($defaultOptions, $maxHostConnections, $maxPendingPushes); + } + + @trigger_error('Configure the "curl.cainfo", "openssl.cafile" or "openssl.capath" php.ini setting to enable the CurlHttpClient', E_USER_WARNING); } return new NativeHttpClient($defaultOptions, $maxHostConnections); diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 0c615bab04514..14d3f935e0fb7 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -336,7 +336,7 @@ private static function parseHeaderLine($ch, string $data, array &$info, array & return 0; } - if ($certinfo = curl_getinfo($ch, CURLINFO_CERTINFO)) { + if (\function_exists('openssl_x509_read') && $certinfo = curl_getinfo($ch, CURLINFO_CERTINFO)) { $info['peer_certificate_chain'] = array_map('openssl_x509_read', array_column($certinfo, 'Cert')); } From a9d0038ec0042b39a96c0141e0d8c78a6fa3f362 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 13 Jun 2019 14:31:28 +0200 Subject: [PATCH 041/106] [VarDumper] fix dumping objects that implement __debugInfo() --- .../Component/VarDumper/Caster/Caster.php | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Caster/Caster.php b/src/Symfony/Component/VarDumper/Caster/Caster.php index 93d0ce2b41b73..ae8b40fa0eacd 100644 --- a/src/Symfony/Component/VarDumper/Caster/Caster.php +++ b/src/Symfony/Component/VarDumper/Caster/Caster.php @@ -53,13 +53,9 @@ public static function castObject($obj, $class, $hasDebugInfo = false) $hasDebugInfo = $class->hasMethod('__debugInfo'); $class = $class->name; } - if ($hasDebugInfo) { - $a = $obj->__debugInfo(); - } elseif ($obj instanceof \Closure) { - $a = []; - } else { - $a = (array) $obj; - } + + $a = $obj instanceof \Closure ? [] : (array) $obj; + if ($obj instanceof \__PHP_Incomplete_Class) { return $a; } @@ -93,6 +89,17 @@ public static function castObject($obj, $class, $hasDebugInfo = false) } } + if ($hasDebugInfo && \is_array($debugInfo = $obj->__debugInfo())) { + foreach ($debugInfo as $k => $v) { + if (!isset($k[0]) || "\0" !== $k[0]) { + $k = self::PREFIX_VIRTUAL.$k; + } + + unset($a[$k]); + $a[$k] = $v; + } + } + return $a; } From 91f1680b3fc8347e84ec2df8dbbfd893eb47cc2e Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Thu, 13 Jun 2019 14:57:18 +0200 Subject: [PATCH 042/106] [Messenger] Remove DispatchAfterCurrentBusStamp when message is put on internal queue --- .../DispatchAfterCurrentBusMiddleware.php | 2 +- .../DispatchAfterCurrentBusMiddlewareTest.php | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Messenger/Middleware/DispatchAfterCurrentBusMiddleware.php b/src/Symfony/Component/Messenger/Middleware/DispatchAfterCurrentBusMiddleware.php index 4c098c79b7281..19c714d1b8cf7 100644 --- a/src/Symfony/Component/Messenger/Middleware/DispatchAfterCurrentBusMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/DispatchAfterCurrentBusMiddleware.php @@ -112,7 +112,7 @@ final class QueuedEnvelope public function __construct(Envelope $envelope, StackInterface $stack) { - $this->envelope = $envelope; + $this->envelope = $envelope->withoutAll(DispatchAfterCurrentBusStamp::class); $this->stack = $stack; } diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/DispatchAfterCurrentBusMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/DispatchAfterCurrentBusMiddlewareTest.php index f2217affda0c1..fe6d190c10258 100644 --- a/src/Symfony/Component/Messenger/Tests/Middleware/DispatchAfterCurrentBusMiddlewareTest.php +++ b/src/Symfony/Component/Messenger/Tests/Middleware/DispatchAfterCurrentBusMiddlewareTest.php @@ -99,6 +99,53 @@ public function testThrowingEventsHandlingWontStopExecution() $messageBus->dispatch($message); } + public function testHandleDelayedEventFromQueue() + { + $message = new DummyMessage('Hello'); + $event = new DummyEvent('Event on queue'); + + $middleware = new DispatchAfterCurrentBusMiddleware(); + $commandHandlingMiddleware = $this->createMock(MiddlewareInterface::class); + $eventHandlingMiddleware = $this->createMock(MiddlewareInterface::class); + + // This bus simulates the bus that are used when messages come back form the queue + $messageBusAfterQueue = new MessageBus([ + // Create a new middleware + new DispatchAfterCurrentBusMiddleware(), + $eventHandlingMiddleware, + ]); + + $fakePutMessageOnQueue = $this->createMock(MiddlewareInterface::class); + $fakePutMessageOnQueue->expects($this->any()) + ->method('handle') + ->with($this->callback(function ($envelope) use ($messageBusAfterQueue) { + // Fake putting the message on the queue + // Fake reading the queue + // Now, we add the message back to a new bus. + $messageBusAfterQueue->dispatch($envelope); + + return true; + })) + ->willReturnArgument(0); + + $eventBus = new MessageBus([ + $middleware, + $fakePutMessageOnQueue, + ]); + + $messageBus = new MessageBus([ + $middleware, + new DispatchingMiddleware($eventBus, [ + new Envelope($event, [new DispatchAfterCurrentBusStamp()]), + ]), + $commandHandlingMiddleware, + ]); + + $this->expectHandledMessage($commandHandlingMiddleware, 0, $message); + $this->expectHandledMessage($eventHandlingMiddleware, 0, $event); + $messageBus->dispatch($message); + } + /** * @param MiddlewareInterface|MockObject $handlingMiddleware */ From 648aa67eca9ab05586a68b7bd1c9842137526c9a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 13 Jun 2019 16:07:09 +0200 Subject: [PATCH 043/106] fix merge --- src/Symfony/Bridge/PhpUnit/ClassExistsMock.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/ClassExistsMock.php b/src/Symfony/Bridge/PhpUnit/ClassExistsMock.php index fbd0a4fa4d5a7..e8ca4ac9402a8 100644 --- a/src/Symfony/Bridge/PhpUnit/ClassExistsMock.php +++ b/src/Symfony/Bridge/PhpUnit/ClassExistsMock.php @@ -30,17 +30,17 @@ public static function withMockedClasses(array $classes) public static function class_exists($name, $autoload = true) { - return (bool) (self::$classes[ltrim($name, '\\')] ?? class_exists($name, $autoload)); + return (bool) (self::$classes[ltrim($name, '\\')] ?? \class_exists($name, $autoload)); } public static function interface_exists($name, $autoload = true) { - return (bool) (self::$classes[ltrim($name, '\\')] ?? interface_exists($name, $autoload)); + return (bool) (self::$classes[ltrim($name, '\\')] ?? \interface_exists($name, $autoload)); } public static function trait_exists($name, $autoload = true) { - return (bool) (self::$classes[ltrim($name, '\\')] ?? trait_exists($name, $autoload)); + return (bool) (self::$classes[ltrim($name, '\\')] ?? \trait_exists($name, $autoload)); } public static function register($class) From d445465ef459b83ce2b9b4342bbb38fc9b8c1d02 Mon Sep 17 00:00:00 2001 From: Stefano Degenkamp Date: Wed, 12 Jun 2019 11:28:52 +0200 Subject: [PATCH 044/106] Fix binary operation `+`, `-` or `*` on string By type casting to integer. --- .../Component/Form/Extension/Core/Type/BirthdayType.php | 2 +- src/Symfony/Component/Form/Extension/Core/Type/DateType.php | 2 +- src/Symfony/Component/HttpFoundation/Response.php | 4 ++-- .../Component/HttpKernel/HttpCache/ResponseCacheStrategy.php | 2 +- .../Intl/DateFormatter/DateFormat/DayOfYearTransformer.php | 2 +- .../Intl/DateFormatter/DateFormat/FullTransformer.php | 2 +- src/Symfony/Component/Validator/Constraints/IssnValidator.php | 2 +- src/Symfony/Component/Validator/Constraints/LuhnValidator.php | 2 +- src/Symfony/Component/VarDumper/Caster/DateCaster.php | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php b/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php index 841bd0d85f32f..acb8d02b8c5a9 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php @@ -21,7 +21,7 @@ class BirthdayType extends AbstractType */ public function configureOptions(OptionsResolver $resolver) { - $resolver->setDefault('years', range(date('Y') - 120, date('Y'))); + $resolver->setDefault('years', range((int) date('Y') - 120, date('Y'))); $resolver->setAllowedTypes('years', 'array'); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php index 09f5e1de5c872..8ab5e9cc8a57b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php @@ -256,7 +256,7 @@ public function configureOptions(OptionsResolver $resolver) }; $resolver->setDefaults([ - 'years' => range(date('Y') - 5, date('Y') + 5), + 'years' => range((int) date('Y') - 5, (int) date('Y') + 5), 'months' => range(1, 12), 'days' => range(1, 31), 'widget' => 'choice', diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index b7d116259d6f2..4ab05066f4745 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -707,7 +707,7 @@ public function getAge() return (int) $age; } - return max(time() - $this->getDate()->format('U'), 0); + return max(time() - (int) $this->getDate()->format('U'), 0); } /** @@ -788,7 +788,7 @@ public function getMaxAge() } if (null !== $this->getExpires()) { - return $this->getExpires()->format('U') - $this->getDate()->format('U'); + return (int) $this->getExpires()->format('U') - (int) $this->getDate()->format('U'); } } diff --git a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php index 7037c497cc9c6..25c071c335a02 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php @@ -85,7 +85,7 @@ public function add(Response $response) $this->storeRelativeAgeDirective('s-maxage', $response->headers->getCacheControlDirective('s-maxage') ?: $response->headers->getCacheControlDirective('max-age'), $age); $expires = $response->getExpires(); - $expires = null !== $expires ? $expires->format('U') - $response->getDate()->format('U') : null; + $expires = null !== $expires ? (int) $expires->format('U') - (int) $response->getDate()->format('U') : null; $this->storeRelativeAgeDirective('expires', $expires >= 0 ? $expires : null, 0); } diff --git a/src/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfYearTransformer.php b/src/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfYearTransformer.php index 8b48371f60c6f..1443cc79ecb11 100644 --- a/src/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfYearTransformer.php +++ b/src/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfYearTransformer.php @@ -25,7 +25,7 @@ class DayOfYearTransformer extends Transformer */ public function format(\DateTime $dateTime, $length) { - $dayOfYear = $dateTime->format('z') + 1; + $dayOfYear = (int) $dateTime->format('z') + 1; return $this->padLeft($dayOfYear, $length); } diff --git a/src/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php b/src/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php index 9c0d86ef05bdc..13854ff719ef8 100644 --- a/src/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php +++ b/src/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php @@ -315,7 +315,7 @@ protected function calculateUnixTimestamp(\DateTime $dateTime, array $options) preg_match_all($this->regExp, $this->pattern, $matches); if (\in_array('yy', $matches[0])) { $dateTime->setTimestamp(time()); - $year = $year > $dateTime->format('y') + 20 ? 1900 + $year : 2000 + $year; + $year = $year > (int) $dateTime->format('y') + 20 ? 1900 + $year : 2000 + $year; } $dateTime->setDate($year, $month, $day); diff --git a/src/Symfony/Component/Validator/Constraints/IssnValidator.php b/src/Symfony/Component/Validator/Constraints/IssnValidator.php index f045e62e2ca18..41da39ebd87bc 100644 --- a/src/Symfony/Component/Validator/Constraints/IssnValidator.php +++ b/src/Symfony/Component/Validator/Constraints/IssnValidator.php @@ -120,7 +120,7 @@ public function validate($value, Constraint $constraint) for ($i = 0; $i < 7; ++$i) { // Multiply the first digit by 8, the second by 7, etc. - $checkSum += (8 - $i) * $canonical[$i]; + $checkSum += (8 - $i) * (int) $canonical[$i]; } if (0 !== $checkSum % 11) { diff --git a/src/Symfony/Component/Validator/Constraints/LuhnValidator.php b/src/Symfony/Component/Validator/Constraints/LuhnValidator.php index 554fc6f48b10b..6e69f9ee74c23 100644 --- a/src/Symfony/Component/Validator/Constraints/LuhnValidator.php +++ b/src/Symfony/Component/Validator/Constraints/LuhnValidator.php @@ -83,7 +83,7 @@ public function validate($value, Constraint $constraint) // ^ ^ ^ ^ ^ // = 1+8 + 4 + 6 + 1+6 + 2 for ($i = $length - 2; $i >= 0; $i -= 2) { - $checkSum += array_sum(str_split($value[$i] * 2)); + $checkSum += array_sum(str_split((int) $value[$i] * 2)); } if (0 === $checkSum || 0 !== $checkSum % 10) { diff --git a/src/Symfony/Component/VarDumper/Caster/DateCaster.php b/src/Symfony/Component/VarDumper/Caster/DateCaster.php index 3b030b734ae1d..40289a930b7be 100644 --- a/src/Symfony/Component/VarDumper/Caster/DateCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/DateCaster.php @@ -95,7 +95,7 @@ public static function castPeriod(\DatePeriod $p, array $a, Stub $stub, $isNeste if (3 === $i) { $now = new \DateTimeImmutable(); $dates[] = sprintf('%s more', ($end = $p->getEndDate()) - ? ceil(($end->format('U.u') - $d->format('U.u')) / ($now->add($p->getDateInterval())->format('U.u') - $now->format('U.u'))) + ? ceil(($end->format('U.u') - $d->format('U.u')) / ((int) $now->add($p->getDateInterval())->format('U.u') - (int) $now->format('U.u'))) : $p->recurrences - $i ); break; From 7439c8de55cb883ac448249bf685ad55055f7335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Tue, 11 Jun 2019 22:09:13 +0200 Subject: [PATCH 045/106] Parameterize Mailgun's region --- .../Mailgun/Http/Api/MailgunTransport.php | 8 ++-- .../Bridge/Mailgun/Http/MailgunTransport.php | 8 ++-- .../Bridge/Mailgun/Smtp/MailgunTransport.php | 4 +- .../Component/Mailer/Tests/TransportTest.php | 45 +++++++++++++++++++ src/Symfony/Component/Mailer/Transport.php | 6 +-- src/Symfony/Component/Mailer/composer.json | 2 +- 6 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php index dc047c2e87291..9e61ee4dcd3c3 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php @@ -27,15 +27,17 @@ */ class MailgunTransport extends AbstractApiTransport { - private const ENDPOINT = 'https://api.mailgun.net/v3/%domain%/messages'; + private const ENDPOINT = 'https://api.%region_dot%mailgun.net/v3/%domain%/messages'; private $key; private $domain; + private $region; - public function __construct(string $key, string $domain, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) + public function __construct(string $key, string $domain, string $region = null, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) { $this->key = $key; $this->domain = $domain; + $this->region = $region; parent::__construct($client, $dispatcher, $logger); } @@ -48,7 +50,7 @@ protected function doSendEmail(Email $email, SmtpEnvelope $envelope): void $headers[] = $header->toString(); } - $endpoint = str_replace('%domain%', urlencode($this->domain), self::ENDPOINT); + $endpoint = str_replace(['%domain%', '%region_dot%'], [urlencode($this->domain), 'us' !== ($this->region ?: 'us') ? $this->region.'.' : ''], self::ENDPOINT); $response = $this->client->request('POST', $endpoint, [ 'auth_basic' => 'api:'.$this->key, 'headers' => $headers, diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/MailgunTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/MailgunTransport.php index 2d3fe15a08eb9..913ed705d9ab0 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/MailgunTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/MailgunTransport.php @@ -27,14 +27,16 @@ */ class MailgunTransport extends AbstractHttpTransport { - private const ENDPOINT = 'https://api.mailgun.net/v3/%domain%/messages.mime'; + private const ENDPOINT = 'https://api.%region_dot%mailgun.net/v3/%domain%/messages.mime'; private $key; private $domain; + private $region; - public function __construct(string $key, string $domain, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) + public function __construct(string $key, string $domain, string $region = null, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) { $this->key = $key; $this->domain = $domain; + $this->region = $region; parent::__construct($client, $dispatcher, $logger); } @@ -49,7 +51,7 @@ protected function doSend(SentMessage $message): void foreach ($body->getPreparedHeaders()->getAll() as $header) { $headers[] = $header->toString(); } - $endpoint = str_replace('%domain%', urlencode($this->domain), self::ENDPOINT); + $endpoint = str_replace(['%domain%', '%region_dot%'], [urlencode($this->domain), 'us' !== ($this->region ?: 'us') ? $this->region.'.' : ''], self::ENDPOINT); $response = $this->client->request('POST', $endpoint, [ 'auth_basic' => 'api:'.$this->key, 'headers' => $headers, diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Smtp/MailgunTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Smtp/MailgunTransport.php index 105ab46ecd98c..c288a46bdd73a 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Smtp/MailgunTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Smtp/MailgunTransport.php @@ -22,9 +22,9 @@ */ class MailgunTransport extends EsmtpTransport { - public function __construct(string $username, string $password, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) + public function __construct(string $username, string $password, string $region = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) { - parent::__construct('smtp.mailgun.org', 465, 'ssl', null, $dispatcher, $logger); + parent::__construct('us' !== ($region ?: 'us') ? sprintf('smtp.%s.mailgun.org', $region) : 'smtp.mailgun.org', 465, 'ssl', null, $dispatcher, $logger); $this->setUsername($username); $this->setPassword($password); diff --git a/src/Symfony/Component/Mailer/Tests/TransportTest.php b/src/Symfony/Component/Mailer/Tests/TransportTest.php index 0d1f14326256f..a12aae4830718 100644 --- a/src/Symfony/Component/Mailer/Tests/TransportTest.php +++ b/src/Symfony/Component/Mailer/Tests/TransportTest.php @@ -23,7 +23,9 @@ use Symfony\Component\Mailer\Exception\InvalidArgumentException; use Symfony\Component\Mailer\Exception\LogicException; use Symfony\Component\Mailer\Transport; +use Symfony\Component\Mime\Email; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; class TransportTest extends TestCase { @@ -106,6 +108,15 @@ public function testFromDsnMailgun() $this->assertEquals('pa$s', $transport->getPassword()); $this->assertProperties($transport, $dispatcher, $logger); + $transport = Transport::fromDsn('smtp://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun', $dispatcher, null, $logger); + $this->assertEquals('smtp.mailgun.org', $transport->getStream()->getHost()); + + $transport = Transport::fromDsn('smtp://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun?region=eu', $dispatcher, null, $logger); + $this->assertEquals('smtp.eu.mailgun.org', $transport->getStream()->getHost()); + + $transport = Transport::fromDsn('smtp://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun?region=us', $dispatcher, null, $logger); + $this->assertEquals('smtp.mailgun.org', $transport->getStream()->getHost()); + $client = $this->createMock(HttpClientInterface::class); $transport = Transport::fromDsn('http://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun', $dispatcher, $client, $logger); $this->assertInstanceOf(Mailgun\Http\MailgunTransport::class, $transport); @@ -115,6 +126,25 @@ public function testFromDsnMailgun() 'client' => $client, ]); + $response = $this->createMock(ResponseInterface::class); + $response->expects($this->any())->method('getStatusCode')->willReturn(200); + $message = (new Email())->from('me@me.com')->to('you@you.com')->subject('hello')->text('Hello you'); + + $client = $this->createMock(HttpClientInterface::class); + $client->expects($this->once())->method('request')->with('POST', 'https://api.mailgun.net/v3/pa%24s/messages.mime')->willReturn($response); + $transport = Transport::fromDsn('http://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun', $dispatcher, $client, $logger); + $transport->send($message); + + $client = $this->createMock(HttpClientInterface::class); + $client->expects($this->once())->method('request')->with('POST', 'https://api.eu.mailgun.net/v3/pa%24s/messages.mime')->willReturn($response); + $transport = Transport::fromDsn('http://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun?region=eu', $dispatcher, $client, $logger); + $transport->send($message); + + $client = $this->createMock(HttpClientInterface::class); + $client->expects($this->once())->method('request')->with('POST', 'https://api.mailgun.net/v3/pa%24s/messages.mime')->willReturn($response); + $transport = Transport::fromDsn('http://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun?region=us', $dispatcher, $client, $logger); + $transport->send($message); + $transport = Transport::fromDsn('api://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun', $dispatcher, $client, $logger); $this->assertInstanceOf(Mailgun\Http\Api\MailgunTransport::class, $transport); $this->assertProperties($transport, $dispatcher, $logger, [ @@ -123,6 +153,21 @@ public function testFromDsnMailgun() 'client' => $client, ]); + $client = $this->createMock(HttpClientInterface::class); + $client->expects($this->once())->method('request')->with('POST', 'https://api.mailgun.net/v3/pa%24s/messages')->willReturn($response); + $transport = Transport::fromDsn('api://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun', $dispatcher, $client, $logger); + $transport->send($message); + + $client = $this->createMock(HttpClientInterface::class); + $client->expects($this->once())->method('request')->with('POST', 'https://api.eu.mailgun.net/v3/pa%24s/messages')->willReturn($response); + $transport = Transport::fromDsn('api://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun?region=eu', $dispatcher, $client, $logger); + $transport->send($message); + + $client = $this->createMock(HttpClientInterface::class); + $client->expects($this->once())->method('request')->with('POST', 'https://api.mailgun.net/v3/pa%24s/messages')->willReturn($response); + $transport = Transport::fromDsn('api://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun?region=us', $dispatcher, $client, $logger); + $transport->send($message); + $this->expectException(LogicException::class); Transport::fromDsn('foo://mailgun'); } diff --git a/src/Symfony/Component/Mailer/Transport.php b/src/Symfony/Component/Mailer/Transport.php index 326452ede9de8..ad5ea86462e33 100644 --- a/src/Symfony/Component/Mailer/Transport.php +++ b/src/Symfony/Component/Mailer/Transport.php @@ -101,13 +101,13 @@ private static function createTransport(string $dsn, EventDispatcherInterface $d } if ('smtp' === $parsedDsn['scheme']) { - return new Mailgun\Smtp\MailgunTransport($user, $pass, $dispatcher, $logger); + return new Mailgun\Smtp\MailgunTransport($user, $pass, $query['region'] ?? null, $dispatcher, $logger); } if ('http' === $parsedDsn['scheme']) { - return new Mailgun\Http\MailgunTransport($user, $pass, $client, $dispatcher, $logger); + return new Mailgun\Http\MailgunTransport($user, $pass, $query['region'] ?? null, $client, $dispatcher, $logger); } if ('api' === $parsedDsn['scheme']) { - return new Mailgun\Http\Api\MailgunTransport($user, $pass, $client, $dispatcher, $logger); + return new Mailgun\Http\Api\MailgunTransport($user, $pass, $query['region'] ?? null, $client, $dispatcher, $logger); } throw new LogicException(sprintf('The "%s" scheme is not supported for mailer "%s".', $parsedDsn['scheme'], $parsedDsn['host'])); diff --git a/src/Symfony/Component/Mailer/composer.json b/src/Symfony/Component/Mailer/composer.json index b9852124f19c2..91bfb1031d937 100644 --- a/src/Symfony/Component/Mailer/composer.json +++ b/src/Symfony/Component/Mailer/composer.json @@ -26,7 +26,7 @@ "symfony/amazon-mailer": "^4.3", "symfony/google-mailer": "^4.3", "symfony/http-client-contracts": "^1.1", - "symfony/mailgun-mailer": "^4.3", + "symfony/mailgun-mailer": "^4.3.2", "symfony/mailchimp-mailer": "^4.3", "symfony/postmark-mailer": "^4.3", "symfony/sendgrid-mailer": "^4.3" From 0f15306d615d3215366fc43713b3c1822e464cd3 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Fri, 14 Jun 2019 02:13:58 +0200 Subject: [PATCH 046/106] [Messenger] fix delay delivery for non-fanout exchanges also fix dsn parsing of plain amqp:// uri --- .../Transport/AmqpExt/ConnectionTest.php | 38 ++++++++----- .../Transport/AmqpExt/Connection.php | 53 ++++++++++--------- 2 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/ConnectionTest.php b/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/ConnectionTest.php index 549ff1f8ec457..9462529b94318 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/ConnectionTest.php @@ -25,14 +25,14 @@ class ConnectionTest extends TestCase { /** * @expectedException \InvalidArgumentException - * @expectedExceptionMessage The given AMQP DSN "amqp://" is invalid. + * @expectedExceptionMessage The given AMQP DSN "amqp://:" is invalid. */ public function testItCannotBeConstructedWithAWrongDsn() { - Connection::fromDsn('amqp://'); + Connection::fromDsn('amqp://:'); } - public function testItGetsParametersFromTheDsn() + public function testItCanBeConstructedWithDefaults() { $this->assertEquals( new Connection([ @@ -44,7 +44,23 @@ public function testItGetsParametersFromTheDsn() ], [ 'messages' => [], ]), - Connection::fromDsn('amqp://localhost/%2f/messages') + Connection::fromDsn('amqp://') + ); + } + + public function testItGetsParametersFromTheDsn() + { + $this->assertEquals( + new Connection([ + 'host' => 'host', + 'port' => 5672, + 'vhost' => '/', + ], [ + 'name' => 'custom', + ], [ + 'custom' => [], + ]), + Connection::fromDsn('amqp://host/%2f/custom') ); } @@ -52,9 +68,9 @@ public function testOverrideOptionsViaQueryParameters() { $this->assertEquals( new Connection([ - 'host' => 'redis', + 'host' => 'localhost', 'port' => 1234, - 'vhost' => '/', + 'vhost' => 'vhost', 'login' => 'guest', 'password' => 'password', ], [ @@ -62,7 +78,7 @@ public function testOverrideOptionsViaQueryParameters() ], [ 'queueName' => [], ]), - Connection::fromDsn('amqp://guest:password@redis:1234/%2f/queue?exchange[name]=exchangeName&queues[queueName]') + Connection::fromDsn('amqp://guest:password@localhost:1234/vhost/queue?exchange[name]=exchangeName&queues[queueName]') ); } @@ -70,18 +86,16 @@ public function testOptionsAreTakenIntoAccountAndOverwrittenByDsn() { $this->assertEquals( new Connection([ - 'host' => 'redis', - 'port' => 1234, + 'host' => 'localhost', + 'port' => 5672, 'vhost' => '/', - 'login' => 'guest', - 'password' => 'password', 'persistent' => 'true', ], [ 'name' => 'exchangeName', ], [ 'queueName' => [], ]), - Connection::fromDsn('amqp://guest:password@redis:1234/%2f/queue?exchange[name]=exchangeName&queues[queueName]', [ + Connection::fromDsn('amqp://localhost/%2f/queue?exchange[name]=exchangeName&queues[queueName]', [ 'persistent' => 'true', 'exchange' => ['name' => 'toBeOverwritten'], ]) diff --git a/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php b/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php index 721949c06953e..e35cbaa1e396b 100644 --- a/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php @@ -58,8 +58,22 @@ class Connection */ private $amqpDelayExchange; + public function __construct(array $connectionOptions, array $exchangeOptions, array $queuesOptions, AmqpFactory $amqpFactory = null) + { + $this->connectionOptions = array_replace_recursive([ + 'delay' => [ + 'routing_key_pattern' => 'delay_%routing_key%_%delay%', + 'exchange_name' => 'delay', + 'queue_name_pattern' => 'delay_queue_%routing_key%_%delay%', + ], + ], $connectionOptions); + $this->exchangeOptions = $exchangeOptions; + $this->queuesOptions = $queuesOptions; + $this->amqpFactory = $amqpFactory ?: new AmqpFactory(); + } + /** - * Constructor. + * Creates a connection based on the DSN and options. * * Available options: * @@ -81,29 +95,19 @@ class Connection * * delay: * * routing_key_pattern: The pattern of the routing key (Default: "delay_%routing_key%_%delay%") * * queue_name_pattern: Pattern to use to create the queues (Default: "delay_queue_%routing_key%_%delay%") - * * exchange_name: Name of the exchange to be used for the retried messages (Default: "retry") + * * exchange_name: Name of the exchange to be used for the retried messages (Default: "delay") * * auto_setup: Enable or not the auto-setup of queues and exchanges (Default: true) - * * loop_sleep: Amount of micro-seconds to wait if no message are available (Default: 200000) * * prefetch_count: set channel prefetch count */ - public function __construct(array $connectionOptions, array $exchangeOptions, array $queuesOptions, AmqpFactory $amqpFactory = null) - { - $this->connectionOptions = array_replace_recursive([ - 'delay' => [ - 'routing_key_pattern' => 'delay_%routing_key%_%delay%', - 'exchange_name' => 'delay', - 'queue_name_pattern' => 'delay_queue_%routing_key%_%delay%', - ], - ], $connectionOptions); - $this->exchangeOptions = $exchangeOptions; - $this->queuesOptions = $queuesOptions; - $this->amqpFactory = $amqpFactory ?: new AmqpFactory(); - } - public static function fromDsn(string $dsn, array $options = [], AmqpFactory $amqpFactory = null): self { if (false === $parsedUrl = parse_url($dsn)) { - throw new InvalidArgumentException(sprintf('The given AMQP DSN "%s" is invalid.', $dsn)); + // this is a valid URI that parse_url cannot handle when you want to pass all parameters as options + if ('amqp://' !== $dsn) { + throw new InvalidArgumentException(sprintf('The given AMQP DSN "%s" is invalid.', $dsn)); + } + + $parsedUrl = []; } $pathParts = isset($parsedUrl['path']) ? explode('/', trim($parsedUrl['path'], '/')) : []; @@ -275,18 +279,17 @@ private function createDelayQueue(int $delay, ?string $routingKey) $queue = $this->amqpFactory->createQueue($this->channel()); $queue->setName(str_replace( ['%delay%', '%routing_key%'], - [$delay, $routingKey ?: ''], + [$delay, $routingKey ?? ''], $this->connectionOptions['delay']['queue_name_pattern'] - )); + )); $queue->setArguments([ 'x-message-ttl' => $delay, 'x-dead-letter-exchange' => $this->exchange()->getName(), ]); - if (null !== $routingKey) { - // after being released from to DLX, this routing key will be used - $queue->setArgument('x-dead-letter-routing-key', $routingKey); - } + // after being released from to DLX, make sure the original routing key will be used + // we must use an empty string instead of null for the argument to be picked up + $queue->setArgument('x-dead-letter-routing-key', $routingKey ?? ''); return $queue; } @@ -295,7 +298,7 @@ private function getRoutingKeyForDelay(int $delay, ?string $finalRoutingKey): st { return str_replace( ['%delay%', '%routing_key%'], - [$delay, $finalRoutingKey ?: ''], + [$delay, $finalRoutingKey ?? ''], $this->connectionOptions['delay']['routing_key_pattern'] ); } From 2ac7027b71a65ba349dce1ebc3cd23e9fb060ed5 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Fri, 14 Jun 2019 05:20:19 +0200 Subject: [PATCH 047/106] [Messenger] improve logs --- .../Middleware/HandleMessageMiddleware.php | 4 +- .../Middleware/SendMessageMiddleware.php | 47 ++++++++----------- .../Retry/MultiplierRetryStrategy.php | 12 +---- .../Messenger/Stamp/RedeliveryStamp.php | 9 ++++ src/Symfony/Component/Messenger/Worker.php | 18 +++---- 5 files changed, 39 insertions(+), 51 deletions(-) diff --git a/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php b/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php index f018d5b6a1280..e9d0e897d25d8 100644 --- a/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/HandleMessageMiddleware.php @@ -64,7 +64,7 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope $handler = $handlerDescriptor->getHandler(); $handledStamp = HandledStamp::fromDescriptor($handlerDescriptor, $handler($message)); $envelope = $envelope->with($handledStamp); - $this->logger->info('Message "{class}" handled by "{handler}"', $context + ['handler' => $handledStamp->getHandlerName()]); + $this->logger->info('Message {class} handled by {handler}', $context + ['handler' => $handledStamp->getHandlerName()]); } catch (\Throwable $e) { $exceptions[] = $e; } @@ -75,7 +75,7 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope throw new NoHandlerForMessageException(sprintf('No handler for message "%s".', $context['class'])); } - $this->logger->info('No handler for message "{class}"', $context); + $this->logger->info('No handler for message {class}', $context); } if (\count($exceptions)) { diff --git a/src/Symfony/Component/Messenger/Middleware/SendMessageMiddleware.php b/src/Symfony/Component/Messenger/Middleware/SendMessageMiddleware.php index 2d401bc850a22..969a120cbfcdc 100644 --- a/src/Symfony/Component/Messenger/Middleware/SendMessageMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/SendMessageMiddleware.php @@ -54,37 +54,30 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope $sender = null; - try { - if ($envelope->all(ReceivedStamp::class)) { - // it's a received message, do not send it back - $this->logger->info('Received message "{class}"', $context); - } else { - /** @var RedeliveryStamp|null $redeliveryStamp */ - $redeliveryStamp = $envelope->last(RedeliveryStamp::class); - - // dispatch event unless this is a redelivery - $shouldDispatchEvent = null === $redeliveryStamp; - foreach ($this->getSenders($envelope, $redeliveryStamp) as $alias => $sender) { - if (null !== $this->eventDispatcher && $shouldDispatchEvent) { - $event = new SendMessageToTransportsEvent($envelope); - $this->eventDispatcher->dispatch($event); - $envelope = $event->getEnvelope(); - $shouldDispatchEvent = false; - } - - $this->logger->info('Sending message "{class}" with "{sender}"', $context + ['sender' => \get_class($sender)]); - $envelope = $sender->send($envelope->with(new SentStamp(\get_class($sender), \is_string($alias) ? $alias : null))); + if ($envelope->all(ReceivedStamp::class)) { + // it's a received message, do not send it back + $this->logger->info('Received message {class}', $context); + } else { + /** @var RedeliveryStamp|null $redeliveryStamp */ + $redeliveryStamp = $envelope->last(RedeliveryStamp::class); + + // dispatch event unless this is a redelivery + $shouldDispatchEvent = null === $redeliveryStamp; + foreach ($this->getSenders($envelope, $redeliveryStamp) as $alias => $sender) { + if (null !== $this->eventDispatcher && $shouldDispatchEvent) { + $event = new SendMessageToTransportsEvent($envelope); + $this->eventDispatcher->dispatch($event); + $envelope = $event->getEnvelope(); + $shouldDispatchEvent = false; } - } - if (null === $sender) { - return $stack->next()->handle($envelope, $stack); + $this->logger->info('Sending message {class} with {sender}', $context + ['sender' => \get_class($sender)]); + $envelope = $sender->send($envelope->with(new SentStamp(\get_class($sender), \is_string($alias) ? $alias : null))); } - } catch (\Throwable $e) { - $context['exception'] = $e; - $this->logger->warning('An exception occurred while handling message "{class}": '.$e->getMessage(), $context); + } - throw $e; + if (null === $sender) { + return $stack->next()->handle($envelope, $stack); } // message should only be sent and not be handled by the next middleware diff --git a/src/Symfony/Component/Messenger/Retry/MultiplierRetryStrategy.php b/src/Symfony/Component/Messenger/Retry/MultiplierRetryStrategy.php index e883b3ffd9ac5..8a44f5fa84935 100644 --- a/src/Symfony/Component/Messenger/Retry/MultiplierRetryStrategy.php +++ b/src/Symfony/Component/Messenger/Retry/MultiplierRetryStrategy.php @@ -70,14 +70,14 @@ public function isRetryable(Envelope $message): bool return true; } - $retries = $this->getCurrentRetryCount($message); + $retries = RedeliveryStamp::getRetryCountFromEnvelope($message); return $retries < $this->maxRetries; } public function getWaitingTime(Envelope $message): int { - $retries = $this->getCurrentRetryCount($message); + $retries = RedeliveryStamp::getRetryCountFromEnvelope($message); $delay = $this->delayMilliseconds * pow($this->multiplier, $retries); @@ -87,12 +87,4 @@ public function getWaitingTime(Envelope $message): int return $delay; } - - private function getCurrentRetryCount(Envelope $message): int - { - /** @var RedeliveryStamp|null $retryMessageStamp */ - $retryMessageStamp = $message->last(RedeliveryStamp::class); - - return $retryMessageStamp ? $retryMessageStamp->getRetryCount() : 0; - } } diff --git a/src/Symfony/Component/Messenger/Stamp/RedeliveryStamp.php b/src/Symfony/Component/Messenger/Stamp/RedeliveryStamp.php index 265ee1a628f48..2895ad9b8325a 100644 --- a/src/Symfony/Component/Messenger/Stamp/RedeliveryStamp.php +++ b/src/Symfony/Component/Messenger/Stamp/RedeliveryStamp.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Messenger\Stamp; use Symfony\Component\Debug\Exception\FlattenException; +use Symfony\Component\Messenger\Envelope; /** * Stamp applied when a messages needs to be redelivered. @@ -38,6 +39,14 @@ public function __construct(int $retryCount, string $senderClassOrAlias, string $this->redeliveredAt = new \DateTimeImmutable(); } + public static function getRetryCountFromEnvelope(Envelope $envelope): int + { + /** @var self|null $retryMessageStamp */ + $retryMessageStamp = $envelope->last(self::class); + + return $retryMessageStamp ? $retryMessageStamp->getRetryCount() : 0; + } + public function getRetryCount(): int { return $this->retryCount; diff --git a/src/Symfony/Component/Messenger/Worker.php b/src/Symfony/Component/Messenger/Worker.php index 4d52eb63ba772..b54382bd713dc 100644 --- a/src/Symfony/Component/Messenger/Worker.php +++ b/src/Symfony/Component/Messenger/Worker.php @@ -140,14 +140,16 @@ private function handleMessage(Envelope $envelope, ReceiverInterface $receiver, $this->dispatchEvent(new WorkerMessageFailedEvent($envelope, $transportName, $throwable, $shouldRetry)); + $retryCount = RedeliveryStamp::getRetryCountFromEnvelope($envelope); if ($shouldRetry) { - $retryCount = $this->getRetryCount($envelope) + 1; + ++$retryCount; + $delay = $retryStrategy->getWaitingTime($envelope); if (null !== $this->logger) { - $this->logger->error('Retrying {class} - retry #{retryCount}.', $context + ['retryCount' => $retryCount, 'error' => $throwable]); + $this->logger->error('Error thrown while handling message {class}. Dispatching for retry #{retryCount} using {delay} ms delay. Error: "{error}"', $context + ['retryCount' => $retryCount, 'delay' => $delay, 'error' => $throwable->getMessage(), 'exception' => $throwable]); } // add the delay and retry stamp info + remove ReceivedStamp - $retryEnvelope = $envelope->with(new DelayStamp($retryStrategy->getWaitingTime($envelope))) + $retryEnvelope = $envelope->with(new DelayStamp($delay)) ->with(new RedeliveryStamp($retryCount, $this->getSenderClassOrAlias($envelope))) ->withoutAll(ReceivedStamp::class); @@ -157,7 +159,7 @@ private function handleMessage(Envelope $envelope, ReceiverInterface $receiver, $receiver->ack($envelope); } else { if (null !== $this->logger) { - $this->logger->critical('Rejecting {class} (removing from transport).', $context + ['error' => $throwable]); + $this->logger->critical('Error thrown while handling message {class}. Removing from transport after {retryCount} retries. Error: "{error}"', $context + ['retryCount' => $retryCount, 'error' => $throwable->getMessage(), 'exception' => $throwable]); } $receiver->reject($envelope); @@ -207,14 +209,6 @@ private function shouldRetry(\Throwable $e, Envelope $envelope, RetryStrategyInt return $retryStrategy->isRetryable($envelope); } - private function getRetryCount(Envelope $envelope): int - { - /** @var RedeliveryStamp|null $retryMessageStamp */ - $retryMessageStamp = $envelope->last(RedeliveryStamp::class); - - return $retryMessageStamp ? $retryMessageStamp->getRetryCount() : 0; - } - private function getSenderClassOrAlias(Envelope $envelope): string { /** @var SentStamp|null $sentStamp */ From 89cba00c6890bc85a5f35a57bd3a4db3e7250b00 Mon Sep 17 00:00:00 2001 From: battye Date: Thu, 13 Jun 2019 08:42:28 +0000 Subject: [PATCH 048/106] [Serializer] Handle true and false appropriately in CSV encoder --- .../Serializer/Encoder/CsvEncoder.php | 3 ++- .../Tests/Encoder/CsvEncoderTest.php | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php b/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php index 1e47d35f17c7f..2552e300941ce 100644 --- a/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php @@ -189,7 +189,8 @@ private function flatten(array $array, array &$result, $keySeparator, $parentKey if (\is_array($value)) { $this->flatten($value, $result, $keySeparator, $parentKey.$key.$keySeparator); } else { - $result[$parentKey.$key] = $value; + // Ensures an actual value is used when dealing with true and false + $result[$parentKey.$key] = false === $value ? 0 : (true === $value ? 1 : $value); } } } diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php index 1eb673e8e21ba..7b5131cb533a6 100644 --- a/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php @@ -29,6 +29,24 @@ protected function setUp() $this->encoder = new CsvEncoder(); } + public function testTrueFalseValues() + { + $data = [ + 'string' => 'foo', + 'int' => 2, + 'false' => false, + 'true' => true, + ]; + + // Check that true and false are appropriately handled + $this->assertEquals(<<<'CSV' +string,int,false,true +foo,2,0,1 + +CSV + , $this->encoder->encode($data, 'csv')); + } + public function testSupportEncoding() { $this->assertTrue($this->encoder->supportsEncoding('csv')); From 94ded00216ef36bf61f2bb12fb3f6788fc38c577 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 14 Jun 2019 09:11:59 +0200 Subject: [PATCH 049/106] validate composite constraints in all groups --- .../Validator/Constraints/FormValidator.php | 5 +- .../Constraints/FormValidatorTest.php | 58 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php index 14adf123ec414..9e167c82155c9 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -13,6 +13,7 @@ use Symfony\Component\Form\FormInterface; use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\Composite; use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\ConstraintValidator; @@ -90,7 +91,9 @@ public function validate($form, Constraint $formConstraint) $validator->atPath('data')->validate($form->getData(), $constraint, $group); // Prevent duplicate validation - continue 2; + if (!$constraint instanceof Composite) { + continue 2; + } } } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php index 4ab56f555a90e..8a8af9ed6809a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php @@ -24,6 +24,7 @@ use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\SubmitButtonBuilder; use Symfony\Component\Translation\IdentityTranslator; +use Symfony\Component\Validator\Constraints\Collection; use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotNull; @@ -673,6 +674,63 @@ public function testCauseForNotAllowedExtraFieldsIsTheFormConstraint() $this->assertSame($constraint, $context->getViolations()->get(0)->getConstraint()); } + public function testNonCompositeConstraintValidatedOnce() + { + $form = $this + ->getBuilder('form', null, [ + 'constraints' => [new NotBlank(['groups' => ['foo', 'bar']])], + 'validation_groups' => ['foo', 'bar'], + ]) + ->setCompound(false) + ->getForm(); + $form->submit(''); + + $context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator()); + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + + $this->assertCount(1, $context->getViolations()); + $this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage()); + $this->assertSame('data', $context->getViolations()[0]->getPropertyPath()); + } + + public function testCompositeConstraintValidatedInEachGroup() + { + $form = $this->getBuilder('form', null, [ + 'constraints' => [ + new Collection([ + 'field1' => new NotBlank([ + 'groups' => ['field1'], + ]), + 'field2' => new NotBlank([ + 'groups' => ['field2'], + ]), + ]), + ], + 'validation_groups' => ['field1', 'field2'], + ]) + ->setData([]) + ->setCompound(true) + ->setDataMapper(new PropertyPathMapper()) + ->getForm(); + $form->add($this->getForm('field1')); + $form->add($this->getForm('field2')); + $form->submit([ + 'field1' => '', + 'field2' => '', + ]); + + $context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator()); + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + + $this->assertCount(2, $context->getViolations()); + $this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage()); + $this->assertSame('data[field1]', $context->getViolations()[0]->getPropertyPath()); + $this->assertSame('This value should not be blank.', $context->getViolations()[1]->getMessage()); + $this->assertSame('data[field2]', $context->getViolations()[1]->getPropertyPath()); + } + protected function createValidator() { return new FormValidator(); From ffd3469ddfb96aa25deb3a0f22f83e26e5d0f040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Thu, 13 Jun 2019 15:23:10 +0200 Subject: [PATCH 050/106] SimpleCacheAdapter fails to cache any item if a namespace is used --- .../Cache/Adapter/AbstractAdapter.php | 2 +- .../Cache/Adapter/SimpleCacheAdapter.php | 8 ++++++++ .../Tests/Adapter/SimpleCacheAdapterTest.php | 11 +++++++++++ .../Component/Cache/Traits/AbstractTrait.php | 18 +++++++++++++----- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index 099c97a4da9d4..70af0c7314cac 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -39,7 +39,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface */ protected function __construct($namespace = '', $defaultLifetime = 0) { - $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':'; + $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::getNsSeparator(); if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, \strlen($namespace), $namespace)); } diff --git a/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php b/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php index bdb62a4bb3809..de4dd745cd119 100644 --- a/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php @@ -75,4 +75,12 @@ protected function doSave(array $values, $lifetime) { return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime); } + + /** + * @return string the namespace separator for cache keys + */ + protected static function getNsSeparator() + { + return '_'; + } } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php index 84713416cdea5..d8470a2e7d5a6 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Cache\Tests\Adapter; use Symfony\Component\Cache\Adapter\SimpleCacheAdapter; +use Symfony\Component\Cache\Simple\ArrayCache; use Symfony\Component\Cache\Simple\FilesystemCache; /** @@ -27,4 +28,14 @@ public function createCachePool($defaultLifetime = 0) { return new SimpleCacheAdapter(new FilesystemCache(), '', $defaultLifetime); } + + public function testValidCacheKeyWithNamespace() + { + $cache = new SimpleCacheAdapter(new ArrayCache(), 'some_namespace', 0); + $item = $cache->getItem('my_key'); + $item->set('someValue'); + $cache->save($item); + + $this->assertTrue($cache->getItem('my_key')->isHit(), 'Stored item is successfully retrieved.'); + } } diff --git a/src/Symfony/Component/Cache/Traits/AbstractTrait.php b/src/Symfony/Component/Cache/Traits/AbstractTrait.php index be576098e45eb..83a86a5ee9e2e 100644 --- a/src/Symfony/Component/Cache/Traits/AbstractTrait.php +++ b/src/Symfony/Component/Cache/Traits/AbstractTrait.php @@ -106,7 +106,7 @@ public function clear() { $this->deferred = []; if ($cleared = $this->versioningIsEnabled) { - $namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), ':', 5); + $namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), static::getNsSeparator(), 5); try { $cleared = $this->doSave(['@'.$this->namespace => $namespaceVersion], 0); } catch (\Exception $e) { @@ -235,13 +235,13 @@ private function getId($key) CacheItem::validateKey($key); if ($this->versioningIsEnabled && '' === $this->namespaceVersion) { - $this->namespaceVersion = '1:'; + $this->namespaceVersion = '1'.static::getNsSeparator(); try { foreach ($this->doFetch(['@'.$this->namespace]) as $v) { $this->namespaceVersion = $v; } - if ('1:' === $this->namespaceVersion) { - $this->namespaceVersion = substr_replace(base64_encode(pack('V', time())), ':', 5); + if ('1'.static::getNsSeparator() === $this->namespaceVersion) { + $this->namespaceVersion = substr_replace(base64_encode(pack('V', time())), static::getNsSeparator(), 5); $this->doSave(['@'.$this->namespace => $this->namespaceVersion], 0); } } catch (\Exception $e) { @@ -252,7 +252,7 @@ private function getId($key) return $this->namespace.$this->namespaceVersion.$key; } if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) { - $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -(\strlen($this->namespaceVersion) + 22)); + $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), static::getNsSeparator(), -(\strlen($this->namespaceVersion) + 22)); } return $id; @@ -265,4 +265,12 @@ public static function handleUnserializeCallback($class) { throw new \DomainException('Class not found: '.$class); } + + /** + * @return string the namespace separator for cache keys + */ + protected static function getNsSeparator() + { + return ':'; + } } From 0034dee6412313d14938e04bb668742054ecd557 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Fri, 14 Jun 2019 22:19:29 +0200 Subject: [PATCH 051/106] [Messenger] make retry logic work without SentStamp --- .../Messenger/Tests/RetryIntegrationTest.php | 8 +++--- .../Component/Messenger/Tests/WorkerTest.php | 12 ++++----- src/Symfony/Component/Messenger/Worker.php | 26 +------------------ 3 files changed, 11 insertions(+), 35 deletions(-) diff --git a/src/Symfony/Component/Messenger/Tests/RetryIntegrationTest.php b/src/Symfony/Component/Messenger/Tests/RetryIntegrationTest.php index 64ff20bae3d3e..2447a0c82b2a1 100644 --- a/src/Symfony/Component/Messenger/Tests/RetryIntegrationTest.php +++ b/src/Symfony/Component/Messenger/Tests/RetryIntegrationTest.php @@ -34,9 +34,9 @@ public function testRetryMechanism() $senderAndReceiver = new DummySenderAndReceiver(); $senderLocator = $this->createMock(ContainerInterface::class); - $senderLocator->method('has')->with('sender_alias')->willReturn(true); - $senderLocator->method('get')->with('sender_alias')->willReturn($senderAndReceiver); - $senderLocator = new SendersLocator([DummyMessage::class => ['sender_alias']], $senderLocator); + $senderLocator->method('has')->with('transportName')->willReturn(true); + $senderLocator->method('get')->with('transportName')->willReturn($senderAndReceiver); + $senderLocator = new SendersLocator([DummyMessage::class => ['transportName']], $senderLocator); $handler = new DummyMessageHandlerFailingFirstTimes(0); $throwingHandler = new DummyMessageHandlerFailingFirstTimes(1); @@ -52,7 +52,7 @@ public function testRetryMechanism() $envelope = new Envelope(new DummyMessage('API')); $bus->dispatch($envelope); - $worker = new Worker(['receiverName' => $senderAndReceiver], $bus, ['receiverName' => new MultiplierRetryStrategy()]); + $worker = new Worker(['transportName' => $senderAndReceiver], $bus, ['transportName' => new MultiplierRetryStrategy()]); $worker->run([], function (?Envelope $envelope) use ($worker) { if (null === $envelope) { $worker->stop(); diff --git a/src/Symfony/Component/Messenger/Tests/WorkerTest.php b/src/Symfony/Component/Messenger/Tests/WorkerTest.php index 46e8149f6c327..c82652fe1d29f 100644 --- a/src/Symfony/Component/Messenger/Tests/WorkerTest.php +++ b/src/Symfony/Component/Messenger/Tests/WorkerTest.php @@ -84,7 +84,7 @@ public function testWorkerDoesNotWrapMessagesAlreadyWrappedWithReceivedMessage() public function testDispatchCausesRetry() { $receiver = new DummyReceiver([ - [new Envelope(new DummyMessage('Hello'), [new SentStamp('Some\Sender', 'sender_alias')])], + [new Envelope(new DummyMessage('Hello'), [new SentStamp('Some\Sender', 'transport1')])], ]); $bus = $this->getMockBuilder(MessageBusInterface::class)->getMock(); @@ -97,7 +97,7 @@ public function testDispatchCausesRetry() $this->assertNotNull($redeliveryStamp); // retry count now at 1 $this->assertSame(1, $redeliveryStamp->getRetryCount()); - $this->assertSame('sender_alias', $redeliveryStamp->getSenderClassOrAlias()); + $this->assertSame('transport1', $redeliveryStamp->getSenderClassOrAlias()); // received stamp is removed $this->assertNull($envelope->last(ReceivedStamp::class)); @@ -108,7 +108,7 @@ public function testDispatchCausesRetry() $retryStrategy = $this->getMockBuilder(RetryStrategyInterface::class)->getMock(); $retryStrategy->expects($this->once())->method('isRetryable')->willReturn(true); - $worker = new Worker(['receiver1' => $receiver], $bus, ['receiver1' => $retryStrategy]); + $worker = new Worker(['transport1' => $receiver], $bus, ['transport1' => $retryStrategy]); $worker->run([], function (?Envelope $envelope) use ($worker) { // stop after the messages finish if (null === $envelope) { @@ -123,7 +123,7 @@ public function testDispatchCausesRetry() public function testDispatchCausesRejectWhenNoRetry() { $receiver = new DummyReceiver([ - [new Envelope(new DummyMessage('Hello'), [new SentStamp('Some\Sender', 'sender_alias')])], + [new Envelope(new DummyMessage('Hello'), [new SentStamp('Some\Sender', 'transport1')])], ]); $bus = $this->getMockBuilder(MessageBusInterface::class)->getMock(); @@ -132,7 +132,7 @@ public function testDispatchCausesRejectWhenNoRetry() $retryStrategy = $this->getMockBuilder(RetryStrategyInterface::class)->getMock(); $retryStrategy->expects($this->once())->method('isRetryable')->willReturn(false); - $worker = new Worker(['receiver1' => $receiver], $bus, ['receiver1' => $retryStrategy]); + $worker = new Worker(['transport1' => $receiver], $bus, ['transport1' => $retryStrategy]); $worker->run([], function (?Envelope $envelope) use ($worker) { // stop after the messages finish if (null === $envelope) { @@ -155,7 +155,7 @@ public function testDispatchCausesRejectOnUnrecoverableMessage() $retryStrategy = $this->getMockBuilder(RetryStrategyInterface::class)->getMock(); $retryStrategy->expects($this->never())->method('isRetryable'); - $worker = new Worker(['receiver1' => $receiver], $bus, ['receiver1' => $retryStrategy]); + $worker = new Worker(['transport1' => $receiver], $bus, ['transport1' => $retryStrategy]); $worker->run([], function (?Envelope $envelope) use ($worker) { // stop after the messages finish if (null === $envelope) { diff --git a/src/Symfony/Component/Messenger/Worker.php b/src/Symfony/Component/Messenger/Worker.php index b54382bd713dc..65fa17b5b32b6 100644 --- a/src/Symfony/Component/Messenger/Worker.php +++ b/src/Symfony/Component/Messenger/Worker.php @@ -17,13 +17,11 @@ use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent; use Symfony\Component\Messenger\Event\WorkerStoppedEvent; use Symfony\Component\Messenger\Exception\HandlerFailedException; -use Symfony\Component\Messenger\Exception\LogicException; use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException; use Symfony\Component\Messenger\Retry\RetryStrategyInterface; use Symfony\Component\Messenger\Stamp\DelayStamp; use Symfony\Component\Messenger\Stamp\ReceivedStamp; use Symfony\Component\Messenger\Stamp\RedeliveryStamp; -use Symfony\Component\Messenger\Stamp\SentStamp; use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; @@ -150,7 +148,7 @@ private function handleMessage(Envelope $envelope, ReceiverInterface $receiver, // add the delay and retry stamp info + remove ReceivedStamp $retryEnvelope = $envelope->with(new DelayStamp($delay)) - ->with(new RedeliveryStamp($retryCount, $this->getSenderClassOrAlias($envelope))) + ->with(new RedeliveryStamp($retryCount, $transportName)) ->withoutAll(ReceivedStamp::class); // re-send the message @@ -197,28 +195,6 @@ private function shouldRetry(\Throwable $e, Envelope $envelope, RetryStrategyInt return false; } - $sentStamp = $envelope->last(SentStamp::class); - if (null === $sentStamp) { - if (null !== $this->logger) { - $this->logger->warning('Message will not be retried because the SentStamp is missing and so the target sender cannot be determined.'); - } - - return false; - } - return $retryStrategy->isRetryable($envelope); } - - private function getSenderClassOrAlias(Envelope $envelope): string - { - /** @var SentStamp|null $sentStamp */ - $sentStamp = $envelope->last(SentStamp::class); - - if (null === $sentStamp) { - // should not happen, because of the check in shouldRetry() - throw new LogicException('Could not find SentStamp.'); - } - - return $sentStamp->getSenderAlias() ?: $sentStamp->getSenderClass(); - } } From fbda90af6e7ef0bcbaed046fec783b2283d21ee8 Mon Sep 17 00:00:00 2001 From: Amrouche Hamza Date: Fri, 14 Jun 2019 09:12:25 +0200 Subject: [PATCH 052/106] [DI] Show the right class autowired when providing a non-existing class in constructor --- .../Compiler/AutowirePass.php | 9 +++++---- .../Tests/Compiler/AutowirePassTest.php | 16 ++++++++++++++++ .../Tests/Fixtures/ConstructNotExists.php | 10 ++++++++++ .../Fixtures/includes/autowiring_classes.php | 7 +++++++ .../Fixtures/yaml/services_not_existing.yml | 7 +++++++ .../Tests/Loader/YamlFileLoaderTest.php | 12 ++++++++++++ 6 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/ConstructNotExists.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_not_existing.yml diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index 2a1a8ab69be26..3ae264f5c8bc5 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -379,13 +379,14 @@ private function createTypeNotFoundMessageCallback(TypedReference $reference, $l $container->setAliases($this->container->getAliases()); $container->setDefinitions($this->container->getDefinitions()); $container->setResourceTracking(false); + $currentId = $this->currentId; - return function () use ($container, $reference, $label) { - return $this->createTypeNotFoundMessage($container, $reference, $label); + return function () use ($container, $reference, $label, $currentId) { + return $this->createTypeNotFoundMessage($container, $reference, $label, $currentId); }; } - private function createTypeNotFoundMessage(ContainerBuilder $container, TypedReference $reference, $label) + private function createTypeNotFoundMessage(ContainerBuilder $container, TypedReference $reference, $label, string $currentId) { if (!$r = $container->getReflectionClass($type = $reference->getType(), false)) { // either $type does not exist or a parent class does not exist @@ -409,7 +410,7 @@ private function createTypeNotFoundMessage(ContainerBuilder $container, TypedRef } } - $message = sprintf('Cannot autowire service "%s": %s %s', $this->currentId, $label, $message); + $message = sprintf('Cannot autowire service "%s": %s %s', $currentId, $label, $message); if (null !== $this->lastFailure) { $message = $this->lastFailure."\n".$message; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php index 3c08425fc2497..319845644422f 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php @@ -50,6 +50,22 @@ public function testProcess() $this->assertEquals(Foo::class, (string) $container->getDefinition('bar')->getArgument(0)); } + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException + * @expectedExceptionMessage Cannot autowire service "Symfony\Component\DependencyInjection\Tests\CompilerEslaAction": argument "$notExisting" of method "Symfony\Component\DependencyInjection\Tests\Compiler\ElsaAction::__construct()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\NotExisting" but this class was not found. + */ + public function testProcessNotExistingActionParam() + { + $container = new ContainerBuilder(); + + $container->register(Foo::class); + $barDefinition = $container->register(__NAMESPACE__.'EslaAction', __NAMESPACE__.'\ElsaAction'); + $barDefinition->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + } + public function testProcessVariadic() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ConstructNotExists.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ConstructNotExists.php new file mode 100644 index 0000000000000..dcf6484fb527c --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ConstructNotExists.php @@ -0,0 +1,10 @@ +getValues()[0]; }, $definition->getBindings())); } + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException + * @expectedExceptionMessage Cannot autowire service "Symfony\Component\DependencyInjection\Tests\Fixtures\ConstructNotExists": argument "$notExist" of method "__construct()" has type "Symfony\Component\DependencyInjection\Tests\Fixtures\NotExist" but this class was not found. + */ + public function testProcessNotExistingActionParam() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_not_existing.yml'); + $container->compile(); + } + public function testFqcnLazyProxy() { $container = new ContainerBuilder(); From 270f10cc81b2222e98dffb15f3746b97107c0764 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Sat, 15 Jun 2019 08:54:32 +0200 Subject: [PATCH 053/106] [HttpFoundation] Fix SA/phpdoc JsonResponse --- .../Component/HttpFoundation/JsonResponse.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index 24798eea42b32..9c7c8e4c9b3be 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -55,10 +55,10 @@ public function __construct($data = null, $status = 200, $headers = [], $json = * * Example: * - * return JsonResponse::create($data, 200) + * return JsonResponse::create(['key' => 'value']) * ->setSharedMaxAge(300); * - * @param mixed $data The json response data + * @param mixed $data The JSON response data * @param int $status The response status code * @param array $headers An array of response headers * @@ -70,7 +70,18 @@ public static function create($data = null, $status = 200, $headers = []) } /** - * Make easier the creation of JsonResponse from raw json. + * Factory method for chainability. + * + * Example: + * + * return JsonResponse::fromJsonString('{"key": "value"}') + * ->setSharedMaxAge(300); + * + * @param string|null $data The JSON response string + * @param int $status The response status code + * @param array $headers An array of response headers + * + * @return static */ public static function fromJsonString($data = null, $status = 200, $headers = []) { From 3f167417fb970014e9c68d31b7404996b6cda6cb Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 16 Jun 2019 20:17:37 +0200 Subject: [PATCH 054/106] [HttpClient] throw DecodingExceptionInterface when toArray() fails because of content-type error --- .../HttpClient/Exception/JsonException.php | 4 ++-- .../Component/HttpClient/composer.json | 2 +- .../Exception/DecodingExceptionInterface.php | 23 +++++++++++++++++++ .../HttpClient/ResponseInterface.php | 4 +++- 4 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Contracts/HttpClient/Exception/DecodingExceptionInterface.php diff --git a/src/Symfony/Component/HttpClient/Exception/JsonException.php b/src/Symfony/Component/HttpClient/Exception/JsonException.php index 6c825cbeb6886..aec51a5970d54 100644 --- a/src/Symfony/Component/HttpClient/Exception/JsonException.php +++ b/src/Symfony/Component/HttpClient/Exception/JsonException.php @@ -11,7 +11,7 @@ namespace Symfony\Component\HttpClient\Exception; -use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; /** * Thrown by responses' toArray() method when their content cannot be JSON-decoded. @@ -20,6 +20,6 @@ * * @experimental in 4.3 */ -final class JsonException extends \JsonException implements TransportExceptionInterface +final class JsonException extends \JsonException implements DecodingExceptionInterface { } diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index bda296a9d92e0..3289ef3a6d748 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -21,7 +21,7 @@ "require": { "php": "^7.1.3", "psr/log": "^1.0", - "symfony/http-client-contracts": "^1.1.3", + "symfony/http-client-contracts": "^1.1.4", "symfony/polyfill-php73": "^1.11" }, "require-dev": { diff --git a/src/Symfony/Contracts/HttpClient/Exception/DecodingExceptionInterface.php b/src/Symfony/Contracts/HttpClient/Exception/DecodingExceptionInterface.php new file mode 100644 index 0000000000000..709db2189eb4b --- /dev/null +++ b/src/Symfony/Contracts/HttpClient/Exception/DecodingExceptionInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When a content-type cannot be decoded to the expected representation. + * + * @author Nicolas Grekas + * + * @experimental in 1.1 + */ +interface DecodingExceptionInterface extends ExceptionInterface +{ +} diff --git a/src/Symfony/Contracts/HttpClient/ResponseInterface.php b/src/Symfony/Contracts/HttpClient/ResponseInterface.php index a7e01be84c28f..791be4bc61309 100644 --- a/src/Symfony/Contracts/HttpClient/ResponseInterface.php +++ b/src/Symfony/Contracts/HttpClient/ResponseInterface.php @@ -12,6 +12,7 @@ namespace Symfony\Contracts\HttpClient; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; @@ -64,7 +65,8 @@ public function getContent(bool $throw = true): string; * * @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes * - * @throws TransportExceptionInterface When the body cannot be decoded or when a network error occurs + * @throws DecodingExceptionInterface When the body cannot be decoded to an array + * @throws TransportExceptionInterface When a network error occurs * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached * @throws ClientExceptionInterface On a 4xx when $throw is true * @throws ServerExceptionInterface On a 5xx when $throw is true From 9f960f34e7785d3bde67b850ac4754cc46f853bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Mon, 17 Jun 2019 16:05:50 +0200 Subject: [PATCH 055/106] Fix expired lock not cleaned --- src/Symfony/Component/Lock/Lock.php | 10 +++++++ .../Component/Lock/Store/CombinedStore.php | 8 ++--- .../Lock/Store/ExpiringStoreTrait.php | 30 +++++++++++++++++++ .../Component/Lock/Store/MemcachedStore.php | 11 +++---- .../Component/Lock/Store/RedisStore.php | 11 +++---- .../Tests/Store/ExpiringStoreTestTrait.php | 25 ++++++++++++++++ 6 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 src/Symfony/Component/Lock/Store/ExpiringStoreTrait.php diff --git a/src/Symfony/Component/Lock/Lock.php b/src/Symfony/Component/Lock/Lock.php index 1a6c0e26ee0c9..0d5714bde20c0 100644 --- a/src/Symfony/Component/Lock/Lock.php +++ b/src/Symfony/Component/Lock/Lock.php @@ -83,6 +83,11 @@ public function acquire($blocking = false) } if ($this->key->isExpired()) { + try { + $this->release(); + } catch (\Exception $e) { + // swallow exception to not hide the original issue + } throw new LockExpiredException(sprintf('Failed to store the "%s" lock.', $this->key)); } @@ -117,6 +122,11 @@ public function refresh() $this->dirty = true; if ($this->key->isExpired()) { + try { + $this->release(); + } catch (\Exception $e) { + // swallow exception to not hide the original issue + } throw new LockExpiredException(sprintf('Failed to put off the expiration of the "%s" lock within the specified time.', $this->key)); } diff --git a/src/Symfony/Component/Lock/Store/CombinedStore.php b/src/Symfony/Component/Lock/Store/CombinedStore.php index 38f3f35e750e9..6038b3be93d31 100644 --- a/src/Symfony/Component/Lock/Store/CombinedStore.php +++ b/src/Symfony/Component/Lock/Store/CombinedStore.php @@ -16,7 +16,6 @@ use Psr\Log\NullLogger; use Symfony\Component\Lock\Exception\InvalidArgumentException; use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Exception\LockExpiredException; use Symfony\Component\Lock\Exception\NotSupportedException; use Symfony\Component\Lock\Key; use Symfony\Component\Lock\StoreInterface; @@ -30,6 +29,7 @@ class CombinedStore implements StoreInterface, LoggerAwareInterface { use LoggerAwareTrait; + use ExpiringStoreTrait; /** @var StoreInterface[] */ private $stores; @@ -78,6 +78,8 @@ public function save(Key $key) } } + $this->checkNotExpired($key); + if ($this->strategy->isMet($successCount, $storesCount)) { return; } @@ -125,9 +127,7 @@ public function putOffExpiration(Key $key, $ttl) } } - if ($key->isExpired()) { - throw new LockExpiredException(sprintf('Failed to put off the expiration of the "%s" lock within the specified time.', $key)); - } + $this->checkNotExpired($key); if ($this->strategy->isMet($successCount, $storesCount)) { return; diff --git a/src/Symfony/Component/Lock/Store/ExpiringStoreTrait.php b/src/Symfony/Component/Lock/Store/ExpiringStoreTrait.php new file mode 100644 index 0000000000000..e22c4405e4151 --- /dev/null +++ b/src/Symfony/Component/Lock/Store/ExpiringStoreTrait.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Lock\Store; + +use Symfony\Component\Lock\Exception\LockExpiredException; +use Symfony\Component\Lock\Key; + +trait ExpiringStoreTrait +{ + private function checkNotExpired(Key $key) + { + if ($key->isExpired()) { + try { + $this->delete($key); + } catch (\Exception $e) { + // swallow exception to not hide the original issue + } + throw new LockExpiredException(sprintf('Failed to store the "%s" lock.', $key)); + } + } +} diff --git a/src/Symfony/Component/Lock/Store/MemcachedStore.php b/src/Symfony/Component/Lock/Store/MemcachedStore.php index 9b795504c990f..7a51d6149b301 100644 --- a/src/Symfony/Component/Lock/Store/MemcachedStore.php +++ b/src/Symfony/Component/Lock/Store/MemcachedStore.php @@ -13,7 +13,6 @@ use Symfony\Component\Lock\Exception\InvalidArgumentException; use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Exception\LockExpiredException; use Symfony\Component\Lock\Key; use Symfony\Component\Lock\StoreInterface; @@ -24,6 +23,8 @@ */ class MemcachedStore implements StoreInterface { + use ExpiringStoreTrait; + private $memcached; private $initialTtl; /** @var bool */ @@ -64,9 +65,7 @@ public function save(Key $key) $this->putOffExpiration($key, $this->initialTtl); } - if ($key->isExpired()) { - throw new LockExpiredException(sprintf('Failed to store the "%s" lock.', $key)); - } + $this->checkNotExpired($key); } public function waitAndSave(Key $key) @@ -110,9 +109,7 @@ public function putOffExpiration(Key $key, $ttl) throw new LockConflictedException(); } - if ($key->isExpired()) { - throw new LockExpiredException(sprintf('Failed to put off the expiration of the "%s" lock within the specified time.', $key)); - } + $this->checkNotExpired($key); } /** diff --git a/src/Symfony/Component/Lock/Store/RedisStore.php b/src/Symfony/Component/Lock/Store/RedisStore.php index 2d7ba45366784..6070c2e74e760 100644 --- a/src/Symfony/Component/Lock/Store/RedisStore.php +++ b/src/Symfony/Component/Lock/Store/RedisStore.php @@ -14,7 +14,6 @@ use Symfony\Component\Cache\Traits\RedisProxy; use Symfony\Component\Lock\Exception\InvalidArgumentException; use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Exception\LockExpiredException; use Symfony\Component\Lock\Key; use Symfony\Component\Lock\StoreInterface; @@ -25,6 +24,8 @@ */ class RedisStore implements StoreInterface { + use ExpiringStoreTrait; + private $redis; private $initialTtl; @@ -66,9 +67,7 @@ public function save(Key $key) throw new LockConflictedException(); } - if ($key->isExpired()) { - throw new LockExpiredException(sprintf('Failed to store the "%s" lock.', $key)); - } + $this->checkNotExpired($key); } public function waitAndSave(Key $key) @@ -94,9 +93,7 @@ public function putOffExpiration(Key $key, $ttl) throw new LockConflictedException(); } - if ($key->isExpired()) { - throw new LockExpiredException(sprintf('Failed to put off the expiration of the "%s" lock within the specified time.', $key)); - } + $this->checkNotExpired($key); } /** diff --git a/src/Symfony/Component/Lock/Tests/Store/ExpiringStoreTestTrait.php b/src/Symfony/Component/Lock/Tests/Store/ExpiringStoreTestTrait.php index f523780ce1444..bc96ff66f5dfb 100644 --- a/src/Symfony/Component/Lock/Tests/Store/ExpiringStoreTestTrait.php +++ b/src/Symfony/Component/Lock/Tests/Store/ExpiringStoreTestTrait.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Lock\Tests\Store; +use Symfony\Component\Lock\Exception\LockExpiredException; use Symfony\Component\Lock\Key; use Symfony\Component\Lock\StoreInterface; @@ -105,4 +106,28 @@ public function testSetExpiration() $this->assertGreaterThanOrEqual(0, $key->getRemainingLifetime()); $this->assertLessThanOrEqual(1, $key->getRemainingLifetime()); } + + public function testExpiredLockCleaned() + { + $resource = uniqid(__METHOD__, true); + + $key1 = new Key($resource); + $key2 = new Key($resource); + + /** @var StoreInterface $store */ + $store = $this->getStore(); + $key1->reduceLifetime(0); + + $this->assertTrue($key1->isExpired()); + try { + $store->save($key1); + $this->fail('The store shouldn\'t have save an expired key'); + } catch (LockExpiredException $e) { + } + + $this->assertFalse($store->exists($key1)); + + $store->save($key2); + $this->assertTrue($store->exists($key2)); + } } From 5bc336416797a065662e8bbc0859c8d33f052005 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Fri, 14 Jun 2019 19:29:31 +0200 Subject: [PATCH 056/106] [Messenger] fix AMQP delay queue to be per exchange --- .../Transport/AmqpExt/ConnectionTest.php | 111 +++++++++--------- .../Transport/AmqpExt/Connection.php | 34 +++--- 2 files changed, 70 insertions(+), 75 deletions(-) diff --git a/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/ConnectionTest.php b/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/ConnectionTest.php index 9462529b94318..e7dee84219e3f 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/AmqpExt/ConnectionTest.php @@ -23,6 +23,8 @@ */ class ConnectionTest extends TestCase { + private const DEFAULT_EXCHANGE_NAME = 'messages'; + /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage The given AMQP DSN "amqp://:" is invalid. @@ -40,9 +42,9 @@ public function testItCanBeConstructedWithDefaults() 'port' => 5672, 'vhost' => '/', ], [ - 'name' => 'messages', + 'name' => self::DEFAULT_EXCHANGE_NAME, ], [ - 'messages' => [], + self::DEFAULT_EXCHANGE_NAME => [], ]), Connection::fromDsn('amqp://') ); @@ -196,7 +198,7 @@ public function testItUsesANormalConnectionByDefault() $amqpChannel->expects($this->once())->method('isConnected')->willReturn(true); $amqpConnection->expects($this->once())->method('connect'); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages', [], $factory); + $connection = Connection::fromDsn('amqp://localhost', [], $factory); $connection->publish('body'); } @@ -213,7 +215,7 @@ public function testItAllowsToUseAPersistentConnection() $amqpChannel->expects($this->once())->method('isConnected')->willReturn(true); $amqpConnection->expects($this->once())->method('pconnect'); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages?persistent=true', [], $factory); + $connection = Connection::fromDsn('amqp://localhost?persistent=true', [], $factory); $connection->publish('body'); } @@ -226,13 +228,12 @@ public function testItSetupsTheConnectionWithDefaults() $amqpExchange = $this->createMock(\AMQPExchange::class) ); - $amqpExchange->method('getName')->willReturn('exchange_name'); $amqpExchange->expects($this->once())->method('declareExchange'); $amqpExchange->expects($this->once())->method('publish')->with('body', null, AMQP_NOPARAM, ['headers' => []]); $amqpQueue->expects($this->once())->method('declareQueue'); - $amqpQueue->expects($this->once())->method('bind')->with('exchange_name', null); + $amqpQueue->expects($this->once())->method('bind')->with(self::DEFAULT_EXCHANGE_NAME, null); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages', [], $factory); + $connection = Connection::fromDsn('amqp://localhost', [], $factory); $connection->publish('body'); } @@ -250,21 +251,20 @@ public function testItSetupsTheConnection() $factory->method('createExchange')->willReturn($amqpExchange); $factory->method('createQueue')->will($this->onConsecutiveCalls($amqpQueue0, $amqpQueue1)); - $amqpExchange->method('getName')->willReturn('exchange_name'); $amqpExchange->expects($this->once())->method('declareExchange'); $amqpExchange->expects($this->once())->method('publish')->with('body', 'routing_key', AMQP_NOPARAM, ['headers' => []]); $amqpQueue0->expects($this->once())->method('declareQueue'); $amqpQueue0->expects($this->exactly(2))->method('bind')->withConsecutive( - ['exchange_name', 'binding_key0'], - ['exchange_name', 'binding_key1'] + [self::DEFAULT_EXCHANGE_NAME, 'binding_key0'], + [self::DEFAULT_EXCHANGE_NAME, 'binding_key1'] ); $amqpQueue1->expects($this->once())->method('declareQueue'); $amqpQueue1->expects($this->exactly(2))->method('bind')->withConsecutive( - ['exchange_name', 'binding_key2'], - ['exchange_name', 'binding_key3'] + [self::DEFAULT_EXCHANGE_NAME, 'binding_key2'], + [self::DEFAULT_EXCHANGE_NAME, 'binding_key3'] ); - $dsn = 'amqp://localhost/%2f/messages?'. + $dsn = 'amqp://localhost?'. 'exchange[default_publish_routing_key]=routing_key&'. 'queues[queue0][binding_keys][0]=binding_key0&'. 'queues[queue0][binding_keys][1]=binding_key1&'. @@ -284,18 +284,17 @@ public function testItCanDisableTheSetup() $amqpExchange = $this->createMock(\AMQPExchange::class) ); - $amqpExchange->method('getName')->willReturn('exchange_name'); $amqpExchange->expects($this->never())->method('declareExchange'); $amqpQueue->expects($this->never())->method('declareQueue'); $amqpQueue->expects($this->never())->method('bind'); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages', ['auto_setup' => 'false'], $factory); + $connection = Connection::fromDsn('amqp://localhost', ['auto_setup' => 'false'], $factory); $connection->publish('body'); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages', ['auto_setup' => false], $factory); + $connection = Connection::fromDsn('amqp://localhost', ['auto_setup' => false], $factory); $connection->publish('body'); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages?auto_setup=false', [], $factory); + $connection = Connection::fromDsn('amqp://localhost?auto_setup=false', [], $factory); $connection->publish('body'); } @@ -312,9 +311,9 @@ public function testSetChannelPrefetchWhenSetup() $amqpChannel->expects($this->exactly(2))->method('isConnected')->willReturn(true); $amqpChannel->expects($this->exactly(2))->method('setPrefetchCount')->with(2); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages?prefetch_count=2', [], $factory); + $connection = Connection::fromDsn('amqp://localhost?prefetch_count=2', [], $factory); $connection->setup(); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages', ['prefetch_count' => 2], $factory); + $connection = Connection::fromDsn('amqp://localhost', ['prefetch_count' => 2], $factory); $connection->setup(); } @@ -329,29 +328,29 @@ public function testItDelaysTheMessage() $factory->method('createChannel')->willReturn($amqpChannel); $factory->method('createQueue')->willReturn($delayQueue); $factory->method('createExchange')->will($this->onConsecutiveCalls( - $delayExchange = $this->getMockBuilder(\AMQPExchange::class)->disableOriginalConstructor()->getMock(), - $amqpExchange = $this->getMockBuilder(\AMQPExchange::class)->disableOriginalConstructor()->getMock() + $amqpExchange = $this->getMockBuilder(\AMQPExchange::class)->disableOriginalConstructor()->getMock(), + $delayExchange = $this->getMockBuilder(\AMQPExchange::class)->disableOriginalConstructor()->getMock() )); - $amqpExchange->expects($this->once())->method('setName')->with('messages'); - $amqpExchange->method('getName')->willReturn('messages'); + $amqpExchange->expects($this->once())->method('setName')->with(self::DEFAULT_EXCHANGE_NAME); + $amqpExchange->expects($this->once())->method('declareExchange'); $delayExchange->expects($this->once())->method('setName')->with('delay'); $delayExchange->expects($this->once())->method('declareExchange'); - $delayExchange->method('getName')->willReturn('delay'); - $delayQueue->expects($this->once())->method('setName')->with('delay_queue__5000'); + $delayQueue->expects($this->once())->method('setName')->with('delay_queue_messages__5000'); $delayQueue->expects($this->once())->method('setArguments')->with([ 'x-message-ttl' => 5000, - 'x-dead-letter-exchange' => 'messages', + 'x-dead-letter-exchange' => self::DEFAULT_EXCHANGE_NAME, + 'x-dead-letter-routing-key' => '', ]); $delayQueue->expects($this->once())->method('declareQueue'); - $delayQueue->expects($this->once())->method('bind')->with('delay', 'delay__5000'); + $delayQueue->expects($this->once())->method('bind')->with('delay', 'delay_messages__5000'); - $delayExchange->expects($this->once())->method('publish')->with('{}', 'delay__5000', AMQP_NOPARAM, ['headers' => ['x-some-headers' => 'foo']]); + $delayExchange->expects($this->once())->method('publish')->with('{}', 'delay_messages__5000', AMQP_NOPARAM, ['headers' => ['x-some-headers' => 'foo']]); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages', [], $factory); + $connection = Connection::fromDsn('amqp://localhost', [], $factory); $connection->publish('{}', ['x-some-headers' => 'foo'], 5000); } @@ -366,16 +365,15 @@ public function testItDelaysTheMessageWithADifferentRoutingKeyAndTTLs() $factory->method('createChannel')->willReturn($amqpChannel); $factory->method('createQueue')->willReturn($delayQueue); $factory->method('createExchange')->will($this->onConsecutiveCalls( - $delayExchange = $this->getMockBuilder(\AMQPExchange::class)->disableOriginalConstructor()->getMock(), - $amqpExchange = $this->getMockBuilder(\AMQPExchange::class)->disableOriginalConstructor()->getMock() + $amqpExchange = $this->getMockBuilder(\AMQPExchange::class)->disableOriginalConstructor()->getMock(), + $delayExchange = $this->getMockBuilder(\AMQPExchange::class)->disableOriginalConstructor()->getMock() )); - $amqpExchange->expects($this->once())->method('setName')->with('messages'); - $amqpExchange->method('getName')->willReturn('messages'); + $amqpExchange->expects($this->once())->method('setName')->with(self::DEFAULT_EXCHANGE_NAME); + $amqpExchange->expects($this->once())->method('declareExchange'); $delayExchange->expects($this->once())->method('setName')->with('delay'); $delayExchange->expects($this->once())->method('declareExchange'); - $delayExchange->method('getName')->willReturn('delay'); $connectionOptions = [ 'retry' => [ @@ -383,24 +381,25 @@ public function testItDelaysTheMessageWithADifferentRoutingKeyAndTTLs() ], ]; - $connection = Connection::fromDsn('amqp://localhost/%2f/messages', $connectionOptions, $factory); + $connection = Connection::fromDsn('amqp://localhost', $connectionOptions, $factory); - $delayQueue->expects($this->once())->method('setName')->with('delay_queue__120000'); + $delayQueue->expects($this->once())->method('setName')->with('delay_queue_messages__120000'); $delayQueue->expects($this->once())->method('setArguments')->with([ 'x-message-ttl' => 120000, - 'x-dead-letter-exchange' => 'messages', + 'x-dead-letter-exchange' => self::DEFAULT_EXCHANGE_NAME, + 'x-dead-letter-routing-key' => '', ]); $delayQueue->expects($this->once())->method('declareQueue'); - $delayQueue->expects($this->once())->method('bind')->with('delay', 'delay__120000'); + $delayQueue->expects($this->once())->method('bind')->with('delay', 'delay_messages__120000'); - $delayExchange->expects($this->once())->method('publish')->with('{}', 'delay__120000', AMQP_NOPARAM, ['headers' => []]); + $delayExchange->expects($this->once())->method('publish')->with('{}', 'delay_messages__120000', AMQP_NOPARAM, ['headers' => []]); $connection->publish('{}', [], 120000); } /** * @expectedException \AMQPException - * @expectedExceptionMessage Could not connect to the AMQP server. Please verify the provided DSN. ({"delay":{"routing_key_pattern":"delay_%routing_key%_%delay%","exchange_name":"delay","queue_name_pattern":"delay_queue_%routing_key%_%delay%"},"host":"localhost","port":5672,"vhost":"\/","login":"user","password":"********"}) + * @expectedExceptionMessage Could not connect to the AMQP server. Please verify the provided DSN. ({"host":"localhost","port":5672,"vhost":"\/","login":"user","password":"********"}) */ public function testObfuscatePasswordInDsn() { @@ -415,7 +414,7 @@ public function testObfuscatePasswordInDsn() new \AMQPConnectionException('Oups.') ); - $connection = Connection::fromDsn('amqp://user:secretpassword@localhost/%2f/messages', [], $factory); + $connection = Connection::fromDsn('amqp://user:secretpassword@localhost', [], $factory); $connection->channel(); } @@ -430,7 +429,7 @@ public function testItCanPublishWithTheDefaultRoutingKey() $amqpExchange->expects($this->once())->method('publish')->with('body', 'routing_key'); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages?exchange[default_publish_routing_key]=routing_key', [], $factory); + $connection = Connection::fromDsn('amqp://localhost?exchange[default_publish_routing_key]=routing_key', [], $factory); $connection->publish('body'); } @@ -445,7 +444,7 @@ public function testItCanPublishWithASuppliedRoutingKey() $amqpExchange->expects($this->once())->method('publish')->with('body', 'routing_key'); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages?exchange[default_publish_routing_key]=default_routing_key', [], $factory); + $connection = Connection::fromDsn('amqp://localhost?exchange[default_publish_routing_key]=default_routing_key', [], $factory); $connection->publish('body', [], 0, new AmqpStamp('routing_key')); } @@ -460,16 +459,15 @@ public function testItDelaysTheMessageWithTheInitialSuppliedRoutingKeyAsArgument $factory->method('createChannel')->willReturn($amqpChannel); $factory->method('createQueue')->willReturn($delayQueue); $factory->method('createExchange')->will($this->onConsecutiveCalls( - $delayExchange = $this->createMock(\AMQPExchange::class), - $amqpExchange = $this->createMock(\AMQPExchange::class) + $amqpExchange = $this->createMock(\AMQPExchange::class), + $delayExchange = $this->createMock(\AMQPExchange::class) )); - $amqpExchange->expects($this->once())->method('setName')->with('messages'); - $amqpExchange->method('getName')->willReturn('messages'); + $amqpExchange->expects($this->once())->method('setName')->with(self::DEFAULT_EXCHANGE_NAME); + $amqpExchange->expects($this->once())->method('declareExchange'); $delayExchange->expects($this->once())->method('setName')->with('delay'); $delayExchange->expects($this->once())->method('declareExchange'); - $delayExchange->method('getName')->willReturn('delay'); $connectionOptions = [ 'retry' => [ @@ -477,22 +475,19 @@ public function testItDelaysTheMessageWithTheInitialSuppliedRoutingKeyAsArgument ], ]; - $connection = Connection::fromDsn('amqp://localhost/%2f/messages', $connectionOptions, $factory); + $connection = Connection::fromDsn('amqp://localhost', $connectionOptions, $factory); - $delayQueue->expects($this->once())->method('setName')->with('delay_queue_routing_key_120000'); + $delayQueue->expects($this->once())->method('setName')->with('delay_queue_messages_routing_key_120000'); $delayQueue->expects($this->once())->method('setArguments')->with([ 'x-message-ttl' => 120000, - 'x-dead-letter-exchange' => 'messages', + 'x-dead-letter-exchange' => self::DEFAULT_EXCHANGE_NAME, + 'x-dead-letter-routing-key' => 'routing_key', ]); - $delayQueue->expects($this->once())->method('setArgument')->with( - 'x-dead-letter-routing-key', - 'routing_key' - ); $delayQueue->expects($this->once())->method('declareQueue'); - $delayQueue->expects($this->once())->method('bind')->with('delay', 'delay_routing_key_120000'); + $delayQueue->expects($this->once())->method('bind')->with('delay', 'delay_messages_routing_key_120000'); - $delayExchange->expects($this->once())->method('publish')->with('{}', 'delay_routing_key_120000', AMQP_NOPARAM, ['headers' => []]); + $delayExchange->expects($this->once())->method('publish')->with('{}', 'delay_messages_routing_key_120000', AMQP_NOPARAM, ['headers' => []]); $connection->publish('{}', [], 120000, new AmqpStamp('routing_key')); } @@ -512,7 +507,7 @@ public function testItCanPublishWithCustomFlagsAndAttributes() ['delivery_mode' => 2, 'headers' => ['type' => DummyMessage::class]] ); - $connection = Connection::fromDsn('amqp://localhost/%2f/messages', [], $factory); + $connection = Connection::fromDsn('amqp://localhost', [], $factory); $connection->publish('body', ['type' => DummyMessage::class], 0, new AmqpStamp('routing_key', AMQP_IMMEDIATE, ['delivery_mode' => 2])); } } diff --git a/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php b/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php index e35cbaa1e396b..6f6b8b22a6db5 100644 --- a/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php @@ -62,9 +62,9 @@ public function __construct(array $connectionOptions, array $exchangeOptions, ar { $this->connectionOptions = array_replace_recursive([ 'delay' => [ - 'routing_key_pattern' => 'delay_%routing_key%_%delay%', + 'routing_key_pattern' => 'delay_%exchange_name%_%routing_key%_%delay%', 'exchange_name' => 'delay', - 'queue_name_pattern' => 'delay_queue_%routing_key%_%delay%', + 'queue_name_pattern' => 'delay_queue_%exchange_name%_%routing_key%_%delay%', ], ], $connectionOptions); $this->exchangeOptions = $exchangeOptions; @@ -93,8 +93,8 @@ public function __construct(array $connectionOptions, array $exchangeOptions, ar * * flags: Exchange flags (Default: AMQP_DURABLE) * * arguments: Extra arguments * * delay: - * * routing_key_pattern: The pattern of the routing key (Default: "delay_%routing_key%_%delay%") - * * queue_name_pattern: Pattern to use to create the queues (Default: "delay_queue_%routing_key%_%delay%") + * * routing_key_pattern: The pattern of the routing key (Default: "delay_%exchange_name%_%routing_key%_%delay%") + * * queue_name_pattern: Pattern to use to create the queues (Default: "delay_queue_%exchange_name%_%routing_key%_%delay%") * * exchange_name: Name of the exchange to be used for the retried messages (Default: "delay") * * auto_setup: Enable or not the auto-setup of queues and exchanges (Default: true) * * prefetch_count: set channel prefetch count @@ -246,12 +246,12 @@ private function setupDelay(int $delay, ?string $routingKey) $this->clear(); } - $exchange = $this->getDelayExchange(); - $exchange->declareExchange(); + $this->exchange()->declareExchange(); // setup normal exchange for delay queue to DLX messages to + $this->getDelayExchange()->declareExchange(); $queue = $this->createDelayQueue($delay, $routingKey); $queue->declareQueue(); - $queue->bind($exchange->getName(), $this->getRoutingKeyForDelay($delay, $routingKey)); + $queue->bind($this->connectionOptions['delay']['exchange_name'], $this->getRoutingKeyForDelay($delay, $routingKey)); } private function getDelayExchange(): \AMQPExchange @@ -278,27 +278,26 @@ private function createDelayQueue(int $delay, ?string $routingKey) { $queue = $this->amqpFactory->createQueue($this->channel()); $queue->setName(str_replace( - ['%delay%', '%routing_key%'], - [$delay, $routingKey ?? ''], + ['%delay%', '%exchange_name%', '%routing_key%'], + [$delay, $this->exchangeOptions['name'], $routingKey ?? ''], $this->connectionOptions['delay']['queue_name_pattern'] )); $queue->setArguments([ 'x-message-ttl' => $delay, - 'x-dead-letter-exchange' => $this->exchange()->getName(), + 'x-dead-letter-exchange' => $this->exchangeOptions['name'], + // after being released from to DLX, make sure the original routing key will be used + // we must use an empty string instead of null for the argument to be picked up + 'x-dead-letter-routing-key' => $routingKey ?? '', ]); - // after being released from to DLX, make sure the original routing key will be used - // we must use an empty string instead of null for the argument to be picked up - $queue->setArgument('x-dead-letter-routing-key', $routingKey ?? ''); - return $queue; } private function getRoutingKeyForDelay(int $delay, ?string $finalRoutingKey): string { return str_replace( - ['%delay%', '%routing_key%'], - [$delay, $finalRoutingKey ?? ''], + ['%delay%', '%exchange_name%', '%routing_key%'], + [$delay, $this->exchangeOptions['name'], $finalRoutingKey ?? ''], $this->connectionOptions['delay']['routing_key_pattern'] ); } @@ -353,7 +352,7 @@ public function setup(): void foreach ($this->queuesOptions as $queueName => $queueConfig) { $this->queue($queueName)->declareQueue(); foreach ($queueConfig['binding_keys'] ?? [null] as $bindingKey) { - $this->queue($queueName)->bind($this->exchange()->getName(), $bindingKey); + $this->queue($queueName)->bind($this->exchangeOptions['name'], $bindingKey); } } } @@ -377,6 +376,7 @@ public function channel(): \AMQPChannel } catch (\AMQPConnectionException $e) { $credentials = $this->connectionOptions; $credentials['password'] = '********'; + unset($credentials['delay']); throw new \AMQPException(sprintf('Could not connect to the AMQP server. Please verify the provided DSN. (%s)', json_encode($credentials)), 0, $e); } From 02a6f248b5041d68bf6e18d3e254aa7a79039a78 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 17 Jun 2019 19:18:24 +0200 Subject: [PATCH 057/106] [Cache] fix versioning with SimpleCacheAdapter --- .../Component/Cache/Adapter/SimpleCacheAdapter.php | 2 ++ src/Symfony/Component/Cache/Traits/AbstractTrait.php | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php b/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php index de4dd745cd119..dc3a9cec2dc03 100644 --- a/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php @@ -78,6 +78,8 @@ protected function doSave(array $values, $lifetime) /** * @return string the namespace separator for cache keys + * + * @internal */ protected static function getNsSeparator() { diff --git a/src/Symfony/Component/Cache/Traits/AbstractTrait.php b/src/Symfony/Component/Cache/Traits/AbstractTrait.php index 83a86a5ee9e2e..e225e075428eb 100644 --- a/src/Symfony/Component/Cache/Traits/AbstractTrait.php +++ b/src/Symfony/Component/Cache/Traits/AbstractTrait.php @@ -108,7 +108,7 @@ public function clear() if ($cleared = $this->versioningIsEnabled) { $namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), static::getNsSeparator(), 5); try { - $cleared = $this->doSave(['@'.$this->namespace => $namespaceVersion], 0); + $cleared = $this->doSave([static::getNsSeparator().$this->namespace => $namespaceVersion], 0); } catch (\Exception $e) { $cleared = false; } @@ -237,12 +237,12 @@ private function getId($key) if ($this->versioningIsEnabled && '' === $this->namespaceVersion) { $this->namespaceVersion = '1'.static::getNsSeparator(); try { - foreach ($this->doFetch(['@'.$this->namespace]) as $v) { + foreach ($this->doFetch([static::getNsSeparator().$this->namespace]) as $v) { $this->namespaceVersion = $v; } if ('1'.static::getNsSeparator() === $this->namespaceVersion) { $this->namespaceVersion = substr_replace(base64_encode(pack('V', time())), static::getNsSeparator(), 5); - $this->doSave(['@'.$this->namespace => $this->namespaceVersion], 0); + $this->doSave([static::getNsSeparator().$this->namespace => $this->namespaceVersion], 0); } } catch (\Exception $e) { } @@ -268,6 +268,8 @@ public static function handleUnserializeCallback($class) /** * @return string the namespace separator for cache keys + * + * @internal */ protected static function getNsSeparator() { From 2bf5da51da24fb8b490f18ec973086df112840dd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 17 Jun 2019 19:26:15 +0200 Subject: [PATCH 058/106] [Cache] replace getNsSeparator by NS_SEPARATOR on AbstractTrait --- .../Cache/Adapter/AbstractAdapter.php | 7 ++++- .../Cache/Adapter/SimpleCacheAdapter.php | 15 ++++------- .../Component/Cache/Simple/AbstractCache.php | 5 ++++ .../Component/Cache/Traits/AbstractTrait.php | 26 ++++++------------- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index 70af0c7314cac..0868c16d47cf8 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -25,6 +25,11 @@ */ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface { + /** + * @internal + */ + const NS_SEPARATOR = ':'; + use AbstractTrait; private static $apcuSupported; @@ -39,7 +44,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface */ protected function __construct($namespace = '', $defaultLifetime = 0) { - $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::getNsSeparator(); + $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::NS_SEPARATOR; if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, \strlen($namespace), $namespace)); } diff --git a/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php b/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php index dc3a9cec2dc03..d3d0ede648a8a 100644 --- a/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php @@ -20,6 +20,11 @@ */ class SimpleCacheAdapter extends AbstractAdapter implements PruneableInterface { + /** + * @internal + */ + const NS_SEPARATOR = '_'; + use ProxyTrait; private $miss; @@ -75,14 +80,4 @@ protected function doSave(array $values, $lifetime) { return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime); } - - /** - * @return string the namespace separator for cache keys - * - * @internal - */ - protected static function getNsSeparator() - { - return '_'; - } } diff --git a/src/Symfony/Component/Cache/Simple/AbstractCache.php b/src/Symfony/Component/Cache/Simple/AbstractCache.php index 0d715e48d2232..23b401c54be55 100644 --- a/src/Symfony/Component/Cache/Simple/AbstractCache.php +++ b/src/Symfony/Component/Cache/Simple/AbstractCache.php @@ -23,6 +23,11 @@ */ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, ResettableInterface { + /** + * @internal + */ + const NS_SEPARATOR = ':'; + use AbstractTrait { deleteItems as private; AbstractTrait::deleteItem as delete; diff --git a/src/Symfony/Component/Cache/Traits/AbstractTrait.php b/src/Symfony/Component/Cache/Traits/AbstractTrait.php index e225e075428eb..cd1f204139186 100644 --- a/src/Symfony/Component/Cache/Traits/AbstractTrait.php +++ b/src/Symfony/Component/Cache/Traits/AbstractTrait.php @@ -106,9 +106,9 @@ public function clear() { $this->deferred = []; if ($cleared = $this->versioningIsEnabled) { - $namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), static::getNsSeparator(), 5); + $namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), static::NS_SEPARATOR, 5); try { - $cleared = $this->doSave([static::getNsSeparator().$this->namespace => $namespaceVersion], 0); + $cleared = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0); } catch (\Exception $e) { $cleared = false; } @@ -235,14 +235,14 @@ private function getId($key) CacheItem::validateKey($key); if ($this->versioningIsEnabled && '' === $this->namespaceVersion) { - $this->namespaceVersion = '1'.static::getNsSeparator(); + $this->namespaceVersion = '1'.static::NS_SEPARATOR; try { - foreach ($this->doFetch([static::getNsSeparator().$this->namespace]) as $v) { + foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) { $this->namespaceVersion = $v; } - if ('1'.static::getNsSeparator() === $this->namespaceVersion) { - $this->namespaceVersion = substr_replace(base64_encode(pack('V', time())), static::getNsSeparator(), 5); - $this->doSave([static::getNsSeparator().$this->namespace => $this->namespaceVersion], 0); + if ('1'.static::NS_SEPARATOR === $this->namespaceVersion) { + $this->namespaceVersion = substr_replace(base64_encode(pack('V', time())), static::NS_SEPARATOR, 5); + $this->doSave([static::NS_SEPARATOR.$this->namespace => $this->namespaceVersion], 0); } } catch (\Exception $e) { } @@ -252,7 +252,7 @@ private function getId($key) return $this->namespace.$this->namespaceVersion.$key; } if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) { - $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), static::getNsSeparator(), -(\strlen($this->namespaceVersion) + 22)); + $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), static::NS_SEPARATOR, -(\strlen($this->namespaceVersion) + 22)); } return $id; @@ -265,14 +265,4 @@ public static function handleUnserializeCallback($class) { throw new \DomainException('Class not found: '.$class); } - - /** - * @return string the namespace separator for cache keys - * - * @internal - */ - protected static function getNsSeparator() - { - return ':'; - } } From 432c21f83c5c5ca32ff3b98085dfe0aeb8bcd67e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 17 Jun 2019 20:45:27 +0200 Subject: [PATCH 059/106] [Lock] fix bad merge --- src/Symfony/Component/Lock/Store/PdoStore.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Lock/Store/PdoStore.php b/src/Symfony/Component/Lock/Store/PdoStore.php index 8066501166227..3b5049f84db4f 100644 --- a/src/Symfony/Component/Lock/Store/PdoStore.php +++ b/src/Symfony/Component/Lock/Store/PdoStore.php @@ -16,7 +16,6 @@ use Doctrine\DBAL\Schema\Schema; use Symfony\Component\Lock\Exception\InvalidArgumentException; use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Exception\LockExpiredException; use Symfony\Component\Lock\Exception\NotSupportedException; use Symfony\Component\Lock\Key; use Symfony\Component\Lock\StoreInterface; @@ -36,6 +35,8 @@ */ class PdoStore implements StoreInterface { + use ExpiringStoreTrait; + private $conn; private $dsn; private $driver; @@ -123,9 +124,7 @@ public function save(Key $key) try { $stmt->execute(); - if ($key->isExpired()) { - throw new LockExpiredException(sprintf('Failed to put off the expiration of the "%s" lock within the specified time.', $key)); - } + $this->checkNotExpired($key); return; } catch (DBALException $e) { @@ -136,9 +135,7 @@ public function save(Key $key) $this->putOffExpiration($key, $this->initialTtl); } - if ($key->isExpired()) { - throw new LockExpiredException(sprintf('Failed to store the "%s" lock.', $key)); - } + $this->checkNotExpired($key); if ($this->gcProbability > 0 && (1.0 === $this->gcProbability || (random_int(0, PHP_INT_MAX) / PHP_INT_MAX) <= $this->gcProbability)) { $this->prune(); @@ -178,9 +175,7 @@ public function putOffExpiration(Key $key, $ttl) throw new LockConflictedException(); } - if ($key->isExpired()) { - throw new LockExpiredException(sprintf('Failed to put off the expiration of the "%s" lock within the specified time.', $key)); - } + $this->checkNotExpired($key); } /** From 4f808ef4f4c77abaed9be31d4230ead832c609b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Mon, 17 Jun 2019 20:41:36 +0200 Subject: [PATCH 060/106] Fix Expiring lock in PDO and ZooKeeper --- src/Symfony/Component/Lock/Store/ZookeeperStore.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Lock/Store/ZookeeperStore.php b/src/Symfony/Component/Lock/Store/ZookeeperStore.php index 4f8b4ee374e86..ce3cb4bab7049 100644 --- a/src/Symfony/Component/Lock/Store/ZookeeperStore.php +++ b/src/Symfony/Component/Lock/Store/ZookeeperStore.php @@ -25,6 +25,8 @@ */ class ZookeeperStore implements StoreInterface { + use ExpiringStoreTrait; + private $zookeeper; public function __construct(\Zookeeper $zookeeper) @@ -45,6 +47,8 @@ public function save(Key $key) $token = $this->getUniqueToken($key); $this->createNewLock($resource, $token); + + $this->checkNotExpired($key); } /** From fc2dc1492446ed2fb8018d3fbf8cb42837003ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Mon, 17 Jun 2019 20:49:50 +0200 Subject: [PATCH 061/106] Fix PDO prune not called --- src/Symfony/Component/Lock/Store/PdoStore.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Lock/Store/PdoStore.php b/src/Symfony/Component/Lock/Store/PdoStore.php index 3b5049f84db4f..0cf3dd35f7a19 100644 --- a/src/Symfony/Component/Lock/Store/PdoStore.php +++ b/src/Symfony/Component/Lock/Store/PdoStore.php @@ -124,9 +124,6 @@ public function save(Key $key) try { $stmt->execute(); - $this->checkNotExpired($key); - - return; } catch (DBALException $e) { // the lock is already acquired. It could be us. Let's try to put off. $this->putOffExpiration($key, $this->initialTtl); @@ -135,11 +132,11 @@ public function save(Key $key) $this->putOffExpiration($key, $this->initialTtl); } - $this->checkNotExpired($key); - if ($this->gcProbability > 0 && (1.0 === $this->gcProbability || (random_int(0, PHP_INT_MAX) / PHP_INT_MAX) <= $this->gcProbability)) { $this->prune(); } + + $this->checkNotExpired($key); } /** @@ -289,7 +286,7 @@ public function createTable(): void } /** - * Cleanups the table by removing all expired locks. + * Cleans up the table by removing all expired locks. */ private function prune(): void { From dc55cf826a381c75934a57d849fecca876ebce84 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 18 Jun 2019 13:47:18 +0200 Subject: [PATCH 062/106] [HttpClient] fixing passing debug info to progress callback --- .../HttpClient/Response/CurlResponse.php | 18 ++++++++---------- .../HttpClient/Response/NativeResponse.php | 6 ------ 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 14d3f935e0fb7..73217aa7ddec1 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -55,6 +55,7 @@ public function __construct(CurlClientState $multi, $ch, array $options = null, $this->info['start_time'] = $this->info['start_time'] ?? microtime(true); $info = &$this->info; $headers = &$this->headers; + $debugBuffer = $this->debugBuffer; if (!$info['response_headers']) { // Used to keep track of what we're waiting for @@ -88,9 +89,11 @@ public function __construct(CurlClientState $multi, $ch, array $options = null, if ($onProgress = $options['on_progress']) { $url = isset($info['url']) ? ['url' => $info['url']] : []; curl_setopt($ch, CURLOPT_NOPROGRESS, false); - curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, static function ($ch, $dlSize, $dlNow) use ($onProgress, &$info, $url, $multi) { + curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, static function ($ch, $dlSize, $dlNow) use ($onProgress, &$info, $url, $multi, $debugBuffer) { try { - $onProgress($dlNow, $dlSize, $url + curl_getinfo($ch) + $info); + rewind($debugBuffer); + $debug = ['debug' => stream_get_contents($debugBuffer)]; + $onProgress($dlNow, $dlSize, $url + curl_getinfo($ch) + $info + $debug); } catch (\Throwable $e) { $multi->handlesActivity[(int) $ch][] = null; $multi->handlesActivity[(int) $ch][] = $e; @@ -148,12 +151,6 @@ public function getInfo(string $type = null) if (!$info = $this->finalInfo) { self::perform($this->multi); - if ('debug' === $type) { - rewind($this->debugBuffer); - - return stream_get_contents($this->debugBuffer); - } - $info = array_merge($this->info, curl_getinfo($this->handle)); $info['url'] = $this->info['url'] ?? $info['url']; $info['redirect_url'] = $this->info['redirect_url'] ?? null; @@ -164,9 +161,10 @@ public function getInfo(string $type = null) $info['starttransfer_time'] = 0.0; } + rewind($this->debugBuffer); + $info['debug'] = stream_get_contents($this->debugBuffer); + if (!\in_array(curl_getinfo($this->handle, CURLINFO_PRIVATE), ['headers', 'content'], true)) { - rewind($this->debugBuffer); - $info['debug'] = stream_get_contents($this->debugBuffer); curl_setopt($this->handle, CURLOPT_VERBOSE, false); rewind($this->debugBuffer); ftruncate($this->debugBuffer, 0); diff --git a/src/Symfony/Component/HttpClient/Response/NativeResponse.php b/src/Symfony/Component/HttpClient/Response/NativeResponse.php index 8be4b0416368b..3e321ffb978c0 100644 --- a/src/Symfony/Component/HttpClient/Response/NativeResponse.php +++ b/src/Symfony/Component/HttpClient/Response/NativeResponse.php @@ -78,18 +78,12 @@ public function getInfo(string $type = null) if (!$info = $this->finalInfo) { self::perform($this->multi); - if ('debug' === $type) { - return $this->info['debug']; - } - $info = $this->info; $info['url'] = implode('', $info['url']); unset($info['fopen_time'], $info['size_body'], $info['request_header']); if (null === $this->buffer) { $this->finalInfo = $info; - } else { - unset($info['debug']); } } From d8d43e6195f786d5ae2816080c2467159919d389 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 18 Jun 2019 23:17:25 +0200 Subject: [PATCH 063/106] [Debug] workaround BC break in PHP 7.3 --- src/Symfony/Component/Debug/ErrorHandler.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index d871b91538c22..c7dc3279d73af 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -382,6 +382,11 @@ private function reRegister($prev) */ public function handleError($type, $message, $file, $line) { + // @deprecated to be removed in Symfony 5.0 + if (\PHP_VERSION_ID >= 70300 && $message && '"' === $message[0] && 0 === strpos($message, '"continue') && preg_match('/^"continue(?: \d++)?" targeting switch is equivalent to "break(?: \d++)?"\. Did you mean to use "continue(?: \d++)?"\?$/', $message)) { + $type = E_DEPRECATED; + } + // Level is the current error reporting level to manage silent error. $level = error_reporting(); $silenced = 0 === ($level & $type); From 6ac23169931efdb79e9dae3a4427a25c20e6f6ff Mon Sep 17 00:00:00 2001 From: Lctrs Date: Wed, 19 Jun 2019 10:51:43 +0200 Subject: [PATCH 064/106] [Validator] Use LogicException for missing Property Access Component in comparison constraints --- .../Component/Validator/Constraints/AbstractComparison.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/AbstractComparison.php b/src/Symfony/Component/Validator/Constraints/AbstractComparison.php index 89c2690c081cd..435ced6eb8486 100644 --- a/src/Symfony/Component/Validator/Constraints/AbstractComparison.php +++ b/src/Symfony/Component/Validator/Constraints/AbstractComparison.php @@ -14,6 +14,7 @@ use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\LogicException; /** * Used for the comparison of values. @@ -46,7 +47,7 @@ public function __construct($options = null) } if (isset($options['propertyPath']) && !class_exists(PropertyAccess::class)) { - throw new ConstraintDefinitionException(sprintf('The "%s" constraint requires the Symfony PropertyAccess component to use the "propertyPath" option.', \get_class($this))); + throw new LogicException(sprintf('The "%s" constraint requires the Symfony PropertyAccess component to use the "propertyPath" option.', \get_class($this))); } } From 494281465da5b5f2f39b098f2b85e7877127099c Mon Sep 17 00:00:00 2001 From: Amrouche Hamza Date: Wed, 19 Jun 2019 07:40:07 +0200 Subject: [PATCH 065/106] [FrameworkBundle] minor: fix typo in SessionTest --- .../Bundle/FrameworkBundle/Tests/Functional/SessionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php index aad3d77949ba4..bf1b76cdc743c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php @@ -71,7 +71,7 @@ public function testFlash($config, $insulate) /** * See if two separate insulated clients can run without - * polluting eachother's session data. + * polluting each other's session data. * * @dataProvider getConfigs */ From 32d02d61414e5938602a1cee993f628fad0719ef Mon Sep 17 00:00:00 2001 From: Stefano Degenkamp Date: Wed, 19 Jun 2019 16:56:52 +0200 Subject: [PATCH 066/106] Update ajax security cheat sheet link As the cheat sheet series project has been moved to github. --- src/Symfony/Component/HttpFoundation/JsonResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index 24798eea42b32..bb1fe1d0ae40d 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -18,7 +18,7 @@ * object. It is however recommended that you do return an object as it * protects yourself against XSSI and JSON-JavaScript Hijacking. * - * @see https://www.owasp.org/index.php/OWASP_AJAX_Security_Guidelines#Always_return_JSON_with_an_Object_on_the_outside + * @see https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/AJAX_Security_Cheat_Sheet.md#always-return-json-with-an-object-on-the-outside * * @author Igor Wiedler */ From c1c3b54a0fbca9f85cdde38cc90431438c539eba Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Thu, 20 Jun 2019 03:38:05 +0100 Subject: [PATCH 067/106] [Messenger] fix delay exchange recreation after disconnect --- src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php b/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php index 6f6b8b22a6db5..ecd72a7be9d90 100644 --- a/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/AmqpExt/Connection.php @@ -430,6 +430,7 @@ private function clear(): void $this->amqpChannel = null; $this->amqpQueues = []; $this->amqpExchange = null; + $this->amqpDelayExchange = null; } private function shouldSetup(): bool From bf6d2532de8e6bc7a6906c9aab750e4a0c966456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Tou=C5=A1ek?= Date: Fri, 14 Jun 2019 12:02:44 +0200 Subject: [PATCH 068/106] [Validator] Fix GroupSequenceProvider annotation --- src/Symfony/Component/Validator/Constraints/GroupSequence.php | 2 +- .../Component/Validator/GroupSequenceProviderInterface.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/GroupSequence.php b/src/Symfony/Component/Validator/Constraints/GroupSequence.php index a39d712bf4be7..fc34ca1a458e2 100644 --- a/src/Symfony/Component/Validator/Constraints/GroupSequence.php +++ b/src/Symfony/Component/Validator/Constraints/GroupSequence.php @@ -57,7 +57,7 @@ class GroupSequence /** * The groups in the sequence. * - * @var string[]|array[]|GroupSequence[] + * @var string[]|string[][]|GroupSequence[] */ public $groups; diff --git a/src/Symfony/Component/Validator/GroupSequenceProviderInterface.php b/src/Symfony/Component/Validator/GroupSequenceProviderInterface.php index 5894397da4deb..1ce504331f7f3 100644 --- a/src/Symfony/Component/Validator/GroupSequenceProviderInterface.php +++ b/src/Symfony/Component/Validator/GroupSequenceProviderInterface.php @@ -22,7 +22,7 @@ interface GroupSequenceProviderInterface * Returns which validation groups should be used for a certain state * of the object. * - * @return string[]|GroupSequence An array of validation groups + * @return string[]|string[][]|GroupSequence An array of validation groups */ public function getGroupSequence(); } From f23a7f60cf5e18969ce987a594db1b507c6503c4 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 20 Jun 2019 10:33:16 +0200 Subject: [PATCH 069/106] don't validate IP addresses from env var placeholders --- .../DependencyInjection/MainConfiguration.php | 35 --------------- .../DependencyInjection/SecurityExtension.php | 44 +++++++++++++++++-- .../Resources/config/routing.yml | 6 +++ .../SecurityRoutingIntegrationTest.php | 2 +- .../app/StandardFormLogin/config.yml | 5 +++ .../invalid_ip_access_control.yml | 2 +- 6 files changed, 54 insertions(+), 40 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index eda62ed9ac715..1e1e97ccb5b3f 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -143,15 +143,6 @@ private function addAccessControlSection(ArrayNodeDefinition $rootNode) ->integerNode('port')->defaultNull()->end() ->arrayNode('ips') ->beforeNormalization()->ifString()->then(function ($v) { return [$v]; })->end() - ->beforeNormalization()->always()->then(function ($v) { - foreach ($v as $ip) { - if (false === $this->isValidIp($ip)) { - throw new \LogicException(sprintf('The given "%s" value in the "access_control" config option is not a valid IP address.', $ip)); - } - } - - return $v; - })->end() ->prototype('scalar')->end() ->end() ->arrayNode('methods') @@ -432,30 +423,4 @@ private function addEncodersSection(ArrayNodeDefinition $rootNode) ->end() ; } - - private function isValidIp(string $cidr): bool - { - $cidrParts = explode('/', $cidr); - - if (1 === \count($cidrParts)) { - return false !== filter_var($cidrParts[0], FILTER_VALIDATE_IP); - } - - $ip = $cidrParts[0]; - $netmask = $cidrParts[1]; - - if (!ctype_digit($netmask)) { - return false; - } - - if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { - return $netmask <= 32; - } - - if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { - return $netmask <= 128; - } - - return false; - } } diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index af4260f04c428..4365d0432948f 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -731,20 +731,32 @@ private function createExpression($container, $expression) return $this->expressions[$id] = new Reference($id); } - private function createRequestMatcher($container, $path = null, $host = null, int $port = null, $methods = [], $ip = null, array $attributes = []) + private function createRequestMatcher(ContainerBuilder $container, $path = null, $host = null, int $port = null, $methods = [], array $ips = null, array $attributes = []) { if ($methods) { $methods = array_map('strtoupper', (array) $methods); } - $id = '.security.request_matcher.'.ContainerBuilder::hash([$path, $host, $port, $methods, $ip, $attributes]); + if (null !== $ips) { + foreach ($ips as $ip) { + $container->resolveEnvPlaceholders($ip, null, $usedEnvs); + + if (!$usedEnvs && !$this->isValidIp($ip)) { + throw new \LogicException(sprintf('The given value "%s" in the "security.access_control" config option is not a valid IP address.', $ip)); + } + + $usedEnvs = null; + } + } + + $id = '.security.request_matcher.'.ContainerBuilder::hash([$path, $host, $port, $methods, $ips, $attributes]); if (isset($this->requestMatchers[$id])) { return $this->requestMatchers[$id]; } // only add arguments that are necessary - $arguments = [$path, $host, $methods, $ip, $attributes, null, $port]; + $arguments = [$path, $host, $methods, $ips, $attributes, null, $port]; while (\count($arguments) > 0 && !end($arguments)) { array_pop($arguments); } @@ -788,4 +800,30 @@ public function getConfiguration(array $config, ContainerBuilder $container) // first assemble the factories return new MainConfiguration($this->factories, $this->userProviderFactories); } + + private function isValidIp(string $cidr): bool + { + $cidrParts = explode('/', $cidr); + + if (1 === \count($cidrParts)) { + return false !== filter_var($cidrParts[0], FILTER_VALIDATE_IP); + } + + $ip = $cidrParts[0]; + $netmask = $cidrParts[1]; + + if (!ctype_digit($netmask)) { + return false; + } + + if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + return $netmask <= 32; + } + + if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + return $netmask <= 128; + } + + return false; + } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/routing.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/routing.yml index 2fff93dcad2ef..bf82a203d8ade 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/routing.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/config/routing.yml @@ -40,6 +40,12 @@ secured-by-one-real-ip-with-mask: secured-by-one-real-ipv6: path: /secured-by-one-real-ipv6 +secured-by-one-env-placeholder: + path: /secured-by-one-env-placeholder + +secured-by-one-env-placeholder-and-one-real-ip: + path: /secured-by-one-env-placeholder-and-one-real-ip + form_logout: path: /logout_path diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php index 682c561ac5aa5..c38bc1a4bf5d3 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php @@ -109,7 +109,7 @@ public function testSecurityConfigurationForExpression($config) public function testInvalidIpsInAccessControl() { $this->expectException(\LogicException::class); - $this->expectExceptionMessage('The given "256.357.458.559" value in the "access_control" config option is not a valid IP address.'); + $this->expectExceptionMessage('The given value "256.357.458.559" in the "security.access_control" config option is not a valid IP address.'); $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'invalid_ip_access_control.yml']); $client->request('GET', '/unprotected_resource'); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/config.yml index df03c20c5c514..4e2ac1e11b9d6 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/config.yml @@ -1,6 +1,9 @@ imports: - { resource: ./../config/default.yml } +parameters: + env(APP_IP): '127.0.0.1' + security: encoders: Symfony\Component\Security\Core\User\User: plaintext @@ -43,6 +46,8 @@ security: - { path: ^/secured-by-one-real-ip$, ips: 198.51.100.0, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/secured-by-one-real-ip-with-mask$, ips: '203.0.113.0/24', roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/secured-by-one-real-ipv6$, ips: 0:0:0:0:0:ffff:c633:6400, roles: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: ^/secured-by-one-env-placeholder$, ips: '%env(APP_IP)%', roles: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: ^/secured-by-one-env-placeholder-and-one-real-ip$, ips: ['%env(APP_IP)%', 198.51.100.0], roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/highly_protected_resource$, roles: IS_ADMIN } - { path: ^/protected-via-expression$, allow_if: "(is_anonymous() and request.headers.get('user-agent') matches '/Firefox/i') or is_granted('ROLE_USER')" } - { path: .*, roles: IS_AUTHENTICATED_FULLY } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/invalid_ip_access_control.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/invalid_ip_access_control.yml index e4f46c4704af6..cc6503affb265 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/invalid_ip_access_control.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/invalid_ip_access_control.yml @@ -19,4 +19,4 @@ security: access_control: # the '256.357.458.559' IP is wrong on purpose, to check invalid IP errors - - { path: ^/unprotected_resource$, ips: [1.1.1.1, 256.357.458.559], roles: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: ^/unprotected_resource$, ips: [1.1.1.1, '%env(APP_IP)%', 256.357.458.559], roles: IS_AUTHENTICATED_ANONYMOUSLY } From ea5b1f4d67e3218a005d6109b64250c80e81d98b Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 20 Jun 2019 12:19:18 +0200 Subject: [PATCH 070/106] tag the FileType service as a form type --- src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml index 5088554ff1947..c5bc8cf5dbae6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml @@ -93,6 +93,7 @@ The "%service_id%" service is deprecated since Symfony 3.1 and will be removed in 4.0. + From 74387cf21fed1f77c925a869e9585282544d47be Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 20 Jun 2019 22:29:36 +0200 Subject: [PATCH 071/106] fix translation domain --- src/Symfony/Component/Form/Extension/Core/Type/FileType.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index f8afce2ee5a4d..86f161307ba2b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -159,7 +159,7 @@ private function getFileUploadError($errorCode) } if (null !== $this->translator) { - $message = $this->translator->trans($messageTemplate, $messageParameters); + $message = $this->translator->trans($messageTemplate, $messageParameters, 'validators'); } else { $message = strtr($messageTemplate, $messageParameters); } From 2abf85599d32535efbabe70f297314ea4c4976a1 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 7 Jun 2019 12:53:37 +0200 Subject: [PATCH 072/106] accept floats for input="string" in NumberType --- .../Form/Extension/Core/Type/NumberType.php | 9 +++++++++ .../Extension/Core/Type/NumberTypeTest.php | 20 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php b/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php index 4c1f1fd71f16b..54cbb758ee4ec 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\CallbackTransformer; use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\StringToFloatTransformer; @@ -37,6 +38,14 @@ public function buildForm(FormBuilderInterface $builder, array $options) if ('string' === $options['input']) { $builder->addModelTransformer(new StringToFloatTransformer($options['scale'])); + $builder->addModelTransformer(new CallbackTransformer( + function ($value) { + return \is_float($value) || \is_int($value) ? (string) $value : $value; + }, + function ($value) { + return $value; + } + )); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php index 2cae8bba4886c..6d8ab4539d4ee 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php @@ -77,6 +77,26 @@ public function testDefaultFormattingWithScaleAndStringInput(): void $this->assertSame('12345,68', $form->createView()->vars['value']); } + public function testStringInputWithFloatData(): void + { + $form = $this->factory->create(static::TESTED_TYPE, 12345.6789, [ + 'input' => 'string', + 'scale' => 2, + ]); + + $this->assertSame('12345,68', $form->createView()->vars['value']); + } + + public function testStringInputWithIntData(): void + { + $form = $this->factory->create(static::TESTED_TYPE, 12345, [ + 'input' => 'string', + 'scale' => 2, + ]); + + $this->assertSame('12345,00', $form->createView()->vars['value']); + } + public function testDefaultFormattingWithRounding(): void { $form = $this->factory->create(static::TESTED_TYPE, null, ['scale' => 0, 'rounding_mode' => \NumberFormatter::ROUND_UP]); From 860164ee7e0573771d35fd7631fa95e23f29124e Mon Sep 17 00:00:00 2001 From: Alessandro Chitolina Date: Fri, 21 Jun 2019 11:39:24 +0200 Subject: [PATCH 073/106] [DebugBundle] fix register ReflectionCaster::unsetClosureFileInfo caster in var cloner service --- .../DependencyInjection/DebugExtension.php | 5 +-- .../DebugExtensionTest.php | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php index a183e82cf8501..8309db19ecd7c 100644 --- a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php +++ b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\VarDumper\Caster\ReflectionCaster; use Symfony\Component\VarDumper\Dumper\CliDumper; use Symfony\Component\VarDumper\Dumper\HtmlDumper; @@ -43,9 +44,9 @@ public function load(array $configs, ContainerBuilder $container) ->addMethodCall('setMinDepth', [$config['min_depth']]) ->addMethodCall('setMaxString', [$config['max_string_length']]); - if (method_exists(ReflectionClass::class, 'unsetClosureFileInfo')) { + if (method_exists(ReflectionCaster::class, 'unsetClosureFileInfo')) { $container->getDefinition('var_dumper.cloner') - ->addMethodCall('addCasters', ReflectionClass::UNSET_CLOSURE_FILE_INFO); + ->addMethodCall('addCasters', [ReflectionCaster::UNSET_CLOSURE_FILE_INFO]); } if (method_exists(HtmlDumper::class, 'setTheme') && 'dark' !== $config['theme']) { diff --git a/src/Symfony/Bundle/DebugBundle/Tests/DependencyInjection/DebugExtensionTest.php b/src/Symfony/Bundle/DebugBundle/Tests/DependencyInjection/DebugExtensionTest.php index cd6084c5e3bce..c09ed8bc8ce37 100644 --- a/src/Symfony/Bundle/DebugBundle/Tests/DependencyInjection/DebugExtensionTest.php +++ b/src/Symfony/Bundle/DebugBundle/Tests/DependencyInjection/DebugExtensionTest.php @@ -15,6 +15,7 @@ use Symfony\Bundle\DebugBundle\DependencyInjection\DebugExtension; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\VarDumper\Caster\ReflectionCaster; class DebugExtensionTest extends TestCase { @@ -36,6 +37,39 @@ public function testLoadWithoutConfiguration() $this->assertSame($expectedTags, $container->getDefinition('data_collector.dump')->getTag('data_collector')); } + public function testUnsetClosureFileInfoShouldBeRegisteredInVarCloner() + { + if (!method_exists(ReflectionCaster::class, 'unsetClosureFileInfo')) { + $this->markTestSkipped('Method not available'); + } + + $container = $this->createContainer(); + $container->registerExtension(new DebugExtension()); + $container->loadFromExtension('debug', []); + $this->compileContainer($container); + + $definition = $container->getDefinition('var_dumper.cloner'); + + $called = false; + foreach ($definition->getMethodCalls() as $call) { + if ('addCasters' !== $call[0]) { + continue; + } + + $argument = $call[1][0] ?? null; + if (null === $argument) { + continue; + } + + if (['Closure' => ReflectionCaster::class.'::unsetClosureFileInfo'] === $argument) { + $called = true; + break; + } + } + + $this->assertTrue($called); + } + private function createContainer() { $container = new ContainerBuilder(new ParameterBag([ From 48664445ba72c611c528eda58652ddbbb6b04664 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 21 Jun 2019 22:46:43 +0200 Subject: [PATCH 074/106] fix typo --- src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index d32da9541ac5b..8c877f562d38e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -15,7 +15,7 @@ CHANGELOG * [BC Break] When using Messenger, the default transport changed from using Symfony's serializer service to use `PhpSerializer`, which uses PHP's native `serialize()` and `unserialize()` functions. To use the - original serialization method, set the `framework.messenger.defaut_serializer` + original serialization method, set the `framework.messenger.default_serializer` config option to `messenger.transport.symfony_serializer`. Or set the `serializer` option under one specific `transport`. * [BC Break] The `framework.messenger.serializer` config key changed to From 47f9235568d05043b448fb56e86025faa2bd8f98 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 21 Jun 2019 23:08:55 +0200 Subject: [PATCH 075/106] sync `require-dev` and `conflict` constraints --- src/Symfony/Bundle/FrameworkBundle/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index bcfdf01fba719..8182355c16603 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -48,7 +48,7 @@ "symfony/security-http": "~3.4|~4.0", "symfony/serializer": "^4.3", "symfony/stopwatch": "~3.4|~4.0", - "symfony/translation": "~4.2", + "symfony/translation": "~4.3", "symfony/templating": "~3.4|~4.0", "symfony/twig-bundle": "~2.8|~3.2|~4.0", "symfony/validator": "^4.1", From e0d2c58bc2fe79bcc5bf6bd3f644463183fb24f3 Mon Sep 17 00:00:00 2001 From: Alex Nostadt Date: Thu, 20 Jun 2019 21:56:03 +0200 Subject: [PATCH 076/106] Fix link to documentation --- src/Symfony/Component/VarExporter/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarExporter/README.md b/src/Symfony/Component/VarExporter/README.md index 180554ed1a036..bb13960e0d929 100644 --- a/src/Symfony/Component/VarExporter/README.md +++ b/src/Symfony/Component/VarExporter/README.md @@ -31,7 +31,7 @@ It also provides a few improvements over `var_export()`/`serialize()`: Resources --------- - * [Documentation](https://symfony.com/doc/current/components/var_exporter/introduction.html) + * [Documentation](https://symfony.com/doc/current/components/var_exporter.html) * [Contributing](https://symfony.com/doc/current/contributing/index.html) * [Report issues](https://github.com/symfony/symfony/issues) and [send Pull Requests](https://github.com/symfony/symfony/pulls) From 7a4570dcac3335a12547c3299c8ded9101417795 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 22 Jun 2019 22:10:25 +0200 Subject: [PATCH 077/106] fix accessing session bags --- .../HttpFoundation/Session/Session.php | 4 ++- .../Tests/Session/SessionTest.php | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Session.php b/src/Symfony/Component/HttpFoundation/Session/Session.php index 867ceba97f8db..db0b9aeb0b118 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Session.php +++ b/src/Symfony/Component/HttpFoundation/Session/Session.php @@ -253,7 +253,9 @@ public function registerBag(SessionBagInterface $bag) */ public function getBag($name) { - return $this->storage->getBag($name)->getBag(); + $bag = $this->storage->getBag($name); + + return method_exists($bag, 'getBag') ? $bag->getBag() : $bag; } /** diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/SessionTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/SessionTest.php index afa00fc7c3046..acb129984edd1 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/SessionTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/SessionTest.php @@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag; use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\SessionBagProxy; use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; /** @@ -260,4 +261,28 @@ public function testIsEmpty() $flash->get('hello'); $this->assertTrue($this->session->isEmpty()); } + + public function testGetBagWithBagImplementingGetBag() + { + $bag = new AttributeBag(); + $bag->setName('foo'); + + $storage = new MockArraySessionStorage(); + $storage->registerBag($bag); + + $this->assertSame($bag, (new Session($storage))->getBag('foo')); + } + + public function testGetBagWithBagNotImplementingGetBag() + { + $data = []; + + $bag = new AttributeBag(); + $bag->setName('foo'); + + $storage = new MockArraySessionStorage(); + $storage->registerBag(new SessionBagProxy($bag, $data, $usageIndex)); + + $this->assertSame($bag, (new Session($storage))->getBag('foo')); + } } From a030e393c51a26e9246be17f9c05203b25549793 Mon Sep 17 00:00:00 2001 From: Emre Akinci Date: Thu, 20 Jun 2019 10:57:58 +0300 Subject: [PATCH 078/106] Turkish translation added to Form Component --- .../Resources/translations/validators.tr.xlf | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/Symfony/Component/Form/Resources/translations/validators.tr.xlf diff --git a/src/Symfony/Component/Form/Resources/translations/validators.tr.xlf b/src/Symfony/Component/Form/Resources/translations/validators.tr.xlf new file mode 100644 index 0000000000000..70e8541ed909c --- /dev/null +++ b/src/Symfony/Component/Form/Resources/translations/validators.tr.xlf @@ -0,0 +1,19 @@ + + + + + + This form should not contain extra fields. + Form ekstra alanlar içeremez. + + + The uploaded file was too large. Please try to upload a smaller file. + Yüklenen dosya boyutu çok yüksek. Lütfen daha küçük bir dosya yüklemeyi deneyin. + + + The CSRF token is invalid. Please try to resubmit the form. + CSRF fişi geçersiz. Formu tekrar göndermeyi deneyin. + + + + From 196ee5599d9e86bcf0876674b50690b9b10ba351 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 23 Jun 2019 10:10:04 +0200 Subject: [PATCH 079/106] fix typos --- src/Symfony/Component/Dotenv/Tests/DotenvTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php index 7137d83b36f3f..97ae5090c9730 100644 --- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php +++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php @@ -209,7 +209,7 @@ public function testLoadDirectory() $dotenv->load(__DIR__); } - public function testServerSuperglobalIsNotOverriden() + public function testServerSuperglobalIsNotOverridden() { $originalValue = $_SERVER['argc']; @@ -219,7 +219,7 @@ public function testServerSuperglobalIsNotOverriden() $this->assertSame($originalValue, $_SERVER['argc']); } - public function testEnvVarIsNotOverriden() + public function testEnvVarIsNotOverridden() { putenv('TEST_ENV_VAR=original_value'); $_SERVER['TEST_ENV_VAR'] = 'original_value'; @@ -230,7 +230,7 @@ public function testEnvVarIsNotOverriden() $this->assertSame('original_value', getenv('TEST_ENV_VAR')); } - public function testHttpVarIsPartiallyOverriden() + public function testHttpVarIsPartiallyOverridden() { $_SERVER['HTTP_TEST_ENV_VAR'] = 'http_value'; From b58a806340c6cd98a72d6c28b0de1767e4bedf8b Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 23 Jun 2019 10:51:25 +0200 Subject: [PATCH 080/106] fix mirroring directory into parent directory --- src/Symfony/Component/Filesystem/Filesystem.php | 5 +++-- .../Filesystem/Tests/FilesystemTest.php | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index d83b27330c307..dd3d8b471edcc 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -569,14 +569,15 @@ public function mirror($originDir, $targetDir, \Traversable $iterator = null, $o } $this->mkdir($targetDir); - $targetDirInfo = new \SplFileInfo($targetDir); + $filesCreatedWhileMirroring = []; foreach ($iterator as $file) { - if ($file->getPathname() === $targetDir || $file->getRealPath() === $targetDir || 0 === strpos($file->getRealPath(), $targetDirInfo->getRealPath())) { + if ($file->getPathname() === $targetDir || $file->getRealPath() === $targetDir || isset($filesCreatedWhileMirroring[$file->getRealPath()])) { continue; } $target = $targetDir.substr($file->getPathname(), $originDirLen); + $filesCreatedWhileMirroring[$target] = true; if (!$copyOnWindows && is_link($file)) { $this->symlink($file->getLinkTarget(), $target); diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index a1a3ce0e6e444..7fa2ecd3de970 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1362,6 +1362,22 @@ public function testMirrorAvoidCopyingTargetDirectoryIfInSourceDirectory() $this->assertFalse($this->filesystem->exists($targetPath.'target')); } + public function testMirrorFromSubdirectoryInToParentDirectory() + { + $targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR; + $sourcePath = $targetPath.'bar'.\DIRECTORY_SEPARATOR; + $file1 = $sourcePath.'file1'; + $file2 = $sourcePath.'file2'; + + $this->filesystem->mkdir($sourcePath); + file_put_contents($file1, 'FILE1'); + file_put_contents($file2, 'FILE2'); + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertFileEquals($file1, $targetPath.'file1'); + } + /** * @dataProvider providePathsForIsAbsolutePath */ From 0d7d1f81bce8af65238804a34dfa45f06955a98b Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 23 Jun 2019 10:51:25 +0200 Subject: [PATCH 081/106] add test to avoid regressions --- .../Filesystem/Tests/FilesystemTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 8f2bde2e36eeb..186b2ef3642d5 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1348,6 +1348,22 @@ public function testMirrorContentsWithSameNameAsSourceOrTargetWithDeleteOption() $this->assertFileNotExists($targetPath.'target'); } + public function testMirrorFromSubdirectoryInToParentDirectory() + { + $targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR; + $sourcePath = $targetPath.'bar'.\DIRECTORY_SEPARATOR; + $file1 = $sourcePath.'file1'; + $file2 = $sourcePath.'file2'; + + $this->filesystem->mkdir($sourcePath); + file_put_contents($file1, 'FILE1'); + file_put_contents($file2, 'FILE2'); + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertFileEquals($file1, $targetPath.'file1'); + } + /** * @dataProvider providePathsForIsAbsolutePath */ From 412411d795d8c264d6b902b95b1db5dba4bfb04d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 23 Jun 2019 19:28:28 +0200 Subject: [PATCH 082/106] [HttpClient] fix dealing with 1xx informational responses --- .../HttpClient/Response/CurlResponse.php | 27 ++++++++++++------- .../HttpClient/Test/Fixtures/web/index.php | 11 ++++++++ .../HttpClient/Test/HttpClientTestCase.php | 9 +++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 14d3f935e0fb7..0c2130241d3b0 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -289,7 +289,19 @@ private static function parseHeaderLine($ch, string $data, array &$info, array & // Regular header line: add it to the list self::addResponseHeaders([substr($data, 0, -2)], $info, $headers); - if (0 === strpos($data, 'HTTP') && 300 <= $info['http_code'] && $info['http_code'] < 400) { + if (0 !== strpos($data, 'HTTP/')) { + if (0 === stripos($data, 'Location:')) { + $location = trim(substr($data, 9, -2)); + } + + return \strlen($data); + } + + if (\function_exists('openssl_x509_read') && $certinfo = curl_getinfo($ch, CURLINFO_CERTINFO)) { + $info['peer_certificate_chain'] = array_map('openssl_x509_read', array_column($certinfo, 'Cert')); + } + + if (300 <= $info['http_code'] && $info['http_code'] < 400) { if (curl_getinfo($ch, CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); } elseif (303 === $info['http_code'] || ('POST' === $info['http_method'] && \in_array($info['http_code'], [301, 302], true))) { @@ -298,15 +310,14 @@ private static function parseHeaderLine($ch, string $data, array &$info, array & } } - if (0 === stripos($data, 'Location:')) { - $location = trim(substr($data, 9, -2)); - } - return \strlen($data); } // End of headers: handle redirects and add to the activity list - $statusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); + if (200 > $statusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE)) { + return \strlen($data); + } + $info['redirect_url'] = null; if (300 <= $statusCode && $statusCode < 400 && null !== $location) { @@ -336,10 +347,6 @@ private static function parseHeaderLine($ch, string $data, array &$info, array & return 0; } - if (\function_exists('openssl_x509_read') && $certinfo = curl_getinfo($ch, CURLINFO_CERTINFO)) { - $info['peer_certificate_chain'] = array_map('openssl_x509_read', array_column($certinfo, 'Cert')); - } - curl_setopt($ch, CURLOPT_PRIVATE, 'content'); } elseif (null !== $info['redirect_url'] && $logger) { $logger->info(sprintf('Redirecting: "%s %s"', $info['http_code'], $info['redirect_url'])); diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index 8d1762913cf50..bc613868f2bf3 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -41,6 +41,17 @@ ob_start('ob_gzhandler'); break; + case '/103': + header('HTTP/1.1 103 Early Hints'); + header('Link: ; rel=preload; as=style', false); + header('Link: ; rel=preload; as=script', false); + echo "HTTP/1.1 200 OK\r\n"; + echo "Date: Fri, 26 May 2017 10:02:11 GMT\r\n"; + echo "Content-Length: 13\r\n"; + echo "\r\n"; + echo 'Here the body'; + exit; + case '/404': header('Content-Type: application/json', true, 404); break; diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index c995bc26fcfba..c0acd55ceaf49 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -721,6 +721,15 @@ public function testQuery() $this->assertSame('/?a=a&b=b', $body['REQUEST_URI']); } + public function testInformationalResponse() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/103'); + + $this->assertSame('Here the body', $response->getContent()); + $this->assertSame(200, $response->getStatusCode()); + } + /** * @requires extension zlib */ From c5c3332400b3d27da42d8a4598bff405405a5bb3 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 24 Jun 2019 10:19:07 +0200 Subject: [PATCH 083/106] [HttpClient] fix timing measurements with NativeHttpClient --- .../Component/HttpClient/NativeHttpClient.php | 15 +++++++-------- .../HttpClient/Response/NativeResponse.php | 6 +++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/HttpClient/NativeHttpClient.php b/src/Symfony/Component/HttpClient/NativeHttpClient.php index 068f3eb7bad31..58c1d3d65ff80 100644 --- a/src/Symfony/Component/HttpClient/NativeHttpClient.php +++ b/src/Symfony/Component/HttpClient/NativeHttpClient.php @@ -98,9 +98,9 @@ public function request(string $method, string $url, array $options = []): Respo 'http_code' => 0, 'redirect_count' => 0, 'start_time' => 0.0, - 'fopen_time' => 0.0, 'connect_time' => 0.0, 'redirect_time' => 0.0, + 'pretransfer_time' => 0.0, 'starttransfer_time' => 0.0, 'total_time' => 0.0, 'namelookup_time' => 0.0, @@ -118,7 +118,7 @@ public function request(string $method, string $url, array $options = []): Respo $onProgress = static function (...$progress) use ($onProgress, &$lastProgress, &$info) { $progressInfo = $info; $progressInfo['url'] = implode('', $info['url']); - unset($progressInfo['fopen_time'], $progressInfo['size_body']); + unset($progressInfo['size_body']); if ($progress && -1 === $progress[0]) { // Response completed @@ -133,14 +133,14 @@ public function request(string $method, string $url, array $options = []): Respo // Always register a notification callback to compute live stats about the response $notification = static function (int $code, int $severity, ?string $msg, int $msgCode, int $dlNow, int $dlSize) use ($onProgress, &$info) { - $now = microtime(true); - $info['total_time'] = $now - $info['start_time']; + $info['total_time'] = microtime(true) - $info['start_time']; if (STREAM_NOTIFY_PROGRESS === $code) { + $info['starttransfer_time'] = $info['starttransfer_time'] ?: $info['total_time']; $info['size_upload'] += $dlNow ? 0 : $info['size_body']; $info['size_download'] = $dlNow; } elseif (STREAM_NOTIFY_CONNECT === $code) { - $info['connect_time'] += $now - $info['fopen_time']; + $info['connect_time'] = $info['total_time']; $info['debug'] .= $info['request_header']; unset($info['request_header']); } else { @@ -310,7 +310,7 @@ private static function dnsResolve(array $url, NativeClientState $multi, array & throw new TransportException(sprintf('Could not resolve host "%s".', $host)); } - $info['namelookup_time'] += microtime(true) - $now; + $info['namelookup_time'] = microtime(true) - ($info['start_time'] ?: $now); $multi->dnsCache[$host] = $ip = $ip[0]; $info['debug'] .= "* Added {$host}:0:{$ip} to DNS cache\n"; } else { @@ -368,10 +368,9 @@ private static function createRedirectResolver(array $options, string $host, ?ar return null; } - $now = microtime(true); $info['url'] = $url; ++$info['redirect_count']; - $info['redirect_time'] = $now - $info['start_time']; + $info['redirect_time'] = microtime(true) - $info['start_time']; // Do like curl and browsers: turn POST to GET on 301, 302 and 303 if (\in_array($info['http_code'], [301, 302, 303], true)) { diff --git a/src/Symfony/Component/HttpClient/Response/NativeResponse.php b/src/Symfony/Component/HttpClient/Response/NativeResponse.php index 3e321ffb978c0..766506479fd71 100644 --- a/src/Symfony/Component/HttpClient/Response/NativeResponse.php +++ b/src/Symfony/Component/HttpClient/Response/NativeResponse.php @@ -80,7 +80,7 @@ public function getInfo(string $type = null) $info = $this->info; $info['url'] = implode('', $info['url']); - unset($info['fopen_time'], $info['size_body'], $info['request_header']); + unset($info['size_body'], $info['request_header']); if (null === $this->buffer) { $this->finalInfo = $info; @@ -128,7 +128,6 @@ private function open(): void $this->info['request_header'] .= implode("\r\n", $context['http']['header'])."\r\n\r\n"; // Send request and follow redirects when needed - $this->info['fopen_time'] = microtime(true); $this->handle = $h = fopen($url, 'r', false, $this->context); self::addResponseHeaders($http_response_header, $this->info, $this->headers, $this->info['debug']); $url = ($this->resolveRedirect)($this->multi, $this->headers['location'][0] ?? null, $this->context); @@ -146,7 +145,7 @@ private function open(): void return; } finally { - $this->info['starttransfer_time'] = $this->info['total_time'] = microtime(true) - $this->info['start_time']; + $this->info['pretransfer_time'] = $this->info['total_time'] = microtime(true) - $this->info['start_time']; restore_error_handler(); } @@ -267,6 +266,7 @@ private static function perform(NativeClientState $multi, array &$responses = nu if (null !== $e || !$remaining || feof($h)) { // Stream completed $info['total_time'] = microtime(true) - $info['start_time']; + $info['starttransfer_time'] = $info['starttransfer_time'] ?: $info['total_time']; if ($onProgress) { try { From afbefe131b45001b4706c5205e52d6062ad79d09 Mon Sep 17 00:00:00 2001 From: Hippolyte Alain Date: Fri, 21 Jun 2019 13:43:07 +0200 Subject: [PATCH 084/106] [Mailgun Mailer] fixed issue when using html body --- .../Bridge/Mailgun/Http/Api/MailgunTransport.php | 2 +- .../Component/Mailer/Tests/TransportTest.php | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php index 9e61ee4dcd3c3..f546537831e85 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php @@ -68,7 +68,7 @@ private function getPayload(Email $email, SmtpEnvelope $envelope): array { $headers = $email->getHeaders(); $html = $email->getHtmlBody(); - if (null !== $html) { + if (null !== $html && \is_resource($html)) { if (stream_get_meta_data($html)['seekable'] ?? false) { rewind($html); } diff --git a/src/Symfony/Component/Mailer/Tests/TransportTest.php b/src/Symfony/Component/Mailer/Tests/TransportTest.php index a12aae4830718..01f25a6aac605 100644 --- a/src/Symfony/Component/Mailer/Tests/TransportTest.php +++ b/src/Symfony/Component/Mailer/Tests/TransportTest.php @@ -168,6 +168,19 @@ public function testFromDsnMailgun() $transport = Transport::fromDsn('api://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun?region=us', $dispatcher, $client, $logger); $transport->send($message); + $message = (new Email())->from('me@me.com')->to('you@you.com')->subject('hello')->html('test'); + $client = $this->createMock(HttpClientInterface::class); + $client->expects($this->once())->method('request')->with('POST', 'https://api.mailgun.net/v3/pa%24s/messages')->willReturn($response); + $transport = Transport::fromDsn('api://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun?region=us', $dispatcher, $client, $logger); + $transport->send($message); + + $stream = fopen('data://text/plain,'.$message->getTextBody(), 'r'); + $message = (new Email())->from('me@me.com')->to('you@you.com')->subject('hello')->html($stream); + $client = $this->createMock(HttpClientInterface::class); + $client->expects($this->once())->method('request')->with('POST', 'https://api.mailgun.net/v3/pa%24s/messages')->willReturn($response); + $transport = Transport::fromDsn('api://'.urlencode('u$er').':'.urlencode('pa$s').'@mailgun?region=us', $dispatcher, $client, $logger); + $transport->send($message); + $this->expectException(LogicException::class); Transport::fromDsn('foo://mailgun'); } From 66c2e8483a80247981b5dae9748966faf4c1ada7 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Mon, 24 Jun 2019 15:34:54 +0100 Subject: [PATCH 085/106] [Messenger] fix retrying handlers using DoctrineTransactionMiddleware --- .../Doctrine/Messenger/DoctrineTransactionMiddleware.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php b/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php index ad0d87b97c6be..62f0bac51dd7b 100644 --- a/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php +++ b/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php @@ -13,9 +13,11 @@ use Doctrine\Common\Persistence\ManagerRegistry; use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Exception\HandlerFailedException; use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException; use Symfony\Component\Messenger\Middleware\MiddlewareInterface; use Symfony\Component\Messenger\Middleware\StackInterface; +use Symfony\Component\Messenger\Stamp\HandledStamp; /** * Wraps all handlers in a single doctrine transaction. @@ -56,6 +58,12 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope } catch (\Throwable $exception) { $entityManager->getConnection()->rollBack(); + if ($exception instanceof HandlerFailedException) { + // Remove all HandledStamp from the envelope so the retry will execute all handlers again. + // When a handler fails, the queries of allegedly successful previous handlers just got rolled back. + throw new HandlerFailedException($exception->getEnvelope()->withoutAll(HandledStamp::class), $exception->getNestedExceptions()); + } + throw $exception; } } From 71eb8cfe99acd34710c81af3ac04660ed1df523f Mon Sep 17 00:00:00 2001 From: Amrouche Hamza Date: Tue, 25 Jun 2019 07:47:15 +0200 Subject: [PATCH 086/106] [Lock] fix missing inherit docs in RedisStore --- src/Symfony/Component/Lock/Store/RedisStore.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Symfony/Component/Lock/Store/RedisStore.php b/src/Symfony/Component/Lock/Store/RedisStore.php index 496ce657782fd..39360de45c47d 100644 --- a/src/Symfony/Component/Lock/Store/RedisStore.php +++ b/src/Symfony/Component/Lock/Store/RedisStore.php @@ -71,6 +71,9 @@ public function save(Key $key) $this->checkNotExpired($key); } + /** + * {@inheritdoc} + */ public function waitAndSave(Key $key) { throw new InvalidArgumentException(sprintf('The store "%s" does not supports blocking locks.', \get_class($this))); From 2ad32df6e052af856ebcd979ef0a2424e50a1180 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 25 Jun 2019 09:45:31 +0200 Subject: [PATCH 087/106] collect called listeners information only once --- .../Debug/TraceableEventDispatcher.php | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php index 752c8aa8293e6..017459723d92d 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php @@ -191,21 +191,18 @@ public function getNotCalledListeners() return []; } + $calledListeners = []; + + if (null !== $this->callStack) { + foreach ($this->callStack as $calledListener) { + $calledListeners[] = $calledListener->getWrappedListener(); + } + } + $notCalled = []; foreach ($allListeners as $eventName => $listeners) { foreach ($listeners as $listener) { - $called = false; - if (null !== $this->callStack) { - foreach ($this->callStack as $calledListener) { - if ($calledListener->getWrappedListener() === $listener) { - $called = true; - - break; - } - } - } - - if (!$called) { + if (!\in_array($listener, $calledListeners, true)) { if (!$listener instanceof WrappedListener) { $listener = new WrappedListener($listener, null, $this->stopwatch, $this); } From 3d37cc98f67134ced307ce5d0a316bc7946a5d6d Mon Sep 17 00:00:00 2001 From: Ben Davies Date: Tue, 25 Jun 2019 10:08:34 +0100 Subject: [PATCH 088/106] revert #30525 due to performance penalty --- .../PropertyInfoCacheExtractor.php | 35 +++++-------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php b/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php index 5731cf445808f..0eb9f63a54856 100644 --- a/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php +++ b/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php @@ -24,13 +24,6 @@ class PropertyInfoCacheExtractor implements PropertyInfoExtractorInterface, Prop { private $propertyInfoExtractor; private $cacheItemPool; - - /** - * A cache of property information, first keyed by the method called and - * then by the serialized method arguments. - * - * @var array - */ private $arrayCache = []; public function __construct(PropertyInfoExtractorInterface $propertyInfoExtractor, CacheItemPoolInterface $cacheItemPool) @@ -110,34 +103,22 @@ private function extract(string $method, array $arguments) } // Calling rawurlencode escapes special characters not allowed in PSR-6's keys - $encodedMethod = rawurlencode($method); - if (\array_key_exists($encodedMethod, $this->arrayCache) && \array_key_exists($serializedArguments, $this->arrayCache[$encodedMethod])) { - return $this->arrayCache[$encodedMethod][$serializedArguments]; + $key = rawurlencode($method.'.'.$serializedArguments); + + if (\array_key_exists($key, $this->arrayCache)) { + return $this->arrayCache[$key]; } - $item = $this->cacheItemPool->getItem($encodedMethod); + $item = $this->cacheItemPool->getItem($key); - $data = $item->get(); if ($item->isHit()) { - $this->arrayCache[$encodedMethod] = $data[$encodedMethod]; - // Only match if the specific arguments have been cached. - if (\array_key_exists($serializedArguments, $data[$encodedMethod])) { - return $this->arrayCache[$encodedMethod][$serializedArguments]; - } - } - - // It's possible that the method has been called, but with different - // arguments, in which case $data will already be initialized. - if (!$data) { - $data = []; + return $this->arrayCache[$key] = $item->get(); } $value = $this->propertyInfoExtractor->{$method}(...$arguments); - $data[$encodedMethod][$serializedArguments] = $value; - $this->arrayCache[$encodedMethod][$serializedArguments] = $value; - $item->set($data); + $item->set($value); $this->cacheItemPool->save($item); - return $this->arrayCache[$encodedMethod][$serializedArguments]; + return $this->arrayCache[$key] = $value; } } From 61ea53d57f3204a0202a9fdaaefeca3e2d5ee2d9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 25 Jun 2019 14:22:47 +0200 Subject: [PATCH 089/106] [Security/Core] Don't use ParagonIE_Sodium_Compat --- .../Security/Core/Encoder/Argon2iPasswordEncoder.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Encoder/Argon2iPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/Argon2iPasswordEncoder.php index 53c016397632d..dae682bf31028 100644 --- a/src/Symfony/Component/Security/Core/Encoder/Argon2iPasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/Argon2iPasswordEncoder.php @@ -26,10 +26,6 @@ public static function isSupported() return true; } - if (class_exists('ParagonIE_Sodium_Compat') && method_exists('ParagonIE_Sodium_Compat', 'crypto_pwhash_is_available')) { - return \ParagonIE_Sodium_Compat::crypto_pwhash_is_available(); - } - return \function_exists('sodium_crypto_pwhash_str') || \extension_loaded('libsodium'); } From 4df2dc5aaae3e3610857f30cb4d323781cdb8cfe Mon Sep 17 00:00:00 2001 From: "nikos.sotiropoulos" Date: Mon, 24 Jun 2019 15:11:42 +0200 Subject: [PATCH 090/106] [Workflow] re-add workflow.definition tag to workflow services --- .../DependencyInjection/FrameworkExtension.php | 4 ++++ .../Tests/DependencyInjection/FrameworkExtensionTest.php | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 1c3cb5311c8ca..a1ab515ae2148 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -652,6 +652,10 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ $definitionDefinition->addArgument($transitions); $definitionDefinition->addArgument($initialMarking); $definitionDefinition->addArgument($metadataStoreDefinition); + $definitionDefinition->addTag('workflow.definition', [ + 'name' => $name, + 'type' => $type, + ]); // Create MarkingStore if (isset($workflow['marking_store']['type'])) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 25b7353523906..fab27d4897502 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -311,6 +311,8 @@ public function testWorkflowLegacy() $workflowDefinition->getArgument(0), 'Places are passed to the workflow definition' ); + + $this->assertSame(['workflow.definition' => [['name' => 'legacy', 'type' => 'state_machine']]], $workflowDefinition->getTags()); } /** From 4fed5d3813ed6c4f726ad69daf21485ce12904dd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 25 Jun 2019 14:18:37 +0200 Subject: [PATCH 091/106] [Security/Core] require libsodium >= 1.0.14 --- .../Security/Core/Encoder/NativePasswordEncoder.php | 4 ++-- .../Security/Core/Encoder/SodiumPasswordEncoder.php | 10 +++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Encoder/NativePasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/NativePasswordEncoder.php index a99d064eeb3e2..94d9f5ca51e6e 100644 --- a/src/Symfony/Component/Security/Core/Encoder/NativePasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/NativePasswordEncoder.php @@ -33,8 +33,8 @@ public function __construct(int $opsLimit = null, int $memLimit = null, int $cos $opsLimit = $opsLimit ?? max(6, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE') ? \SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE : 6); $memLimit = $memLimit ?? max(64 * 1024 * 1024, \defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 1024); - if (2 > $opsLimit) { - throw new \InvalidArgumentException('$opsLimit must be 2 or greater.'); + if (3 > $opsLimit) { + throw new \InvalidArgumentException('$opsLimit must be 3 or greater.'); } if (10 * 1024 > $memLimit) { diff --git a/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php index 7c6ae62f6359c..01b8b95c8b8f5 100644 --- a/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php @@ -37,8 +37,8 @@ public function __construct(int $opsLimit = null, int $memLimit = null) $this->opsLimit = $opsLimit ?? max(6, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE') ? \SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE : 6); $this->memLimit = $memLimit ?? max(64 * 1024 * 1024, \defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 2014); - if (2 > $this->opsLimit) { - throw new \InvalidArgumentException('$opsLimit must be 2 or greater.'); + if (3 > $this->opsLimit) { + throw new \InvalidArgumentException('$opsLimit must be 3 or greater.'); } if (10 * 1024 > $this->memLimit) { @@ -48,11 +48,7 @@ public function __construct(int $opsLimit = null, int $memLimit = null) public static function isSupported(): bool { - if (class_exists('ParagonIE_Sodium_Compat') && method_exists('ParagonIE_Sodium_Compat', 'crypto_pwhash_is_available')) { - return \ParagonIE_Sodium_Compat::crypto_pwhash_is_available(); - } - - return \function_exists('sodium_crypto_pwhash_str') || \extension_loaded('libsodium'); + return \function_exists('sodium_crypto_pwhash_str_needs_rehash') || \function_exists('Sodium\crypto_pwhash_str_needs_rehash'); } /** From 7b8ee3ece80a8d428ae6605eebed61edbe01654a Mon Sep 17 00:00:00 2001 From: Tomas Date: Tue, 25 Jun 2019 10:30:09 +0300 Subject: [PATCH 092/106] Fix type error --- .../Doctrine/DataCollector/DoctrineDataCollector.php | 3 +++ .../DataCollector/DoctrineDataCollectorTest.php | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php b/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php index 19decb46e49cf..152c07bf60a91 100644 --- a/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php +++ b/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php @@ -138,6 +138,9 @@ private function sanitizeQuery($connectionName, $query) if (!\is_array($query['params'])) { $query['params'] = [$query['params']]; } + if (!\is_array($query['types'])) { + $query['types'] = []; + } foreach ($query['params'] as $j => $param) { if (isset($query['types'][$j])) { // Transform the param according to the type diff --git a/src/Symfony/Bridge/Doctrine/Tests/DataCollector/DoctrineDataCollectorTest.php b/src/Symfony/Bridge/Doctrine/Tests/DataCollector/DoctrineDataCollectorTest.php index 32b4aa730cad3..a789b7a9793fc 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DataCollector/DoctrineDataCollectorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DataCollector/DoctrineDataCollectorTest.php @@ -102,6 +102,18 @@ public function testCollectQueryWithNoParams() $this->assertTrue($collectedQueries['default'][1]['explainable']); } + public function testCollectQueryWithNoTypes() + { + $queries = [ + ['sql' => 'SET sql_mode=(SELECT REPLACE(@@sql_mode, \'ONLY_FULL_GROUP_BY\', \'\'))', 'params' => [], 'types' => null, 'executionMS' => 1], + ]; + $c = $this->createCollector($queries); + $c->collect(new Request(), new Response()); + + $collectedQueries = $c->getQueries(); + $this->assertSame([], $collectedQueries['default'][0]['types']); + } + public function testReset() { $queries = [ From 9e6f4b2122914d8175d846fc18a4b9a79d65a4ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 25 Jun 2019 17:43:39 +0200 Subject: [PATCH 093/106] [FrameworkBundle] Fix calling Client::getProfile() before sending a request --- src/Symfony/Bundle/FrameworkBundle/Client.php | 2 +- .../FrameworkBundle/Tests/Functional/ProfilerTest.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Client.php b/src/Symfony/Bundle/FrameworkBundle/Client.php index 6473f97584f39..6c75b5ab14029 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Client.php @@ -66,7 +66,7 @@ public function getKernel() */ public function getProfile() { - if (!$this->kernel->getContainer()->has('profiler')) { + if (null === $this->response || !$this->kernel->getContainer()->has('profiler')) { return false; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php index c5252c0d5892e..2768b59a1c3f5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ProfilerTest.php @@ -28,9 +28,9 @@ public function testProfilerIsDisabled($insulate) // enable the profiler for the next request $client->enableProfiler(); - $crawler = $client->request('GET', '/profiler'); - $profile = $client->getProfile(); - $this->assertInternalType('object', $profile); + $this->assertFalse($client->getProfile()); + $client->request('GET', '/profiler'); + $this->assertInternalType('object', $client->getProfile()); $client->request('GET', '/profiler'); $this->assertFalse($client->getProfile()); From 6a2f4dc67ab6e1a92bf68b65bc1b8746b842a6c7 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Mon, 24 Jun 2019 03:47:45 +0100 Subject: [PATCH 094/106] Extract unrecoverable exception to interface --- .../DelayedMessageHandlingException.php | 2 +- .../MessageDecodingFailedException.php | 2 +- .../NoHandlerForMessageException.php | 2 +- .../Exception/UnknownSenderException.php | 2 +- .../UnrecoverableExceptionInterface.php | 26 +++++++++++++++++++ .../UnrecoverableMessageHandlingException.php | 7 ++--- .../Exception/ValidationFailedException.php | 2 +- src/Symfony/Component/Messenger/Worker.php | 4 +-- 8 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 src/Symfony/Component/Messenger/Exception/UnrecoverableExceptionInterface.php diff --git a/src/Symfony/Component/Messenger/Exception/DelayedMessageHandlingException.php b/src/Symfony/Component/Messenger/Exception/DelayedMessageHandlingException.php index 313d6f672c123..4314a4f2fb61b 100644 --- a/src/Symfony/Component/Messenger/Exception/DelayedMessageHandlingException.php +++ b/src/Symfony/Component/Messenger/Exception/DelayedMessageHandlingException.php @@ -17,7 +17,7 @@ * * @author Tobias Nyholm */ -class DelayedMessageHandlingException extends \RuntimeException implements ExceptionInterface +class DelayedMessageHandlingException extends RuntimeException { private $exceptions; diff --git a/src/Symfony/Component/Messenger/Exception/MessageDecodingFailedException.php b/src/Symfony/Component/Messenger/Exception/MessageDecodingFailedException.php index 9e429ecc9b4fe..f908d42b5e9c8 100644 --- a/src/Symfony/Component/Messenger/Exception/MessageDecodingFailedException.php +++ b/src/Symfony/Component/Messenger/Exception/MessageDecodingFailedException.php @@ -16,6 +16,6 @@ * * @experimental in 4.3 */ -class MessageDecodingFailedException extends \InvalidArgumentException implements ExceptionInterface +class MessageDecodingFailedException extends InvalidArgumentException { } diff --git a/src/Symfony/Component/Messenger/Exception/NoHandlerForMessageException.php b/src/Symfony/Component/Messenger/Exception/NoHandlerForMessageException.php index a3fc0fa414ef7..1e8e674d6a366 100644 --- a/src/Symfony/Component/Messenger/Exception/NoHandlerForMessageException.php +++ b/src/Symfony/Component/Messenger/Exception/NoHandlerForMessageException.php @@ -16,6 +16,6 @@ * * @experimental in 4.3 */ -class NoHandlerForMessageException extends \LogicException implements ExceptionInterface +class NoHandlerForMessageException extends LogicException { } diff --git a/src/Symfony/Component/Messenger/Exception/UnknownSenderException.php b/src/Symfony/Component/Messenger/Exception/UnknownSenderException.php index 72fccfa566f90..ec138c1e209b5 100644 --- a/src/Symfony/Component/Messenger/Exception/UnknownSenderException.php +++ b/src/Symfony/Component/Messenger/Exception/UnknownSenderException.php @@ -16,6 +16,6 @@ * * @experimental in 4.3 */ -class UnknownSenderException extends \InvalidArgumentException implements ExceptionInterface +class UnknownSenderException extends InvalidArgumentException { } diff --git a/src/Symfony/Component/Messenger/Exception/UnrecoverableExceptionInterface.php b/src/Symfony/Component/Messenger/Exception/UnrecoverableExceptionInterface.php new file mode 100644 index 0000000000000..d5dd01dbaa191 --- /dev/null +++ b/src/Symfony/Component/Messenger/Exception/UnrecoverableExceptionInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Exception; + +/** + * Marker interface for exceptions to indicate that handling a message will continue to fail. + * + * If something goes wrong while handling a message that's received from a transport + * and the message should not be retried, a handler can throw such an exception. + * + * @author Tobias Schultze + * + * @experimental in 4.3 + */ +interface UnrecoverableExceptionInterface extends \Throwable +{ +} diff --git a/src/Symfony/Component/Messenger/Exception/UnrecoverableMessageHandlingException.php b/src/Symfony/Component/Messenger/Exception/UnrecoverableMessageHandlingException.php index df08e79d8bbf6..3a5e52be21cad 100644 --- a/src/Symfony/Component/Messenger/Exception/UnrecoverableMessageHandlingException.php +++ b/src/Symfony/Component/Messenger/Exception/UnrecoverableMessageHandlingException.php @@ -12,15 +12,12 @@ namespace Symfony\Component\Messenger\Exception; /** - * Thrown while handling a message to indicate that handling will continue to fail. - * - * If something goes wrong while handling a message that's received from a transport - * and the message should not be retried, a handler can throw this exception. + * A concrete implementation of UnrecoverableExceptionInterface that can be used directly. * * @author Frederic Bouchery * * @experimental in 4.3 */ -class UnrecoverableMessageHandlingException extends RuntimeException +class UnrecoverableMessageHandlingException extends RuntimeException implements UnrecoverableExceptionInterface { } diff --git a/src/Symfony/Component/Messenger/Exception/ValidationFailedException.php b/src/Symfony/Component/Messenger/Exception/ValidationFailedException.php index a05a213526464..da87bcd2a08ff 100644 --- a/src/Symfony/Component/Messenger/Exception/ValidationFailedException.php +++ b/src/Symfony/Component/Messenger/Exception/ValidationFailedException.php @@ -18,7 +18,7 @@ * * @experimental in 4.3 */ -class ValidationFailedException extends \RuntimeException implements ExceptionInterface +class ValidationFailedException extends RuntimeException { private $violations; private $violatingMessage; diff --git a/src/Symfony/Component/Messenger/Worker.php b/src/Symfony/Component/Messenger/Worker.php index 65fa17b5b32b6..a51cd3506fe50 100644 --- a/src/Symfony/Component/Messenger/Worker.php +++ b/src/Symfony/Component/Messenger/Worker.php @@ -17,7 +17,7 @@ use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent; use Symfony\Component\Messenger\Event\WorkerStoppedEvent; use Symfony\Component\Messenger\Exception\HandlerFailedException; -use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException; +use Symfony\Component\Messenger\Exception\UnrecoverableExceptionInterface; use Symfony\Component\Messenger\Retry\RetryStrategyInterface; use Symfony\Component\Messenger\Stamp\DelayStamp; use Symfony\Component\Messenger\Stamp\ReceivedStamp; @@ -191,7 +191,7 @@ private function dispatchEvent($event) private function shouldRetry(\Throwable $e, Envelope $envelope, RetryStrategyInterface $retryStrategy): bool { - if ($e instanceof UnrecoverableMessageHandlingException) { + if ($e instanceof UnrecoverableExceptionInterface) { return false; } From 3cd795fddeb3466f7be195ffd6108577aa639fdf Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 26 Jun 2019 09:55:28 +0200 Subject: [PATCH 095/106] fixed CS --- .../Cache/Tests/Adapter/SimpleCacheAdapterTest.php | 2 +- .../Messenger/Tests/Transport/Doctrine/ConnectionTest.php | 6 +++--- .../Component/Messenger/Transport/Doctrine/Connection.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php index 788fe59d93127..8097e49cfdaed 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php @@ -12,8 +12,8 @@ namespace Symfony\Component\Cache\Tests\Adapter; use Symfony\Component\Cache\Adapter\SimpleCacheAdapter; -use Symfony\Component\Cache\Simple\FilesystemCache; use Symfony\Component\Cache\Simple\ArrayCache; +use Symfony\Component\Cache\Simple\FilesystemCache; /** * @group time-sensitive diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php index d1cc7ef0c2a15..83708c5085a75 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php @@ -240,7 +240,7 @@ public function testFind() $stmt = $this->getStatementMock([ 'id' => $id, 'body' => '{"message":"Hi"}', - 'headers' => \json_encode(['type' => DummyMessage::class]), + 'headers' => json_encode(['type' => DummyMessage::class]), ]); $driverConnection @@ -274,12 +274,12 @@ public function testFindAll() $message1 = [ 'id' => 1, 'body' => '{"message":"Hi"}', - 'headers' => \json_encode(['type' => DummyMessage::class]), + 'headers' => json_encode(['type' => DummyMessage::class]), ]; $message2 = [ 'id' => 2, 'body' => '{"message":"Hi again"}', - 'headers' => \json_encode(['type' => DummyMessage::class]), + 'headers' => json_encode(['type' => DummyMessage::class]), ]; $stmt = $this->getMockBuilder(Statement::class) diff --git a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php index 8256c7e9c4b3f..74a85bbfbe1e9 100644 --- a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php @@ -240,7 +240,7 @@ public function findAll(int $limit = null): array $data = $this->executeQuery($queryBuilder->getSQL(), $queryBuilder->getParameters())->fetchAll(); - return \array_map(function ($doctrineEnvelope) { + return array_map(function ($doctrineEnvelope) { return $this->decodeEnvelopeHeaders($doctrineEnvelope); }, $data); } @@ -339,7 +339,7 @@ public static function formatDateTime(\DateTimeInterface $dateTime) private function decodeEnvelopeHeaders(array $doctrineEnvelope): array { - $doctrineEnvelope['headers'] = \json_decode($doctrineEnvelope['headers'], true); + $doctrineEnvelope['headers'] = json_decode($doctrineEnvelope['headers'], true); return $doctrineEnvelope; } From d9f0ba386a63a2fb4a25b0e0291c47a257c87979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Thu, 30 May 2019 13:28:51 +0200 Subject: [PATCH 096/106] [PhpUnitBridge] More accurate grouping --- .../PhpUnit/DeprecationErrorHandler.php | 9 +- .../DeprecationErrorHandler/Deprecation.php | 110 +++++++++++------- .../DeprecationTest.php | 4 +- .../DeprecationErrorHandler/default.phpt | 10 +- .../fake_vendor/autoload.php | 2 + .../fake_vendor/composer/autoload_real.php | 17 +++ .../self_on_non_vendor.phpt | 10 +- .../shutdown_deprecations.phpt | 10 +- .../weak_vendors_on_non_vendor.phpt | 11 +- 9 files changed, 114 insertions(+), 69 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 55089e0be11f6..bcbc9d9ab8a2a 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -139,10 +139,13 @@ public function handleError($type, $msg, $file, $line, $context = []) $group = 'unsilenced'; } elseif ($deprecation->isLegacy(self::$utilPrefix)) { $group = 'legacy'; - } elseif (!$deprecation->isSelf()) { - $group = $deprecation->isIndirect() ? 'remaining indirect' : 'remaining direct'; } else { - $group = 'remaining self'; + $group = [ + Deprecation::TYPE_SELF => 'remaining self', + Deprecation::TYPE_DIRECT => 'remaining direct', + Deprecation::TYPE_INDIRECT => 'remaining indirect', + Deprecation::TYPE_UNDETERMINED => 'other', + ][$deprecation->getType()]; } if ($this->getConfiguration()->shouldDisplayStackTrace($msg)) { diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php index ba9e753c7b1d1..b70d7c262e102 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php @@ -18,6 +18,15 @@ */ class Deprecation { + private const PATH_TYPE_VENDOR = 'path_type_vendor'; + private const PATH_TYPE_SELF = 'path_type_internal'; + private const PATH_TYPE_UNDETERMINED = 'path_type_undetermined'; + + public const TYPE_SELF = 'type_self'; + public const TYPE_DIRECT = 'type_direct'; + public const TYPE_INDIRECT = 'type_indirect'; + public const TYPE_UNDETERMINED = 'type_undetermined'; + /** * @var array */ @@ -39,13 +48,21 @@ class Deprecation private $originMethod; /** - * @var bool + * @var string one of the PATH_TYPE_* constants */ - private $self; + private $triggeringFilePathType; /** @var string[] absolute paths to vendor directories */ private static $vendors; + /** + * @var string[] absolute paths to source or tests of the project. This + * excludes cache directories, because it is based on + * autoloading rules and cache systems typically do not use + * those. + */ + private static $internalPaths; + /** * @param string $message * @param string $file @@ -59,7 +76,7 @@ public function __construct($message, array $trace, $file) // No-op } $line = $trace[$i]; - $this->self = !$this->pathOriginatesFromVendor($file); + $this->trigerringFilePathType = $this->getPathType($file); if (isset($line['object']) || isset($line['class'])) { if (isset($line['class']) && 0 === strpos($line['class'], SymfonyTestsListenerFor::class)) { $parsedMsg = unserialize($this->message); @@ -70,8 +87,9 @@ public function __construct($message, array $trace, $file) // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest() // then we need to use the serialized information to determine // if the error has been triggered from vendor code. - $this->self = isset($parsedMsg['triggering_file']) - && $this->pathOriginatesFromVendor($parsedMsg['triggering_file']); + if (isset($parsedMsg['triggering_file'])) { + $this->trigerringFilePathType = $this->getPathType($parsedMsg['triggering_file']); + } return; } @@ -101,14 +119,6 @@ public function originatesFromAnObject() return isset($this->originClass); } - /** - * @return bool - */ - public function isSelf() - { - return $this->self; - } - /** * @return string */ @@ -163,10 +173,16 @@ public function isLegacy($utilPrefix) * Tells whether both the calling package and the called package are vendor * packages. * - * @return bool + * @return string */ - public function isIndirect() + public function getType() { + if (self::PATH_TYPE_SELF === $this->trigerringFilePathType) { + return self::TYPE_SELF; + } + if (self::PATH_TYPE_UNDETERMINED === $this->trigerringFilePathType) { + return self::TYPE_UNDETERMINED; + } $erroringFile = $erroringPackage = null; foreach ($this->trace as $line) { if (\in_array($line['function'], ['require', 'require_once', 'include', 'include_once'], true)) { @@ -179,13 +195,16 @@ public function isIndirect() if ('-' === $file || 'Standard input code' === $file || !realpath($file)) { continue; } - if (!$this->pathOriginatesFromVendor($file)) { - return false; + if (self::PATH_TYPE_SELF === $this->getPathType($file)) { + return self::TYPE_DIRECT; + } + if (self::PATH_TYPE_UNDETERMINED === $this->getPathType($file)) { + return self::TYPE_UNDETERMINED; } if (null !== $erroringFile && null !== $erroringPackage) { $package = $this->getPackage($file); if ('composer' !== $package && $package !== $erroringPackage) { - return true; + return self::TYPE_INDIRECT; } continue; } @@ -193,11 +212,11 @@ public function isIndirect() $erroringPackage = $this->getPackage($file); } - return false; + return self::TYPE_DIRECT; } /** - * pathOriginatesFromVendor() should always be called prior to calling this method. + * getPathType() should always be called prior to calling this method. * * @param string $path * @@ -237,6 +256,15 @@ private static function getVendors() $v = \dirname(\dirname($r->getFileName())); if (file_exists($v.'/composer/installed.json')) { self::$vendors[] = $v; + $loader = require $v.'/autoload.php'; + $paths = self::getSourcePathsFromPrefixes(array_merge($loader->getPrefixes(), $loader->getPrefixesPsr4())); + } + } + } + foreach ($paths as $path) { + foreach (self::$vendors as $vendor) { + if (0 !== strpos($path, $vendor)) { + self::$internalPaths[] = $path; } } } @@ -245,24 +273,41 @@ private static function getVendors() return self::$vendors; } + private static function getSourcePathsFromPrefixes(array $prefixesByNamespace) + { + foreach ($prefixesByNamespace as $prefixes) { + foreach ($prefixes as $prefix) { + if (false !== realpath($prefix)) { + yield realpath($prefix); + } + } + } + } + /** * @param string $path * - * @return bool + * @return string */ - private function pathOriginatesFromVendor($path) + private function getPathType($path) { $realPath = realpath($path); if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) { - return true; + return self::PATH_TYPE_UNDETERMINED; } foreach (self::getVendors() as $vendor) { if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) { - return true; + return self::PATH_TYPE_VENDOR; } } - return false; + foreach (self::$internalPaths as $internalPath) { + if (0 === strpos($realPath, $internalPath)) { + return self::PATH_TYPE_SELF; + } + } + + return self::PATH_TYPE_UNDETERMINED; } /** @@ -281,19 +326,4 @@ public function toString() "\n".str_replace(' '.getcwd().\DIRECTORY_SEPARATOR, ' ', $exception->getTraceAsString()). "\n"; } - - private function getPackageFromLine(array $line) - { - if (!isset($line['file'])) { - return 'internal function'; - } - if (!$this->pathOriginatesFromVendor($line['file'])) { - return 'source code'; - } - try { - return $this->getPackage($line['file']); - } catch (\RuntimeException $e) { - return 'unknown'; - } - } } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php index 92bad71e08498..583cca22f44c4 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php @@ -27,7 +27,7 @@ public function testItCanDetermineTheClassWhereTheDeprecationHappened() public function testItCanTellWhetherItIsInternal() { $deprecation = new Deprecation('💩', $this->debugBacktrace(), __FILE__); - $this->assertTrue($deprecation->isSelf()); + $this->assertSame(Deprecation::TYPE_SELF, $deprecation->getType()); } public function testLegacyTestMethodIsDetectedAsSuch() @@ -46,7 +46,7 @@ public function testItCanBeConvertedToAString() public function testItRulesOutFilesOutsideVendorsAsIndirect() { $deprecation = new Deprecation('💩', $this->debugBacktrace(), __FILE__); - $this->assertFalse($deprecation->isIndirect()); + $this->assertNotSame(Deprecation::TYPE_INDIRECT, $deprecation->getType()); } /** diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt index e9f7bec9664c6..126d23389a516 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt @@ -73,15 +73,13 @@ Unsilenced deprecation notices (3) 1x: unsilenced bar deprecation 1x in FooTestCase::testNonLegacyBar -Remaining self deprecation notices (1) - - 1x: silenced bar deprecation - 1x in FooTestCase::testNonLegacyBar - Legacy deprecation notices (1) -Other deprecation notices (1) +Other deprecation notices (2) 1x: root deprecation + 1x: silenced bar deprecation + 1x in FooTestCase::testNonLegacyBar + I get precedence over any exit statements inside the deprecation error handler. diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php index bf315f2eaa312..3c4471bcbe345 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php @@ -1,3 +1,5 @@ Date: Wed, 26 Jun 2019 10:33:58 +0200 Subject: [PATCH 097/106] [Bridge/PhpUnit] Fix PHP5.5 compat --- .../DeprecationErrorHandler/Deprecation.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php index b70d7c262e102..6d5b39fd54212 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php @@ -18,14 +18,14 @@ */ class Deprecation { - private const PATH_TYPE_VENDOR = 'path_type_vendor'; - private const PATH_TYPE_SELF = 'path_type_internal'; - private const PATH_TYPE_UNDETERMINED = 'path_type_undetermined'; - - public const TYPE_SELF = 'type_self'; - public const TYPE_DIRECT = 'type_direct'; - public const TYPE_INDIRECT = 'type_indirect'; - public const TYPE_UNDETERMINED = 'type_undetermined'; + const PATH_TYPE_VENDOR = 'path_type_vendor'; + const PATH_TYPE_SELF = 'path_type_internal'; + const PATH_TYPE_UNDETERMINED = 'path_type_undetermined'; + + const TYPE_SELF = 'type_self'; + const TYPE_DIRECT = 'type_direct'; + const TYPE_INDIRECT = 'type_indirect'; + const TYPE_UNDETERMINED = 'type_undetermined'; /** * @var array From 88cfcb536d9b30e751ee8cdd4c71b5265ef8a7ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 8 Jun 2019 12:20:20 +0200 Subject: [PATCH 098/106] [PhpunitBridge] Read environment variable from superglobals The Dotenv component has recently been switched to using superglobals instead of putenv(). Let us support both and give priority to superglobals. Closes #31857 --- .../PhpUnit/DeprecationErrorHandler.php | 8 ++++++- .../DeprecationErrorHandler/disabled.phpt | 4 ++-- .../disabled_from_env_superglobal.phpt | 24 +++++++++++++++++++ .../disabled_from_putenv.phpt | 24 +++++++++++++++++++ 4 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_from_env_superglobal.phpt create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_from_putenv.phpt diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 55089e0be11f6..b259337ee1145 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -216,7 +216,13 @@ private function getConfiguration() return $this->configuration; } if (false === $mode = $this->mode) { - $mode = getenv('SYMFONY_DEPRECATIONS_HELPER'); + if (isset($_SERVER['SYMFONY_DEPRECATIONS_HELPER'])) { + $mode = $_SERVER['SYMFONY_DEPRECATIONS_HELPER']; + } elseif (isset($_ENV['SYMFONY_DEPRECATIONS_HELPER'])) { + $mode = $_ENV['SYMFONY_DEPRECATIONS_HELPER']; + } else { + $mode = getenv('SYMFONY_DEPRECATIONS_HELPER'); + } } if ('strict' === $mode) { return $this->configuration = Configuration::inStrictMode(); diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled.phpt index 0115bbd24259a..a55e88d1a8ed5 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled.phpt @@ -1,9 +1,9 @@ --TEST-- -Test DeprecationErrorHandler in weak mode +Test DeprecationErrorHandler in disabled mode --FILE-- +--EXPECTF-- +00 diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_from_putenv.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_from_putenv.phpt new file mode 100644 index 0000000000000..73a67241a495f --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_from_putenv.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test DeprecationErrorHandler in disabled mode (via putenv) +--FILE-- + +--EXPECTF-- +00 From 85ac1a6dd56a37d43344b5739f852abe323bc6bc Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 26 Jun 2019 12:03:25 +0200 Subject: [PATCH 099/106] Bump phpunit-bridge --- composer.json | 2 +- phpunit | 2 +- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 6da4810c5c456..143f73d3c2f35 100644 --- a/composer.json +++ b/composer.json @@ -98,7 +98,7 @@ "ocramius/proxy-manager": "~0.4|~1.0|~2.0", "predis/predis": "~1.0", "egulias/email-validator": "~1.2,>=1.2.8|~2.0", - "symfony/phpunit-bridge": "~3.4|~4.0", + "symfony/phpunit-bridge": "~3.4|~4.0|~5.0", "symfony/security-acl": "~2.8|~3.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0" }, diff --git a/phpunit b/phpunit index 5bbbf0ded1863..dc9e127b78fb7 100755 --- a/phpunit +++ b/phpunit @@ -1,7 +1,7 @@ #!/usr/bin/env php Date: Wed, 26 Jun 2019 13:14:13 +0200 Subject: [PATCH 100/106] Fixed type annotation. --- .../Component/Routing/Generator/UrlGeneratorInterface.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php b/src/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php index f7d37b2564b12..64714d354dba2 100644 --- a/src/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php +++ b/src/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php @@ -71,9 +71,9 @@ interface UrlGeneratorInterface extends RequestContextAwareInterface * * The special parameter _fragment will be used as the document fragment suffixed to the final URL. * - * @param string $name The name of the route - * @param mixed $parameters An array of parameters - * @param int $referenceType The type of reference to be generated (one of the constants) + * @param string $name The name of the route + * @param mixed[] $parameters An array of parameters + * @param int $referenceType The type of reference to be generated (one of the constants) * * @return string The generated URL * From bca4761f372724fe631f5018dd18db0e0a23eb11 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 26 Jun 2019 13:29:01 +0200 Subject: [PATCH 101/106] [PhpUnitBridge] Fix tests --- .../DeprecationTest.php | 6 +++++ .../DeprecationErrorHandler/disabled.phpt | 4 ++-- .../disabled_from_env_superglobal.phpt | 24 ------------------- .../disabled_from_putenv.phpt | 24 ------------------- 4 files changed, 8 insertions(+), 50 deletions(-) delete mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_from_env_superglobal.phpt delete mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_from_putenv.phpt diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php index 583cca22f44c4..0c8708bb35f00 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php @@ -26,6 +26,12 @@ public function testItCanDetermineTheClassWhereTheDeprecationHappened() public function testItCanTellWhetherItIsInternal() { + $r = new \ReflectionClass(Deprecation::class); + + if (dirname($r->getFileName(), 2) !== dirname(__DIR__, 2)) { + $this->markTestSkipped('Test case is not compatible with having the bridge in vendor/'); + } + $deprecation = new Deprecation('💩', $this->debugBacktrace(), __FILE__); $this->assertSame(Deprecation::TYPE_SELF, $deprecation->getType()); } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled.phpt index a55e88d1a8ed5..0115bbd24259a 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled.phpt @@ -1,9 +1,9 @@ --TEST-- -Test DeprecationErrorHandler in disabled mode +Test DeprecationErrorHandler in weak mode --FILE-- ---EXPECTF-- -00 diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_from_putenv.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_from_putenv.phpt deleted file mode 100644 index 73a67241a495f..0000000000000 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_from_putenv.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -Test DeprecationErrorHandler in disabled mode (via putenv) ---FILE-- - ---EXPECTF-- -00 From 4814fd3a4e3c7a668e063e1d4d2cf10e8d1b0d23 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 26 Jun 2019 14:05:53 +0200 Subject: [PATCH 102/106] Revert "bug #31730 [PhpUnitBridge] More accurate grouping (greg0ire)" This reverts commit 64b68d49226b7095aec69f3a2b86b17f3d049e79, reversing changes made to 3cd795fddeb3466f7be195ffd6108577aa639fdf. --- .../PhpUnit/DeprecationErrorHandler.php | 9 +- .../DeprecationErrorHandler/Deprecation.php | 110 +++++++----------- .../DeprecationTest.php | 4 +- .../DeprecationErrorHandler/default.phpt | 10 +- .../fake_vendor/autoload.php | 2 - .../fake_vendor/composer/autoload_real.php | 17 --- .../self_on_non_vendor.phpt | 10 +- .../shutdown_deprecations.phpt | 10 +- .../weak_vendors_on_non_vendor.phpt | 11 +- 9 files changed, 69 insertions(+), 114 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index f9457c937d531..b259337ee1145 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -139,13 +139,10 @@ public function handleError($type, $msg, $file, $line, $context = []) $group = 'unsilenced'; } elseif ($deprecation->isLegacy(self::$utilPrefix)) { $group = 'legacy'; + } elseif (!$deprecation->isSelf()) { + $group = $deprecation->isIndirect() ? 'remaining indirect' : 'remaining direct'; } else { - $group = [ - Deprecation::TYPE_SELF => 'remaining self', - Deprecation::TYPE_DIRECT => 'remaining direct', - Deprecation::TYPE_INDIRECT => 'remaining indirect', - Deprecation::TYPE_UNDETERMINED => 'other', - ][$deprecation->getType()]; + $group = 'remaining self'; } if ($this->getConfiguration()->shouldDisplayStackTrace($msg)) { diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php index 6d5b39fd54212..ba9e753c7b1d1 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php @@ -18,15 +18,6 @@ */ class Deprecation { - const PATH_TYPE_VENDOR = 'path_type_vendor'; - const PATH_TYPE_SELF = 'path_type_internal'; - const PATH_TYPE_UNDETERMINED = 'path_type_undetermined'; - - const TYPE_SELF = 'type_self'; - const TYPE_DIRECT = 'type_direct'; - const TYPE_INDIRECT = 'type_indirect'; - const TYPE_UNDETERMINED = 'type_undetermined'; - /** * @var array */ @@ -48,21 +39,13 @@ class Deprecation private $originMethod; /** - * @var string one of the PATH_TYPE_* constants + * @var bool */ - private $triggeringFilePathType; + private $self; /** @var string[] absolute paths to vendor directories */ private static $vendors; - /** - * @var string[] absolute paths to source or tests of the project. This - * excludes cache directories, because it is based on - * autoloading rules and cache systems typically do not use - * those. - */ - private static $internalPaths; - /** * @param string $message * @param string $file @@ -76,7 +59,7 @@ public function __construct($message, array $trace, $file) // No-op } $line = $trace[$i]; - $this->trigerringFilePathType = $this->getPathType($file); + $this->self = !$this->pathOriginatesFromVendor($file); if (isset($line['object']) || isset($line['class'])) { if (isset($line['class']) && 0 === strpos($line['class'], SymfonyTestsListenerFor::class)) { $parsedMsg = unserialize($this->message); @@ -87,9 +70,8 @@ public function __construct($message, array $trace, $file) // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest() // then we need to use the serialized information to determine // if the error has been triggered from vendor code. - if (isset($parsedMsg['triggering_file'])) { - $this->trigerringFilePathType = $this->getPathType($parsedMsg['triggering_file']); - } + $this->self = isset($parsedMsg['triggering_file']) + && $this->pathOriginatesFromVendor($parsedMsg['triggering_file']); return; } @@ -119,6 +101,14 @@ public function originatesFromAnObject() return isset($this->originClass); } + /** + * @return bool + */ + public function isSelf() + { + return $this->self; + } + /** * @return string */ @@ -173,16 +163,10 @@ public function isLegacy($utilPrefix) * Tells whether both the calling package and the called package are vendor * packages. * - * @return string + * @return bool */ - public function getType() + public function isIndirect() { - if (self::PATH_TYPE_SELF === $this->trigerringFilePathType) { - return self::TYPE_SELF; - } - if (self::PATH_TYPE_UNDETERMINED === $this->trigerringFilePathType) { - return self::TYPE_UNDETERMINED; - } $erroringFile = $erroringPackage = null; foreach ($this->trace as $line) { if (\in_array($line['function'], ['require', 'require_once', 'include', 'include_once'], true)) { @@ -195,16 +179,13 @@ public function getType() if ('-' === $file || 'Standard input code' === $file || !realpath($file)) { continue; } - if (self::PATH_TYPE_SELF === $this->getPathType($file)) { - return self::TYPE_DIRECT; - } - if (self::PATH_TYPE_UNDETERMINED === $this->getPathType($file)) { - return self::TYPE_UNDETERMINED; + if (!$this->pathOriginatesFromVendor($file)) { + return false; } if (null !== $erroringFile && null !== $erroringPackage) { $package = $this->getPackage($file); if ('composer' !== $package && $package !== $erroringPackage) { - return self::TYPE_INDIRECT; + return true; } continue; } @@ -212,11 +193,11 @@ public function getType() $erroringPackage = $this->getPackage($file); } - return self::TYPE_DIRECT; + return false; } /** - * getPathType() should always be called prior to calling this method. + * pathOriginatesFromVendor() should always be called prior to calling this method. * * @param string $path * @@ -256,15 +237,6 @@ private static function getVendors() $v = \dirname(\dirname($r->getFileName())); if (file_exists($v.'/composer/installed.json')) { self::$vendors[] = $v; - $loader = require $v.'/autoload.php'; - $paths = self::getSourcePathsFromPrefixes(array_merge($loader->getPrefixes(), $loader->getPrefixesPsr4())); - } - } - } - foreach ($paths as $path) { - foreach (self::$vendors as $vendor) { - if (0 !== strpos($path, $vendor)) { - self::$internalPaths[] = $path; } } } @@ -273,41 +245,24 @@ private static function getVendors() return self::$vendors; } - private static function getSourcePathsFromPrefixes(array $prefixesByNamespace) - { - foreach ($prefixesByNamespace as $prefixes) { - foreach ($prefixes as $prefix) { - if (false !== realpath($prefix)) { - yield realpath($prefix); - } - } - } - } - /** * @param string $path * - * @return string + * @return bool */ - private function getPathType($path) + private function pathOriginatesFromVendor($path) { $realPath = realpath($path); if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) { - return self::PATH_TYPE_UNDETERMINED; + return true; } foreach (self::getVendors() as $vendor) { if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) { - return self::PATH_TYPE_VENDOR; + return true; } } - foreach (self::$internalPaths as $internalPath) { - if (0 === strpos($realPath, $internalPath)) { - return self::PATH_TYPE_SELF; - } - } - - return self::PATH_TYPE_UNDETERMINED; + return false; } /** @@ -326,4 +281,19 @@ public function toString() "\n".str_replace(' '.getcwd().\DIRECTORY_SEPARATOR, ' ', $exception->getTraceAsString()). "\n"; } + + private function getPackageFromLine(array $line) + { + if (!isset($line['file'])) { + return 'internal function'; + } + if (!$this->pathOriginatesFromVendor($line['file'])) { + return 'source code'; + } + try { + return $this->getPackage($line['file']); + } catch (\RuntimeException $e) { + return 'unknown'; + } + } } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php index 0c8708bb35f00..095f49c5c9fac 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php @@ -33,7 +33,7 @@ public function testItCanTellWhetherItIsInternal() } $deprecation = new Deprecation('💩', $this->debugBacktrace(), __FILE__); - $this->assertSame(Deprecation::TYPE_SELF, $deprecation->getType()); + $this->assertTrue($deprecation->isSelf()); } public function testLegacyTestMethodIsDetectedAsSuch() @@ -52,7 +52,7 @@ public function testItCanBeConvertedToAString() public function testItRulesOutFilesOutsideVendorsAsIndirect() { $deprecation = new Deprecation('💩', $this->debugBacktrace(), __FILE__); - $this->assertNotSame(Deprecation::TYPE_INDIRECT, $deprecation->getType()); + $this->assertFalse($deprecation->isIndirect()); } /** diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt index 126d23389a516..e9f7bec9664c6 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt @@ -73,13 +73,15 @@ Unsilenced deprecation notices (3) 1x: unsilenced bar deprecation 1x in FooTestCase::testNonLegacyBar +Remaining self deprecation notices (1) + + 1x: silenced bar deprecation + 1x in FooTestCase::testNonLegacyBar + Legacy deprecation notices (1) -Other deprecation notices (2) +Other deprecation notices (1) 1x: root deprecation - 1x: silenced bar deprecation - 1x in FooTestCase::testNonLegacyBar - I get precedence over any exit statements inside the deprecation error handler. diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php index 3c4471bcbe345..bf315f2eaa312 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php @@ -1,5 +1,3 @@ Date: Wed, 26 Jun 2019 14:14:14 +0200 Subject: [PATCH 103/106] Revert "Revert "bug #31730 [PhpUnitBridge] More accurate grouping (greg0ire)"" This reverts commit 4814fd3a4e3c7a668e063e1d4d2cf10e8d1b0d23. --- .../PhpUnit/DeprecationErrorHandler.php | 9 +- .../DeprecationErrorHandler/Deprecation.php | 110 +++++++++++------- .../DeprecationTest.php | 4 +- .../DeprecationErrorHandler/default.phpt | 10 +- .../fake_vendor/autoload.php | 2 + .../fake_vendor/composer/autoload_real.php | 17 +++ .../self_on_non_vendor.phpt | 10 +- .../shutdown_deprecations.phpt | 10 +- .../weak_vendors_on_non_vendor.phpt | 11 +- 9 files changed, 114 insertions(+), 69 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index b259337ee1145..f9457c937d531 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -139,10 +139,13 @@ public function handleError($type, $msg, $file, $line, $context = []) $group = 'unsilenced'; } elseif ($deprecation->isLegacy(self::$utilPrefix)) { $group = 'legacy'; - } elseif (!$deprecation->isSelf()) { - $group = $deprecation->isIndirect() ? 'remaining indirect' : 'remaining direct'; } else { - $group = 'remaining self'; + $group = [ + Deprecation::TYPE_SELF => 'remaining self', + Deprecation::TYPE_DIRECT => 'remaining direct', + Deprecation::TYPE_INDIRECT => 'remaining indirect', + Deprecation::TYPE_UNDETERMINED => 'other', + ][$deprecation->getType()]; } if ($this->getConfiguration()->shouldDisplayStackTrace($msg)) { diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php index ba9e753c7b1d1..6d5b39fd54212 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php @@ -18,6 +18,15 @@ */ class Deprecation { + const PATH_TYPE_VENDOR = 'path_type_vendor'; + const PATH_TYPE_SELF = 'path_type_internal'; + const PATH_TYPE_UNDETERMINED = 'path_type_undetermined'; + + const TYPE_SELF = 'type_self'; + const TYPE_DIRECT = 'type_direct'; + const TYPE_INDIRECT = 'type_indirect'; + const TYPE_UNDETERMINED = 'type_undetermined'; + /** * @var array */ @@ -39,13 +48,21 @@ class Deprecation private $originMethod; /** - * @var bool + * @var string one of the PATH_TYPE_* constants */ - private $self; + private $triggeringFilePathType; /** @var string[] absolute paths to vendor directories */ private static $vendors; + /** + * @var string[] absolute paths to source or tests of the project. This + * excludes cache directories, because it is based on + * autoloading rules and cache systems typically do not use + * those. + */ + private static $internalPaths; + /** * @param string $message * @param string $file @@ -59,7 +76,7 @@ public function __construct($message, array $trace, $file) // No-op } $line = $trace[$i]; - $this->self = !$this->pathOriginatesFromVendor($file); + $this->trigerringFilePathType = $this->getPathType($file); if (isset($line['object']) || isset($line['class'])) { if (isset($line['class']) && 0 === strpos($line['class'], SymfonyTestsListenerFor::class)) { $parsedMsg = unserialize($this->message); @@ -70,8 +87,9 @@ public function __construct($message, array $trace, $file) // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest() // then we need to use the serialized information to determine // if the error has been triggered from vendor code. - $this->self = isset($parsedMsg['triggering_file']) - && $this->pathOriginatesFromVendor($parsedMsg['triggering_file']); + if (isset($parsedMsg['triggering_file'])) { + $this->trigerringFilePathType = $this->getPathType($parsedMsg['triggering_file']); + } return; } @@ -101,14 +119,6 @@ public function originatesFromAnObject() return isset($this->originClass); } - /** - * @return bool - */ - public function isSelf() - { - return $this->self; - } - /** * @return string */ @@ -163,10 +173,16 @@ public function isLegacy($utilPrefix) * Tells whether both the calling package and the called package are vendor * packages. * - * @return bool + * @return string */ - public function isIndirect() + public function getType() { + if (self::PATH_TYPE_SELF === $this->trigerringFilePathType) { + return self::TYPE_SELF; + } + if (self::PATH_TYPE_UNDETERMINED === $this->trigerringFilePathType) { + return self::TYPE_UNDETERMINED; + } $erroringFile = $erroringPackage = null; foreach ($this->trace as $line) { if (\in_array($line['function'], ['require', 'require_once', 'include', 'include_once'], true)) { @@ -179,13 +195,16 @@ public function isIndirect() if ('-' === $file || 'Standard input code' === $file || !realpath($file)) { continue; } - if (!$this->pathOriginatesFromVendor($file)) { - return false; + if (self::PATH_TYPE_SELF === $this->getPathType($file)) { + return self::TYPE_DIRECT; + } + if (self::PATH_TYPE_UNDETERMINED === $this->getPathType($file)) { + return self::TYPE_UNDETERMINED; } if (null !== $erroringFile && null !== $erroringPackage) { $package = $this->getPackage($file); if ('composer' !== $package && $package !== $erroringPackage) { - return true; + return self::TYPE_INDIRECT; } continue; } @@ -193,11 +212,11 @@ public function isIndirect() $erroringPackage = $this->getPackage($file); } - return false; + return self::TYPE_DIRECT; } /** - * pathOriginatesFromVendor() should always be called prior to calling this method. + * getPathType() should always be called prior to calling this method. * * @param string $path * @@ -237,6 +256,15 @@ private static function getVendors() $v = \dirname(\dirname($r->getFileName())); if (file_exists($v.'/composer/installed.json')) { self::$vendors[] = $v; + $loader = require $v.'/autoload.php'; + $paths = self::getSourcePathsFromPrefixes(array_merge($loader->getPrefixes(), $loader->getPrefixesPsr4())); + } + } + } + foreach ($paths as $path) { + foreach (self::$vendors as $vendor) { + if (0 !== strpos($path, $vendor)) { + self::$internalPaths[] = $path; } } } @@ -245,24 +273,41 @@ private static function getVendors() return self::$vendors; } + private static function getSourcePathsFromPrefixes(array $prefixesByNamespace) + { + foreach ($prefixesByNamespace as $prefixes) { + foreach ($prefixes as $prefix) { + if (false !== realpath($prefix)) { + yield realpath($prefix); + } + } + } + } + /** * @param string $path * - * @return bool + * @return string */ - private function pathOriginatesFromVendor($path) + private function getPathType($path) { $realPath = realpath($path); if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) { - return true; + return self::PATH_TYPE_UNDETERMINED; } foreach (self::getVendors() as $vendor) { if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) { - return true; + return self::PATH_TYPE_VENDOR; } } - return false; + foreach (self::$internalPaths as $internalPath) { + if (0 === strpos($realPath, $internalPath)) { + return self::PATH_TYPE_SELF; + } + } + + return self::PATH_TYPE_UNDETERMINED; } /** @@ -281,19 +326,4 @@ public function toString() "\n".str_replace(' '.getcwd().\DIRECTORY_SEPARATOR, ' ', $exception->getTraceAsString()). "\n"; } - - private function getPackageFromLine(array $line) - { - if (!isset($line['file'])) { - return 'internal function'; - } - if (!$this->pathOriginatesFromVendor($line['file'])) { - return 'source code'; - } - try { - return $this->getPackage($line['file']); - } catch (\RuntimeException $e) { - return 'unknown'; - } - } } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php index 095f49c5c9fac..0c8708bb35f00 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php @@ -33,7 +33,7 @@ public function testItCanTellWhetherItIsInternal() } $deprecation = new Deprecation('💩', $this->debugBacktrace(), __FILE__); - $this->assertTrue($deprecation->isSelf()); + $this->assertSame(Deprecation::TYPE_SELF, $deprecation->getType()); } public function testLegacyTestMethodIsDetectedAsSuch() @@ -52,7 +52,7 @@ public function testItCanBeConvertedToAString() public function testItRulesOutFilesOutsideVendorsAsIndirect() { $deprecation = new Deprecation('💩', $this->debugBacktrace(), __FILE__); - $this->assertFalse($deprecation->isIndirect()); + $this->assertNotSame(Deprecation::TYPE_INDIRECT, $deprecation->getType()); } /** diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt index e9f7bec9664c6..126d23389a516 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt @@ -73,15 +73,13 @@ Unsilenced deprecation notices (3) 1x: unsilenced bar deprecation 1x in FooTestCase::testNonLegacyBar -Remaining self deprecation notices (1) - - 1x: silenced bar deprecation - 1x in FooTestCase::testNonLegacyBar - Legacy deprecation notices (1) -Other deprecation notices (1) +Other deprecation notices (2) 1x: root deprecation + 1x: silenced bar deprecation + 1x in FooTestCase::testNonLegacyBar + I get precedence over any exit statements inside the deprecation error handler. diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php index bf315f2eaa312..3c4471bcbe345 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/autoload.php @@ -1,3 +1,5 @@ Date: Wed, 26 Jun 2019 14:21:28 +0200 Subject: [PATCH 104/106] Reject phpunit-bridge v5 for now --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 206141f8a7382..897516fd30bca 100644 --- a/composer.json +++ b/composer.json @@ -115,7 +115,7 @@ "psr/http-client": "^1.0", "psr/simple-cache": "^1.0", "egulias/email-validator": "~1.2,>=1.2.8|~2.0", - "symfony/phpunit-bridge": "~3.4|~4.0|~5.0", + "symfony/phpunit-bridge": "~3.4|~4.0", "symfony/security-acl": "~2.8|~3.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0" }, From fde0b1fa9ec1b6c500fc577c6e75dfa41d714ea2 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 26 Jun 2019 16:26:04 +0200 Subject: [PATCH 105/106] updated CHANGELOG for 4.3.2 --- CHANGELOG-4.3.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/CHANGELOG-4.3.md b/CHANGELOG-4.3.md index 29037980b3d30..965e52e7db2a5 100644 --- a/CHANGELOG-4.3.md +++ b/CHANGELOG-4.3.md @@ -7,6 +7,69 @@ in 4.3 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.3.0...v4.3.1 +* 4.3.2 (2019-06-26) + + * bug #31954 [PhpunitBridge] Read environment variable from superglobals (greg0ire) + * bug #32131 [Mailgun Mailer] fixed issue when using html body (alOneh) + * bug #31730 [PhpUnitBridge] More accurate grouping (greg0ire) + * bug #31966 [Messenger] Doctrine Connection find and findAll now correctly decode headers (TimoBakx) + * bug #31972 Add missing rendering of form help block. (alexsegura) + * bug #32141 [HttpClient] fix dealing with 1xx informational responses (nicolas-grekas) + * bug #32138 [Filesystem] fix mirroring directory into parent directory (xabbuh) + * bug #32137 [HttpFoundation] fix accessing session bags (xabbuh) + * bug #32147 [HttpClient] fix timing measurements with NativeHttpClient (nicolas-grekas) + * bug #32165 revert #30525 due to performance penalty (bendavies) + * bug #32164 [EventDispatcher] collect called listeners information only once (xabbuh) + * bug #32173 [FrameworkBundle] Fix calling Client::getProfile() before sending a request (dunglas) + * bug #32163 [DoctrineBridge] Fix type error (norkunas) + * bug #32154 [Messenger] fix retrying handlers using DoctrineTransactionMiddleware (Tobion) + * bug #32169 [Security/Core] require libsodium >= 1.0.14 (nicolas-grekas) + * bug #32170 [Security/Core] Don't use ParagonIE_Sodium_Compat (nicolas-grekas) + * bug #32156 [Workflow] re-add workflow.definition tag to workflow services (nikossvnk) + * bug #32053 [Messenger] No need for retry to require SentStamp (Tobion) + * bug #32083 [HttpClient] fixing passing debug info to progress callback (nicolas-grekas) + * bug #32129 [DebugBundle] fix register ReflectionCaster::unsetClosureFileInfo caster in var cloner service (alekitto) + * bug #32027 [Messenger] Remove DispatchAfterCurrentBusStamp when message is put on internal queue (Nyholm) + * bug #32125 [Form] accept floats for input="string" in NumberType (xabbuh) + * bug #32094 [Validator] Use LogicException for missing Property Access Component in comparison constraints (Lctrs) + * bug #32136 [FrameworkBundle] sync `require-dev` and `conflict` constraints (xabbuh) + * bug #32123 [Form] fix translation domain (xabbuh) + * bug #32115 [SecurityBundle] don't validate IP addresses from env var placeholders (xabbuh) + * bug #32116 [FrameworkBundle] tag the FileType service as a form type (xabbuh) + * bug #32109 [Messenger] fix delay exchange recreation after disconnect (Tobion) + * bug #32090 [Debug] workaround BC break in PHP 7.3 (nicolas-grekas) + * bug #32076 [Lock] Fix PDO prune not called (jderusse) + * bug #32071 Fix expired lock not cleaned (jderusse) + * bug #32052 [Messenger] fix AMQP delay queue to be per exchange (Tobion) + * bug #32065 [HttpClient] throw DecodingExceptionInterface when toArray() fails because of content-type error (nicolas-grekas) + * bug #32057 [HttpFoundation] Fix SA/phpdoc JsonResponse (ro0NL) + * bug #32040 [DI] Show the right class autowired when providing a non-existing class (Simperfit) + * bug #32035 [Messenger] fix delay delivery for non-fanout exchanges (Tobion) + * bug #32025 SimpleCacheAdapter fails to cache any item if a namespace is used (moufmouf) + * bug #32022 [HttpClient] Don't use CurlHttpClient on Windows when curl.cainfo is not set (nicolas-grekas) + * bug #32037 [Form] validate composite constraints in all groups (xabbuh) + * bug #32007 [Serializer] Handle true and false appropriately in CSV encoder (battye) + * bug #32036 [Messenger] improve logs (Tobion) + * bug #31998 Parameterize Mailgun's region (jderusse) + * bug #32000 [Routing] fix absolute url generation when scheme is not known (Tobion) + * bug #32012 Add statement to fileLink to ignore href code when no fileLink. (bmxmale) + * bug #32024 [VarDumper] fix dumping objects that implement __debugInfo() (nicolas-grekas) + * bug #32014 Do not log or call the proxy function when the locale is the same (gmponos) + * bug #32011 [HttpClient] fix closing debug stream prematurely (nicolas-grekas) + * bug #32017 [Contracts] add missing required dependencies (mbessolov) + * bug #31992 Fix sender/recipients in SMTP Envelope (fabpot) + * bug #31999 [PhpunitBridge] Restore php 5.5 compat (greg0ire) + * bug #31991 [EventDispatcher] collect called listeners information only once (xabbuh) + * bug #31988 [TwigBridge] add back possibility to use form themes without translations (xabbuh) + * bug #31982 [HttpClient] fix Psr18Client handling of non-200 response codes (nicolas-grekas) + * bug #31953 [DoctrineBridge] fix handling nested embeddables (xabbuh) + * bug #31962 Fix reporting unsilenced deprecations from insulated tests (nicolas-grekas) + * bug #31936 PropertyInfoLoader should not try to add validation to non-existent property (weaverryan) + * bug #31923 [Serializer] Fix DataUriNormalizer deprecation (MIME type guesser is optional) (ogizanagi) + * bug #31928 [FrameworkBundle] avoid service id conflicts with Swiftmailer (xabbuh) + * bug #31925 [Form] fix usage of legacy TranslatorInterface (nicolas-grekas) + * bug #31908 [Validator] fix deprecation layer of ValidatorBuilder (nicolas-grekas) + * 4.3.1 (2019-06-06) * bug #31894 Fix wrong requirements for ocramius/proxy-manager in root composer.json (henrikvolmer) From 6314d4f9bc49789cf8f41012fad14d19d8ae56c4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 26 Jun 2019 16:26:16 +0200 Subject: [PATCH 106/106] updated VERSION for 4.3.2 --- 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 b9edce2354d63..4752759004acf 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -73,12 +73,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '4.3.2-DEV'; + const VERSION = '4.3.2'; const VERSION_ID = 40302; const MAJOR_VERSION = 4; const MINOR_VERSION = 3; const RELEASE_VERSION = 2; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '01/2020'; const END_OF_LIFE = '07/2020';