Completed
Push — develop ( 90d90f...48c4f2 )
by Neomerx
06:19 queued 04:30
created

JsonApiRuleSerializer::getData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
crap 1
1
<?php namespace Limoncello\Flute\Validation\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\Validation\Contracts\Execution\BlockSerializerInterface;
20
use Limoncello\Validation\Contracts\Rules\RuleInterface;
21
use Limoncello\Validation\Execution\BlockSerializer;
22
use Neomerx\JsonApi\Contracts\Document\DocumentInterface;
23
24
/**
25
 * @package Limoncello\Flute
26
 */
27
class JsonApiRuleSerializer
28
{
29
    /** Serialized indexes key */
30
    protected const SERIALIZED_RULE_SETS = 0;
31
32
    /** Serialized rules key */
33
    protected const SERIALIZED_BLOCKS = self::SERIALIZED_RULE_SETS + 1;
34
35
    /** Index key */
36
    protected const ID_SERIALIZED = 0;
37
38
    /** Index key */
39
    protected const TYPE_SERIALIZED = self::ID_SERIALIZED + 1;
40
41
    /** Index key */
42
    protected const ATTRIBUTES_SERIALIZED = self::TYPE_SERIALIZED + 1;
43
44
    /** Index key */
45
    protected const TO_ONE_SERIALIZED = self::ATTRIBUTES_SERIALIZED + 1;
46
47
    /** Index key */
48
    protected const TO_MANY_SERIALIZED = self::TO_ONE_SERIALIZED + 1;
49
50
    // Single rule serialization keys
51
52
    /** Index key */
53
    protected const SINGLE_RULE_INDEX = 0;
54
55
    /** Index key */
56
    protected const SINGLE_RULE_START_INDEXES = self::SINGLE_RULE_INDEX + 1;
57
58
    /** Index key */
59
    protected const SINGLE_RULE_END_INDEXES = self::SINGLE_RULE_START_INDEXES + 1;
60
61
    // Rules array serialization keys
62
63
    /** Index key */
64
    protected const RULES_ARRAY_INDEXES = 0;
65
66
    /** Index key */
67
    protected const RULES_ARRAY_START_INDEXES = self::RULES_ARRAY_INDEXES + 1;
68
69
    /** Index key */
70
    protected const RULES_ARRAY_END_INDEXES = self::RULES_ARRAY_START_INDEXES + 1;
71
72
    /**
73
     * @var BlockSerializerInterface
74
     */
75
    private $blockSerializer;
76
77
    /**
78
     * @var array
79
     */
80
    private $ruleSets;
81
82
    /**
83
     * Constructor.
84
     */
85 30
    public function __construct()
86
    {
87 30
        $this->blockSerializer = $this->createBlockSerializer();
88 30
        $this->ruleSets        = [];
89
    }
90
91
    /** @noinspection PhpTooManyParametersInspection
92
     * @param string          $name
93
     * @param RuleInterface   $idRule
94
     * @param RuleInterface   $typeRule
95
     * @param RuleInterface[] $attributeRules
96
     * @param RuleInterface[] $toOneRules
97
     * @param RuleInterface[] $toManyRules
98
     *
99
     * @return self
100
     */
101 30
    public function addResourceRules(
102
        string $name,
103
        RuleInterface $idRule,
104
        RuleInterface $typeRule,
105
        array $attributeRules,
106
        array $toOneRules,
107
        array $toManyRules
108
    ): self {
109 30
        assert(!empty($name));
110 30
        assert(!array_key_exists($name, $this->ruleSets));
111
112 30
        $idRule->setName(DocumentInterface::KEYWORD_ID)->enableCapture();
113 30
        $typeRule->setName(DocumentInterface::KEYWORD_TYPE)->enableCapture();
114
115
        $ruleSet = [
116 30
            static::ID_SERIALIZED         => $this->serializeRule($idRule),
117 30
            static::TYPE_SERIALIZED       => $this->serializeRule($typeRule),
118 30
            static::ATTRIBUTES_SERIALIZED => $this->serializeRulesArray($attributeRules),
119 30
            static::TO_ONE_SERIALIZED     => $this->serializeRulesArray($toOneRules),
120 30
            static::TO_MANY_SERIALIZED    => $this->serializeRulesArray($toManyRules),
121
        ];
122
123 30
        $this->ruleSets[$name] = $ruleSet;
124
125 30
        $this->getSerializer()->clearBlocksWithStart()->clearBlocksWithEnd();
126
127 30
        return $this;
128
    }
129
130
    /**
131
     * @return array
132
     *
133
     * @SuppressWarnings(PHPMD.StaticAccess)
134
     */
135 30
    public function getData(): array
136
    {
137
        return [
138 30
            static::SERIALIZED_RULE_SETS => $this->ruleSets,
139 30
            static::SERIALIZED_BLOCKS    => static::getBlocks($this->getSerializer()->get()),
140
        ];
141
    }
142
143
    /**
144
     * @param string $name
145
     * @param array  $data
146
     *
147
     * @return array
148
     */
149 9
    public static function extractRuleSet(string $name, array $data): array
150
    {
151 9
        assert($data[static::SERIALIZED_RULE_SETS] ?? false);
152 9
        $indexes = $data[static::SERIALIZED_RULE_SETS][$name];
153 9
        assert(is_array($indexes));
154
155 9
        return $indexes;
156
    }
157
158
    /**
159
     * @param array $data
160
     *
161
     * @return array
162
     */
163 9
    public static function extractBlocks(array $data): array
164
    {
165 9
        assert(array_key_exists(static::SERIALIZED_BLOCKS, $data));
166 9
        $serializedRules = $data[static::SERIALIZED_BLOCKS];
167 9
        assert(is_array($serializedRules));
168
169 9
        return $serializedRules;
170
    }
171
172
    /**
173
     * @param array $ruleSet
174
     *
175
     * @return array
176
     */
177 9
    public static function getIdRule(array $ruleSet): array
178
    {
179 9
        assert(array_key_exists(static::ID_SERIALIZED, $ruleSet));
180 9
        $rule = $ruleSet[static::ID_SERIALIZED];
181 9
        assert(is_array($rule));
182
183 9
        return $rule;
184
    }
185
186
    /**
187
     * @param array $ruleSet
188
     *
189
     * @return array
190
     */
191 9
    public static function getTypeRule(array $ruleSet): array
192
    {
193 9
        assert(array_key_exists(static::TYPE_SERIALIZED, $ruleSet));
194 9
        $rule = $ruleSet[static::TYPE_SERIALIZED];
195 9
        assert(is_array($rule));
196
197 9
        return $rule;
198
    }
199
200
    /**
201
     * @param array $ruleSet
202
     *
203
     * @return array
204
     */
205 9
    public static function getAttributeRules(array $ruleSet): array
206
    {
207 9
        assert(array_key_exists(static::ATTRIBUTES_SERIALIZED, $ruleSet));
208 9
        $rules = $ruleSet[static::ATTRIBUTES_SERIALIZED];
209 9
        assert(is_array($rules));
210
211 9
        return $rules;
212
    }
213
214
    /**
215
     * @param array $ruleSet
216
     *
217
     * @return array
218
     */
219 9
    public static function getToOneRules(array $ruleSet): array
220
    {
221 9
        assert(array_key_exists(static::TO_ONE_SERIALIZED, $ruleSet));
222 9
        $rules = $ruleSet[static::TO_ONE_SERIALIZED];
223 9
        assert(is_array($rules));
224
225 9
        return $rules;
226
    }
227
228
    /**
229
     * @param array $ruleSet
230
     *
231
     * @return array
232
     */
233 9
    public static function getToManyRules(array $ruleSet): array
234
    {
235 9
        assert(array_key_exists(static::TO_MANY_SERIALIZED, $ruleSet));
236 9
        $rules = $ruleSet[static::TO_MANY_SERIALIZED];
237 9
        assert(is_array($rules));
238
239 9
        return $rules;
240
    }
241
242
    /**
243
     * @param array $serializedRule
244
     *
245
     * @return int
246
     */
247
    public static function getRuleIndex(array $serializedRule): int
248
    {
249
        assert(array_key_exists(static::SINGLE_RULE_INDEX, $serializedRule));
250
        $result = $serializedRule[static::SINGLE_RULE_INDEX];
251
        assert(is_int($result));
252
253
        return $result;
254
    }
255
256
    /**
257
     * @param array $serializedRule
258
     *
259
     * @return array
260
     */
261 7
    public static function getRuleStartIndexes(array $serializedRule): array
262
    {
263 7
        assert(array_key_exists(static::SINGLE_RULE_START_INDEXES, $serializedRule));
264 7
        $result = $serializedRule[static::SINGLE_RULE_START_INDEXES];
265 7
        assert(is_array($result));
266
267 7
        return $result;
268
    }
269
270
    /**
271
     * @param array $serializedRule
272
     *
273
     * @return array
274
     */
275
    public static function getRuleEndIndexes(array $serializedRule): array
276
    {
277
        assert(array_key_exists(static::SINGLE_RULE_END_INDEXES, $serializedRule));
278
        $result = $serializedRule[static::SINGLE_RULE_END_INDEXES];
279
        assert(is_array($result));
280
281
        return $result;
282
    }
283
284
    /**
285
     * @param array $serializedRules
286
     *
287
     * @return array
288
     */
289 9
    public static function getRulesIndexes(array $serializedRules): array
290
    {
291 9
        assert(array_key_exists(static::RULES_ARRAY_INDEXES, $serializedRules));
292 9
        $result = $serializedRules[static::RULES_ARRAY_INDEXES];
293 9
        assert(is_array($result));
294
295 9
        return $result;
296
    }
297
298
    /**
299
     * @param array $serializedRules
300
     *
301
     * @return array
302
     */
303 9
    public static function getRulesStartIndexes(array $serializedRules): array
304
    {
305 9
        assert(array_key_exists(static::RULES_ARRAY_START_INDEXES, $serializedRules));
306 9
        $result = $serializedRules[static::RULES_ARRAY_START_INDEXES];
307 9
        assert(is_array($result));
308
309 9
        return $result;
310
    }
311
312
    /**
313
     * @param array $serializedRules
314
     *
315
     * @return array
316
     */
317 9
    public static function getRulesEndIndexes(array $serializedRules): array
318
    {
319 9
        assert(array_key_exists(static::RULES_ARRAY_END_INDEXES, $serializedRules));
320 9
        $result = $serializedRules[static::RULES_ARRAY_END_INDEXES];
321 9
        assert(is_array($result));
322
323 9
        return $result;
324
    }
325
326
    /**
327
     * @param int   $index
328
     * @param array $blocks
329
     *
330
     * @return bool
331
     */
332 6
    public static function isRuleExist(int $index, array $blocks): bool
333
    {
334 6
        $result = array_key_exists($index, $blocks);
335
336 6
        return $result;
337
    }
338
339
    /**
340
     * @param array $serializedRules
341
     *
342
     * @return array
343
     *
344
     * @SuppressWarnings(PHPMD.StaticAccess)
345
     */
346 30
    protected static function getBlocks(array $serializedRules): array
347
    {
348 30
        $blocks = BlockSerializer::unserializeBlocks($serializedRules);
349
350 30
        return $blocks;
351
    }
352
353
    /**
354
     * @return BlockSerializerInterface
355
     */
356 30
    protected function getSerializer(): BlockSerializerInterface
357
    {
358 30
        return $this->blockSerializer;
359
    }
360
361
    /**
362
     * @return BlockSerializerInterface
363
     */
364 30
    protected function createBlockSerializer(): BlockSerializerInterface
365
    {
366 30
        return new BlockSerializer();
367
    }
368
369
    /**
370
     * @param RuleInterface $rule
371
     *
372
     * @return array
373
     */
374 30
    private function serializeRule(RuleInterface $rule): array
375
    {
376 30
        $this->getSerializer()->clearBlocksWithStart()->clearBlocksWithEnd();
377
378
        $result = [
379 30
            static::SINGLE_RULE_INDEX         => $this->getSerializer()->addBlock($rule->toBlock()),
380 30
            static::SINGLE_RULE_START_INDEXES => $this->getSerializer()->getBlocksWithStart(),
381 30
            static::SINGLE_RULE_END_INDEXES   => $this->getSerializer()->getBlocksWithEnd(),
382
        ];
383
384 30
        return $result;
385
    }
386
387
    /**
388
     * @param RuleInterface[] $rules
389
     *
390
     * @return array
391
     */
392 30
    private function serializeRulesArray(array $rules): array
393
    {
394 30
        $this->getSerializer()->clearBlocksWithStart()->clearBlocksWithEnd();
395
396 30
        $indexes = [];
397 30
        foreach ($rules as $name => $rule) {
398 27
            assert(is_string($name) === true && empty($name) === false);
399 27
            assert($rule instanceof RuleInterface);
400
401 27
            $block          = $rule->setName($name)->enableCapture()->toBlock();
402 27
            $indexes[$name] = $this->getSerializer()->addBlock($block);
403
        }
404
405
        return [
406 30
            static::RULES_ARRAY_INDEXES       => $indexes,
407 30
            static::RULES_ARRAY_START_INDEXES => $this->getSerializer()->getBlocksWithStart(),
408 30
            static::RULES_ARRAY_END_INDEXES   => $this->getSerializer()->getBlocksWithEnd(),
409
        ];
410
    }
411
}
412