Completed
Branch next (92e3a0)
by Neomerx
01:44
created

Factory::createRelationshipDataIsResource()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
c 0
b 0
f 0
cc 1
nc 1
nop 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php declare(strict_types=1);
2
3
namespace Neomerx\JsonApi\Factories;
4
5
/**
6
 * Copyright 2015-2019 [email protected]
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
use Neomerx\JsonApi\Contracts\Encoder\EncoderInterface;
22
use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
23
use Neomerx\JsonApi\Contracts\Http\Headers\AcceptMediaTypeInterface;
24
use Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
25
use Neomerx\JsonApi\Contracts\Parser\IdentifierInterface as ParserIdentifierInterface;
26
use Neomerx\JsonApi\Contracts\Parser\ParserInterface;
27
use Neomerx\JsonApi\Contracts\Parser\PositionInterface;
28
use Neomerx\JsonApi\Contracts\Parser\RelationshipDataInterface;
29
use Neomerx\JsonApi\Contracts\Parser\RelationshipInterface;
30
use Neomerx\JsonApi\Contracts\Parser\ResourceInterface;
31
use Neomerx\JsonApi\Contracts\Representation\DocumentWriterInterface;
32
use Neomerx\JsonApi\Contracts\Representation\ErrorWriterInterface;
33
use Neomerx\JsonApi\Contracts\Representation\FieldSetFilterInterface;
34
use Neomerx\JsonApi\Contracts\Schema\IdentifierInterface as SchemaIdentifierInterface;
35
use Neomerx\JsonApi\Contracts\Schema\LinkInterface;
36
use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
37
use Neomerx\JsonApi\Encoder\Encoder;
38
use Neomerx\JsonApi\Http\Headers\AcceptMediaType;
39
use Neomerx\JsonApi\Http\Headers\MediaType;
40
use Neomerx\JsonApi\Parser\IdentifierAndResource;
41
use Neomerx\JsonApi\Parser\Parser;
42
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsCollection;
43
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsIdentifier;
44
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsNull;
45
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsResource;
46
use Neomerx\JsonApi\Representation\DocumentWriter;
47
use Neomerx\JsonApi\Representation\ErrorWriter;
48
use Neomerx\JsonApi\Representation\FieldSetFilter;
49
use Neomerx\JsonApi\Schema\Link;
50
use Neomerx\JsonApi\Schema\SchemaContainer;
51
52
/**
53
 * @package Neomerx\JsonApi
54
 */
