Completed
Push — master ( 6173d9...210649 )
by Neomerx
04:26
created

JsonApiQueryRulesSerializer::addQueryRules()   F

Complexity

Conditions 13
Paths 4096

Size

Total Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 13

Importance

Changes 0
Metric Value
dl 0
loc 38
ccs 24
cts 24
cp 1
rs 2.45
c 0
b 0
f 0
cc 13
nc 4096
nop 8
crap 13

How to fix   Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php namespace Limoncello\Flute\Validation\JsonApi\Execution;
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\Flute\Contracts\Validation\JsonApiQueryRulesInterface;
20
use Limoncello\Flute\Contracts\Validation\JsonApiQueryRulesSerializerInterface;
21
use Limoncello\Flute\Contracts\Validation\JsonApiQueryValidatingParserInterface;
22
use Limoncello\Flute\Validation\Serialize\RulesSerializer;
23
use Limoncello\Validation\Contracts\Rules\RuleInterface;
24
25
/**
26
 * @package Limoncello\Flute
27
 *
28
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
29
 */
30
class JsonApiQueryRulesSerializer extends RulesSerializer implements JsonApiQueryRulesSerializerInterface
31
{
32
    /**
33
     * @var array
34
     */
35
    private $serializedRules = [];
36
37
    /** Index key */
38
    protected const IDENTITY_RULE= 0;
39
40
    /** Index key */
41
    protected const FILTER_RULES = self::IDENTITY_RULE + 1;
42
43
    /** Index key */
44
    protected const FIELD_SET_RULES = self::FILTER_RULES + 1;
45
46
    /** Index key */
47
    protected const SORTS_RULE = self::FIELD_SET_RULES + 1;
48
49
    /** Index key */
50
    protected const INCLUDES_RULE = self::SORTS_RULE + 1;
51
52
    /** Index key */
53
    protected const PAGE_OFFSET_RULE = self::INCLUDES_RULE + 1;
54
55
    /** Index key */
56
    protected const PAGE_LIMIT_RULE = self::PAGE_OFFSET_RULE + 1;
57
58
    /** Index key */
59
    protected const SINGLE_RULE_INDEX = 0;
60
61
    /** Serialized indexes key */
62
    protected const SERIALIZED_RULES = 0;
63
64
    /** Serialized rules key */
65
    protected const SERIALIZED_BLOCKS = self::SERIALIZED_RULES + 1;
66
67
    /**
68
     * @inheritdoc
69
     */
70 43
    public function addRulesFromClass(string $rulesClass): JsonApiQueryRulesSerializerInterface
71
    {
72 43
        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...
73
74 43
        $name = $rulesClass;
75
76
        /** @var JsonApiQueryRulesInterface $rulesClass */
77
78 43
        return $this->addQueryRules(
79 43
            $name,
80 43
            $rulesClass::getIdentityRule(),
81 43
            $rulesClass::getFilterRules(),
82 43
            $rulesClass::getFieldSetRules(),
83 43
            $rulesClass::getSortsRule(),
84 43
            $rulesClass::getIncludesRule(),
85 43
            $rulesClass::getPageOffsetRule(),
86 43
            $rulesClass::getPageLimitRule()
87
        );
88
    }
89
90
    /** @noinspection PhpTooManyParametersInspection
91
     * @inheritdoc
92
     *
93
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
94
     * @SuppressWarnings(PHPMD.NPathComplexity)
95
     */
96 43
    public function addQueryRules(
97
        string $name,
98
        ?RuleInterface $identityRule,
99
        ?array $filterRules,
100
        ?array $fieldSetRules,
101
        ?RuleInterface $sortsRule,
102
        ?RuleInterface $includesRule,
103
        ?RuleInterface $pageOffsetRule,
104
        ?RuleInterface $pageLimitRule
105
    ): JsonApiQueryRulesSerializerInterface {
106 43
        assert(!empty($name));
107 43
        assert(static::hasRules($name, $this->serializedRules) === false);
108
109 43
        $identityRule === null ?: $identityRule->setName(JsonApiQueryValidatingParserInterface::PARAM_IDENTITY);
110 43
        $sortsRule === null ?: $sortsRule->setName(JsonApiQueryValidatingParserInterface::PARAM_SORT);
111 43
        $includesRule === null ?: $includesRule->setName(JsonApiQueryValidatingParserInterface::PARAM_INCLUDE);
112 43
        $pageOffsetRule === null ?: $pageOffsetRule->setName(JsonApiQueryValidatingParserInterface::PARAM_PAGE);
113 43
        $pageLimitRule === null ?: $pageLimitRule->setName(JsonApiQueryValidatingParserInterface::PARAM_PAGE);
114
115 43
        $this->serializedRules[$name] = [
116 43
            static::IDENTITY_RULE     =>
117 43
                $identityRule === null ? null : $this->addRules([static::SINGLE_RULE_INDEX => $identityRule]),
118 43
            static::FILTER_RULES     =>
119 43
                $filterRules === null ? null : $this->addRules($filterRules),
120 43
            static::FIELD_SET_RULES  =>
121 43
                $fieldSetRules === null ? null : $this->addRules($fieldSetRules),
122 43
            static::SORTS_RULE       =>
123 43
                $sortsRule === null ? null : $this->addRules([static::SINGLE_RULE_INDEX => $sortsRule]),
124 43
            static::INCLUDES_RULE    =>
125 43
                $includesRule === null ? null : $this->addRules([static::SINGLE_RULE_INDEX => $includesRule]),
126 43
            static::PAGE_OFFSET_RULE =>
127 43
                $pageOffsetRule === null ? null : $this->addRules([static::SINGLE_RULE_INDEX => $pageOffsetRule]),
128 43
            static::PAGE_LIMIT_RULE  =>
129 43
                $pageLimitRule === null ? null : $this->addRules([static::SINGLE_RULE_INDEX => $pageLimitRule]),
130
        ];
131
132 43
        return $this;
133
    }
134
135
    /**
136
     * @inheritdoc
137
     */
138 43
    public function getData(): array
139
    {
140
        return [
141 43
            static::SERIALIZED_RULES  => $this->serializedRules,
142 43
            static::SERIALIZED_BLOCKS => $this->getBlocks(),
143
        ];
144
    }
145
146
    /**
147
     * @inheritdoc
148
     */
149 58
    public static function readBlocks(array $serializedData): array
150
    {
151 58
        return $serializedData[static::SERIALIZED_BLOCKS];
152
    }
153
154
    /**
155
     * @inheritdoc
156
     */
157 43
    public static function hasRules(string $name, array $serializedData): bool
158
    {
159
        // the value could be null so we have to check by key existence.
160
        return
161 43
            array_key_exists(static::SERIALIZED_RULES, $serializedData) === true &&
162 43
            array_key_exists($name, $serializedData[static::SERIALIZED_RULES]);
163
    }
164
165
    /**
166
     * @inheritdoc
167
     */
168 36
    public static function readRules(string $name, array $serializedData): array
169
    {
170 36
        assert(static::hasRules($name, $serializedData) === true);
171
172 36
        return $serializedData[static::SERIALIZED_RULES][$name];
173
    }
174
175
    /**
176
     * @inheritdoc
177
     */
178 5
    public static function readIdentityRuleIndexes(array $serializedRules): ?array
179
    {
180 5
        return $serializedRules[static::IDENTITY_RULE];
181
    }
182
183
    /**
184
     * @inheritdoc
185
     */
186 22
    public static function readFilterRulesIndexes(array $serializedRules): ?array
187
    {
188 22
        return $serializedRules[static::FILTER_RULES];
189
    }
190
191
    /**
192
     * @inheritdoc
193
     */
194 2
    public static function readFieldSetRulesIndexes(array $serializedRules): ?array
195
    {
196 2
        return $serializedRules[static::FIELD_SET_RULES];
197
    }
198
199
    /**
200
     * @inheritdoc
201
     */
202 16
    public static function readSortsRuleIndexes(array $serializedRules): ?array
203
    {
204 16
        return $serializedRules[static::SORTS_RULE];
205
    }
206
207
    /**
208
     * @inheritdoc
209
     */
210 16
    public static function readIncludesRuleIndexes(array $serializedRules): ?array
211
    {
212 16
        return $serializedRules[static::INCLUDES_RULE];
213
    }
214
215
    /**
216
     * @inheritdoc
217
     */
218 35
    public static function readPageOffsetRuleIndexes(array $serializedRules): ?array
219
    {
220 35
        return $serializedRules[static::PAGE_OFFSET_RULE];
221
    }
222
223
    /**
224
     * @inheritdoc
225
     */
226 35
    public static function readPageLimitRuleIndexes(array $serializedRules): ?array
227
    {
228 35
        return $serializedRules[static::PAGE_LIMIT_RULE];
229
    }
230
231
    /**
232
     * @inheritdoc
233
     */
234 22
    public static function readRuleMainIndexes(array $ruleIndexes): ?array
235
    {
236 22
        return parent::getRulesIndexes($ruleIndexes);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getRulesIndexes() instead of readRuleMainIndexes()). 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...
237
    }
