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-wp-optimize-preloader.php +86 -36 3.4.1 → 4.7.0 View file →
@@ -8,8 +8,15 @@
8 8
9 9 protected $options;
10 10
11 11 /**
12 + * If set to true, the preloader will not close the browser connection when running via AJAX.
13 + *
14 + * @var bool
15 + */
16 + protected $dont_close_browser_connection = false;
17 +
18 + /**
12 19 * WP_Optimize_Page_Cache_Preloader constructor.
13 20 */
14 21 public function __construct() {
15 22 parent::__construct();
@@ -15,9 +22,13 @@
15 22 parent::__construct();
16 23
17 24 $this->options = WP_Optimize()->get_options();
18 25 // setup loggers
19 - $this->set_loggers(WP_Optimize()->wpo_loggers());
26 + if (did_action('init')) {
27 + $this->setup_loggers();
28 + } else {
29 + add_action('init', array($this, 'setup_loggers'));
30 + }
20 31
21 32 add_action('wpo_' . $this->preload_type . '_preload_continue', array($this, 'process_tasks_queue'));
22 33 add_filter('updraft_interrupt_tasks_queue_'.$this->task_type, array($this, 'maybe_interrupt_queue'), 20);
23 34 }
@@ -22,8 +33,17 @@
22 33 add_filter('updraft_interrupt_tasks_queue_'.$this->task_type, array($this, 'maybe_interrupt_queue'), 20);
23 34 }
24 35
25 36 /**
37 + * Setup loggers
38 + *
39 + * @return void
40 + */
41 + public function setup_loggers() {
42 + $this->set_loggers(WP_Optimize()->wpo_loggers());
43 + }
44 +
45 + /**
26 46 * Get a schedule interval
27 47 *
28 48 * @param string $schedule_key The schedule to check
29 49 * @return integer
@@ -33,9 +53,9 @@
33 53 if (!isset($schedules[$schedule_key])) {
34 54 $this->log('Could not get interval for event of type '.$schedule_key);
35 55 return 0;
36 56 }
37 - return isset($schedules[$schedule_key]['interval']) ? $schedules[$schedule_key]['interval'] : 0;
57 + return (int) $schedules[$schedule_key]['interval'] ?? 0;
38 58 }
39 59
40 60 /**
41 61 * Get the interval to continuing a preload task
@@ -45,9 +65,10 @@
45 65 public function get_continue_preload_cron_interval() {
46 66 /**
47 67 * Filters the interval between each preload attempt, in seconds.
48 68 */
49 - return (int) apply_filters('wpo_' . $this->preload_type . '_preload_continue_interval', 600);
69 + $filtered_interval = apply_filters('wpo_' . $this->preload_type . '_preload_continue_interval', 600);
70 + return is_int($filtered_interval) ? $filtered_interval : 600;
50 71 }
51 72
52 73 /**
53 74 * Schedule action for continuously preload.
@@ -56,9 +77,9 @@
56 77 $continue_in = wp_next_scheduled('wpo_' . $this->preload_type .'_preload_continue');
57 78
58 79 // Action is still scheduled
59 80 if ($continue_in && $continue_in > 0) return;
60 - // Action is overdue, delete it and re schedule it
81 + // Action is overdue, delete it and re-schedule it
61 82 if ($continue_in && $continue_in < 0) $this->delete_preload_continue_action();
62 83
63 84 wp_schedule_event(time() + $this->get_schedule_interval('wpo_' . $this->preload_type . '_preload_continue_interval'), 'wpo_' . $this->preload_type . '_preload_continue_interval', 'wpo_' . $this->preload_type . '_preload_continue');
64 85 }
@@ -73,12 +94,13 @@
73 94 /**
74 95 * Run preload. If task queue is empty it creates tasks for site urls.
75 96 *
76 97 * @param string $type - The preload type (schedule | manual)
77 - * @param array $response - Specific response for echo into output thread when browser connection closing.
98 + * @param ?array $response - Specific response for echo into output thread when browser connection closing.
99 + * @param bool $silent - If DOING_AJAX, close the connection without sending any additional data (default: false)
78 100 * @return array|void - Void when closing the browser connection
79 101 */
80 - public function run($type = 'scheduled', $response = null) {
102 + public function run($type = 'scheduled', $response = null, $silent = false) {
81 103 if (!$this->is_option_active()) {
82 104 return $this->get_option_disabled_error();
83 105 }
84 106
@@ -102,18 +124,27 @@
102 124
103 125 $is_wp_cli = defined('WP_CLI') && WP_CLI;
104 126
105 127 // close browser connection and continue work for ajax actions.
106 - if (defined('DOING_AJAX') && DOING_AJAX) {
107 - WP_Optimize()->close_browser_connection(json_encode($response));
128 + if (defined('DOING_AJAX') && DOING_AJAX && !$this->dont_close_browser_connection) {
129 + if (true === $silent) {
130 + $output = '';
131 + } else {
132 + $output = wp_json_encode($response);
133 + }
134 +
135 + WP_Optimize()->close_browser_connection($output);
108 136 }
109 137
138 + // Reset the flag to not close the browser connection for the next runs.
139 + $this->dont_close_browser_connection = false;
140 +
110 141 // trying to change time limit.
111 142 WP_Optimize()->change_time_limit();
112 143
113 144 $status = $this->get_status($this->task_type);
114 145
115 - if (0 == $status['all_tasks'] && $lock) {
146 + if (0 === (int) $status['all_tasks'] && $lock) {
116 147 if (is_multisite()) {
117 148 $sites = WP_Optimize()->get_sites();
118 149
119 150 foreach ($sites as $site) {
@@ -136,8 +167,24 @@
136 167 }
137 168 }
138 169
139 170 /**
171 + * Set the flag to not close the browser connection when running via AJAX.
172 + *
173 + * @return void
174 + */
175 + public function maybe_dont_close_browser_connection() {
176 +
177 + if ($this->dont_close_browser_connection) return;
178 +
179 + $dont_close_browser_connection = apply_filters('wpo_' . $this->preload_type . '_preloader_dont_close_browser_connection', $this->dont_close_browser_connection);
180 +
181 + if ($dont_close_browser_connection) {
182 + $this->dont_close_browser_connection = true;
183 + }
184 + }
185 +
186 + /**
140 187 * Process tasks queue.
141 188 */
142 189 public function process_tasks_queue() {
143 190 // schedule continue preload action.
@@ -168,9 +215,9 @@
168 215
169 216 if ($interrupt) return $interrupt;
170 217
171 218 static $memory_threshold = null;
172 - if (null == $memory_threshold) {
219 + if (null === $memory_threshold) {
173 220 /**
174 221 * Filters the minimum memory required before stopping a queue. Default: 10MB
175 222 */
176 223 $memory_threshold = apply_filters('wpo_' . $this->preload_type . '_preload_memory_threshold', 10485760);
@@ -207,9 +254,9 @@
207 254 *
208 255 * @return bool
209 256 */
210 257 public function is_cancelled() {
211 - return $this->options->get_option("last_{$this->preload_type}_preload_cancel", false);
258 + return (bool) $this->options->get_option("last_{$this->preload_type}_preload_cancel", false);
212 259 }
213 260
214 261 /**
215 262 * Check if preloading queue is processing.
@@ -222,9 +269,9 @@
222 269
223 270 /**
224 271 * Get current status of preloading urls.
225 272 *
226 - * @return array
273 + * @return mixed
227 274 */
228 275 public function get_status_info() {
229 276
230 277 $status = $this->get_status($this->task_type);
@@ -232,9 +279,9 @@
232 279
233 280 if ($this->is_semaphore_locked('wpo_' . $this->preload_type . '_preloader_creating_tasks') && !$this->is_cancelled()) {
234 281 // we are still creating tasks.
235 282 return $this->get_preloading_message($preload_data);
236 - } elseif ($status['complete_tasks'] == $status['all_tasks']) {
283 + } elseif ((int) $status['complete_tasks'] === (int) $status['all_tasks']) {
237 284 $gmt_offset = (int) (3600 * get_option('gmt_offset'));
238 285
239 286 $last_preload_time = $this->options->get_option('wpo_last_' . $this->preload_type . '_preload');
240 287
@@ -246,10 +293,11 @@
246 293 }
247 294 } else {
248 295 $preload_resuming_time = wp_next_scheduled('wpo_' . $this->preload_type . '_preload_continue');
249 296 $preload_resuming_in = $preload_resuming_time ? $preload_resuming_time - time() : 0;
297 + // translators: %1$s: number of preloaded urls, %2$s: total number of urls
250 298 $preloaded_message = sprintf(_n('%1$s out of %2$s URL preloaded', '%1$s out of %2$s URLs preloaded', $status['all_tasks'], 'wp-optimize'), $status['complete_tasks'], $status['all_tasks']);
251 - if ('sitemap' == $this->options->get_option('wpo_last_' . $this->preload_type . '_preload_type', '')) {
299 + if ('sitemap' === $this->options->get_option('wpo_last_' . $this->preload_type . '_preload_type', '')) {
252 300 $preloaded_message = __('Preloading posts found in sitemap:', 'wp-optimize') .' '. $preloaded_message;
253 301 }
254 302 $return = $this->get_preload_progress_message($preload_data, $preloaded_message, $preload_resuming_in);
255 303 if (defined('DOING_AJAX') && DOING_AJAX) {
@@ -254,9 +302,9 @@
254 302 $return = $this->get_preload_progress_message($preload_data, $preloaded_message, $preload_resuming_in);
255 303 if (defined('DOING_AJAX') && DOING_AJAX) {
256 304 // if no cron was found or cron is overdue more than 20s, trigger it
257 305 if (!$preload_resuming_time || $preload_resuming_in < -20) {
258 - $this->run($return);
306 + $this->run('scheduled', $return);
259 307 }
260 308 }
261 309 return $return;
262 310 }
@@ -269,9 +317,9 @@
269 317 */
270 318 public function is_running() {
271 319 $status = $this->get_status($this->task_type);
272 320
273 - if ($status['all_tasks'] > 0) return true;
321 + return $status['all_tasks'] > 0;
274 322 }
275 323
276 324 /**
277 325 * Preload desktop version from url.
@@ -282,9 +330,9 @@
282 330 */
283 331 public function preload_desktop($url) {
284 332 $desktop_args = array(
285 333 'httpversion' => '1.1',
286 - 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36',
334 + 'user-agent' => WP_Optimize_Utils::get_user_agent(),
287 335 'timeout' => 10,
288 336 'headers' => apply_filters('wpo_preload_headers', array()),
289 337 );
290 338
@@ -306,9 +354,9 @@
306 354 if (!apply_filters('wpo_should_preload_amp', false, $url)) return;
307 355
308 356 $amp_args = array(
309 357 'httpversion' => '1.1',
310 - 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36',
358 + 'user-agent' => WP_Optimize_Utils::get_user_agent(),
311 359 'timeout' => 10,
312 360 'headers' => apply_filters('wpo_preload_headers', array()),
313 361 );
314 362
@@ -326,8 +374,9 @@
326 374 *
327 375 * @return string
328 376 */
329 377 protected function get_sitemap_filename() {
378 + $sitemap_filename = 'sitemap.xml';
330 379 /**
331 380 * Filter the sitemap file used to collect the URLs to preload
332 381 *
333 382 * @param string $filename - The sitemap name
@@ -332,9 +381,10 @@
332 381 *
333 382 * @param string $filename - The sitemap name
334 383 * @default sitemap.xml
335 384 */
336 - return apply_filters('wpo_cache_preload_sitemap_filename', 'sitemap.xml');
385 + $filtered_sitemap_filename = apply_filters('wpo_cache_preload_sitemap_filename', $sitemap_filename);
386 + return is_string($filtered_sitemap_filename) ? $filtered_sitemap_filename : $sitemap_filename;
337 387 }
338 388
339 389 /**
340 390 * Check if sitemap exists then returns list of urls from sitemap file otherwise returns all posts urls.
@@ -351,8 +401,9 @@
351 401 $urls = $this->get_post_urls();
352 402 $this->options->update_option('wpo_last_' . $this->preload_type . '_preload_type', 'posts');
353 403 }
354 404
405 + // translators: %d: number of urls
355 406 $this->log(sprintf(_n('%d url found.', '%d urls found.', count($urls), 'wp-optimize'), count($urls)));
356 407
357 408 /**
358 409 * Filter the URLs which will be preloaded
@@ -359,9 +410,10 @@
359 410 *
360 411 * @param array $urls
361 412 * @return array
362 413 */
363 - return apply_filters('wpo_preload_get_site_urls', $urls);
414 + $filtered_url = apply_filters('wpo_preload_get_site_urls', $urls);
415 + return is_array($filtered_url) ? $filtered_url : array();
364 416 }
365 417
366 418 /**
367 419 * Loads sitemap file and returns list of urls.
@@ -367,9 +419,9 @@
367 419 * Loads sitemap file and returns list of urls.
368 420 *
369 421 * @param string $sitemap_url
370 422 *
371 - * @return array|bool
423 + * @return mixed
372 424 */
373 425 public function get_sitemap_urls($sitemap_url = '') {
374 426
375 427 $urls = array();
@@ -389,9 +441,9 @@
389 441 if (is_wp_error($response)) {
390 442 $response = file_get_contents($sitemap_url);
391 443
392 444 // if response is empty then try load from file.
393 - if (empty($response) && '' == $sitemap_url) {
445 + if (empty($response) && '' === $sitemap_url) {
394 446 $sitemap_file = $this->get_local_sitemap_file();
395 447
396 448 $response = file_get_contents($sitemap_file);
397 449 }
@@ -404,9 +456,9 @@
404 456 $xml = @simplexml_load_string(wp_remote_retrieve_body($response)); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- suppress warnings when error found in XML data
405 457 }
406 458
407 459 // xml file has not valid xml content then return false.
408 - if (false === $xml) return false;
460 + if (false === $xml) return array();
409 461
410 462 // if exists urls then return them.
411 463 if (isset($xml->url)) {
412 464 foreach ($xml->url as $element) {
@@ -413,17 +465,14 @@
413 465 if (!isset($element->loc)) continue;
414 466 $urls[] = (string) $element->loc;
415 467 }
416 468 } elseif (isset($xml->sitemap)) {
417 - // if has links to other sitemap files then get urls from them.
469 + // if it has links to other sitemap files then get urls from them.
418 470 foreach ($xml->sitemap as $element) {
419 471 if (!isset($element->loc)) continue;
420 472
421 473 $sitemap_urls = $this->get_sitemap_urls($element->loc);
422 -
423 - if (is_array($sitemap_urls)) {
424 - $urls = array_merge($urls, $sitemap_urls);
425 - }
474 + $urls = array_merge($urls, $sitemap_urls);
426 475 }
427 476 }
428 477
429 478 return $urls;
@@ -476,9 +525,9 @@
476 525 $urls[] = $permalink;
477 526
478 527 // check page separators in the post content
479 528 preg_match_all('/\<\!--nextpage--\>/', $post->post_content, $matches);
480 - // if there any separators add urls for each page
529 + // if there are any separators add urls for each page
481 530 if (count($matches[0])) {
482 531 $prefix = strpos($permalink, '?') ? '&page=' : '';
483 532 for ($page = 0; $page < count($matches[0]); $page++) {
484 533 if ('' != $prefix) {
@@ -520,9 +569,9 @@
520 569 * @return bool
521 570 */
522 571 public function is_domain_mapping_enabled() {
523 572 // SUNRISE constant is defined with installation WordPress MU Domain Mapping plugin.
524 - $enabled = is_multisite() && defined('SUNRISE') && 'on' == strtolower(SUNRISE);
573 + $enabled = is_multisite() && defined('SUNRISE') && 'on' === strtolower(SUNRISE);
525 574
526 575 /**
527 576 * Filters if Multisite Domain mapping is enabled.
528 577 * Currently, we can only detect if the WordPress MU Domain Mapping plugin is in use.
@@ -527,9 +576,9 @@
527 576 * Filters if Multisite Domain mapping is enabled.
528 577 * Currently, we can only detect if the WordPress MU Domain Mapping plugin is in use.
529 578 * Using the WP Core functionality should not require this, unless if the domain name is set somewhere else but in the site url option.
530 579 */
531 - return apply_filters('wpo_is_domain_mapping_enabled', $enabled);
580 + return (bool) apply_filters('wpo_is_domain_mapping_enabled', $enabled);
532 581 }
533 582
534 583 /**
535 584 * Return mapped domain by $blog_id.
@@ -543,11 +592,11 @@
543 592
544 593 $domain = '';
545 594 $multisite_plugin_table_name = $wpdb->base_prefix.'domain_mapping';
546 595 // Check if table exists
547 - if ($wpdb->get_var("SHOW TABLES LIKE '$multisite_plugin_table_name'") != $multisite_plugin_table_name) {
596 + if ($wpdb->get_var("SHOW TABLES LIKE '" . esc_sql($multisite_plugin_table_name) . "'") != $multisite_plugin_table_name) {
548 597 // This table created in WordPress MU Domain Mapping plugin.
549 - $row = $wpdb->get_row("SELECT `domain` FROM {$multisite_plugin_table_name} WHERE `blog_id` = {$blog_id} AND `active` = 1", ARRAY_A);
598 + $row = $wpdb->get_row($wpdb->prepare("SELECT `domain` FROM " . esc_sql($multisite_plugin_table_name) . " WHERE `blog_id` = %d AND `active` = %d", $blog_id, 1), ARRAY_A);
550 599 if (!empty($row)) {
551 600 $domain = $row['domain'];
552 601 }
553 602 } else {
@@ -560,16 +609,17 @@
560 609 *
561 610 * @param string $domain The domain name
562 611 * @param integer $blog_id The blog ID
563 612 */
564 - return apply_filters('wpo_get_mapped_domain', $domain, $blog_id);
613 + $filtered_domain = apply_filters('wpo_get_mapped_domain', $domain, $blog_id);
614 + return is_string($filtered_domain) ? $filtered_domain : $domain;
565 615 }
566 616
567 617 /**
568 618 * Captures and logs any interesting messages
569 619 *
570 - * @param String $message - the error message
571 - * @param String $error_type - the error type
620 + * @param string $message - the error message
621 + * @param string $error_type - the error type
572 622 */
573 623 public function log($message, $error_type = 'info') {
574 624
575 625 if (isset($this->loggers)) {