PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.4.2
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.4.2
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
wp-optimize / cache / class-wp-optimize-page-cache-preloader.php

class-wp-optimize-page-cache-preloader.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 3.4.2, at cache/class-wp-optimize-page-cache-preloader.php

716 lines 21.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) die('No direct access allowed');
4
5 if (!class_exists('WP_Optimize_Load_Url_Task')) {
6 require_once(WPO_PLUGIN_MAIN_PATH . 'cache/class-wpo-load-url-task.php');
7 }
8
9 class WP_Optimize_Page_Cache_Preloader extends WP_Optimize_Preloader {
10
11 protected $preload_type = 'page_cache';
12
13 protected $task_type = 'load-url-task';
14
15 static protected $_instance = null;
16
17 /**
18 * WP_Optimize_Page_Cache_Preloader constructor.
19 */
20 public function __construct() {
21 parent::__construct();
22
23 add_action('wpo_page_cache_schedule_preload', array($this, 'run_scheduled_cache_preload'));
24 add_filter('wpo_preload_headers', array($this, 'preload_headers'));
25 }
26
27 /**
28 * Check if cache is active.
29 *
30 * @return bool
31 */
32 public function is_option_active() {
33 return WP_Optimize()->get_page_cache()->is_enabled();
34 }
35
36 /**
37 * Schedule or delete automatic preload action on cache settings update.
38 *
39 * @param array $new_settings The new settings
40 * @param array $previous_settings Settings before saving
41 */
42 public function cache_settings_updated($new_settings, $previous_settings) {
43 if (!$new_settings['enable_page_caching']) {
44 wp_clear_scheduled_hook('wpo_page_cache_schedule_preload');
45 $this->delete_preload_continue_action();
46 return;
47 }
48
49 if (!empty($new_settings['enable_schedule_preload'])) {
50
51 $last_schedule_type = $previous_settings['preload_schedule_type'];
52
53 $last_use_nighttime = $this->options->get_option('page_cache_schedule_preload_nighttime');
54 // By default, we schedule preload events to the nighttime.
55 $use_nighttime = apply_filters('wpo_page_cache_schedule_preload_use_nighttime', 1);
56
57 $this->options->update_option('page_cache_schedule_preload_nighttime', $use_nighttime);
58
59 if (wp_next_scheduled('wpo_page_cache_schedule_preload')) {
60 // if already scheduled this schedule type
61 if ($new_settings['preload_schedule_type'] == $last_schedule_type && ($last_use_nighttime === $use_nighttime)) {
62 // If the schedule type is cache lifespan, check if the cache lifespan changed.
63 if ('wpo_use_cache_lifespan' == $new_settings['preload_schedule_type']) {
64 // Else, if the settings cache lifespan settings haven't changed, returns
65 if ($new_settings['page_cache_length_value'] == $previous_settings['page_cache_length_value'] && $new_settings['page_cache_length_unit'] == $previous_settings['page_cache_length_unit']) {
66 return;
67 }
68 } else {
69 return;
70 }
71 }
72 // clear currently scheduled preload action.
73 wp_clear_scheduled_hook('wpo_page_cache_schedule_preload');
74 }
75
76 // schedule preload action.
77 $timestamp = time() + $this->get_schedule_interval($new_settings['preload_schedule_type']);
78
79 if ($use_nighttime) {
80 $timestamp = $this->make_nighttime($timestamp);
81 }
82
83 wp_schedule_event($timestamp, $new_settings['preload_schedule_type'], 'wpo_page_cache_schedule_preload');
84 } else {
85 wp_clear_scheduled_hook('wpo_page_cache_schedule_preload');
86 }
87
88 }
89
90 /**
91 * Clear active preload tasks, reschedule preload action.
92 */
93 public function reschedule_preload() {
94 // clear scheduled action.
95 if (wp_next_scheduled('wpo_page_cache_schedule_preload')) {
96 wp_clear_scheduled_hook('wpo_page_cache_schedule_preload');
97 }
98
99 // schedule preload action if need.
100 if ($this->is_scheduled_preload_enabled()) {
101 $preload_schedule_type = $this->get_cache_config('preload_schedule_type');
102 // By default, we schedule preload events to the nighttime.
103 $use_nighttime = apply_filters('wpo_page_cache_schedule_preload_use_nighttime', 1);
104
105 $timestamp = time() + $this->get_schedule_interval($preload_schedule_type);
106 if ($use_nighttime) {
107 $timestamp = $this->make_nighttime($timestamp);
108 }
109
110 wp_schedule_event($timestamp, $preload_schedule_type, 'wpo_page_cache_schedule_preload');
111 }
112 }
113
114 /**
115 * Check if scheduled preload enabled.
116 *
117 * @return bool
118 */
119 public function is_scheduled_preload_enabled() {
120 $enable_schedule_preload = $this->get_cache_config('enable_schedule_preload');
121 return !empty($enable_schedule_preload);
122 }
123
124 /**
125 * Check if we need run cache preload and run it.
126 */
127 public function run_scheduled_cache_preload() {
128
129 $schedule_type = WPO_Cache_Config::instance()->get_option('preload_schedule_type');
130 if (!$schedule_type) return;
131
132 // Don't run preload if cache lifespan option enabled and cache not expired yet.
133 if ('wpo_use_cache_lifespan' == $schedule_type) {
134
135 /**
136 * Filters the allowed time difference between the cache exiry and the current time, in seconds.
137 * If the cache expires in less than $allowed_time_difference, preload. Otherwise leave it.
138 *
139 * @param integer $allowed_time_difference The time difference, in seconds (default is same as changed time limit)
140 */
141 $time_limit = (defined('WP_OPTIMIZE_SET_TIME_LIMIT') && WP_OPTIMIZE_SET_TIME_LIMIT > 15) ? WP_OPTIMIZE_SET_TIME_LIMIT : 1800;
142
143 $allowed_time_difference = apply_filters('wpo_preload_allowed_time_difference', $time_limit);
144 $page_cache_lifespan = WPO_Cache_Config::instance()->get_option('page_cache_length', 0);
145 $last_preload_time = $this->options->get_option('wpo_last_page_cache_preload', 0);
146 $time_since_last_preload = time() - $last_preload_time;
147 $minimum_time_to_next_schedule_preload = $page_cache_lifespan - $allowed_time_difference;
148 // Skip this if the last preload is not as old as the cache lifespan minus $allowed_time_difference
149 if ($page_cache_lifespan > 0 && $time_since_last_preload < $minimum_time_to_next_schedule_preload) return;
150 }
151
152 $this->run();
153 }
154
155
156 /**
157 * Get cache config option value.
158 *
159 * @return mixed
160 */
161 public function get_cache_config($option) {
162 static $config = null;
163
164 if (null === $config) $config = WPO_Page_Cache::instance()->config->get();
165
166 if (is_array($config) && array_key_exists($option, $config)) {
167 return $config[$option];
168 }
169
170 return false;
171 }
172
173 /**
174 * Create tasks (WP_Optimize_Load_Url_Task) for preload all urls from site.
175 *
176 * @param string $type The preload type (currently: scheduled, manual)
177 * @return void
178 */
179 public function create_tasks_for_preload_site_urls($type) {
180 $urls = $this->get_site_urls();
181
182 if (!empty($urls)) {
183
184 $this->log(__('Creating tasks for preload site urls.', 'wp-optimize'));
185
186 foreach ($urls as $url) {
187 if (wpo_url_in_exceptions($url)) continue;
188
189 if ($this->url_is_already_cached($url, $type)) {
190 continue;
191 }
192
193 // this description is being used for internal purposes.
194 $description = 'Preload - '.$url;
195 $options = array('url' => $url, 'preload_type' => $type, 'anonymous_user_allowed' => (defined('DOING_CRON') && DOING_CRON) || (defined('WP_CLI') && WP_CLI));
196
197 if (!class_exists('WP_Optimize_Load_Url_Task')) {
198 require_once WPO_PLUGIN_MAIN_PATH . 'cache/class-wpo-load-url-task.php';
199 }
200 WP_Optimize_Load_Url_Task::create_task($this->task_type, $description, $options, 'WP_Optimize_Load_Url_Task');
201 }
202
203 $this->log(__('Tasks for preload site urls created.', 'wp-optimize'));
204 }
205 }
206
207 /**
208 * Preload mobile version from $url.
209 *
210 * @param string $url
211 *
212 * @return void
213 */
214 public function preload_mobile($url) {
215 static $is_mobile_caching_enabled;
216 if (!isset($is_mobile_caching_enabled)) {
217 $is_mobile_caching_enabled = $this->get_cache_config('enable_mobile_caching');
218 }
219
220 // Only run if option is active
221 if (!$is_mobile_caching_enabled) return;
222
223 $mobile_args = array(
224 'httpversion' => '1.1',
225 'user-agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
226 'timeout' => 10,
227 'headers' => apply_filters('wpo_preload_headers', array()),
228 );
229
230 $mobile_args = apply_filters('wpo_page_cache_preloader_mobile_args', $mobile_args, $url);
231
232 $this->log('preload_mobile - ' . $url);
233
234 wp_remote_get($url, $mobile_args);
235 }
236
237 /**
238 * Preload amp version from $url.
239 *
240 * @param string $url
241 *
242 * @return void
243 */
244 public function preload_amp($url) {
245 if (!apply_filters('wpo_should_preload_amp', false, $url)) return;
246
247 $amp_args = array(
248 'httpversion' => '1.1',
249 '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',
250 'timeout' => 10,
251 'headers' => array(
252 'X-WP-Optimize-Cache-Preload' => 'Yes',
253 ),
254 );
255
256 $url = untrailingslashit($url) . '/amp/';
257
258 $amp_args = apply_filters('wpo_page_cache_preloader_amp_args', $amp_args, $url);
259
260 $this->log('preload_amp - ' . $url);
261
262 wp_remote_get($url, $amp_args);
263 }
264
265 /**
266 * Check if sitemap exists then returns list of urls from sitemap file otherwise returns all posts urls.
267 *
268 * @return array
269 */
270 public function get_site_urls() {
271
272 $urls = $this->get_sitemap_urls();
273
274 if (!empty($urls)) {
275 $this->options->update_option('wpo_last_page_cache_preload_type', 'sitemap');
276 } else {
277 $urls = $this->get_post_urls();
278 $this->options->update_option('wpo_last_page_cache_preload_type', 'posts');
279 }
280
281 $this->log(sprintf(_n('%d url found.', '%d urls found.', count($urls), 'wp-optimize'), count($urls)));
282
283 /**
284 * Filter the URLs which will be preloaded
285 *
286 * @param array $urls
287 * @return array
288 */
289 return apply_filters('wpo_preload_get_site_urls', $urls);
290 }
291
292 /**
293 * Loads sitemap file and returns list of urls.
294 *
295 * @param string $sitemap_url
296 *
297 * @return array|bool
298 */
299 public function get_sitemap_urls($sitemap_url = '') {
300
301 $urls = array();
302
303 // if sitemap url is empty then use main sitemap file name.
304 $sitemap_url = ('' === $sitemap_url) ? site_url('/'.$this->get_sitemap_filename()) : $sitemap_url;
305
306 // if simplexml_load_string not available then we don't load sitemap.
307 if (!function_exists('simplexml_load_string')) {
308 return $urls;
309 }
310
311 // load sitemap file.
312 $response = wp_remote_get($sitemap_url, array('timeout' => 30));
313
314 // if we get error then
315 // sometimes returns error due to timeout
316 if (is_wp_error($response)) {
317 $response = file_get_contents($sitemap_url);
318
319 // if response is empty then try load from file.
320 if (empty($response) && '' == $sitemap_url) {
321 $sitemap_file = $this->get_local_sitemap_file();
322
323 if (is_file($sitemap_file)) {
324 $response = file_get_contents($sitemap_file);
325 }
326 }
327
328 if (empty($response)) return $urls;
329
330 $xml = @simplexml_load_string($response); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- suppress warnings when error found in XML data
331 } else {
332 // parse xml answer.
333 $xml = @simplexml_load_string(wp_remote_retrieve_body($response)); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- suppress warnings when error found in XML data
334 }
335
336 // xml file has not valid xml content then return false.
337 if (false === $xml) return false;
338
339 // if exists urls then return them.
340 if (isset($xml->url)) {
341 foreach ($xml->url as $element) {
342 if (!isset($element->loc)) continue;
343 $urls[] = (string) $element->loc;
344 }
345 } elseif (isset($xml->sitemap)) {
346 // if has links to other sitemap files then get urls from them.
347 foreach ($xml->sitemap as $element) {
348 if (!isset($element->loc)) continue;
349
350 $sitemap_urls = $this->get_sitemap_urls($element->loc);
351
352 if (is_array($sitemap_urls)) {
353 $urls = array_merge($urls, $sitemap_urls);
354 }
355 }
356 }
357
358 return $urls;
359 }
360
361 /**
362 * Get all posts of any post type and returns urls for them.
363 *
364 * @return array
365 */
366 public function get_post_urls() {
367 global $post;
368
369 $offset = 0;
370 $posts_per_page = 1000;
371 $urls = array();
372
373 $urls[] = site_url('/');
374
375 do {
376 $query = new WP_Query(array(
377 'post_type' => 'any',
378 'post_status' => 'publish',
379 'posts_per_page' => $posts_per_page,
380 'offset' => $offset,
381 'orderby' => 'ID',
382 'order' => 'ASC',
383 'cache_results' => false, // disable cache to avoid memory error.
384 ));
385
386 $posts_loaded = $query->post_count;
387
388 while ($query->have_posts()) {
389 $query->the_post();
390 $permalink = get_permalink();
391 $urls[] = $permalink;
392
393 // check page separators in the post content
394 preg_match_all('/\<\!--nextpage--\>/', $post->post_content, $matches);
395 // if there any separators add urls for each page
396 if (count($matches[0])) {
397 $prefix = strpos($permalink, '?') ? '&page=' : '';
398 for ($page = 0; $page < count($matches[0]); $page++) {
399 if ('' != $prefix) {
400 $urls[] = $permalink . $prefix . ($page+2);
401 } else {
402 $urls[] = trailingslashit($permalink) . ($page+2);
403 }
404 }
405 }
406 }
407
408 $offset += $posts_loaded;
409 } while ($posts_loaded > 0);
410
411 /**
412 * If domain mapping enabled then replace domains in urls.
413 */
414 if ($this->is_domain_mapping_enabled()) {
415 $blog_id = get_current_blog_id();
416
417 $mapped_domain = $this->get_mapped_domain($blog_id);
418 $blog_details = get_blog_details($blog_id);
419
420 if ($mapped_domain) {
421 foreach ($urls as $i => $url) {
422 $urls[$i] = preg_replace('/'.$blog_details->domain.'/i', $mapped_domain, $url, 1);
423 }
424 }
425 }
426
427 wp_reset_postdata();
428
429 return $urls;
430 }
431
432 /**
433 * Check if domain mapping enabled.
434 *
435 * @return bool
436 */
437 public function is_domain_mapping_enabled() {
438 // SUNRISE constant is defined with installation WordPress MU Domain Mapping plugin.
439 $enabled = is_multisite() && defined('SUNRISE') && 'on' == strtolower(SUNRISE);
440
441 /**
442 * Filters if Multisite Domain mapping is enabled.
443 * Currently, we can only detect if the WordPress MU Domain Mapping plugin is in use.
444 * Using the WP Core functionality should not require this, unless if the domain name is set somewhere else but in the site url option.
445 */
446 return apply_filters('wpo_is_domain_mapping_enabled', $enabled);
447 }
448
449 /**
450 * Return mapped domain by $blog_id.
451 *
452 * @param int $blog_id
453 *
454 * @return string
455 */
456 public function get_mapped_domain($blog_id) {
457 global $wpdb;
458
459 $domain = '';
460 $multisite_plugin_table_name = $wpdb->base_prefix.'domain_mapping';
461 // Check if table exists
462 if ($wpdb->get_var("SHOW TABLES LIKE '$multisite_plugin_table_name'") != $multisite_plugin_table_name) {
463 // This table created in WordPress MU Domain Mapping plugin.
464 $row = $wpdb->get_row("SELECT `domain` FROM {$multisite_plugin_table_name} WHERE `blog_id` = {$blog_id} AND `active` = 1", ARRAY_A);
465 if (!empty($row)) {
466 $domain = $row['domain'];
467 }
468 } else {
469 // When using the WP Core method, the site url option contains the mapped domain.
470 $domain = get_site_url($blog_id);
471 }
472
473 /**
474 * Filters the mapped domain name
475 *
476 * @param string $domain The domain name
477 * @param integer $blog_id The blog ID
478 */
479 return apply_filters('wpo_get_mapped_domain', $domain, $blog_id);
480 }
481
482 /**
483 * Captures and logs any interesting messages
484 *
485 * @param String $message - the error message
486 * @param String $error_type - the error type
487 */
488 public function log($message, $error_type = 'info') {
489
490 if (isset($this->loggers)) {
491 foreach ($this->loggers as $logger) {
492 $logger->log($message, $error_type);
493 }
494 }
495 }
496
497 /**
498 * Instance of WP_Optimize_Page_Cache_Preloader.
499 *
500 * @return WP_Optimize_Page_Cache_Preloader
501 */
502 public static function instance() {
503 if (empty(self::$_instance)) {
504 self::$_instance = new WP_Optimize_Page_Cache_Preloader();
505 }
506
507 return self::$_instance;
508 }
509
510 /**
511 * Check if the URL is already cached, or needs to be preloaded
512 *
513 * @param string $url The preloaded url
514 * @param string $preload_type The preload type (manual | scheduled)
515 * @return boolean
516 */
517 private function url_is_already_cached($url, $preload_type) {
518 static $files = array();
519 $regenerate_count = 0;
520 $folder = trailingslashit(WPO_CACHE_FILES_DIR) . wpo_get_url_path($url);
521 // If the folder does not exist, consider the URL as cleared
522 if (!is_dir($folder)) return false;
523
524 if (empty($files)) {
525 // Check only the base files
526 $files[] = 'index.html';
527
528 if (WPO_Cache_Config::instance()->get_option('enable_mobile_caching')) {
529 $files[] = 'mobile.index.html';
530 }
531 $files = apply_filters('wpo_maybe_clear_files_list', $files);
532 }
533
534 foreach ($files as $file) {
535 $file_path = trailingslashit($folder).$file;
536 if (!file_exists($file_path)) {
537 // The file does not exist, count it as "deleted"
538 $regenerate_count++;
539 continue;
540 }
541
542 if ($this->should_regenerate_file($file_path, $preload_type)) {
543 // delefe the expired cache file
544 unlink($file_path);
545 $regenerate_count++;
546 }
547 }
548
549 // if 0 == $regenerate_count, nothing all the expected files exist, and none were deleted.
550 return 0 == $regenerate_count;
551 }
552
553 /**
554 * Determine if a file should be regenerated
555 *
556 * @param string $path The file to check
557 * @param string $preload_type The preload type (manual | scheduled)
558 *
559 * @return boolean
560 */
561 private function should_regenerate_file($path, $preload_type) {
562 // Store the variables, as they'll be used for each file and each file
563 static $is_preloader_scheduled = null;
564 static $lifespan = null;
565 static $schedule_type = null;
566 static $schedule_interval = null;
567 static $lifespan_expiry_threshold = null;
568 static $always_regenerate_file_if_preload_is_manual = null;
569 static $always_regenerate_file_if_preload_is_scheduled = null;
570 static $regenerate_file_when_no_expiry_date = null;
571
572 // Sets the variables once per request:
573 if (null === $is_preloader_scheduled) {
574 $is_preloader_scheduled = WPO_Cache_Config::instance()->get_option('enable_schedule_preload');
575 $schedule_type = WPO_Cache_Config::instance()->get_option('preload_schedule_type');
576 $lifespan = WPO_Cache_Config::instance()->get_option('page_cache_length');
577 $schedule_interval = $this->get_schedule_interval($schedule_type);
578
579 /**
580 * Expiry threshold: the current file will be considered stale if within the threshold. Default: 600s (10min)
581 */
582 $lifespan_expiry_threshold = apply_filters('wpo_lifespan_expiry_threshold', 600);
583
584 /**
585 * Filters if a cache should systematically be regenerated when running a manual preload. Default: false
586 */
587 $always_regenerate_file_if_preload_is_manual = apply_filters('wpo_always_regenerate_file_if_preload_is_manual', false);
588
589 /**
590 * Filters if a cache should systematically be regenerated when running a scheduled preload. Default: false
591 */
592 $always_regenerate_file_if_preload_is_scheduled = apply_filters('wpo_always_regenerate_file_if_preload_is_scheduled', false);
593
594 /**
595 * Filters if a cache should systematically be regenerated when running a preload and no schedule is set, and cache does not expire. Default: true
596 */
597 $regenerate_file_when_no_expiry_date = apply_filters('wpo_regenerate_file_when_no_expiry_date', true);
598 }
599
600 if (($always_regenerate_file_if_preload_is_manual && 'manual' == $preload_type) || ($always_regenerate_file_if_preload_is_scheduled && 'scheduled' == $preload_type)) {
601 $result = true;
602 } else {
603
604 $modified_time = (int) filemtime($path);
605
606 // cache lifespan is set.
607 if (0 != $lifespan) {
608 $expiry_time = $modified_time + $lifespan - $lifespan_expiry_threshold;
609 $result = time() > $expiry_time;
610 } elseif ($is_preloader_scheduled) {
611 $expiry_time = $modified_time + $schedule_interval - $lifespan_expiry_threshold;
612 $result = time() > $expiry_time;
613 } else {
614 $result = $regenerate_file_when_no_expiry_date;
615 }
616
617 }
618
619 return apply_filters('wpo_preloader_should_regenerate_file', $result, $path, $preload_type);
620 }
621
622 /**
623 * Add preloader headers
624 */
625 public function preload_headers($headers) {
626 $headers['X-WP-Optimize-Cache-Preload'] = 'Yes';
627 return $headers;
628 }
629
630 /**
631 * Option disabled error message
632 *
633 * @return array
634 */
635 protected function get_option_disabled_error() {
636 return array(
637 'success' => false,
638 'error' => __('Page cache is disabled.', 'wp-optimize')
639 );
640 }
641
642 /**
643 * Get preload already running error message
644 *
645 * @return array
646 */
647 protected function get_preload_already_running_error() {
648 return array(
649 'success' => false,
650 'error' => __('Probably page cache preload is running already.', 'wp-optimize')
651 );
652 }
653
654 protected function get_preload_data() {
655 return WP_Optimize()->get_page_cache()->get_cache_size();
656 }
657
658 protected function get_preloading_message($cache_size) {
659 return array(
660 'done' => false,
661 'message' => __('Loading URLs...', 'wp-optimize'),
662 'size' => WP_Optimize()->format_size($cache_size['size']),
663 'file_count' => $cache_size['file_count']
664 );
665 }
666
667 protected function get_last_preload_message($cache_size, $last_preload_time_str) {
668 return array(
669 'done' => true,
670 'message' => sprintf(__('Last preload finished at %s', 'wp-optimize'), $last_preload_time_str),
671 'size' => WP_Optimize()->format_size($cache_size['size']),
672 'file_count' => $cache_size['file_count']
673 );
674 }
675
676 protected function get_preload_success_message($cache_size) {
677 return array(
678 'done' => true,
679 'size' => WP_Optimize()->format_size($cache_size['size']),
680 'file_count' => $cache_size['file_count']
681 );
682 }
683
684 protected function get_preload_progress_message($cache_size, $preloaded_message, $preload_resuming_in) {
685 return array(
686 'done' => false,
687 'message' => $preloaded_message,
688 'size' => WP_Optimize()->format_size($cache_size['size']),
689 'file_count' => $cache_size['file_count'],
690 'resume_in' => $preload_resuming_in
691 );
692 }
693
694 /**
695 * Shifts the given timestamp to nighttime.
696 *
697 * @param int $time
698 *
699 * @return int
700 */
701 private function make_nighttime($time) {
702
703 $gmt_offset = WP_Optimize_Utils::get_gmt_offset();
704
705 // Set time to random time from 1 a.m. to 4:59 a.m.
706 $random_time = sprintf('%02d:%02d', rand(1, 4), rand(0, 59));
707 $nighttime = strtotime(date("Y-m-d {$random_time}:00", $time)) - $gmt_offset;
708
709 if ($nighttime < time()) $nighttime += 24 * 3600;
710
711 return $nighttime;
712 }
713 }
714
715 WP_Optimize_Page_Cache_Preloader::instance();
716