Completed
Push — master ( beec4b...b0a6d2 )
by Philip
08:54
created

AnnotationDriver::loadMetadataForClass()   F

Complexity

Conditions 24
Paths > 20000

Size

Total Lines 125
Code Lines 64

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 50
CRAP Score 30.0251

Importance

Changes 0
Metric Value
dl 0
loc 125
ccs 50
cts 64
cp 0.7813
rs 2
c 0
b 0
f 0
cc 24
eloc 64
nc 125580
nop 1
crap 30.0251

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 100
    public function __construct(Reader $reader, DriverInterface $doctrineDriver)
32
    {
33 100
        $this->reader = $reader;
34 100
        $this->doctrineDriver = $doctrineDriver;
35 100
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40 70
    public function loadMetadataForClass(\ReflectionClass $class)
41
    {
42
        /** @var ClassMetadata $ddrRestClassMetadata */
43 70
        $ddrRestClassMetadata = $this->doctrineDriver->loadMetadataForClass($class);
44 70
        if (null === $ddrRestClassMetadata) {
45
            $ddrRestClassMetadata = new ClassMetadata($class->getName());
46
        }
47
48
        /** @var RootResource $restResourceAnnotation */
49 70
        $restResourceAnnotation = $this->reader->getClassAnnotation($class, RootResource::class);
50 70
        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->service) {
63
                $ddrRestClassMetadata->setService($restResourceAnnotation->service);
64
            }
65
66 66
            if (null !== $restResourceAnnotation->controller) {
67
                $ddrRestClassMetadata->setController($restResourceAnnotation->controller);
68
            }
69
70 66
            $ddrRestClassMetadata->idField = $restResourceAnnotation->idField;
71
72 66
            if (null !== $restResourceAnnotation->methods) {
73 66
                $methods = [];
74 66
                $methodAnnotations = $restResourceAnnotation->methods;
75 66
                foreach ($methodAnnotations as $methodAnnotation) {
76 66
                    $methods[$methodAnnotation->name] = $methodAnnotation;
77
                }
78 66
                $ddrRestClassMetadata->setMethods($methods);
79
            }
80
81 66
            if (null !== $restResourceAnnotation->methods) {
82 66
                $ddrRestClassMetadata->setMethods($restResourceAnnotation->methods);
83
            }
84
        }
85
86 70
        foreach ($class->getProperties() as $reflectionProperty) {
87
88 70
            $propertyMetadata = $ddrRestClassMetadata->getPropertyMetadata($reflectionProperty->getName());
89 70
            if (null === $propertyMetadata) {
90 48
                $propertyMetadata = new PropertyMetadata($class->getName(), $reflectionProperty->getName());
91
            }
92
93
            /** @var Puttable $puttable */
94 70
            if (null !== $puttable = $this->reader->getPropertyAnnotation($reflectionProperty, Puttable::class)) {
95 54
                $propertyMetadata->setPuttable($puttable);
96
            }
97
98
            /** @var Postable $postable */
99 70
            if (null !== $postable = $this->reader->getPropertyAnnotation($reflectionProperty, Postable::class)) {
100 54
                $propertyMetadata->setPostable($postable);
101
            }
102
103
            /** @var Includable $includable */
104 70
            $includable = $this->reader->getPropertyAnnotation($reflectionProperty, Includable::class);
105 70
            if (null !== $includable) {
106 56
                $this->parseIncludable($propertyMetadata, $includable);
107
            }
108
109 70
            $excluded = $this->reader->getPropertyAnnotation($reflectionProperty, Excluded::class);
110 70
            if (null !== $excluded) {
111 48
                $propertyMetadata->setExcluded(true);
112
            }
113
114
            /** @var SubResource $subResourceAnnotation */
115 70
            $subResourceAnnotation = $this->reader->getPropertyAnnotation($reflectionProperty, SubResource::class);
116 70
            if (null !== $subResourceAnnotation) {
117
118 52
                $propertyMetadata->setSubResource(true);
119
120 52
                if (null !== $subResourceAnnotation->path) {
121
                    $propertyMetadata->setSubResourcePath($subResourceAnnotation->path);
122
                }
123
124 52
                if (null !== $subResourceAnnotation->methods) {
125 52
                    $methods = [];
126 52
                    $methodAnnotations = $subResourceAnnotation->methods;
127 52
                    foreach ($methodAnnotations as $methodAnnotation) {
128 52
                        $methods[$methodAnnotation->name] = $methodAnnotation;
129
                    }
130 52
                    $propertyMetadata->setMethods($methods);
131
                }
132
            }
133
134 70
            $ddrRestClassMetadata->addPropertyMetadata($propertyMetadata);
135
        }
136
137 70
        foreach ($class->getMethods() as $reflectionMethod) {
138
            /** @var Virtual $virtualAnnotation */
139 70
            $virtualAnnotation = $this->reader->getMethodAnnotation($reflectionMethod, Virtual::class);
140 70
            if (null !== $virtualAnnotation) {
141
142
                $name = $this->methodToPropertyName($reflectionMethod);
143
144
                $propertyMetadata = $ddrRestClassMetadata->getPropertyMetadata($name);
145
                if (null === $propertyMetadata) {
146
                    $propertyMetadata = new PropertyMetadata($class->getName(), $name);
147
                }
148
                $propertyMetadata->setVirtual(true);
149
150
                /** @var Includable|null $includableAnnotation */
151
                if (null !== $includable = $this->reader->getMethodAnnotation(
152
                        $reflectionMethod,
153
                        Includable::class
154
                    )
155
                ) {
156
                    $this->parseIncludable($propertyMetadata, $includable);
157
                }
158
159 70
                $ddrRestClassMetadata->addPropertyMetadata($propertyMetadata);
160
            }
161
        }
162
163 70
        return $ddrRestClassMetadata;
164
    }
165
166
    private function methodToPropertyName(\ReflectionMethod $reflectionMethod): string
167
    {
168
        $name = $reflectionMethod->getName();
169
        if (0 === strpos($name, 'get')) {
170
            return lcfirst(substr($name, 3));
171
        }
172
173
        if (0 === strpos($name, 'is')) {
174
            return lcfirst(substr($name, 2));
175
        }
176
177
        if (0 === strpos($name, 'has')) {
178
            return lcfirst(substr($name, 3));
179
        }
180
181
        return $name;
182
    }
183
184 56
    public function parseIncludable(PropertyMetadata $propertyMetadata, Includable $includableAnnotation): void
185
    {
186 56
        $paths = $includableAnnotation->paths;
187 56
        if (null === $paths) {
188 52
            $paths = [$propertyMetadata->name];
189
        }
190 56
        $propertyMetadata->setIncludable(true);
191 56
        $propertyMetadata->setIncludablePaths($paths);
192 56
    }
193
}
194