PluginProbe ʕ •ᴥ•ʔ
ShortPixel Image Optimizer – Optimize Images, Convert WebP & AVIF / 6.5.3
ShortPixel Image Optimizer – Optimize Images, Convert WebP & AVIF v6.5.3
6.5.3 6.5.2 6.5.1 trunk 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.6 1.2.0 1.3.1 1.3.5 1.4.0 1.4.1 1.5.0 1.5.3 1.6.0 1.6.1 1.6.10 1.6.2 1.6.3 1.6.4 1.6.6 1.6.7 1.6.8 1.6.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.2 3.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 4.0.0 4.0.1 4.0.2 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.7 4.10.0 4.10.1 4.10.2 4.10.3 4.10.4 4.10.5 4.11.0 4.11.1 4.11.2 4.11.3 4.12.0 4.12.1 4.12.2 4.12.3 4.12.4 4.12.5 4.12.6 4.12.7 4.12.8 4.13.0 4.13.1 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.15.0 4.15.1 4.15.2 4.15.3 4.15.4 4.16.0 4.16.1 4.16.2 4.16.3 4.16.4 4.17.0 4.17.1 4.17.2 4.17.3 4.17.4 4.18.0 4.18.1 4.19.0 4.19.1 4.19.2 4.19.3 4.2.0 4.2.1 4.2.2 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.20.0 4.20.1 4.20.2 4.21.0 4.21.1 4.21.2 4.22.0 4.22.1 4.22.10 4.22.2 4.22.3 4.22.4 4.22.5 4.22.6 4.22.7 4.22.8 4.22.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.2 4.5.3 4.5.5 4.6.0 4.7.0 4.7.1 4.7.2 4.8.0 4.8.1 4.8.2 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.8.9 4.9.0 4.9.1 5.0.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.0.9 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.2.0 5.2.1 5.2.2 5.2.3 5.3.0 5.4.0 5.4.1 5.4.2 5.4.3 5.5.0 5.5.1 5.5.2 5.5.3 5.5.4 5.5.5 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.2.0 6.2.1 6.2.2 6.3.0 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.4.0 6.4.1 6.4.2 6.4.3 6.4.4 6.5.0
shortpixel-image-optimiser / class / Model.php
shortpixel-image-optimiser / class Last commit date
Controller 6 days ago Helper 3 weeks ago Model 6 days ago external 6 days ago view 6 days ago .gitignore 5 years ago BuildAutoLoader.php 3 weeks ago Controller.php 3 weeks ago Model.php 3 weeks ago ViewController.php 3 weeks ago plugin.json 1 month ago
Model.php
306 lines
1 <?php
2 namespace ShortPixel;
3 use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit; // Exit if accessed directly.
7 }
8
9 /**
10 * Abstract base model providing field definition, sanitization, and data retrieval.
11 *
12 * Subclasses define their fields via the $model property array, where each entry
13 * describes the field's sanitization type ('s'), optional max value, and optional
14 * maxlength. The class then handles sanitizing, retrieving, and exposing data in a
15 * consistent manner.
16 *
17 * @package ShortPixel
18 */
19 abstract class Model
20 {
21 /**
22 * Field definitions for the model.
23 *
24 * Each key is a field name; the value is an options array with at minimum:
25 * - 's' (string): sanitization type — 'string', 'int', 'boolean', 'array',
26 * 'exception', or 'skip'.
27 * - 'max' (int, optional): maximum allowed numeric value.
28 * - 'maxlength' (int, optional): maximum string length.
29 *
30 * @var array<string, array<string, mixed>>
31 */
32 protected $model = [];
33
34 /**
35 * Collects all field values defined in the model and returns them as an associative array.
36 *
37 * String values have slashes stripped before being returned.
38 *
39 * @return array<string, mixed> Associative array of field name => current value.
40 */
41 public function getData()
42 {
43 $data = array();
44 foreach($this->model as $item => $options)
45 {
46
47 $value = $this->{$item};
48
49 if (isset($this->model[$item]) && $this->model[$item]['s'] == 'string')
50 {
51 if (false === is_null($value))
52 {
53 $value = stripslashes($value);
54 }
55 }
56
57 $data[$item] = $value;
58
59 }
60 return $data;
61 }
62
63 /**
64 * Returns the list of public field names defined in the model.
65 *
66 * @return string[] Array of field name strings.
67 */
68 public function getModel()
69 {
70 return array_keys($this->model); // only the variable names are public.
71 }
72
73 /**
74 * Sanitizes a single field value according to its model definition.
75 *
76 * Dispatches to the appropriate sanitization helper based on the field's 's' type.
77 * Returns null for unknown fields or 'skip' fields, and passes through values
78 * typed as 'exception' without modification.
79 *
80 * @param string $name The field name.
81 * @param mixed $value The raw value to sanitize.
82 * @return mixed|null Sanitized value, or null if the field is unknown or should be skipped.
83 */
84 protected function sanitize($name, $value)
85 {
86 if (! isset($this->model[$name]))
87 {
88 return null;
89 }
90
91 // if no sanitize method is set, default to strictest string.
92 $sanitize = isset($this->model[$name]['s']) ? $this->model[$name]['s'] : 'string';
93 switch($sanitize)
94 {
95 case "string":
96 $value = $this->sanitizeString($value);
97 $value = $this->checkMaxLength($name, $value);
98 break;
99 case "int":
100 $value = $this->sanitizeInteger($value);
101 $value = $this->checkMax($name, $value);
102 break;
103 case "boolean":
104 $value = $this->sanitizeBoolean($value);
105 break;
106 case 'array':
107 case 'Array':
108 $value = $this->sanitizeArray($value);
109 if (is_null($value))
110 {
111 Log::addWarn('Field ' . $name . ' is of type Array, but Array not provided');
112 }
113 break;
114 case 'exception': // for exceptional situations. The data will not be sanitized! Need to do this elsewhere.
115 return $value;
116 break;
117 case 'skip': // skips should not be in any save candidate and not be sanitized.
118 return null;
119 break;
120 }
121
122 return $value;
123 }
124
125 /** Sanitize the passed post data against the model attribute formats.
126 *
127 * @param array $post The Post data.
128 * @param boolean $missing If fields are missing, include them empty in the output.
129 * @return array Sanitized Post Data.
130 */
131 public function getSanitizedData($post, $missing = true)
132 {
133 $postData = array();
134 foreach($post as $name => $value)
135 {
136 $name = sanitize_text_field($name);
137 $value = $this->sanitize($name, $value);
138 if ($value !== null)
139 $postData[$name] = $value;
140 else {
141 Log::addWarn("Provided field $name not part of model " . get_class($this) );
142 }
143 }
144
145 if ($missing)
146 {
147 $model_fields = $this->getModel();
148 $post_fields = array_keys($postData);
149
150 $missing_fields = array_diff($model_fields, $post_fields);
151 foreach($missing_fields as $index => $field_name)
152 {
153 $field_name = sanitize_text_field($field_name);
154 $type = $this->getType($field_name);
155 if ($type === 'boolean')
156 {
157 $postData[$field_name] = 0;
158 }
159 elseif ($type !== false && $type !== 'skip')
160 {
161 $postData[$field_name] = '';
162 }
163
164 }
165 }
166
167 return $postData;
168 }
169
170
171 /**
172 * Returns the sanitization type string for a named field.
173 *
174 * @param string $name The field name to look up.
175 * @return string|false|null The type string (e.g. 'string', 'int'), false if no type
176 * is set, or null if the field is not in the model.
177 */
178 public function getType($name)
179 {
180 if (! isset($this->model[$name]))
181 {
182 return null;
183 Log::addWarn("Provided field $name not part of model " . get_class($this) );
184 }
185
186
187 $type = isset($this->model[$name]['s']) ? $this->model[$name]['s'] : false;
188 return $type;
189 }
190
191 /**
192 * Sanitizes a value as a plain text string using WordPress's sanitize_text_field().
193 *
194 * @param mixed $string The value to sanitize.
195 * @return string Sanitized string.
196 */
197 public function sanitizeString($string)
198 {
199 return (string) sanitize_text_field($string);
200 }
201
202 /**
203 * Sanitizes a value as an integer using intval().
204 *
205 * @param mixed $int The value to sanitize.
206 * @return int Integer representation of the value.
207 */
208 public function sanitizeInteger($int)
209 {
210 return intval($int);
211 }
212
213 /**
214 * Clamps an integer value to the maximum defined for the field in the model.
215 *
216 * @param string $name The field name.
217 * @param int $value The value to check.
218 * @return int The original value, or the model's max if the value exceeds it.
219 */
220 protected function checkMax($name, $value)
221 {
222 if (false === isset($this->model[$name]['max']))
223 {
224 return $value;
225 }
226
227 if ($value > $this->model[$name]['max'])
228 {
229 return $this->model[$name]['max'];
230 }
231
232 return $value;
233 }
234
235 /**
236 * Truncates a string value to the maximum length defined for the field in the model.
237 *
238 * @param string $name The field name.
239 * @param string $value The string value to check.
240 * @return string The original value, or a truncated copy if it exceeds maxlength.
241 */
242 protected function checkMaxLength($name, $value)
243 {
244 if (false === isset($this->model[$name]['maxlength']))
245 {
246 return $value;
247 }
248
249 $maxlength = $this->model[$name]['maxlength'];
250
251 if (strlen($value) > $maxlength)
252 {
253 $value = substr($value, 0, $maxlength);
254 }
255
256 return $value;
257
258 }
259
260 /**
261 * Sanitizes a value as a boolean (truthy/falsy).
262 *
263 * @param mixed $bool The value to evaluate.
264 * @return bool True if truthy, false otherwise.
265 */
266 public function sanitizeBoolean($bool)
267 {
268 return ($bool) ? true : false;
269 }
270
271 /**
272 * Recursively sanitizes an array, applying sanitizeString() to all keys and leaf values.
273 *
274 * Returns null if the input is not an array.
275 *
276 * @param mixed $array The value to sanitize.
277 * @return array<string, mixed>|null Sanitized array, or null if input was not an array.
278 */
279 public function sanitizeArray($array)
280 {
281 if (! is_array($array))
282 {
283 return null;
284 }
285 $new_array = array();
286 foreach($array as $key => $value)
287 {
288 $newkey = $this->sanitizeString($key);
289
290 if (true === is_array($value))
291 {
292 $newval = $this->sanitizeArray($value);
293 }
294 else {
295 $newval = $this->sanitizeString($value);
296 }
297
298 $new_array[$newkey] = $newval ;
299
300 }
301
302 return $new_array;
303 }
304
305 }
306