Passed
Push — master ( 58eb35...91e98b )
by Julien
56s
created

AnnotationDriver::getPropertyAnnotation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 7
nc 1
nop 3
crap 1
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 method Doctrine\Common\Annotati...egistry::registerFile() has been deprecated with message: 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')

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

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class 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)) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $metadata is correct as $this->getClassMetadataForClassname($class) (which targets Mapado\RestClientSdk\Map...sMetadataForClassname()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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 with message: 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.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

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