Completed
Push — master ( 1a67d2...dfab50 )
by Neomerx
11:35 queued 22s
created

JsonApiDataRulesSerializer   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 288
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 4
dl 0
loc 288
rs 10
c 0
b 0
f 0
ccs 79
cts 79
cp 1

19 Methods

Rating   Name   Duplication   Size   Complexity  
A addRulesFromClass() 0 17 1
B addDataRules() 0 25 1
A getData() 0 7 1
A readRules() 0 8 1
A hasRules() 0 7 2
A readBlocks() 0 8 1
A readIdRuleIndexes() 0 8 1
A readTypeRuleIndexes() 0 8 1
A readAttributeRulesIndexes() 0 8 1
A readToOneRulesIndexes() 0 8 1
A readToManyRulesIndexes() 0 8 1
A readRuleIndex() 0 4 1
A readRuleStartIndexes() 0 4 1
A readRuleEndIndexes() 0 4 1
A readRulesIndexes() 0 4 1
A readRulesStartIndexes() 0 4 1
A readRulesEndIndexes() 0 4 1
A hasRule() 0 6 1
A isRulesClass() 0 6 2
1
<?php namespace Limoncello\Flute\Validation\JsonApi\Execution;
2
3
/**
4
 * Copyright 2015-2017 [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\Flute\Contracts\Validation\JsonApiDataRulesInterface;
20
use Limoncello\Flute\Contracts\Validation\JsonApiDataRulesSerializerInterface;
21
use Limoncello\Flute\Validation\Serialize\RulesSerializer;
22
use Limoncello\Validation\Contracts\Rules\RuleInterface;
23
use Neomerx\JsonApi\Contracts\Document\DocumentInterface;
24
25
/**
26
 * @package Limoncello\Flute
27
 *
28
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
29
 */
