PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.7.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.7.0
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
← All changes | includes/class-updraft-smush-manager-commands.php +121 -123 3.7.0 → 4.7.0 View file →
@@ -49,8 +49,10 @@
49 49 }
50 50
51 51 /**
52 52 * Returns a list of commands available for smush related operations
53 + *
54 + * @return array
53 55 */
54 56 public static function get_allowed_ajax_commands() {
55 57
56 58 $commands = parent::get_allowed_ajax_commands();
@@ -81,28 +83,36 @@
81 83
82 84 /**
83 85 * Process the compression of a single image
84 86 *
85 - * @param mixed $data - sent in via AJAX
87 + * @param array $data - sent in via AJAX
86 88 * @return WP_Error|array - information about the operation or WP_Error object on failure
87 89 */
88 90 public function compress_single_image($data) {
89 91
90 - $options = !empty($data['smush_options']) ? $data['smush_options'] : $this->task_manager->get_smush_options();
91 - $image = isset($data['selected_image']) ? filter_var($data['selected_image']['attachment_id'], FILTER_SANITIZE_NUMBER_INT) : false;
92 - $blog = isset($data['selected_image']) ? filter_var($data['selected_image']['blog_id'], FILTER_SANITIZE_NUMBER_INT) : false;
92 + $options = empty($data['smush_options']) ? $this->task_manager->get_smush_options() : $data['smush_options'];
93 + $image = isset($data['selected_image']['attachment_id']) ? absint($data['selected_image']['attachment_id']) : 0;
94 + $blog = isset($data['selected_image']['blog_id']) ? absint($data['selected_image']['blog_id']) : 0;
93 95
94 - // A subsite administrator can only compress their own image. If the blog ID isn't theirs, return an error.
95 - if ($blog && is_multisite() && get_current_blog_id() != $blog && !current_user_can('manage_network_options')) {
96 + if (0 === $image) {
97 + return new WP_Error('invalid_image', __('Image ID is invalid', 'wp-optimize'));
98 + }
99 +
100 + if (0 === $blog && is_multisite()) {
101 + return new WP_Error('invalid_blog', __('Blog ID is invalid', 'wp-optimize'));
102 + }
103 +
104 + // A sub site administrator can only compress their own image. If the blog ID isn't theirs, return an error.
105 + if ($blog && is_multisite() && get_current_blog_id() !== $blog && !WP_Optimize()->current_user_can('manage_network_options')) {
96 106 return new WP_Error('compression_not_permitted', __('The blog ID provided does not match the current blog.', 'wp-optimize'));
97 107 }
98 108
99 - $server = sanitize_text_field($options['compression_server']);
109 + $server = isset($options['compression_server']) ? sanitize_text_field($options['compression_server']) : $this->task_manager->get_default_webservice();
100 110
101 - $lossy = filter_var($options['lossy_compression'], FILTER_VALIDATE_BOOLEAN) ? true : false;
102 - $backup = filter_var($options['back_up_original'], FILTER_VALIDATE_BOOLEAN) ? true : false;
103 - $exif = filter_var($options['preserve_exif'], FILTER_VALIDATE_BOOLEAN) ? true : false;
104 - $quality = filter_var($options['image_quality'], FILTER_SANITIZE_NUMBER_INT);
111 + $lossy = isset($options['lossy_compression']) ? filter_var($options['lossy_compression'], FILTER_VALIDATE_BOOLEAN) : false;
112 + $backup = isset($options['back_up_original']) ? filter_var($options['back_up_original'], FILTER_VALIDATE_BOOLEAN) : true;
113 + $exif = isset($options['preserve_exif']) ? filter_var($options['preserve_exif'], FILTER_VALIDATE_BOOLEAN) : false;
114 + $quality = isset($options['image_quality']) ? absint($options['image_quality']) : 92;
105 115
106 116 $options = array(
107 117 'attachment_id' => $image,
108 118 'blog_id' => $blog,
@@ -118,9 +128,9 @@
118 128
119 129 $success = $this->task_manager->compress_single_image($image, $options, $server);
120 130
121 131 if (!$success) {
122 - return new WP_Error('compress_failed', get_post_meta($image, 'smush-info', true));
132 + return new WP_Error('compress_failed', get_post_meta($image, '_wpo-smush-info', true));
123 133 }
124 134
125 135 $response = array();
126 136 $response['status'] = true;
@@ -128,11 +138,11 @@
128 138 $response['options'] = $options;
129 139 $response['server'] = $server;
130 140 $response['success'] = $success;
131 141 $response['restore_possible'] = $backup;
132 - $response['summary'] = get_post_meta($image, 'smush-info', true);
142 + $response['summary'] = get_post_meta($image, '_wpo-smush-info', true);
133 143
134 - $smush_stats = get_post_meta($image, 'smush-stats', true);
144 + $smush_stats = get_post_meta($image, '_wpo-smush-stats', true);
135 145 if (isset($smush_stats['sizes-info'])) {
136 146 $response['sizes-info'] = WP_Optimize()->include_template('images/smush-details.php', true, array('sizes_info' => $smush_stats['sizes-info']));
137 147 }
138 148
@@ -143,15 +153,15 @@
143 153
144 154 /**
145 155 * Restores a single image, if backup is available
146 156 *
147 - * @param mixed $data - Sent in via AJAX
157 + * @param array $data - Sent in via AJAX
148 158 * @return WP_Error|array - information about the operation or a WP_Error object on failure
149 159 */
150 160 public function restore_single_image($data) {
151 161
152 - $blog_id = isset($data['blog_id']) ? $data['blog_id'] : false;
153 - $image_id = isset($data['selected_image']) ? $data['selected_image'] : false;
162 + $blog_id = isset($data['blog_id']) ? absint($data['blog_id']) : 0;
163 + $image_id = isset($data['selected_image']) ? absint($data['selected_image']) : 0;
154 164
155 165 $success = $this->task_manager->restore_single_image($image_id, $blog_id);
156 166
157 167 if (is_wp_error($success)) {
@@ -173,13 +183,13 @@
173 183
174 184 /**
175 185 * Process the compression of multiple images
176 186 *
177 - * @param mixed $data - Sent in via AJAX
187 + * @param array $data - Sent in via AJAX
178 188 * @return array
179 189 */
180 190 public function process_bulk_smush($data = array()) {
181 - $images = isset($data['selected_images']) ? $data['selected_images'] : array();
191 + $images = isset($data['selected_images']) && is_array($data['selected_images']) ? $this->sanitize_images($data['selected_images']) : array();
182 192
183 193 $this->images = $images;
184 194
185 195 $this->background_command = true;
@@ -196,9 +206,9 @@
196 206 *
197 207 * @return void
198 208 */
199 209 public function process_bulk_smush_shutdown() {
200 - WP_Optimize()->close_browser_connection(json_encode($this->final_response));
210 + WP_Optimize()->close_browser_connection(wp_json_encode($this->final_response));
201 211
202 212 $this->task_manager->process_bulk_smush($this->images);
203 213 exit;
204 214 }
@@ -205,13 +215,16 @@
205 215
206 216 /**
207 217 * Returns useful information for the UI and closes the connection
208 218 *
209 - * @param mixed $data - Sent in via AJAX
219 + * @param array $data - Sent in via AJAX
210 220 *
211 221 * @return array - Information for the UI
212 222 */
213 223 public function get_ui_update($data) {
224 + $use_cache = isset($data['use_cache']) ? sanitize_text_field($data['use_cache']) : 'true';
225 + $image_list = isset($data['image_list']) && is_array($data['image_list']) ? $this->sanitize_images($data['image_list']) : false;
226 +
214 227 $ui_update = array();
215 228 $ui_update['status'] = true;
216 229 $ui_update['is_multisite'] = is_multisite() ? 1 : 0;
217 230 $pending_tasks = $this->task_manager->get_pending_tasks();
@@ -216,9 +229,9 @@
216 229 $ui_update['is_multisite'] = is_multisite() ? 1 : 0;
217 230 $pending_tasks = $this->task_manager->get_pending_tasks();
218 231
219 232 $ui_update['pending_tasks'] = is_array($pending_tasks) ? count($this->task_manager->get_pending_tasks()) : 0;
220 - $ui_update['unsmushed_images'] = $this->task_manager->get_uncompressed_images(isset($data['use_cache']) ? $data['use_cache'] : "true");
233 + $ui_update['unsmushed_images'] = $this->task_manager->get_uncompressed_images($use_cache);
221 234 $ui_update['admin_urls'] = $this->task_manager->get_admin_urls();
222 235 $ui_update['completed_task_count'] = $this->task_manager->options->get_option('completed_task_count', 0);
223 236 $ui_update['bytes_saved'] = WP_Optimize()->format_size($this->task_manager->options->get_option('total_bytes_saved', 0));
224 237 $ui_update['percent_saved'] = number_format($this->task_manager->options->get_option('total_percent_saved', 1), 2).'%';
@@ -224,26 +237,31 @@
224 237 $ui_update['percent_saved'] = number_format($this->task_manager->options->get_option('total_percent_saved', 1), 2).'%';
225 238 $ui_update['failed_task_count'] = $this->task_manager->get_failed_task_count();
226 239
227 240 if (is_multisite()) {
228 - $ui_update['summary'] = sprintf(__('Since the last reset of compression statistics on this multisite, a total of %d image(s) were compressed across the network.', 'wp-optimize').' '.__('This saved approximately %s of space at an average of %02d percent per image.', 'wp-optimize'), $ui_update['completed_task_count'], $ui_update['bytes_saved'], $ui_update['percent_saved']);
241 + // translators: %d: number of images compressed, %2$s: size of saved space, %3$02d: average percent saved
242 + $ui_update['summary'] = sprintf(__('Since the last reset of compression statistics on this multisite, a total of %d image(s) were compressed across the network.', 'wp-optimize').' '.__('This saved approximately %2$s of space at an average of %3$02d percent per image.', 'wp-optimize'), $ui_update['completed_task_count'], $ui_update['bytes_saved'], $ui_update['percent_saved']);
229 243 } else {
230 - $ui_update['summary'] = sprintf(__('Since your compression statistics were last reset, a total of %d image(s) were compressed on this site.', 'wp-optimize').' '.__('This saved approximately %s of space at an average of %02d percent per image.', 'wp-optimize'), $ui_update['completed_task_count'], $ui_update['bytes_saved'], $ui_update['percent_saved']);
244 + // translators: %d: number of images compressed, %2$s: size of saved space, %3$02d: average percent saved
245 + $ui_update['summary'] = sprintf(__('Since your compression statistics were last reset, a total of %d image(s) were compressed on this site.', 'wp-optimize').' '.__('This saved approximately %2$s of space at an average of %3$02d percent per image.', 'wp-optimize'), $ui_update['completed_task_count'], $ui_update['bytes_saved'], $ui_update['percent_saved']);
231 246 }
247 + // translators: %d: number of images that could not be compressed
232 248 $ui_update['failed'] = sprintf(__("%d image(s) could not be compressed.", 'wp-optimize'), $ui_update['failed_task_count']) . ' ' . __('Please see the logs for more information, or try again later.', 'wp-optimize');
249 + // translators: %d: number of images that were selected for compression, and pending processing
233 250 $ui_update['pending'] = sprintf(__("%d image(s) images were selected for compressing previously, but were not all processed.", 'wp-optimize'), $ui_update['pending_tasks']) . ' ' . __('You can either complete them now or cancel and retry later.', 'wp-optimize');
234 251 $ui_update['smush_complete'] = $this->task_manager->is_queue_processed();
235 252
236 - if (isset($data['image_list'])) {
237 - $images = $data['image_list'];
238 - $stats = $this->task_manager->get_session_stats($images);
253 + if ($image_list) {
254 + $stats = $this->task_manager->get_session_stats($image_list);
239 255 $ui_update['session_stats'] = "";
240 256
241 257 if (!empty($stats['success'])) {
242 - $ui_update['session_stats'] .= sprintf(__("A total of %d image(s) were successfully compressed in this iteration.", 'wp-optimize'), $stats['success']);
258 + // translators: %d: number of images compressed
259 + $ui_update['session_stats'] .= sprintf(__("A total of %d image(s) were successfully compressed in this iteration.", 'wp-optimize'), $stats['success']);
243 260 }
244 261
245 262 if (!empty($stats['fail'])) {
263 + // translators: %d: number of images that could not be compressed
246 264 $ui_update['session_stats'] .= sprintf(__("%d selected image(s) could not be compressed.", 'wp-optimize'), $stats['fail']) . ' ' . __('Please see the logs for more information, you may try again later.', 'wp-optimize');
247 265 }
248 266 }
249 267
@@ -253,71 +271,21 @@
253 271
254 272 /**
255 273 * Updates webp related options
256 274 *
257 - * @param mixed $data - Sent in via AJAX
275 + * @param array $data - Sent in via AJAX
258 276 * @return WP_Error|array - information about the operation or WP_Error object on failure
259 277 */
260 278 public function update_webp_options($data) {
261 279 $webp_instance = WP_Optimize()->get_webp_instance();
262 - $options = array();
263 - $options['webp_conversion'] = filter_var($data['webp_conversion'], FILTER_VALIDATE_BOOLEAN);
264 -
265 - // Only run checks when trying to enable WebP
266 - if ($options['webp_conversion']) {
267 - //Run checks if we are enabling webp conversion
268 - if (!$webp_instance->shell_functions_available()) {
269 - $webp_instance->disable_webp_conversion();
270 - $webp_instance->log("Required WebP shell functions are not available on the server, disabling WebP conversion");
271 - return new WP_Error('update_failed_no_shell_functions', __('Required WebP shell functions are not available on the server.', 'wp-optimize'));
272 - }
273 -
274 - // Run conversion test if not already done and set necessary option value
275 - if ($webp_instance->should_run_webp_conversion_test()) {
276 - $converter_status = WPO_WebP_Test_Run::get_converter_status();
277 -
278 - if (!$webp_instance->is_webp_conversion_successful()) {
279 - $webp_instance->disable_webp_conversion();
280 - $webp_instance->log("No working WebP converter was found on the server when updating WebP options, disabling WebP conversion");
281 - return new WP_Error('update_failed_no_working_webp_converter', __('No working WebP converter was found on the server.', 'wp-optimize'));
282 - }
283 -
284 - $options['webp_conversion_test'] = true;
285 - $options['webp_converters'] = $converter_status['working_converters'];
286 - }
287 -
288 - // Run serving methods tests and set necessary option values
289 - // Not possible to test alter html since test is browser based
290 - $webp_instance->save_htaccess_rules();
291 - if (!$webp_instance->is_webp_redirection_possible()) {
292 - $webp_instance->empty_htaccess_file();
293 - $options['redirection_possible'] = 'false';
294 - } else {
295 - $options['redirection_possible'] = 'true';
296 - }
280 + $result = $webp_instance->save_webp_settings($data);
281 + if (is_wp_error($result)) {
282 + return $result;
297 283 }
298 284
299 - $success = $this->task_manager->update_smush_options($options);
300 -
301 - if (!$success) {
302 - $webp_instance->disable_webp_conversion();
303 - $webp_instance->log("WebP options could not be updated");
304 - return new WP_Error('update_failed', __('WebP options could not be updated.', 'wp-optimize'));
305 - }
306 -
307 - // Setup daily CRON only when enabling WebP and Delete daily CRON when disabling WebP
308 - if ($options['webp_conversion']) {
309 - $webp_instance->init_webp_cron_scheduler();
310 - } else {
311 - $webp_instance->remove_webp_cron_schedules();
312 - $webp_instance->empty_htaccess_file();
313 - }
314 -
315 - do_action('wpo_save_images_settings');
316 -
317 285 $response = array();
318 286 $response['status'] = true;
319 - $response['saved'] = $success;
287 + $response['saved'] = $result;
320 288 $response['summary'] = __('WebP options updated successfully.', 'wp-optimize');
321 289
322 290 return $response;
323 291 }
@@ -324,22 +292,22 @@
324 292
325 293 /**
326 294 * Updates smush related options
327 295 *
328 - * @param mixed $data - Sent in via AJAX
296 + * @param array $data - Sent in via AJAX
329 297 * @return WP_Error|array - information about the operation or WP_Error object on failure
330 298 */
331 299 public function update_smush_options($data) {
332 300 $options = array();
333 - $options['compression_server'] = sanitize_text_field($data['compression_server']);
334 - $options['lossy_compression'] = filter_var($data['lossy_compression'], FILTER_VALIDATE_BOOLEAN) ? true : false;
335 - $options['back_up_original'] = filter_var($data['back_up_original'], FILTER_VALIDATE_BOOLEAN) ? true : false;
336 - $options['back_up_delete_after'] = filter_var($data['back_up_delete_after'], FILTER_VALIDATE_BOOLEAN) ? true : false;
337 - $options['back_up_delete_after_days'] = filter_var($data['back_up_delete_after_days'], FILTER_SANITIZE_NUMBER_INT);
338 - $options['preserve_exif'] = filter_var($data['preserve_exif'], FILTER_VALIDATE_BOOLEAN) ? true : false;
339 - $options['autosmush'] = filter_var($data['autosmush'], FILTER_VALIDATE_BOOLEAN) ? true : false;
340 - $options['image_quality'] = filter_var($data['image_quality'], FILTER_SANITIZE_NUMBER_INT);
341 - $options['show_smush_metabox'] = filter_var($data['show_smush_metabox'], FILTER_VALIDATE_BOOLEAN) ? 'show' : 'hide';
301 + $options['compression_server'] = isset($data['compression_server']) ? sanitize_text_field($data['compression_server']) : $this->task_manager->get_default_webservice();
302 + $options['lossy_compression'] = isset($data['lossy_compression']) ? filter_var($data['lossy_compression'], FILTER_VALIDATE_BOOLEAN) : false;
303 + $options['back_up_original'] = isset($data['back_up_original']) ? filter_var($data['back_up_original'], FILTER_VALIDATE_BOOLEAN) : true;
304 + $options['back_up_delete_after'] = isset($data['back_up_delete_after']) ? filter_var($data['back_up_delete_after'], FILTER_VALIDATE_BOOLEAN) : true;
305 + $options['back_up_delete_after_days'] = isset($data['back_up_delete_after_days']) ? absint($data['back_up_delete_after_days']) : 50;
306 + $options['preserve_exif'] = isset($data['preserve_exif']) ? filter_var($data['preserve_exif'], FILTER_VALIDATE_BOOLEAN) : false;
307 + $options['autosmush'] = isset($data['autosmush']) ? filter_var($data['autosmush'], FILTER_VALIDATE_BOOLEAN) : false;
308 + $options['image_quality'] = isset($data['image_quality']) ? absint($data['image_quality']) : 92;
309 + $options['show_smush_metabox'] = isset($data['show_smush_metabox']) && filter_var($data['show_smush_metabox'], FILTER_VALIDATE_BOOLEAN) ? 'show' : 'hide';
342 310
343 311 $success = $this->task_manager->update_smush_options($options);
344 312
345 313 if (!$success) {
@@ -378,12 +346,14 @@
378 346
379 347 /**
380 348 * Checks if the selected server is online
381 349 *
382 - * @param mixed $data - Sent in via AJAX
350 + * @param array $data - Sent in via AJAX
351 + *
352 + * @return array
383 353 */
384 354 public function check_server_status($data) {
385 - $server = sanitize_text_field($data['server']);
355 + $server = isset($data['server']) ? sanitize_text_field($data['server']) : $this->task_manager->get_default_webservice();
386 356 $response = array();
387 357 $response['status'] = true;
388 358 $response['online'] = $this->task_manager->check_server_online($server);
389 359
@@ -410,10 +380,11 @@
410 380 * @return WP_Error|array - information about the operation or WP_Error object on failure
411 381 */
412 382 public function clear_pending_images($data) {
413 383
414 - if (!empty($data['restore_images'])) {
415 - foreach ($data['restore_images'] as $image) {
384 + if (!empty($data['restore_images']) && is_array($data['restore_images'])) {
385 + $restore_images = $this->sanitize_images($data['restore_images']);
386 + foreach ($restore_images as $image) {
416 387 $this->task_manager->restore_single_image($image['attachment_id'], $image['blog_id']);
417 388 }
418 389 }
419 390
@@ -440,10 +411,11 @@
440 411 $response = array();
441 412 $selected_images = array();
442 413
443 414 $unmark = isset($data['unmark']) && $data['unmark'];
415 + $image_list = isset($data['selected_images']) && is_array($data['selected_images']) ? $this->sanitize_images($data['selected_images']) : array();
444 416
445 - foreach ($data['selected_images'] as $image) {
417 + foreach ($image_list as $image) {
446 418 if (!array_key_exists($image['blog_id'], $selected_images)) $selected_images[$image['blog_id']] = array();
447 419
448 420 $selected_images[$image['blog_id']][] = $image['attachment_id'];
449 421 }
@@ -454,15 +426,15 @@
454 426 if (is_multisite()) switch_to_blog($blog_id);
455 427
456 428 foreach ($selected_images[$blog_id] as $attachment_id) {
457 429 if ($unmark) {
458 - delete_post_meta($attachment_id, 'smush-complete');
459 - delete_post_meta($attachment_id, 'smush-marked');
460 - delete_post_meta($attachment_id, 'smush-info');
430 + delete_post_meta($attachment_id, '_wpo-smush-complete');
431 + delete_post_meta($attachment_id, '_wpo-smush-marked');
432 + delete_post_meta($attachment_id, '_wpo-smush-info');
461 433 } else {
462 - update_post_meta($attachment_id, 'smush-complete', true);
463 - update_post_meta($attachment_id, 'smush-marked', true);
464 - update_post_meta($attachment_id, 'smush-info', $info);
434 + update_post_meta($attachment_id, '_wpo-smush-complete', true);
435 + update_post_meta($attachment_id, '_wpo-smush-marked', true);
436 + update_post_meta($attachment_id, '_wpo-smush-info', $info);
465 437 }
466 438 }
467 439
468 440 if (is_multisite()) restore_current_blog();
@@ -470,17 +442,17 @@
470 442
471 443 $response['status'] = true;
472 444
473 445 if ($unmark) {
474 - $response['summary'] = _n('The selected image was successfully marked as uncompressed', 'The selected images were successfully marked as uncompressed', count($data['selected_images']), 'wp-optimize');
446 + $response['summary'] = _n('The selected image was successfully marked as uncompressed', 'The selected images were successfully marked as uncompressed', count($image_list), 'wp-optimize');
475 447 } else {
476 - $response['summary'] = _n('The selected image was successfully marked as compressed', 'The selected images were successfully marked as compressed', count($data['selected_images']), 'wp-optimize');
448 + $response['summary'] = _n('The selected image was successfully marked as compressed', 'The selected images were successfully marked as compressed', count($image_list), 'wp-optimize');
477 449 }
478 450
479 451 $response['info'] = $info;
480 452
481 - if (1 === count($data['selected_images'])) {
482 - $selected_image = reset($data['selected_images']);
453 + if (1 === count($image_list)) {
454 + $selected_image = reset($image_list);
483 455 $response['media_column_html'] = $this->get_smush_media_column_content($selected_image['blog_id'], $selected_image['attachment_id']);
484 456 }
485 457
486 458 return $response;
@@ -533,8 +505,9 @@
533 505 } else {
534 506 if ($delete_only_backups_meta) {
535 507 if ($smushed_images_total > 0) {
536 508 $response['message'] = __('All the compressed images with backup copies of their original files were successfully restored.', 'wp-optimize');
509 + // translators: %s - number of smushed images
537 510 $response['message'] .= ' '.sprintf(_n('Unable to restore %s image without backup files.', 'Unable to restore %s images without backup files.', $smushed_images_total, 'wp-optimize'), $smushed_images_total);
538 511 } else {
539 512 $response['message'] = __('All the compressed images were successfully restored.', 'wp-optimize');
540 513 }
@@ -559,9 +532,9 @@
559 532
560 533 /**
561 534 * Returns the log file
562 535 *
563 - * @return WP_Error|file - logfile or WP_Error object on failure
536 + * @return void|WP_Error - logfile or WP_Error object on failure
564 537 */
565 538 public function get_smush_logs() {
566 539
567 540 $logfile = $this->task_manager->get_logfile_path();
@@ -572,9 +545,9 @@
572 545
573 546 if (is_file($logfile)) {
574 547 if ($this->heartbeat_command) {
575 548 // The response will be inside the heartbeat response envelope, as each response of a heartbeat goes in its own unique ID key
576 - readfile($logfile);
549 + readfile($logfile); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile -- Using WP_Filesystem and get contents will result in `echo` and unescaped error
577 550 } else {
578 551 // Headers are needed for the `Download logs` link, which will run this command and just prompt a file download
579 552 header('Content-Description: File Transfer');
580 553 header('Content-Type: application/octet-stream');
@@ -582,9 +555,9 @@
582 555 header('Expires: 0');
583 556 header('Cache-Control: must-revalidate');
584 557 header('Pragma: public');
585 558 header('Content-Length: ' . filesize($logfile));
586 - readfile($logfile);
559 + readfile($logfile); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile -- Using WP_Filesystem and get contents will result in `echo` and unescaped error
587 560 exit;
588 561 }
589 562 } else {
590 563 return new WP_Error('log_file_error', __('Log file does not exist or could not be read', 'wp-optimize'));
@@ -614,14 +587,10 @@
614 587 */
615 588 public function reset_webp_serving_method() {
616 589 $webp_instance = WP_Optimize()->get_webp_instance();
617 590 //Run checks before calling reset_webp_serving_method
618 - if (!$webp_instance->shell_functions_available()) {
591 + if (!$webp_instance->is_webp_conversion_enabled()) {
619 592 $webp_instance->disable_webp_conversion();
620 - $webp_instance->log("The WebP serving method cannot be reset because required WebP shell functions are not available on the server");
621 - return new WP_Error('reset_failed_no_shell_functions', __('The WebP serving method cannot be reset because required WebP shell functions are not available on the server', 'wp-optimize'));
622 - } elseif (!$webp_instance->is_webp_conversion_enabled()) {
623 - $webp_instance->disable_webp_conversion();
624 593 $webp_instance->log("The WebP serving method cannot be reset because WebP conversion is currently disabled");
625 594 return new WP_Error('reset_failed_webp_conversion_disabled', __('The WebP serving method cannot be reset because WebP conversion is currently disabled', 'wp-optimize'));
626 595 }
627 596
@@ -637,9 +606,9 @@
637 606 * @param array $data
638 607 * @return array
639 608 */
640 609 public function convert_to_webp_format($data) {
641 - $attachment_id = isset($data['attachment_id']) ? $data['attachment_id'] : 0;
610 + $attachment_id = isset($data['attachment_id']) ? absint($data['attachment_id']) : 0;
642 611 if (0 === $attachment_id) return $this->image_not_found_response();
643 612
644 613 $images = WPO_Image_Utils::get_attachment_files($attachment_id);
645 614 if (empty($images)) return $this->image_not_found_response();
@@ -645,9 +614,11 @@
645 614 if (empty($images)) return $this->image_not_found_response();
646 615
647 616 $images['original'] = get_attached_file($attachment_id);
648 617 foreach ($images as $image) {
649 - WPO_WebP_Utils::do_webp_conversion($image);
618 + if (!is_file($image.'.webp')) {
619 + WPO_WebP_Utils::do_webp_conversion($image);
620 + }
650 621 }
651 622
652 623 return array(
653 624 'success' => __('Image is converted to WebP format.', 'wp-optimize'),
@@ -660,12 +631,12 @@
660 631 * @param array $data
661 632 * @return array
662 633 */
663 634 public function get_smush_settings_form($data) {
664 - $attachment_id = isset($data['attachment_id']) ? $data['attachment_id'] : 0;
635 + $attachment_id = isset($data['attachment_id']) ? absint($data['attachment_id']) : 0;
665 636 if (0 === $attachment_id) return $this->image_not_found_response();
666 637
667 - $compressed = get_post_meta($attachment_id, 'smush-complete', true) ? true : false;
638 + $compressed = (bool) get_post_meta($attachment_id, '_wpo-smush-complete', true);
668 639
669 640 $smush_options = Updraft_Smush_Manager()->get_smush_options();
670 641
671 642 $extract = array(
@@ -683,10 +654,10 @@
683 654
684 655 /**
685 656 * Get content for Media Library column content
686 657 *
687 - * @param {int} $blog_id
688 - * @param {int} $attachment_id
658 + * @param int $blog_id
659 + * @param int $attachment_id
689 660 *
690 661 * @return string
691 662 */
692 663 private function get_smush_media_column_content($blog_id, $attachment_id) {
@@ -717,9 +688,9 @@
717 688 *
718 689 * @return array
719 690 */
720 691 public function get_smush_details($data) {
721 - $selected_images = isset($data['selected_images']) ? $data['selected_images'] : array();
692 + $selected_images = isset( $data['selected_images'] ) && is_array( $data['selected_images'] ) ? array_map( 'absint', $data['selected_images'] ) : array();
722 693 $smush_details = array();
723 694 foreach ($selected_images as $attachment_id) {
724 695 $smush_details[$attachment_id] = $this->task_manager->get_smush_details($attachment_id);
725 696 }
@@ -727,8 +698,35 @@
727 698 return array(
728 699 'success' => true,
729 700 'smush_details' => $smush_details,
730 701 );
702 + }
703 +
704 + /**
705 + * Sanitize array of images ensuring proper integer values for attachment_id and blog_id
706 + *
707 + * @param array $images Array of image data to sanitize
708 + * @return array
709 + */
710 + private function sanitize_images($images) {
711 + $result = array();
712 +
713 + foreach ($images as $image) {
714 + $attachment_id = isset($image['attachment_id']) ? absint($image['attachment_id']) : 0;
715 + $blog_id = isset($image['blog_id']) ? absint($image['blog_id']) : 0;
716 +
717 + // Skip entries where either value is zero
718 + if (0 === $attachment_id || 0 === $blog_id) {
719 + continue;
720 + }
721 +
722 + $result[] = array(
723 + 'attachment_id' => $attachment_id,
724 + 'blog_id' => $blog_id,
725 + );
726 + }
727 +
728 + return $result;
731 729 }
732 730 }
733 731
734 732 endif;