From 83a75f4313ba1d8e03707840e8daac352898f037 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Wed, 5 Sep 2018 20:27:19 -0400 Subject: [PATCH 01/12] Caching missed templates on cache warmup --- src/Symfony/Bundle/TwigBundle/TemplateIterator.php | 2 +- .../Fixtures/templates/Resources/BarBundle/views/base.html.twig | 0 src/Symfony/Bundle/TwigBundle/Tests/TemplateIteratorTest.php | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Bundle/TwigBundle/Tests/Fixtures/templates/Resources/BarBundle/views/base.html.twig diff --git a/src/Symfony/Bundle/TwigBundle/TemplateIterator.php b/src/Symfony/Bundle/TwigBundle/TemplateIterator.php index cc93e27b55..3c6a615382 100644 --- a/src/Symfony/Bundle/TwigBundle/TemplateIterator.php +++ b/src/Symfony/Bundle/TwigBundle/TemplateIterator.php @@ -57,7 +57,7 @@ class TemplateIterator implements \IteratorAggregate $this->templates = array_merge( $this->templates, $this->findTemplatesInDirectory($bundle->getPath().'/Resources/views', $name), - $this->findTemplatesInDirectory($this->rootDir.'/'.$bundle->getName().'/views', $name) + $this->findTemplatesInDirectory($this->rootDir.'/Resources/'.$bundle->getName().'/views', $name) ); } diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Fixtures/templates/Resources/BarBundle/views/base.html.twig b/src/Symfony/Bundle/TwigBundle/Tests/Fixtures/templates/Resources/BarBundle/views/base.html.twig new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Symfony/Bundle/TwigBundle/Tests/TemplateIteratorTest.php b/src/Symfony/Bundle/TwigBundle/Tests/TemplateIteratorTest.php index 636d5796f8..1b2835ccb2 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/TemplateIteratorTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/TemplateIteratorTest.php @@ -31,6 +31,7 @@ class TemplateIteratorTest extends TestCase sort($sorted); $this->assertEquals( array( + '@Bar/base.html.twig', '@Bar/index.html.twig', '@Foo/index.html.twig', 'layout.html.twig', From f405b4d5a0e2a169a5bef8f7bac4f97b50ad431d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 23 Sep 2018 10:13:20 +0200 Subject: [PATCH 02/12] [HttpFoundation] fix hidding warnings from session handlers --- .../Session/Storage/NativeSessionStorage.php | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index a9a54b49dd..1ec5c7ff4e 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -230,29 +230,22 @@ class NativeSessionStorage implements SessionStorageInterface unset($_SESSION[$key]); } - // Register custom error handler to catch a possible failure warning during session write - set_error_handler(function ($errno, $errstr, $errfile, $errline) { - throw new \ErrorException($errstr, $errno, E_WARNING, $errfile, $errline); - }, E_WARNING); + // Register error handler to add information about the current save handler + $previousHandler = set_error_handler(function ($type, $msg, $file, $line) use (&$previousHandler) { + if (E_WARNING === $type && 0 === strpos($msg, 'session_write_close():')) { + $handler = $this->saveHandler instanceof SessionHandlerProxy ? $this->saveHandler->getHandler() : $this->saveHandler; + $msg = sprintf('session_write_close(): Failed to write session data with "%s" handler', \get_class($handler)); + } + + return $previousHandler ? $previousHandler($type, $msg, $file, $line) : false; + }); try { - $e = null; session_write_close(); - } catch (\ErrorException $e) { } finally { restore_error_handler(); $_SESSION = $session; } - if (null !== $e) { - // The default PHP error message is not very helpful, as it does not give any information on the current save handler. - // Therefore, we catch this error and trigger a warning with a better error message - $handler = $this->getSaveHandler(); - if ($handler instanceof SessionHandlerProxy) { - $handler = $handler->getHandler(); - } - - trigger_error(sprintf('session_write_close(): Failed to write session data with %s handler', \get_class($handler)), E_USER_WARNING); - } $this->closed = true; $this->started = false; From b90a3f12a1407f20ee625443350bb929da6de8ce Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Fri, 21 Sep 2018 19:07:33 +0200 Subject: [PATCH 03/12] [Console] Send the right exit code to console.terminate listeners --- src/Symfony/Component/Console/Application.php | 35 +++++++++---- .../Console/Tests/ApplicationTest.php | 50 +++++++++++++++++++ 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index d1a21049ee..240a9ab7a8 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -129,15 +129,7 @@ class Application $this->renderException($e, $output); } - $exitCode = $e->getCode(); - if (is_numeric($exitCode)) { - $exitCode = (int) $exitCode; - if (0 === $exitCode) { - $exitCode = 1; - } - } else { - $exitCode = 1; - } + $exitCode = $this->getExitCodeForThrowable($e); } if ($this->autoExit) { @@ -873,7 +865,8 @@ class Application if ($x !== $event->getException()) { $e = $event->getException(); } - $exitCode = $e->getCode(); + + $exitCode = $this->getExitCodeForThrowable($e); } $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode); @@ -1148,4 +1141,26 @@ class Application $this->add($command); } } + + /** + * Type hint omitted to be PHP5 compatible. + * + * @param \Exception|\Throwable $throwable + * + * @return int + */ + private function getExitCodeForThrowable($throwable) + { + $exitCode = $throwable->getCode(); + if (is_numeric($exitCode)) { + $exitCode = (int) $exitCode; + if (0 === $exitCode) { + $exitCode = 1; + } + } else { + $exitCode = 1; + } + + return $exitCode; + } } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 1664302dcf..8eb01d9f59 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -774,6 +774,31 @@ class ApplicationTest extends TestCase $this->assertSame(4, $exitCode, '->run() returns integer exit code extracted from raised exception'); } + public function testRunDispatchesIntegerExitCode() + { + $passedRightValue = false; + + // We can assume here that some other test asserts that the event is dispatched at all + $dispatcher = new EventDispatcher(); + $self = $this; + $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($self, &$passedRightValue) { + $passedRightValue = (4 === $event->getExitCode()); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('test')->setCode(function (InputInterface $input, OutputInterface $output) { + throw new \Exception('', 4); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'test')); + + $this->assertTrue($passedRightValue, '-> exit code 4 was passed in the console.terminate event'); + } + public function testRunReturnsExitCodeOneForExceptionCodeZero() { $exception = new \Exception('', 0); @@ -789,6 +814,31 @@ class ApplicationTest extends TestCase $this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0'); } + public function testRunDispatchesExitCodeOneForExceptionCodeZero() + { + $passedRightValue = false; + + // We can assume here that some other test asserts that the event is dispatched at all + $dispatcher = new EventDispatcher(); + $self = $this; + $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($self, &$passedRightValue) { + $passedRightValue = (1 === $event->getExitCode()); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('test')->setCode(function (InputInterface $input, OutputInterface $output) { + throw new \Exception(); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'test')); + + $this->assertTrue($passedRightValue, '-> exit code 1 was passed in the console.terminate event'); + } + /** * @expectedException \LogicException * @expectedExceptionMessage An option with shortcut "e" already exists. From 41eb1914f6cd9feff78b180e1102b24d8b716ee5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 23 Sep 2018 16:32:19 +0200 Subject: [PATCH 04/12] [HttpFoundation][Security] forward locale and format to subrequests --- .../Component/HttpFoundation/Request.php | 2 +- .../Fragment/InlineFragmentRenderer.php | 7 +++++++ .../Fragment/InlineFragmentRendererTest.php | 20 +++++++++++++++++++ .../Component/Security/Http/HttpUtils.php | 7 +++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index a29037279a..85b5a53f4f 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1367,7 +1367,7 @@ class Request * * _format request parameter * * $default * - * @param string $default The default format + * @param string|null $default The default format * * @return string The request format */ diff --git a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php index 712248578d..13fc335624 100644 --- a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php +++ b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php @@ -122,6 +122,13 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer $subRequest->setSession($session); } + if ($request->get('_format')) { + $subRequest->attributes->set('_format', $request->get('_format')); + } + if ($request->getDefaultLocale() !== $request->getLocale()) { + $subRequest->setLocale($request->getLocale()); + } + return $subRequest; } diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php index 197a720439..6cd2bf03ca 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php @@ -175,6 +175,26 @@ class InlineFragmentRendererTest extends TestCase $this->assertEquals('Foo', ob_get_clean()); } + public function testLocaleAndFormatAreIsKeptInSubrequest() + { + $expectedSubRequest = Request::create('/'); + $expectedSubRequest->attributes->set('_format', 'foo'); + $expectedSubRequest->setLocale('fr'); + if (Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP)) { + $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1')); + $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1'); + } + $expectedSubRequest->headers->set('forwarded', array('for="127.0.0.1";host="localhost";proto=http')); + $expectedSubRequest->server->set('HTTP_FORWARDED', 'for="127.0.0.1";host="localhost";proto=http'); + + $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest)); + + $request = Request::create('/'); + $request->attributes->set('_format', 'foo'); + $request->setLocale('fr'); + $strategy->render('/', $request); + } + public function testESIHeaderIsKeptInSubrequest() { $expectedSubRequest = Request::create('/'); diff --git a/src/Symfony/Component/Security/Http/HttpUtils.php b/src/Symfony/Component/Security/Http/HttpUtils.php index 60498231a6..b0377bb44f 100644 --- a/src/Symfony/Component/Security/Http/HttpUtils.php +++ b/src/Symfony/Component/Security/Http/HttpUtils.php @@ -91,6 +91,13 @@ class HttpUtils $newRequest->attributes->set(Security::LAST_USERNAME, $request->attributes->get(Security::LAST_USERNAME)); } + if ($request->get('_format')) { + $newRequest->attributes->set('_format', $request->get('_format')); + } + if ($request->getDefaultLocale() !== $request->getLocale()) { + $newRequest->setLocale($request->getLocale()); + } + return $newRequest; } From 3033aaf6fb035b35646d5c279d818d1333470c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 23 Sep 2018 18:44:27 +0200 Subject: [PATCH 05/12] [FWBundle] Fix an error in WebTestCase::createClient's PHPDoc --- src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php index 5708ef716d..9692a138c3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php @@ -23,7 +23,7 @@ abstract class WebTestCase extends KernelTestCase /** * Creates a Client. * - * @param array $options An array of options to pass to the createKernel class + * @param array $options An array of options to pass to the createKernel method * @param array $server An array of server parameters * * @return Client A Client instance From ad500e74ecfff4c30524ee46e4bf172b28477687 Mon Sep 17 00:00:00 2001 From: Laurent Bassin Date: Mon, 24 Sep 2018 10:04:37 +0200 Subject: [PATCH 06/12] [Filesystem] Skip tests on readable file when run with root user --- src/Symfony/Component/Filesystem/Tests/FilesystemTest.php | 8 ++++++++ .../Component/Filesystem/Tests/LockHandlerTest.php | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 20cbdfc123..d24d967502 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -50,6 +50,10 @@ class FilesystemTest extends FilesystemTestCase $this->markTestSkipped('This test cannot run on Windows.'); } + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; @@ -124,6 +128,10 @@ class FilesystemTest extends FilesystemTestCase $this->markTestSkipped('This test cannot run on Windows.'); } + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; diff --git a/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php b/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php index 6390b1f1e6..635570cefd 100644 --- a/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php +++ b/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php @@ -49,6 +49,10 @@ class LockHandlerTest extends TestCase $this->markTestSkipped('This test cannot run on Windows.'); } + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + $lockPath = sys_get_temp_dir().'/'.uniqid('', true); $e = null; $wrongMessage = null; From 34429797b3d659d339648f4a4209e5f4c01507eb Mon Sep 17 00:00:00 2001 From: Laurent Bassin Date: Thu, 20 Sep 2018 16:39:16 +0200 Subject: [PATCH 07/12] [Yaml] Skip parser test with root user --- src/Symfony/Component/Yaml/Tests/ParserTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index c9aff59fcb..6372fe45ee 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -2099,6 +2099,10 @@ YAML; $this->markTestSkipped('chmod is not supported on Windows'); } + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + $file = __DIR__.'/Fixtures/not_readable.yml'; chmod($file, 0200); From 310870a497f8fbf2563f3fb200bcc8e57dcc4e26 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 24 Sep 2018 10:42:32 +0200 Subject: [PATCH 08/12] [WebProfilerBundle] added a note in the README --- src/Symfony/Bundle/WebProfilerBundle/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Symfony/Bundle/WebProfilerBundle/README.md b/src/Symfony/Bundle/WebProfilerBundle/README.md index 03780d5e59..48e6075636 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/README.md +++ b/src/Symfony/Bundle/WebProfilerBundle/README.md @@ -1,6 +1,12 @@ WebProfilerBundle ================= +The Web profiler bundle is a **development tool** that gives detailed +information about the execution of any request. + +**Never** enable it on production servers as it will lead to major security +vulnerabilities in your project. + Resources --------- From 00855895a85dc04db70012a1c8a5ce643db39765 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 23 Sep 2018 09:05:27 +0200 Subject: [PATCH 09/12] [Cache] prevent getting older entries when the version key is evicted --- .../Component/Cache/Traits/AbstractTrait.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/Cache/Traits/AbstractTrait.php b/src/Symfony/Component/Cache/Traits/AbstractTrait.php index ec60fe79c4..87aeba9e7b 100644 --- a/src/Symfony/Component/Cache/Traits/AbstractTrait.php +++ b/src/Symfony/Component/Cache/Traits/AbstractTrait.php @@ -106,14 +106,7 @@ trait AbstractTrait { $this->deferred = array(); if ($cleared = $this->versioningIsEnabled) { - $namespaceVersion = 2; - try { - foreach ($this->doFetch(array('@'.$this->namespace)) as $v) { - $namespaceVersion = 1 + (int) $v; - } - } catch (\Exception $e) { - } - $namespaceVersion .= ':'; + $namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), ':', 5); try { $cleared = $this->doSave(array('@'.$this->namespace => $namespaceVersion), 0); } catch (\Exception $e) { @@ -247,6 +240,10 @@ trait AbstractTrait foreach ($this->doFetch(array('@'.$this->namespace)) as $v) { $this->namespaceVersion = $v; } + if ('1:' === $this->namespaceVersion) { + $this->namespaceVersion = substr_replace(base64_encode(pack('V', time())), ':', 5); + $this->doSave(array('@'.$this->namespace => $this->namespaceVersion), 0); + } } catch (\Exception $e) { } } From 179a081ee38bd134cf3eea89fa71ca2e785f1e52 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 25 Sep 2018 09:16:06 +0200 Subject: [PATCH 10/12] improve docblocks around group sequences --- .../Validator/Constraints/FormValidator.php | 8 +++--- .../GroupSequenceProviderInterface.php | 4 ++- .../Validator/Mapping/ClassMetadata.php | 2 +- .../ContextualValidatorInterface.php | 27 ++++++++----------- .../RecursiveContextualValidator.php | 12 ++++----- .../Validator/ValidatorInterface.php | 27 ++++++++----------- 6 files changed, 36 insertions(+), 44 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php index 21551f36bb..fc6f2abe51 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -211,7 +211,7 @@ class FormValidator extends ConstraintValidator /** * Returns the validation groups of the given form. * - * @return array The validation groups + * @return string|GroupSequence|(string|GroupSequence)[] The validation groups */ private static function getValidationGroups(FormInterface $form) { @@ -246,10 +246,10 @@ class FormValidator extends ConstraintValidator /** * Post-processes the validation groups option for a given form. * - * @param array|callable $groups The validation groups - * @param FormInterface $form The validated form + * @param string|GroupSequence|(string|GroupSequence)[]|callable $groups The validation groups + * @param FormInterface $form The validated form * - * @return array The validation groups + * @return (string|GroupSequence)[] The validation groups */ private static function resolveValidationGroups($groups, FormInterface $form) { diff --git a/src/Symfony/Component/Validator/GroupSequenceProviderInterface.php b/src/Symfony/Component/Validator/GroupSequenceProviderInterface.php index 62e8a5ed0d..5894397da4 100644 --- a/src/Symfony/Component/Validator/GroupSequenceProviderInterface.php +++ b/src/Symfony/Component/Validator/GroupSequenceProviderInterface.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Validator; +use Symfony\Component\Validator\Constraints\GroupSequence; + /** * Defines the interface for a group sequence provider. */ @@ -20,7 +22,7 @@ interface GroupSequenceProviderInterface * Returns which validation groups should be used for a certain state * of the object. * - * @return array An array of validation groups + * @return string[]|GroupSequence An array of validation groups */ public function getGroupSequence(); } diff --git a/src/Symfony/Component/Validator/Mapping/ClassMetadata.php b/src/Symfony/Component/Validator/Mapping/ClassMetadata.php index 26dba4b725..c3a6544ed4 100644 --- a/src/Symfony/Component/Validator/Mapping/ClassMetadata.php +++ b/src/Symfony/Component/Validator/Mapping/ClassMetadata.php @@ -485,7 +485,7 @@ class ClassMetadata extends ElementMetadata implements ClassMetadataInterface /** * Sets the default group sequence for this class. * - * @param array $groupSequence An array of group names + * @param string[]|GroupSequence $groupSequence An array of group names * * @return $this * diff --git a/src/Symfony/Component/Validator/Validator/ContextualValidatorInterface.php b/src/Symfony/Component/Validator/Validator/ContextualValidatorInterface.php index 1cc96c834e..c8b545b54b 100644 --- a/src/Symfony/Component/Validator/Validator/ContextualValidatorInterface.php +++ b/src/Symfony/Component/Validator/Validator/ContextualValidatorInterface.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Validator\Validator; use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\ConstraintViolationListInterface; /** @@ -39,12 +40,9 @@ interface ContextualValidatorInterface * If no constraint is passed, the constraint * {@link \Symfony\Component\Validator\Constraints\Valid} is assumed. * - * @param mixed $value The value to validate - * @param Constraint|Constraint[] $constraints The constraint(s) to validate - * against - * @param array|null $groups The validation groups to - * validate. If none is given, - * "Default" is assumed + * @param mixed $value The value to validate + * @param Constraint|Constraint[] $constraints The constraint(s) to validate against + * @param string|GroupSequence|(string|GroupSequence)[]|null $groups The validation groups to validate. If none is given, "Default" is assumed * * @return $this */ @@ -54,10 +52,9 @@ interface ContextualValidatorInterface * Validates a property of an object against the constraints specified * for this property. * - * @param object $object The object - * @param string $propertyName The name of the validated property - * @param array|null $groups The validation groups to validate. If - * none is given, "Default" is assumed + * @param object $object The object + * @param string $propertyName The name of the validated property + * @param string|GroupSequence|(string|GroupSequence)[]|null $groups The validation groups to validate. If none is given, "Default" is assumed * * @return $this */ @@ -67,12 +64,10 @@ interface ContextualValidatorInterface * Validates a value against the constraints specified for an object's * property. * - * @param object|string $objectOrClass The object or its class name - * @param string $propertyName The name of the property - * @param mixed $value The value to validate against the - * property's constraints - * @param array|null $groups The validation groups to validate. If - * none is given, "Default" is assumed + * @param object|string $objectOrClass The object or its class name + * @param string $propertyName The name of the property + * @param mixed $value The value to validate against the property's constraints + * @param string|GroupSequence|(string|GroupSequence)[]|null $groups The validation groups to validate. If none is given, "Default" is assumed * * @return $this */ diff --git a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php index 033900d103..14456d8c91 100644 --- a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php +++ b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php @@ -275,9 +275,9 @@ class RecursiveContextualValidator implements ContextualValidatorInterface /** * Normalizes the given group or list of groups to an array. * - * @param mixed $groups The groups to normalize + * @param string|GroupSequence|(string|GroupSequence)[] $groups The groups to normalize * - * @return array A group array + * @return (string|GroupSequence)[] A group array */ protected function normalizeGroups($groups) { @@ -298,7 +298,7 @@ class RecursiveContextualValidator implements ContextualValidatorInterface * * @param object $object The object to cascade * @param string $propertyPath The current property path - * @param string[] $groups The validated groups + * @param (string|GroupSequence)[] $groups The validated groups * @param int $traversalStrategy The strategy for traversing the * cascaded object * @param ExecutionContextInterface $context The current execution context @@ -361,7 +361,7 @@ class RecursiveContextualValidator implements ContextualValidatorInterface * * @param iterable $collection The collection * @param string $propertyPath The current property path - * @param string[] $groups The validated groups + * @param (string|GroupSequence)[] $groups The validated groups * @param bool $stopRecursion Whether to disable * recursive iteration. For * backwards compatibility @@ -441,7 +441,7 @@ class RecursiveContextualValidator implements ContextualValidatorInterface * the object * @param string $propertyPath The property path leading * to the object - * @param string[] $groups The groups in which the + * @param (string|GroupSequence)[] $groups The groups in which the * object should be validated * @param string[]|null $cascadedGroups The groups in which * cascaded objects should @@ -630,7 +630,7 @@ class RecursiveContextualValidator implements ContextualValidatorInterface * value * @param string $propertyPath The property path leading * to the value - * @param string[] $groups The groups in which the + * @param (string|GroupSequence)[] $groups The groups in which the * value should be validated * @param string[]|null $cascadedGroups The groups in which * cascaded objects should diff --git a/src/Symfony/Component/Validator/Validator/ValidatorInterface.php b/src/Symfony/Component/Validator/Validator/ValidatorInterface.php index 5bac2e8898..78157465ab 100644 --- a/src/Symfony/Component/Validator/Validator/ValidatorInterface.php +++ b/src/Symfony/Component/Validator/Validator/ValidatorInterface.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Validator\Validator; use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\ConstraintViolationListInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; @@ -29,12 +30,9 @@ interface ValidatorInterface extends MetadataFactoryInterface * If no constraint is passed, the constraint * {@link \Symfony\Component\Validator\Constraints\Valid} is assumed. * - * @param mixed $value The value to validate - * @param Constraint|Constraint[] $constraints The constraint(s) to validate - * against - * @param array|null $groups The validation groups to - * validate. If none is given, - * "Default" is assumed + * @param mixed $value The value to validate + * @param Constraint|Constraint[] $constraints The constraint(s) to validate against + * @param string|GroupSequence|(string|GroupSequence)[]|null $groups The validation groups to validate. If none is given, "Default" is assumed * * @return ConstraintViolationListInterface A list of constraint violations * If the list is empty, validation @@ -46,10 +44,9 @@ interface ValidatorInterface extends MetadataFactoryInterface * Validates a property of an object against the constraints specified * for this property. * - * @param object $object The object - * @param string $propertyName The name of the validated property - * @param array|null $groups The validation groups to validate. If - * none is given, "Default" is assumed + * @param object $object The object + * @param string $propertyName The name of the validated property + * @param string|GroupSequence|(string|GroupSequence)[]|null $groups The validation groups to validate. If none is given, "Default" is assumed * * @return ConstraintViolationListInterface A list of constraint violations * If the list is empty, validation @@ -61,12 +58,10 @@ interface ValidatorInterface extends MetadataFactoryInterface * Validates a value against the constraints specified for an object's * property. * - * @param object|string $objectOrClass The object or its class name - * @param string $propertyName The name of the property - * @param mixed $value The value to validate against the - * property's constraints - * @param array|null $groups The validation groups to validate. If - * none is given, "Default" is assumed + * @param object|string $objectOrClass The object or its class name + * @param string $propertyName The name of the property + * @param mixed $value The value to validate against the property's constraints + * @param string|GroupSequence|(string|GroupSequence)[]|null $groups The validation groups to validate. If none is given, "Default" is assumed * * @return ConstraintViolationListInterface A list of constraint violations * If the list is empty, validation From 42c5a91ddfd1a4d9c8e0d613166a6df30849dea1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 30 Sep 2018 05:33:07 +0200 Subject: [PATCH 11/12] removed useless phpdoc --- src/Symfony/Component/Console/Application.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 240a9ab7a8..fe62e8d860 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -1143,8 +1143,6 @@ class Application } /** - * Type hint omitted to be PHP5 compatible. - * * @param \Exception|\Throwable $throwable * * @return int From 8805cfdf8d4ba6776cfd74e290d8d17b0ae1b62d Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 30 Sep 2018 05:35:36 +0200 Subject: [PATCH 12/12] [Console] simplified code --- src/Symfony/Component/Console/Application.php | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 2e749cfa94..6bad2b5425 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -153,7 +153,17 @@ class Application $renderException($e); - $exitCode = $this->getExitCodeForThrowable($e); + $exitCode = $e->getCode(); + if (is_numeric($exitCode)) { + $exitCode = (int) $exitCode; + if (0 === $exitCode) { + $exitCode = 1; + } + } else { + $exitCode = 1; + } + + return $exitCode; } finally { // if the exception handler changed, keep it // otherwise, unregister $renderException @@ -1212,24 +1222,4 @@ class Application $this->add($command); } } - - /** - * @param \Exception|\Throwable $throwable - * - * @return int - */ - private function getExitCodeForThrowable($throwable) - { - $exitCode = $throwable->getCode(); - if (is_numeric($exitCode)) { - $exitCode = (int) $exitCode; - if (0 === $exitCode) { - $exitCode = 1; - } - } else { - $exitCode = 1; - } - - return $exitCode; - } }