PluginProbe
Autoptimize / trunk
Autoptimize vtrunk
3.1.16 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 All 108 releases
← All changes | classes/autoptimizeCache.php +99 -11 2.6.0 → trunk View file →
@@ -39,17 +39,22 @@
39 39 * @param string $ext Extension.
40 40 */
41 41 public function __construct( $md5, $ext = 'php' )
42 42 {
43 + $_min_ext = '';
44 + if ( apply_filters( 'autoptimize_filter_cache_url_add_min_ext', false ) ) {
45 + $_min_ext = '.min';
46 + }
47 +
43 48 $this->cachedir = AUTOPTIMIZE_CACHE_DIR;
44 49 $this->nogzip = AUTOPTIMIZE_CACHE_NOGZIP;
45 50 if ( ! $this->nogzip ) {
46 - $this->filename = AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . '.php';
51 + $this->filename = AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . $_min_ext . '.php';
47 52 } else {
48 53 if ( in_array( $ext, array( 'js', 'css' ) ) ) {
49 - $this->filename = $ext . '/' . AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . '.' . $ext;
54 + $this->filename = $ext . '/' . AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . $_min_ext . '.' . $ext;
50 55 } else {
51 - $this->filename = AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . '.' . $ext;
56 + $this->filename = AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . $_min_ext . '.' . $ext;
52 57 }
53 58 }
54 59 }
55 60
@@ -85,12 +90,17 @@
85 90 *
86 91 * @param string $data Data to cache.
87 92 * @param string $mime Mimetype.
88 93 *
89 - * @return void
94 + * @return void|bool
90 95 */
91 96 public function cache( $data, $mime )
92 97 {
98 + // readonly FS explicitly OK'ed by developer, so just pretend all is OK.
99 + if ( defined( 'AUTOPTIMIZE_CACHE_READONLY' ) ) {
100 + return true;
101 + }
102 +
93 103 // off by default; check if cachedirs exist every time before caching
94 104 //
95 105 // to be activated for users that experience these ugly errors;
96 106 // PHP Warning: file_put_contents failed to open stream: No such file or directory.
@@ -113,9 +123,9 @@
113 123 // save fallback .js or .css file if filter true (to be false by default) but not if snippet or single.
114 124 if ( self::do_fallback() && strpos( $this->filename, '_snippet_' ) === false && strpos( $this->filename, '_single_' ) === false ) {
115 125 $_extension = pathinfo( $this->filename, PATHINFO_EXTENSION );
116 126 $_fallback_file = AUTOPTIMIZE_CACHEFILE_PREFIX . 'fallback.' . $_extension;
117 - if ( ! file_exists( $this->cachedir . $_extension . '/' . $_fallback_file ) ) {
127 + if ( ( 'css' === $_extension || 'js' === $_extension ) && ! file_exists( $this->cachedir . $_extension . '/' . $_fallback_file ) ) {
118 128 file_put_contents( $this->cachedir . $_extension . '/' . $_fallback_file, $data );
119 129 }
120 130 }
121 131
@@ -127,8 +137,12 @@
127 137 file_put_contents( $this->cachedir . $this->filename . '.br', brotli_compress( $data, 11, BROTLI_GENERIC ) );
128 138 }
129 139 }
130 140 }
141 +
142 + // Provide 3rd party action hook for every cache file that is created.
143 + // This hook can for example be used to inject a copy of the created cache file to a other domain.
144 + do_action( 'autoptimize_action_cache_file_created', $this->cachedir . $this->filename );
131 145 }
132 146
133 147 /**
134 148 * Get cache filename.
@@ -367,9 +381,21 @@
367 381 * @return bool
368 382 */
369 383 public static function clearall( $propagate = true )
370 384 {
371 - if ( ! self::cacheavail() ) {
385 + if ( defined( 'ET_CORE_VERSION' ) && 'Divi' === get_template() ) {
386 + // see https://blog.futtta.be/2018/11/17/warning-divi-purging-autoptimizes-cache/ .
387 + $dbt = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 );
388 + $caller = isset( $dbt[1]['function'] ) ? $dbt[1]['function'] : null;
389 + if ( 'et_core_clear_wp_cache' === $caller ) {
390 + if ( apply_filters( 'autoptimize_filter_cache_divi_wrong_complain', true ) ) {
391 + _doing_it_wrong( 'autoptimizeCache::clearall', 'Divi devs: please don\'t clear Autoptimize\'s cache, it is unneeded and can break sites. You can contact me at [email protected] to discuss.', 'Autoptimize 2.9.6' );
392 + }
393 + return false;
394 + }
395 + }
396 +
397 + if ( ! self::cacheavail() || true === apply_filters( 'autoptimize_filter_cache_clearall_disabled', false ) ) {
372 398 return false;
373 399 }
374 400
375 401 // TODO/FIXME: If cache is big, switch to advanced/new cache clearing automatically?
@@ -519,8 +545,13 @@
519 545 * @return bool
520 546 */
521 547 public static function cacheavail()
522 548 {
549 + // readonly FS explicitly OK'ed by dev, let's assume the cache dirs are there!
550 + if ( defined( 'AUTOPTIMIZE_CACHE_READONLY' ) ) {
551 + return true;
552 + }
553 +
523 554 if ( false === autoptimizeCache::check_and_create_dirs() ) {
524 555 return false;
525 556 }
526 557
@@ -588,9 +619,9 @@
588 619 </Files>
589 620 </IfModule>';
590 621 }
591 622
592 - if ( self::do_fallback() ) {
623 + if ( self::do_fallback() === true ) {
593 624 $content .= "\nErrorDocument 404 " . trailingslashit( parse_url( content_url(), PHP_URL_PATH ) ) . 'autoptimize_404_handler.php';
594 625 }
595 626 @file_put_contents( $htaccess, $content ); // @codingStandardsIgnoreLine
596 627 }
@@ -612,12 +643,16 @@
612 643 $_fallback_filename = 'autoptimize_404_handler.php';
613 644 $_fallback_php = trailingslashit( WP_CONTENT_DIR ) . $_fallback_filename;
614 645 $_fallback_status = true;
615 646
616 - if ( ! file_exists( $_fallback_php ) ) {
647 + if ( ! file_exists( $_fallback_php ) && is_writable( WP_CONTENT_DIR ) ) {
617 648 $_fallback_php_contents = file_get_contents( AUTOPTIMIZE_PLUGIN_DIR . 'config/' . $_fallback_filename );
618 649 $_fallback_php_contents = str_replace( '<?php exit;', '<?php', $_fallback_php_contents );
619 650 $_fallback_php_contents = str_replace( '<!--ao-cache-dir-->', AUTOPTIMIZE_CACHE_DIR, $_fallback_php_contents );
651 + $_fallback_php_contents = str_replace( '<!--ao-cachefile-prefix-->', AUTOPTIMIZE_CACHEFILE_PREFIX, $_fallback_php_contents );
652 + if ( is_multisite() ) {
653 + $_fallback_php_contents = str_replace( '$multisite = false;', '$multisite = true;', $_fallback_php_contents );
654 + }
620 655 if ( apply_filters( 'autoptimize_filter_cache_fallback_log_errors', false ) ) {
621 656 $_fallback_php_contents = str_replace( '// error_log', 'error_log', $_fallback_php_contents );
622 657 }
623 658 $_fallback_status = file_put_contents( $_fallback_php, $_fallback_php_contents );
@@ -627,17 +662,60 @@
627 662 }
628 663
629 664 /**
630 665 * Tells if AO should try to avoid 404's by creating fallback filesize
631 - * and create a php 404 handler and tell .htaccess to redirect to said handler.
666 + * and create a php 404 handler and tell .htaccess to redirect to said handler
667 + * and hook into WordPress to redirect 404 to said handler as well. NGINX users
668 + * are smart enough to get this working, no? ;-)
632 669 *
633 670 * Return bool
634 671 */
635 672 public static function do_fallback() {
636 - return apply_filters( 'autoptimize_filter_cache_do_fallback', false );
673 + static $_do_fallback = null;
674 +
675 + if ( null === $_do_fallback ) {
676 + $_do_fallback = (bool) apply_filters( 'autoptimize_filter_cache_do_fallback', autoptimizeOptionWrapper::get_option( 'autoptimize_cache_fallback', '1' ) );
677 + }
678 +
679 + return $_do_fallback;
637 680 }
638 681
639 682 /**
683 + * Hooks into template_redirect, will act on 404-ing requests for
684 + * Autoptimized files and redirects to the fallback CSS/ JS if available
685 + * and 410'ing ("Gone") if fallback not available.
686 + */
687 + public static function wordpress_notfound_fallback() {
688 + $original_request = strtok( $_SERVER['REQUEST_URI'], '?' );
689 + if ( strpos( $original_request, wp_basename( WP_CONTENT_DIR ) . AUTOPTIMIZE_CACHE_CHILD_DIR ) !== false && is_404() ) {
690 + // make sure this is not considered a 404.
691 + global $wp_query;
692 + $wp_query->is_404 = false;
693 +
694 + // set fallback path.
695 + $js_or_css = pathinfo( $original_request, PATHINFO_EXTENSION );
696 + $fallback_path = AUTOPTIMIZE_CACHE_DIR . $js_or_css . '/autoptimize_fallback.' . $js_or_css;
697 +
698 + // prepare for Shakeeb's Unused CSS files to be 404-handled as well.
699 + if ( strpos( $original_request, 'uucss/uucss-' ) !== false ) {
700 + $original_request = preg_replace( '/uucss\/uucss-[a-z0-9]{32}-/', 'css/', $original_request );
701 + }
702 +
703 + // set fallback URL.
704 + $fallback_target = preg_replace( '/(.*)_(?:[a-z0-9]{32})\.(js|css)$/', '${1}_fallback.${2}', $original_request );
705 +
706 + // redirect to fallback if possible.
707 + if ( $original_request !== $fallback_target && file_exists( $fallback_path ) ) {
708 + // redirect to fallback.
709 + wp_redirect( $fallback_target, 302 );
710 + } else {
711 + // return HTTP 410 (gone) reponse.
712 + status_header( 410 );
713 + }
714 + }
715 + }
716 +
717 + /**
640 718 * Checks if cache dirs exist and create if not.
641 719 * Returns false if not succesful.
642 720 *
643 721 * @return bool
@@ -708,8 +786,12 @@
708 786 } elseif ( function_exists( 'w3tc_pgcache_flush' ) ) {
709 787 w3tc_pgcache_flush();
710 788 } elseif ( function_exists( 'wp_fast_cache_bulk_delete_all' ) ) {
711 789 wp_fast_cache_bulk_delete_all();
790 + } elseif ( function_exists( 'rapidcache_clear_cache' ) ) {
791 + rapidcache_clear_cache();
792 + } elseif ( class_exists( 'Swift_Performance_Cache' ) ) {
793 + Swift_Performance_Cache::clear_all_cache();
712 794 } elseif ( class_exists( 'WpFastestCache' ) ) {
713 795 $wpfc = new WpFastestCache();
714 796 $wpfc->deleteCache();
715 797 } elseif ( class_exists( 'c_ws_plugin__qcache_purging_routines' ) ) {
@@ -742,13 +824,16 @@
742 824 } elseif ( array_key_exists( 'KINSTA_CACHE_ZONE', $_SERVER ) ) {
743 825 $_kinsta_clear_cache_url = 'https://localhost/kinsta-clear-cache-all';
744 826 $_kinsta_response = wp_remote_get(
745 827 $_kinsta_clear_cache_url,
746 - array(
828 + array(
747 829 'sslverify' => false,
748 830 'timeout' => 5,
749 831 )
750 832 );
833 + } elseif ( class_exists( 'RaidboxesNginxCacheFunctions' ) ) {
834 + $rb_cache_helper = new RaidboxesNginxCacheFunctions();
835 + $rb_cache_helper->purge_cache();
751 836 } elseif ( defined('NGINX_HELPER_BASENAME') ) {
752 837 do_action( 'rt_nginx_helper_purge_all' );
753 838 } elseif ( file_exists( WP_CONTENT_DIR . '/wp-cache-config.php' ) && function_exists( 'prune_super_cache' ) ) {
754 839 // fallback for WP-Super-Cache
@@ -760,8 +845,11 @@
760 845 } else {
761 846 prune_super_cache( $cache_path . 'supercache/', true );
762 847 prune_super_cache( $cache_path, true );
763 848 }
849 + } elseif ( class_exists( 'NginxCache' ) ) {
850 + $nginx_cache = new NginxCache();
851 + $nginx_cache->purge_zone_once();
764 852 }
765 853 }
766 854 // @codingStandardsIgnoreEnd
767 855 }