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 ( 314331...73d977 )
by Cees-Jan
02:03
created

Hydrator::hydrateCollectionResources()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 22
Code Lines 12

Duplication

Lines 22
Ratio 100 %

Code Coverage

Tests 11
CRAP Score 5.0144

Importance

Changes 0
Metric Value
dl 22
loc 22
ccs 11
cts 12
cp 0.9167
rs 8.6737
c 0
b 0
f 0
cc 5
eloc 12
nc 5
nop 2
crap 5.0144
1
<?php
2
declare(strict_types=1);
3
4
namespace WyriHaximus\ApiClient\Transport;
5
6
use Doctrine\Common\Annotations\AnnotationReader;
7
use GeneratedHydrator\Configuration;
8
use ReflectionClass;
9
use WyriHaximus\ApiClient\Annotations\Collection;
10
use WyriHaximus\ApiClient\Annotations\Nested;
11
use WyriHaximus\ApiClient\Resource\ResourceInterface;
12
use Zend\Hydrator\HydratorInterface;
13
14
class Hydrator
15
{
16
    /**
17
     * @var array
18
     */
19
    protected $options;
20
21
    /**
22
     * @var Client
23
     */
24
    protected $transport;
25
26
    /**
27
     * @var array
28
     */
29
    protected $hydrators = [];
30
31
    /**
32
     * @var array
33
     */
34
    protected $annotations = [];
35
36
    /**
37
     * @var AnnotationReader
38
     */
39
    protected $annotationReader;
40
41
    /**
42
     * @param Client $transport
43
     * @param array $options
44
     */
45 15
    public function __construct(Client $transport, array $options)
46
    {
47 15
        $this->transport = $transport;
48 15
        $this->options = $options;
49 15
        $this->annotationReader = new AnnotationReader();
50 15
    }
51
52
    /**
53
     * @param string $class
54
     * @param array $json
55
     * @return ResourceInterface
56
     */
57 3
    public function hydrateFQCN(string $class, array $json): ResourceInterface
58
    {
59 3
        $hydrator = $this->getHydrator($class);
60 3
        $object = $this->createObject($class);
61 3
        $json = $this->hydrateNestedResources($object, $json);
62 3
        $json = $this->hydrateCollectionResources($object, $json);
63 3
        return $hydrator->hydrate($json, $object);
64
    }
65
66
    /**
67
     * @param ResourceInterface $object
68
     * @param array $json
69
     * @return array
70
     */
71 3
    protected function hydrateNestedResources(ResourceInterface $object, array $json)
72
    {
73 3
        $annotation = $this->getAnnotation($object, Nested::class);
74
75 3
        if (!($annotation instanceof Nested)) {
76 3
            return $json;
77
        }
78
79 3
        foreach ($annotation->properties() as $property) {
80 3
            if ($json[$property] === null) {
81
                continue;
82
            }
83
84 3
            $json[$property] = $this->hydrate($annotation->get($property), $json[$property]);
85
        }
86
87 3
        return $json;
88
    }
89
90
    /**
91
     * @param ResourceInterface $object
92
     * @param array $json
93
     * @return array
94
     */
95 3 View Code Duplication
    protected function hydrateCollectionResources(ResourceInterface $object, array $json)
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...
96
    {
97 3
        $annotation = $this->getAnnotation($object, Collection::class);
98
99 3
        if (!($annotation instanceof Collection)) {
100 3
            return $json;
101
        }
102
103 3
        foreach ($annotation->properties() as $property) {
104 3
            $array = $json[$property];
105 3
            $json[$property] = [];
106 3
            foreach ($array as $resource) {
107 3
                if ($resource === null) {
108
                    continue;
109
                }
110
111 3
                $json[$property][] = $this->hydrate($annotation->get($property), $resource);
112
            }
113
        }
114
115 3
        return $json;
116
    }
117
118
    /**
119
     * @param string $class
120
     * @param array $json
121
     * @return ResourceInterface
122
     */
123 3
    public function hydrate(string $class, array $json): ResourceInterface
124
    {
125 3
        $fullClassName = $this->options['namespace'] . '\\' . $this->options['resource_namespace'] . '\\' . $class;
126 3
        return $this->hydrateFQCN($fullClassName, $json);
127
    }
128
129
    /**
130
     * Takes a fully qualified class name and extracts the data for that class from the given $object
131
     * @param string $class
132
     * @param ResourceInterface $object
133
     * @return array
134
     */
135 2
    public function extractFQCN(string $class, ResourceInterface $object): array
136
    {
137 2
        $json = $this->getHydrator($class)->extract($object);
138 2
        $json = $this->extractNestedResources($json, $object);
139 2
        $json = $this->extractCollectionResources($json, $object);
140 2
        return $json;
141
    }
142
143
    /**
144
     * @param array $json
145
     * @param ResourceInterface $object
146
     * @return array
147
     */
148 2
    protected function extractNestedResources(array $json, ResourceInterface $object)
149
    {
150 2
        $annotation = $this->getAnnotation($object, Nested::class);
151
152 2
        if (!($annotation instanceof Nested)) {
153 2
            return $json;
154
        }
155
156 2
        foreach ($annotation->properties() as $property) {
157 2
            $json[$property] = $this->extract($annotation->get($property), $json[$property]);
158
        }
159
160 2
        return $json;
161
    }
162
163
    /**
164
     * @param array $json
165
     * @param ResourceInterface $object
166
     * @return array
167
     */
168 2 View Code Duplication
    protected function extractCollectionResources(array $json, ResourceInterface $object)
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...
169
    {
170 2
        $annotation = $this->getAnnotation($object, Collection::class);
171
172 2
        if (!($annotation instanceof Collection)) {
173 2
            return $json;
174
        }
175
176 2
        foreach ($annotation->properties() as $property) {
177 2
            $array = $json[$property];
178 2
            $json[$property] = [];
179 2
            foreach ($array as $resource) {
180 2
                $json[$property][] = $this->extract($annotation->get($property), $resource);
181
            }
182
        }
183
184 2
        return $json;
185
    }
186
187
    /**
188
     * @param ResourceInterface $object
189
     * @param string $annotationClass
190
     * @return null|object
191
     */
192 3
    protected function getAnnotation(ResourceInterface $object, string $annotationClass)
193
    {
194 3
        $class = get_class($object);
195 3
        if (isset($this->annotations[$class][$annotationClass])) {
196 1
            return $this->annotations[$class][$annotationClass];
197
        }
198
199 3
        if (!isset($this->annotations[$class])) {
200 3
            $this->annotations[$class] = [];
201
        }
202
203 3
        $this->annotations[$class][$annotationClass] = $this->annotationReader
204 3
            ->getClassAnnotation(
205 3
                new ReflectionClass($object),
206
                $annotationClass
207
            )
208
        ;
209
210 3
        if (get_class($this->annotations[$class][$annotationClass]) === $annotationClass) {
211
            return $this->annotations[$class][$annotationClass];
212
        }
213
214 3
        $this->annotations[$class][$annotationClass] = $this->annotationReader
215 3
            ->getClassAnnotation(
216 3
                new ReflectionClass(get_parent_class($object)),
217
                $annotationClass
218
            )
219
        ;
220
221 3
        return $this->annotations[$class][$annotationClass];
222
    }
223
224
    /**
225
     * @param string $class
226
     * @param ResourceInterface $object
227
     * @return array
228
     */
229 2
    public function extract(string $class, ResourceInterface $object): array
230
    {
231 2
        $fullClassName = $this->options['namespace'] . '\\' . $this->options['resource_namespace'] . '\\' . $class;
232 2
        return $this->extractFQCN($fullClassName, $object);
233
    }
234
235
    /**
236
     * @param string $resource
237
     * @param ResourceInterface $object
238
     * @return ResourceInterface
239
     */
240 1
    public function buildAsyncFromSync(string $resource, ResourceInterface $object): ResourceInterface
241
    {
242 1
        return $this->hydrateFQCN(
243 1
            $this->options['namespace'] . '\\Async\\' . $resource,
244 1
            $this->extractFQCN(
245 1
                $this->options['namespace'] . '\\Sync\\' . $resource,
246
                $object
247
            )
248
        );
249
    }
250
251
    /**
252
     * @param string $class
253
     * @return HydratorInterface
254
     */
255 3
    protected function getHydrator(string $class): HydratorInterface
256
    {
257 3
        if (isset($this->hydrators[$class])) {
258 3
            return $this->hydrators[$class];
259
        }
260
261 3
        $config = new Configuration($class);
262 3
        if (isset($this->options['resource_hydrator_cache_dir'])) {
263 3
            $config->setGeneratedClassesTargetDir($this->options['resource_hydrator_cache_dir']);
264
        }
265 3
        if (isset($this->options['resource_hydrator_namespace'])) {
266 3
            $config->setGeneratedClassesNamespace($this->options['resource_hydrator_namespace']);
267
        }
268 3
        $hydrator = $config->createFactory()->getHydratorClass();
269 3
        $this->hydrators[$class] = new $hydrator;
270
271 3
        return $this->hydrators[$class];
272
    }
273
274
    /**
275
     * @param string $class
276
     * @return ResourceInterface
277
     */
278 3
    protected function createObject(string $class): ResourceInterface
279
    {
280 3
        $object = new $class();
281 3
        $object->setTransport($this->transport);
282 3
        if (isset($this->options['setters'])) {
283
            foreach ($this->options['setters'] as $method => $argument) {
284
                if (!method_exists($object, $method)) {
285
                    continue;
286
                }
287
                $object->$method($argument);
288
            }
289
        }
290 3
        return $object;
291
    }
292
}
293