55
class Factory implements FactoryInterface
56
{
57
    /**
58
     * @inheritdoc
59
     */
60 72
    public function createEncoder(SchemaContainerInterface $container): EncoderInterface
61
    {
62 72
        return new Encoder($this, $container);
63
    }
64
65
    /**
66
     * @inheritdoc
67
     */
68 77
    public function createSchemaContainer(iterable $schemas): SchemaContainerInterface
69
    {
70 77
        return new SchemaContainer($this, $schemas);
71
    }
72
73
    /**
74
     * @inheritdoc
75
     */
76 67
    public function createPosition(
77
        int $level,
78
        string $path,
79
        ?string $parentType,
80
        ?string $parentRelationship
81
    ): PositionInterface {
82
        return new class ($level, $path, $parentType, $parentRelationship) implements PositionInterface
83
        {
84
            /**
85
             * @var int
86
             */
87
            private $level;
88
89
            /**
90
             * @var string
91
             */
92
            private $path;
93
94
            /**
95
             * @var null|string
96
             */
97
            private $parentType;
98
99
            /**
100
             * @var null|string
101
             */
102
            private $parentRelationship;
103
104
            /**
105
             * @param int         $level
106
             * @param string      $path
107
             * @param null|string $parentType
108
             * @param null|string $parentRelationship
109
             */
110
            public function __construct(int $level, string $path, ?string $parentType, ?string $parentRelationship)
111
            {
112 67
                $this->level              = $level;
113 67
                $this->path               = $path;
114 67
                $this->parentType         = $parentType;
115 67
                $this->parentRelationship = $parentRelationship;
116 67
            }
117
118
            /**
119
             * @inheritdoc
120
             */
121
            public function getLevel(): int
122
            {
123 59
                return $this->level;
124
            }
125
126
            /**
127
             * @inheritdoc
128
             */
129
            public function getPath(): string
130
            {
131 59
                return $this->path;
132
            }
133
134
            /**
135
             * @inheritdoc
136
             */
137
            public function getParentType(): ?string
138
            {
139 21
                return $this->parentType;
140
            }
141
142
            /**
143
             * @inheritdoc
144
             */
145
            public function getParentRelationship(): ?string
146
            {
147 7
                return $this->parentRelationship;
148
            }
149
        };
150
    }
151
152
    /**
153
     * @inheritdoc
154
     */
155 67
    public function createParser(SchemaContainerInterface $container): ParserInterface
156
    {
157 67
        return new Parser($this, $container);
158
    }
159
160
    /**
161
     * @inheritdoc
162
     */
163 69
    public function createDocumentWriter(): DocumentWriterInterface
164
    {
165 69
        return new DocumentWriter($this);
166
    }
167
168
    /**
169
     * @inheritdoc
170
     */
171 7
    public function createErrorWriter(): ErrorWriterInterface
172
    {
173 7
        return new ErrorWriter($this);
174
    }
175
176
    /**
177
     * @inheritdoc
178
     */
179 66
    public function createFieldSetFilter(array $fieldSets): FieldSetFilterInterface
180
    {
181 66
        return new FieldSetFilter($fieldSets);
182
    }
183
184
    /**
185
     * @inheritdoc
186
     */
187 59
    public function createParsedResource(
188
        PositionInterface $position,
189
        SchemaContainerInterface $container,
190
        $data
191
    ): ResourceInterface {
192 59
        return new IdentifierAndResource($position, $this, $container, $data);
193
    }
194
195
    /**
196
     * @inheritdoc
197
     */
198 1
    public function createParsedIdentifier(
199
        PositionInterface $position,
200
        SchemaIdentifierInterface $identifier
201
    ): ParserIdentifierInterface {
202
        return new class ($position, $identifier) implements ParserIdentifierInterface
203
        {
204
            /**
205
             * @var PositionInterface
206
             */
207
            private $position;
208
209
            /**
210
             * @var SchemaIdentifierInterface
211
             */
212
            private $identifier;
213
214
            /**
215
             * @param PositionInterface         $position
216
             * @param SchemaIdentifierInterface $identifier
217
             */
218
            public function __construct(
219
                PositionInterface $position,
220
                SchemaIdentifierInterface $identifier
221
            ) {
222 1
                $this->position   = $position;
223 1
                $this->identifier = $identifier;
224 1
            }
225
226
            /**
227
             * @inheritdoc
228
             */
229
            public function getType(): string
230
            {
231 1
                return $this->identifier->getType();
232
            }
233
234
            /**
235
             * @inheritdoc
236
             */
237
            public function getId(): ?string
238
            {
239 1
                return $this->identifier->getId();
240
            }
241
242
            /**
243
             * @inheritdoc
244
             */
245
            public function hasIdentifierMeta(): bool
246
            {
247 1
                return $this->identifier->hasIdentifierMeta();
248
            }
249
250
            /**
251
             * @inheritdoc
252
             */
253
            public function getIdentifierMeta()
254
            {
255
                return $this->identifier->getIdentifierMeta();
256
            }
257
258
            /**
259
             * @inheritdoc
260
             */
261
            public function getPosition(): PositionInterface
262
            {
263
                return $this->position;
264
            }
265
        };
266
    }
267
268
    /**
269
     * @inheritdoc
270
     */
271 61
    public function createLink(bool $isSubUrl, string $value, bool $hasMeta, $meta = null): LinkInterface
272
    {
273 61
        return new Link($isSubUrl, $value, $hasMeta, $meta);
274
    }
275
276
    /**
277
     * @inheritdoc
278
     */
279
    public function createRelationship(
280
        PositionInterface $position,
281
        bool $hasData,
282
        ?RelationshipDataInterface $data,
283
        bool $hasLinks,
284
        ?iterable $links,
285
        bool $hasMeta,
286
        $meta
287
    ): RelationshipInterface {
288
        return new class (
289
            $position,
290
            $hasData,
291
            $data,
292
            $hasLinks,
293
            $links,
294
            $hasMeta,
295
            $meta
296
        ) implements RelationshipInterface
297
        {
298
            /**
299
             * @var PositionInterface
300
             */
301
            private $position;
302
303
            /**
304
             * @var bool
305
             */
306
            private $hasData;
307
308
            /**
309
             * @var ?RelationshipDataInterface
310
             */
311
            private $data;
312
313
            /**
314
             * @var bool
315
             */
316
            private $hasLinks;
317
318
            /**
319
             * @var ?iterable
320
             */
321
            private $links;
322
323
            /**
324
             * @var bool
325
             */
326
            private $hasMeta;
327
328
            /**
329
             * @var mixed
330
             */
331
            private $meta;
332
333
            /**
334
             * @var bool
335
             */
336
            private $metaIsCallable;
337
338
            /**
339
             * @param PositionInterface              $position
340
             * @param bool                           $hasData
341
             * @param RelationshipDataInterface|null $data
342
             * @param bool                           $hasLinks
343
             * @param iterable|null                  $links
344
             * @param bool                           $hasMeta
345
             * @param mixed                          $meta
346
             */
347 44
            public function __construct(
348
                PositionInterface $position,
349
                bool $hasData,
350
                ?RelationshipDataInterface $data,
351
                bool $hasLinks,
352
                ?iterable $links,
353
                bool $hasMeta,
354
                $meta
355
            ) {
356 44
                assert($position->getLevel() > ParserInterface::ROOT_LEVEL);
357 44
                assert(empty($position->getPath()) === false);
358 44
                assert(($hasData === false && $data === null) || ($hasData === true && $data !== null));
359 44
                assert(($hasLinks === false && $links === null) || ($hasLinks === true && $links !== null));
360
361 44
                $this->position       = $position;
362 44
                $this->hasData        = $hasData;
363 44
                $this->data           = $data;
364 44
                $this->hasLinks       = $hasLinks;
365 44
                $this->links          = $links;
366 44
                $this->hasMeta        = $hasMeta;
367 44
                $this->meta           = $meta;
368 44
                $this->metaIsCallable = is_callable($meta);
369 44
            }
370
371
            /**
372
             * @inheritdoc
373
             */
374 44
            public function getPosition(): PositionInterface
375
            {
376 44
                return $this->position;
377
            }
378
379
            /**
380
             * @inheritdoc
381
             */
382 44
            public function hasData(): bool
383
            {
384 44
                return $this->hasData;
385
            }
386
387
            /**
388
             * @inheritdoc
389
             */
390 33
            public function getData(): RelationshipDataInterface
391
            {
392 33
                assert($this->hasData());
393
394 33
                return $this->data;
395
            }
396
397
            /**
398
             * @inheritdoc
399
             */
400 38
            public function hasLinks(): bool
401
            {
402 38
                return $this->hasLinks;
403
            }
404
405
            /**
406
             * @inheritdoc
407
             */
408 21
            public function getLinks(): iterable
409
            {
410 21
                assert($this->hasLinks());
411
412 21
                return $this->links;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->links; of type Neomerx\JsonApi\Factories\iterable|null adds the type Neomerx\JsonApi\Factories\iterable to the return on line 412 which is incompatible with the return type declared by the interface Neomerx\JsonApi\Contract...shipInterface::getLinks of type Neomerx\JsonApi\Contracts\Parser\iterable.
Loading history...
413
            }
414
415
            /**
416
             * @inheritdoc
417
             */
418 38
            public function hasMeta(): bool
419
            {
420 38
                return $this->hasMeta;
421
            }
422
423
            /**
424
             * @inheritdoc
425
             */
426 1
            public function getMeta()
427
            {
428 1
                assert($this->hasMeta());
429
430 1
                if ($this->metaIsCallable === true) {
431 1
                    $this->meta           = call_user_func($this->meta);
432 1
                    $this->metaIsCallable = false;
433
                }
434
435 1
                return $this->meta;
436
            }
437
        };
438
    }
439
440
    /**
441
     * @inheritdoc
442
     */
443 23
    public function createRelationshipDataIsResource(
444
        SchemaContainerInterface $schemaContainer,
445
        PositionInterface $position,
446
        $resource
447
    ): RelationshipDataInterface {
448 23
        return new RelationshipDataIsResource($this, $schemaContainer, $position, $resource);
449
    }
450
451
    /**
452
     * @inheritdoc
453
     */
454 1
    public function createRelationshipDataIsIdentifier(
455
        SchemaContainerInterface $schemaContainer,
456
        PositionInterface $position,
457
        SchemaIdentifierInterface $identifier
458
    ): RelationshipDataInterface {
459 1
        return new RelationshipDataIsIdentifier($this, $schemaContainer, $position, $identifier);
460
    }
461
462
    /**
463
     * @inheritdoc
464
     */
465 31
    public function createRelationshipDataIsCollection(
466
        SchemaContainerInterface $schemaContainer,
467
        PositionInterface $position,
468
        iterable $resources
469
    ): RelationshipDataInterface {
470 31
        return new RelationshipDataIsCollection($this, $schemaContainer, $position, $resources);
471
    }
472
473
    /**
474
     * @inheritdoc
475
     */
476 5
    public function createRelationshipDataIsNull(): RelationshipDataInterface
477
    {
478 5
        return new RelationshipDataIsNull();
479
    }
480
481
    /**
482
     * @inheritdoc
483
     */
484 4
    public function createMediaType(string $type, string $subType, array $parameters = null): MediaTypeInterface
485
    {
486 4
        return new MediaType($type, $subType, $parameters);
487
    }
488
489
    /**
490
     * @inheritdoc
491
     */
492 12
    public function createAcceptMediaType(
493
        int $position,
494
        string $type,
495
        string $subType,
496
        array $parameters = null,
497
        float $quality = 1.0
498
    ): AcceptMediaTypeInterface {
499 12
        return new AcceptMediaType($position, $type, $subType, $parameters, $quality);
500
    }
501
}
502