Completed
Branch devel (4fc3ef)
by Marcin
05:51
created

Filter::toArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
c 0
b 0
f 0
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * Created by Marcin.
4
 * Date: 16.06.2018
5
 * Time: 19:05
6
 */
7
declare(strict_types=1);
8
9
namespace Mrcnpdlk\Lib\UrlSearchParser\Criteria;
10
11
use function array_key_exists;
12
use ArrayIterator;
13
use function gettype;
14
use function in_array;
15
use function is_array;
16
use function is_string;
17
use IteratorAggregate;
18
use Mrcnpdlk\Lib\UrlSearchParser\Exception\InvalidParamException;
19
use Traversable;
20
21
/**
22
 * Class Filter
23
 */
24
class Filter implements IteratorAggregate
25
{
26
    public const DELIMITER = ',';
27
28
    public const PARAM_EQ      = 'eq';
29
    public const PARAM_GT      = 'gt';
30
    public const PARAM_GTE     = 'gte';
31
    public const PARAM_LT      = 'lt';
32
    public const PARAM_LTE     = 'lte';
33
    public const PARAM_LIKE    = 'like';
34
    public const PARAM_IN      = 'in';
35
    public const PARAM_NOTIN   = 'notin';
36
    public const PARAM_NULL    = 'null';
37
    public const PARAM_NOTNULL = 'notnull';
38
    public const PARAM_NOT     = 'not';
39
40
    public static $allowedOperators = [
41
        self::PARAM_EQ      => '=',
42
        self::PARAM_GT      => '>',
43
        self::PARAM_GTE     => '>=',
44
        self::PARAM_LT      => '<',
45
        self::PARAM_LTE     => '<=',
46
        self::PARAM_LIKE    => 'like',
47
        self::PARAM_IN      => null,
48
        self::PARAM_NOTIN   => null,
49
        self::PARAM_NULL    => null,
50
        self::PARAM_NOTNULL => null,
51
        self::PARAM_NOT     => '!=',
52
    ];
53
54
    /**
55
     * @var \Mrcnpdlk\Lib\UrlSearchParser\Criteria\FilterParam[]
56
     */
57
    private $filters = [];
58
59
    /**
60
     * Filter constructor.
61
     *
62
     * @param array|FilterParam[] $filterArray
63
     *
64
     * @throws \Mrcnpdlk\Lib\UrlSearchParser\Exception\InvalidParamException
65
     *
66
     * @todo Check PLUS sign in string %2B code
67
     */
68 19
    public function __construct($filterArray = [])
69
    {
70 19
        if (!is_array($filterArray)) {
0 ignored issues
show
introduced by
The condition is_array($filterArray) is always true.
Loading history...
71 1
            throw new InvalidParamException(sprintf('FILTER params are invalid. Is [%s], Array expected', gettype($filterArray)));
72
        }
73
74
        /** @var FilterParam|string|array $filters */
75 18
        foreach ($filterArray as $param => $filters) {
76 7
            if ($filters instanceof FilterParam) {
77 2
                $this->appendParam($filters);
78 2
                continue;
79
            }
80
81 7
            if (!is_string($param)) {
82 2
                throw new InvalidParamException(sprintf('Key in FILTER param is not a string'));
83
            }
84 5
            if (is_array($filters)) {
85 5
                foreach ($filters as $operator => $value) {
86 5
                    if (!array_key_exists($operator, self::$allowedOperators)) {
87 2
                        throw new InvalidParamException(sprintf('Operator [%s] in FILTER is not allowed', $operator));
88
                    }
89 3
                    if (in_array($operator, [self::PARAM_IN, self::PARAM_NOTIN], true)) {
90 1
                        $value = explode(self::DELIMITER, $value);
91
                    }
92 3
                    if (in_array($operator, [self::PARAM_NULL, self::PARAM_NOTNULL], true)) {
93 1
                        $value = null;
94
                    }
95 3
                    $this->appendParam(new FilterParam($param, $operator, $value));
96
                }
97 1
            } elseif (is_string($filters)) {
98 3
                $this->appendParam(new FilterParam($param, self::PARAM_EQ, $filters));
99
            }
100
        }
101 14
    }
102
103
    /**
104
     * @param \Mrcnpdlk\Lib\UrlSearchParser\Criteria\FilterParam $filterParam
105
     *
106
     * @return \Mrcnpdlk\Lib\UrlSearchParser\Criteria\Filter
107
     */
108 3
    public function appendParam(FilterParam $filterParam): Filter
109
    {
110 3
        $this->filters[] = $filterParam;
111
112 3
        return $this;
113
    }
114
115
    /**
116
     * @param string $paramName
117
     *
118
     * @throws \Mrcnpdlk\Lib\UrlSearchParser\Exception\InvalidParamException
119
     *
120
     * @return \Mrcnpdlk\Lib\UrlSearchParser\Criteria\Filter
121
     */
122 2
    public function getByParam(string $paramName): Filter
123
    {
124 2
        $params = [];
125 2
        foreach ($this as $item) {
126 2
            if ($item->param === $paramName) {
127 2
                $params[] = $item;
128
            }
129
        }
130
131 2
        return new self($params);
132
    }
133
134
    /**
135
     * Retrieve an external iterator
136
     *
137
     * @see   http://php.net/manual/en/iteratoraggregate.getiterator.php
138
     *
139
     * @return Traversable An instance of an object implementing <b>Iterator</b> or
140
     *                     <b>Traversable</b>
141
     *
142
     * @since 5.0.0
143
     */
144 3
    public function getIterator(): Traversable
145
    {
146 3
        return new ArrayIterator($this->filters);
147
    }
148
149
    /**
150
     * @param \Mrcnpdlk\Lib\UrlSearchParser\Criteria\FilterParam $filterParam
151
     *
152
     * @return \Mrcnpdlk\Lib\UrlSearchParser\Criteria\Filter
153
     */
154 1
    public function replaceParam(FilterParam $filterParam): Filter
155
    {
156 1
        $isChanged = false;
157 1
        foreach ($this->filters as &$filter) {
158 1
            if ($filter->param === $filterParam->param && $filter->operator = $filterParam->operator) {
159 1
                $filter->value = $filterParam->value;
160 1
                $isChanged     = true;
161
            }
162
        }
163 1
        unset($filter);
164 1
        if (!$isChanged) {
165 1
            $this->appendParam($filterParam);
166
        }
167
168 1
        return $this;
169
    }
170
171
    /**
172
     * @return \Mrcnpdlk\Lib\UrlSearchParser\Criteria\FilterParam[]
173
     */
174 2
    public function toArray(): array
175
    {
176 2
        return $this->filters;
177
    }
178
}
179