Completed
Push — master ( b27094...afbc6d )
by Julien
05:50 queued 01:38
created

AnnotationDriver::getClassMetadataForClassname()   B

Complexity

Conditions 7
Paths 9

Size

Total Lines 67
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 38
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 39
nc 9
nop 1
dl 0
loc 67
ccs 38
cts 38
cp 1
crap 7
rs 7.0237
c 0
b 0
f 0

How to fix   Long Method   

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
3
namespace Mapado\RestClientSdk\Mapping\Driver;
4
5
use Doctrine\Common\Annotations\AnnotationReader;
6
use Doctrine\Common\Annotations\AnnotationRegistry;
7
use Doctrine\Common\Annotations\FileCacheReader;
8
use Doctrine\Common\Annotations\Reader;
9
use Mapado\RestClientSdk\Exception\MappingException;
10
use Mapado\RestClientSdk\Mapping\Annotations;
11
use Mapado\RestClientSdk\Mapping\Attribute;
12
use Mapado\RestClientSdk\Mapping\ClassMetadata;
13
use Mapado\RestClientSdk\Mapping\Relation;
14
15
/**
16
 * Class AnnotationDriver
17
 *
18
 * @author Julien Deniau <[email protected]>
19
 */
20
class AnnotationDriver
21
{
22
    /**
23
     * cachePath
24
     *
25
     * @var string
26
     */
27
    private $cachePath;
28
29
    /**
30
     * debug
31
     *
32
     * @var bool
33
     */
34
    private $debug;
35
36
    /**
37
     * Constructor.
38
     *
39
     * @param string $cachePath
40
     * @param bool   $debug
41
     */
42
    public function __construct($cachePath, $debug = false)
43
    {
44 1
        $this->cachePath = $cachePath;
45 1
        $this->debug = $debug;
46
47 1
        AnnotationRegistry::registerFile(
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\Common\Annotati...egistry::registerFile() has been deprecated: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists') ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

47
        /** @scrutinizer ignore-deprecated */ AnnotationRegistry::registerFile(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
48 1
            __DIR__ . '/../Annotations/AllAnnotations.php'
49
        );
50 1
    }
51
52
    /**
53
     * loadDirectory
54
     *
55
     * @param string $path
56
     *
57
     * @return ClassMetadata[]
58
     *
59
     * @throws MappingException
60
     */
61
    public function loadDirectory($path)
62
    {
63 1
        if (!is_dir($path)) {
64
            throw new MappingException($path . ' is not a valid directory');
65
        }
66
67 1
        $iterator = new \RegexIterator(
68 1
            new \RecursiveIteratorIterator(
69 1
                new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
70 1
                \RecursiveIteratorIterator::LEAVES_ONLY
71
            ),
72 1
            '/^.+\.php$/i',
73 1
            \RecursiveRegexIterator::GET_MATCH
74
        );
75
76 1
        $classes = [];
77 1
        $includedFiles = [];
78
79 1
        foreach ($iterator as $file) {
80 1
            $sourceFile = $file[0];
81 1
            if (!preg_match('(^phar:)i', $sourceFile)) {
82 1
                $sourceFile = realpath($sourceFile);
83
            }
84
85 1
            require_once $sourceFile;
86 1
            $includedFiles[] = $sourceFile;
87
        }
88
89 1
        $declared = get_declared_classes();
90 1
        foreach ($declared as $className) {
91 1
            $rc = new \ReflectionClass($className);
92 1
            $sourceFile = $rc->getFileName();
93 1
            if (in_array($sourceFile, $includedFiles)) {
94 1
                $classes[] = $className;
95
            }
96
        }
97
98 1
        $mapping = [];
99 1
        foreach ($classes as $class) {
100 1
            if ($metadata = $this->getClassMetadataForClassname($class)) {
101 1
                $mapping[] = $metadata;
102
            }
103
        }
104
105 1
        return $mapping;
106
    }
107
108
    /**
109
     * loadClassname
110
     *
111
     * @param string $classname
112
     *
113
     * @return ClassMetadata[]
114
     */
115
    public function loadClassname($classname)
116
    {
117 1
        $metadata = $this->getClassMetadataForClassname($classname);
118
119 1
        return $metadata ? [$metadata] : [];
120
    }
121
122
    /**
123
     * getClassMetadataForClassname
124
     *
125
     * @param string $classname
126
     *
127
     * @return ClassMetadata|null
128
     */
129
    private function getClassMetadataForClassname($classname)
130
    {
131 1
        $reader = new FileCacheReader(
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\Common\Annotations\FileCacheReader has been deprecated: the FileCacheReader is deprecated and will be removed in version 2.0.0 of doctrine/annotations. Please use the {@see \Doctrine\Common\Annotations\CachedReader} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

131
        $reader = /** @scrutinizer ignore-deprecated */ new FileCacheReader(
Loading history...
132 1
            new AnnotationReader(),
133 1
            $this->cachePath,
134 1
            $this->debug
135
        );
136
137 1
        $reflClass = new \ReflectionClass($classname);
138
        /** @var Annotations\Entity */
139 1
        $classAnnotation = $reader->getClassAnnotation($reflClass, Annotations\Entity::class);
140
141 1
        if (!$classAnnotation) {
142 1
            return null;
143
        }
144
145 1
        $attributeList = [];
146 1
        $relationList = [];
147 1
        foreach ($reflClass->getProperties() as $property) {
148
            // manage attributes
149
            /** @var Annotations\Attribute */
150 1
            $propertyAnnotation = $this->getPropertyAnnotation($reader, $property, 'Attribute');
151
152 1
            if ($propertyAnnotation) {
153 1
                $isId = $this->getPropertyAnnotation($reader, $property, 'Id');
154
155 1
                $attributeList[] = new Attribute(
156 1
                    $propertyAnnotation->name,
157 1
                    $property->getName(),
158 1
                    $propertyAnnotation->type,
159 1
                    (bool) $isId
160
                );
161
            } else {
162
                // manage relations
163
                /** @var Annotations\OneToMany */
164 1
                $relation = $this->getPropertyAnnotation($reader, $property, 'OneToMany');
165 1
                if (!$relation) {
166
                    /** @var Annotations\ManyToOne */
167 1
                    $relation = $this->getPropertyAnnotation($reader, $property, 'ManyToOne');
168
                }
169
170 1
                if ($relation) {
171 1
                    $attributeList[] = new Attribute($relation->name, $property->getName());
172
173 1
                    $targetEntity = $relation->targetEntity;
174 1
                    if (false === strpos($targetEntity, '/')) {
175 1
                        $targetEntity = substr($classname, 0, strrpos($classname, '\\') + 1) . $targetEntity;
176
                    }
177
178 1
                    $relationList[] = new Relation(
179 1
                        $relation->name,
180 1
                        $relation->type,
181 1
                        $targetEntity
182
                    );
183
                }
184
            }
185
        }
186
187 1
        $classMetadata = new ClassMetadata(
188 1
            $classAnnotation->key,
189 1
            $classname,
190 1
            $classAnnotation->repository
191
        );
192 1
        $classMetadata->setAttributeList($attributeList);
193 1
        $classMetadata->setRelationList($relationList);
194
195 1
        return $classMetadata;
196
    }
197
198
    /**
199
     * getPropertyAnnotation
200
     *
201
     * @param Reader              $reader
202
     * @param \ReflectionProperty $property
203
     * @param string              $classname
204
     *
205
     * @return null|object
206
     */
207
    private function getPropertyAnnotation(
208
        Reader $reader,
209
        \ReflectionProperty $property,
210
        $classname
211
    ) {
212 1
        return $reader->getPropertyAnnotation(
213 1
            $property,
214 1
            'Mapado\\RestClientSdk\\Mapping\\Annotations\\' . $classname
215
        );
216
    }
217
}
218