Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
48 / 48
100.00% covered (success)
100.00%
16 / 16
CRAP
100.00% covered (success)
100.00%
1 / 1
AbstractFilter
100.00% covered (success)
100.00%
48 / 48
100.00% covered (success)
100.00%
16 / 16
34
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 setCallable
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 setParams
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 setExcludeByName
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 setExcludeByType
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getCallable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 removeCallable
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getParams
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 getExcludeByName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getExcludeByType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasCallable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasParams
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 hasExcludeByName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasExcludeByType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 filter
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
9
 callCallable
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Filter;
16
17use Pop\Utils\CallableObject;
18
19/**
20 * Abstract filter class
21 *
22 * @category   Pop
23 * @package    Pop\Filter
24 * @author     Nick Sagona, III <nick@popphp.org>
25 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
26 * @license    https://www.popphp.org/license     New BSD License
27 * @version    5.0.0
28 */
29abstract class AbstractFilter implements FilterInterface
30{
31
32    /**
33     * Filter callable
34     * @var CallableObject
35     */
36    protected ?CallableObject $callable = null;
37
38    /**
39     * Exclude by type
40     * @var array
41     */
42    protected array $excludeByType = [];
43
44    /**
45     * Exclude by name
46     * @var array
47     */
48    protected array $excludeByName = [];
49
50    /**
51     * Constructor
52     *
53     * Instantiate the form filter object
54     *
55     * @param  mixed $callable
56     * @param  mixed $params
57     * @param  mixed $excludeByName
58     * @param  mixed $excludeByType
59     */
60    public function __construct(mixed $callable, mixed $params = null, mixed $excludeByName = null, mixed $excludeByType = null)
61    {
62        $this->setCallable($callable);
63
64        if ($params !== null) {
65            $this->setParams($params);
66        }
67        if ($excludeByName !== null) {
68            $this->setExcludeByName($excludeByName);
69        }
70        if ($excludeByType !== null) {
71            $this->setExcludeByType($excludeByType);
72        }
73    }
74
75    /**
76     * Set callable
77     *
78     * @param  mixed $callable
79     * @return AbstractFilter
80     */
81    public function setCallable(mixed $callable): AbstractFilter
82    {
83        if (!($callable instanceof CallableObject)) {
84            $callable = new CallableObject($callable);
85        }
86        $this->callable = $callable;
87        return $this;
88    }
89
90    /**
91     * Set params
92     *
93     * @param  mixed $params
94     * @return AbstractFilter
95     */
96    public function setParams(mixed $params): AbstractFilter
97    {
98        if ($this->callable !== null) {
99            if (is_array($params)) {
100                $this->callable->setParameters($params);
101            } else {
102                $this->callable->setParameters([$params]);
103            }
104        }
105
106        return $this;
107    }
108
109    /**
110     * Set exclude by name
111     *
112     * @param  mixed $excludeByName
113     * @return AbstractFilter
114     */
115    public function setExcludeByName(mixed $excludeByName): AbstractFilter
116    {
117        if (!is_array($excludeByName)) {
118            $excludeByName = [$excludeByName];
119        }
120        $this->excludeByName = $excludeByName;
121
122        return $this;
123    }
124
125    /**
126     * Set exclude by type
127     *
128     * @param  mixed $excludeByType
129     * @return AbstractFilter
130     */
131    public function setExcludeByType(mixed $excludeByType): AbstractFilter
132    {
133        if (!is_array($excludeByType)) {
134            $excludeByType = [$excludeByType];
135        }
136        $this->excludeByType = $excludeByType;
137
138        return $this;
139    }
140
141    /**
142     * Get callable
143     *
144     * @return ?CallableObject
145     */
146    public function getCallable(): ?CallableObject
147    {
148        return $this->callable;
149    }
150
151    /**
152     * Remove callable
153     *
154     * @return AbstractFilter
155     */
156    public function removeCallable(): AbstractFilter
157    {
158        $this->callable = null;
159        return $this;
160    }
161
162    /**
163     * Get params
164     *
165     * @return array
166     */
167    public function getParams(): array
168    {
169        return ($this->callable !== null) ? $this->callable->getParameters() : [];
170    }
171
172    /**
173     * Get exclude by name
174     *
175     * @return array
176     */
177    public function getExcludeByName(): array
178    {
179        return $this->excludeByName;
180    }
181
182    /**
183     * Get exclude by type
184     *
185     * @return array
186     */
187    public function getExcludeByType(): array
188    {
189        return $this->excludeByType;
190    }
191
192    /**
193     * Has callable
194     *
195     * @return bool
196     */
197    public function hasCallable(): bool
198    {
199        return ($this->callable !== null);
200    }
201
202    /**
203     * Has params
204     *
205     * @return bool
206     */
207    public function hasParams(): bool
208    {
209        return ($this->callable !== null) && $this->callable->hasParameters();
210    }
211
212    /**
213     * Has exclude by name
214     *
215     * @return bool
216     */
217    public function hasExcludeByName(): bool
218    {
219        return (!empty($this->excludeByName));
220    }
221
222    /**
223     * Has exclude by type
224     *
225     * @return bool
226     */
227    public function hasExcludeByType(): bool
228    {
229        return (!empty($this->excludeByType));
230    }
231
232    /**
233     * Filter value
234     *
235     * @param  mixed   $value
236     * @param  ?string $name
237     * @param  mixed   $type
238     * @return mixed
239     */
240    public function filter(mixed $value, ?string $name = null, mixed $type = null): mixed
241    {
242        if (($this->callable !== null) &&
243            (($type === null) || (!in_array($type, $this->excludeByType))) &&
244            (($name === null) || (!in_array($name, $this->excludeByName)))) {
245            if (is_array($value)) {
246                foreach ($value as $k => $v) {
247                    $value[$k] = is_array($v) ? $this->filter($v, $name, $type) : $this->callCallable($v);
248                }
249            } else {
250                $value = $this->callCallable($value);
251            }
252        }
253
254        return $value;
255    }
256
257    /**
258     * Call the filter callable with the value prepended to its configured params
259     *
260     * @param  mixed $value
261     * @return mixed
262     */
263    protected function callCallable(mixed $value): mixed
264    {
265        $callableParams = $this->callable->getParameters();
266        $params         = array_merge([$value], $callableParams);
267        $this->callable->setParameters($params);
268
269        $result = $this->callable->call();
270
271        $this->callable->setParameters($callableParams);
272
273        return $result;
274    }
275
276}