GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 1c2332...e42a09 )
by Cees-Jan
11s
created

Hydrator::hydrateApplyAnnotations()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 13
Ratio 100 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 13
loc 13
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 2
crap 3
1
<?php declare(strict_types=1);
2
3
namespace ApiClients\Foundation\Hydrator;
4
5
use Doctrine\Common\Annotations\AnnotationReader;
6
use Doctrine\Common\Annotations\CachedReader;
7
use Doctrine\Common\Annotations\Reader;
8
use Doctrine\Common\Cache\Cache;
9
use GeneratedHydrator\Configuration;
10
use ReflectionClass;
11
use RecursiveDirectoryIterator;
12
use RecursiveIteratorIterator;
13
use ApiClients\Foundation\Resource\ResourceInterface;
14
use ApiClients\Foundation\Resource\AbstractResource;
15
use Zend\Hydrator\HydratorInterface;
16
17
class Hydrator
18
{
19
    /**
20
     * @var array
21
     */
22
    protected $options;
23
24
    /**
25
     * @var array
26
     */
27
    protected $hydrators = [];
28
29
    /**
30
     * @var array
31
     */
32
    protected $annotations = [];
33
34
    /**
35
     * @var HandlerInterface[]
36
     */
37
    protected $annotationHandlers = [];
38
39
    /**
40
     * @var Reader
41
     */
42
    protected $annotationReader;
43
44
    /**
45
     * @param array $options
46
     */
47 6
    public function __construct(array $options)
48
    {
49 6
        $this->options = $options;
50
51 6
        $reader = new AnnotationReader();
52 6
        if (isset($this->options[Options::ANNOTATION_CACHE]) &&
53 6
            $this->options[Options::ANNOTATION_CACHE] instanceof Cache
54
        ) {
55 1
            $reader = new CachedReader(
56
                $reader,
57 1
                $this->options[Options::ANNOTATION_CACHE]
58
            );
59
        }
60 6
        $this->annotationReader = $reader;
61
62 6
        $this->setUpAnnotations();
63 6
        $this->addSelfToExtraProperties();
64 6
    }
65
66 6
    protected function setUpAnnotations()
67
    {
68 6
        if (!isset($this->options[Options::ANNOTATIONS])) {
69
            return;
70
        }
71
72 6
        foreach ($this->options[Options::ANNOTATIONS] as $annotationClass => $handler) {
73 6
            $this->annotationHandlers[$annotationClass] = new $handler($this);
74
        }
75 6
    }
76
77 6
    protected function addSelfToExtraProperties()
78
    {
79 6
        $this->options[Options::EXTRA_PROPERTIES]['hydrator'] = $this;
80 6
    }
81
82 2
    public function preheat(string $scanTarget, string $namespace)
83
    {
84 2
        $directory = new RecursiveDirectoryIterator($scanTarget);
85 2
        $directory = new RecursiveIteratorIterator($directory);
86
87 2
        foreach ($directory as $node) {
88 2
            if (!is_file($node->getPathname())) {
89 2
                continue;
90
            }
91
92 2
            $file = substr($node->getPathname(), strlen($scanTarget));
93 2
            $file = ltrim($file, DIRECTORY_SEPARATOR);
94 2
            $file = rtrim($file, '.php');
95
96 2
            $class = $namespace . '\\' . str_replace(DIRECTORY_SEPARATOR, '\\', $file);
97
98 2
            if (!class_exists($class)) {
99
                continue;
100
            }
101
102 2
            if (!is_subclass_of($class, ResourceInterface::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \ApiClients\Foundation\R...esourceInterface::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
103
                continue;
104
            }
105
106 2
            $this->getHydrator($class);
107 2
            $this->annotationReader->getClassAnnotations(new ReflectionClass($class));
108
        }
109 2
    }
110
111
    /**
112
     * @param string $class
113
     * @param array $json
114
     * @return ResourceInterface
115
     */
116 4 View Code Duplication
    public function hydrate(string $class, array $json): ResourceInterface
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
    {
118 4
        $fullClassName = implode(
119 4
            '\\',
120
            [
121
                $this->options[Options::NAMESPACE],
122 4
                $this->options[Options::NAMESPACE_SUFFIX],
123 4
                $class,
124
            ]
125
        );
126 4
        return $this->hydrateFQCN($fullClassName, $json);
127
    }
128
129
    /**
130
     * @param string $class
131
     * @param array $json
132
     * @return ResourceInterface
133
     */
134 4
    public function hydrateFQCN(string $class, array $json): ResourceInterface
135
    {
136 4
        $hydrator = $this->getHydrator($class);
137 4
        $object = new $class();
138 4
        $json = $this->hydrateApplyAnnotations($json, $object);
139 4
        $resource = $hydrator->hydrate($json, $object);
140 4
        if ($resource instanceof AbstractResource) {
141
            $resource->setExtraProperties($this->options[Options::EXTRA_PROPERTIES]);
142
        }
143 4
        return $resource;
144
    }
145
146
    /**
147
     * @param array $json
148
     * @param ResourceInterface $object
149
     * @return array
150
     */
151 4 View Code Duplication
    protected function hydrateApplyAnnotations(array $json, ResourceInterface $object): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
152
    {
153 4
        foreach ($this->annotationHandlers as $annotationClass => $handler) {
154 4
            $annotation = $this->getAnnotation($object, $annotationClass);
155 4
            if ($annotation === null) {
156 4
                continue;
157
            }
158
159 4
            $json = $handler->hydrate($annotation, $json, $object);
160
        }
161
162 4
        return $json;
163
    }
164
165
    /**
166
     * @param string $class
167
     * @param ResourceInterface $object
168
     * @return array
169
     */
170 2 View Code Duplication
    public function extract(string $class, ResourceInterface $object): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
171
    {
172 2
        $fullClassName = implode(
173 2
            '\\',
174
            [
175
                $this->options[Options::NAMESPACE],
176 2
                $this->options[Options::NAMESPACE_SUFFIX],
177 2
                $class,
178
            ]
179
        );
180 2
        return $this->extractFQCN($fullClassName, $object);
181
    }
182
183
    /**
184
     * Takes a fully qualified class name and extracts the data for that class from the given $object
185
     * @param string $class
186
     * @param ResourceInterface $object
187
     * @return array
188
     */
189 2
    public function extractFQCN(string $class, ResourceInterface $object): array
190
    {
191 2
        $json = $this->getHydrator($class)->extract($object);
192 2
        $json = $this->extractApplyAnnotations($object, $json);
193 2
        return $json;
194
    }
195
196
    /**
197
     * @param array $json
198
     * @param ResourceInterface $object
199
     * @return array
200
     */
201 2 View Code Duplication
    protected function extractApplyAnnotations(ResourceInterface $object, array $json): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
202
    {
203 2
        foreach ($this->annotationHandlers as $annotationClass => $handler) {
204 2
            $annotation = $this->getAnnotation($object, $annotationClass);
205 2
            if ($annotation === null) {
206 2
                continue;
207
            }
208
209 2
            $json = $handler->extract($annotation, $object, $json);
210
        }
211
212 2
        return $json;
213
    }
214
215
    /**
216
     * @param ResourceInterface $object
217
     * @param string $annotationClass
218
     * @return null|AnnotationInterface
219
     */
220 4
    protected function getAnnotation(ResourceInterface $object, string $annotationClass)
221
    {
222 4
        $class = get_class($object);
223 4
        if (isset($this->annotations[$class][$annotationClass])) {
224 2
            return $this->annotations[$class][$annotationClass];
225
        }
226
227 4
        if (!isset($this->annotations[$class])) {
228 4
            $this->annotations[$class] = [];
229
        }
230
231 4
        $this->annotations[$class][$annotationClass] = $this->annotationReader
232 4
            ->getClassAnnotation(
233 4
                new ReflectionClass($object),
234
                $annotationClass
235
            )
236
        ;
237
238 4
        if (get_class($this->annotations[$class][$annotationClass]) === $annotationClass) {
239
            return $this->annotations[$class][$annotationClass];
240
        }
241
242 4
        $this->annotations[$class][$annotationClass] = $this->annotationReader
243 4
            ->getClassAnnotation(
244 4
                new ReflectionClass(get_parent_class($object)),
245
                $annotationClass
246
            )
247
        ;
248
249 4
        return $this->annotations[$class][$annotationClass];
250
    }
251
252
    /**
253
     * @param string $resource
254
     * @param ResourceInterface $object
255
     * @return ResourceInterface
256
     */
257 1
    public function buildAsyncFromSync(string $resource, ResourceInterface $object): ResourceInterface
258
    {
259 1
        return $this->hydrateFQCN(
260
            $this->options[Options::NAMESPACE] . '\\Async\\' . $resource,
261 1
            $this->extractFQCN(
262
                $this->options[Options::NAMESPACE] . '\\Sync\\' . $resource,
263
                $object
264
            )
265
        );
266
    }
267
268
    /**
269
     * @param string $class
270
     * @return HydratorInterface
271
     */
272 6
    protected function getHydrator(string $class): HydratorInterface
273
    {
274 6
        if (isset($this->hydrators[$class])) {
275 4
            return $this->hydrators[$class];
276
        }
277
278 6
        $config = new Configuration($class);
279 6
        if (isset($this->options[Options::RESOURCE_CACHE_DIR])) {
280 6
            $config->setGeneratedClassesTargetDir($this->options[Options::RESOURCE_CACHE_DIR]);
281
        }
282 6
        if (isset($this->options[Options::RESOURCE_NAMESPACE])) {
283 6
            $config->setGeneratedClassesNamespace($this->options[Options::RESOURCE_NAMESPACE]);
284
        }
285 6
        $hydrator = $config->createFactory()->getHydratorClass();
286 6
        $this->hydrators[$class] = new $hydrator;
287
288 6
        return $this->hydrators[$class];
289
    }
290
}
291