Completed
Push — master ( 382574...1a7856 )
by Neomerx
03:37
created

BlockInterpreter   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 529
Duplicated Lines 24.39 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 50
lcom 1
cbo 6
dl 129
loc 529
ccs 170
cts 170
cp 1
rs 8.6206
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
A execute() 0 16 3
A executeStarts() 20 20 3
A executeEnds() 20 20 3
B executeBlock() 0 24 2
B executeBlockImpl() 0 30 5
A executeProcedureBlock() 0 18 1
B executeIfBlock() 0 24 2
A executeAndBlock() 22 22 2
A executeOrBlock() 23 23 2
A getBlocks() 0 7 1
A getBlocksWithStart() 12 12 2
A getBlocksWithEnd() 12 12 2
A getBlockType() 0 8 1
A captureSuccessfulBlockResultIfEnabled() 0 14 3
A executeProcedureStart() 10 10 1
A executeProcedureEnd() 10 10 1
A addBlockErrors() 0 16 2
B debugCheckLooksLikeBlocksArray() 0 13 5
A debugCheckBlocksExist() 0 12 4
B debugHasKnownBlockType() 0 16 5

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like BlockInterpreter often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use BlockInterpreter, and based on these observations, apply Extract Interface, too.

1
<?php namespace Limoncello\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\Captures\CaptureAggregatorInterface;
20
use Limoncello\Validation\Contracts\Errors\ErrorAggregatorInterface;
21
use Limoncello\Validation\Contracts\Execution\ContextInterface;
22
use Limoncello\Validation\Contracts\Execution\ContextStorageInterface;
23
use Limoncello\Validation\Errors\Error;
24
use Limoncello\Validation\Rules\BaseRule;
25
26
/**
27
 * @package Limoncello\Validation
28
 *
29
 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
30
 */
