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-task.php +90 -111 3.2.3 → 4.7.0 View file →
@@ -11,9 +11,9 @@
11 11
12 12 abstract class Updraft_Smush_Task extends Updraft_Task_1_2 {
13 13
14 14 /**
15 - * A flag indicating if the operation was succesful
15 + * A flag indicating if the operation was successful
16 16 *
17 17 * @var bool
18 18 */
19 19 protected $success = false;
@@ -27,9 +27,9 @@
27 27
28 28 /**
29 29 * Initialise the task
30 30 *
31 - * @param Array $options - options to use
31 + * @param array $options - options to use
32 32 */
33 33 public function initialise($options = array()) {
34 34 parent::initialise($options);
35 35 $this->set_current_stage('initialised');
@@ -61,9 +61,9 @@
61 61
62 62 $api_endpoint = $this->get_option('api_endpoint');
63 63
64 64 if (false === filter_var($api_endpoint, FILTER_VALIDATE_URL)) {
65 - $this->fail('invalid_api_url', "The API endpoint supplied {$api_endpoint} is invalid");
65 + $this->fail('invalid_api_url', "The API endpoint supplied $api_endpoint is invalid");
66 66 return false;
67 67 }
68 68
69 69 $original_image = $file_path;
@@ -74,11 +74,26 @@
74 74
75 75 $this->update_option('original_filesize', filesize($file_path));
76 76
77 77 // build list of files for smush.
78 - $files = array_merge(array('full' => $file_path), $this->get_attachment_files($attachment_id));
78 + if (is_multisite()) {
79 + switch_to_blog($this->get_option('blog_id', 1));
80 + $files = array_merge(array('full' => $file_path), WPO_Image_Utils::get_attachment_files($attachment_id));
81 + restore_current_blog();
82 + } else {
83 + $files = array_merge(array('full' => $file_path), WPO_Image_Utils::get_attachment_files($attachment_id));
84 + }
79 85
80 86 $sizes_info = array();
87 + $webp_tools_available = true;
88 + $lossy = $this->get_option('lossy_compression');
89 + if ($lossy) {
90 + $quality = $this->get_option('image_quality');
91 + } else {
92 + $quality = 92;
93 + }
94 + $this->log($this->get_description());
95 + $this->log("File: " . basename($file_path) . ", Compression quality: $quality");
81 96
82 97 foreach ($files as $size => $file_path) {
83 98
84 99 if (in_array($size, $dont_smush_sizes)) continue;
@@ -88,17 +103,23 @@
88 103 if ($file_size > 5242880) {
89 104 $this->update_option('request_timeout', 180);
90 105 }
91 106
92 - $this->log($this->get_description());
107 + $ext = WPO_Image_Utils::get_extension($file_path);
108 + $allowed_extensions = WPO_Image_Utils::get_allowed_extensions();
109 + $allowed_extensions = array_diff($allowed_extensions, array('gif'));
110 + if (WPO_WebP_Utils::can_do_webp_conversion()) {
111 + if (WPO_Image_Utils::is_supported_extension($ext, $allowed_extensions)) {
112 + WPO_WebP_Utils::do_webp_conversion($file_path);
113 + }
114 + } else {
115 + $webp_tools_available = false;
116 + }
93 117
94 - if (defined('WPO_USE_WEBP_CONVERSION') && true === WPO_USE_WEBP_CONVERSION) {
95 - $this->maybe_do_webp_conversion($file_path);
96 - }
97 -
118 +
98 119 /**
99 120 * Filters the options for a single image to compress.
100 - * Currently supports:
121 + * Currently, supports:
101 122 * - 'quality': Will use the image quality set in this filter, instead of the one defined in the settings.
102 123 *
103 124 * @param array $options - The options (default: empty array)
104 125 * @param integer $attachment_id - The attachment post ID
@@ -112,9 +133,9 @@
112 133 $response = $this->post_to_remote_server($api_endpoint, $post_data);
113 134 $optimised_image = $this->process_server_response($response);
114 135
115 136 if ($optimised_image) {
116 - $backup_image = ($original_image == $file_path) ? $backup_original_image : false;
137 + $backup_image = ($original_image === $file_path) ? $backup_original_image : false;
117 138 $this->save_optimised_image($file_path, $optimised_image, $backup_image);
118 139
119 140 clearstatcache($file_path);
120 141
@@ -127,33 +148,32 @@
127 148 }
128 149
129 150 $this->update_option('smush-sizes-info', $sizes_info);
130 151
131 - return $this->success;
132 - }
152 + if (!$webp_tools_available) {
153 + $this->log('There were no WebP conversion tools found on your server.');
154 + }
133 155
134 - /**
135 - * Converts to WebP format, if possible
136 - *
137 - * @param string $source Source image file path
138 - */
139 - public function maybe_do_webp_conversion($source) {
140 - $webp_conversion = WP_Optimize()->get_options()->get_option('webp_conversion', false);
141 - if (!empty($webp_conversion)) {
142 - if (!class_exists('WPO_WebP_Convert')) include_once(WPO_PLUGIN_MAIN_PATH . 'webp/class-wpo-webp-convert.php');
143 - $webp_converter = new WPO_WebP_Convert();
144 - $webp_converter->convert($source);
145 - } else {
146 - $this->log('There were no WebP conversion tools found on your server.');
156 + $destination = WPO_WebP_Utils::get_destination_path($file_path);
157 + if ($webp_tools_available && file_exists($destination)) {
158 + if (is_multisite()) {
159 + switch_to_blog($this->get_option('blog_id', 1));
160 + update_post_meta($attachment_id, WPO_Webp_Convert_Image_Task::WEBP_CONVERSION_META_KEY, true);
161 + restore_current_blog();
162 + } else {
163 + update_post_meta($attachment_id, WPO_Webp_Convert_Image_Task::WEBP_CONVERSION_META_KEY, true);
164 + }
147 165 }
166 +
167 + return $this->success;
148 168 }
149 169
150 170 /**
151 171 * Posts the supplied data to the API url and returns a response
152 172 *
153 - * @param String $api_endpoint - the url to post the form to
154 - * @param String $post_data - the post data as specified by the server
155 - * @return mixed - the response
173 + * @param string $api_endpoint - the url to post the form to
174 + * @param array $post_data - the post data as specified by the server
175 + * @return array|false|WP_Error - the response
156 176 */
157 177 public function post_to_remote_server($api_endpoint, $post_data) {
158 178
159 179 $this->set_current_stage('connecting');
@@ -167,9 +187,9 @@
167 187 return $response;
168 188 }
169 189
170 190 /**
171 - * Processes the response recieved from the remote server
191 + * Processes the response received from the remote server
172 192 *
173 193 * @param mixed $response - the response object
174 194 * @return mixed - the response
175 195 */
@@ -180,9 +200,9 @@
180 200
181 201 /**
182 202 * Checks if a file is valid and capable of being smushed
183 203 *
184 - * @param String $file_path - the path of the original image
204 + * @param string $file_path - the path of the original image
185 205 * @return bool - true on success, false otherwise
186 206 */
187 207 public function validate_file($file_path) {
188 208
@@ -208,9 +228,9 @@
208 228
209 229 /**
210 230 * Creates a backup of the original image
211 231 *
212 - * @param String $file_path - the path of the original image
232 + * @param string $file_path - the path of the original image
213 233 * @return bool - true on success, false otherwise
214 234 */
215 235 public function backup_original_image($file_path) {
216 236
@@ -226,15 +246,15 @@
226 246
227 247 // Make path relative and safe for migrations
228 248 $back_up_relative_path = preg_replace('#^'.wp_normalize_path($uploads_dir['basedir'].'/').'#', '', $back_up);
229 249
230 - update_post_meta($this->get_option('attachment_id'), 'original-file', $back_up_relative_path);
250 + update_post_meta($this->get_option('attachment_id'), '_wpo-original-file', $back_up_relative_path);
231 251
232 252 if (is_multisite()) {
233 253 restore_current_blog();
234 254 }
235 255
236 - $this->log("Backing up the original image - {$back_up_relative_path}");
256 + $this->log("Backing up the original image - $back_up_relative_path");
237 257
238 258 return copy($file_path, $back_up);
239 259 }
240 260
@@ -240,10 +260,10 @@
240 260
241 261 /**
242 262 * Creates a backup of the original image
243 263 *
244 - * @param String $file_path - the path of the original image
245 - * @param Mixes $optimised_image - the contents of the image
264 + * @param string $file_path - the path of the original image
265 + * @param mixed $optimised_image - the contents of the image
246 266 * @param bool $backup_original - backup original image
247 267 *
248 268 * @return bool - true on success, false otherwise
249 269 */
@@ -263,9 +283,9 @@
263 283 return $this->success;
264 284 }
265 285
266 286 /**
267 - * Fires if the task succeds, any clean up code and logging goes here
287 + * Fires if the task succeeds, any clean up code and logging goes here
268 288 */
269 289 public function complete() {
270 290
271 291 $attachment_id = $this->get_option('attachment_id');
@@ -277,18 +297,20 @@
277 297 } else {
278 298 $file_path = get_attached_file($attachment_id);
279 299 }
280 300
281 - $original_size = $this->get_option('original_filesize');
301 + $original_size = (int) $this->get_option('original_filesize');
282 302 $this->set_current_stage('completed');
283 303
284 - clearstatcache(true, $file_path); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctionParameters.clearstatcache_clear_realpath_cacheFound,PHPCompatibility.FunctionUse.NewFunctionParameters.clearstatcache_filenameFound
285 - if (0 == $original_size) {
304 + clearstatcache(true, $file_path);
305 + if (0 === $original_size) {
286 306 $saved = '';
307 + // translators: %s is a file size
287 308 $info = sprintf(__("The file was compressed to %s using WP-Optimize", 'wp-optimize'), WP_Optimize()->format_size(filesize($file_path)));
288 309 } else {
289 310 $saved = round((($original_size - filesize($file_path)) / $original_size * 100), 2);
290 - $info = sprintf(__("The file was compressed from %s to %s saving %s percent using WP-Optimize", 'wp-optimize'), WP_Optimize()->format_size($original_size), WP_Optimize()->format_size(filesize($file_path)), $saved);
311 + // translators: %1$s is a file size, %2$s is a file size, %3$s is a percentage
312 + $info = sprintf(__('The file was compressed from %1$s to %2$s, saving %3$s percent, using WP-Optimize', 'wp-optimize'), WP_Optimize()->format_size($original_size), WP_Optimize()->format_size(filesize($file_path)), $saved);
291 313 }
292 314
293 315 $stats = array(
294 316 'smushed-with' => $this->label,
@@ -299,19 +321,19 @@
299 321 );
300 322
301 323 if (is_multisite()) {
302 324 switch_to_blog($this->get_option('blog_id', 1));
303 - update_post_meta($attachment_id, 'smush-complete', true);
304 - update_post_meta($attachment_id, 'smush-info', $info);
305 - update_post_meta($attachment_id, 'smush-stats', $stats);
325 + update_post_meta($attachment_id, '_wpo-smush-complete', true);
326 + update_post_meta($attachment_id, '_wpo-smush-info', $info);
327 + update_post_meta($attachment_id, '_wpo-smush-stats', $stats);
306 328 restore_current_blog();
307 329 } else {
308 - update_post_meta($attachment_id, 'smush-complete', true);
309 - update_post_meta($attachment_id, 'smush-info', $info);
310 - update_post_meta($attachment_id, 'smush-stats', $stats);
330 + update_post_meta($attachment_id, '_wpo-smush-complete', true);
331 + update_post_meta($attachment_id, '_wpo-smush-info', $info);
332 + update_post_meta($attachment_id, '_wpo-smush-stats', $stats);
311 333 }
312 334
313 - $this->log("Successfully optimized the image - {$file_path}." . $info);
335 + $this->log("Successfully optimized the image - $file_path." . $info);
314 336 $this->set_status('complete');
315 337
316 338 return parent::complete();
317 339 }
@@ -318,25 +340,26 @@
318 340
319 341 /**
320 342 * Fires if the task fails, any clean up code and logging goes here
321 343 *
322 - * @param String $error_code - A code for the failure
323 - * @param String $error_message - A description for the failure
344 + * @param string $error_code - A code for the failure
345 + * @param string $error_message - A description for the failure
324 346 */
325 347 public function fail($error_code = "Unknown", $error_message = "Unknown") {
326 348
327 349 $attachment_id = $this->get_option('attachment_id');
328 350
329 - $info = sprintf(__("Failed with error code %s - %s", 'wp-optimize'), $error_code, $error_message);
351 + // translators: %1$s is the error code, %2$s is the error message
352 + $info = sprintf(__('Failed with error code %1$s - %2$s', 'wp-optimize'), $error_code, $error_message);
330 353
331 354 if (is_multisite()) {
332 355 switch_to_blog($this->get_option('blog_id', 1));
333 - update_post_meta($attachment_id, 'smush-info', $info);
334 - update_post_meta($attachment_id, 'smush-complete', false);
356 + update_post_meta($attachment_id, '_wpo-smush-info', $info);
357 + update_post_meta($attachment_id, '_wpo-smush-complete', false);
335 358 restore_current_blog();
336 359 } else {
337 - update_post_meta($attachment_id, 'smush-info', $info);
338 - update_post_meta($attachment_id, 'smush-complete', false);
360 + update_post_meta($attachment_id, '_wpo-smush-info', $info);
361 + update_post_meta($attachment_id, '_wpo-smush-complete', false);
339 362 }
340 363
341 364
342 365 do_action('ud_smush_task_failed', $this, $error_code, $error_message);
@@ -359,36 +382,25 @@
359 382 'saving_image' => __('Saving optimized image', 'wp-optimize'),
360 383 'completed' => __('Successful', 'wp-optimize'),
361 384 );
362 385
363 - return apply_filters('allowed_task_stages', $stages);
386 + $filtered_stages = apply_filters('allowed_task_stages', $stages);
387 + if (!empty($filtered_stages) && is_array($filtered_stages)) return $filtered_stages;
388 + return $stages;
364 389 }
365 390
366 391 /**
367 - * Get features available with this service
368 - *
369 - * @return Array - an array of features
370 - */
371 - public static function get_features() {
372 - return array(
373 - 'max_filesize' => self::MAX_FILESIZE,
374 - 'lossy_compression' => true,
375 - 'preserve_exif' => true,
376 - );
377 - }
378 -
379 - /**
380 392 * Retrieve default options for this task.
381 393 * This method should normally be over-ridden by the child.
382 394 *
383 - * @return Array - an array of options
395 + * @return array - an array of options
384 396 */
385 397 public function get_default_options() {
386 398
387 399 return array(
388 - 'allowed_file_types' => array('gif', 'png', 'jpg', 'tif', 'jpeg'),
400 + 'allowed_file_types' => WPO_Image_Utils::get_allowed_extensions(),
389 401 'request_timeout' => 15,
390 - 'image_quality' => 90,
402 + 'image_quality' => 92,
391 403 'backup_prefix' => '-updraft-pre-smush-original.'
392 404 );
393 405 }
394 406
@@ -394,9 +406,9 @@
394 406
395 407 /**
396 408 * Sets the task stage.
397 409 *
398 - * @param String $stage - the current stage of the task
410 + * @param string $stage - the current stage of the task
399 411 * @return bool - the result of the update
400 412 */
401 413 public function set_current_stage($stage) {
402 414
@@ -401,9 +413,9 @@
401 413 public function set_current_stage($stage) {
402 414
403 415 if (array_key_exists($stage, self::get_allowed_stages())) {
404 416 $this->stage = $stage;
405 - return $this->update_option('current_stage', $this->stage);
417 + return (bool) $this->update_option('current_stage', $this->stage);
406 418 }
407 419
408 420 return false;
409 421 }
@@ -410,50 +422,17 @@
410 422
411 423 /**
412 424 * Gets the task stage
413 425 *
414 - * @return String $stage - the current stage of the task
426 + * @return string $stage - the current stage of the task
415 427 */
416 428 public function get_current_stage() {
417 - if (isset($this->stage))
418 - return $this->stage;
419 - else return $this->get_option('current_stage');
429 + return $this->stage ?? $this->get_option('current_stage');
420 430 }
421 431
422 432 /**
423 - * Get image paths to resized attachment images.
433 + * Check the mime type of downloaded file, returns true if it is a valid image mime type.
424 434 *
425 - * @param int $attachment_id
426 - * @return array
427 - */
428 - private function get_attachment_files($attachment_id) {
429 - $attachment_images = array();
430 - $upload_dir = function_exists('wp_get_upload_dir') ? wp_get_upload_dir() : wp_upload_dir(null, false);
431 -
432 - // get sizes info from attachment meta data.
433 - $meta = wp_get_attachment_metadata($attachment_id);
434 - if (!is_array($meta) || !array_key_exists('sizes', $meta)) return $attachment_images;
435 -
436 - $image_sizes = array_keys($meta['sizes']);
437 -
438 - // build list of resized images.
439 - foreach ($image_sizes as $size) {
440 - $image = image_get_intermediate_size($attachment_id, $size);
441 -
442 - if (is_array($image)) {
443 - $file = trailingslashit($upload_dir['basedir']) . $image['path'];
444 - if (is_file($file) && !in_array($file, $attachment_images)) {
445 - $attachment_images[$size] = $file;
446 - }
447 - }
448 - }
449 -
450 - return $attachment_images;
451 - }
452 -
453 - /**
454 - * Check the mime type of a downloaded file, returns true if it is a valid image mime type.
455 - *
456 435 * @param string $file_buffer The buffer string downloaded from the compression service
457 436 * @return boolean
458 437 */
459 438 protected function is_downloaded_image_buffer_mime_type_valid($file_buffer) {
@@ -460,9 +439,9 @@
460 439 // If the required class does not exist, return true to avoid breaking the functionality
461 440 if (!class_exists('finfo')) return true;
462 441 $accepted_types = apply_filters('wpo_image_compression_accepted_mime_types', array('image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/webp'));
463 442 // The ignore rule below is added because "finfo" doesn't exist in PHP5.2.
464 - $finfo = new finfo(FILEINFO_MIME_TYPE); // phpcs:ignore PHPCompatibility.Classes.NewClasses.finfoFound, PHPCompatibility.Constants.NewConstants.fileinfo_mime_typeFound
443 + $finfo = new finfo(FILEINFO_MIME_TYPE);
465 444 $mime_type = $finfo->buffer($file_buffer);
466 445 return in_array($mime_type, $accepted_types);
467 446 }
468 447 }