PluginProbe
WebberZone Top 10 — Popular Posts / 4.5.1
WebberZone Top 10 — Popular Posts v4.5.1
4.5.1 4.5.0 4.4.3 4.4.2 4.4.1 4.4.0 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.4.1 1.5 1.5.1 1.5.2 1.5.3 1.6 1.6.1 All 117 releases
← All changes | includes/admin/settings/class-settings-sanitize.php +250 -4 4.3.2 → 4.5.1 View file →
@@ -15,8 +15,10 @@
15 15 }
16 16
17 17 /**
18 18 * Settings Sanitize Class.
19 + *
20 + * @since 4.0.0
19 21 */
20 22 class Settings_Sanitize {
21 23
22 24 /**
@@ -71,15 +73,33 @@
71 73 return $default_value;
72 74 }
73 75
74 76 /**
75 - * Miscellaneous sanitize function
77 + * Fallback for field types that declare no sanitize callback of their own.
76 78 *
77 79 * @param mixed $value Setting Value.
78 - * @return string Sanitized value.
80 + * @return mixed Sanitized value.
79 81 */
80 82 public function sanitize_missing( $value ) {
81 - return $value;
83 + if ( is_array( $value ) ) {
84 + $sanitized = array();
85 +
86 + foreach ( $value as $key => $item ) {
87 + $sanitized[ sanitize_text_field( (string) $key ) ] = $this->sanitize_missing( $item );
88 + }
89 +
90 + return $sanitized;
91 + }
92 +
93 + if ( is_bool( $value ) || is_int( $value ) || is_float( $value ) ) {
94 + return $value;
95 + }
96 +
97 + if ( is_object( $value ) || is_null( $value ) ) {
98 + return '';
99 + }
100 +
101 + return sanitize_text_field( wp_unslash( (string) $value ) );
82 102 }
83 103
84 104 /**
85 105 * Sanitize text fields
@@ -146,8 +166,12 @@
146 166 * @return string Sanitized value
147 167 */
148 168 public function sanitize_textarea_field( $value ) {
149 169
170 + if ( ! current_user_can( 'unfiltered_html' ) ) {
171 + return wp_kses_post( wp_unslash( $value ) );
172 + }
173 +
150 174 global $allowedposttags;
151 175
152 176 // We need more tags to allow for script and style.
153 177 $moretags = array(
@@ -197,8 +221,18 @@
197 221 return $value;
198 222 }
199 223
200 224 /**
225 + * Sanitize toggle fields
226 + *
227 + * @param mixed $value The field value.
228 + * @return int Sanitized value
229 + */
230 + public function sanitize_toggle_field( $value ) {
231 + return $this->sanitize_checkbox_field( $value );
232 + }
233 +
234 + /**
201 235 * Sanitize multicheck fields
202 236 *
203 237 * @param array|int $value The field value.
204 238 * @return string $value Sanitized value
@@ -259,8 +293,145 @@
259 293 return esc_url_raw( $value );
260 294 }
261 295
262 296 /**
297 + * Sanitize file fields, which hold the URL picked in the media browser.
298 + *
299 + * @param string $value The field value.
300 + * @return string Sanitized value
301 + */
302 + public function sanitize_file_field( $value ) {
303 + return esc_url_raw( wp_unslash( $value ) );
304 + }
305 +
306 + /**
307 + * Sanitize password fields.
308 + *
309 + * @param string $value The field value.
310 + * @return string Sanitized value
311 + */
312 + public function sanitize_password_field( $value ) {
313 + return sanitize_text_field( wp_unslash( $value ) );
314 + }
315 +
316 + /**
317 + * Sanitize WYSIWYG fields.
318 + *
319 + * @param string $value The field value.
320 + * @return string Sanitized value
321 + */
322 + public function sanitize_wysiwyg_field( $value ) {
323 + return wp_kses_post( wp_unslash( $value ) );
324 + }
325 +
326 + /**
327 + * Sanitize HTML fields.
328 + *
329 + * @param string $value The field value.
330 + * @return string Sanitized value
331 + */
332 + public function sanitize_html_field( $value ) {
333 + return $this->sanitize_textarea_field( $value );
334 + }
335 +
336 + /**
337 + * Sanitize CSS fields.
338 + *
339 + * @param string $value The field value.
340 + * @return string Sanitized value
341 + */
342 + public function sanitize_css_field( $value ) {
343 + return wp_strip_all_tags( wp_unslash( $value ) );
344 + }
345 +
346 + /**
347 + * Sanitize radio fields against the options the field actually offers.
348 + *
349 + * @param mixed $value The field value.
350 + * @param array $field Field configuration array.
351 + * @return string Sanitized value
352 + */
353 + public function sanitize_radio_field( $value, $field = array() ) {
354 + return $this->sanitize_choice( $value, array_keys( (array) ( $field['options'] ?? array() ) ), $field );
355 + }
356 +
357 + /**
358 + * Sanitize select fields against the options the field actually offers.
359 + *
360 + * @param mixed $value The field value.
361 + * @param array $field Field configuration array.
362 + * @return string Sanitized value
363 + */
364 + public function sanitize_select_field( $value, $field = array() ) {
365 + return $this->sanitize_choice( $value, array_keys( (array) ( $field['options'] ?? array() ) ), $field );
366 + }
367 +
368 + /**
369 + * Sanitize radio fields that carry a description per option.
370 + *
371 + * @param mixed $value The field value.
372 + * @param array $field Field configuration array.
373 + * @return string Sanitized value
374 + */
375 + public function sanitize_radiodesc_field( $value, $field = array() ) {
376 + $allowed = array();
377 +
378 + foreach ( (array) ( $field['options'] ?? array() ) as $option ) {
379 + if ( isset( $option['id'] ) ) {
380 + $allowed[] = $option['id'];
381 + }
382 + }
383 +
384 + return $this->sanitize_choice( $value, $allowed, $field );
385 + }
386 +
387 + /**
388 + * Sanitize thumbnail size fields.
389 + *
390 + * @param mixed $value The field value.
391 + * @param array $field Field configuration array.
392 + * @return string Sanitized value
393 + */
394 + public function sanitize_thumbsizes_field( $value, $field = array() ) {
395 + $allowed = array_keys( (array) ( $field['options'] ?? array() ) );
396 +
397 + // The form injects this size at render time, so it is never in the registered options.
398 + $allowed[] = $this->prefix . '_thumbnail';
399 +
400 + return $this->sanitize_choice( $value, $allowed, $field );
401 + }
402 +
403 + /**
404 + * Restrict a value to a list of allowed choices.
405 + *
406 + * @param mixed $value The field value.
407 + * @param array $allowed Allowed choices.
408 + * @param array $field Field configuration array.
409 + * @return string Sanitized value
410 + */
411 + protected function sanitize_choice( $value, $allowed, $field = array() ) {
412 + $value = sanitize_text_field( wp_unslash( (string) $value ) );
413 + $allowed = array_map( 'strval', (array) $allowed );
414 +
415 + if ( in_array( $value, $allowed, true ) ) {
416 + return $value;
417 + }
418 +
419 + // The select callback prints option values through sanitize_key().
420 + foreach ( $allowed as $choice ) {
421 + if ( sanitize_key( $choice ) === $value ) {
422 + return $choice;
423 + }
424 + }
425 +
426 + if ( isset( $field['default'] ) ) {
427 + return (string) $field['default'];
428 + }
429 +
430 + return empty( $allowed ) ? '' : reset( $allowed );
431 + }
432 +
433 + /**
263 434 * Sanitize sensitive fields.
264 435 *
265 436 * @param string $value The field value.
266 437 * @param string|array $key The field key.
@@ -297,8 +468,14 @@
297 468 * @param array $field Field configuration array.
298 469 * @return array Sanitized array
299 470 */
300 471 public function sanitize_repeater_field( $value, $field = array() ) {
472 + // No usable controls are rendered, so submitted rows are forged.
473 + if ( ! empty( $field['disabled'] ) || ! empty( $field['pro'] ) ) {
474 + $stored = ! empty( $field['id'] ) ? $this->get_option( $field['id'], array() ) : array();
475 + return is_array( $stored ) ? $stored : array();
476 + }
477 +
301 478 if ( ! is_array( $value ) ) {
302 479 return array();
303 480 }
304 481
@@ -395,8 +572,77 @@
395 572 return $sanitized_value;
396 573 }
397 574
398 575 /**
576 + * Find repeater rows that fail their own required-field rules.
577 + *
578 + * Purely structural - returns what is wrong, not a human message, so it carries no i18n.
579 + *
580 + * @param array $rows Sanitized repeater rows, as returned by sanitize_repeater_field().
581 + * @param array $field Repeater field configuration.
582 + * @return array Map of row index => issue, where issue may have a 'missing' key
583 + * (subfield IDs with required => true that are empty) and/or a
584 + * 'missing_one_of' key (the required_one_of group, present only when
585 + * none of it is filled).
586 + */
587 + public static function get_incomplete_repeater_rows( array $rows, array $field ) {
588 + $subfields = ! empty( $field['fields'] ) && is_array( $field['fields'] ) ? $field['fields'] : array();
589 +
590 + $required_subfields = array();
591 + foreach ( $subfields as $subfield_id => $subfield ) {
592 + // Row values are keyed by the subfield's own id; the array key may be numeric.
593 + if ( ! empty( $subfield['required'] ) ) {
594 + $required_subfields[] = $subfield['id'] ?? $subfield_id;
595 + }
596 + }
597 +
598 + $required_one_of = ! empty( $field['required_one_of'] ) && is_array( $field['required_one_of'] ) ? $field['required_one_of'] : array();
599 +
600 + if ( empty( $required_subfields ) && empty( $required_one_of ) ) {
601 + return array();
602 + }
603 +
604 + $is_filled = static function ( $values, $subfield_id ) {
605 + return '' !== trim( (string) ( $values[ $subfield_id ] ?? '' ), " \t\n\r\0\x0B," );
606 + };
607 + $incomplete = array();
608 +
609 + foreach ( array_values( $rows ) as $index => $row ) {
610 + $values = isset( $row['fields'] ) && is_array( $row['fields'] ) ? $row['fields'] : array();
611 + $issue = array();
612 +
613 + $missing = array();
614 + foreach ( $required_subfields as $subfield_id ) {
615 + if ( ! $is_filled( $values, $subfield_id ) ) {
616 + $missing[] = $subfield_id;
617 + }
618 + }
619 + if ( ! empty( $missing ) ) {
620 + $issue['missing'] = $missing;
621 + }
622 +
623 + if ( ! empty( $required_one_of ) ) {
624 + $filled = false;
625 + foreach ( $required_one_of as $subfield_id ) {
626 + if ( $is_filled( $values, $subfield_id ) ) {
627 + $filled = true;
628 + break;
629 + }
630 + }
631 + if ( ! $filled ) {
632 + $issue['missing_one_of'] = $required_one_of;
633 + }
634 + }
635 +
636 + if ( ! empty( $issue ) ) {
637 + $incomplete[ $index ] = $issue;
638 + }
639 + }
640 +
641 + return $incomplete;
642 + }
643 +
644 + /**
399 645 * Convert a string to CSV.
400 646 *
401 647 * @param array $input_array Input string.
402 648 * @param string $delimiter Delimiter.
@@ -453,9 +699,9 @@
453 699 return $output;
454 700 }
455 701
456 702 /**
457 - * Processes category/taxonomy slugs and adds a new element to the settings array containing the term taxonomy IDs.
703 + * Resolve taxonomy slugs to term taxonomy IDs.
458 704 *
459 705 * @param array $settings The settings array containing the taxonomy slugs to sanitize.
460 706 * @param string $source_key The key in the settings array containing the slugs. Pattern is Name (taxonomy:term_taxonomy_id).
461 707 * @param string $target_key The key in the settings array to store the sanitized term taxonomy IDs.