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

ParseRelationshipDataTrait   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 90
ccs 37
cts 37
cp 1
rs 10
c 0
b 0
f 0
wmc 13
lcom 0
cbo 3

2 Methods

Rating   Name   Duplication   Size   Complexity  
A parseRelationshipData() 0 36 5
B parseData() 0 31 8
1
<?php declare(strict_types=1);
2
3
namespace Neomerx\JsonApi\Parser\RelationshipData;
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 IteratorAggregate;
22
use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
23
use Neomerx\JsonApi\Contracts\Parser\PositionInterface;
24
use Neomerx\JsonApi\Contracts\Parser\RelationshipDataInterface;
25
use Neomerx\JsonApi\Contracts\Schema\IdentifierInterface;
26
use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
27
use Neomerx\JsonApi\Contracts\Schema\SchemaInterface;
28
use Neomerx\JsonApi\Exceptions\InvalidArgumentException;
29
use Neomerx\JsonApi\Parser\IdentifierAndResource;
30
use Traversable;
31
use function Neomerx\JsonApi\I18n\format as _;
32
33
/**
34
 * @package Neomerx\JsonApi
35
 */
36
trait ParseRelationshipDataTrait
37
{
38
    /**
39
     * @param FactoryInterface         $factory
40
     * @param SchemaContainerInterface $container
41
     * @param string                   $parentType
42
     * @param string                   $name
43
     * @param array                    $description
44
     * @param int                      $nextLevel
45
     * @param string                   $nextPathPrefix
46
     *
47
     * @return array [has data, parsed data]
48
     */
49 45
    private function parseRelationshipData(
50
        FactoryInterface $factory,
51
        SchemaContainerInterface $container,
52
        string $parentType,
53
        string $name,
54
        array $description,
55
        int $nextLevel,
56
        string $nextPathPrefix
57
    ): array {
58 45
        $hasData = array_key_exists(SchemaInterface::RELATIONSHIP_DATA, $description);
59
        // either no data or data should be array/object/null
60 45
        assert(
61 45
            $hasData === false ||
62
            (
63 34
                is_array($data = $description[SchemaInterface::RELATIONSHIP_DATA]) === true ||
64 29
                is_object($data) === true ||
65 45
                $data === null
66
            )
67
        );
68
69 45
        $nextPosition = $factory->createPosition(
70 45
            $nextLevel,
71 45
            $nextPathPrefix . $name,
72 45
            $parentType,
73 45
            $name
74
        );
75
76 45
        $relationshipData = $hasData === true ? $this->parseData(
77 34
            $factory,
78 34
            $container,
79 34
            $nextPosition,
80 34
            $description[SchemaInterface::RELATIONSHIP_DATA]
81 45
        ) : null;
82
83 45
        return [$hasData, $relationshipData, $nextPosition];
84
    }
85
86
    /**
87
     * @param FactoryInterface         $factory
88
     * @param SchemaContainerInterface $container
89
     * @param PositionInterface        $position
90
     * @param mixed                    $data
91
     *
92
     * @return RelationshipDataInterface
93
     */
94 34
    private function parseData(
95
        FactoryInterface $factory,
96
        SchemaContainerInterface $container,
97
        PositionInterface $position,
98
        $data
99
    ): RelationshipDataInterface {
100
        // support if data is callable (e.g. a closure used to postpone actual data reading)
101 34
        if (is_callable($data) === true) {
102 1
            $data = call_user_func($data);
103
        }
104
105 34
        if ($container->hasSchema($data) === true) {
106 23
            return $factory->createRelationshipDataIsResource($container, $position, $data);
107 33
        } elseif ($data instanceof IdentifierInterface) {
108 1
            return $factory->createRelationshipDataIsIdentifier($container, $position, $data);
109 32
        } elseif (is_array($data) === true) {
110 30
            return $factory->createRelationshipDataIsCollection($container, $position, $data);
0 ignored issues
show
Documentation introduced by
$data is of type array, but the function expects a object<Neomerx\JsonApi\C...cts\Factories\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
111 6
        } elseif ($data instanceof Traversable) {
112 1
            return $factory->createRelationshipDataIsCollection(
113 1
                $container,
114 1
                $position,
115 1
                $data instanceof IteratorAggregate ? $data->getIterator() : $data
0 ignored issues
show
Documentation introduced by
$data instanceof \Iterat...->getIterator() : $data is of type object<Traversable>, but the function expects a object<Neomerx\JsonApi\C...cts\Factories\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
116
            );
117 5
        } elseif ($data === null) {
118 5
            return $factory->createRelationshipDataIsNull();
119
        }
120
121 1
        throw new InvalidArgumentException(
122 1
            _(IdentifierAndResource::MSG_NO_SCHEMA_FOUND, get_class($data), $position->getPath())
123
        );
124
    }
125
}
126