Completed
Branch master (9645b9)
by Neomerx
02:19
created

Factory::createRelationship()   B

Complexity

Conditions 2
Paths 1

Size

Total Lines 160

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 1
nop 7
dl 0
loc 160
ccs 34
cts 34
cp 1
crap 2
rs 8
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
B Factory.php$2 ➔ __construct() 0 23 7
A Factory.php$2 ➔ getPosition() 0 4 1
A Factory.php$2 ➔ hasData() 0 4 1
A Factory.php$2 ➔ getData() 0 6 1
A Factory.php$2 ➔ hasLinks() 0 4 1
A Factory.php$2 ➔ getLinks() 0 6 1
A Factory.php$2 ➔ hasMeta() 0 4 1
A Factory.php$2 ➔ getMeta() 0 11 2

How to fix   Long Method   

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 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
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
56
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
57
 */
58
class Factory implements FactoryInterface
59
{
60
    /**
61
     * @inheritdoc
62
     */
63 76
    public function createEncoder(SchemaContainerInterface $container): EncoderInterface
64
    {
65 76
        return new Encoder($this, $container);
66
    }
67
68
    /**
69
     * @inheritdoc
70
     */
71 89
    public function createSchemaContainer(iterable $schemas): SchemaContainerInterface
72
    {
73 89
        return new SchemaContainer($this, $schemas);
74
    }
75
76
    /**
77
     * @inheritdoc
78
     */
79 75
    public function createPosition(
80
        int $level,
81
        string $path,
82
        ?string $parentType,
83
        ?string $parentRelationship
84
    ): PositionInterface {
85
        return new class ($level, $path, $parentType, $parentRelationship) implements PositionInterface
86
        {
87
            /**
88
             * @var int
89
             */
90
            private $level;
91
92
            /**
93
             * @var string
94
             */
95
            private $path;
96
97
            /**
98
             * @var null|string
99
             */
100
            private $parentType;
101
102
            /**
103
             * @var null|string
104
             */
105
            private $parentRelationship;
106
107
            /**
108
             * @param int         $level
109
             * @param string      $path
110
             * @param null|string $parentType
111
             * @param null|string $parentRelationship
112
             */
113
            public function __construct(int $level, string $path, ?string $parentType, ?string $parentRelationship)
114
            {
115 75
                $this->level              = $level;
116 75
                $this->path               = $path;
117 75
                $this->parentType         = $parentType;
118 75
                $this->parentRelationship = $parentRelationship;
119 75
            }
120
121
            /**
122
             * @inheritdoc
123
             */
124
            public function getLevel(): int
125
            {
126 70
                return $this->level;
127
            }
128
129
            /**
130
             * @inheritdoc
131
             */
132
            public function getPath(): string
133
            {
134 60
                return $this->path;
135
            }
136
137
            /**
138
             * @inheritdoc
139
             */
140
            public function getParentType(): ?string
141
            {
142 21
                return $this->parentType;
143
            }
144
145
            /**
146
             * @inheritdoc
147
             */
148
            public function getParentRelationship(): ?string
149
            {
150 7
                return $this->parentRelationship;
151
            }
152
        };
153
    }
154
155
    /**
156
     * @inheritdoc
157
     */
158 71
    public function createParser(SchemaContainerInterface $container): ParserInterface
159
    {
160 71
        return new Parser($this, $container);
161
    }
162
163
    /**
164
     * @inheritdoc
165
     */
166 73
    public function createDocumentWriter(): DocumentWriterInterface
167
    {
168 73
        return new DocumentWriter();
169
    }
170
171
    /**
172
     * @inheritdoc
173
     */
174 7
    public function createErrorWriter(): ErrorWriterInterface
175
    {
176 7
        return new ErrorWriter();
177
    }
178
179
    /**
180
     * @inheritdoc
181
     */
182 70
    public function createFieldSetFilter(array $fieldSets): FieldSetFilterInterface
183
    {
184 70
        return new FieldSetFilter($fieldSets);
185
    }
186
187
    /**
188
     * @inheritdoc
189
     */
190 60
    public function createParsedResource(
191
        PositionInterface $position,
192
        SchemaContainerInterface $container,
193
        $data
194
    ): ResourceInterface {
195 60
        return new IdentifierAndResource($position, $this, $container, $data);
196
    }
197
198
    /**
199
     * @inheritdoc
200
     */
201 1
    public function createParsedIdentifier(
202
        PositionInterface $position,
203
        SchemaIdentifierInterface $identifier
204
    ): ParserIdentifierInterface {
205
        return new class ($position, $identifier) implements ParserIdentifierInterface
206
        {
207
            /**
208
             * @var PositionInterface
209
             */
210
            private $position;
211
212
            /**
213
             * @var SchemaIdentifierInterface
214
             */
215
            private $identifier;
216
217
            /**
218
             * @param PositionInterface         $position
219
             * @param SchemaIdentifierInterface $identifier
220
             */
221
            public function __construct(
222
                PositionInterface $position,
223
                SchemaIdentifierInterface $identifier
224
            ) {
225 1
                $this->position   = $position;
226 1
                $this->identifier = $identifier;
227
228
                // for test coverage only
229 1
                assert($this->getPosition() !== null);
230 1
            }
231
232
            /**
233
             * @inheritdoc
234
             */
235
            public function getType(): string
236
            {
237 1
                return $this->identifier->getType();
238
            }
239
240
            /**
241
             * @inheritdoc
242
             */
243
            public function getId(): ?string
244
            {
245 1
                return $this->identifier->getId();
246
            }
247
248
            /**
249
             * @inheritdoc
250
             */
251
            public function hasIdentifierMeta(): bool
252
            {
253 1
                return $this->identifier->hasIdentifierMeta();
254
            }
255
256
            /**
257
             * @inheritdoc
258
             */
259
            public function getIdentifierMeta()
260
            {
261 1
                return $this->identifier->getIdentifierMeta();
262
            }
263
264
            /**
265
             * @inheritdoc
266
             */
267
            public function getPosition(): PositionInterface
268
            {
269 1
                return $this->position;
270
            }
271
        };
272
    }
273
274
    /**
275
     * @inheritdoc
276
     */
277 62
    public function createLink(bool $isSubUrl, string $value, bool $hasMeta, $meta = null): LinkInterface
278
    {
279 62
        return new Link($isSubUrl, $value, $hasMeta, $meta);
280
    }
281
282
    /**
283
     * @inheritdoc
284
     *
285
     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
286
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
287
     */
288
    public function createRelationship(
289
        PositionInterface $position,
290
        bool $hasData,
291
        ?RelationshipDataInterface $data,
292
        bool $hasLinks,
293
        ?iterable $links,
294
        bool $hasMeta,
295
        $meta
296
    ): RelationshipInterface {
297
        return new class (
298
            $position,
299
            $hasData,
300
            $data,
301
            $hasLinks,
302
            $links,
303
            $hasMeta,
304
            $meta
305
        ) implements RelationshipInterface
306
        {
307
            /**
308
             * @var PositionInterface
309
             */
310
            private $position;
311
312
            /**
313
             * @var bool
314
             */
315
            private $hasData;
316
317
            /**
318
             * @var ?RelationshipDataInterface
319
             */
320
            private $data;
321
322
            /**
323
             * @var bool
324
             */
325
            private $hasLinks;
326
327
            /**
328
             * @var ?iterable
329
             */
330
            private $links;
331
332
            /**
333
             * @var bool
334
             */
335
            private $hasMeta;
336
337
            /**
338
             * @var mixed
339
             */
340
            private $meta;
341
342
            /**
343
             * @var bool
344
             */
345
            private $metaIsCallable;
346
347
            /**
348
             * @param PositionInterface              $position
349
             * @param bool                           $hasData
350
             * @param RelationshipDataInterface|null $data
351
             * @param bool                           $hasLinks
352
             * @param iterable|null                  $links
353
             * @param bool                           $hasMeta
354
             * @param mixed                          $meta
355
             */
356 45
            public function __construct(
357
                PositionInterface $position,
358
                bool $hasData,
359
                ?RelationshipDataInterface $data,
360
                bool $hasLinks,
361
                ?iterable $links,
362
                bool $hasMeta,
363
                $meta
364
            ) {
365 45
                assert($position->getLevel() > ParserInterface::ROOT_LEVEL);
366 45
                assert(empty($position->getPath()) === false);
367 45
                assert(($hasData === false && $data === null) || ($hasData === true && $data !== null));
368 45
                assert(($hasLinks === false && $links === null) || ($hasLinks === true && $links !== null));
369
370 45
                $this->position       = $position;
371 45
                $this->hasData        = $hasData;
372 45
                $this->data           = $data;
373 45
                $this->hasLinks       = $hasLinks;
374 45
                $this->links          = $links;
375 45
                $this->hasMeta        = $hasMeta;
376 45
                $this->meta           = $meta;
377 45
                $this->metaIsCallable = is_callable($meta);
378 45
            }
379
380
            /**
381
             * @inheritdoc
382
             */
383 45
            public function getPosition(): PositionInterface
384
            {
385 45
                return $this->position;
386
            }
387
388
            /**
389
             * @inheritdoc
390
             */
391 45
            public function hasData(): bool
392
            {
393 45
                return $this->hasData;
394
            }
395
396
            /**
397
             * @inheritdoc
398
             */
399 33
            public function getData(): RelationshipDataInterface
400
            {
401 33
                assert($this->hasData());
402
403 33
                return $this->data;
404
            }
405
406
            /**
407
             * @inheritdoc
408
             */
409 39
            public function hasLinks(): bool
410
            {
411 39
                return $this->hasLinks;
412
            }
413
414
            /**
415
             * @inheritdoc
416
             */
417 22
            public function getLinks(): iterable
418
            {
419 22
                assert($this->hasLinks());
420
421 22
                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 421 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...
422
            }
423
424
            /**
425
             * @inheritdoc
426
             */
427 39
            public function hasMeta(): bool
428
            {
429 39
                return $this->hasMeta;
430
            }
431
432
            /**
433
             * @inheritdoc
434
             */
435 1
            public function getMeta()
436
            {
437 1
                assert($this->hasMeta());
438
439 1
                if ($this->metaIsCallable === true) {
440 1
                    $this->meta           = call_user_func($this->meta);
441 1
                    $this->metaIsCallable = false;
442
                }
443
444 1
                return $this->meta;
445
            }
446
        };
447
    }
448
449
    /**
450
     * @inheritdoc
451
     */
452 23
    public function createRelationshipDataIsResource(
453
        SchemaContainerInterface $schemaContainer,
454
        PositionInterface $position,
455
        $resource
456
    ): RelationshipDataInterface {
457 23
        return new RelationshipDataIsResource($this, $schemaContainer, $position, $resource);
458
    }
459
460
    /**
461
     * @inheritdoc
462
     */
463 1
    public function createRelationshipDataIsIdentifier(
464
        SchemaContainerInterface $schemaContainer,
465
        PositionInterface $position,
466
        SchemaIdentifierInterface $identifier
467
    ): RelationshipDataInterface {
468 1
        return new RelationshipDataIsIdentifier($this, $schemaContainer, $position, $identifier);
469
    }
470
471
    /**
472
     * @inheritdoc
473
     */
474 31
    public function createRelationshipDataIsCollection(
475
        SchemaContainerInterface $schemaContainer,
476
        PositionInterface $position,
477
        iterable $resources
478
    ): RelationshipDataInterface {
479 31
        return new RelationshipDataIsCollection($this, $schemaContainer, $position, $resources);
480
    }
481
482
    /**
483
     * @inheritdoc
484
     */
485 5
    public function createRelationshipDataIsNull(): RelationshipDataInterface
486
    {
487 5
        return new RelationshipDataIsNull();
488
    }
489
490
    /**
491
     * @inheritdoc
492
     */
493 4
    public function createMediaType(string $type, string $subType, array $parameters = null): MediaTypeInterface
494
    {
495 4
        return new MediaType($type, $subType, $parameters);
496
    }
497
498
    /**
499
     * @inheritdoc
500
     */
501 12
    public function createAcceptMediaType(
502
        int $position,
503
        string $type,
504
        string $subType,
505
        array $parameters = null,
506
        float $quality = 1.0
507
    ): AcceptMediaTypeInterface {
508 12
        return new AcceptMediaType($position, $type, $subType, $parameters, $quality);
509
    }
510
}
511