Completed
Pull Request — master (#22)
by
unknown
11:53
created

Parser::getJsonApiDocumentRelationShips()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 6
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
use Swis\JsonApi\Client\Items\JenssegersItem;
17
18
class Parser implements ParserInterface
19
{
20
    /**
21
     * @var \Art4\JsonApiClient\Utils\Manager
22
     */
23
    protected $manager;
24
25
    /**
26
     * @var \Swis\JsonApi\Client\JsonApi\Hydrator
27
     */
28
    private $hydrator;
29
30
    /**
31
     * @var \Swis\JsonApi\Client\JsonApi\ErrorsParser
32
     */
33
    private $errorsParser;
34
35
    /**
36
     * @param \Art4\JsonApiClient\Utils\Manager         $manager
37
     * @param \Swis\JsonApi\Client\JsonApi\Hydrator     $hydrator
38
     * @param \Swis\JsonApi\Client\JsonApi\ErrorsParser $errorsParser
39
     */
40
    public function __construct(Art4JsonApiClientManager $manager, Hydrator $hydrator, ErrorsParser $errorsParser)
41
    {
42
        $this->manager = $manager;
43
        $this->hydrator = $hydrator;
44
        $this->errorsParser = $errorsParser;
45
    }
46
47
    /**
48
     * @return \Swis\JsonApi\Client\JsonApi\Hydrator
49
     */
50
    public function getHydrator(): Hydrator
51
    {
52
        return $this->hydrator;
53
    }
54
55
    /**
56
     * @param string $json
57
     *
58
     * @throws \DomainException
59
     *
60
     * @return \Swis\JsonApi\Client\Interfaces\DocumentInterface
61
     */
62
    public function deserialize(string $json): DocumentInterface
63
    {
64
        $jsonApiDocument = $this->getJsonApiDocument($json);
65
66
        if ($jsonApiDocument->has('data')) {
67
            $document = $this->buildDataDocument($jsonApiDocument);
68
        } else {
69
            $document = new Document();
70
        }
71
72
        $document->setLinks($this->parseLinks($jsonApiDocument));
73
        $document->setErrors($this->parseErrors($jsonApiDocument));
74
        $document->setMeta($this->parseMeta($jsonApiDocument));
75
76
        return $document;
77
    }
78
79
    /**
80
     * @param string $json
81
     *
82
     * @throws \DomainException
83
     *
84
     * @return \Art4\JsonApiClient\DocumentInterface
85
     */
86
    private function getJsonApiDocument(string $json): Art4JsonApiDocumentInterface
87
    {
88
        $jsonApiDocument = $this->manager->parse($json);
89
90
        if (!$jsonApiDocument instanceof Art4JsonApiDocumentInterface) {
91
            throw new \DomainException('Result is not a JSON API Document');
92
        }
93
94
        return $jsonApiDocument;
95
    }
96
97
    /**
98
     * @param \Art4\JsonApiClient\DocumentInterface $jsonApiDocument
99
     *
100
     * @throws \DomainException
101
     *includedInDocument
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
143
                    $id = $relationship->getId();
144
                    $type = $relationship->getType();
145
                    $desiredObject = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $desiredObject is dead and can be removed.
Loading history...
146
147
                    //check duplicate
148
                    $desiredObject = $included->first(function ($item) use ($id, $type) {
149
                        return ($item->getId() == $id) && ($item->getType() == $type);
150
                    });
151
                    if (is_null($desiredObject)) {
152
                        $newRelationships->push($relationship);
153
                    }
154
                }
155
            } else {
156
                $newRelationships = $relationships;
0 ignored issues
show
Unused Code introduced by
The assignment to $newRelationships is dead and can be removed.
Loading history...
157
            }
158
        }
159
160
161
            //$allHydratedItems Items will be in response
162
        $this->hydrator->hydrateRelationships($allJsonApiItems, $allHydratedItems);
163
        if ($included) {
164
            $document->setIncluded($included);
165
        }
166
167
        return $document;
168
    }
169
170
171
    /**
172
     * @param \Art4\JsonApiClient\DocumentInterface $document
173
     *
174
     * @throws \DomainException
175
     *
176
     * @return \Art4\JsonApiClient\ResourceItemInterface|\Art4\JsonApiClient\ResourceCollectionInterface
177
     */
178
    private function getJsonApiDocumentData(Art4JsonApiDocumentInterface $document)
179
    {
180
        $resource = $document->get('data');
181
182
        if (!$resource instanceof ResourceItemInterface && !$resource instanceof ResourceCollectionInterface) {
183
            throw new \DomainException('Result is not a Json API Resource');
184
        }
185
186
        return $resource;
187
    }
188
189
    /**
190
     * @param \Art4\JsonApiClient\DocumentInterface $document
191
     *
192
     * @return \Art4\JsonApiClient\ResourceCollection|null
193
     */
194
    private function getJsonApiDocumentIncluded(Art4JsonApiDocumentInterface $document)
195
    {
196
        if ($document->has('included')) {
197
            return $document->get('included');
198
        }
199
200
        return null;
201
    }
202
203
    /**
204
     * @param \Art4\JsonApiClient\DocumentInterface $document
205
     *
206
     * @return \Art4\JsonApiClient\ResourceCollection|null
207
     */
208
    private function getJsonApiDocumentRelationShips(Art4JsonApiDocumentInterface $document)
209
    {
210
        if ($document->has('data.relationships')) {
211
            return $document->get('data.relationships');
212
        }
213
        return null;
214
    }
215
216
217
    /**
218
     * @param \Art4\JsonApiClient\DocumentInterface $document
219
     *
220
     * @return array
221
     */
222
    private function parseLinks(Art4JsonApiDocumentInterface $document): array
223
    {
224
        if (!$document->has('links')) {
225
            return [];
226
        }
227
        return $document->get('links')->asArray(true);
228
    }
229
230
    /**
231
     * @param \Art4\JsonApiClient\DocumentInterface $document
232
     *
233
     * @return \Swis\JsonApi\Client\Errors\ErrorCollection
234
     */
235
    private function parseErrors(Art4JsonApiDocumentInterface $document): ErrorCollection
236
    {
237
        if (!$document->has('errors')) {
238
            return new ErrorCollection();
239
        }
240
241
        return $this->errorsParser->parse($document->get('errors'));
242
    }
243
244
    /**
245
     * @param \Art4\JsonApiClient\DocumentInterface $document
246
     *
247
     * @return array
248
     */
249
    private function parseMeta(Art4JsonApiDocumentInterface $document): array
250
    {
251
        if (!$document->has('meta')) {
252
            return [];
253
        }
254
255
        return $document->get('meta')->asArray(true);
256
    }
257
258
    /**
259
     * @param \Swis\JsonApi\Client\Interfaces\DocumentInterface $document
260
     *
261
     * @return string
262
     */
263
    public function serialize(DocumentInterface $document): string
264
    {
265
    }
266
}
267