PluginProbe
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score / 1.2
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score v1.2
trunk 1.0 1.0.1 1.1 1.1.1 1.1.2 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1 2.1.1 2.1.2 2.2 2.2.1 All 69 releases
powered-cache / includes / functions.php

functions.php in Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score 1.2, at includes/functions.php

700 lines 17.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Common functions
4 */
5
6
7 // Exit if accessed directly
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12
13 /**
14 * Get all settings, if db hasn't settings options set defaults.
15 *
16 * @since 1.0
17 * @return mixed|void
18 */
19 function powered_cache_get_settings() {
20 $settings = get_option( 'powered_cache_settings' );
21
22 if ( empty( $settings ) ) {
23 $settings = Powered_Cache_Config::factory()->default_settings();
24 update_option( 'powered_cache_settings', $settings );
25 }
26
27 return apply_filters( 'powered_cache_get_settings', $settings );
28 }
29
30
31 /**
32 * Get single settings item of plugin
33 *
34 * @since 1.0
35 * @param string $key
36 * @param bool|false $default
37 *
38 * @return mixed|void
39 */
40 function powered_cache_get_option( $key = '', $default = false ) {
41 global $powered_cache_options;
42 $value = ! empty( $powered_cache_options[ $key ] ) ? $powered_cache_options[ $key ] : $default;
43 $value = apply_filters( 'powered_cache_get_option', $value, $key, $default );
44
45 return apply_filters( 'powered_cache_get_option_' . $key, $value, $key, $default );
46 }
47
48
49 /**
50 * Flush object cache and clean cache directory
51 *
52 * @since 1.0
53 */
54 function powered_cache_flush() {
55 if ( function_exists( 'wp_cache_flush' ) ) {
56 wp_cache_flush();
57 }
58 powered_cache_clean_page_cache_dir();
59 do_action( 'powered_cache_flushed' );
60 }
61
62
63 /**
64 * Save powered cache settings, update global settings variable and write to file
65 *
66 * @since 1.0
67 *
68 * @param $old_settings array
69 * @param $new_settings array
70 *
71 * @return bool depends on writing settings to file
72 */
73 function powered_cache_save_settings( $old_settings, $new_settings ) {
74 global $powered_cache_options;
75 $settings = array_merge( $old_settings, $new_settings );
76
77 $powered_cache_options = $settings;
78
79 $changed_settings = array_diff_assoc( array_map( 'serialize', $settings ), array_map( 'serialize', $old_settings ) );
80
81 update_option( 'powered_cache_settings', $settings );
82
83 if ( isset( $changed_settings['object_cache'] ) && function_exists( 'wp_cache_flush' ) ) {
84 wp_cache_flush();
85 }
86
87 if ( isset( $changed_settings['enable_page_caching'] ) ) {
88 powered_cache_clean_site_cache_dir();
89 }
90
91 Powered_Cache_Config::factory()->setup_object_cache( $settings['object_cache'] );
92 Powered_Cache_Config::factory()->setup_page_cache( $settings['enable_page_caching'] );
93
94 do_action( 'powered_cache_settings_saved', $settings );
95
96 unset( $settings['extension_settings'] );
97
98 return Powered_Cache_Config::factory()->save_to_file( $settings );
99 }
100
101 /**
102 * Prepare regex string for browser detetch
103 *
104 * @since 1.0
105 * @return mixed|void
106 */
107 function powered_cache_mobile_browsers_regex(){
108 $browsers = powered_cache_mobile_browsers();
109 $regex_str = addcslashes( implode( '|', explode( ',', $browsers ) ),' ');
110
111 return apply_filters( 'powered_cache_mobile_browsers_regex', $regex_str, $browsers );
112 }
113
114 /**
115 * Prepare regex string for mobile prefix
116 *
117 * @since 1.0
118 * @return mixed|void
119 */
120 function powered_cache_mobile_prefixes_regex(){
121 $prefixes = powered_cache_mobile_prefixes();
122 $regex_str = addcslashes( implode( '|', explode( ',', $prefixes ) ),' ');
123
124 return apply_filters( 'powered_cache_mobile_prefixes_regex', $regex_str, $prefixes );
125 }
126
127 /**
128 * Supported mobile browsers
129 *
130 * @since 1.0
131 * @return mixed|void
132 */
133 function powered_cache_mobile_browsers() {
134 $mobile_browsers = '2.0 MMP, 240x320, 400X240, AvantGo, BlackBerry, Blazer, Cellphone, Danger, DoCoMo, Elaine/3.0, EudoraWeb, Googlebot-Mobile, hiptop, IEMobile, KYOCERA/WX310K, LG/U990, MIDP-2., MMEF20, MOT-V, NetFront, Newt, Nintendo Wii, Nitro, Nokia, Opera Mini, Palm, PlayStation Portable, portalmmm, Proxinet, ProxiNet, SHARP-TQ-GX10, SHG-i900, Small, SonyEricsson, Symbian OS, SymbianOS, TS21i-10, UP.Browser, UP.Link, webOS, Windows CE, WinWAP, YahooSeeker/M1A1-R2D2, iPhone, iPod, Android, BlackBerry9530, LG-TU915 Obigo, LGE VX, webOS, Nokia5800';
135
136 return apply_filters( 'powered_cache_mobile_browsers', $mobile_browsers );
137 }
138
139
140 /**
141 * Supported mobile prefixes
142 *
143 * @since 1.0
144 * @return mixed|void
145 */
146 function powered_cache_mobile_prefixes() {
147 $mobile_prefixes = 'w3c , w3c-, acs-, alav, alca, amoi, audi, avan, benq, bird, blac, blaz, brew, cell, cldc, cmd-, dang, doco, eric, hipt, htc_, inno, ipaq, ipod, jigs, kddi, keji, leno, lg-c, lg-d, lg-g, lge-, lg/u, maui, maxo, midp, mits, mmef, mobi, mot-, moto, mwbp, nec-, newt, noki, palm, pana, pant, phil, play, port, prox, qwap, sage, sams, sany, sch-, sec-, send, seri, sgh-, shar, sie-, siem, smal, smar, sony, sph-, symb, t-mo, teli, tim-, tosh, tsm-, upg1, upsi, vk-v, voda, wap-, wapa, wapi, wapp, wapr, webc, winw, winw, xda , xda-';
148
149 return apply_filters( 'powered_cache_mobile_prefixes', $mobile_prefixes );
150 }
151
152
153 /**
154 * Prepare cdn addresses with hostname + zone
155 *
156 * @since 1.0
157 * @return mixed|void
158 */
159 function powered_cache_cdn_addresses() {
160 global $powered_cache_options;
161
162 $hostnames = $powered_cache_options['cdn_hostname'];
163 $zones = $powered_cache_options['cdn_zone'];
164
165 $cdn_addresses = array();
166 foreach ( $hostnames as $host_key => $host ) {
167 if ( ! empty( $host ) ) {
168 $cdn_addresses[ $zones[ $host_key ] ][] = $host;
169 }
170 }
171
172 return apply_filters( 'powered_cache_cdn_addresses', $cdn_addresses );
173 }
174
175
176 /**
177 * Check premium version running
178 * This is just simple helper function, our premium checks are more strict than your thoughts :)
179 *
180 * @since 1.0
181 * @return bool
182 */
183 function powered_cache_is_premium() {
184 if ( defined( 'POWERED_CACHE_PREMIUM' ) && true === POWERED_CACHE_PREMIUM ) {
185 return true;
186 }
187
188 return false;
189 }
190
191
192 function powered_cache_maybe_require_premium_html() {
193
194 if ( ! powered_cache_is_premium() ) {?>
195 <div class="<?php echo( ! powered_cache_is_premium() ? 'need-upgrade' : '' ); ?>">
196 <span class="upgrade-msg"><?php echo __( 'This feature available only premium users', 'powered-cache' ); ?></span>
197 </div>
198 <?php
199 }
200 }
201
202
203 /**
204 * Page cache base directory.
205 *
206 * @since 1.0
207 * @since 1.1 $url parameter removed @see `powered_cache_get_url_dir`
208 * @return string
209 */
210 function powered_cache_get_page_cache_dir() {
211 $path = powered_cache_get_cache_dir() . 'powered-cache/';
212
213 return apply_filters( 'powered_cache_get_page_cache_dir', $path );
214 }
215
216
217 /**
218 * get cache location of given url
219 *
220 * @param string $url
221 *
222 * @since 1.1
223 * @return mixed|void
224 */
225 function powered_cache_get_url_dir( $url ) {
226 $url_info = parse_url( $url );
227 $sub_dir = $url_info['host'] . $url_info['path'];
228 $path = powered_cache_get_cache_dir() . 'powered-cache/' . ltrim( $sub_dir, '/' );
229
230 return apply_filters( 'powered_cache_get_url_dir', $path );
231 }
232
233 /**
234 * get base caching directory of site
235 *
236 * @since 1.1
237 * @return mixed|void
238 */
239 function powered_cache_site_cache_dir() {
240 $base_dir = powered_cache_get_page_cache_dir();
241
242 // compatible with multisite
243 $site_url = get_site_url();
244
245 $site_path = parse_url( $site_url, PHP_URL_HOST );
246
247 $site_cache_dir = $base_dir . $site_path;
248
249 return apply_filters( 'powered_cache_site_cache_dir', $site_cache_dir );
250 }
251
252
253 /**
254 * Delete cache file
255 *
256 * @param string $url
257 *
258 * @since 1.0
259 * @return bool true when found cache dir, otherwhise false
260 */
261 function powered_cache_delete_page_cache( $url ) {
262
263 $dir = trailingslashit( powered_cache_get_url_dir( trim( $url ) ) );
264
265 if ( is_dir( $dir ) ) {
266 $files = scandir( $dir );
267 foreach ( $files as $file ) {
268 /**
269 * Don't need to lookup for index-https, index-https-mobile etc..
270 * Just clean that directory's files only.
271 */
272 if ( ! is_dir( $dir . $file ) && ! in_array( $file, array( '.', '..' ) ) ) {
273 unlink( $dir . $file );
274 }
275 }
276
277 return true;
278 }
279
280 return false;
281 }
282
283 /**
284 * Get all settings for plugin
285 *
286 * @since 1.0
287 * @param $extension_id
288 *
289 * @return bool
290 */
291 function powered_cache_get_extension_settings( $extension_id ) {
292 $extension_settings = powered_cache_get_option( 'extension_settings' );
293
294 if ( ! is_array( $extension_settings ) ) {
295 return false;
296 }
297
298 if ( array_key_exists( $extension_id, $extension_settings ) ) {
299 return $extension_settings[ $extension_id ];
300 }
301
302 return false;
303 }
304
305
306 /**
307 * Update options of extension
308 * @since 1.0
309 * @param $extension_id
310 * @param array $settings
311 *
312 * @return bool
313 */
314 function powered_cache_update_extension_option( $extension_id, $settings = array() ) {
315 $options = get_option( 'powered_cache_settings' );
316
317 $options['extension_settings'][ $extension_id ] = $settings;
318
319 $options_updated = update_option( 'powered_cache_settings', $options );
320
321 do_action( 'powered_cache_extension_option_updated', $options );
322
323 return $options_updated;
324 }
325
326
327 /**
328 * Get single option of plugin. Generally used for fields
329 *
330 * @since 1.0
331 * @param $extension_id
332 * @param string $option_name
333 * @param bool|false $default
334 *
335 * @return bool
336 */
337 function powered_cache_get_extension_option( $extension_id, $option_name = '', $default = false ) {
338 $option = powered_cache_get_extension_settings( $extension_id );
339
340 if ( is_array( $option ) && array_key_exists( $option_name, $option ) ) {
341 return $option[ $option_name ];
342 }
343
344 return $default;
345 }
346
347 /**
348 * return base caching dir
349 * use this function to get base caching directory instead of directly calling constant
350 *
351 * @since 1.0
352 * @return string path
353 */
354 function powered_cache_get_cache_dir() {
355 if ( defined( 'POWERED_CACHE_CACHE_DIR' ) ) {
356 return POWERED_CACHE_CACHE_DIR;
357 }
358
359 return WP_CONTENT_DIR . '/cache/';
360 }
361
362
363 /**
364 * Clean up cache directory
365 *
366 * @since 1.0
367 * @return mixed
368 */
369 function powered_cache_clean_page_cache_dir() {
370 global $powered_cache_fs;
371
372 return $powered_cache_fs->rmdir( untrailingslashit( powered_cache_get_cache_dir() ) . '/powered-cache', true );
373 }
374
375 /**
376 * Clean cache base for the current site
377 *
378 * @since 1.1
379 * @return mixed
380 */
381 function powered_cache_clean_site_cache_dir() {
382 global $powered_cache_fs;
383
384 return $powered_cache_fs->rmdir( powered_cache_site_cache_dir(), true );
385 }
386
387
388 /**
389 * Collect post related urls
390 *
391 * @since 1.0
392 * @since 1.1 powered_cache_post_related_urls filter added
393 *
394 * @param $post_id
395 *
396 * @return array
397 */
398 function powered_cache_get_post_related_urls( $post_id ) {
399
400 $current_post_status = get_post_status( $post_id );
401
402 // array to collect all our URLs
403 $related_urls = array();
404
405 if ( get_permalink( $post_id ) == true ) {
406 // we're going to add a ton of things to flush.
407
408 // related category urls
409 $categories = get_the_category( $post_id );
410 if ( $categories ) {
411 foreach ( $categories as $cat ) {
412 array_push( $related_urls, get_category_link( $cat->term_id ) );
413 }
414 }
415
416 // related tags url
417 $tags = get_the_tags( $post_id );
418 if ( $tags ) {
419 foreach ( $tags as $tag ) {
420 array_push( $related_urls, get_tag_link( $tag->term_id ) );
421 }
422 }
423
424 // Author URL
425 array_push( $related_urls, get_author_posts_url( get_post_field( 'post_author', $post_id ) ), get_author_feed_link( get_post_field( 'post_author', $post_id ) ) );
426
427 // Archives and their feeds
428 if ( get_post_type_archive_link( get_post_type( $post_id ) ) == true ) {
429 array_push( $related_urls, get_post_type_archive_link( get_post_type( $post_id ) ), get_post_type_archive_feed_link( get_post_type( $post_id ) ) );
430 }
431
432 // Post URL
433 array_push( $related_urls, get_permalink( $post_id ) );
434
435 // Also clean URL for trashed post.
436 if ( $current_post_status == "trash" ) {
437 $trashpost = get_permalink( $post_id );
438 $trashpost = str_replace( "__trashed", "", $trashpost );
439 array_push( $related_urls, $trashpost, $trashpost . 'feed/' );
440 }
441
442 // Add in AMP permalink if Automattic's AMP is installed
443 if ( function_exists( 'amp_get_permalink' ) ) {
444 array_push( $related_urls, amp_get_permalink( $post_id ) );
445 }
446
447 // Regular AMP url for posts
448 array_push( $related_urls, get_permalink( $post_id ) . 'amp/' );
449
450 // Feeds
451 array_push( $related_urls, get_bloginfo_rss( 'rdf_url' ), get_bloginfo_rss( 'rss_url' ), get_bloginfo_rss( 'rss2_url' ), get_bloginfo_rss( 'atom_url' ), get_bloginfo_rss( 'comments_rss2_url' ), get_post_comments_feed_link( $post_id ) );
452
453 // Home Page and (if used) posts page
454 array_push( $related_urls, trailingslashit( home_url() ) );
455 if ( get_option( 'show_on_front' ) == 'page' ) {
456 // Ensure we have a page_for_posts setting to avoid empty URL
457 if ( get_option( 'page_for_posts' ) ) {
458 array_push( $related_urls, get_permalink( get_option( 'page_for_posts' ) ) );
459 }
460 }
461 }
462
463 $related_urls = apply_filters( 'powered_cache_post_related_urls', $related_urls );
464
465 return $related_urls;
466 }
467
468
469 /**
470 * Get site related info. This could help us to debug.
471 *
472 * @since 1.0
473 * @return array
474 */
475 function powered_cache_get_debug_info() {
476 global $wpdb;
477 if ( ! function_exists( 'get_plugins' ) ) {
478 require_once ABSPATH . 'wp-admin/includes/plugin.php';
479 }
480
481 $active_plugins_option = get_option( 'active_plugins' );
482 $active_plugins = array();
483 $plugins = get_plugins();
484
485 foreach ( $active_plugins_option as $aplugin ) {
486 $active_plugins[ $plugins[ $aplugin ]['Name'] ] = array(
487 'file' => $aplugin,
488 'Name' => $plugins[ $aplugin ]['Name'],
489 'Version' => $plugins[ $aplugin ]['Version'],
490 );
491 }
492
493
494 $theme = wp_get_theme();
495
496 $theme_info = array(
497 'Name' => $theme->get( 'Name' ),
498 'Version' => $theme->get( 'Version' ),
499 'ThemeURI' => $theme->get( 'ThemeURI' ),
500 );
501
502
503 $mysql_version = $wpdb->get_var( 'select version() as mysqlversion' );
504 $php_version = phpversion();
505
506 $debug_info['php_version'] = $php_version;
507 $debug_info['mysql_version'] = $mysql_version;
508 $debug_info['active_plugins'] = $active_plugins;
509 $debug_info['active_theme'] = $theme_info;
510 $debug_info['is_multisite'] = is_multisite();
511
512 if ( is_multisite() && function_exists( 'is_subdomain_install' ) ) {
513 $debug_info['is_subdomain_install'] = is_subdomain_install();
514 }
515
516 return $debug_info;
517 }
518
519
520 /**
521 * Get list of expired files for given directory
522 *
523 * @param string $path
524 * @param int $lifespan lifespan in seconds
525 *
526 * @since 1.1
527 * @return array expired file list
528 */
529 function powered_cache_get_exprired_files( $path, $lifespan = 0 ) {
530
531 $current_time = time();
532
533 $expired_files = array();
534
535 // return immediately if the path is not exist!
536 if ( ! file_exists( $path ) ) {
537 return $expired_files;
538 }
539
540 $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ) );
541
542 foreach ( $files as $file ) {
543
544 if ( $file->isDir() ) {
545 continue;
546 }
547
548
549 $path = $file->getPathname();
550
551 if ( @filemtime( $path ) + $lifespan <= $current_time ) {
552 $expired_files[] = $path;
553 }
554
555 }
556
557 return $expired_files;
558 }
559
560 /**
561 * Is saving options now?
562 *
563 * @since 1.0
564 * @since 1.2 checks query arg
565 * @return bool
566 */
567 function powered_cache_is_saving_options() {
568 if ( isset( $_GET['pc_options'] ) && 'updated' === $_GET['pc_options'] ) {
569 return true;
570 }
571
572 return false;
573 }
574
575 /**
576 * Fragment caching for WordPress
577 *
578 * @link https://gist.github.com/markjaquith/2653957
579 * @see https://gist.github.com/westonruter/5475349
580 *
581 * @param string $key
582 * @param int $ttl
583 * @param callable $function
584 *
585 * @since 1.2
586 */
587 function powered_cache_fragment( $key, $ttl, $function ) {
588 $group = 'powered-fragments';
589 $output = wp_cache_get( $key, $group );
590 if ( empty( $output ) ) {
591 ob_start();
592 call_user_func( $function );
593 $output = ob_get_clean();
594 wp_cache_add( $key, $output, $group, $ttl );
595 }
596 echo $output;
597 }
598
599
600 /**
601 * Fetches known headers, ported from WP Super Cache but not using apache_response_headers
602 *
603 * @since 1.2
604 * @return array|false
605 */
606 function powered_cache_get_response_headers() {
607 static $known_headers = array(
608 'Access-Control-Allow-Origin',
609 'Accept-Ranges',
610 'Age',
611 'Allow',
612 'Cache-Control',
613 'Connection',
614 'Content-Encoding',
615 'Content-Language',
616 'Content-Length',
617 'Content-Location',
618 'Content-MD5',
619 'Content-Disposition',
620 'Content-Range',
621 'Content-Type',
622 'Date',
623 'ETag',
624 'Expires',
625 'Last-Modified',
626 'Link',
627 'Location',
628 'P3P',
629 'Pragma',
630 'Proxy-Authenticate',
631 "Referrer-Policy",
632 'Refresh',
633 'Retry-After',
634 'Server',
635 'Status',
636 'Strict-Transport-Security',
637 'Trailer',
638 'Transfer-Encoding',
639 'Upgrade',
640 'Vary',
641 'Via',
642 'Warning',
643 'WWW-Authenticate',
644 'X-Frame-Options',
645 'Public-Key-Pins',
646 'X-XSS-Protection',
647 'Content-Security-Policy',
648 "X-Pingback",
649 'X-Content-Security-Policy',
650 'X-WebKit-CSP',
651 'X-Content-Type-Options',
652 'X-Powered-By',
653 'X-UA-Compatible',
654 'X-Robots-Tag',
655 );
656
657 $known_headers = apply_filters( 'powered_cache_known_headers', $known_headers );
658
659 if ( ! isset( $known_headers['age'] ) ) {
660 $known_headers = array_map( 'strtolower', $known_headers );
661 }
662
663 $headers = array();
664
665 if ( function_exists( 'headers_list' ) ) {
666 $headers = array();
667 foreach ( headers_list() as $hdr ) {
668 $header_parts = explode( ':', $hdr, 2 );
669 $header_name = isset( $header_parts[0] ) ? trim( $header_parts[0] ) : '';
670 $header_value = isset( $header_parts[1] ) ? trim( $header_parts[1] ) : '';
671
672 $headers[ $header_name ] = $header_value;
673 }
674 }
675
676
677 foreach ( $headers as $key => $value ) {
678 if ( ! in_array( strtolower( $key ), $known_headers ) ) {
679 unset( $headers[ $key ] );
680 }
681 }
682
683 return $headers;
684 }
685
686
687 if ( ! function_exists( 'boolval' ) ) {
688 /**
689 * For compatible reason.
690 * If we create compat file someday this function should move there
691 *
692 * @since 1.0
693 * @param $val
694 *
695 * @return bool
696 */
697 function boolval( $val ) {
698 return (bool) $val;
699 }
700 }