Passed
Push — master ( 1f27ac...52075a )
by Alexander
04:53 queued 02:24
created

Group   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 28
dl 0
loc 67
ccs 32
cts 32
cp 1
rs 10
c 0
b 0
f 0
wmc 9

1 Method

Rating   Name   Duplication   Size   Complexity  
B match() 0 56 9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;
6
7
use InvalidArgumentException;
8
use Yiisoft\Data\Reader\FilterAssert;
9
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;
10
11
use function array_shift;
12
use function count;
13
use function is_array;
14
use function is_string;
15
use function sprintf;
16
17
/**
18
 * Abstract `Group` iterable filter handler allows to combine runs of several iterable filters.
19
 * How to interpret results is determined by {@see checkResults()} implemented in child
20
 * classes.
21
 */
22
abstract class Group implements IterableFilterHandlerInterface
23
{
24
    /**
25
     * Return final decision for the match based on sub-filter match results.
26
     *
27
     * @param bool[] $results Sub-filter match results.
28
     *
29
     * @return bool Final result.
30
     */
31
    abstract protected function checkResults(array $results): bool;
32
33 73
    public function match(array|object $item, array $arguments, array $iterableFilterHandlers): bool
34
    {
35 73
        if (count($arguments) !== 1) {
36 8
            throw new InvalidArgumentException('$arguments should contain exactly one element.');
37
        }
38
39 65
        [$subFilters] = $arguments;
40
41 65
        if (!is_array($subFilters)) {
42 16
            throw new InvalidArgumentException(sprintf(
43 16
                'The sub filters should be array. The %s is received.',
44 16
                get_debug_type($subFilters),
45 16
            ));
46
        }
47
48 49
        $results = [];
49
50 49
        foreach ($subFilters as $subFilter) {
51 49
            if (!is_array($subFilter)) {
52 16
                throw new InvalidArgumentException(sprintf(
53 16
                    'The sub filter should be array. The %s is received.',
54 16
                    get_debug_type($subFilter),
55 16
                ));
56
            }
57
58 33
            if (empty($subFilter)) {
59 2
                throw new InvalidArgumentException('At least operator should be provided.');
60
            }
61
62 31
            $operator = array_shift($subFilter);
63
64 31
            if (!is_string($operator)) {
65 10
                throw new InvalidArgumentException(sprintf(
66 10
                    'The operator should be string. The %s is received.',
67 10
                    get_debug_type($operator),
68 10
                ));
69
            }
70
71 21
            if ($operator === '') {
72 2
                throw new InvalidArgumentException('The operator string cannot be empty.');
73
            }
74
75
            /** @var mixed $filterHandler */
76 19
            $filterHandler = $iterableFilterHandlers[$operator] ?? null;
77
78 19
            if ($filterHandler === null) {
79 2
                throw new InvalidArgumentException(sprintf('"%s" operator is not supported.', $operator));
80
            }
81
82 17
            FilterAssert::isIterableFilterHandlerInterface($filterHandler);
83
            /** @var IterableFilterHandlerInterface $filterHandler */
84
85 15
            $results[] = $filterHandler->match($item, $subFilter, $iterableFilterHandlers);
86
        }
87
88 15
        return $this->checkResults($results);
89
    }
90
}
91