Completed
Push — master ( dcfc04...697864 )
by Neomerx
04:30
created

JsonSchemas::hasSchema()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php namespace Limoncello\Flute\Schema;
2
3
/**
4
 * Copyright 2015-2018 [email protected]
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use Limoncello\Common\Reflection\ClassIsTrait;
20
use Limoncello\Contracts\Data\ModelSchemaInfoInterface;
21
use Limoncello\Flute\Contracts\Schema\JsonSchemasInterface;
22
use Limoncello\Flute\Contracts\Schema\SchemaInterface;
23
use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
24
use Neomerx\JsonApi\Contracts\Schema\SchemaInterface as JsonSchemaInterface;
25
26
/**
27
 * @package Limoncello\Flute
28
 */
29
class JsonSchemas implements JsonSchemasInterface
30
{
31
    use ClassIsTrait;
32
33
    /**
34
     * @var FactoryInterface
35
     */
36
    private $factory;
37
38
    /**
39
     * @var array
40
     */
41
    private $modelToSchemaMap;
42
43
    /**
44
     * @var array
45
     */
46
    private $typeToSchemaMap;
47
48
    /**
49
     * @var array
50
     */
51
    private $schemaInstances = [];
52
53
    /**
54
     * @var ModelSchemaInfoInterface
55
     */
56
    private $modelSchemas;
57
58
    /**
59
     * @param FactoryInterface         $factory
60
     * @param array                    $modelToSchemaMap
61
     * @param array                    $typeToSchemaMap
62
     * @param ModelSchemaInfoInterface $modelSchemas
63
     */
64 56
    public function __construct(
65
        FactoryInterface $factory,
66
        array $modelToSchemaMap,
67
        array $typeToSchemaMap,
68
        ModelSchemaInfoInterface $modelSchemas
69
    ) {
70 56
        $this->factory          = $factory;
71 56
        $this->modelToSchemaMap = $modelToSchemaMap;
72 56
        $this->typeToSchemaMap  = $typeToSchemaMap;
73 56
        $this->modelSchemas     = $modelSchemas;
74
    }
75
76
    /**
77
     * @inheritdoc
78
     */
79 17
    public function getSchema($resourceObject): JsonSchemaInterface
80
    {
81 17
        assert($this->hasSchema($resourceObject));
82
83 17
        return $this->getSchemaByModelClass($this->getResourceClass($resourceObject));
84
    }
85
86
    /**
87
     * @inheritdoc
88
     */
89 17
    public function hasSchema($resourceObject): bool
90
    {
91 17
        return is_object($resourceObject) === true &&
92 17
            array_key_exists($this->getResourceClass($resourceObject), $this->modelToSchemaMap);
93
    }
94
95
    /**
96
     * @inheritdoc
97
     */
98 5
    public function hasRelationshipSchema(string $schemaClass, string $relationshipName): bool
99
    {
100 5
        assert(static::classImplements($schemaClass, SchemaInterface::class));
101
102
        /** @var SchemaInterface $schemaClass */
103
104 5
        $hasRel = $schemaClass::getMappings()[SchemaInterface::SCHEMA_RELATIONSHIPS][$relationshipName] ?? false;
105
106 5
        assert($hasRel === false || $this->getRelationshipSchema($schemaClass, $relationshipName) !== null);
0 ignored issues
show
Documentation introduced by
$schemaClass is of type object<Limoncello\Flute\...Schema\SchemaInterface>, but the function expects a string.

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...
107
108 5
        return $hasRel !== false;
109
    }
110
111
    /**
112
     * @inheritdoc
113
     */
114 20
    public function getRelationshipSchema(string $schemaClass, string $relationshipName): SchemaInterface
115
    {
116 20
        assert(static::classImplements($schemaClass, SchemaInterface::class));
117
118
        /** @var SchemaInterface $schemaClass */
119
120 20
        $modelRelName = $schemaClass::getMappings()[SchemaInterface::SCHEMA_RELATIONSHIPS][$relationshipName];
121 20
        $targetSchema = $this->getModelRelationshipSchema($schemaClass::MODEL, $modelRelName);
122
123 20
        return $targetSchema;
124
    }
125
126
    /**
127
     * @inheritdoc
128
     */
129 20
    public function getModelRelationshipSchema(string $modelClass, string $relationshipName): SchemaInterface
130
    {
131 20
        $reverseModelClass = $this->getModelSchemas()->getReverseModelClass($modelClass, $relationshipName);
132
133
        /** @var SchemaInterface $targetSchema */
134 20
        $targetSchema = $this->getSchemaByModelClass($reverseModelClass);
135
136 20
        return $targetSchema;
137
    }
138
139
    /**
140
     * @inheritdoc
141
     */
142 25
    public function getSchemaByResourceType(string $resourceType): SchemaInterface
143
    {
144 25
        assert(array_key_exists($resourceType, $this->typeToSchemaMap));
145
146 25
        $schemaClass = $this->typeToSchemaMap[$resourceType];
147
148 25
        return $this->getSchemaByClass($schemaClass);
149
    }
150
151
    /**
152
     * @return FactoryInterface
153
     */
154 28
    private function getFactory(): FactoryInterface
155
    {
156 28
        return $this->factory;
157
    }
158
159
    /**
160
     * @return ModelSchemaInfoInterface
161
     */
162 28
    private function getModelSchemas(): ModelSchemaInfoInterface
163
    {
164 28
        return $this->modelSchemas;
165
    }
166
167
    /**
168
     * @param mixed $resource
169
     *
170
     * @return string
171
     */
172 17
    private function getResourceClass($resource): string
173
    {
174 17
        assert(
175 17
            is_object($resource) === true,
176 17
            'Unable to get a type of the resource as it is not an object.'
177
        );
178
179 17
        return get_class($resource);
180
    }
181
182
    /**
183
     * @inheritdoc
184
     */
185 22
    private function getSchemaByModelClass(string $modelClass): JsonSchemaInterface
186
    {
187 22
        assert(array_key_exists($modelClass, $this->modelToSchemaMap));
188
189 22
        $schemaClass = $this->modelToSchemaMap[$modelClass];
190
191 22
        return $this->getSchemaByClass($schemaClass);
192
    }
193
194
    /**
195
     * @param string $schemaClass
196
     *
197
     * @return SchemaInterface
198
     */
199 28
    private function getSchemaByClass(string $schemaClass): JsonSchemaInterface
200
    {
201 28
        assert(static::classImplements($schemaClass, JsonSchemaInterface::class));
202
203 28
        if (array_key_exists($schemaClass, $this->schemaInstances) === false) {
204 28
            $this->schemaInstances[$schemaClass] =
205 28
                ($schema = new $schemaClass($this->getFactory(), $this, $this->getModelSchemas()));
206
207 28
            return $schema;
208
        }
209
210 20
        return $this->schemaInstances[$schemaClass];
211
    }
212
}
213