PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.2.0
Kirki – Freeform Page Builder, Website Builder & Customizer v6.2.0
6.2.1 6.2.0 6.1.1 6.1.0 6.0.14 6.0.13 6.0.12 6.0.11 6.0.10 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.19 4.0.20 4.0.21 4.0.22 4.0.23 4.0.24 4.1 4.2.0 5.0.0 5.1.0 5.1.1 5.2.0 5.2.1 5.2.2 5.2.3 6.0.0 trunk 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.1.0 3.1.1 3.1.2
kirki / libraries / framework / Validation / ValidationRule.php
kirki / libraries / framework / Validation Last commit date
Rules 6 days ago Rule.php 6 days ago RuleFactory.php 6 days ago RuleParser.php 6 days ago ValidationRule.php 6 days ago Validator.php 6 days ago
ValidationRule.php
438 lines
1 <?php
2
3 /**
4 * Validation rule class.
5 *
6 * @package Framework
7 * @subpackage Validation
8 * @since 1.0.0
9 */
10 namespace Kirki\Framework\Validation;
11
12 use Closure;
13 use Kirki\Framework\Filesystem\File;
14 use Kirki\Framework\Supports\Arr;
15 use Kirki\Framework\Supports\Fluent;
16 use function Kirki\Framework\message;
17 \defined('ABSPATH') || exit;
18 abstract class ValidationRule extends Fluent
19 {
20 /**
21 * The data to validate.
22 *
23 * @var array
24 *
25 * @since 1.0.0
26 */
27 protected $data = [];
28 /**
29 * The value to validate.
30 *
31 * @var mixed
32 *
33 * @since 1.0.0
34 */
35 protected $value;
36 /**
37 * The name of the field where the validation rule is applied.
38 *
39 * @var string
40 *
41 * @since 1.0.0
42 */
43 protected string $name = '';
44 /**
45 * The name of the validation rule.
46 *
47 * @var string
48 *
49 * @since 1.0.0
50 */
51 protected string $rule = '';
52 /**
53 * The arguments to validate.
54 *
55 * @var array
56 *
57 * @since 1.0.0
58 */
59 protected $args;
60 /**
61 * Whether the rule is an implicit rule.
62 *
63 * @var bool
64 *
65 * @since 1.0.0
66 */
67 public bool $is_implicit = \false;
68 /**
69 * The messages to return.
70 *
71 * @var array
72 *
73 * @since 1.0.0
74 */
75 protected array $messages = [];
76 /**
77 * The default messages to return.
78 *
79 * @var array
80 *
81 * @since 1.0.0
82 */
83 protected array $default_messages = [];
84 /**
85 * The custom user defined messages to return.
86 *
87 * @var array
88 *
89 * @since 1.0.0
90 */
91 protected array $custom_messages = [];
92 /**
93 * Whether to stop on first failure.
94 *
95 * @var bool
96 *
97 * @since 1.0.0
98 */
99 protected $should_stop_on_first_failure = \false;
100 /**
101 * The constraints to validate.
102 *
103 * @var array
104 *
105 * @since 1.0.0
106 */
107 protected array $constraints = [];
108 /**
109 * Create a new rule instance.
110 *
111 * @param array|null $args The additional arguments to validate.
112 *
113 * @return void
114 *
115 * @since 1.0.0
116 */
117 public function __construct($args = null)
118 {
119 $this->args = $args;
120 $this->process_default_messages($this->constraints);
121 }
122 /**
123 * Get the rule name.
124 *
125 * @return string
126 *
127 * @since 1.0.0
128 */
129 public function get_rule_name()
130 {
131 return $this->rule;
132 }
133 /**
134 * Set whether to stop on first failure.
135 *
136 * @param bool $should_stop_on_first_failure Whether to stop on first failure.
137 *
138 * @return $this
139 *
140 * @since 1.0.0
141 */
142 public function should_stop_on_first_failure(bool $should_stop_on_first_failure)
143 {
144 $this->should_stop_on_first_failure = $should_stop_on_first_failure;
145 return $this;
146 }
147 /**
148 * Set the value to validate.
149 *
150 * @param mixed $value The value to validate.
151 *
152 * @return $this
153 *
154 * @since 1.0.0
155 */
156 public function with_value($value)
157 {
158 $this->value = $value;
159 return $this;
160 }
161 /**
162 * Set the data to validate.
163 *
164 * @param array $data The data to validate.
165 *
166 * @return $this
167 *
168 * @since 1.0.0
169 */
170 public function with_data(array $data)
171 {
172 $this->data = $data;
173 return $this;
174 }
175 /**
176 * Set the name of the field where the validation rule is applied.
177 *
178 * @param string $name The name of the field where the validation rule is applied.
179 *
180 * @return $this
181 *
182 * @since 1.0.0
183 */
184 public function with_name(string $name)
185 {
186 $this->name = $name;
187 return $this;
188 }
189 /**
190 * Run the applied constraints against the value.
191 *
192 * @param callable $callback The callback to call when a constraint fails.
193 *
194 * @return bool
195 *
196 * @since 1.0.0
197 */
198 protected function validate_constraints(callable $callback)
199 {
200 $constraints = \array_intersect($this->keys(), $this->constraints);
201 $passed = \true;
202 foreach ($constraints as $constraint) {
203 $method = 'validate_' . \strtolower($constraint);
204 if (!\method_exists($this, $method)) {
205 continue;
206 }
207 if (!$this->{$method}($this->value)) {
208 $passed = \false;
209 $callback($passed, $constraint);
210 if ($this->should_stop_on_first_failure) {
211 return \false;
212 }
213 }
214 }
215 return $passed;
216 }
217 /**
218 * Check if the rule has a constraint.
219 *
220 * @param string $constraint The constraint to check.
221 *
222 * @return bool
223 *
224 * @since 1.0.0
225 */
226 public function has_constraint(string $constraint)
227 {
228 return \in_array($constraint, $this->constraints, \true);
229 }
230 /**
231 * Validate the rule.
232 *
233 * @return bool
234 *
235 * @since 1.0.0
236 */
237 public abstract function validate() : bool;
238 /**
239 * Get the error message.
240 *
241 * @return string
242 *
243 * @since 1.0.0
244 */
245 public abstract function messages();
246 /**
247 * Check if the rule passed.
248 *
249 * @return bool
250 *
251 * @since 1.0.0
252 */
253 public function passed()
254 {
255 return $this->validate();
256 }
257 /**
258 * Reset the messages to an empty array.
259 *
260 * @return $this
261 *
262 * @since 1.0.0
263 */
264 public function clear_error_messages()
265 {
266 $this->messages = [];
267 return $this;
268 }
269 /**
270 * Set the custom messages to return.
271 *
272 * @param array $messages The custom messages to return.
273 *
274 * @return $this
275 *
276 * @since 1.0.0
277 */
278 public function sync_custom_messages(array $messages)
279 {
280 $this->custom_messages = $messages;
281 $this->sync_default_messages_with_custom_messages();
282 return $this;
283 }
284 /**
285 * Sync the default messages with the custom messages.
286 *
287 * @return void
288 *
289 * @since 1.0.0
290 */
291 protected function sync_default_messages_with_custom_messages()
292 {
293 $this->process_default_messages($this->constraints);
294 }
295 /**
296 * Check if the value is null, an empty string, or an empty countable.
297 *
298 * @param mixed $value The value to check.
299 *
300 * @return bool
301 *
302 * @since 1.0.0
303 */
304 public static function is_nullish($value)
305 {
306 if (\is_null($value)) {
307 return \true;
308 }
309 if (\is_string($value) && \trim($value) === '') {
310 return \true;
311 }
312 if (\is_countable($value) && \count($value) < 1) {
313 return \true;
314 }
315 if ($value instanceof File) {
316 return (string) $value->getPath() === '';
317 }
318 return \false;
319 }
320 /**
321 * Add a message to the validation errors.
322 *
323 * @param string $message The message to add.
324 * @param array $placeholders The placeholders to replace.
325 *
326 * @return bool
327 *
328 * @since 1.0.0
329 */
330 protected function fails(string $message, array $placeholders = [])
331 {
332 $message = $this->replace_message_placeholders($message, $placeholders);
333 $this->messages = \array_merge($this->messages, Arr::wrap($message));
334 return \false;
335 }
336 /**
337 * Replace the message placeholders.
338 *
339 * @param string $message The message to replace the placeholders in.
340 * @param array $placeholders The placeholders to replace.
341 *
342 * @return string
343 *
344 * @since 1.0.0
345 */
346 protected function replace_message_placeholders(string $message, array $placeholders = [])
347 {
348 $placeholders = \array_merge(['name' => $this->name, 'args' => \is_array($this->args) ? Arr::join(Arr::reject($this->args, fn($arg) => !\is_string($arg) && !\is_numeric($arg)), ', ') : (string) $this->args], $placeholders);
349 $placeholders = Arr::map($placeholders, fn($placeholder) => \is_array($placeholder) ? \implode(', ', $placeholder) : $placeholder);
350 foreach ($placeholders as $key => $value) {
351 $placeholder = '{' . $key . '}';
352 $message = \str_replace($placeholder, $value, $message);
353 }
354 return $message;
355 }
356 /**
357 * Process the messages.
358 *
359 * @param array $messages The messages to process.
360 *
361 * @return array
362 *
363 * @since 1.0.0
364 */
365 protected function process_messages(array $messages)
366 {
367 foreach ($messages as $key => $message) {
368 $messages[$key] = $this->replace_message_placeholders($message);
369 }
370 return $messages;
371 }
372 /**
373 * Get the default messages.
374 *
375 * @param array $keys The keys to get the default messages for.
376 *
377 * @return array
378 *
379 * @since 1.0.0
380 */
381 protected function process_default_messages(array $keys)
382 {
383 $keys = \array_merge(['default'], $keys);
384 $messages = [];
385 foreach ($keys as $key) {
386 $messages[$key] = $this->get_custom_message($key) ?? $this->get_default_message($key);
387 }
388 return $this->default_messages = $messages;
389 }
390 /**
391 * Get the default message.
392 *
393 * @param string $key The key to get the default message for.
394 *
395 * @return string
396 *
397 * @since 1.0.0
398 */
399 protected function get_default_message(string $key)
400 {
401 return message($this->build_message_key($key)) ?? '';
402 }
403 /**
404 * Get the custom message.
405 *
406 * @param string $key The key to get the custom message for.
407 *
408 * @return string|null
409 *
410 * @since 1.0.0
411 */
412 protected function get_custom_message(string $key)
413 {
414 if ($key === 'default') {
415 $key = $this->rule;
416 }
417 $custom_message_key = $this->name . '.' . $key;
418 $message = Arr::get($this->custom_messages, $custom_message_key);
419 if ($message instanceof Closure) {
420 return $message($this->name, $this->value, $this->data);
421 }
422 return $message;
423 }
424 /**
425 * Build the message key.
426 *
427 * @param string $key The key to build the message key for.
428 *
429 * @return string
430 *
431 * @since 1.0.0
432 */
433 protected function build_message_key(string $key)
434 {
435 return 'validator.' . $this->rule . '.' . $key;
436 }
437 }
438