diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index 3a520c1b44..26a09fb8f6 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -433,8 +433,6 @@ class Command * This feature should be used only when creating a long process command, * like a daemon. * - * PHP 5.5+ or the proctitle PECL library is required - * * @param string $title The process title * * @return $this diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index 0cac5208c2..345c1968bc 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -403,18 +403,6 @@ class ErrorHandler } $scope = $this->scopedErrors & $type; - if (4 < $numArgs = \func_num_args()) { - $context = $scope ? (func_get_arg(4) ?: []) : []; - } else { - $context = []; - } - - if (isset($context['GLOBALS']) && $scope) { - $e = $context; // Whatever the signature of the method, - unset($e['GLOBALS'], $context); // $context is always a reference in 5.3 - $context = $e; - } - if (false !== strpos($message, "@anonymous\0")) { $logMessage = $this->levels[$type].': '.(new FlattenException())->setMessage($message)->getMessage(); } else { @@ -476,6 +464,8 @@ class ErrorHandler // `return trigger_error($e, E_USER_ERROR);` allows this error handler // to make $e get through the __toString() barrier. + $context = 4 < \func_num_args() ? (func_get_arg(4) ?: []) : []; + foreach ($context as $e) { if ($e instanceof \Throwable && $e->__toString() === $message) { self::$toStringException = $e; diff --git a/src/Symfony/Component/ErrorHandler/ErrorHandler.php b/src/Symfony/Component/ErrorHandler/ErrorHandler.php index e02a8fc45d..bad3d0cfdd 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorHandler.php +++ b/src/Symfony/Component/ErrorHandler/ErrorHandler.php @@ -423,18 +423,6 @@ class ErrorHandler } $scope = $this->scopedErrors & $type; - if (4 < $numArgs = \func_num_args()) { - $context = $scope ? (func_get_arg(4) ?: []) : []; - } else { - $context = []; - } - - if (isset($context['GLOBALS']) && $scope) { - $e = $context; // Whatever the signature of the method, - unset($e['GLOBALS'], $context); // $context is always a reference in 5.3 - $context = $e; - } - if (false !== strpos($message, "@anonymous\0")) { $logMessage = $this->parseAnonymousClass($message); } else { @@ -496,6 +484,8 @@ class ErrorHandler // `return trigger_error($e, E_USER_ERROR);` allows this error handler // to make $e get through the __toString() barrier. + $context = 4 < \func_num_args() ? (func_get_arg(4) ?: []) : []; + foreach ($context as $e) { if ($e instanceof \Throwable && $e->__toString() === $message) { self::$toStringException = $e; diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php b/src/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php index 4674f8b35a..eb09e5a4b2 100644 --- a/src/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php +++ b/src/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php @@ -18,6 +18,7 @@ class EntityParent implements EntityInterfaceA protected $firstName; private $internal; private $data = 'Data'; + private $child; /** * @NotNull @@ -28,4 +29,9 @@ class EntityParent implements EntityInterfaceA { return 'Data'; } + + public function getChild() + { + return $this->child; + } } diff --git a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php index 8eb76ef3f5..48de5820fc 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php @@ -21,6 +21,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\Optional; use Symfony\Component\Validator\Constraints\Required; +use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\ConstraintValidatorFactory; use Symfony\Component\Validator\Context\ExecutionContextFactory; use Symfony\Component\Validator\Mapping\ClassMetadata; @@ -28,6 +29,7 @@ use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; use Symfony\Component\Validator\Tests\Constraints\Fixtures\ChildA; use Symfony\Component\Validator\Tests\Constraints\Fixtures\ChildB; use Symfony\Component\Validator\Tests\Fixtures\Entity; +use Symfony\Component\Validator\Tests\Fixtures\EntityParent; use Symfony\Component\Validator\Tests\Fixtures\EntityWithGroupedConstraintOnMethods; use Symfony\Component\Validator\Validator\RecursiveValidator; use Symfony\Component\Validator\Validator\ValidatorInterface; @@ -144,6 +146,31 @@ class RecursiveValidatorTest extends AbstractTest $this->assertInstanceOf(IsTrue::class, $violations->get(1)->getConstraint()); } + public function testValidConstraintOnGetterReturningNull() + { + $metadata = new ClassMetadata(EntityParent::class); + $metadata->addGetterConstraint('child', new Valid()); + + $this->metadataFactory->addMetadata($metadata); + + $violations = $this->validator->validate(new EntityParent()); + + $this->assertCount(0, $violations); + } + + public function testNotNullConstraintOnGetterReturningNull() + { + $metadata = new ClassMetadata(EntityParent::class); + $metadata->addGetterConstraint('child', new NotNull()); + + $this->metadataFactory->addMetadata($metadata); + + $violations = $this->validator->validate(new EntityParent()); + + $this->assertCount(1, $violations); + $this->assertInstanceOf(NotNull::class, $violations->get(0)->getConstraint()); + } + public function testAllConstraintValidateAllGroupsForNestedConstraints() { $this->metadata->addPropertyConstraint('data', new All(['constraints' => [ diff --git a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php index 1f0dd842ba..fb321ff838 100644 --- a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php +++ b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php @@ -637,6 +637,10 @@ class RecursiveContextualValidator implements ContextualValidatorInterface if ($value instanceof LazyProperty) { $value = $value->getPropertyValue(); + + if (null === $value) { + return; + } } if (\is_array($value)) {