31
final class BlockInterpreter
32
{
33
    /**
34
     * @param mixed                      $input
35
     * @param array                      $serializedBlocks
36
     * @param ContextStorageInterface    $context
37
     * @param CaptureAggregatorInterface $captures
38
     * @param ErrorAggregatorInterface   $errors
39
     *
40
     * @return bool
41
     *
42
     * @SuppressWarnings(PHPMD.StaticAccess)
43
     */
44 9
    public static function execute(
45
        $input,
46
        array $serializedBlocks,
47
        ContextStorageInterface $context,
48
        CaptureAggregatorInterface $captures,
49
        ErrorAggregatorInterface $errors
50
    ): bool {
51 9
        $blockIndex = BlockSerializer::FIRST_BLOCK_INDEX;
52
53 9
        $blocks   = static::getBlocks($serializedBlocks);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
54 9
        $startsOk = static::executeStarts(static::getBlocksWithStart($serializedBlocks), $blocks, $context, $errors);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
55 9
        $blockOk  = static::executeBlock($input, $blockIndex, $blocks, $context, $captures, $errors);
56 9
        $endsOk   = static::executeEnds(static::getBlocksWithEnd($serializedBlocks), $blocks, $context, $errors);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
57
58 9
        return $startsOk && $blockOk && $endsOk;
59
    }
60
61
    /**
62
     * @param int[]                    $indexes
63
     * @param array                    $blocks
64
     * @param ContextStorageInterface  $context
65
     * @param ErrorAggregatorInterface $errors
66
     *
67
     * @return bool
68
     *
69
     * @SuppressWarnings(PHPMD.StaticAccess)
70
     */
71 18 View Code Duplication
    public static function executeStarts(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
72
        array $indexes,
73
        array $blocks,
74
        ContextStorageInterface $context,
75
        ErrorAggregatorInterface $errors
76
    ): bool {
77 18
        $allOk = true;
78
79 18
        foreach ($indexes as $index) {
80 5
            $context->setCurrentBlockId($index);
81 5
            $block      = $blocks[$index];
82 5
            $errorsInfo = static::executeProcedureStart($block, $context);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
83 5
            if (empty($errorsInfo) === false) {
84 2
                static::addBlockErrors($errorsInfo, $context, $errors);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
85 5
                $allOk = false;
86
            }
87
        }
88
89 18
        return $allOk;
90
    }
91
92
    /**
93
     * @param int[]                    $indexes
94
     * @param array                    $blocks
95
     * @param ContextStorageInterface  $context
96
     * @param ErrorAggregatorInterface $errors
97
     *
98
     * @return bool
99
     *
100
     * @SuppressWarnings(PHPMD.StaticAccess)
101
     */
102 18 View Code Duplication
    public static function executeEnds(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
103
        array $indexes,
104
        array $blocks,
105
        ContextStorageInterface $context,
106
        ErrorAggregatorInterface $errors
107
    ): bool {
108 18
        $allOk = true;
109
110 18
        foreach ($indexes as $index) {
111 6
            $context->setCurrentBlockId($index);
112 6
            $block      = $blocks[$index];
113 6
            $errorsInfo = static::executeProcedureEnd($block, $context);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
114 6
            if (empty($errorsInfo) === false) {
115 3
                static::addBlockErrors($errorsInfo, $context, $errors);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
116 6
                $allOk = false;
117
            }
118
        }
119
120 18
        return $allOk;
121
    }
122
123
    /**
124
     * @param mixed                      $input
125
     * @param int                        $blockIndex
126
     * @param array                      $blocks
127
     * @param ContextStorageInterface    $context
128
     * @param CaptureAggregatorInterface $captures
129
     * @param ErrorAggregatorInterface   $errors
130
     *
131
     * @return bool
132
     *
133
     * @SuppressWarnings(PHPMD.StaticAccess)
134
     */
135 18
    public static function executeBlock(
136
        $input,
137
        int $blockIndex,
138
        array $blocks,
139
        ContextStorageInterface $context,
140
        CaptureAggregatorInterface $captures,
141
        ErrorAggregatorInterface $errors
142
    ): bool {
143 18
        $result = static::executeBlockImpl(
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
144 18
            $input,
145 18
            $blockIndex,
146 18
            $blocks,
147 18
            $context,
148 18
            $captures
149
        );
150 18
        if (BlockReplies::isResultSuccessful($result) === false) {
151 13
            $errorsInfo = BlockReplies::extractResultErrorsInfo($result);
152 13
            static::addBlockErrors($errorsInfo, $context, $errors);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
153
154 13
            return false;
155
        }
156
157 16
        return true;
158
    }
159
160
    /**
161
     * @param mixed                      $input
162
     * @param int                        $blockIndex
163
     * @param array                      $blocks
164
     * @param ContextStorageInterface    $context
165
     * @param CaptureAggregatorInterface $captures
166
     *
167
     * @return array
168
     *
169
     * @SuppressWarnings(PHPMD.StaticAccess)
170
     */
171 18
    private static function executeBlockImpl(
172
        $input,
173
        int $blockIndex,
174
        array $blocks,
175
        ContextStorageInterface $context,
176
        CaptureAggregatorInterface $captures
177
    ): array {
178 18
        assert(array_key_exists($blockIndex, $blocks));
179
180 18
        $blockType = static::getBlockType($blocks[$blockIndex]);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
181 18
        $context->setCurrentBlockId($blockIndex);
182
        switch ($blockType) {
183 18
            case BlockSerializer::TYPE__PROCEDURE:
184 18
                $result = static::executeProcedureBlock($input, $blockIndex, $blocks, $context, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
185 18
                break;
186 10
            case BlockSerializer::TYPE__IF_EXPRESSION:
187 6
                $result = static::executeIfBlock($input, $blockIndex, $blocks, $context, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
188 6
                break;
189 10
            case BlockSerializer::TYPE__AND_EXPRESSION:
190 10
                $result = static::executeAndBlock($input, $blockIndex, $blocks, $context, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
191 10
                break;
192 4
            case BlockSerializer::TYPE__OR_EXPRESSION:
193
            default:
194 4
                assert($blockType === BlockSerializer::TYPE__OR_EXPRESSION);
195 4
                $result = static::executeOrBlock($input, $blockIndex, $blocks, $context, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
196 4
                break;
197
        }
198
199 18
        return $result;
200
    }
201
202
    /**
203
     * @param mixed                      $input
204
     * @param int                        $blockIndex
205
     * @param array                      $blocks
206
     * @param ContextStorageInterface    $context
207
     * @param CaptureAggregatorInterface $captures
208
     *
209
     * @return array
210
     *
211
     * @SuppressWarnings(PHPMD.StaticAccess)
212
     */
213 18
    private static function executeProcedureBlock(
214
        $input,
215
        int $blockIndex,
216
        array $blocks,
217
        ContextStorageInterface $context,
218
        CaptureAggregatorInterface $captures
219
    ): array {
220 18
        $block = $blocks[$blockIndex];
221 18
        assert(static::getBlockType($block) === BlockSerializer::TYPE__PROCEDURE);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
222
223 18
        $procedure = $block[BlockSerializer::PROCEDURE_EXECUTE_CALLABLE];
224 18
        assert(is_callable($procedure));
225 18
        $result = call_user_func($procedure, $input, $context);
226
227 18
        static::captureSuccessfulBlockResultIfEnabled($result, $block, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
228
229 18
        return $result;
230
    }
231
232
    /**
233
     * @param mixed                      $input
234
     * @param int                        $blockIndex
235
     * @param array                      $blocks
236
     * @param ContextStorageInterface    $context
237
     * @param CaptureAggregatorInterface $captures
238
     *
239
     * @return array
240
     *
241
     * @SuppressWarnings(PHPMD.StaticAccess)
242
     */
243 6
    private static function executeIfBlock(
244
        $input,
245
        int $blockIndex,
246
        array $blocks,
247
        ContextStorageInterface $context,
248
        CaptureAggregatorInterface $captures
249
    ): array {
250 6
        $block = $blocks[$blockIndex];
251 6
        assert(static::getBlockType($block) === BlockSerializer::TYPE__IF_EXPRESSION);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
252
253 6
        $conditionCallable = $block[BlockSerializer::IF_EXPRESSION_CONDITION_CALLABLE];
254 6
        assert(is_callable($conditionCallable));
255 6
        $conditionResult = call_user_func($conditionCallable, $input, $context);
256 6
        assert(is_bool($conditionResult));
257
258 6
        $index = $block[$conditionResult === true ?
259 6
            BlockSerializer::IF_EXPRESSION_ON_TRUE_BLOCK : BlockSerializer::IF_EXPRESSION_ON_FALSE_BLOCK];
260
261 6
        $result = static::executeBlockImpl($input, $index, $blocks, $context, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
262
263 6
        static::captureSuccessfulBlockResultIfEnabled($result, $block, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
264
265 6
        return $result;
266
    }
267
268
    /**
269
     * @param mixed                      $input
270
     * @param int                        $blockIndex
271
     * @param array                      $blocks
272
     * @param ContextStorageInterface    $context
273
     * @param CaptureAggregatorInterface $captures
274
     *
275
     * @return array
276
     *
277
     * @SuppressWarnings(PHPMD.StaticAccess)
278
     */
279 10 View Code Duplication
    private static function executeAndBlock(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
        $input,
281
        int $blockIndex,
282
        array $blocks,
283
        ContextStorageInterface $context,
284
        CaptureAggregatorInterface $captures
285
    ): array {
286 10
        $block = $blocks[$blockIndex];
287 10
        assert(static::getBlockType($block) === BlockSerializer::TYPE__AND_EXPRESSION);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
288
289 10
        $primaryIndex = $block[BlockSerializer::AND_EXPRESSION_PRIMARY];
290 10
        $result       = static::executeBlockImpl($input, $primaryIndex, $blocks, $context, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
291 10
        if (BlockReplies::isResultSuccessful($result) === true) {
292 10
            $nextInput      = BlockReplies::extractResultOutput($result);
293 10
            $secondaryIndex = $block[BlockSerializer::AND_EXPRESSION_SECONDARY];
294 10
            $result         = static::executeBlockImpl($nextInput, $secondaryIndex, $blocks, $context, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
295
        }
296
297 10
        static::captureSuccessfulBlockResultIfEnabled($result, $block, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
298
299 10
        return $result;
300
    }
301
302
    /**
303
     * @param mixed                      $input
304
     * @param int                        $blockIndex
305
     * @param array                      $blocks
306
     * @param ContextStorageInterface    $context
307
     * @param CaptureAggregatorInterface $captures
308
     *
309
     * @return array
310
     *
311
     * @SuppressWarnings(PHPMD.StaticAccess)
312
     * @SuppressWarnings(PHPMD.ElseExpression)
313
     */
314 4 View Code Duplication
    private static function executeOrBlock(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
315
        $input,
316
        int $blockIndex,
317
        array $blocks,
318
        ContextStorageInterface $context,
319
        CaptureAggregatorInterface $captures
320
    ): array {
321 4
        $block = $blocks[$blockIndex];
322 4
        assert(static::getBlockType($block) === BlockSerializer::TYPE__OR_EXPRESSION);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
323
324 4
        $primaryIndex      = $block[BlockSerializer::OR_EXPRESSION_PRIMARY];
325 4
        $resultFromPrimary = static::executeBlockImpl($input, $primaryIndex, $blocks, $context, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
326 4
        if (BlockReplies::isResultSuccessful($resultFromPrimary) === true) {
327 4
            $result = $resultFromPrimary;
328
        } else {
329 4
            $secondaryIndex = $block[BlockSerializer::OR_EXPRESSION_SECONDARY];
330 4
            $result         = static::executeBlockImpl($input, $secondaryIndex, $blocks, $context, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
331
        }
332
333 4
        static::captureSuccessfulBlockResultIfEnabled($result, $block, $captures);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
334
335 4
        return $result;
336
    }
337
338
    /**
339
     * @param array $serializedBlocks
340
     *
341
     * @return array
342
     *
343
     * @SuppressWarnings(PHPMD.StaticAccess)
344
     */
345 9
    private static function getBlocks(array $serializedBlocks): array
346
    {
347 9
        $blocks = BlockSerializer::unserializeBlocks($serializedBlocks);
348 9
        assert(static::debugCheckLooksLikeBlocksArray($blocks));
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
349
350 9
        return $blocks;
351
    }
352
353
    /**
354
     * @param array $serializedBlocks
355
     *
356
     * @return array
357
     *
358
     * @SuppressWarnings(PHPMD.StaticAccess)
359
     */
360 9 View Code Duplication
    private static function getBlocksWithStart(array $serializedBlocks): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
361
    {
362 9
        $blocksWithStart = BlockSerializer::unserializeBlocksWithStart($serializedBlocks);
363
364
        // check result contain only block indexes and the blocks are procedures
365 9
        assert(
366 9
            is_array($blocks = static::getBlocks($serializedBlocks)) &&
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
367 9
            static::debugCheckBlocksExist($blocksWithStart, $blocks, BlockSerializer::TYPE__PROCEDURE)
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
368
        );
369
370 9
        return $blocksWithStart;
371
    }
372
373
    /**
374
     * @param array $serializedBlocks
375
     *
376
     * @return array
377
     *
378
     * @SuppressWarnings(PHPMD.StaticAccess)
379
     */
380 9 View Code Duplication
    private static function getBlocksWithEnd(array $serializedBlocks): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
381
    {
382 9
        $blocksWithEnd = BlockSerializer::unserializeBlocksWithEnd($serializedBlocks);
383
384
        // check result contain only block indexes and the blocks are procedures
385 9
        assert(
386 9
            is_array($blocks = static::getBlocks($serializedBlocks)) &&
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
387 9
            static::debugCheckBlocksExist($blocksWithEnd, $blocks, BlockSerializer::TYPE__PROCEDURE)
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
388
        );
389
390 9
        return $blocksWithEnd;
391
    }
392
393
    /**
394
     * @param array $block
395
     *
396
     * @return int
397
     *
398
     * @SuppressWarnings(PHPMD.StaticAccess)
399
     */
400 18
    private static function getBlockType(array $block): int
401
    {
402 18
        assert(static::debugHasKnownBlockType($block));
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
403
404 18
        $type = $block[BlockSerializer::TYPE];
405
406 18
        return $type;
407
    }
408
409
    /**
410
     * @param array                      $result
411
     * @param array                      $block
412
     * @param CaptureAggregatorInterface $captures
413
     *
414
     * @return void
415
     *
416
     * @SuppressWarnings(PHPMD.StaticAccess)
417
     */
418 18
    private static function captureSuccessfulBlockResultIfEnabled(
419
        array $result,
420
        array $block,
421
        CaptureAggregatorInterface $captures
422
    ): void {
423 18
        if (BlockReplies::isResultSuccessful($result) === true) {
424 16
            $isCaptureEnabled = $block[BlockSerializer::PROPERTIES][BaseRule::PROPERTY_IS_CAPTURE_ENABLED] ?? false;
425 16
            if ($isCaptureEnabled === true) {
426 15
                $name  = $block[BlockSerializer::PROPERTIES][BaseRule::PROPERTY_NAME];
427 15
                $value = BlockReplies::extractResultOutput($result);
428 15
                $captures->remember($name, $value);
429
            }
430
        }
431
    }
432
433
    /**
434
     * @param array            $procedureBlock
435
     * @param ContextInterface $context
436
     *
437
     * @return array
438
     *
439
     * @SuppressWarnings(PHPMD.StaticAccess)
440
     */
441 5 View Code Duplication
    private static function executeProcedureStart(array $procedureBlock, ContextInterface $context): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
442
    {
443 5
        assert(static::getBlockType($procedureBlock) === BlockSerializer::TYPE__PROCEDURE);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
444 5
        $callable = $procedureBlock[BlockSerializer::PROCEDURE_START_CALLABLE];
445 5
        assert(is_callable($callable) === true);
446 5
        $errors = call_user_func($callable, $context);
447 5
        assert(is_array($errors));
448
449 5
        return $errors;
450
    }
451
452
    /**
453
     * @param array            $procedureBlock
454
     * @param ContextInterface $context
455
     *
456
     * @return array
457
     *
458
     * @SuppressWarnings(PHPMD.StaticAccess)
459
     */
460 6 View Code Duplication
    private static function executeProcedureEnd(array $procedureBlock, ContextInterface $context): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
461
    {
462 6
        assert(static::getBlockType($procedureBlock) === BlockSerializer::TYPE__PROCEDURE);
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
463 6
        $callable = $procedureBlock[BlockSerializer::PROCEDURE_END_CALLABLE];
464 6
        assert(is_callable($callable) === true);
465 6
        $errors = call_user_func($callable, $context);
466 6
        assert(is_array($errors));
467
468 6
        return $errors;
469
    }
470
471
    /**
472
     * @param array                    $errorsInfo
473
     * @param ContextStorageInterface  $context
474
     * @param ErrorAggregatorInterface $errors
475
     *
476
     * @return void
477
     */
478 16
    private static function addBlockErrors(
479
        array $errorsInfo,
480
        ContextStorageInterface $context,
481
        ErrorAggregatorInterface $errors
482
    ): void {
483 16
        foreach ($errorsInfo as $errorInfo) {
484 16
            $index        = $errorInfo[BlockReplies::ERROR_INFO_BLOCK_INDEX];
485 16
            $value        = $errorInfo[BlockReplies::ERROR_INFO_VALUE];
486 16
            $errorCode    = $errorInfo[BlockReplies::ERROR_INFO_CODE];
487 16
            $errorContext = $errorInfo[BlockReplies::ERROR_INFO_CONTEXT];
488
489 16
            $name = $context->setCurrentBlockId($index)->getProperties()->getProperty(BaseRule::PROPERTY_NAME);
490
491 16
            $errors->add(new Error($name, $value, $errorCode, $errorContext));
492
        }
493
    }
494
495
    /**
496
     * @param array $blocks
497
     *
498
     * @return bool
499
     *
500
     * @SuppressWarnings(PHPMD.StaticAccess)
501
     */
502 9
    private static function debugCheckLooksLikeBlocksArray(array $blocks): bool
503
    {
504 9
        foreach ($blocks as $index => $block) {
505 9
            if (is_int($index) === false ||
506 9
                is_array($block) === false ||
507 9
                static::debugHasKnownBlockType($block) === false
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
508
            ) {
509 9
                return false;
510
            }
511
        }
512
513 9
        return true;
514
    }
515
516
    /**
517
     * @param array $blockIndexes
518
     * @param array $blockList
519
     * @param int   $blockType
520
     *
521
     * @return bool
522
     *
523
     * @SuppressWarnings(PHPMD.StaticAccess)
524
     */
525 9
    private static function debugCheckBlocksExist(array $blockIndexes, array $blockList, int $blockType): bool
526
    {
527 9
        foreach ($blockIndexes as $index) {
528 5
            if (array_key_exists($index, $blockList) === false ||
529 5
                static::getBlockType($blockList[$index]) !== $blockType
0 ignored issues
show
Comprehensibility introduced by
Since Limoncello\Validation\Execution\BlockInterpreter is declared final, using late-static binding will have no effect. You might want to replace static with self instead.

Late static binding only has effect in subclasses. A final class cannot be extended anymore so late static binding cannot occurr. Consider replacing static:: with self::.

To learn more about late static binding, please refer to the PHP core documentation.

Loading history...
530
            ) {
531 5
                return false;
532
            }
533
        }
534
535 9
        return true;
536
    }
537
538
    /**
539
     * @param array $block
540
     *
541
     * @return bool
542
     */
543 18
    private static function debugHasKnownBlockType(array $block): bool
544
    {
545 18
        $result = false;
546
547 18
        if (array_key_exists(BlockSerializer::TYPE, $block) === true) {
548 18
            $type = $block[BlockSerializer::TYPE];
549
550
            $result =
551 18
                $type === BlockSerializer::TYPE__PROCEDURE ||
552 18
                $type === BlockSerializer::TYPE__AND_EXPRESSION ||
553 18
                $type === BlockSerializer::TYPE__OR_EXPRESSION ||
554 18
                $type === BlockSerializer::TYPE__IF_EXPRESSION;
555
        }
556
557 18
        return $result;
558
    }
559
}
560