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 / ViewController.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
ViewController.php
358 lines
1 <?php
2 namespace ShortPixel;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
9 use ShortPixel\Model\AccessModel as AccessModel;
10
11 /**
12 * Base controller for view-related functionality.
13 *
14 * Extends Controller to add view rendering, POST data handling, nonce verification,
15 * and HTML output helpers. Most admin page controllers extend this class.
16 *
17 * @package ShortPixel
18 */
19 class ViewController extends Controller
20 {
21 // protected static $controllers = array();
22
23 /**
24 * Tracks which view templates have already been included to prevent double-loading.
25 *
26 * @var string[]
27 */
28 protected static $viewsLoaded = array();
29
30 /**
31 * Singleton instance of the controller.
32 *
33 * @var static|null
34 */
35 protected static $instance;
36
37 /** @var mixed|null Connected model instance. */
38 protected $model; // connected model to load.
39
40 /** @var string|null Template file name (without .php extension) to include when loading the view. */
41 protected $template = null; // template name to include when loading.
42
43 /** @var array<string, mixed> Data array for passing database data and other values to the view. */
44 protected $data = []; // data array for usage with databases data and such
45
46 /** @var array<string, mixed> Sanitized data received from form POST submissions. */
47 protected $postData = []; // data coming from form posts.
48
49 /**
50 * Optional map of POST field names to model field names.
51 * Keys are the incoming POST names; values are the corresponding model field names.
52 *
53 * @var array<string, string>|null
54 */
55 protected $mapper; // Mapper is array of View Name => Model Name. Convert between the two
56
57 /** @var bool Whether a form was submitted in the current request. */
58 protected $is_form_submit = false; // Was the form submitted?
59
60 /** @var \stdClass View data object passed into included template files. */
61 protected $view; // object to use in the view.
62
63 /** @var string|null URL of the admin page this controller manages, used for redirects. */
64 protected $url; // if controller is home to a page, sets the URL here. For redirects and what not.
65
66 /** @var string Nonce action name used when verifying form submissions. */
67 protected $form_action = 'sp-action';
68
69 public static function init()
70 {
71
72 }
73
74 public function __construct()
75 {
76 parent::__construct();
77 $this->view = new \stdClass;
78 // Basic View Construct
79 $this->view->notices = null; // Notices of class notice, for everything noticable
80 $this->view->data = null; // Data(base), to separate from regular view data
81
82 }
83
84 /**
85 * Returns the singleton instance of the calling class, creating it if necessary.
86 *
87 * Uses late static binding so subclasses each maintain their own instance.
88 *
89 * @return static The singleton instance.
90 */
91 public static function getInstance() {
92 if (is_null(static::$instance)) {
93 static::$instance = new static();
94 }
95
96 return static::$instance;
97 }
98
99 /**
100 * Verifies an incoming form POST against the controller's nonce.
101 *
102 * When a valid POST is detected, optionally calls processPostData() to sanitize
103 * and store the submitted fields. Returns false and terminates execution on a
104 * hard nonce failure; returns true silently when no POST data is present.
105 *
106 * @param bool $processPostData Whether to call processPostData() on valid submission. Default true.
107 * @return bool True when no POST or POST is valid; false on nonce mismatch with ajaxSave present.
108 */
109 protected function checkPost($processPostData = true)
110 {
111
112 if(count($_POST) === 0) // no post, nothing to check, return silent.
113 {
114 return true;
115 }
116 elseif (! isset($_POST['sp-nonce']) || ! wp_verify_nonce( sanitize_key($_POST['sp-nonce']), $this->form_action))
117 {
118 // Obscure issue. Detected other plugin that adds information to $_POST without an actual form submit, which would trigger the nonce check on the settings page. In case this happens, be lenient.
119 if ( ! isset($_POST['ajaxSave']) || ! isset($_POST['action']) )
120 {
121 return false;
122 }
123 Log::addInfo('Check Post fails nonce check, action : ' . $this->form_action, array($_POST) );
124 wp_die('Nonce Failed');
125 return true;
126 }
127 elseif (isset($_POST) && count($_POST) > 0)
128 {
129 check_admin_referer( $this->form_action, 'sp-nonce' ); // extra check, when we are wrong here, it dies.
130
131 $this->is_form_submit = true;
132 if (true === $processPostData) // only processData on form save.
133 {
134 $this->processPostData($_POST);
135 }
136
137
138 }
139 return true;
140 }
141
142 /**
143 * Returns the singleton AccessModel instance for permission checks.
144 *
145 * @return AccessModel
146 */
147 public function access()
148 {
149 return AccessModel::getInstance();
150 }
151
152 /**
153 * Loads and includes a view template file from the class/view/ directory.
154 *
155 * If $unique is true (default), each template is included only once per request.
156 * Passes $this->view and $this as local variables ($view and $controller) to the template.
157 *
158 * @param string|null $template Relative template name (without .php). Falls back to $this->template.
159 * @param bool $unique Whether to prevent loading the same template more than once. Default true.
160 * @param array $args Additional arguments made available as $view->template_args inside the template.
161 * @return bool|void False when no valid template name is available; void otherwise.
162 */
163 public function loadView($template = null, $unique = true, $args = [])
164 {
165 // load either param or class template.
166 $template = (is_null($template)) ? $this->template : $template;
167
168 if (is_null($template) )
169 {
170 return false;
171 }
172 elseif (strlen(trim($template)) == 0)
173 {
174 return false;
175 }
176
177 $view = $this->view;
178 $view->template_args = $args; // local pass only for this view, useful for snippets, not main controllers.
179 $controller = $this;
180
181 $template_path = \wpSPIO()->plugin_path('class/view/' . $template . '.php');
182 if (file_exists($template_path) === false)
183 {
184 Log::addError("View $template could not be found in " . $template_path,
185 array('class' => get_class($this)));
186 }
187 elseif ($unique === false || ! in_array($template, self::$viewsLoaded))
188 {
189 include($template_path);
190 self::$viewsLoaded[] = $template;
191 }
192 else {
193
194 }
195
196 }
197
198 /** Manually add data to this viewcontroller
199 *
200 * @param array $data Data to add.
201 * @return void
202 */
203 public function addData($data)
204 {
205 $this->data = array_merge($this->data, $data);
206 }
207
208 /** Loads a view and then returns it as html string. Handy for passing back snippets in JSON and other things.
209 *
210 * @param string $template Name of template
211 * @return string HTML string of view loaded.
212 */
213 public function returnView($template = null)
214 {
215 $bool = ob_start();
216 $html = '';
217
218 if (true === $bool)
219 {
220 $this->loadView($template, false);
221 $html = ob_get_contents();
222 ob_end_clean();
223 }
224 else
225 {
226 Log::addError('Output buffer failed requesting returnView!' . $template);
227 }
228
229 return $html;
230 }
231
232 /**
233 * Outputs an inline help icon linking to external documentation.
234 *
235 * @param string $url The documentation URL to link to (will be escaped).
236 * @return void
237 */
238 protected function printInlineHelp($url)
239 {
240
241 $output = '<i class="documentation dashicons dashicons-editor-help" data-link="' . esc_url($url). '"></i>';
242 echo $output;
243
244 }
245
246 /**
247 * Renders and echoes a toggle switch button element.
248 *
249 * Accepts an array of arguments that control the name, checked state, label,
250 * CSS classes, data attributes, and disabled state of the rendered switch.
251 *
252 * @param array $args {
253 * Optional. Overrides for the switch button defaults.
254 *
255 * @type string $name Input name attribute. Default ''.
256 * @type bool $checked Whether the switch is checked. Default false.
257 * @type string $label Label text displayed beside the switch. Default ''.
258 * @type string|false $switch_class CSS class for the outer <switch> element. Default false.
259 * @type string $input_class CSS class for the <input> element. Default 'switch'.
260 * @type array $data Additional data attributes as pre-formatted strings. Default [].
261 * @type bool $disabled Whether the switch is disabled. Default false.
262 * }
263 * @return void
264 */
265 protected function printSwitchButton($args)
266 {
267 $defaults = array(
268 'name' => '',
269 'checked' => false,
270 'label' => '',
271 'switch_class' => false,
272 'input_class' => 'switch',
273 'data' => [],
274 'disabled' => false,
275 'tooltip_link' => '',
276 );
277
278 $args = wp_parse_args($args, $defaults);
279
280 $switchclass = ($args['switch_class'] !== false) ? 'class="' . $args['switch_class'] . '"' : '';
281 $inputclass = $args['input_class'];
282 $checked = checked($args['checked'], true, false);
283 $name = esc_attr($args['name']);
284 $label = esc_attr($args['label']);
285
286 $tooltip = '';
287 if (! empty($args['tooltip_link'])) {
288 $tooltip = sprintf('<i class="documentation dashicons dashicons-editor-help" data-link="%s"></i>', esc_attr($args['tooltip_link']));
289 }
290
291 $data = implode(' ', $args['data']);
292
293 $disabled = $args['disabled'];
294 $disabled = (true === $disabled) ? 'disabled' : '';
295
296 $output = sprintf('<switch %s>
297 <label>
298 <input type="checkbox" class="%s" name="%s" value="1" %s %s %s>
299 <div class="the_switch">&nbsp;</div>
300 %s%s
301 </label>
302 </switch>', $switchclass, $inputclass, $name, $checked, $disabled, $data, $label, $tooltip);
303
304 echo $output;
305 }
306
307 /** Accepts POST data, maps, checks missing fields, and applies sanitization to it.
308 *
309 * Applies any field name mappings defined in $this->mapper, then either sanitizes
310 * each field via the connected model or falls back to sanitize_text_field() when no
311 * model is set. The result is stored in $this->postData.
312 *
313 * @param array $post Raw POST data (typically $_POST).
314 * @return array<string, mixed>|bool Sanitized post data array, or true if no model is set.
315 */
316 protected function processPostData($post)
317 {
318
319 // If there is something to map, map.
320 if ($this->mapper && is_array($this->mapper) && count($this->mapper) > 0)
321 {
322 foreach($this->mapper as $item => $replace)
323 {
324 if ( isset($post[$item]))
325 {
326 $post[$replace] = $post[$item];
327 unset($post[$item]);
328 }
329 }
330 }
331
332 if (is_null($this->model) && is_null($model))
333 {
334 foreach($post as $name => $value )
335 {
336 $this->postData[sanitize_text_field($name)] = sanitize_text_field($value);
337 return true;
338 }
339 }
340 else
341 {
342 $this->postData = $this->model->getSanitizedData($post, false);
343 }
344
345 return $this->postData;
346
347 }
348
349 /** Sets the URL of the admin page */
350 public function setControllerURL($url)
351 {
352 $this->url = $url;
353 }
354
355
356
357 } // controller
358