Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
50 / 50
100.00% covered (success)
100.00%
21 / 21
CRAP
100.00% covered (success)
100.00%
1 / 1
Condition
100.00% covered (success)
100.00%
50 / 50
100.00% covered (success)
100.00%
21 / 21
39
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
6
 createFromRule
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 create
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setField
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setValidator
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setValue
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setMessage
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setPrefix
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getField
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getValidator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getValue
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMessage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPrefix
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getValidatorObject
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasField
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasValidator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasValue
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasMessage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasPrefix
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasValidatorObject
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 evaluate
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
14
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\Validator;
16
17/**
18 * Has one that equals validator class
19 *
20 * @category   Pop
21 * @package    Pop\Validator
22 * @author     Nick Sagona, III <nick@popphp.org>
23 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
24 * @license    https://www.popphp.org/license     New BSD License
25 * @version    5.0.0
26 */
27class Condition
28{
29
30    /**
31     * Field
32     * @var ?string
33     */
34    protected ?string $field = null;
35
36    /**
37     * Validator
38     * @var ?string
39     */
40    protected ?string $validator = null;
41
42    /**
43     * Value
44     * @var mixed
45     */
46    protected mixed $value = null;
47
48    /**
49     * Message
50     * @var ?string
51     */
52    protected ?string $message = null;
53
54
55    /**
56     * Prefix
57     * @var ?string
58     */
59    protected ?string $prefix = null;
60
61    /**
62     * Validator
63     * @var ?AbstractValidator
64     */
65    protected ?AbstractValidator $validatorObject = null;
66
67    /**
68     * Constructor
69     *
70     * Instantiate the condition object
71     *
72     * @param ?string $field
73     * @param ?string $validator
74     * @param mixed   $value
75     * @param ?string $message
76     * @param ?string $prefix
77     */
78    public function __construct(
79        ?string $field = null, ?string $validator = null, mixed $value = null,
80        ?string $message = null, ?string $prefix = 'Pop\Validator\\'
81    )
82    {
83        if ($field !== null) {
84            $this->setField($field);
85        }
86        if ($validator !== null) {
87            $this->setValidator($validator);
88        }
89        if ($value !== null) {
90            $this->setValue($value);
91        }
92        if ($message !== null) {
93            $this->setMessage($message);
94        }
95        if ($prefix !== null) {
96            $this->setPrefix($prefix);
97        }
98    }
99
100    /**
101     * Create condition from rule
102     *
103     * @param  string $rule
104     * @return static
105     */
106    public static function createFromRule(string $rule, string $prefix = 'Pop\Validator\\'): static
107    {
108        ['field' => $field, 'validator' => $validator, 'value' => $value, 'message' => $message] = Rule::parse($rule, $prefix);
109        return new static($field, $validator, $value, $message, $prefix);
110    }
111
112    /**
113     * Create condition
114     *
115     * @param  ?string $field
116     * @param  ?string $validator
117     * @param  mixed   $value
118     * @param  ?string $message
119     * @param  ?string $prefix
120     * @return static
121     */
122    public static function create(
123        ?string $field = null, ?string $validator = null, mixed $value = null,
124        ?string $message = null, ?string $prefix = 'Pop\Validator\\'
125    ): static
126    {
127        return new static($field, $validator, $value, $message, $prefix);
128    }
129
130    /**
131     * Set the condition field
132     *
133     * @param  ?string $field
134     * @return static
135     */
136    public function setField(?string $field = null): static
137    {
138        $this->field = $field;
139        return $this;
140    }
141
142    /**
143     * Set the condition validator
144     *
145     * @param  ?string $validator
146     * @return static
147     */
148    public function setValidator(?string $validator = null): static
149    {
150        $this->validator = $validator;
151        return $this;
152    }
153
154    /**
155     * Set the condition value
156     *
157     * @param  mixed $value
158     * @return static
159     */
160    public function setValue(mixed $value = null): static
161    {
162        $this->value = $value;
163        return $this;
164    }
165
166    /**
167     * Set the condition message
168     *
169     * @param  ?string $message
170     * @return static
171     */
172    public function setMessage(?string $message = null): static
173    {
174        $this->message = $message;
175        return $this;
176    }
177
178    /**
179     * Set the condition prefix
180     *
181     * @param  ?string $prefix
182     * @return static
183     */
184    public function setPrefix(?string $prefix = null): static
185    {
186        $this->prefix = $prefix;
187        return $this;
188    }
189
190    /**
191     * Get the condition field
192     *
193     * @return ?string
194     */
195    public function getField(): ?string
196    {
197        return $this->field;
198    }
199
200    /**
201     * Get the condition validator
202     *
203     * @return ?string
204     */
205    public function getValidator(): ?string
206    {
207        return $this->validator;
208    }
209
210    /**
211     * Get the condition value
212     *
213     * @return mixed
214     */
215    public function getValue(): mixed
216    {
217        return $this->value;
218    }
219
220    /**
221     * Get the condition message
222     *
223     * @return ?string
224     */
225    public function getMessage(): ?string
226    {
227        return $this->message;
228    }
229
230    /**
231     * Get the condition prefix
232     *
233     * @return ?string
234     */
235    public function getPrefix(): ?string
236    {
237        return $this->prefix;
238    }
239
240    /**
241     * Get the condition validator object
242     *
243     * @return ?AbstractValidator
244     */
245    public function getValidatorObject(): ?AbstractValidator
246    {
247        return $this->validatorObject;
248    }
249
250    /**
251     * Has the condition field
252     *
253     * @return bool
254     */
255    public function hasField(): bool
256    {
257        return ($this->field !== null);
258    }
259
260    /**
261     * Has the condition validator
262     *
263     * @return bool
264     */
265    public function hasValidator(): bool
266    {
267        return ($this->validator !== null);
268    }
269
270    /**
271     * Has the condition value
272     *
273     * @return bool
274     */
275    public function hasValue(): bool
276    {
277        return ($this->value !== null);
278    }
279
280    /**
281     * Has the condition message
282     *
283     * @return bool
284     */
285    public function hasMessage(): bool
286    {
287        return ($this->message !== null);
288    }
289
290    /**
291     * Has the condition prefix
292     *
293     * @return bool
294     */
295    public function hasPrefix(): bool
296    {
297        return ($this->prefix !== null);
298    }
299
300    /**
301     * Has the condition validator object
302     *
303     * @return bool
304     */
305    public function hasValidatorObject(): bool
306    {
307        return ($this->validatorObject !== null);
308    }
309
310    /**
311     * Evaluate the condition
312     *
313     * @param  array $input
314     * @throws Exception
315     * @return bool
316     */
317    public function evaluate(array $input): bool
318    {
319        if (!class_exists($this->prefix . $this->validator)) {
320            throw new Exception('Error: The condition class does not exist.');
321        }
322
323        if (!str_contains($this->field, '.') && !str_contains($this->field, '[') && !array_key_exists($this->field, $input))  {
324            throw new Exception("Error: The input data does not contain a '" . $this->field . "' field value.");
325        }
326
327        // If the value references a value in the input array
328        if (is_string($this->value) && str_starts_with($this->value, '[') && str_ends_with($this->value, ']')) {
329            $value = substr($this->value, 1, -1);
330            if (array_key_exists($value, $input)) {
331                $this->value = $input[$value];
332            }
333        }
334
335        $class       = $this->prefix . $this->validator;
336        $isFormatted = (is_array($this->value) && array_key_exists($this->field, $this->value));
337
338        $this->validatorObject = (str_starts_with($this->validator, 'Has') && (!$isFormatted)) ?
339            new $class([$this->field => $this->value], $this->message) : new $class($this->value, $this->message);
340
341        if (!empty($this->field)) {
342            $this->validatorObject->setField($this->field);
343        }
344
345        return $this->validatorObject->evaluate((array_key_exists($this->field, $input) ? $input[$this->field] : $input));
346    }
347
348}