4495f0d56c3bf8225d59c77768b3d444aba642d9
[yaffs-website] / vendor / symfony / serializer / Mapping / Loader / AnnotationLoader.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\Serializer\Mapping\Loader;
13
14 use Doctrine\Common\Annotations\Reader;
15 use Symfony\Component\Serializer\Annotation\Groups;
16 use Symfony\Component\Serializer\Annotation\MaxDepth;
17 use Symfony\Component\Serializer\Exception\MappingException;
18 use Symfony\Component\Serializer\Mapping\AttributeMetadata;
19 use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
20
21 /**
22  * Annotation loader.
23  *
24  * @author Kévin Dunglas <dunglas@gmail.com>
25  */
26 class AnnotationLoader implements LoaderInterface
27 {
28     /**
29      * @var Reader
30      */
31     private $reader;
32
33     /**
34      * @param Reader $reader
35      */
36     public function __construct(Reader $reader)
37     {
38         $this->reader = $reader;
39     }
40
41     /**
42      * {@inheritdoc}
43      */
44     public function loadClassMetadata(ClassMetadataInterface $classMetadata)
45     {
46         $reflectionClass = $classMetadata->getReflectionClass();
47         $className = $reflectionClass->name;
48         $loaded = false;
49
50         $attributesMetadata = $classMetadata->getAttributesMetadata();
51
52         foreach ($reflectionClass->getProperties() as $property) {
53             if (!isset($attributesMetadata[$property->name])) {
54                 $attributesMetadata[$property->name] = new AttributeMetadata($property->name);
55                 $classMetadata->addAttributeMetadata($attributesMetadata[$property->name]);
56             }
57
58             if ($property->getDeclaringClass()->name === $className) {
59                 foreach ($this->reader->getPropertyAnnotations($property) as $annotation) {
60                     if ($annotation instanceof Groups) {
61                         foreach ($annotation->getGroups() as $group) {
62                             $attributesMetadata[$property->name]->addGroup($group);
63                         }
64                     } elseif ($annotation instanceof MaxDepth) {
65                         $attributesMetadata[$property->name]->setMaxDepth($annotation->getMaxDepth());
66                     }
67
68                     $loaded = true;
69                 }
70             }
71         }
72
73         foreach ($reflectionClass->getMethods() as $method) {
74             if ($method->getDeclaringClass()->name !== $className) {
75                 continue;
76             }
77
78             $accessorOrMutator = preg_match('/^(get|is|has|set)(.+)$/i', $method->name, $matches);
79             if ($accessorOrMutator) {
80                 $attributeName = lcfirst($matches[2]);
81
82                 if (isset($attributesMetadata[$attributeName])) {
83                     $attributeMetadata = $attributesMetadata[$attributeName];
84                 } else {
85                     $attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName);
86                     $classMetadata->addAttributeMetadata($attributeMetadata);
87                 }
88             }
89
90             foreach ($this->reader->getMethodAnnotations($method) as $annotation) {
91                 if ($annotation instanceof Groups) {
92                     if (!$accessorOrMutator) {
93                         throw new MappingException(sprintf('Groups on "%s::%s" cannot be added. Groups can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name));
94                     }
95
96                     foreach ($annotation->getGroups() as $group) {
97                         $attributeMetadata->addGroup($group);
98                     }
99                 } elseif ($annotation instanceof MaxDepth) {
100                     if (!$accessorOrMutator) {
101                         throw new MappingException(sprintf('MaxDepth on "%s::%s" cannot be added. MaxDepth can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name));
102                     }
103
104                     $attributeMetadata->setMaxDepth($annotation->getMaxDepth());
105                 }
106
107                 $loaded = true;
108             }
109         }
110
111         return $loaded;
112     }
113 }