JsonApiQueryRulesSerializer::addQueryRules()   F
last analyzed

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