vendor/symfony/validator/Mapping/Loader/AnnotationLoader.php line 32

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Validator\Mapping\Loader;
  11. use Doctrine\Common\Annotations\Reader;
  12. use Symfony\Component\Validator\Constraint;
  13. use Symfony\Component\Validator\Constraints\Callback;
  14. use Symfony\Component\Validator\Constraints\GroupSequence;
  15. use Symfony\Component\Validator\Constraints\GroupSequenceProvider;
  16. use Symfony\Component\Validator\Exception\MappingException;
  17. use Symfony\Component\Validator\Mapping\ClassMetadata;
  18. /**
  19.  * Loads validation metadata using a Doctrine annotation {@link Reader} or using PHP 8 attributes.
  20.  *
  21.  * @author Bernhard Schussek <bschussek@gmail.com>
  22.  * @author Alexander M. Turek <me@derrabus.de>
  23.  */
  24. class AnnotationLoader implements LoaderInterface
  25. {
  26.     protected $reader;
  27.     public function __construct(Reader $reader null)
  28.     {
  29.         $this->reader $reader;
  30.     }
  31.     /**
  32.      * {@inheritdoc}
  33.      */
  34.     public function loadClassMetadata(ClassMetadata $metadata): bool
  35.     {
  36.         $reflClass $metadata->getReflectionClass();
  37.         $className $reflClass->name;
  38.         $success false;
  39.         foreach ($this->getAnnotations($reflClass) as $constraint) {
  40.             if ($constraint instanceof GroupSequence) {
  41.                 $metadata->setGroupSequence($constraint->groups);
  42.             } elseif ($constraint instanceof GroupSequenceProvider) {
  43.                 $metadata->setGroupSequenceProvider(true);
  44.             } elseif ($constraint instanceof Constraint) {
  45.                 $metadata->addConstraint($constraint);
  46.             }
  47.             $success true;
  48.         }
  49.         foreach ($reflClass->getProperties() as $property) {
  50.             if ($property->getDeclaringClass()->name === $className) {
  51.                 foreach ($this->getAnnotations($property) as $constraint) {
  52.                     if ($constraint instanceof Constraint) {
  53.                         $metadata->addPropertyConstraint($property->name$constraint);
  54.                     }
  55.                     $success true;
  56.                 }
  57.             }
  58.         }
  59.         foreach ($reflClass->getMethods() as $method) {
  60.             if ($method->getDeclaringClass()->name === $className) {
  61.                 foreach ($this->getAnnotations($method) as $constraint) {
  62.                     if ($constraint instanceof Callback) {
  63.                         $constraint->callback $method->getName();
  64.                         $metadata->addConstraint($constraint);
  65.                     } elseif ($constraint instanceof Constraint) {
  66.                         if (preg_match('/^(get|is|has)(.+)$/i'$method->name$matches)) {
  67.                             $metadata->addGetterMethodConstraint(lcfirst($matches[2]), $matches[0], $constraint);
  68.                         } else {
  69.                             throw new MappingException(sprintf('The constraint on "%s::%s()" cannot be added. Constraints can only be added on methods beginning with "get", "is" or "has".'$className$method->name));
  70.                         }
  71.                     }
  72.                     $success true;
  73.                 }
  74.             }
  75.         }
  76.         return $success;
  77.     }
  78.     /**
  79.      * @param \ReflectionClass|\ReflectionMethod|\ReflectionProperty $reflection
  80.      */
  81.     private function getAnnotations(object $reflection): iterable
  82.     {
  83.         foreach ($reflection->getAttributes(GroupSequence::class) as $attribute) {
  84.             yield $attribute->newInstance();
  85.         }
  86.         foreach ($reflection->getAttributes(GroupSequenceProvider::class) as $attribute) {
  87.             yield $attribute->newInstance();
  88.         }
  89.         foreach ($reflection->getAttributes(Constraint::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
  90.             yield $attribute->newInstance();
  91.         }
  92.         if (!$this->reader) {
  93.             return;
  94.         }
  95.         if ($reflection instanceof \ReflectionClass) {
  96.             yield from $this->reader->getClassAnnotations($reflection);
  97.         }
  98.         if ($reflection instanceof \ReflectionMethod) {
  99.             yield from $this->reader->getMethodAnnotations($reflection);
  100.         }
  101.         if ($reflection instanceof \ReflectionProperty) {
  102.             yield from $this->reader->getPropertyAnnotations($reflection);
  103.         }
  104.     }
  105. }