PluginProbe
Autoptimize / 1.4
Autoptimize v1.4
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 2.7.8 All 107 releases
← All changes | classes/autoptimizeCache.php +155 -761 2.6.11.4 View file →
@@ -1,767 +1,161 @@
1 1 <?php
2 -/**
3 - * Handles disk-cache-related operations.
4 - */
5 2
6 -if ( ! defined( 'ABSPATH' ) ) {
7 - exit;
8 -}
9 -
10 3 class autoptimizeCache
11 4 {
12 - /**
13 - * Cache filename.
14 - *
15 - * @var string
16 - */
17 - private $filename;
5 + private $filename;
6 + private $mime;
7 + private $cachedir;
8 + private $delayed;
9 +
10 + public function __construct($md5,$ext='php')
11 + {
12 + $this->cachedir = AUTOPTIMIZE_CACHE_DIR;
13 + $this->delayed = AUTOPTIMIZE_CACHE_DELAY;
14 + $this->nogzip = AUTOPTIMIZE_CACHE_NOGZIP;
15 + if($this->nogzip == false)
16 + $this->filename = 'autoptimize_'.$md5.'.php';
17 + else
18 + $this->filename = 'autoptimize_'.$md5.'.'.$ext;
19 + }
20 +
21 + public function check()
22 + {
23 + if(!file_exists($this->cachedir.$this->filename))
24 + {
25 + //No cached file, sorry
26 + return false;
27 + }
28 + //Cache exists!
29 + return true;
30 + }
31 +
32 + public function retrieve()
33 + {
34 + if($this->check())
35 + {
36 + if($this->nogzip == false)
37 + return file_get_contents($this->cachedir.$this->filename.'.none');
38 + else
39 + return file_get_contents($this->cachedir.$this->filename);
40 + }
41 + return false;
42 + }
43 +
44 + public function cache($code,$mime)
45 + {
46 + if($this->nogzip == false)
47 + {
48 + $file = ($this->delayed ? 'delayed.php' : 'default.php');
49 + $phpcode = file_get_contents(WP_PLUGIN_DIR.'/autoptimize/config/'.$file);
50 + $phpcode = str_replace(array('%%CONTENT%%','exit;'),array($mime,''),$phpcode);
51 + file_put_contents($this->cachedir.$this->filename,$phpcode);
52 + file_put_contents($this->cachedir.$this->filename.'.none',$code);
53 + if(!$this->delayed)
54 + {
55 + //Compress now!
56 + file_put_contents($this->cachedir.$this->filename.'.deflate',gzencode($code,9,FORCE_DEFLATE));
57 + file_put_contents($this->cachedir.$this->filename.'.gzip',gzencode($code,9,FORCE_GZIP));
58 + }
59 + }else{
60 + //Write code to cache without doing anything else
61 + file_put_contents($this->cachedir.$this->filename,$code);
62 + }
63 + }
64 +
65 + public function getname()
66 + {
67 + return $this->filename;
68 + }
69 +
70 + static function clearall()
71 + {
72 + //Cache not available :(
73 + if(!autoptimizeCache::cacheavail())
74 + return false;
75 +
76 + //Clean the cachedir
77 + $scan = scandir(AUTOPTIMIZE_CACHE_DIR);
78 + foreach($scan as $file)
79 + {
80 + if(!in_array($file,array('.','..')) && strpos($file,'autoptimize') !== false && is_file(AUTOPTIMIZE_CACHE_DIR.$file))
81 + {
82 + @unlink(AUTOPTIMIZE_CACHE_DIR.$file);
83 + }
84 + }
85 +
86 + //Do we need to clean WP Super Cache's cache files?
87 + if(function_exists('wp_cache_clear_cache'))
88 + {
89 + //Newer WP-Super-Cache
90 + //See http://ocaoimh.ie/wp-super-cache-developers/
91 + wp_cache_clear_cache();
92 + }elseif(file_exists(WP_CONTENT_DIR.'/wp-cache-config.php') && function_exists('prune_super_cache')){
93 + //Old WP-Super-Cache
94 + global $cache_path;
95 + prune_super_cache($cache_path.'supercache/',true);
96 + prune_super_cache($cache_path,true);
97 + }
98 +
99 + return true;
100 + }
101 +
102 + static function stats()
103 + {
104 + //Cache not available :(
105 + if(!autoptimizeCache::cacheavail())
106 + return 0;
18 107
19 - /**
20 - * Cache directory path (with a trailing slash).
21 - *
22 - * @var string
23 - */
24 - private $cachedir;
25 -
26 - /**
27 - * Whether gzipping is done by the web server or us.
28 - * True => we don't gzip, the web server does it.
29 - * False => we do it ourselves.
30 - *
31 - * @var bool
32 - */
33 - private $nogzip;
34 -
35 - /**
36 - * Ctor.
37 - *
38 - * @param string $md5 Hash.
39 - * @param string $ext Extension.
40 - */
41 - public function __construct( $md5, $ext = 'php' )
42 - {
43 - $this->cachedir = AUTOPTIMIZE_CACHE_DIR;
44 - $this->nogzip = AUTOPTIMIZE_CACHE_NOGZIP;
45 - if ( ! $this->nogzip ) {
46 - $this->filename = AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . '.php';
47 - } else {
48 - if ( in_array( $ext, array( 'js', 'css' ) ) ) {
49 - $this->filename = $ext . '/' . AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . '.' . $ext;
50 - } else {
51 - $this->filename = AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . '.' . $ext;
52 - }
53 - }
54 - }
55 -
56 - /**
57 - * Returns true if the cached file exists on disk.
58 - *
59 - * @return bool
60 - */
61 - public function check()
62 - {
63 - return file_exists( $this->cachedir . $this->filename );
64 - }
65 -
66 - /**
67 - * Returns cache contents if they exist, false otherwise.
68 - *
69 - * @return string|false
70 - */
71 - public function retrieve()
72 - {
73 - if ( $this->check() ) {
74 - if ( false == $this->nogzip ) {
75 - return file_get_contents( $this->cachedir . $this->filename . '.none' );
76 - } else {
77 - return file_get_contents( $this->cachedir . $this->filename );
78 - }
79 - }
80 - return false;
81 - }
82 -
83 - /**
84 - * Stores given $data in cache.
85 - *
86 - * @param string $data Data to cache.
87 - * @param string $mime Mimetype.
88 - *
89 - * @return void
90 - */
91 - public function cache( $data, $mime )
92 - {
93 - // off by default; check if cachedirs exist every time before caching
94 - //
95 - // to be activated for users that experience these ugly errors;
96 - // PHP Warning: file_put_contents failed to open stream: No such file or directory.
97 - if ( apply_filters( 'autoptimize_filter_cache_checkdirs_on_write', false ) ) {
98 - $this->check_and_create_dirs();
99 - }
100 -
101 - if ( false === $this->nogzip ) {
102 - // We handle gzipping ourselves.
103 - $file = 'default.php';
104 - $phpcode = file_get_contents( AUTOPTIMIZE_PLUGIN_DIR . 'config/' . $file );
105 - $phpcode = str_replace( array( '%%CONTENT%%', 'exit;' ), array( $mime, '' ), $phpcode );
106 -
107 - file_put_contents( $this->cachedir . $this->filename, $phpcode );
108 - file_put_contents( $this->cachedir . $this->filename . '.none', $data );
109 - } else {
110 - // Write code to cache without doing anything else.
111 - file_put_contents( $this->cachedir . $this->filename, $data );
112 -
113 - // save fallback .js or .css file if filter true (to be false by default) but not if snippet or single.
114 - if ( self::do_fallback() && strpos( $this->filename, '_snippet_' ) === false && strpos( $this->filename, '_single_' ) === false ) {
115 - $_extension = pathinfo( $this->filename, PATHINFO_EXTENSION );
116 - $_fallback_file = AUTOPTIMIZE_CACHEFILE_PREFIX . 'fallback.' . $_extension;
117 - if ( ! file_exists( $this->cachedir . $_extension . '/' . $_fallback_file ) ) {
118 - file_put_contents( $this->cachedir . $_extension . '/' . $_fallback_file, $data );
119 - }
120 - }
121 -
122 - if ( apply_filters( 'autoptimize_filter_cache_create_static_gzip', false ) ) {
123 - // Create an additional cached gzip file.
124 - file_put_contents( $this->cachedir . $this->filename . '.gz', gzencode( $data, 9, FORCE_GZIP ) );
125 - // If PHP Brotli extension is installed, create an additional cached Brotli file.
126 - if ( function_exists( 'brotli_compress' ) ) {
127 - file_put_contents( $this->cachedir . $this->filename . '.br', brotli_compress( $data, 11, BROTLI_GENERIC ) );
128 - }
129 - }
130 - }
131 - }
132 -
133 - /**
134 - * Get cache filename.
135 - *
136 - * @return string
137 - */
138 - public function getname()
139 - {
140 - // NOTE: This could've maybe been a do_action() instead, however,
141 - // that ship has sailed.
142 - // The original idea here was to provide 3rd party code a hook so that
143 - // it can "listen" to all the complete autoptimized-urls that the page
144 - // will emit... Or something to that effect I think?
145 - apply_filters( 'autoptimize_filter_cache_getname', AUTOPTIMIZE_CACHE_URL . $this->filename );
146 -
147 - return $this->filename;
148 - }
149 -
150 - /**
151 - * Returns true if given `$file` is considered a valid Autoptimize cache file,
152 - * false otherwise.
153 - *
154 - * @param string $dir Directory name (with a trailing slash).
155 - * @param string $file Filename.
156 - * @return bool
157 - */
158 - protected static function is_valid_cache_file( $dir, $file )
159 - {
160 - if ( '.' !== $file && '..' !== $file &&
161 - false !== strpos( $file, AUTOPTIMIZE_CACHEFILE_PREFIX ) &&
162 - is_file( $dir . $file ) ) {
163 -
164 - // It's a valid file!
165 - return true;
166 - }
167 -
168 - // Everything else is considered invalid!
169 - return false;
170 - }
171 -
172 - /**
173 - * Clears contents of AUTOPTIMIZE_CACHE_DIR.
174 - *
175 - * @return void
176 - */
177 - protected static function clear_cache_classic()
178 - {
179 - $contents = self::get_cache_contents();
180 - foreach ( $contents as $name => $files ) {
181 - $dir = rtrim( AUTOPTIMIZE_CACHE_DIR . $name, '/' ) . '/';
182 - foreach ( $files as $file ) {
183 - if ( self::is_valid_cache_file( $dir, $file ) ) {
184 - @unlink( $dir . $file ); // @codingStandardsIgnoreLine
185 - }
186 - }
187 - }
188 -
189 - @unlink( AUTOPTIMIZE_CACHE_DIR . '/.htaccess' ); // @codingStandardsIgnoreLine
190 - }
191 -
192 - /**
193 - * Recursively deletes the specified pathname (file/directory) if possible.
194 - * Returns true on success, false otherwise.
195 - *
196 - * @param string $pathname Pathname to remove.
197 - *
198 - * @return bool
199 - */
200 - protected static function rmdir( $pathname )
201 - {
202 - $files = self::get_dir_contents( $pathname );
203 - foreach ( $files as $file ) {
204 - $path = $pathname . '/' . $file;
205 - if ( is_dir( $path ) ) {
206 - self::rmdir( $path );
207 - } else {
208 - unlink( $path );
209 - }
210 - }
211 -
212 - return rmdir( $pathname );
213 - }
214 -
215 - /**
216 - * Clears contents of AUTOPTIMIZE_CACHE_DIR by renaming the current
217 - * cache directory into a new one with a unique name and then
218 - * re-creating the default (empty) cache directory.
219 - *
220 - * Important/ Fixme: this does not take multisite into account, so
221 - * if advanced_cache_clear_enabled is true (it is not by default)
222 - * then the content for all subsites is zapped!
223 - *
224 - * @return bool Returns true when everything is done successfully, false otherwise.
225 - */
226 - protected static function clear_cache_via_rename()
227 - {
228 - $ok = false;
229 - $dir = self::get_pathname_base();
230 - $new_name = self::get_unique_name();
231 -
232 - // Makes sure the new pathname is on the same level...
233 - $new_pathname = dirname( $dir ) . '/' . $new_name;
234 - $renamed = @rename( $dir, $new_pathname ); // @codingStandardsIgnoreLine
235 -
236 - // When renamed, re-create the default cache directory back so it's
237 - // available again...
238 - if ( $renamed ) {
239 - $ok = self::cacheavail();
240 - }
241 -
242 - return $ok;
243 - }
244 -
245 - /**
246 - * Returns true when advanced cache clearing is enabled.
247 - *
248 - * @return bool
249 - */
250 - public static function advanced_cache_clear_enabled()
251 - {
252 - return apply_filters( 'autoptimize_filter_cache_clear_advanced', false );
253 - }
254 -
255 - /**
256 - * Returns a (hopefully) unique new cache folder name for renaming purposes.
257 - *
258 - * @return string
259 - */
260 - protected static function get_unique_name()
261 - {
262 - $prefix = self::get_advanced_cache_clear_prefix();
263 - $new_name = uniqid( $prefix, true );
264 -
265 - return $new_name;
266 - }
267 -
268 - /**
269 - * Get cache prefix name used in advanced cache clearing mode.
270 - *
271 - * @return string
272 - */
273 - protected static function get_advanced_cache_clear_prefix()
274 - {
275 - $pathname = self::get_pathname_base();
276 - $basename = basename( $pathname );
277 - $prefix = $basename . '-artifact-';
278 -
279 - return $prefix;
280 - }
281 -
282 - /**
283 - * Returns an array of file and directory names found within
284 - * the given $pathname without '.' and '..' elements.
285 - *
286 - * @param string $pathname Pathname.
287 - *
288 - * @return array
289 - */
290 - protected static function get_dir_contents( $pathname )
291 - {
292 - return array_slice( scandir( $pathname ), 2 );
293 - }
294 -
295 - /**
296 - * Wipes directories which were created as part of the fast cache clearing
297 - * routine (which renames the current cache directory into a new one with
298 - * a custom-prefixed unique name).
299 - *
300 - * @return bool
301 - */
302 - public static function delete_advanced_cache_clear_artifacts()
303 - {
304 - // Don't go through these motions (called from the cachechecker) if advanced cache clear isn't even active.
305 - if ( ! self::advanced_cache_clear_enabled() ) {
306 - return false;
307 - }
308 -
309 - $dir = self::get_pathname_base();
310 - $prefix = self::get_advanced_cache_clear_prefix();
311 - $parent = dirname( $dir );
312 - $ok = false;
313 -
314 - // Returns the list of files without '.' and '..' elements.
315 - $files = self::get_dir_contents( $parent );
316 - if ( is_array( $files ) && ! empty( $files ) ) {
317 - foreach ( $files as $file ) {
318 - $path = $parent . '/' . $file;
319 - $prefixed = ( false !== strpos( $path, $prefix ) );
320 - // Removing only our own (prefixed) directories...
321 - if ( is_dir( $path ) && $prefixed ) {
322 - $ok = self::rmdir( $path );
323 - }
324 - }
325 - }
326 -
327 - return $ok;
328 - }
329 -
330 - /**
331 - * Returns the cache directory pathname used.
332 - * Done as a function so we canSlightly different
333 - * if multisite is used and `autoptimize_separate_blog_caches` filter
334 - * is used.
335 - *
336 - * @return string
337 - */
338 - public static function get_pathname()
339 - {
340 - $pathname = self::get_pathname_base();
341 -
342 - if ( is_multisite() && apply_filters( 'autoptimize_separate_blog_caches', true ) ) {
343 - $blog_id = get_current_blog_id();
344 - $pathname .= $blog_id . '/';
345 - }
346 -
347 - return $pathname;
348 - }
349 -
350 - /**
351 - * Returns the base path of our cache directory.
352 - *
353 - * @return string
354 - */
355 - protected static function get_pathname_base()
356 - {
357 - $pathname = WP_CONTENT_DIR . AUTOPTIMIZE_CACHE_CHILD_DIR;
358 -
359 - return $pathname;
360 - }
361 -
362 - /**
363 - * Deletes everything from the cache directories.
364 - *
365 - * @param bool $propagate Whether to trigger additional actions when cache is purged.
366 - *
367 - * @return bool
368 - */
369 - public static function clearall( $propagate = true )
370 - {
371 - if ( ! self::cacheavail() ) {
372 - return false;
373 - }
374 -
375 - // TODO/FIXME: If cache is big, switch to advanced/new cache clearing automatically?
376 - if ( self::advanced_cache_clear_enabled() ) {
377 - self::clear_cache_via_rename();
378 - } else {
379 - self::clear_cache_classic();
380 - }
381 -
382 - // Remove 404 handler if required.
383 - if ( self::do_fallback() ) {
384 - $_fallback_php = trailingslashit( WP_CONTENT_DIR ) . 'autoptimize_404_handler.php';
385 - @unlink( $_fallback_php ); // @codingStandardsIgnoreLine
386 - }
387 -
388 - // Remove the transient so it gets regenerated...
389 - delete_transient( 'autoptimize_stats' );
390 -
391 - // Cache was just purged, clear page cache and allow others to hook into our purging...
392 - if ( true === $propagate ) {
393 - if ( ! function_exists( 'autoptimize_do_cachepurged_action' ) ) {
394 - function autoptimize_do_cachepurged_action() {
395 - do_action( 'autoptimize_action_cachepurged' );
396 - }
397 - }
398 - add_action( 'shutdown', 'autoptimize_do_cachepurged_action', 11 );
399 - add_action( 'autoptimize_action_cachepurged', array( 'autoptimizeCache', 'flushPageCache' ), 10, 0 );
400 - }
401 -
402 - // Warm cache (part of speedupper)!
403 - if ( apply_filters( 'autoptimize_filter_speedupper', true ) && false == get_transient( 'autoptimize_cache_warmer_protector' ) ) {
404 - set_transient( 'autoptimize_cache_warmer_protector', 'I shall not warm cache for another 10 minutes.', 60 * 10 );
405 - $url = site_url() . '/?ao_speedup_cachebuster=' . rand( 1, 100000 );
406 - $url = apply_filters( 'autoptimize_filter_cache_warmer_url', $url );
407 - $cache = @wp_remote_get( $url ); // @codingStandardsIgnoreLine
408 - unset( $cache );
409 - }
410 -
411 - return true;
412 - }
413 -
414 - /**
415 - * Wrapper for clearall but with false param
416 - * to ensure the event is not propagated to others
417 - * through our own hooks (to avoid infinite loops).
418 - *
419 - * @return bool
420 - */
421 - public static function clearall_actionless()
422 - {
423 - return self::clearall( false );
424 - }
425 -
426 - /**
427 - * Returns the contents of our cache dirs.
428 - *
429 - * @return array
430 - */
431 - protected static function get_cache_contents()
432 - {
433 - $contents = array();
434 -
435 - foreach ( array( '', 'js', 'css' ) as $dir ) {
436 - $contents[ $dir ] = scandir( AUTOPTIMIZE_CACHE_DIR . $dir );
437 - }
438 -
439 - return $contents;
440 - }
441 -
442 - /**
443 - * Returns stats about cached contents.
444 - *
445 - * @return array
446 - */
447 - public static function stats()
448 - {
449 - $stats = get_transient( 'autoptimize_stats' );
450 -
451 - // If no transient, do the actual scan!
452 - if ( ! is_array( $stats ) ) {
453 - if ( ! self::cacheavail() ) {
454 - return 0;
455 - }
456 - $stats = self::stats_scan();
457 - $count = $stats[0];
458 - if ( $count > 100 ) {
459 - // Store results in transient.
460 - set_transient(
461 - 'autoptimize_stats',
462 - $stats,
463 - apply_filters( 'autoptimize_filter_cache_statsexpiry', HOUR_IN_SECONDS )
464 - );
465 - }
466 - }
467 -
468 - return $stats;
469 - }
470 -
471 - /**
472 - * Performs a scan of cache directory contents and returns an array
473 - * with 3 values: count, size, timestamp.
474 - * count = total number of found files
475 - * size = total filesize (in bytes) of found files
476 - * timestamp = unix timestamp when the scan was last performed/finished.
477 - *
478 - * @return array
479 - */
480 - protected static function stats_scan()
481 - {
482 - $count = 0;
483 - $size = 0;
484 -
485 - // Scan everything in our cache directories.
486 - foreach ( self::get_cache_contents() as $name => $files ) {
487 - $dir = rtrim( AUTOPTIMIZE_CACHE_DIR . $name, '/' ) . '/';
488 - foreach ( $files as $file ) {
489 - if ( self::is_valid_cache_file( $dir, $file ) ) {
490 - if ( AUTOPTIMIZE_CACHE_NOGZIP &&
491 - (
492 - false !== strpos( $file, '.js' ) ||
493 - false !== strpos( $file, '.css' ) ||
494 - false !== strpos( $file, '.img' ) ||
495 - false !== strpos( $file, '.txt' )
496 - )
497 - ) {
498 - // Web server is gzipping, we count .js|.css|.img|.txt files.
499 - $count++;
500 - } elseif ( ! AUTOPTIMIZE_CACHE_NOGZIP && false !== strpos( $file, '.none' ) ) {
501 - // We are gzipping ourselves via php, counting only .none files.
502 - $count++;
503 - }
504 - $size += filesize( $dir . $file );
505 - }
506 - }
507 - }
508 -
509 - $stats = array( $count, $size, time() );
510 -
511 - return $stats;
512 - }
513 -
514 - /**
515 - * Ensures the cache directory exists, is writeable and contains the
516 - * required .htaccess files.
517 - * Returns false in case it fails to ensure any of those things.
518 - *
519 - * @return bool
520 - */
521 - public static function cacheavail()
522 - {
523 - if ( false === autoptimizeCache::check_and_create_dirs() ) {
524 - return false;
525 - }
526 -
527 - // Using .htaccess inside our cache folder to overrule wp-super-cache.
528 - $htaccess = AUTOPTIMIZE_CACHE_DIR . '/.htaccess';
529 - if ( ! is_file( $htaccess ) ) {
530 - /**
531 - * Create `wp-content/AO_htaccess_tmpl` file with
532 - * whatever htaccess rules you might need
533 - * if you want to override default AO htaccess
534 - */
535 - $htaccess_tmpl = WP_CONTENT_DIR . '/AO_htaccess_tmpl';
536 - if ( is_file( $htaccess_tmpl ) ) {
537 - $content = file_get_contents( $htaccess_tmpl );
538 - } elseif ( is_multisite() || ! AUTOPTIMIZE_CACHE_NOGZIP ) {
539 - $content = '<IfModule mod_expires.c>
540 - ExpiresActive On
541 - ExpiresByType text/css A30672000
542 - ExpiresByType text/javascript A30672000
543 - ExpiresByType application/javascript A30672000
544 -</IfModule>
545 -<IfModule mod_headers.c>
546 - Header append Cache-Control "public, immutable"
547 -</IfModule>
548 -<IfModule mod_deflate.c>
549 - <FilesMatch "\.(js|css)$">
550 - SetOutputFilter DEFLATE
551 - </FilesMatch>
552 -</IfModule>
553 -<IfModule mod_authz_core.c>
554 - <Files *.php>
555 - Require all granted
556 - </Files>
557 -</IfModule>
558 -<IfModule !mod_authz_core.c>
559 - <Files *.php>
560 - Order allow,deny
561 - Allow from all
562 - </Files>
563 -</IfModule>';
564 - } else {
565 - $content = '<IfModule mod_expires.c>
566 - ExpiresActive On
567 - ExpiresByType text/css A30672000
568 - ExpiresByType text/javascript A30672000
569 - ExpiresByType application/javascript A30672000
570 -</IfModule>
571 -<IfModule mod_headers.c>
572 - Header append Cache-Control "public, immutable"
573 -</IfModule>
574 -<IfModule mod_deflate.c>
575 - <FilesMatch "\.(js|css)$">
576 - SetOutputFilter DEFLATE
577 - </FilesMatch>
578 -</IfModule>
579 -<IfModule mod_authz_core.c>
580 - <Files *.php>
581 - Require all denied
582 - </Files>
583 -</IfModule>
584 -<IfModule !mod_authz_core.c>
585 - <Files *.php>
586 - Order deny,allow
587 - Deny from all
588 - </Files>
589 -</IfModule>';
590 - }
591 -
592 - if ( self::do_fallback() ) {
593 - $content .= "\nErrorDocument 404 " . trailingslashit( parse_url( content_url(), PHP_URL_PATH ) ) . 'autoptimize_404_handler.php';
594 - }
595 - @file_put_contents( $htaccess, $content ); // @codingStandardsIgnoreLine
596 - }
597 -
598 - if ( self::do_fallback() ) {
599 - self::check_fallback_php();
600 - }
601 -
602 - // All OK!
603 - return true;
604 - }
605 -
606 - /**
607 - * Checks if fallback-php file exists and create it if not.
608 - *
609 - * Return bool
610 - */
611 - public static function check_fallback_php() {
612 - $_fallback_filename = 'autoptimize_404_handler.php';
613 - $_fallback_php = trailingslashit( WP_CONTENT_DIR ) . $_fallback_filename;
614 - $_fallback_status = true;
615 -
616 - if ( ! file_exists( $_fallback_php ) ) {
617 - $_fallback_php_contents = file_get_contents( AUTOPTIMIZE_PLUGIN_DIR . 'config/' . $_fallback_filename );
618 - $_fallback_php_contents = str_replace( '<?php exit;', '<?php', $_fallback_php_contents );
619 - $_fallback_php_contents = str_replace( '<!--ao-cache-dir-->', AUTOPTIMIZE_CACHE_DIR, $_fallback_php_contents );
620 - if ( apply_filters( 'autoptimize_filter_cache_fallback_log_errors', false ) ) {
621 - $_fallback_php_contents = str_replace( '// error_log', 'error_log', $_fallback_php_contents );
622 - }
623 - $_fallback_status = file_put_contents( $_fallback_php, $_fallback_php_contents );
624 - }
625 -
626 - return $_fallback_status;
627 - }
628 -
629 - /**
630 - * 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.
632 - *
633 - * Return bool
634 - */
635 - public static function do_fallback() {
636 - return apply_filters( 'autoptimize_filter_cache_do_fallback', false );
637 - }
638 -
639 - /**
640 - * Checks if cache dirs exist and create if not.
641 - * Returns false if not succesful.
642 - *
643 - * @return bool
644 - */
645 - public static function check_and_create_dirs() {
646 - if ( ! defined( 'AUTOPTIMIZE_CACHE_DIR' ) ) {
647 - // We didn't set a cache.
648 - return false;
649 - }
650 -
651 - foreach ( array( '', 'js', 'css' ) as $dir ) {
652 - if ( ! self::check_cache_dir( AUTOPTIMIZE_CACHE_DIR . $dir ) ) {
653 - return false;
654 - }
655 - }
656 - return true;
657 - }
658 -
659 - /**
660 - * Ensures the specified `$dir` exists and is writeable.
661 - * Returns false if that's not the case.
662 - *
663 - * @param string $dir Directory to check/create.
664 - *
665 - * @return bool
666 - */
667 - protected static function check_cache_dir( $dir )
668 - {
669 - // Try creating the dir if it doesn't exist.
670 - if ( ! file_exists( $dir ) ) {
671 - @mkdir( $dir, 0775, true ); // @codingStandardsIgnoreLine
672 - if ( ! file_exists( $dir ) ) {
673 - return false;
674 - }
675 - }
676 -
677 - // If we still cannot write, bail.
678 - if ( ! is_writable( $dir ) ) {
679 - return false;
680 - }
681 -
682 - // Create an index.html in there to avoid prying eyes!
683 - $idx_file = rtrim( $dir, '/\\' ) . '/index.html';
684 - if ( ! is_file( $idx_file ) ) {
685 - @file_put_contents( $idx_file, '<html><head><meta name="robots" content="noindex, nofollow"></head><body>Generated by <a href="http://wordpress.org/extend/plugins/autoptimize/" rel="nofollow">Autoptimize</a></body></html>' ); // @codingStandardsIgnoreLine
686 - }
687 -
688 - return true;
689 - }
690 -
691 - /**
692 - * Flushes as many page cache plugin's caches as possible.
693 - *
694 - * @return void
695 - */
696 - // @codingStandardsIgnoreStart
697 - public static function flushPageCache()
698 - {
699 - if ( function_exists( 'wp_cache_clear_cache' ) ) {
700 - if ( is_multisite() ) {
701 - $blog_id = get_current_blog_id();
702 - wp_cache_clear_cache( $blog_id );
703 - } else {
704 - wp_cache_clear_cache();
705 - }
706 - } elseif ( has_action( 'cachify_flush_cache' ) ) {
707 - do_action( 'cachify_flush_cache' );
708 - } elseif ( function_exists( 'w3tc_pgcache_flush' ) ) {
709 - w3tc_pgcache_flush();
710 - } elseif ( function_exists( 'wp_fast_cache_bulk_delete_all' ) ) {
711 - wp_fast_cache_bulk_delete_all();
712 - } elseif ( class_exists( 'WpFastestCache' ) ) {
713 - $wpfc = new WpFastestCache();
714 - $wpfc->deleteCache();
715 - } elseif ( class_exists( 'c_ws_plugin__qcache_purging_routines' ) ) {
716 - c_ws_plugin__qcache_purging_routines::purge_cache_dir(); // quick cache
717 - } elseif ( class_exists( 'zencache' ) ) {
718 - zencache::clear();
719 - } elseif ( class_exists( 'comet_cache' ) ) {
720 - comet_cache::clear();
721 - } elseif ( class_exists( 'WpeCommon' ) ) {
722 - // WPEngine cache purge/flush methods to call by default
723 - $wpe_methods = array(
724 - 'purge_varnish_cache',
725 - );
726 -
727 - // More agressive clear/flush/purge behind a filter
728 - if ( apply_filters( 'autoptimize_flush_wpengine_aggressive', false ) ) {
729 - $wpe_methods = array_merge( $wpe_methods, array( 'purge_memcached', 'clear_maxcdn_cache' ) );
730 - }
731 -
732 - // Filtering the entire list of WpeCommon methods to be called (for advanced usage + easier testing)
733 - $wpe_methods = apply_filters( 'autoptimize_flush_wpengine_methods', $wpe_methods );
734 -
735 - foreach ( $wpe_methods as $wpe_method ) {
736 - if ( method_exists( 'WpeCommon', $wpe_method ) ) {
737 - WpeCommon::$wpe_method();
738 - }
739 - }
740 - } elseif ( function_exists( 'sg_cachepress_purge_cache' ) ) {
741 - sg_cachepress_purge_cache();
742 - } elseif ( array_key_exists( 'KINSTA_CACHE_ZONE', $_SERVER ) ) {
743 - $_kinsta_clear_cache_url = 'https://localhost/kinsta-clear-cache-all';
744 - $_kinsta_response = wp_remote_get(
745 - $_kinsta_clear_cache_url,
746 - array(
747 - 'sslverify' => false,
748 - 'timeout' => 5,
749 - )
750 - );
751 - } elseif ( defined('NGINX_HELPER_BASENAME') ) {
752 - do_action( 'rt_nginx_helper_purge_all' );
753 - } elseif ( file_exists( WP_CONTENT_DIR . '/wp-cache-config.php' ) && function_exists( 'prune_super_cache' ) ) {
754 - // fallback for WP-Super-Cache
755 - global $cache_path;
756 - if ( is_multisite() ) {
757 - $blog_id = get_current_blog_id();
758 - prune_super_cache( get_supercache_dir( $blog_id ), true );
759 - prune_super_cache( $cache_path . 'blogs/', true );
760 - } else {
761 - prune_super_cache( $cache_path . 'supercache/', true );
762 - prune_super_cache( $cache_path, true );
763 - }
764 - }
765 - }
766 - // @codingStandardsIgnoreEnd
108 + //Count cached info
109 + $count = 0;
110 + $scan = scandir(AUTOPTIMIZE_CACHE_DIR);
111 + foreach($scan as $file)
112 + {
113 + if(!in_array($file,array('.','..')) && strpos($file,'autoptimize') !== false)
114 + {
115 + if(is_file(AUTOPTIMIZE_CACHE_DIR.$file))
116 + {
117 + if(AUTOPTIMIZE_CACHE_NOGZIP && (strpos($file,'.js') !== false || strpos($file,'.css') !== false))
118 + {
119 + $count++;
120 + }elseif(!AUTOPTIMIZE_CACHE_NOGZIP && strpos($file,'.none') !== false){
121 + $count++;
122 + }/*else{
123 + //Tricky one... it was a dir or a gzip/deflate file
124 + }*/
125 + }
126 + }
127 + }
128 +
129 + //Tell the number of instances
130 + return $count;
131 + }
132 +
133 + static function cacheavail()
134 + {
135 + if(!defined('AUTOPTIMIZE_CACHE_DIR'))
136 + {
137 + //We didn't set a cache
138 + return false;
139 + }
140 +
141 + //Check for existence
142 + if(!file_exists(AUTOPTIMIZE_CACHE_DIR))
143 + {
144 + @mkdir(AUTOPTIMIZE_CACHE_DIR,0775,true);
145 + if(!file_exists(AUTOPTIMIZE_CACHE_DIR))
146 + {
147 + //Where should we cache?
148 + return false;
149 + }
150 + }
151 +
152 + if(!is_writable(AUTOPTIMIZE_CACHE_DIR))
153 + {
154 + //How are we supposed to write?
155 + return false;
156 + }
157 +
158 + //All OK
159 + return true;
160 + }
767 161 }