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

Group   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 10
eloc 19
dl 0
loc 80
ccs 21
cts 21
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A toCriteriaArray() 0 13 3
A withCriteriaArray() 0 21 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Data\Reader\Filter;
6
7
use InvalidArgumentException;
8
use Yiisoft\Data\Reader\FilterInterface;
9
10
use function array_shift;
11
use function is_array;
12
use function is_string;
13
use function sprintf;
14
15
/**
16
 * `Group` filter is an abstract class that allows combining multiple criteria or sub-filters.
17
 */
18
abstract class Group implements FilterInterface
19
{
20
    /**
21
     * @var array[]|FilterInterface[] Criteria and sub-filters to use.
22
     */
23
    private array $filtersAndCriteria;
24
25
    /**
26
     * @param FilterInterface ...$filters Sub-filters to use.
27
     */
28 32
    public function __construct(FilterInterface ...$filters)
29
    {
30 32
        $this->filtersAndCriteria = $filters;
31
    }
32
33
    /**
34
     * Get criteria array based on current filters and criteria.
35
     *
36
     * @return array Criteria array.
37
     */
38 6
    public function toCriteriaArray(): array
39
    {
40 6
        $criteriaArray = [];
41
42 6
        foreach ($this->filtersAndCriteria as $filterOrCriteria) {
43 6
            if ($filterOrCriteria instanceof FilterInterface) {
44 6
                $filterOrCriteria = $filterOrCriteria->toCriteriaArray();
45
            }
46
47 6
            $criteriaArray[] = $filterOrCriteria;
48
        }
49
50 6
        return [static::getOperator(), $criteriaArray];
51
    }
52
53
    /**
54
     * Get a new instance with filters set from criteria array provided.
55
     *
56
     * ```php
57
     * $dataReader->withFilter((new All())->withCriteriaArray(
58
     *   [
59
     *     ['>', 'id', 88],
60
     *     ['or', [
61
     *        ['=', 'state', 2],
62
     *        ['like', 'name', 'eva'],
63
     *     ],
64
     *   ]
65
     * ));
66
     * ```
67
     *
68
     * @param array[]|FilterInterface[] $criteriaArray Criteria array to use.
69
     * Instances of FilterInterface are ignored.
70
     *
71
     * @throws InvalidArgumentException If criteria arrays is not valid.
72
     *
73
     * @return static New instance.
74
     *
75
     * @psalm-suppress DocblockTypeContradiction
76
     */
77 28
    public function withCriteriaArray(array $criteriaArray): static
78
    {
79 28
        foreach ($criteriaArray as $key => $item) {
80 28
            if ($item instanceof FilterInterface) {
81 14
                continue;
82
            }
83
84 28
            if (!is_array($item)) {
85 12
                throw new InvalidArgumentException(sprintf('Invalid filter on "%s" key.', $key));
86
            }
87
88 16
            $operator = array_shift($item);
89
90 16
            if (!is_string($operator) || $operator === '') {
91 14
                throw new InvalidArgumentException(sprintf('Invalid filter operator on "%s" key.', $key));
92
            }
93
        }
94
95 2
        $new = clone $this;
96 2
        $new->filtersAndCriteria = $criteriaArray;
97 2
        return $new;
98
    }
99
}
100