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.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 2 days ago background 2 days ago backups 2 days ago bulk 2 days ago cache 2 days ago cli 2 days ago external 2 days ago frontend 2 days ago integrations 2 days ago lazy-load 2 days ago media 2 days ago media-library 2 days ago membership 2 days ago modules 2 days ago parser 2 days ago photon 2 days ago png2jpg 2 days ago product-analytics 2 days ago rating-notification 2 days ago resize 2 days ago security 2 days ago smush 2 days ago srcset 2 days ago stats 2 days ago threads 2 days ago transform 2 days ago class-abstract-settings-dto.php 2 days ago class-activity-log-controller.php 2 days ago class-animated-status-controller.php 2 days ago class-array-utils.php 2 days ago class-attachment-id-list.php 2 days ago class-backup-size.php 2 days ago class-configs.php 2 days ago class-controller.php 2 days ago class-core.php 2 days ago class-cron-controller.php 2 days ago class-deprecated-hooks.php 2 days ago class-error-handler.php 2 days ago class-file-system.php 2 days ago class-file-utils.php 2 days ago class-format-utils.php 2 days ago class-helper.php 2 days ago class-hub-connector.php 2 days ago class-installer.php 2 days ago class-keyword-exclusions.php 2 days ago class-modules.php 2 days ago class-multisite-utils.php 2 days ago class-optimization-controller.php 2 days ago class-optimizer.php 2 days ago class-plugin-settings-watcher.php 2 days ago class-rest.php 2 days ago class-server-utils.php 2 days ago class-settings-controller.php 2 days ago class-settings-dto.php 2 days ago class-settings-sanitizer.php 2 days ago class-settings.php 2 days ago class-shim.php 2 days ago class-smush-file.php 2 days ago class-stats.php 2 days ago class-string-utils.php 2 days ago class-time-utils.php 2 days ago class-timer.php 2 days ago class-upload-dir.php 2 days ago class-url-utils.php 2 days ago class-urls-exclusions.php 2 days ago class-wp-query-utils.php 2 days ago wp-compat.php 2 days 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