PluginProbe ʕ •ᴥ•ʔ
Smush – Image Optimization, Compression, Lazy Load, WebP & CDN / 4.1.0
Smush – Image Optimization, Compression, Lazy Load, WebP & CDN v4.1.0
4.1.2 4.1.1 4.1.0 4.0.3 4.0.2 2.8.1 2.9.1 3.0.0 3.0.1 3.0.2 3.1.1 3.10.1 3.10.2 3.10.3 3.11.1 3.12.3 3.12.4 3.12.5 3.12.6 3.13.0 3.13.1 3.13.2 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.2 3.16.4 3.16.5 3.16.6 3.17.0 3.17.1 3.18.0 3.18.1 3.2.0.1 3.2.1 3.2.2.1 3.2.4 3.20.0 3.21.1 3.22.1 3.22.3 3.23.0 3.23.1 3.23.2 3.23.3 3.23.4 3.24.0 3.24.0-beta.2 3.3.0 3.3.1 3.3.2 3.4.1 3.4.2 3.6.1 3.6.3 3.7.0 3.7.1 3.7.2 3.7.3 3.8.2 3.8.3 3.8.4 3.8.5 3.8.7 3.8.8 3.9.0 3.9.1 3.9.11 3.9.2 3.9.4 3.9.5 3.9.8 3.9.9 trunk 1.0.0 1.0.1 1.0.2 1.1 1.1.1 1.1.2 1.1.3 1.2 1.2.1 1.2.10 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.5.1 1.6.5.2 1.6.5.3 1.6.5.4 1.7 1.7.1 1.7.1.1 2.0 2.0.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.6.2 2.0.6.3 2.0.6.5 2.0.7 2.0.7.1 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2 2.2.1 2.2.2 2.3 2.3.1 2.4 2.4.2 2.4.3 2.4.4 2.4.5 2.5.2 2.5.3 2.6.1 2.6.2 2.6.3 2.7 2.7.1 2.7.4 2.7.4.1 2.7.5 2.7.6 2.7.8 2.7.8.1 2.7.9.1 2.8.0 2.8.0.1
wp-smushit / core / class-settings-sanitizer.php
wp-smushit / core Last commit date
api 3 weeks ago background 3 weeks ago backups 3 weeks ago bulk 3 weeks ago cache 3 weeks ago cli 3 weeks ago external 3 weeks ago frontend 3 weeks ago integrations 3 weeks ago lazy-load 3 weeks ago media 3 weeks ago media-library 3 weeks ago membership 3 weeks ago modules 3 weeks ago parser 3 weeks ago photon 3 weeks ago png2jpg 3 weeks ago product-analytics 3 weeks ago rating-notification 3 weeks ago resize 3 weeks ago security 3 weeks ago smush 3 weeks ago srcset 3 weeks ago stats 3 weeks ago threads 3 weeks ago transform 3 weeks ago class-abstract-settings-dto.php 3 weeks ago class-activity-log-controller.php 3 weeks ago class-animated-status-controller.php 3 weeks ago class-array-utils.php 3 weeks ago class-attachment-id-list.php 3 weeks ago class-backup-size.php 3 weeks ago class-configs.php 3 weeks ago class-controller.php 3 weeks ago class-core.php 3 weeks ago class-cron-controller.php 3 weeks ago class-deprecated-hooks.php 3 weeks ago class-error-handler.php 3 weeks ago class-file-system.php 3 weeks ago class-file-utils.php 3 weeks ago class-format-utils.php 3 weeks ago class-helper.php 3 weeks ago class-hub-connector.php 3 weeks ago class-installer.php 3 weeks ago class-keyword-exclusions.php 3 weeks ago class-modules.php 3 weeks ago class-multisite-utils.php 3 weeks ago class-optimization-controller.php 3 weeks ago class-optimizer.php 3 weeks ago class-plugin-settings-watcher.php 3 weeks ago class-rest.php 3 weeks ago class-server-utils.php 3 weeks ago class-settings-controller.php 3 weeks ago class-settings-dto.php 3 weeks ago class-settings-sanitizer.php 3 weeks ago class-settings.php 3 weeks ago class-shim.php 3 weeks ago class-smush-file.php 3 weeks ago class-stats.php 3 weeks ago class-string-utils.php 3 weeks ago class-time-utils.php 3 weeks ago class-timer.php 3 weeks ago class-upload-dir.php 3 weeks ago class-url-utils.php 3 weeks ago class-urls-exclusions.php 3 weeks ago class-wp-query-utils.php 3 weeks ago wp-compat.php 3 weeks ago
class-settings-sanitizer.php
169 lines
1 <?php
2 /**
3 * Settings Sanitizer Utility
4 *
5 * Generic helpers to sanitize settings received from UI/API before persisting to the database.
6 * Includes schema-based sanitization and small helpers for common shapes (e.g. non-empty string lists).
7 *
8 * @package Smush\Core
9 */
10
11 namespace Smush\Core;
12
13 if ( ! defined( 'WPINC' ) ) {
14 die;
15 }
16
17 /**
18 * Class Settings_Sanitizer
19 *
20 * Provides schema-driven sanitization for settings arrays and helper methods for common settings shapes.
21 */
22 class Settings_Sanitizer {
23
24 /**
25 * Sanitize settings using a schema. Works for both partial updates and full settings arrays.
26 *
27 * Rules:
28 * - 'key' => 'callback' : sanitize that key. If value is array, apply callback to all leaves (map_deep).
29 * - 'key' => [ ... ] : nested schema for arrays.
30 * - Keys missing from schema are sanitized with $fallback_callback (deep).
31 * - Nested keys missing from nested schema are also sanitized with $fallback_callback (deep).
32 *
33 * @param array $input Incoming settings (partial or full).
34 * @param array $schema Sanitization schema.
35 * @param string|callable $fallback_callback Fallback sanitizer applied via deep() when rule is missing/invalid.
36 *
37 * @return array Sanitized settings (same shape/keys as $input).
38 */
39 public static function sanitize( $input, $schema = array(), $fallback_callback = 'sanitize_text_field' ) {
40 $input = is_array( $input ) ? $input : array();
41 $schema = is_array( $schema ) ? $schema : array();
42
43 $out = array();
44
45 foreach ( $input as $key => $value ) {
46 if ( array_key_exists( $key, $schema ) ) {
47 $out[ $key ] = self::sanitize_value_by_rule( $value, $schema[ $key ], $fallback_callback );
48 continue;
49 }
50
51 $out[ $key ] = self::deep( $value, $fallback_callback );
52 }
53
54 return $out;
55 }
56
57 /**
58 * Sanitize a value using a rule (callback or nested schema).
59 *
60 * @param mixed $value Value to sanitize.
61 * @param mixed $rule Rule describing how to sanitize the value.
62 * @param string|callable $fallback_callback Fallback sanitizer applied via deep() when rule is missing/invalid.
63 *
64 * @return mixed
65 */
66 private static function sanitize_value_by_rule( $value, $rule, $fallback_callback ) {
67 /**
68 * Security note:
69 * Only allow executables via the explicit config-schema:
70 * array( 'sanitizer' => (callable) )
71 *
72 * This avoids treating arbitrary input arrays/strings as callables.
73 */
74
75 if ( is_array( $rule ) && array_key_exists( 'sanitizer', $rule ) ) {
76 $callback = is_callable( $rule['sanitizer'] ) ? $rule['sanitizer'] : $fallback_callback;
77 $sanitized = self::deep( $value, $callback );
78
79 // Optionally normalise the whole list: trim, remove empties, deduplicate.
80 if ( ! empty( $rule['nonempty_list'] ) ) {
81 $sanitized = self::sanitize_nonempty_string_list( $sanitized );
82 }
83
84 return $sanitized;
85 }
86
87 // Nested schema (no callables allowed here).
88 if ( is_array( $rule ) ) {
89 $value = is_array( $value ) ? $value : array();
90 $out = array();
91
92 foreach ( $value as $child_key => $child_value ) {
93 if ( array_key_exists( $child_key, $rule ) ) {
94 $out[ $child_key ] = self::sanitize_value_by_rule( $child_value, $rule[ $child_key ], $fallback_callback );
95 } else {
96 $out[ $child_key ] = self::deep( $child_value, $fallback_callback );
97 }
98 }
99
100 return $out;
101 }
102
103 // Invalid rule => fallback.
104 return self::deep( $value, $fallback_callback );
105 }
106
107 /**
108 * Sanitize a list of strings.
109 *
110 * Normalizes typical "list" inputs coming from UI components:
111 * - Ensures the result is always an array.
112 * - Trims each item.
113 * - Drops empty items.
114 * - Removes duplicates.
115 *
116 * @param mixed $sanitized_value Incoming value.
117 *
118 * @return array Normalized list of non-empty, unique strings.
119 */
120 public static function sanitize_nonempty_string_list( $sanitized_value ) {
121 if ( ! is_array( $sanitized_value ) ) {
122 $sanitized_value = array();
123 }
124
125 $items = array();
126 foreach ( $sanitized_value as $item ) {
127 $item = is_string( $item ) ? trim( $item ) : '';
128 if ( '' === $item ) {
129 continue;
130 }
131 $items[] = $item;
132 }
133
134 $items = array_values( array_unique( $items ) );
135
136 return $items;
137 }
138
139 /**
140 * Deep sanitizer: apply callback to all leaf values.
141 *
142 * @param mixed $value Value to sanitize (scalar|array|object).
143 * @param callable $callback Callback to apply to leaf values.
144 *
145 * @return mixed
146 */
147 public static function deep( $value, $callback ) {
148 if ( function_exists( 'map_deep' ) ) {
149 return map_deep( $value, $callback );
150 }
151
152 if ( is_array( $value ) ) {
153 foreach ( $value as $k => $v ) {
154 $value[ $k ] = self::deep( $v, $callback );
155 }
156 return $value;
157 }
158
159 if ( is_object( $value ) ) {
160 foreach ( get_object_vars( $value ) as $k => $v ) {
161 $value->$k = self::deep( $v, $callback );
162 }
163 return $value;
164 }
165
166 return call_user_func( $callback, $value );
167 }
168 }
169