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