JsonSchemas::getModelSchemas()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php declare (strict_types = 1);
2
3
namespace Limoncello\Flute\Schema;
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 Limoncello\Common\Reflection\ClassIsTrait;
22
use Limoncello\Contracts\Data\ModelSchemaInfoInterface;
23
use Limoncello\Flute\Contracts\Schema\JsonSchemasInterface;
24
use Limoncello\Flute\Contracts\Schema\SchemaInterface;
25
use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
26
use Neomerx\JsonApi\Contracts\Schema\SchemaInterface as JsonSchemaInterface;
27
use function array_key_exists;
28
use function assert;
29
use function get_class;
30
use function is_object;
31
32
/**
33
 * @package Limoncello\Flute
34
 */
35
class JsonSchemas implements JsonSchemasInterface
36
{
37
    use ClassIsTrait;
38
39
    /**
40
     * @var FactoryInterface
41
     */
42
    private $factory;
43
44
    /**
45
     * @var array
46
     */
47
    private $modelToSchemaMap;
48
49
    /**
50
     * @var array
51
     */
52
    private $typeToSchemaMap;
53
54
    /**
55
     * @var array
56
     */
57
    private $schemaInstances = [];
58
59
    /**
60
     * @var ModelSchemaInfoInterface
61
     */
62
    private $modelSchemas;
63
64
    /**
65
     * @param FactoryInterface         $factory
66 58
     * @param array                    $modelToSchemaMap
67
     * @param array                    $typeToSchemaMap
68
     * @param ModelSchemaInfoInterface $modelSchemas
69
     */
70
    public function __construct(
71
        FactoryInterface $factory,
72 58
        array $modelToSchemaMap,
73 58
        array $typeToSchemaMap,
74 58
        ModelSchemaInfoInterface $modelSchemas
75 58
    ) {
76
        $this->factory          = $factory;
77
        $this->modelToSchemaMap = $modelToSchemaMap;
78
        $this->typeToSchemaMap  = $typeToSchemaMap;
79
        $this->modelSchemas     = $modelSchemas;
80
    }
81 17
82
    /**
83 17
     * @inheritdoc
84
     */
85 17
    public function getSchema($resourceObject): JsonSchemaInterface
86
    {
87
        assert($this->hasSchema($resourceObject));
88
89
        return $this->getSchemaByModelClass($this->getResourceClass($resourceObject));
90
    }
91 17
92
    /**
93 17
     * @inheritdoc
94 17
     */
95
    public function hasSchema($resourceObject): bool
96
    {
97
        return is_object($resourceObject) === true &&
98
            array_key_exists($this->getResourceClass($resourceObject), $this->modelToSchemaMap);
99
    }
100 5
101
    /**
102 5
     * @inheritdoc
103
     */
104
    public function hasRelationshipSchema(string $schemaClass, string $relationshipName): bool
105
    {
106 5
        assert(static::classImplements($schemaClass, SchemaInterface::class));
107
108 5
        /** @var SchemaInterface $schemaClass */
109
110 5
        $hasRel = $schemaClass::getMappings()[SchemaInterface::SCHEMA_RELATIONSHIPS][$relationshipName] ?? false;
111
112
        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...
113
114
        return $hasRel !== false;
115
    }
116 20
117
    /**
118 20
     * @inheritdoc
119
     */
120
    public function getRelationshipSchema(string $schemaClass, string $relationshipName): SchemaInterface
121
    {
122 20
        assert(static::classImplements($schemaClass, SchemaInterface::class));
123 20
124
        /** @var SchemaInterface $schemaClass */
125 20
126
        $modelRelName = $schemaClass::getMappings()[SchemaInterface::SCHEMA_RELATIONSHIPS][$relationshipName];
127
        $targetSchema = $this->getModelRelationshipSchema($schemaClass::MODEL, $modelRelName);
128
129
        return $targetSchema;
130
    }
131 20
132
    /**
133 20
     * @inheritdoc
134
     */
135
    public function getModelRelationshipSchema(string $modelClass, string $relationshipName): SchemaInterface
136 20
    {
137
        $reverseModelClass = $this->getModelSchemas()->getReverseModelClass($modelClass, $relationshipName);
138 20
139
        /** @var SchemaInterface $targetSchema */
140
        $targetSchema = $this->getSchemaByModelClass($reverseModelClass);
141
142
        return $targetSchema;
143
    }
144 25
145
    /**
146 25
     * @inheritdoc
147
     */
148 25
    public function getSchemaByResourceType(string $resourceType): SchemaInterface
149
    {
150 25
        assert(array_key_exists($resourceType, $this->typeToSchemaMap));
151
152
        $schemaClass = $this->typeToSchemaMap[$resourceType];
153
154
        return $this->getSchemaByClass($schemaClass);
155
    }
156 28
157
    /**
158 28
     * @return FactoryInterface
159
     */
160
    private function getFactory(): FactoryInterface
161
    {
162
        return $this->factory;
163
    }
164 28
165
    /**
166 28
     * @return ModelSchemaInfoInterface
167
     */
168
    private function getModelSchemas(): ModelSchemaInfoInterface
169
    {
170
        return $this->modelSchemas;
171
    }
172
173
    /**
174 17
     * @param mixed $resource
175
     *
176 17
     * @return string
177 17
     */
178 17
    private function getResourceClass($resource): string
179
    {
180
        assert(
181 17
            is_object($resource) === true,
182
            'Unable to get a type of the resource as it is not an object.'
183
        );
184
185
        return get_class($resource);
186
    }
187 22
188
    /**
189 22
     * @inheritdoc
190
     */
191 22
    private function getSchemaByModelClass(string $modelClass): JsonSchemaInterface
192
    {
193 22
        assert(array_key_exists($modelClass, $this->modelToSchemaMap));
194
195
        $schemaClass = $this->modelToSchemaMap[$modelClass];
196
197
        return $this->getSchemaByClass($schemaClass);
198
    }
199
200
    /**
201 28
     * @param string $schemaClass
202
     *
203 28
     * @return SchemaInterface
204
     */
205 28
    private function getSchemaByClass(string $schemaClass): JsonSchemaInterface
206 28
    {
207 28
        assert(static::classImplements($schemaClass, JsonSchemaInterface::class));
208
209 28
        if (array_key_exists($schemaClass, $this->schemaInstances) === false) {
210
            $this->schemaInstances[$schemaClass] =
211
                ($schema = new $schemaClass($this->getFactory(), $this, $this->getModelSchemas()));
212 20
213
            return $schema;
214
        }
215
216
        return $this->schemaInstances[$schemaClass];
217
    }
218
}
219