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