Completed
Pull Request — master (#22)
by
unknown
12:27
created

Parser::buildDataDocument()   B

Complexity

Conditions 10
Paths 25

Size

Total Lines 62
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 0
Metric Value
eloc 42
dl 0
loc 62
ccs 0
cts 31
cp 0
rs 7.6666
c 0
b 0
f 0
cc 10
nc 25
nop 1
crap 110

How to fix   Long Method    Complexity   

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 Swis\JsonApi\Client\JsonApi;
4
5
use Art4\JsonApiClient\DocumentInterface as Art4JsonApiDocumentInterface;
6
use Art4\JsonApiClient\ResourceCollectionInterface;
7
use Art4\JsonApiClient\ResourceItemInterface;
8
use Art4\JsonApiClient\Utils\Manager as Art4JsonApiClientManager;
9
use Swis\JsonApi\Client\Collection;
10
use Swis\JsonApi\Client\CollectionDocument;
11
use Swis\JsonApi\Client\Document;
12
use Swis\JsonApi\Client\Errors\ErrorCollection;
13
use Swis\JsonApi\Client\Interfaces\DocumentInterface;
14
use Swis\JsonApi\Client\Interfaces\ParserInterface;
15
use Swis\JsonApi\Client\ItemDocument;
16
17
class Parser implements ParserInterface
18
{
19
    /**
20
     * @var \Art4\JsonApiClient\Utils\Manager
21
     */
22
    protected $manager;
23
24
    /**
25
     * @var \Swis\JsonApi\Client\JsonApi\Hydrator
26
     */
27
    private $hydrator;
28
29
    /**
30
     * @var \Swis\JsonApi\Client\JsonApi\ErrorsParser
31
     */
32
    private $errorsParser;
33
34
    /**
35
     * @param \Art4\JsonApiClient\Utils\Manager         $manager
36
     * @param \Swis\JsonApi\Client\JsonApi\Hydrator     $hydrator
37
     * @param \Swis\JsonApi\Client\JsonApi\ErrorsParser $errorsParser
38
     */
39
    public function __construct(Art4JsonApiClientManager $manager, Hydrator $hydrator, ErrorsParser $errorsParser)
40
    {
41
        $this->manager = $manager;
42
        $this->hydrator = $hydrator;
43
        $this->errorsParser = $errorsParser;
44
    }
45
46
    /**
47
     * @return \Swis\JsonApi\Client\JsonApi\Hydrator
48
     */
49
    public function getHydrator(): Hydrator
50
    {
51
        return $this->hydrator;
52
    }
53
54
    /**
55
     * @param string $json
56
     *
57
     * @throws \DomainException
58
     *
59
     * @return \Swis\JsonApi\Client\Interfaces\DocumentInterface
60
     */
61
    public function deserialize(string $json): DocumentInterface
62
    {
63
        $jsonApiDocument = $this->getJsonApiDocument($json);
64
65
        if ($jsonApiDocument->has('data')) {
66
            $document = $this->buildDataDocument($jsonApiDocument);
67
        } else {
68
            $document = new Document();
69
        }
70
71
        $document->setLinks($this->parseLinks($jsonApiDocument));
72
        $document->setErrors($this->parseErrors($jsonApiDocument));
73
        $document->setMeta($this->parseMeta($jsonApiDocument));
74
75
        return $document;
76
    }
77
78
    /**
79
     * @param string $json
80
     *
81
     * @throws \DomainException
82
     *
83
     * @return \Art4\JsonApiClient\DocumentInterface
84
     */
85
    private function getJsonApiDocument(string $json): Art4JsonApiDocumentInterface
86
    {
87
        $jsonApiDocument = $this->manager->parse($json);
88
89
        if (!$jsonApiDocument instanceof Art4JsonApiDocumentInterface) {
90
            throw new \DomainException('Result is not a JSON API Document');
91
        }
92
93
        return $jsonApiDocument;
94
    }
95
96
    /**
97
     * @param \Art4\JsonApiClient\DocumentInterface $jsonApiDocument
98
     *
99
     * @throws \DomainException
100
     *includedInDocument
101
     *
102
     * @return \Swis\JsonApi\Client\Interfaces\DocumentInterface
103
     */
104
    protected function buildDataDocument(Art4JsonApiDocumentInterface $jsonApiDocument): DocumentInterface
105
    {
106
        $data = $this->getJsonApiDocumentData($jsonApiDocument);
107
        $includedInDocument = $this->getJsonApiDocumentIncluded($jsonApiDocument);
108
        $relationshipsInDocument = $this->getJsonApiDocumentRelationShips($jsonApiDocument);
109
        $allHydratedItems = new Collection();
110
        $allJsonApiItems = new Collection();
111
112
        if ($data instanceof ResourceItemInterface) {
113
            $item = $this->hydrator->hydrateItem($data);
114
            $allHydratedItems->push($item);
115
            $allJsonApiItems->push($data);
116
117
            $document = new ItemDocument();
118
            $document->setData($item);
119
        } elseif ($data instanceof ResourceCollectionInterface) {
0 ignored issues
show
introduced by
$data is always a sub-type of Art4\JsonApiClient\ResourceCollectionInterface.
Loading history...
120
            $collection = $this->hydrator->hydrateCollection($data);
121
            $allHydratedItems = $allHydratedItems->concat($collection);
122
            $allJsonApiItems = $allJsonApiItems->concat(new Collection($data->asArray()));
123
124
            $document = new CollectionDocument();
125
            $document->setData($collection);
126
        } else {
127
            throw new \DomainException('Data is not Collection or Item');
128
        }
129
130
        $included = null;
131
        if ($includedInDocument) {
132
            $included = $this->hydrator->hydrateCollection($includedInDocument);
133
            $allHydratedItems = $allHydratedItems->concat($included);
134
            $allJsonApiItems = $allJsonApiItems->concat(new Collection($includedInDocument->asArray()));
135
        }
136
137
        if ($relationshipsInDocument) {
138
            $relationships = $this->hydrator->hydrateRelationCollection($relationshipsInDocument);
139
            if ($includedInDocument) {
140
                $newRelationships = new Collection();
141
                foreach ($relationships as $relationship) {
142
                    $id = $relationship->getId();
143
                    $type = $relationship->getType();
144
                    $desiredObject = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $desiredObject is dead and can be removed.
Loading history...
145
146
                    //check duplicate
147
                    $desiredObject = $included->first(function ($item) use ($id, $type) {
148
                        return ($item->getId() == $id) && ($item->getType() == $type);
149
                    });
150
                    if (is_null($desiredObject)) {
151
                        $newRelationships->push($relationship);
152
                    }
153
                }
154
            } else {
155
                $newRelationships = $relationships;
0 ignored issues
show
Unused Code introduced by
The assignment to $newRelationships is dead and can be removed.
Loading history...
156
            }
157
        }
158
159
        //$allHydratedItems Items will be in response
160
        $this->hydrator->hydrateRelationships($allJsonApiItems, $allHydratedItems);
161
        if ($included) {
162
            $document->setIncluded($included);
163
        }
164
165
        return $document;
166
    }
167
168
    /**
169
     * @param \Art4\JsonApiClient\DocumentInterface $document
170
     *
171
     * @throws \DomainException
172
     *
173
     * @return \Art4\JsonApiClient\ResourceItemInterface|\Art4\JsonApiClient\ResourceCollectionInterface
174
     */
175
    private function getJsonApiDocumentData(Art4JsonApiDocumentInterface $document)
176
    {
177
        $resource = $document->get('data');
178
179
        if (!$resource instanceof ResourceItemInterface && !$resource instanceof ResourceCollectionInterface) {
180
            throw new \DomainException('Result is not a Json API Resource');
181
        }
182
183
        return $resource;
184
    }
185
186
    /**
187
     * @param \Art4\JsonApiClient\DocumentInterface $document
188
     *
189
     * @return \Art4\JsonApiClient\ResourceCollection|null
190
     */
191
    private function getJsonApiDocumentIncluded(Art4JsonApiDocumentInterface $document)
192
    {
193
        if ($document->has('included')) {
194
            return $document->get('included');
195
        }
196
197
        return null;
198
    }
199
200
    /**
201
     * @param \Art4\JsonApiClient\DocumentInterface $document
202
     *
203
     * @return \Art4\JsonApiClient\ResourceCollection|null
204
     */
205
    private function getJsonApiDocumentRelationShips(Art4JsonApiDocumentInterface $document)
206
    {
207
        if ($document->has('data.relationships')) {
208
            return $document->get('data.relationships');
209
        }
210
211
        return null;
212
    }
213
214
    /**
215
     * @param \Art4\JsonApiClient\DocumentInterface $document
216
     *
217
     * @return array
218
     */
219
    private function parseLinks(Art4JsonApiDocumentInterface $document): array
220
    {
221
        if (!$document->has('links')) {
222
            return [];
223
        }
224
225
        return $document->get('links')->asArray(true);
226
    }
227
228
    /**
229
     * @param \Art4\JsonApiClient\DocumentInterface $document
230
     *
231
     * @return \Swis\JsonApi\Client\Errors\ErrorCollection
232
     */
233
    private function parseErrors(Art4JsonApiDocumentInterface $document): ErrorCollection
234
    {
235
        if (!$document->has('errors')) {
236
            return new ErrorCollection();
237
        }
238
239
        return $this->errorsParser->parse($document->get('errors'));
240
    }
241
242
    /**
243
     * @param \Art4\JsonApiClient\DocumentInterface $document
244
     *
245
     * @return array
246
     */
247
    private function parseMeta(Art4JsonApiDocumentInterface $document): array
248
    {
249
        if (!$document->has('meta')) {
250
            return [];
251
        }
252
253
        return $document->get('meta')->asArray(true);
254
    }
255
256
    /**
257
     * @param \Swis\JsonApi\Client\Interfaces\DocumentInterface $document
258
     *
259
     * @return string
260
     */
261
    public function serialize(DocumentInterface $document): string
262
    {
263
    }
264
}
265