Factory.php$2 ➔ getLinks()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Neomerx\JsonApi\Factories;
4
5
/**
6
 * Copyright 2015-2020 [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\EditableContextInterface;
26
use Neomerx\JsonApi\Contracts\Parser\IdentifierInterface as ParserIdentifierInterface;
27
use Neomerx\JsonApi\Contracts\Parser\ParserInterface;
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\PositionInterface;
37
use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
38
use Neomerx\JsonApi\Encoder\Encoder;
39
use Neomerx\JsonApi\Http\Headers\AcceptMediaType;
40
use Neomerx\JsonApi\Http\Headers\MediaType;
41
use Neomerx\JsonApi\Parser\IdentifierAndResource;
42
use Neomerx\JsonApi\Parser\Parser;
43
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsCollection;
44
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsIdentifier;
45
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsNull;
46
use Neomerx\JsonApi\Parser\RelationshipData\RelationshipDataIsResource;
47
use Neomerx\JsonApi\Representation\DocumentWriter;
48
use Neomerx\JsonApi\Representation\ErrorWriter;
49
use Neomerx\JsonApi\Representation\FieldSetFilter;
50
use Neomerx\JsonApi\Schema\Link;
51
use Neomerx\JsonApi\Schema\SchemaContainer;
52
53
/**
54
 * @package Neomerx\JsonApi
55
 *
56
 * @SuppressWarnings(PHPMD.TooManyFields)
57
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
58
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
59
 */