30
class JsonApiDataRulesSerializer extends RulesSerializer implements JsonApiDataRulesSerializerInterface
31
{
32
    /** Serialized indexes key */
33
    protected const SERIALIZED_RULES = 0;
34
35
    /** Serialized rules key */
36
    protected const SERIALIZED_BLOCKS = self::SERIALIZED_RULES + 1;
37
38
    /** Index key */
39
    protected const ID_SERIALIZED = 0;
40
41
    /** Index key */
42
    protected const TYPE_SERIALIZED = self::ID_SERIALIZED + 1;
43
44
    /** Index key */
45
    protected const ATTRIBUTES_SERIALIZED = self::TYPE_SERIALIZED + 1;
46
47
    /** Index key */
48
    protected const TO_ONE_SERIALIZED = self::ATTRIBUTES_SERIALIZED + 1;
49
50
    /** Index key */
51
    protected const TO_MANY_SERIALIZED = self::TO_ONE_SERIALIZED + 1;
52
53
    /**
54
     * @var array
55
     */
56
    private $serializedRules = [];
57
58
    /**
59
     * @param string $rulesClass
60
     *
61
     * @return self
62
     */
63 28
    public function addRulesFromClass(string $rulesClass): JsonApiDataRulesSerializerInterface
64
    {
65 28
        assert(static::isRulesClass($rulesClass));
0 ignored issues
show
Bug introduced by
Since isRulesClass() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of isRulesClass() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
66
67 28
        $name = $rulesClass;
68
69
        /** @var JsonApiDataRulesInterface $rulesClass */
70
71 28
        return $this->addDataRules(
72 28
            $name,
73 28
            $rulesClass::getIdRule(),
74 28
            $rulesClass::getTypeRule(),
75 28
            $rulesClass::getAttributeRules(),
76 28
            $rulesClass::getToOneRelationshipRules(),
77 28
            $rulesClass::getToManyRelationshipRules()
78
        );
79
    }
80
81
    /**
82
     * @inheritdoc
83
     */
84 40
    public function addDataRules(
85
        string $name,
86
        RuleInterface $idRule,
87
        RuleInterface $typeRule,
88
        array $attributeRules,
89
        array $toOneRules,
90
        array $toManyRules
91
    ): JsonApiDataRulesSerializerInterface {
92 40
        $idRule->setName(DocumentInterface::KEYWORD_ID)->enableCapture();
93 40
        $typeRule->setName(DocumentInterface::KEYWORD_TYPE)->enableCapture();
94
95
        $ruleSet = [
96 40
            static::ID_SERIALIZED         => $this->addRule($idRule),
97 40
            static::TYPE_SERIALIZED       => $this->addRule($typeRule),
98 40
            static::ATTRIBUTES_SERIALIZED => $this->addRules($attributeRules),
99 40
            static::TO_ONE_SERIALIZED     => $this->addRules($toOneRules),
100 40
            static::TO_MANY_SERIALIZED    => $this->addRules($toManyRules),
101
        ];
102
103 40
        $this->serializedRules[$name] = $ruleSet;
104
105 40
        $this->getSerializer()->clearBlocksWithStart()->clearBlocksWithEnd();
106
107 40
        return $this;
108
    }
109
110
    /**
111
     * @inheritdoc
112
     *
113
     * @SuppressWarnings(PHPMD.StaticAccess)
114
     */
115 40
    public function getData(): array
116
    {
117
        return [
118 40
            static::SERIALIZED_RULES  => $this->serializedRules,
119 40
            static::SERIALIZED_BLOCKS => static::getBlocks(),
120
        ];
121
    }
122
123
    /**
124
     * @param string $rulesClass
125
     * @param array  $serializedData
126
     *
127
     * @return array
128
     */
129 21
    public static function readRules(string $rulesClass, array $serializedData): array
130
    {
131 21
        assert(static::hasRules($rulesClass, $serializedData));
132
133 21
        $indexes = $serializedData[static::SERIALIZED_RULES][$rulesClass];
134
135 21
        return $indexes;
136
    }
137
138
    /**
139
     * @inheritdoc
140
     */
141 21
    public static function hasRules(string $name, array $serializedData): bool
142
    {
143
        // the value could be null so we have to check by key existence.
144
        return
145 21
            array_key_exists(static::SERIALIZED_RULES, $serializedData) === true &&
146 21
            array_key_exists($name, $serializedData[static::SERIALIZED_RULES]);
147
    }
148
149
    /**
150
     * @param array $serializedData
151
     *
152
     * @return array
153
     */
154 21
    public static function readBlocks(array $serializedData): array
155
    {
156 21
        assert(array_key_exists(static::SERIALIZED_BLOCKS, $serializedData));
157 21
        $serializedRules = $serializedData[static::SERIALIZED_BLOCKS];
158 21
        assert(is_array($serializedRules));
159
160 21
        return $serializedRules;
161
    }
162
163
    /**
164
     * @param array $serializedRules
165
     *
166
     * @return array
167
     */
168 21
    public static function readIdRuleIndexes(array $serializedRules): array
169
    {
170 21
        assert(array_key_exists(static::ID_SERIALIZED, $serializedRules));
171 21
        $rule = $serializedRules[static::ID_SERIALIZED];
172 21
        assert(is_array($rule));
173
174 21
        return $rule;
175
    }
176
177
    /**
178
     * @param array $serializedRules
179
     *
180
     * @return array
181
     */
182 21
    public static function readTypeRuleIndexes(array $serializedRules): array
183
    {
184 21
        assert(array_key_exists(static::TYPE_SERIALIZED, $serializedRules));
185 21
        $rule = $serializedRules[static::TYPE_SERIALIZED];
186 21
        assert(is_array($rule));
187
188 21
        return $rule;
189
    }
190
191
    /**
192
     * @param array $serializedRules
193
     *
194
     * @return array
195
     */
196 21
    public static function readAttributeRulesIndexes(array $serializedRules): array
197
    {
198 21
        assert(array_key_exists(static::ATTRIBUTES_SERIALIZED, $serializedRules));
199 21
        $rules = $serializedRules[static::ATTRIBUTES_SERIALIZED];
200 21
        assert(is_array($rules));
201
202 21
        return $rules;
203
    }
204
205
    /**
206
     * @param array $serializedRules
207
     *
208
     * @return array
209
     */
210 21
    public static function readToOneRulesIndexes(array $serializedRules): array
211
    {
212 21
        assert(array_key_exists(static::TO_ONE_SERIALIZED, $serializedRules));
213 21
        $rules = $serializedRules[static::TO_ONE_SERIALIZED];
214 21
        assert(is_array($rules));
215
216 21
        return $rules;
217
    }
218
219
    /**
220
     * @param array $serializedRules
221
     *
222
     * @return array
223
     */
224 21
    public static function readToManyRulesIndexes(array $serializedRules): array
225
    {
226 21
        assert(array_key_exists(static::TO_MANY_SERIALIZED, $serializedRules));
227 21
        $rules = $serializedRules[static::TO_MANY_SERIALIZED];
228 21
        assert(is_array($rules));
229
230 21
        return $rules;
231
    }
232
233
    /**
234
     * @param array $ruleIndexes
235
     *
236
     * @return int
237
     */
238 14
    public static function readRuleIndex(array $ruleIndexes): int
239
    {
240 14
        return parent::getRuleIndex($ruleIndexes);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getRuleIndex() instead of readRuleIndex()). Are you sure this is correct? If so, you might want to change this to $this->getRuleIndex().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
241
    }
