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 | webp/class-wp-optimize-webp.php +135 -81 4.5.2 → 4.7.0 View file →
@@ -5,9 +5,12 @@
5 5 if (!class_exists('WP_Optimize_WebP')) :
6 6
7 7 class WP_Optimize_WebP {
8 8
9 - private $_htaccess = null;
9 + /**
10 + * @var WP_Optimize_Htaccess
11 + */
12 + private $_htaccess;
10 13
11 14 /**
12 15 * Set to true when webp is enabled and vice versa
13 16 *
@@ -17,9 +20,9 @@
17 20
18 21 /**
19 22 * The logger for this instance
20 23 *
21 - * @var mixed
24 + * @var Updraft_File_Logger
22 25 */
23 26 private $logger;
24 27
25 28 /**
@@ -38,14 +41,14 @@
38 41
39 42 /**
40 43 * Returns singleton instance
41 44 *
42 - * @return WP_Optimize_WebP
45 + * @return self
43 46 */
44 - public static function get_instance() {
47 + public static function get_instance(): self {
45 48 static $instance = null;
46 49 if (null === $instance) {
47 - $instance = new WP_Optimize_WebP();
50 + $instance = new self();
48 51 }
49 52 return $instance;
50 53 }
51 54
@@ -51,9 +54,9 @@
51 54
52 55 /**
53 56 * Evaluate WebP conversion capability.
54 57 *
55 - * @return array
58 + * @return array{is_available: bool, reason: string, message: string, converter_status: array<string, array<string>>, test_ran: bool}
56 59 */
57 60 public function evaluate_webp_capability(): array {
58 61 $converter_status = array();
59 62 $test_ran = false;
@@ -92,9 +95,9 @@
92 95
93 96 /**
94 97 * Try to enable webp conversion, upon failure disable webp conversion
95 98 *
96 - * @param array $data - Data webp_conversion (true|false)
99 + * @param array<string, string> $data - Data webp_conversion (true|false)
97 100 * @return WP_Error|bool - information about the operation or WP_Error object on failure
98 101 */
99 102 private function configure_webp_conversion($data) {
100 103
@@ -105,10 +108,12 @@
105 108 $capability = $this->evaluate_webp_capability();
106 109
107 110 if (!$capability['is_available']) {
108 111 $this->disable_webp_conversion();
109 - $this->log($capability['message']);
110 - return new WP_Error($capability['reason'], $capability['message']);
112 + $message = $capability['message'];
113 + $reason = $capability['reason'];
114 + $this->log($message);
115 + return new WP_Error($reason, $message);
111 116 }
112 117
113 118 // Only update the test result and converters if the test actually ran
114 119 if ($capability['test_ran']) {
@@ -148,9 +153,9 @@
148 153
149 154 /**
150 155 * Save WebP settings and trigger related actions.
151 156 *
152 - * @param array $data WebP settings (expects 'webp_conversion').
157 + * @param array<string, string> $data WebP settings (expects 'webp_conversion').
153 158 * @return bool|WP_Error True on success, WP_Error on failure.
154 159 */
155 160 public function save_webp_settings($data) {
156 161
@@ -171,26 +176,30 @@
171 176 * Returns the path to the logfile
172 177 *
173 178 * @return string - file path
174 179 */
175 - private function get_logfile_path() {
180 + private function get_logfile_path(): string {
176 181 return WP_Optimize_Utils::get_log_file_path('webp');
177 182 }
178 183
179 184 /**
180 - * Logging of interesting messages related to Webp
185 + * Logging of interesting messages related to WebP.
181 186 *
182 - * @param string $message
183 - * @param string $level
187 + * @param string $message Log message
188 + * @param string $level Log level (e.g., 'info', 'warning', 'error')
189 + *
190 + * @return void
184 191 */
185 - public function log(string $message, string $level = 'info') {
192 + public function log(string $message, string $level = 'info'): void {
186 193 $this->logger->log($message, $level);
187 194 }
188 195
189 196 /**
190 197 * Prunes the log file
198 + *
199 + * @return void
191 200 */
192 - public function prune_webp_logs() {
201 + public function prune_webp_logs(): void {
193 202 $this->log("Pruning the WebP log file");
194 203 $this->logger->prune_logs();
195 204 }
196 205
@@ -195,10 +204,12 @@
195 204 }
196 205
197 206 /**
198 207 * Test Run and find converter status
208 + *
209 + * @return void
199 210 */
200 - private function set_converter_status() {
211 + private function set_converter_status(): void {
201 212 $converter_status = WPO_WebP_Test_Run::get_converter_status();
202 213 if ($this->is_webp_conversion_successful()) {
203 214 WP_Optimize()->get_options()->update_option('webp_conversion_test', true);
204 215 WP_Optimize()->get_options()->update_option('webp_converters', $converter_status['working_converters']);
@@ -205,9 +216,9 @@
205 216 }
206 217 }
207 218
208 219 /**
209 - * If .htaccess redirection is not possible, attempts to use the alter_html method
220 + * If .htaccess redirection is not possible, attempts to use the alter_html method.
210 221 *
211 222 * @param string $buffer Page HTML
212 223 *
213 224 * @return string
@@ -219,9 +230,9 @@
219 230 return $buffer;
220 231 }
221 232
222 233 /**
223 - * If alter html method is possible, then use it
234 + * If alter HTML method is possible, apply it to the buffer.
224 235 *
225 236 * @param string $buffer Page HTML
226 237 *
227 238 * @return string
@@ -234,21 +245,28 @@
234 245 return $buffer;
235 246 }
236 247
237 248 /**
238 - * Even if server support .htaccess rewrite, sometimes it is not possible
239 - * to serve webp images. So, find it webp redirection is possible or not
249 + * Even if the server supports .htaccess rewrite, sometimes it is not possible
250 + * to serve webp images. This method determines whether webp redirection is possible.
251 + *
240 252 * Also applies `wpo_force_webp_serve_using_altered_html` filter for users to be able to
241 - * force Altered HTML method
253 + * force the Altered HTML method.
242 254 *
243 255 * @return bool
244 256 */
245 - public function is_webp_redirection_possible() {
257 + public function is_webp_redirection_possible(): bool {
246 258 if (apply_filters('wpo_force_webp_serve_using_altered_html', false)) {
247 259 return false;
248 260 }
261 +
249 262 $redirection_possible = WP_Optimize()->get_options()->get_option('redirection_possible');
250 - if (!empty($redirection_possible)) return 'true' === $redirection_possible;
263 +
264 + // If a previous test result exists, use it; otherwise, run the self test
265 + if (!empty($redirection_possible)) {
266 + return 'true' === $redirection_possible;
267 + }
268 +
251 269 return $this->run_webp_serving_self_test();
252 270 }
253 271
254 272 /**
@@ -255,16 +273,18 @@
255 273 * Detect whether using alter HTML method is possible or not
256 274 *
257 275 * @return bool
258 276 */
259 - private function is_alter_html_possible() {
277 + private function is_alter_html_possible(): bool {
260 278 return WPO_WebP_Utils::is_browser_accepting_webp();
261 279 }
262 280
263 281 /**
264 282 * Initialize .htaccess
283 + *
284 + * @return void
265 285 */
266 - private function setup_htaccess_file() {
286 + private function setup_htaccess_file(): void {
267 287 if (null !== $this->_htaccess) return;
268 288 $wp_uploads = wp_get_upload_dir();
269 289 $htaccess_file = $wp_uploads['basedir'] . '/.htaccess';
270 290 if (!file_exists($htaccess_file)) {
@@ -277,9 +297,9 @@
277 297 * Save .htaccess rules
278 298 *
279 299 * @return void
280 300 */
281 - private function save_htaccess_rules() {
301 + private function save_htaccess_rules(): void {
282 302 $this->setup_htaccess_file();
283 303 $this->add_webp_mime_type();
284 304 $htaccess_comment_section = 'WP-Optimize WebP Rules';
285 305 if ($this->_htaccess->is_commented_section_exists($htaccess_comment_section)) return;
@@ -289,10 +309,12 @@
289 309 }
290 310
291 311 /**
292 312 * Empty .htaccess file
313 + *
314 + * @return void
293 315 */
294 - private function empty_htaccess_file() {
316 + private function empty_htaccess_file(): void {
295 317 // Setting default to true, so on initial run (when option is not yet present in the DB) we don't break the function here
296 318 if (!WP_Optimize()->get_options()->get_option('htaccess_has_webp_rules', true)) return;
297 319 $this->setup_htaccess_file();
298 320 $htaccess_comment_sections = array(
@@ -309,9 +331,9 @@
309 331
310 332 /**
311 333 * Prepare array of htaccess rules to use webp images.
312 334 *
313 - * @return array
335 + * @return array<int, array<array<array<string>|string>|string>>
314 336 */
315 337 private function prepare_webp_htaccess_rules() {
316 338 return array(
317 339 array(
@@ -365,10 +387,12 @@
365 387 }
366 388
367 389 /**
368 390 * Add webp mime type to htaccess rules.
391 + *
392 + * @return void
369 393 */
370 - private function add_webp_mime_type() {
394 + private function add_webp_mime_type(): void {
371 395 $htaccess_comment_section = 'Register webp mime type';
372 396 if ($this->_htaccess->is_exists() && !$this->_htaccess->is_commented_section_exists($htaccess_comment_section)) {
373 397 $webp_mime_type = array(
374 398 array(
@@ -382,16 +406,24 @@
382 406 }
383 407 }
384 408
385 409 /**
410 + * Returns the path to the WebP test image file.
411 + *
412 + * @return string
413 + */
414 + private function get_webp_test_image_path(): string {
415 + $upload_dir = wp_upload_dir();
416 + return $upload_dir['basedir'] . '/wpo/images/wpo_logo_small.png.webp';
417 + }
418 +
419 + /**
386 420 * Checks whether a webp conversion test is successful or not
387 421 *
388 422 * @return bool
389 423 */
390 - private function is_webp_conversion_successful() {
391 - $upload_dir = wp_upload_dir();
392 - $destination = $upload_dir['basedir']. '/wpo/images/wpo_logo_small.png.webp';
393 - return file_exists($destination);
424 + private function is_webp_conversion_successful(): bool {
425 + return file_exists($this->get_webp_test_image_path());
394 426 }
395 427
396 428 /**
397 429 * Checks whether a sample webp conversion test should be run or not
@@ -397,17 +429,16 @@
397 429 * Checks whether a sample webp conversion test should be run or not
398 430 *
399 431 * @return bool Returns true if the sample test should be run, false otherwise
400 432 */
401 - private function should_run_webp_conversion_test() {
402 - $webp_conversion_test = $this->get_webp_conversion_test_result();
403 - return true !== $webp_conversion_test;
433 + private function should_run_webp_conversion_test(): bool {
434 + return !$this->get_webp_conversion_test_result();
404 435 }
405 436
406 437 /**
407 438 * Returns webp conversion test result
408 439 *
409 - * @return boolean Returns the value of the webp_conversion_test saved in the options table
440 + * @return bool Returns the value of the webp_conversion_test saved in the options table
410 441 */
411 442 public function get_webp_conversion_test_result(): bool {
412 443 return (bool) WP_Optimize()->get_options()->get_option('webp_conversion_test');
413 444 }
@@ -416,9 +447,9 @@
416 447 * Checks whether the webp redirection is possible or not and sets flag
417 448 *
418 449 * @return bool Returns true if webp is served successfully, false otherwise
419 450 */
420 - private function run_webp_serving_self_test() {
451 + private function run_webp_serving_self_test(): bool {
421 452 $self_test = WPO_WebP_Self_Test::get_instance();
422 453
423 454 if ($self_test->is_webp_served()) {
424 455 WP_Optimize()->get_options()->update_option('redirection_possible', 'true');
@@ -430,10 +461,12 @@
430 461 }
431 462
432 463 /**
433 464 * Resets webp serving method by running self test, if needed purges cache and empties `uploads/.htaccess` file
465 + *
466 + * @return void
434 467 */
435 - public function reset_webp_serving_method() {
468 + public function reset_webp_serving_method(): void {
436 469 if ($this->_should_use_webp) {
437 470 $this->reset_webp_options();
438 471 $this->run_self_test();
439 472 list($old_redirection_possible, $new_redirection_possible) = $this->get_old_and_new_redirection_possibility();
@@ -443,10 +476,12 @@
443 476 }
444 477
445 478 /**
446 479 * Resets WebP related options
480 + *
481 + * @return void
447 482 */
448 - private function reset_webp_options() {
483 + private function reset_webp_options(): void {
449 484 $options = WP_Optimize()->get_options();
450 485 $options->update_option('old_redirection_possible', $options->get_option('redirection_possible'));
451 486 $options->update_option('webp_conversion_test', false);
452 487 $options->update_option('webp_converters', false);
@@ -455,10 +490,12 @@
455 490 }
456 491
457 492 /**
458 493 * Running self test to find available converters and possibility of serving webp using redirection method
494 + *
495 + * @return void
459 496 */
460 - private function run_self_test() {
497 + private function run_self_test(): void {
461 498 $this->set_converter_status();
462 499 if ($this->get_webp_conversion_test_result()) {
463 500 $this->save_htaccess_rules();
464 501 $this->run_webp_serving_self_test();
@@ -470,9 +507,9 @@
470 507
471 508 /**
472 509 * Gets old and new redirection possibility values
473 510 *
474 - * @return array
511 + * @return array<string>
475 512 */
476 513 private function get_old_and_new_redirection_possibility() {
477 514 $options = WP_Optimize()->get_options();
478 515 return array(
@@ -483,23 +520,25 @@
483 520
484 521 /**
485 522 * Cache is cleared when there is a change in the potential for serving WebP using redirection.
486 523 *
487 - * @param string $old_redirection_possible
488 - * @param string $new_redirection_possible
524 + * @param string $old_redirection_possible Previous redirection possibility value
525 + * @param string $new_redirection_possible Current redirection possibility value
526 + * @return void
489 527 */
490 - private function maybe_purge_cache($old_redirection_possible, $new_redirection_possible) {
491 - if ($old_redirection_possible !== $new_redirection_possible) {
492 - $is_cache_purged = WP_Optimize()->get_page_cache()->purge();
493 - $log_old_value = empty($old_redirection_possible) ? "null" : $old_redirection_possible;
494 - $log_new_value = empty($new_redirection_possible) ? "null" : $new_redirection_possible;
495 - $this->log("Purging cache because redirection_possible value changed from: " .
496 - $log_old_value .
497 - " to " .
498 - $log_new_value
499 - );
500 - if ($is_cache_purged) WP_Optimize()->get_page_cache()->file_log("Full Cache Purge due to change in the value of WebP redirection");
528 + private function maybe_purge_cache($old_redirection_possible, $new_redirection_possible): void {
529 + if ($old_redirection_possible === $new_redirection_possible) {
530 + return;
501 531 }
532 +
533 + $is_cache_purged = WP_Optimize()->get_page_cache()->purge();
534 + $log_old_value = empty($old_redirection_possible) ? 'null' : $old_redirection_possible;
535 + $log_new_value = empty($new_redirection_possible) ? 'null' : $new_redirection_possible;
536 + $this->log("Purging cache because redirection_possible value changed from: {$log_old_value} to {$log_new_value}");
537 +
538 + if ($is_cache_purged) {
539 + WP_Optimize()->get_page_cache()->file_log('Full Cache Purge due to change in the value of WebP redirection');
540 + }
502 541 }
503 542
504 543 /**
505 544 * Remove redirection rules from `uploads/.htaccess` file if redirection is not possible
@@ -504,10 +543,11 @@
504 543 /**
505 544 * Remove redirection rules from `uploads/.htaccess` file if redirection is not possible
506 545 *
507 546 * @param string $new_redirection_possible
547 + * @return void
508 548 */
509 - private function maybe_empty_htaccess_file($new_redirection_possible) {
549 + private function maybe_empty_htaccess_file($new_redirection_possible): void {
510 550 if ('false' === $new_redirection_possible) {
511 551 $this->empty_htaccess_file();
512 552 }
513 553 }
@@ -513,10 +553,12 @@
513 553 }
514 554
515 555 /**
516 556 * Initialize cron scheduler
557 + *
558 + * @return void
517 559 */
518 - public function init_webp_cron_scheduler() {
560 + public function init_webp_cron_scheduler(): void {
519 561 if (!wp_next_scheduled('wpo_reset_webp_conversion_test_result')) {
520 562 wp_schedule_event(time(), 'wpo_daily', 'wpo_reset_webp_conversion_test_result');
521 563 }
522 564 if (!wp_next_scheduled('wpo_prune_webp_logs')) {
@@ -528,10 +570,12 @@
528 570 }
529 571
530 572 /**
531 573 * Remove all cron schedules
574 + *
575 + * @return void
532 576 */
533 - public function remove_webp_cron_schedules() {
577 + public function remove_webp_cron_schedules(): void {
534 578 wp_clear_scheduled_hook('wpo_reset_webp_conversion_test_result');
535 579 wp_clear_scheduled_hook('wpo_prune_webp_logs');
536 580 wp_clear_scheduled_hook('wpo_webp_convert_compressed_images');
537 581 }
@@ -546,10 +590,12 @@
546 590 }
547 591
548 592 /**
549 593 * Set the webp_conversion option value to false and remove webp cron schedules
594 + *
595 + * @return void
550 596 */
551 - public function disable_webp_conversion() {
597 + public function disable_webp_conversion(): void {
552 598 $this->empty_htaccess_file();
553 599 WP_Optimize()->get_options()->update_option("webp_conversion", false);
554 600 $this->remove_webp_cron_schedules();
555 601 $message = __('Disabling the webp conversion.', 'wp-optimize');
@@ -557,21 +603,22 @@
557 603 }
558 604
559 605 /**
560 606 * Remove webp converted test image file
607 + *
608 + * @return void
561 609 */
562 - private function remove_webp_test_image_file() {
563 - $upload_dir = wp_upload_dir();
564 - $destination = $upload_dir['basedir']. '/wpo/images/wpo_logo_small.png.webp';
565 - if (@file_exists($destination)) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- suppress PHP warning in case of failure
566 - wp_delete_file($destination);
567 - }
610 + private function remove_webp_test_image_file(): void {
611 + $destination = $this->get_webp_test_image_path();
612 + wp_delete_file($destination);
568 613 }
569 614
570 615 /**
571 616 * Run during plugin deactivation
617 + *
618 + * @return void
572 619 */
573 - public function plugin_deactivate() {
620 + public function plugin_deactivate(): void {
574 621 $this->empty_htaccess_file();
575 622 $this->remove_webp_test_image_file();
576 623 }
577 624
@@ -579,10 +626,15 @@
579 626 * Determines whether one of the PHP shell functions required for WebP conversion is available or not.
580 627 *
581 628 * @return bool
582 629 */
583 - public function shell_functions_available() {
584 - return function_exists('escapeshellarg') && ($this->any_function_exists(array('exec', 'passthru')) || $this->all_functions_exist(array('proc_open', 'proc_close')) || $this->all_functions_exist(array('popen', 'pclose')));
630 + public function shell_functions_available(): bool {
631 + $has_escapeshellarg = function_exists('escapeshellarg');
632 + $has_exec_or_passthru = $this->any_function_exists(array('exec', 'passthru'));
633 + $has_proc_functions = $this->all_functions_exist(array('proc_open', 'proc_close'));
634 + $has_popen_functions = $this->all_functions_exist(array('popen', 'pclose'));
635 +
636 + return $has_escapeshellarg && ($has_exec_or_passthru || $has_proc_functions || $has_popen_functions);
585 637 }
586 638
587 639 /**
588 640 * Checks if only shell converters available for WebP conversion.
@@ -588,10 +640,11 @@
588 640 * Checks if only shell converters available for WebP conversion.
589 641 *
590 642 * @return boolean
591 643 */
592 - private function is_only_shell_converters_available() {
644 + private function is_only_shell_converters_available(): bool {
593 645 $available_converters = WP_Optimize()->get_options()->get_option('webp_converters');
646 + /** @var array<string> $available_converters */
594 647 $available_converters = is_array($available_converters) ? $available_converters : array();
595 648 $converters_with_shell = WPO_WebP_Test_Run::get_converters_with_shell();
596 649 $available_with_shell = array_intersect($available_converters, $converters_with_shell);
597 650
@@ -603,10 +656,10 @@
603 656 *
604 657 * @deprecated 3.6.0
605 658 * @return bool
606 659 */
607 - public static function is_shell_functions_available() {
608 - _deprecated_function(__METHOD__, '3.6.0', 'WP_Optimize_WebP::is_shell_functions_available');
660 + public static function is_shell_functions_available(): bool {
661 + _deprecated_function(__METHOD__, '3.6.0', 'WP_Optimize_WebP::shell_functions_available');
609 662 return WP_Optimize_WebP::get_instance()->shell_functions_available();
610 663 }
611 664
612 665 /**
@@ -611,12 +664,12 @@
611 664
612 665 /**
613 666 * Check if all the functions from the list is available.
614 667 *
615 - * @param array $functions
668 + * @param array<string> $functions
616 669 * @return bool
617 670 */
618 - private function all_functions_exist($functions) {
671 + private function all_functions_exist($functions): bool {
619 672 foreach ($functions as $function) {
620 673 if (!function_exists($function)) return false;
621 674 }
622 675 return true;
@@ -624,12 +677,12 @@
624 677
625 678 /**
626 679 * Check if one of the functions from the list is available.
627 680 *
628 - * @param array $functions
681 + * @param array<string> $functions
629 682 * @return bool
630 683 */
631 - private function any_function_exists($functions) {
684 + private function any_function_exists($functions): bool {
632 685 foreach ($functions as $function) {
633 686 if (function_exists($function)) return true;
634 687 }
635 688 return false;
@@ -635,23 +688,24 @@
635 688 return false;
636 689 }
637 690
638 691 /**
639 - * Return the configuration setting `webp_conversion` value
692 + * Return true if webp conversion is enabled and vice versa.
640 693 *
641 694 * @return bool
642 695 */
643 696 public function is_webp_enabled(): bool {
644 - return $this->_should_use_webp;
697 + _deprecated_function(__METHOD__, '4.5.4', 'WP_Optimize_WebP::is_webp_conversion_enabled');
698 + return $this->is_webp_conversion_enabled();
645 699 }
646 -
700 +
647 701 /**
648 702 * Actions to be performed upon plugin activation
649 703 *
650 704 * @return void
651 705 */
652 - public function plugin_activate() {
653 - if ($this->is_webp_enabled()) {
706 + public function plugin_activate(): void {
707 + if ($this->is_webp_conversion_enabled()) {
654 708 $this->init_webp_cron_scheduler();
655 709 $this->reset_webp_serving_method();
656 710 }
657 711 }