238
239
    /**
240
     * @inheritdoc
241
     */
242 34
    public static function readRuleMainIndex(array $ruleIndexes): ?int
243
    {
244
        // if you read main/first/only rule and blocks actually have more then something must be wrong
245 34
        assert(count($ruleIndexes[static::RULES_ARRAY_INDEXES]) === 1);
246
247 34
        return $ruleIndexes[static::RULES_ARRAY_INDEXES][static::SINGLE_RULE_INDEX];
248
    }
249
250
    /**
251
     * @inheritdoc
252
     */
253 34
    public static function readRuleStartIndexes(array $ruleIndexes): array
254
    {
255 34
        return parent::getRulesStartIndexes($ruleIndexes);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getRulesStartIndexes() instead of readRuleStartIndexes()). 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...
256
    }
257
258
    /**
259
     * @inheritdoc
260
     */
261 34
    public static function readRuleEndIndexes(array $ruleIndexes): array
262
    {
263 34
        return parent::getRulesEndIndexes($ruleIndexes);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getRulesEndIndexes() instead of readRuleEndIndexes()). 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...
264
    }
265
266
    /**
267
     * @param string $rulesClass
268
     *
269
     * @return bool
270
     */
271 43
    private static function isRulesClass(string $rulesClass): bool
272
    {
273
        return
274 43
            class_exists($rulesClass) === true &&
275 43
            in_array(JsonApiQueryRulesInterface::class, class_implements($rulesClass)) === true;
276
    }
277
}
278