242
243
    /**
244
     * @param array $ruleIndexes
245
     *
246
     * @return array
247
     */
248 15
    public static function readRuleStartIndexes(array $ruleIndexes): array
249
    {
250 15
        return parent::getRuleStartIndexes($ruleIndexes);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getRuleStartIndexes() instead of readRuleStartIndexes()). Are you sure this is correct? If so, you might want to change this to $this->getRuleStartIndexes().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
251
    }
252
253
    /**
254
     * @param array $ruleIndexes
255
     *
256
     * @return array
257
     */
258 15
    public static function readRuleEndIndexes(array $ruleIndexes): array
259
    {
260 15
        return parent::getRuleEndIndexes($ruleIndexes);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getRuleEndIndexes() instead of readRuleEndIndexes()). Are you sure this is correct? If so, you might want to change this to $this->getRuleEndIndexes().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
261
    }
262
263
    /**
264
     * @param array $arrayRuleIndexes
265
     *
266
     * @return array
267
     */
268 21
    public static function readRulesIndexes(array $arrayRuleIndexes): array
269
    {
270 21
        return parent::getRulesIndexes($arrayRuleIndexes);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getRulesIndexes() instead of readRulesIndexes()). Are you sure this is correct? If so, you might want to change this to $this->getRulesIndexes().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
271
    }
272
273
    /**
274
     * @param array $arrayRuleIndexes
275
     *
276
     * @return array
277
     */
278 21
    public static function readRulesStartIndexes(array $arrayRuleIndexes): array
279
    {
280 21
        return parent::getRulesStartIndexes($arrayRuleIndexes);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getRulesStartIndexes() instead of readRulesStartIndexes()). Are you sure this is correct? If so, you might want to change this to $this->getRulesStartIndexes().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
281
    }
282
283
    /**
284
     * @param array $arrayRuleIndexes
285
     *
286
     * @return array
287
     */
288 21
    public static function readRulesEndIndexes(array $arrayRuleIndexes): array
289
    {
290 21
        return parent::getRulesEndIndexes($arrayRuleIndexes);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getRulesEndIndexes() instead of readRulesEndIndexes()). Are you sure this is correct? If so, you might want to change this to $this->getRulesEndIndexes().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
291
    }
292
293
    /**
294
     * @param int   $index
295
     * @param array $blocks
296
     *
297
     * @return bool
298
     */
299 17
    public static function hasRule(int $index, array $blocks): bool
300
    {
301 17
        $result = array_key_exists($index, $blocks);
302
303 17
        return $result;
304
    }
305
306
    /**
307
     * @param string $rulesClass
308
     *
309
     * @return bool
310
     */
311 28
    private static function isRulesClass(string $rulesClass): bool
312
    {
313
        return
314 28
            class_exists($rulesClass) === true &&
315 28
            in_array(JsonApiDataRulesInterface::class, class_implements($rulesClass)) === true;
316
    }
317
}
318