Passed
Push — master ( 7067f6...c51298 )
by Julien
01:15 queued 11s
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
 * @author Julien Deniau <[email protected]>
18
 */
19
class AnnotationDriver
20
{
21
    /**
22
     * cachePath
23
     *
24
     * @var string
25
     * @access private
26
     */
27
    private $cachePath;
28
29
    /**
30
     * debug
31
     *
32
     * @var bool
33
     * @access private
34
     */
35
    private $debug;
36
37
    /**
38
     * Constructor.
39
     *
40
     * @param string $cachePath
41
     * @param bool   $debug
42
     * @access public
43
     */
44
    public function __construct($cachePath, $debug = false)
45
    {
46 1
        $this->cachePath = $cachePath;
47 1
        $this->debug = $debug;
48
49 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

49
        /** @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...
50 1
            __DIR__ . '/../Annotations/AllAnnotations.php'
51
        );
52 1
    }
53
54
    /**
55
     * loadDirectory
56
     *
57
     * @param string $path
58
     * @access public
59
     * @return ClassMetadata[]
60
     * @throws MappingException
61
     */
62
    public function loadDirectory($path)
63
    {
64 1
        if (!is_dir($path)) {
65
            throw new MappingException($path . ' is not a valid directory');
66
        }
67
68 1
        $iterator = new \RegexIterator(
69 1
            new \RecursiveIteratorIterator(
70 1
                new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
71 1
                \RecursiveIteratorIterator::LEAVES_ONLY
72
            ),
73 1
            '/^.+\.php$/i',
74 1
            \RecursiveRegexIterator::GET_MATCH
75
        );
76
77 1
        $classes = [];
78 1
        $includedFiles = [];
79
80 1
        foreach ($iterator as $file) {
81 1
            $sourceFile = $file[0];
82 1
            if (! preg_match('(^phar:)i', $sourceFile)) {
83 1
                $sourceFile = realpath($sourceFile);
84
            }
85
86 1
            require_once $sourceFile;
87 1
            $includedFiles[] = $sourceFile;
88
        }
89
90 1
        $declared = get_declared_classes();
91 1
        foreach ($declared as $className) {
92 1
            $rc = new \ReflectionClass($className);
93 1
            $sourceFile = $rc->getFileName();
94 1
            if (in_array($sourceFile, $includedFiles)) {
95 1
                $classes[] = $className;
96
            }
97
        }
98
99 1
        $mapping = [];
100 1
        foreach ($classes as $class) {
101 1
            if ($metadata = $this->getClassMetadataForClassname($class)) {
102 1
                $mapping[] = $metadata;
103
            }
104
        }
105
106 1
        return $mapping;
107
    }
108
109
    /**
110
     * loadClassname
111
     *
112
     * @param string $classname
113
     * @access public
114
     * @return ClassMetadata[]
115
     */
116
    public function loadClassname($classname)
117
    {
118 1
        $metadata = $this->getClassMetadataForClassname($classname);
119
120 1
        return $metadata ? [$metadata,] : [];
121
    }
122
123
    /**
124
     * getClassMetadataForClassname
125
     *
126
     * @param string $classname
127
     * @access private
128
     * @return ClassMetadata|null
129
     */
130
    private function getClassMetadataForClassname($classname)
131
    {
132 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

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