PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.0.13
Kirki – Freeform Page Builder, Website Builder & Customizer v6.0.13
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 / Sanitizer.php
kirki / libraries / framework Last commit date
Collections 2 weeks ago Concerns 2 weeks ago Console 2 weeks ago Constants 2 weeks ago Contracts 2 weeks ago Database 2 weeks ago Discovery 2 weeks ago Exceptions 2 weeks ago Filesystem 2 weeks ago Http 2 weeks ago Managers 2 weeks ago Middlewares 2 weeks ago Polyfill 2 weeks ago Supports 2 weeks ago Validation 2 weeks ago Wordpress 2 weeks ago ApiExceptionHandler.php 2 weeks ago Application.php 2 weeks ago Container.php 2 weeks ago CoreServiceProvider.php 2 weeks ago DTO.php 2 weeks ago Facade.php 2 weeks ago Listener.php 2 weeks ago Resource.php 2 weeks ago Route.php 2 weeks ago Sanitizer.php 2 weeks ago ServiceProvider.php 2 weeks ago helpers.php 2 weeks ago
Sanitizer.php
385 lines
1 <?php
2
3 /**
4 * Central registry of named sanitization strategies mapped to WordPress and custom cleaners.
5 * Defines constants for text, email, url, rich-text, and structured types with a dispatch method per rule name.
6 * Shared by validation and request sanitization pipelines.
7 *
8 * @package Framework
9 * @since 1.0.0
10 */
11 namespace Kirki\Framework;
12
13 \defined('ABSPATH') || exit;
14 use Kirki\Framework\Supports\Facades\Date;
15 use function Kirki\Framework\is_valid_json;
16 class Sanitizer
17 {
18 /**
19 * Trim the value.
20 *
21 * @var string
22 */
23 public const ANY = 'any';
24 /**
25 * Trim the value.
26 *
27 * @var string
28 */
29 public const TRIM = 'trim';
30 /**
31 * Sanitize the value as text.
32 *
33 * @var string
34 */
35 public const TEXT = 'text';
36 /**
37 * Sanitize the rich text content.
38 *
39 * @var string
40 */
41 public const RICH_TEXT = 'rich-text';
42 /**
43 * Sanitize the value as textarea.
44 *
45 * @var string
46 */
47 public const TEXTAREA = 'textarea';
48 /**
49 * Sanitize the value as email.
50 *
51 * @var string
52 */
53 public const EMAIL = 'email';
54 /**
55 * Sanitize the value as username.
56 *
57 * @var string
58 */
59 public const USERNAME = 'username';
60 /**
61 * Sanitize the value as url.
62 *
63 * @var string
64 */
65 public const URL = 'url';
66 /**
67 * Sanitize the value as key.
68 *
69 * @var string
70 */
71 public const KEY = 'key';
72 /**
73 * Sanitize the value as title.
74 *
75 * @var string
76 */
77 public const TITLE = 'title';
78 /**
79 * Sanitize the value as file name.
80 *
81 * @var string
82 */
83 public const FILE_NAME = 'file-name';
84 /**
85 * Sanitize the value as mime type.
86 *
87 * @var string
88 */
89 public const MIME_TYPE = 'mime-type';
90 /**
91 * Sanitize the value as int.
92 *
93 * @var string
94 */
95 public const INT = 'int';
96 /**
97 * Sanitize the value as int.
98 *
99 * @var string
100 */
101 public const FLOAT = 'float';
102 /**
103 * Sanitize the value as double.
104 *
105 * @var string
106 */
107 public const DOUBLE = 'double';
108 /**
109 * Sanitize the value as boolean.
110 *
111 * @var string
112 */
113 public const BOOL = 'bool';
114 /**
115 * Sanitize the value as array.
116 *
117 * @var string
118 */
119 public const ARRAY = 'array';
120 /**
121 * Sanitize the value as date.
122 *
123 * @var string
124 */
125 public const DATE = 'date';
126 /**
127 * Sanitize the value as datetime.
128 *
129 * @var string
130 */
131 public const DATETIME = 'datetime';
132 /**
133 * Sanitize the value as serialized.
134 *
135 * @var string
136 */
137 public const SERIALIZED = 'serialized';
138 /**
139 * Sanitize the value as unserialized.
140 *
141 * @var string
142 */
143 public const UNSERIALIZED = 'unserialized';
144 /**
145 * Input data.
146 *
147 * @var array<key:int,value:mixed>
148 *
149 * @since 1.0.0
150 */
151 protected $data;
152 /**
153 * Sanitized data.
154 *
155 * @var array<key:int,value:mixed>
156 *
157 * @since 1.0.0
158 */
159 protected $sanitized_data = [];
160 /**
161 * Sanitization rules.
162 *
163 * @var array<key:int,value:mixed>
164 *
165 * @since 1.0.0
166 */
167 protected $rules;
168 /**
169 * Create a new Sanitizer instance.
170 *
171 * @param array $data The data payload.
172 * @param array $rules The rules.
173 *
174 * @return void
175 *
176 * @since 1.0.0
177 */
178 public function __construct(array $data = [], array $rules = [])
179 {
180 $this->data = $data;
181 $this->rules = $rules;
182 $this->run_sanitizer();
183 }
184 /**
185 * Get the sanitized data.
186 *
187 * @return array
188 *
189 * @since 1.0.0
190 */
191 public function get_sanitized_data()
192 {
193 return $this->sanitized_data;
194 }
195 /**
196 * Sanitize the data.
197 *
198 * @param array $data The data payload.
199 * @param array $rules The rules.
200 *
201 * @return static
202 *
203 * @since 1.0.0
204 */
205 public static function make(array $data = [], array $rules = [])
206 {
207 return new static($data, $rules);
208 }
209 /**
210 * Run sanitizer
211 *
212 * @return void
213 *
214 * @since 1.0.0
215 */
216 protected function run_sanitizer()
217 {
218 foreach ($this->rules as $key => $rule) {
219 $key_segments = \explode('.', $key);
220 $this->traverse_and_sanitize($this->data, $key_segments, [], $rule);
221 }
222 }
223 /**
224 * Recursively traverses the input data structure according to a dot-notated rule key,
225 * handling wildcard segments (e.g., *) to apply sanitization rules at dynamic levels.
226 *
227 * @param mixed $current_data The current level of data being inspected. This is a portion
228 * @param array $key_segments The remaining parts (split by '.') of the rule key that
229 * @param array $traversed_path_stack The stack of key_segments already traversed so far. This is used
230 * @param string $rule A sanitization rule to apply on the current data.
231 *
232 * @return void
233 *
234 * @since 1.0.0
235 */
236 protected function traverse_and_sanitize($current_data, $key_segments, $traversed_path_stack, $rule)
237 {
238 // when all segments have been traversed
239 if (empty($key_segments)) {
240 $this->set_sanitized_data($traversed_path_stack, static::apply_rule($current_data, $rule, $this->data));
241 return;
242 }
243 $segment = \array_shift($key_segments);
244 if ($segment === '*') {
245 if (!\is_array($current_data)) {
246 $this->set_sanitized_data($traversed_path_stack, static::apply_rule($current_data, static::ARRAY, $this->data));
247 return;
248 }
249 foreach ($current_data as $index => $item) {
250 $this->traverse_and_sanitize($item, $key_segments, \array_merge($traversed_path_stack, [$index]), $rule);
251 }
252 } elseif (\is_array($current_data) && \array_key_exists($segment, $current_data)) {
253 $this->traverse_and_sanitize($current_data[$segment], $key_segments, \array_merge($traversed_path_stack, [$segment]), $rule);
254 }
255 }
256 /**
257 * Set the sanitized data using a series of keys to traverse the nested array structure.
258 *
259 * @param array $keys An array of keys representing the path in the nested array structure.
260 * @param mixed $value The value to set at the specified path in the sanitized data array.
261 *
262 * @return void
263 *
264 * @since 1.0.0
265 */
266 protected function set_sanitized_data($keys, $value)
267 {
268 $ref =& $this->sanitized_data;
269 foreach ($keys as $key) {
270 if (!isset($ref[$key])) {
271 $ref[$key] = [];
272 }
273 $ref =& $ref[$key];
274 }
275 $ref = $value;
276 }
277 /**
278 * Apply sanitization.
279 *
280 * @param mixed $value The value.
281 * @param mixed $type The type.
282 * @param array $data The data payload.
283 *
284 * @return mixed
285 *
286 * @since 1.0.0
287 */
288 public static function apply_rule($value, $type, array $data = [])
289 {
290 // For the null values, we don't need to sanitize them.
291 if (\is_null($value)) {
292 return null;
293 }
294 if ($type === null) {
295 return $value;
296 }
297 switch ($type) {
298 case static::ANY:
299 return $value;
300 case static::TRIM:
301 $value = \trim($value);
302 break;
303 case static::TEXT:
304 $value = sanitize_text_field($value);
305 break;
306 case static::RICH_TEXT:
307 $value = wp_kses_post($value);
308 break;
309 case static::TEXTAREA:
310 $value = sanitize_textarea_field($value);
311 break;
312 case static::EMAIL:
313 $value = sanitize_email($value);
314 break;
315 case static::USERNAME:
316 $value = sanitize_user($value);
317 break;
318 case static::URL:
319 $value = sanitize_url($value);
320 break;
321 case static::KEY:
322 $value = sanitize_key($value);
323 break;
324 case static::TITLE:
325 $value = sanitize_title($value);
326 break;
327 case static::FILE_NAME:
328 $value = sanitize_file_name($value);
329 break;
330 case static::MIME_TYPE:
331 $value = sanitize_mime_type($value);
332 break;
333 case static::INT:
334 $value = (int) $value;
335 break;
336 case static::FLOAT:
337 case static::DOUBLE:
338 $value = (float) $value;
339 break;
340 case static::BOOL:
341 $value = rest_sanitize_boolean($value);
342 break;
343 case static::ARRAY:
344 if (\is_array($value)) {
345 break;
346 }
347 if (empty($value)) {
348 return null;
349 }
350 if (is_valid_json($value)) {
351 $value = \json_decode($value, \true);
352 break;
353 }
354 return null;
355 case static::DATE:
356 if (!Date::is_valid_date($value)) {
357 return null;
358 }
359 $value = Date::start_of_day(Date::parse($value));
360 break;
361 case static::DATETIME:
362 if (!Date::is_valid_date($value)) {
363 return null;
364 }
365 $value = Date::parse($value);
366 break;
367 case static::SERIALIZED:
368 $value = maybe_serialize($value);
369 break;
370 case static::UNSERIALIZED:
371 if (!is_serialized($value)) {
372 break;
373 }
374 $value = \unserialize(\trim($value), ['allowed_classes' => \false]);
375 break;
376 default:
377 if (\is_callable($type)) {
378 $value = $type($value, $data);
379 }
380 break;
381 }
382 return $value;
383 }
384 }
385