60
class Factory implements FactoryInterface
61
{
62
    /**
63
     * @inheritdoc
64
     */
65 81
    public function createEncoder(SchemaContainerInterface $container): EncoderInterface
66
    {
67 81
        return new Encoder($this, $container);
68
    }
69
70
    /**
71
     * @inheritdoc
72
     */
73 94
    public function createSchemaContainer(iterable $schemas): SchemaContainerInterface
74
    {
75 94
        return new SchemaContainer($this, $schemas);
76
    }
77
78
    /**
79
     * @inheritdoc
80
     */
81 80
    public function createPosition(
82
        int $level,
83
        string $path,
84
        ?string $parentType,
85
        ?string $parentRelationship
86
    ): PositionInterface {
87
        return new class ($level, $path, $parentType, $parentRelationship) implements PositionInterface
88
        {
89
            /**
90
             * @var int
91
             */
92
            private $level;
93
94
            /**
95
             * @var string
96
             */
97
            private $path;
98
99
            /**
100
             * @var null|string
101
             */
102
            private $parentType;
103
104
            /**
105
             * @var null|string
106
             */
107
            private $parentRelationship;
108
109
            /**
110
             * @param int         $level
111
             * @param string      $path
112
             * @param null|string $parentType
113
             * @param null|string $parentRelationship
114
             */
115
            public function __construct(int $level, string $path, ?string $parentType, ?string $parentRelationship)
116
            {
117 80
                $this->level              = $level;
118 80
                $this->path               = $path;
119 80
                $this->parentType         = $parentType;
120 80
                $this->parentRelationship = $parentRelationship;
121 80
            }
122
123
            /**
124
             * @inheritdoc
125
             */
126 75
            public function getLevel(): int
127
            {
128 75
                return $this->level;
129
            }
130
131
            /**
132
             * @inheritdoc
133
             */
134 65
            public function getPath(): string
135
            {
136 65
                return $this->path;
137
            }
138
139
            /**
140
             * @inheritdoc
141
             */
142 25
            public function getParentType(): ?string
143
            {
144 25
                return $this->parentType;
145
            }
146
147
            /**
148
             * @inheritdoc
149
             */
150 7
            public function getParentRelationship(): ?string
151
            {
152 7
                return $this->parentRelationship;
153
            }
154
        };
155
    }
156
157
    /**
158
     * @inheritdoc
159
     */
160 74
    public function createParser(
161
        SchemaContainerInterface $container,
162
        EditableContextInterface $context
163
    ): ParserInterface {
164 74
        return new Parser($this, $container, $context);
165
    }
166
167
    /**
168
     * @inheritdoc
169
     */
170 78
    public function createDocumentWriter(): DocumentWriterInterface
171
    {
172 78
        return new DocumentWriter();
173
    }
174
175
    /**
176
     * @inheritdoc
177
     */
178 7
    public function createErrorWriter(): ErrorWriterInterface
179
    {
180 7
        return new ErrorWriter();
181
    }
182
183
    /**
184
     * @inheritdoc
185
     */
186 75
    public function createFieldSetFilter(array $fieldSets): FieldSetFilterInterface
187
    {
188 75
        return new FieldSetFilter($fieldSets);
189
    }
190
191
    /**
192
     * @inheritdoc
193
     */
194 64
    public function createParsedResource(
195
        EditableContextInterface $context,
196
        PositionInterface $position,
197
        SchemaContainerInterface $container,
198
        $data
199
    ): ResourceInterface {
200 64
        return new IdentifierAndResource($context, $position, $this, $container, $data);
201
    }
202
203
    /**
204
     * @inheritdoc
205
     */
206 2
    public function createParsedIdentifier(
207
        PositionInterface $position,
208
        SchemaIdentifierInterface $identifier
209
    ): ParserIdentifierInterface {
210
        return new class ($position, $identifier) implements ParserIdentifierInterface
211
        {
212
            /**
213
             * @var PositionInterface
214
             */
215
            private $position;
216
217
            /**
218
             * @var SchemaIdentifierInterface
219
             */
220
            private $identifier;
221
222
            /**
223
             * @param PositionInterface         $position
224
             * @param SchemaIdentifierInterface $identifier
225
             */
226
            public function __construct(
227
                PositionInterface $position,
228
                SchemaIdentifierInterface $identifier
229
            ) {
230 2
                $this->position   = $position;
231 2
                $this->identifier = $identifier;
232
233
                // for test coverage only
234 2
                \assert($this->getPosition() !== null);
235 2
            }
236
237
            /**
238
             * @inheritdoc
239
             */
240 2
            public function getType(): string
241
            {
242 2
                return $this->identifier->getType();
243
            }
244
245
            /**
246
             * @inheritdoc
247
             */
248 2
            public function getId(): ?string
249
            {
250 2
                return $this->identifier->getId();
251
            }
252
253
            /**
254
             * @inheritdoc
255
             */
256 2
            public function hasIdentifierMeta(): bool
257
            {
258 2
                return $this->identifier->hasIdentifierMeta();
259
            }
260
261
            /**
262
             * @inheritdoc
263
             */
264 1
            public function getIdentifierMeta()
265
            {
266 1
                return $this->identifier->getIdentifierMeta();
267
            }
268
269
            /**
270
             * @inheritdoc
271
             */
272
            public function getPosition(): PositionInterface
273
            {
274 2
                return $this->position;
275
            }
276
        };
277
    }
278
279
    /**
280
     * @inheritdoc
281
     */
282 67
    public function createLink(bool $isSubUrl, string $value, bool $hasMeta, $meta = null): LinkInterface
283
    {
284 67
        return new Link($isSubUrl, $value, $hasMeta, $meta);
285
    }
286
287
    /**
288
     * @inheritdoc
289
     *
290
     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
291
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
292
     */
293 50
    public function createRelationship(
294
        PositionInterface $position,
295
        bool $hasData,
296
        ?RelationshipDataInterface $data,
297
        bool $hasLinks,
298
        ?iterable $links,
299
        bool $hasMeta,
300
        $meta
301
    ): RelationshipInterface {
302
        return new class (
303 50
            $position,
304 50
            $hasData,
305 50
            $data,
306 50
            $hasLinks,
307 50
            $links,
308 50
            $hasMeta,
309 50
            $meta
310
        ) implements RelationshipInterface
311
        {
312
            /**
313
             * @var PositionInterface
314
             */
315
            private $position;
316
317
            /**
318
             * @var bool
319
             */
320
            private $hasData;
321
322
            /**
323
             * @var ?RelationshipDataInterface
324
             */
325
            private $data;
326
327
            /**
328
             * @var bool
329
             */
330
            private $hasLinks;
331
332
            /**
333
             * @var ?iterable
334
             */
335
            private $links;
336
337
            /**
338
             * @var bool
339
             */
340
            private $hasMeta;
341
342
            /**
343
             * @var mixed
344
             */
345
            private $meta;
346
347
            /**
348
             * @var bool
349
             */
350
            private $metaIsCallable;
351
352
            /**
353
             * @param PositionInterface              $position
354
             * @param bool                           $hasData
355
             * @param RelationshipDataInterface|null $data
356
             * @param bool                           $hasLinks
357
             * @param iterable|null                  $links
358
             * @param bool                           $hasMeta
359
             * @param mixed                          $meta
360
             */
361
            public function __construct(
362
                PositionInterface $position,
363
                bool $hasData,
364
                ?RelationshipDataInterface $data,
365
                bool $hasLinks,
366
                ?iterable $links,
367
                bool $hasMeta,
368
                $meta
369
            ) {
370 50
                \assert($position->getLevel() > ParserInterface::ROOT_LEVEL);
371 50
                \assert(empty($position->getPath()) === false);
372 50
                \assert(($hasData === false && $data === null) || ($hasData === true && $data !== null));
373 50
                \assert(($hasLinks === false && $links === null) || ($hasLinks === true && $links !== null));
374
375 50
                $this->position       = $position;
376 50
                $this->hasData        = $hasData;
377 50
                $this->data           = $data;
378 50
                $this->hasLinks       = $hasLinks;
379 50
                $this->links          = $links;
380 50
                $this->hasMeta        = $hasMeta;
381 50
                $this->meta           = $meta;
382 50
                $this->metaIsCallable = \is_callable($meta);
383 50
            }
384
385
            /**
386
             * @inheritdoc
387
             */
388
            public function getPosition(): PositionInterface
389
            {
390 50
                return $this->position;
391
            }
392
393
            /**
394
             * @inheritdoc
395
             */
396 45
            public function hasData(): bool
397
            {
398 45
                return $this->hasData;
399
            }
400
401
            /**
402
             * @inheritdoc
403
             */
404 38
            public function getData(): RelationshipDataInterface
405
            {
406 38
                \assert($this->hasData());
407
408 38
                return $this->data;
409
            }
410
411
            /**
412
             * @inheritdoc
413
             */
414 44
            public function hasLinks(): bool
415
            {
416 44
                return $this->hasLinks;
417
            }
418
419
            /**
420
             * @inheritdoc
421
             */
422 27
            public function getLinks(): iterable
423
            {
424 27
                \assert($this->hasLinks());
425
426 27
                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 426 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...
427
            }
428
429
            /**
430
             * @inheritdoc
431
             */
432 44
            public function hasMeta(): bool
433
            {
434 44
                return $this->hasMeta;
435
            }
436
437
            /**
438
             * @inheritdoc
439
             */
440 2
            public function getMeta()
441
            {
442 2
                \assert($this->hasMeta());
443
444 2
                if ($this->metaIsCallable === true) {
445 1
                    $this->meta           = \call_user_func($this->meta);
446 1
                    $this->metaIsCallable = false;
447
                }
448
449 2
                return $this->meta;
450
            }
451
        };
452
    }
453
454
    /**
455
     * @inheritdoc
456
     */
457 27
    public function createRelationshipDataIsResource(
458
        SchemaContainerInterface $schemaContainer,
459
        EditableContextInterface $context,
460
        PositionInterface $position,
461
        $resource
462
    ): RelationshipDataInterface {
463 27
        return new RelationshipDataIsResource($this, $schemaContainer, $context, $position, $resource);
464
    }
465
466
    /**
467
     * @inheritdoc
468
     */
469 1
    public function createRelationshipDataIsIdentifier(
470
        SchemaContainerInterface $schemaContainer,
471
        EditableContextInterface $context,
472
        PositionInterface $position,
473
        SchemaIdentifierInterface $identifier
474
    ): RelationshipDataInterface {
475 1
        return new RelationshipDataIsIdentifier($this, $schemaContainer, $context, $position, $identifier);
476
    }
477
478
    /**
479
     * @inheritdoc
480
     */
481 35
    public function createRelationshipDataIsCollection(
482
        SchemaContainerInterface $schemaContainer,
483
        EditableContextInterface $context,
484
        PositionInterface $position,
485
        iterable $resources
486
    ): RelationshipDataInterface {
487 35
        return new RelationshipDataIsCollection($this, $schemaContainer, $context, $position, $resources);
488
    }
489
490
    /**
491
     * @inheritdoc
492
     */
493 5
    public function createRelationshipDataIsNull(): RelationshipDataInterface
494
    {
495 5
        return new RelationshipDataIsNull();
496
    }
497
498
    /**
499
     * @inheritdoc
500
     */
501 4
    public function createMediaType(string $type, string $subType, array $parameters = null): MediaTypeInterface
502
    {
503 4
        return new MediaType($type, $subType, $parameters);
504
    }
505
506
    /**
507
     * @inheritdoc
508
     */
509 12
    public function createAcceptMediaType(
510
        int $position,
511
        string $type,
512
        string $subType,
513
        array $parameters = null,
514
        float $quality = 1.0
515
    ): AcceptMediaTypeInterface {
516 12
        return new AcceptMediaType($position, $type, $subType, $parameters, $quality);
517
    }
518
519
    /**
520
     * @inheritdoc
521
     *
522
     * @SuppressWarnings(PHPMD.UndefinedVariable) PHPMD currently has a glitch with `$position` in `setPosition`
523
     */
524 80
    public function createParserContext(array $fieldSets, array $includePaths): EditableContextInterface
525
    {
526
        return new class ($fieldSets, $includePaths) implements EditableContextInterface
527
        {
528
            /**
529
             * @var array
530
             */
531
            private $fieldSets;
532
533
            /**
534
             * @var array
535
             */
536
            private $includePaths;
537
538
            /**
539
             * @var PositionInterface|null
540
             */
541
            private $position = null;
542
543
            /**
544
             * @param array $fieldSets
545
             * @param array $includePaths
546
             */
547
            public function __construct(array $fieldSets, array $includePaths)
548
            {
549 80
                $this->fieldSets    = $fieldSets;
550 80
                $this->includePaths = $includePaths;
551 80
            }
552
553
            /**
554
             * @inheritdoc
555
             */
556 35
            public function getFieldSets(): array
557
            {
558 35
                return $this->fieldSets;
559
            }
560
561
            /**
562
             * @inheritdoc
563
             */
564 35
            public function getIncludePaths(): array
565
            {
566 35
                return $this->includePaths;
567
            }
568
569
            /**
570
             * @inheritdoc
571
             */
572
            public function getPosition(): PositionInterface
573
            {
574
                // parser's implementation should guarantee that position will always be initialized
575
                // before use in a schema.
576 35
                \assert($this->position !== null);
577
578 35
                return $this->position;
579
            }
580
581
            /**
582
             * @inheritdoc
583
             */
584 65
            public function setPosition(PositionInterface $position): void
585
            {
586 65
                $this->position = $position;
587 65
            }
588
        };
589
    }
590
}
591