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 ( 77ecf9...d14a59 )
by Cees-Jan
9s
created

Hydrator::extractCollectionResources()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 10

Duplication

Lines 18
Ratio 100 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
dl 18
loc 18
ccs 10
cts 10
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 10
nc 4
nop 2
crap 4
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 View Code Duplication
    protected function hydrateNestedResources(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...
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
            $json[$property] = $this->hydrate($annotation->get($property), $json[$property]);
81
        }
82
83 3
        return $json;
84
    }
85
86
    /**
87
     * @param ResourceInterface $object
88
     * @param array $json
89
     * @return array
90
     */
91 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...
92
    {
93 3
        $annotation = $this->getAnnotation($object, Collection::class);
94
95 3
        if (!($annotation instanceof Collection)) {
96 3
            return $json;
97
        }
98
99 3
        foreach ($annotation->properties() as $property) {
100 3
            $array = $json[$property];
101 3
            $json[$property] = [];
102 3
            foreach ($array as $resource) {
103 3
                $json[$property][] = $this->hydrate($annotation->get($property), $resource);
104
            }
105
        }
106
107 3
        return $json;
108
    }
109
110
    /**
111
     * @param string $class
112
     * @param array $json
113
     * @return ResourceInterface
114
     */
115 3
    public function hydrate(string $class, array $json): ResourceInterface
116
    {
117 3
        $fullClassName = $this->options['namespace'] . '\\' . $this->options['resource_namespace'] . '\\' . $class;
118 3
        return $this->hydrateFQCN($fullClassName, $json);
119
    }
120
121
    /**
122
     * Takes a fully qualified class name and extracts the data for that class from the given $object
123
     * @param string $class
124
     * @param ResourceInterface $object
125
     * @return array
126
     */
127 2
    public function extractFQCN(string $class, ResourceInterface $object): array
128
    {
129 2
        $json = $this->getHydrator($class)->extract($object);
130 2
        $json = $this->extractNestedResources($json, $object);
131 2
        $json = $this->extractCollectionResources($json, $object);
132 2
        return $json;
133
    }
134
135
    /**
136
     * @param array $json
137
     * @param ResourceInterface $object
138
     * @return array
139
     */
140 2 View Code Duplication
    protected function extractNestedResources(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...
141
    {
142 2
        $annotation = $this->getAnnotation($object, Nested::class);
143
144 2
        if (!($annotation instanceof Nested)) {
145 2
            return $json;
146
        }
147
148 2
        foreach ($annotation->properties() as $property) {
149 2
            $json[$property] = $this->extract($annotation->get($property), $json[$property]);
150
        }
151
152 2
        return $json;
153
    }
154
155
    /**
156
     * @param array $json
157
     * @param ResourceInterface $object
158
     * @return array
159
     */
160 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...
161
    {
162 2
        $annotation = $this->getAnnotation($object, Collection::class);
163
164 2
        if (!($annotation instanceof Collection)) {
165 2
            return $json;
166
        }
167
168 2
        foreach ($annotation->properties() as $property) {
169 2
            $array = $json[$property];
170 2
            $json[$property] = [];
171 2
            foreach ($array as $resource) {
172 2
                $json[$property][] = $this->extract($annotation->get($property), $resource);
173
            }
174
        }
175
176 2
        return $json;
177
    }
178
179
    /**
180
     * @param ResourceInterface $object
181
     * @param string $annotationClass
182
     * @return null|object
183
     */
184 3
    protected function getAnnotation(ResourceInterface $object, string $annotationClass)
185
    {
186 3
        $class = get_class($object);
187 3
        if (isset($this->annotations[$class][$annotationClass])) {
188 1
            return $this->annotations[$class][$annotationClass];
189
        }
190
191 3
        if (!isset($this->annotations[$class])) {
192 3
            $this->annotations[$class] = [];
193
        }
194
195 3
        $this->annotations[$class][$annotationClass] = $this->annotationReader
196 3
            ->getClassAnnotation(
197 3
                new ReflectionClass($object),
198
                $annotationClass
199
            )
200
        ;
201
202 3
        if (get_class($this->annotations[$class][$annotationClass]) === $annotationClass) {
203
            return $this->annotations[$class][$annotationClass];
204
        }
205
206 3
        $this->annotations[$class][$annotationClass] = $this->annotationReader
207 3
            ->getClassAnnotation(
208 3
                new ReflectionClass(get_parent_class($object)),
209
                $annotationClass
210
            )
211
        ;
212
213 3
        return $this->annotations[$class][$annotationClass];
214
    }
215
216
    /**
217
     * @param string $class
218
     * @param ResourceInterface $object
219
     * @return array
220
     */
221 2
    public function extract(string $class, ResourceInterface $object): array
222
    {
223 2
        $fullClassName = $this->options['namespace'] . '\\' . $this->options['resource_namespace'] . '\\' . $class;
224 2
        return $this->extractFQCN($fullClassName, $object);
225
    }
226
227
    /**
228
     * @param string $resource
229
     * @param ResourceInterface $object
230
     * @return ResourceInterface
231
     */
232 1
    public function buildAsyncFromSync(string $resource, ResourceInterface $object): ResourceInterface
233
    {
234 1
        return $this->hydrateFQCN(
235 1
            $this->options['namespace'] . '\\Async\\' . $resource,
236 1
            $this->extractFQCN(
237 1
                $this->options['namespace'] . '\\Sync\\' . $resource,
238
                $object
239
            )
240
        );
241
    }
242
243
    /**
244
     * @param string $class
245
     * @return HydratorInterface
246
     */
247 3
    protected function getHydrator(string $class): HydratorInterface
248
    {
249 3
        if (isset($this->hydrators[$class])) {
250 3
            return $this->hydrators[$class];
251
        }
252
253 3
        $config = new Configuration($class);
254 3
        if (isset($this->options['resource_hydrator_cache_dir'])) {
255 3
            $config->setGeneratedClassesTargetDir($this->options['resource_hydrator_cache_dir']);
256
        }
257 3
        if (isset($this->options['resource_hydrator_namespace'])) {
258 3
            $config->setGeneratedClassesNamespace($this->options['resource_hydrator_namespace']);
259
        }
260 3
        $hydrator = $config->createFactory()->getHydratorClass();
261 3
        $this->hydrators[$class] = new $hydrator;
262
263 3
        return $this->hydrators[$class];
264
    }
265
266
    /**
267
     * @param string $class
268
     * @return ResourceInterface
269
     */
270 3
    protected function createObject(string $class): ResourceInterface
271
    {
272 3
        $object = new $class();
273 3
        $object->setTransport($this->transport);
274 3
        if (isset($this->options['setters'])) {
275
            foreach ($this->options['setters'] as $method => $argument) {
276
                if (!method_exists($object, $method)) {
277
                    continue;
278
                }
279
                $object->$method($argument);
280
            }
281
        }
282 3
        return $object;
283
    }
284
}
285