AnnotationDriver::methodToPropertyName()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 0
cts 9
cp 0
rs 9.7
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 20
1
<?php
2
namespace Dontdrinkandroot\RestBundle\Metadata\Driver;
3
4
use Doctrine\Common\Annotations\Reader;
5
use Dontdrinkandroot\RestBundle\Metadata\Annotation\Excluded;
6
use Dontdrinkandroot\RestBundle\Metadata\Annotation\Includable;
7
use Dontdrinkandroot\RestBundle\Metadata\Annotation\Postable;
8
use Dontdrinkandroot\RestBundle\Metadata\Annotation\Puttable;
9
use Dontdrinkandroot\RestBundle\Metadata\Annotation\RootResource;
10
use Dontdrinkandroot\RestBundle\Metadata\Annotation\SubResource;
11
use Dontdrinkandroot\RestBundle\Metadata\Annotation\Virtual;
12
use Dontdrinkandroot\RestBundle\Metadata\ClassMetadata;
13
use Dontdrinkandroot\RestBundle\Metadata\PropertyMetadata;
14
use Metadata\Driver\DriverInterface;
15
16
/**
17
 * @author Philip Washington Sorst <[email protected]>
18
 */
19
class AnnotationDriver implements DriverInterface
20
{
21
    /**
22
     * @var Reader
23
     */
24
    private $reader;
25
26
    /**
27
     * @var DriverInterface
28
     */
29
    private $doctrineDriver;
30
31 90
    public function __construct(Reader $reader, DriverInterface $doctrineDriver)
32
    {
33 90
        $this->reader = $reader;
34 90
        $this->doctrineDriver = $doctrineDriver;
35 90
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40 68
    public function loadMetadataForClass(\ReflectionClass $class)
41
    {
42
        /** @var ClassMetadata $ddrRestClassMetadata */
43 68
        $ddrRestClassMetadata = $this->doctrineDriver->loadMetadataForClass($class);
44 68
        if (null === $ddrRestClassMetadata) {
45
            $ddrRestClassMetadata = new ClassMetadata($class->getName());
46
        }
47
48
        /** @var RootResource $restResourceAnnotation */
49 68
        $restResourceAnnotation = $this->reader->getClassAnnotation($class, RootResource::class);
50 68
        if (null !== $restResourceAnnotation) {
51
52 66
            $ddrRestClassMetadata->setRestResource(true);
53
54 66
            if (null !== $restResourceAnnotation->namePrefix) {
55
                $ddrRestClassMetadata->setNamePrefix($restResourceAnnotation->namePrefix);
56
            }
57
58 66
            if (null !== $restResourceAnnotation->pathPrefix) {
59 44
                $ddrRestClassMetadata->setPathPrefix($restResourceAnnotation->pathPrefix);
60
            }
61
62 66
            if (null !== $restResourceAnnotation->controller) {
63
                $ddrRestClassMetadata->setController($restResourceAnnotation->controller);
64
            }
65
66 66
            $ddrRestClassMetadata->idField = $restResourceAnnotation->idField;
67
68 66
            if (null !== $restResourceAnnotation->methods) {
69 66
                $methods = [];
70 66
                $methodAnnotations = $restResourceAnnotation->methods;
71 66
                foreach ($methodAnnotations as $methodAnnotation) {
72 66
                    $methods[$methodAnnotation->name] = $methodAnnotation;
73
                }
74 66
                $ddrRestClassMetadata->setMethods($methods);
75
            }
76
77 66
            if (null !== $restResourceAnnotation->methods) {
78 66
                $ddrRestClassMetadata->setMethods($restResourceAnnotation->methods);
79
            }
80
        }
81
82 68
        foreach ($class->getProperties() as $reflectionProperty) {
83
84 68
            $propertyMetadata = $ddrRestClassMetadata->getPropertyMetadata($reflectionProperty->getName());
85 68
            if (null === $propertyMetadata) {
86 48
                $propertyMetadata = new PropertyMetadata($class->getName(), $reflectionProperty->getName());
87
            }
88
89
            /** @var Puttable $puttable */
90 68
            if (null !== $puttable = $this->reader->getPropertyAnnotation($reflectionProperty, Puttable::class)) {
91 54
                $propertyMetadata->setPuttable($puttable);
92
            }
93
94
            /** @var Postable $postable */
95 68
            if (null !== $postable = $this->reader->getPropertyAnnotation($reflectionProperty, Postable::class)) {
96 54
                $propertyMetadata->setPostable($postable);
97
            }
98
99
            /** @var Includable $includable */
100 68
            $includable = $this->reader->getPropertyAnnotation($reflectionProperty, Includable::class);
101 68
            if (null !== $includable) {
102 56
                $this->parseIncludable($propertyMetadata, $includable);
103
            }
104
105 68
            $excluded = $this->reader->getPropertyAnnotation($reflectionProperty, Excluded::class);
106 68
            if (null !== $excluded) {
107 48
                $propertyMetadata->setExcluded(true);
108
            }
109
110
            /** @var SubResource $subResourceAnnotation */
111 68
            $subResourceAnnotation = $this->reader->getPropertyAnnotation($reflectionProperty, SubResource::class);
112 68
            if (null !== $subResourceAnnotation) {
113
114 52
                $propertyMetadata->setSubResource(true);
115
116 52
                if (null !== $subResourceAnnotation->path) {
117
                    $propertyMetadata->setSubResourcePath($subResourceAnnotation->path);
118
                }
119
120 52
                if (null !== $subResourceAnnotation->methods) {
121 52
                    $methods = [];
122 52
                    $methodAnnotations = $subResourceAnnotation->methods;
123 52
                    foreach ($methodAnnotations as $methodAnnotation) {
124 52
                        $methods[$methodAnnotation->name] = $methodAnnotation;
125
                    }
126 52
                    $propertyMetadata->setMethods($methods);
127
                }
128
            }
129
130 68
            $ddrRestClassMetadata->addPropertyMetadata($propertyMetadata);
131
        }
132
133 68
        foreach ($class->getMethods() as $reflectionMethod) {
134
            /** @var Virtual $virtualAnnotation */
135 68
            $virtualAnnotation = $this->reader->getMethodAnnotation($reflectionMethod, Virtual::class);
136 68
            if (null !== $virtualAnnotation) {
137
138
                $name = $this->methodToPropertyName($reflectionMethod);
139
140
                $propertyMetadata = $ddrRestClassMetadata->getPropertyMetadata($name);
141
                if (null === $propertyMetadata) {
142
                    $propertyMetadata = new PropertyMetadata($class->getName(), $name);
143
                }
144
                $propertyMetadata->setVirtual(true);
145
146
                /** @var Includable|null $includableAnnotation */
147
                if (null !== $includable = $this->reader->getMethodAnnotation(
148
                        $reflectionMethod,
149
                        Includable::class
150
                    )
151
                ) {
152
                    $this->parseIncludable($propertyMetadata, $includable);
153
                }
154
155 68
                $ddrRestClassMetadata->addPropertyMetadata($propertyMetadata);
156
            }
157
        }
158
159 68
        return $ddrRestClassMetadata;
160
    }
161
162
    private function methodToPropertyName(\ReflectionMethod $reflectionMethod): string
163
    {
164
        $name = $reflectionMethod->getName();
165
        if (0 === strpos($name, 'get')) {
166
            return lcfirst(substr($name, 3));
167
        }
168
169
        if (0 === strpos($name, 'is')) {
170
            return lcfirst(substr($name, 2));
171
        }
172
173
        if (0 === strpos($name, 'has')) {
174
            return lcfirst(substr($name, 3));
175
        }
176
177
        return $name;
178
    }
179
180 56
    public function parseIncludable(PropertyMetadata $propertyMetadata, Includable $includableAnnotation): void
181
    {
182 56
        $paths = $includableAnnotation->paths;
183 56
        if (null === $paths) {
184 52
            $paths = [$propertyMetadata->name];
185
        }
186 56
        $propertyMetadata->setIncludable(true);
187 56
        $propertyMetadata->setIncludablePaths($paths);
188 56
    }
189
}
190