PluginProbe
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score / 1.2.4
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score v1.2.4
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 / class-powered-cache-config.php

class-powered-cache-config.php in Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score 1.2.4, at includes/class-powered-cache-config.php

799 lines 26.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 class Powered_Cache_Config {
8
9
10 /**
11 * Return an instance of the current class
12 *
13 * @since 1.0
14 * @since 1.1 initialize WP_Filesystem_Direct
15 * @return Powered_Cache_Config
16 */
17 public static function factory() {
18 static $instance = false;
19
20 if ( ! $instance ) {
21 $instance = new self();
22 global $powered_cache_fs;
23
24 if ( ! $powered_cache_fs ) {
25 include_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
26 include_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
27
28 if ( ! defined( 'FS_CHMOD_DIR' ) ) {
29 define( 'FS_CHMOD_DIR', ( fileperms( ABSPATH ) & 0777 | 0755 ) );
30 }
31
32 if ( ! defined( 'FS_CHMOD_FILE' ) ) {
33 define( 'FS_CHMOD_FILE', ( fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 ) );
34 }
35
36 $powered_cache_fs = new WP_Filesystem_Direct( new StdClass() );
37 }
38 }
39
40 return $instance;
41 }
42
43 /**
44 * placeholder
45 *
46 * @since 1.0
47 */
48 public function __construct() { }
49
50
51 /**
52 * Default options
53 *
54 * @since 1.0
55 * @return mixed|void
56 */
57 public function default_settings() {
58 $settings = array(
59 // basic options
60 'enable_page_caching' => false,
61 'configure_htaccess' => true,
62 'object_cache' => 'off',
63 'cache_mobile' => true,
64 'cache_mobile_separate_file' => false,
65 'loggedin_user_cache' => false,
66 'ssl_cache' => true,
67 'gzip_compression' => false,
68 'cache_timeout' => 1440,
69 'cache_location' => powered_cache_get_cache_dir(),
70 // advanced options
71 'remove_query_string' => false,
72 'rejected_user_agents' => '',
73 'rejected_cookies' => '',
74 'rejected_uri' => '',
75 'accepted_query_strings' => '',
76 'purge_additional_pages' => '',
77 // cdn
78 'cdn_status' => false,
79 'cdn_hostname' => array(),
80 'cdn_zone' => array(),
81 'cdn_rejected_files' => '',
82 // skip extensions, we don't need default for them
83 // misc
84 'show_cache_message' => true,
85 );
86
87
88 return apply_filters( 'powered_cache_default_settings', $settings );
89 }
90
91 /**
92 * Generates advanced-cache.php
93 *
94 * @since 1.0
95 * @since 1.1 is_multisite control added
96 * @return bool
97 */
98 public function generate_advanced_cache_file() {
99 global $powered_cache_fs;
100
101 $file = untrailingslashit( WP_CONTENT_DIR ) . '/advanced-cache.php';
102
103
104 $file_string = '';
105
106 /**
107 * multisite setups should always have `advanced-cache.php` file
108 */
109 if ( true === powered_cache_get_option( 'enable_page_caching' ) || is_multisite() ) {
110 $file_string = $this->advanced_cache_file_content();
111 }
112
113 if ( ! $powered_cache_fs->put_contents( $file, $file_string, FS_CHMOD_FILE ) ) {
114 return false;
115 }
116
117 return true;
118 }
119
120
121 /**
122 * Setup object-cache.php
123 *
124 * @since 1.0
125 * @param string $backend
126 *
127 * @return bool
128 */
129 public function setup_object_cache( $backend = 'off' ) {
130 global $powered_cache_fs;
131
132 $file = untrailingslashit( WP_CONTENT_DIR ) . '/object-cache.php';
133
134 if ( is_multisite() && ! current_user_can( 'manage_network' ) ) {
135 return false;
136 }
137
138 if ( 'off' === $backend ) {
139 if ( $powered_cache_fs->exists( $file ) ) {
140 $powered_cache_fs->delete( $file ); // remove object cache file
141 }
142
143 return true;
144 }
145
146 $file_string = $this->object_cache_file_content( $backend );
147
148 if ( ! $powered_cache_fs->put_contents( $file, $file_string, FS_CHMOD_FILE ) ) {
149 return false;
150 }
151
152 return true;
153 }
154
155
156 /**
157 * Generate advanced-cache.php and define WP_CACHE
158 *
159 * @since 1.0
160 *
161 * @param $status
162 *
163 * @return bool
164 */
165 public function setup_page_cache( $status ) {
166
167 /**
168 * Forcing multisite settings always true
169 */
170 if ( is_multisite() ) {
171 $status = true;
172 }
173
174 Powered_Cache_Config::factory()->generate_advanced_cache_file();
175 Powered_Cache_Config::factory()->define_wp_cache( $status );
176 Powered_Cache_Config::factory()->configure_htaccess( $status );
177 Powered_Cache_Config::factory()->protect_cache_dir();
178
179 return true;
180 }
181
182
183 /**
184 * object-cache.php contents
185 *
186 * @since 1.0
187 * @since 1.1 supports `POWERED_CACHE_OBJECT_CACHE_DROPIN`
188 * @param $backend
189 * @see Powered_Cache_Admin_Helper::object_cache_dropins
190 *
191 * @return mixed|void
192 */
193 public function object_cache_file_content( $backend ) {
194 $string = '<?php ' . "\n";
195 $string .= "defined( 'ABSPATH' ) || exit;" . PHP_EOL;
196 $string .= "define( 'POWERED_OBJECT_CACHE', true );" . PHP_EOL;
197 $string .= "if ( ! @file_exists( WP_CONTENT_DIR . '/pc-config/config-' . \$_SERVER['HTTP_HOST'] . '.php' ) ) { return; }" . PHP_EOL;
198
199 $object_caches = Powered_Cache_Admin_Helper::object_cache_dropins();
200
201 $string .= "\$GLOBALS['powered_cache_options'] = include( WP_CONTENT_DIR . '/pc-config/config-' . \$_SERVER['HTTP_HOST'] . '.php' );" . "\n\n";
202 $string .= 'if ( defined( \'POWERED_CACHE_OBJECT_CACHE_DROPIN\') && @file_exists( POWERED_CACHE_OBJECT_CACHE_DROPIN ) ) {' . PHP_EOL;
203 $string .= "\t" . 'include( POWERED_CACHE_OBJECT_CACHE_DROPIN );' . PHP_EOL;
204 $string .= '} elseif ( @file_exists( \'' . $object_caches[ $backend ] . '\' ) ) {' . PHP_EOL;
205 $string .= "\t" . 'include( \'' . $object_caches[ $backend ] . '\' );' . PHP_EOL;
206 $string .= '} else {' . PHP_EOL;
207 $string .= "\t" . 'define( \'POWERED_OBJECT_CACHE_HAS_PROBLEM\', true );' . PHP_EOL;
208 $string .= '}';
209
210 return apply_filters( 'powered_cache_object_cache_file_content', $string );
211 }
212
213
214 /**
215 * Prepare advanced-cache.php contents
216 *
217 * @since 1.0
218 * @since 1.1 supports `POWERED_CACHE_ADVANCED_CACHE_DROPIN`
219 * @return mixed|void
220 */
221 public function advanced_cache_file_content(){
222
223 $string = '<?php ' . PHP_EOL;
224 $string .= "defined( 'ABSPATH' ) || exit;" . PHP_EOL;
225 $string .= "define( 'POWERED_CACHE_PAGE_CACHING', true );" . PHP_EOL;
226
227 $string .= "\$config_file = WP_CONTENT_DIR . '/pc-config/config-' . \$_SERVER['HTTP_HOST'];" . PHP_EOL . PHP_EOL;
228
229 $string .= "if ( is_multisite() && ( defined( 'SUBDOMAIN_INSTALL' ) && false === SUBDOMAIN_INSTALL ) ) {" . PHP_EOL;
230 $string .= "\t" . "\$request_uri = explode( '/', ltrim( \$_SERVER['REQUEST_URI'], '/' ) );" . PHP_EOL;
231 $string .= "\t" . "\$sub_site_name = \$request_uri[0];" . PHP_EOL;
232 $string .= "\t" . "\$config_file .= '-'.\$sub_site_name;" . PHP_EOL;
233 $string .= "}" . PHP_EOL;
234 $string .= "\$config_file .= '.php';" . PHP_EOL;
235
236
237 $string .= "if ( ! @file_exists( \$config_file ) ) { return; }" . PHP_EOL;
238 // get config file
239 $string .= "\$GLOBALS['powered_cache_options'] = include( \$config_file );" . PHP_EOL . PHP_EOL;
240 // mobile cache varibales
241 $string .= '$powered_cache_mobile_browsers = ' . var_export( powered_cache_mobile_browsers(), true ) . ";" . PHP_EOL;
242 $string .= '$powered_cache_mobile_prefixes = ' . var_export( powered_cache_mobile_prefixes(), true ) . ";" . PHP_EOL;
243
244 if ( substr( get_option( 'permalink_structure' ), - 1 ) == '/' ) {
245 $string .= '$powered_cache_slash_check = true;' . PHP_EOL;
246 } else {
247 $string .= '$powered_cache_slash_check = false;' . PHP_EOL;
248 }
249
250 $string .= 'if ( defined( \'POWERED_CACHE_ADVANCED_CACHE_DROPIN\') && @file_exists( POWERED_CACHE_ADVANCED_CACHE_DROPIN ) ) {' . PHP_EOL;
251 $string .= "\t" . 'include( POWERED_CACHE_ADVANCED_CACHE_DROPIN );' . PHP_EOL;
252 $string .= '} elseif ( @file_exists( \'' . POWERED_CACHE_DROPIN_DIR . 'page-cache.php' . '\' ) ) {' . PHP_EOL;
253 $string .= "\t" . 'include( \'' . POWERED_CACHE_DROPIN_DIR . 'page-cache.php' . '\' );' . PHP_EOL;
254 $string .= '} else {' . PHP_EOL;
255 $string .= "\t" . 'define( \'POWERED_CACHE_PAGE_CACHING_HAS_PROBLEM\', true );' . PHP_EOL;
256 $string .= '}';
257
258
259 return apply_filters( 'powered_cache_advanced_cache_file_content', $string );
260 }
261
262 /**
263 * Define WP_CACHE constant
264 *
265 * @since 1.0
266 * @param $status
267 *
268 * @return bool
269 */
270 public function define_wp_cache( $status ) {
271 global $powered_cache_fs;
272 $config_path = $this->find_wp_config_file();
273
274 if ( ! $config_path ) {
275 return false;
276 }
277
278
279 if ( defined( 'WP_CACHE' ) && WP_CACHE === $status ) {
280 return true;
281 }
282
283 $config_file_string = $powered_cache_fs->get_contents( $config_path );
284
285 // Config file is empty. Maybe couldn't read it?
286 if ( empty( $config_file_string ) ) {
287 return false;
288 }
289
290 $config_file = preg_split( "#(\r\n|\r|\n)#", $config_file_string );
291 $line_key = false;
292
293 foreach ( $config_file as $key => $line ) {
294 if ( ! preg_match( '/^\s*define\(\s*(\'|")([A-Z_]+)(\'|")(.*)/', $line, $match ) ) {
295 continue;
296 }
297
298 if ( $match[2] == 'WP_CACHE' ) {
299 $line_key = $key;
300 }
301 }
302
303 if ( $line_key !== false ) {
304 unset( $config_file[ $line_key ] );
305 }
306
307 $status_string = ( $status ) ? 'true' : 'false';
308
309 array_shift( $config_file );
310 array_unshift( $config_file, '<?php', "define( 'WP_CACHE', $status_string ); // Powered Cache" );
311
312 foreach ( $config_file as $key => $line ) {
313 if ( '' === $line ) {
314 unset( $config_file[$key] );
315 }
316 }
317
318 if ( ! $powered_cache_fs->put_contents( $config_path, implode( PHP_EOL, $config_file ), FS_CHMOD_FILE ) ) {
319 return false;
320 }
321
322 return true;
323 }
324
325
326 /**
327 * seeking wp-config file
328 *
329 * @since 1.0
330 *
331 * @return bool|string
332 */
333 public function find_wp_config_file() {
334 global $powered_cache_fs;
335
336 $file = '/wp-config.php';
337
338 for ( $i = 1; $i <= 3; $i ++ ) {
339 if ( $i > 1 ) {
340 $file = '/..' . $file;
341 }
342
343 if ( $powered_cache_fs->exists( untrailingslashit( ABSPATH ) . $file ) ) {
344 $config_path = untrailingslashit( ABSPATH ) . $file;
345 break;
346 }
347 }
348
349 if ( ! isset( $config_path ) ) {
350 return false;
351 }
352
353 return $config_path;
354 }
355
356 /**
357 * Save settings to file
358 *
359 * @since 1.0
360 * @param $configuration
361 *
362 * @return bool
363 */
364 public function save_to_file( $configuration ) {
365 global $powered_cache_fs;
366
367 $config_dir = WP_CONTENT_DIR . '/pc-config';
368
369 $site_url_parts = parse_url( site_url() );
370 $config_file_name = $site_url_parts['host'];
371
372 if ( is_multisite() && ( defined( 'SUBDOMAIN_INSTALL' ) && false === SUBDOMAIN_INSTALL ) ) {
373 if ( is_main_site( get_current_blog_id() ) ) {
374 $config_file_name .= '-blog';
375 } else {
376 $subdir_name = ltrim( parse_url( get_site_url( get_current_blog_id() ), PHP_URL_PATH ), '/' );
377 $config_file_name .= '-' . $subdir_name;
378 }
379 }
380
381
382 $config_file = $config_dir . '/config-' . $config_file_name . '.php';
383
384 $configuration['cache_location'] = powered_cache_get_cache_dir();
385
386 $powered_cache_fs->mkdir( $config_dir );
387
388 $config_file_string = '<?php' . PHP_EOL . "defined( 'ABSPATH' ) || exit;" . PHP_EOL . 'return ' . var_export( $configuration, true ) . ';' . PHP_EOL;
389
390 if ( ! $powered_cache_fs->put_contents( $config_file, $config_file_string, FS_CHMOD_FILE ) ) {
391 return false;
392 }
393
394 return true;
395 }
396
397 /**
398 * Create .htaccess file based on current setting preferences
399 *
400 * @since 1.0
401 * @return bool
402 */
403 public function configure_htaccess( $enable = true ) {
404 global $powered_cache_fs;
405 $htaccess_file = get_home_path() . '.htaccess';
406
407 /**
408 * Users might want to control .htaccess manually
409 *
410 * @since 1.1.1
411 */
412 if ( true !== apply_filters( 'powered_cache_auto_htaccess_update', true ) ) {
413 return false;
414 }
415
416 /**
417 * Apache users can control automatic configuration
418 *
419 * @since 1.2
420 */
421 $automatic_configuration = powered_cache_get_option( 'configure_htaccess' );
422
423 if ( ! $automatic_configuration ) {
424 return false;
425 }
426
427 if ( $powered_cache_fs->is_writable( $htaccess_file ) ) {
428 $contents = $powered_cache_fs->get_contents( $htaccess_file );
429
430 //clean up
431 $contents = preg_replace( '/# BEGIN POWERED CACHE(.*)# END POWERED CACHE/is', '', $contents );
432
433 if ( false === $enable ) {
434 return $powered_cache_fs->put_contents( $htaccess_file, $contents, FS_CHMOD_FILE );
435 }
436
437 $rules = $this->htaccess_rules();
438 $contents = $rules . $contents;
439
440 // Update the .htacces file
441 if ( ! $powered_cache_fs->put_contents( $htaccess_file, $contents, FS_CHMOD_FILE ) ) {
442 return false;
443 }
444
445 return true;
446 }
447
448 return false;
449 }
450
451
452 /**
453 * Prepares .htaccess rules for the caching
454 *
455 * @since 1.1
456 * @return string $rules
457 */
458 public function htaccess_rules() {
459 $rules = '';
460
461 /**
462 * @since 1.1 $contents parameter removed
463 */
464 $rules .= apply_filters( 'powered_cache_pre_htaccess', '' );
465
466 $rules .= '# BEGIN POWERED CACHE' . PHP_EOL;
467
468 // todo set option here.
469 if ( apply_filters( 'powered_cache_browser_cache', true ) ) {
470 $wp_mime_types = wp_get_mime_types();
471 $mime_types = array_flip( $wp_mime_types );
472 //mimes
473 $rules .= '<IfModule mod_mime.c>' . PHP_EOL;
474 foreach ( $mime_types as $mime_type => $ext ) {
475 $ext_str = '.' . str_replace( '|', ' .', $ext );
476 $rules .= " AddType " . $mime_type . " " . $ext_str . PHP_EOL;
477 }
478 $rules .= "</IfModule>" . PHP_EOL;
479
480 // set expire time
481
482 $rules .= '<IfModule mod_expires.c>' . PHP_EOL;
483 $rules .= " ExpiresActive On" . PHP_EOL;
484 $rules .= ' ExpiresByType text/html "access plus 0 seconds"' . PHP_EOL;
485 $rules .= ' ExpiresByType text/richtext "access plus 0 seconds"' . PHP_EOL;
486 $rules .= ' ExpiresByType text/plain "access plus 0 seconds"' . PHP_EOL;
487 $rules .= ' ExpiresByType text/xsd "access plus 0 seconds"' . PHP_EOL;
488 $rules .= ' ExpiresByType text/xsl "access plus 0 seconds"' . PHP_EOL;
489 $rules .= ' ExpiresByType text/xml "access plus 0 seconds"' . PHP_EOL;
490 $rules .= ' ExpiresByType text/cache-manifest "access plus 0 seconds"' . PHP_EOL;
491
492 foreach ( $mime_types as $mime_type => $ext ) {
493
494 if ( in_array( $mime_type, array( 'text/html', 'text/richtext', 'text/plain', 'text/xsd', 'text/xsl', 'text/xml', 'text/cache-manifest' ) ) ) {
495 continue;
496 }
497
498 /**
499 * Apache allow both format like A2592000 => "access plus 1 month"
500 * A => access, M => Modified
501 *
502 * @see http://httpd.apache.org/docs/current/mod/mod_expires.html
503 */
504 if ( in_array( $mime_type, array( 'text/css', 'application/javascript' ) ) ) {
505 $expiry_time = apply_filters( 'powered_cache_browser_cache_assets_lifespan', 'access plus 1 year' );
506 } else {
507 $expiry_time = apply_filters( 'powered_cache_browser_cache_default_lifespan', 'access plus 1 month' );
508 }
509 $rules .= ' ExpiresByType ' . $mime_type . ' "' . $expiry_time . '"' . PHP_EOL;
510 }
511
512 $rules .= ' ExpiresByType application/x-font-ttf "access plus 1 month"' . PHP_EOL;
513 $rules .= ' ExpiresByType application/x-font-woff "access plus 1 month"' . PHP_EOL;
514 $rules .= ' ExpiresByType application/x-font-woff2 "access plus 1 month"' . PHP_EOL;
515 $rules .= ' ExpiresByType font/opentype "access plus 1 month"' . PHP_EOL;
516 $rules .= ' ExpiresByType application/vnd.ms-fontobject "access plus 1 month"' . PHP_EOL;
517 $rules .= ' ExpiresByType application/font-sfnt "access plus 1 month"' . PHP_EOL;
518 $rules .= ' ExpiresByType image/svg+xml "access plus 1 month"' . PHP_EOL;
519
520
521 $rules .= "</IfModule>" . PHP_EOL;
522
523 }
524
525
526 // gzip
527 $rules .= '<IfModule mod_deflate.c>' . PHP_EOL;
528 $rules .= ' <IfModule mod_headers.c>' . PHP_EOL;
529 $rules .= ' Header append Vary User-Agent env=!dont-vary' . PHP_EOL;
530 $rules .= ' </IfModule>' . PHP_EOL;
531 $rules .= ' AddOutputFilterByType DEFLATE text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/html text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/bmp application/java application/msword application/vnd.ms-fontobject application/x-msdownload image/x-icon application/json application/vnd.ms-access application/vnd.ms-project application/x-font-otf application/vnd.ms-opentype application/vnd.oasis.opendocument.database application/vnd.oasis.opendocument.chart application/vnd.oasis.opendocument.formula application/vnd.oasis.opendocument.graphics application/vnd.oasis.opendocument.presentation application/vnd.oasis.opendocument.spreadsheet application/vnd.oasis.opendocument.text audio/ogg application/pdf application/vnd.ms-powerpoint application/x-shockwave-flash image/tiff application/x-font-ttf application/vnd.ms-opentype audio/wav application/vnd.ms-write application/font-woff application/font-woff2 application/vnd.ms-excel' . PHP_EOL;
532 $rules .= ' <IfModule mod_mime.c>' . PHP_EOL;
533 $rules .= ' AddOutputFilter DEFLATE js css htm html xml' . PHP_EOL;
534 $rules .= ' </IfModule>' . PHP_EOL;
535 $rules .= '</IfModule>' . PHP_EOL;
536
537
538 if ( true === powered_cache_get_option( 'gzip_compression' ) ) {
539 $rules .= '<IfModule mod_mime.c>' . PHP_EOL;
540 $rules .= ' AddType text/html .html_gzip' . PHP_EOL;
541 $rules .= ' AddEncoding gzip .html_gzip' . PHP_EOL;
542 $rules .= '</IfModule>' . PHP_EOL;
543 $rules .= '<IfModule mod_setenvif.c>' . PHP_EOL;
544 $rules .= ' SetEnvIfNoCase Request_URI \.html_gzip$ no-gzip' . PHP_EOL;
545 $rules .= '</IfModule>'.PHP_EOL;
546 }
547
548
549 // remove etag
550 $rules .= '<IfModule mod_headers.c>' . PHP_EOL;
551 $rules .= 'Header unset ETag' . PHP_EOL;
552 $rules .= '</IfModule>' . PHP_EOL . PHP_EOL;
553
554
555 // rewrite
556
557 $env_powered_cache_ua = '';
558 $env_powered_cache_ssl = '';
559 $env_powered_cache_enc = '';
560
561
562 $rewrite_base = parse_url( home_url() );
563 $rewrite_base = isset( $rewrite_base['path'] ) ? trailingslashit( $rewrite_base['path'] ) : '/';
564
565 $rules .= '<IfModule mod_rewrite.c>' . PHP_EOL;
566 $rules .= ' RewriteEngine On' . PHP_EOL;
567 $rules .= ' RewriteBase ' . $rewrite_base . PHP_EOL;
568 $rules .= ' AddDefaultCharset UTF-8 ' . PHP_EOL;
569
570
571 if ( true === powered_cache_get_option( 'cache_mobile' ) && true === powered_cache_get_option( 'cache_mobile_separate_file' ) ) {
572 $mobile_browsers = addcslashes( implode( '|', preg_split( '/[\s*,\s*]*,+[\s*,\s*]*/', powered_cache_mobile_browsers() ) ), ' ' );
573 $mobile_prefixes = addcslashes( implode( '|', preg_split( '/[\s*,\s*]*,+[\s*,\s*]*/', powered_cache_mobile_prefixes() ) ), ' ' );
574 // mobile env set
575 $rules .= " RewriteCond %{HTTP_USER_AGENT} (" . $mobile_browsers . ") [NC]" . PHP_EOL;
576 $rules .= " RewriteRule .* - [E=PC_UA:-mobile]" . PHP_EOL;
577 $rules .= " RewriteCond %{HTTP_USER_AGENT} ^(" . $mobile_prefixes . ") [NC]" . PHP_EOL;
578 $rules .= " RewriteRule .* - [E=PC_UA:-mobile]" . PHP_EOL;
579 $env_powered_cache_ua = '%{ENV:PC_UA}';
580 }
581
582 if ( true === powered_cache_get_option( 'ssl_cache' ) ) {
583 $rules .= " RewriteCond %{HTTPS} =on" . PHP_EOL;
584 $rules .= " RewriteRule .* - [E=PC_SSL:-https]" . PHP_EOL;
585 $rules .= " RewriteCond %{SERVER_PORT} =443" . PHP_EOL;
586 $rules .= " RewriteRule .* - [E=PC_SSL:-https]" . PHP_EOL;
587 $rules .= " RewriteCond %{HTTP:X-Forwarded-Proto} https" . PHP_EOL;
588 $rules .= " RewriteRule .* - [E=PC_SSL:-https]" . PHP_EOL;
589 $env_powered_cache_ssl = '%{ENV:PC_SSL}';
590 }
591
592 if ( true === powered_cache_get_option( 'gzip_compression' ) ) {
593 $rules .= " RewriteCond %{HTTP:Accept-Encoding} gzip" . PHP_EOL;
594 $rules .= " RewriteRule .* - [E=PC_ENC:_gzip]" . PHP_EOL;
595 $env_powered_cache_enc = '%{ENV:PC_ENC}';
596 }
597
598 $rules .= " RewriteCond %{REQUEST_METHOD} !=POST" . PHP_EOL;
599 $rules .= ' RewriteCond %{QUERY_STRING} =""' . PHP_EOL;
600
601 if ( substr( get_option( 'permalink_structure' ), - 1 ) == '/' ) {
602 $rules .= " RewriteCond %{REQUEST_URI} !^.*[^/]$" . PHP_EOL;
603 $rules .= " RewriteCond %{REQUEST_URI} !^.*//.*$" . PHP_EOL;
604 }
605
606 // Get root base
607 $site_root = parse_url( site_url() );
608 $site_root = isset( $site_root['path'] ) ? trailingslashit( $site_root['path'] ) : '';
609
610
611 // reject user agent
612 if ( false !== powered_cache_get_option( 'rejected_user_agents' ) ) {
613 $rejected_user_agents = preg_split( '#(\r\n|\r|\n)#', powered_cache_get_option( 'rejected_user_agents' ) );
614 if ( ! empty( $rejected_user_agents ) ) {
615 $rules .= ' RewriteCond %{HTTP_USER_AGENT} !^(' . implode( '|', $rejected_user_agents ) . ').* [NC]' . PHP_EOL;
616 }
617 }
618
619
620 // ignore cookies
621 if ( false !== powered_cache_get_option( 'rejected_uri' ) ) {
622 $cookies = preg_split( '#(\r\n|\r|\n)#', powered_cache_get_option( 'rejected_uri' ) );
623 }
624 $wp_cookies = array( 'wordpressuser_', 'wordpresspass_', 'wordpress_sec_', 'wordpress_logged_in_' );
625 if ( ! empty( $cookies ) ) {
626 $wp_cookies = array_merge( $cookies, $wp_cookies );
627 }
628 $rules .= ' RewriteCond %{HTTP:Cookie} !(' . implode( '|', $wp_cookies ) . ') [NC]' . PHP_EOL;
629
630 // dont cache fbexternal
631 $rules .= ' RewriteCond %{HTTP_USER_AGENT} !^(facebookexternalhit).* [NC]' . PHP_EOL;
632
633
634 $cache_location = powered_cache_get_cache_dir();
635 $cache_location = untrailingslashit( $cache_location ) . '/powered-cache/';
636 if ( strpos( ABSPATH, $cache_location ) === false ) {
637 // clean doc root
638 $cache_path = str_replace( $_SERVER['DOCUMENT_ROOT'], '', $cache_location );
639 } else {
640 $cache_path = $site_root . str_replace( ABSPATH, '', $cache_location );
641 }
642
643
644 if ( apply_filters( 'powered_cache_maybe_1and1_hosting', ( 0 === strpos( $_SERVER['DOCUMENT_ROOT'], '/kunden/homepage/' ) ) ) ) {
645 $rules .= ' RewriteCond "' . str_replace( '/kunden/homepage/', '/', $cache_location ) . '%{HTTP_HOST}' . '%{REQUEST_URI}/index' . $env_powered_cache_ssl . $env_powered_cache_ua . '.html' . $env_powered_cache_enc . '" -f' . PHP_EOL;
646 } else {
647 $rules .= ' RewriteCond "%{DOCUMENT_ROOT}/' . ltrim( $cache_path, '/' ) . '%{HTTP_HOST}' . '%{REQUEST_URI}/index' . $env_powered_cache_ssl . $env_powered_cache_ua . '.html' . $env_powered_cache_enc . '" -f' . PHP_EOL;
648 }
649 $rules .= ' RewriteRule .* "' . $cache_path . '%{HTTP_HOST}' . '%{REQUEST_URI}/index' . $env_powered_cache_ssl . $env_powered_cache_ua . '.html' . $env_powered_cache_enc . '" [L]' . PHP_EOL;
650 $rules .= '</IfModule>' . PHP_EOL;
651 $rules .= '# END POWERED CACHE' . PHP_EOL;
652
653 return $rules;
654 }
655
656
657 /**
658 * Prepares nginx configuration
659 *
660 * @since 1.1
661 * @since 1.2 trailingslash rule added
662 *
663 * @return string $contents nginx rules
664 */
665 public function nginx_rules() {
666 $contents = '';
667 $contents .= '##### POWERED CACHE CONF #####' . PHP_EOL;
668 $contents .= 'set $cache_uri $request_uri;' . PHP_EOL;
669 $contents .= 'set $pc_ssl "";' . PHP_EOL;
670 $contents .= 'set $pc_enc "";' . PHP_EOL;
671 $contents .= 'set $pc_ua "";' . PHP_EOL . PHP_EOL;
672
673 // post
674 $contents .= '# POST requests and urls with a query string should always go to PHP' . PHP_EOL;
675 $contents .= 'if ($request_method = POST) {' . PHP_EOL;
676 $contents .= ' set $cache_uri \'null cache\';' . PHP_EOL;
677 $contents .= '}' . PHP_EOL . PHP_EOL;
678
679 // query string
680 $contents .= 'if ($query_string != "") {' . PHP_EOL;
681 $contents .= ' set $cache_uri \'null cache\';' . PHP_EOL;
682 $contents .= '}' . PHP_EOL . PHP_EOL;
683
684 // https
685 $contents .= '# HTTPS' . PHP_EOL;
686 $contents .= 'if ($https = "on") {' . PHP_EOL;
687 $contents .= ' set $pc_ssl "-https";' . PHP_EOL;
688 $contents .= '}' . PHP_EOL . PHP_EOL;
689
690 $contents .= '# Don\'t cache uris containing the following segments' . PHP_EOL;
691 $contents .= 'if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {' . PHP_EOL;
692 $contents .= ' set $cache_uri \'null cache\';' . PHP_EOL;
693 $contents .= '}' . PHP_EOL . PHP_EOL;
694
695 $contents .= '# Don\'t use the cache for logged in users or recent commenters' . PHP_EOL;
696 $contents .= 'if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in|powered_cache_commented_posts") {' . PHP_EOL;
697 $contents .= ' set $cache_uri \'null cache\';' . PHP_EOL;
698 $contents .= '}' . PHP_EOL . PHP_EOL;
699
700 $contents .= 'if ($http_x_wap_profile) {' . PHP_EOL;
701 $contents .= ' set $pc_ua \'-mobile\';' . PHP_EOL;
702 $contents .= '}' . PHP_EOL . PHP_EOL;
703
704 if ( true === powered_cache_get_option( 'cache_mobile' ) && true === powered_cache_get_option( 'cache_mobile_separate_file' ) ) {
705 $mobile_browsers = addcslashes( implode( '|', preg_split( '/[\s*,\s*]*,+[\s*,\s*]*/', powered_cache_mobile_browsers() ) ), ' ' );
706 $mobile_prefixes = addcslashes( implode( '|', preg_split( '/[\s*,\s*]*,+[\s*,\s*]*/', powered_cache_mobile_prefixes() ) ), ' ' );
707
708 $contents .= 'if ($http_user_agent ~* (' . $mobile_browsers . '))' . PHP_EOL;
709 $contents .= ' set $pc_ua \'-mobile\';' . PHP_EOL;
710 $contents .= '}' . PHP_EOL . PHP_EOL;
711
712 $contents .= 'if ($http_user_agent ~* (' . $mobile_prefixes . '))' . PHP_EOL;
713 $contents .= ' set $pc_ua \'-mobile\';' . PHP_EOL;
714 $contents .= '}' . PHP_EOL . PHP_EOL;
715 }
716
717 $contents .= 'location = /favicon.ico { log_not_found off; access_log off; }' . PHP_EOL;
718 $contents .= 'location = /robots.txt { try_files $uri $uri/ /index.php?$args; log_not_found off; access_log off; }' . PHP_EOL . PHP_EOL;
719
720 $contents .= 'location ~* .(jpg|jpeg|png|gif|ico|css|js|svg|eot|woff|woff2|ttf|otf)$ {' . PHP_EOL;
721 $contents .= ' expires 1M;' . PHP_EOL;
722 $contents .= '}' . PHP_EOL . PHP_EOL;
723
724 $cache_suffix = 'html';
725 if ( true === powered_cache_get_option( 'gzip_compression' ) ) {
726 $cache_suffix .= '_gzip';
727 }
728
729
730 $contents .= 'location / {' . PHP_EOL;
731 $contents .= ' add_header X-Powered-Cache nginx;' . PHP_EOL;
732 $contents .= ' try_files /wp-content/cache/powered-cache/$http_host/$cache_uri/index${pc_ssl}${pc_ua}.' . $cache_suffix . ' $uri $uri/ /index.php?$args;' . PHP_EOL;
733 $contents .= '}' . PHP_EOL . PHP_EOL;
734
735 if ( substr( get_option( 'permalink_structure' ), - 1 ) == '/' ) {
736 $contents .= '# add trailingslash rule' . PHP_EOL;
737 $contents .= 'rewrite ^([^.]*[^/])$ $1/ permanent;'. PHP_EOL;
738 }
739
740 return $contents;
741 }
742
743
744 /**
745 * Downloads configuration files
746 *
747 * @since 1.1
748 *
749 * @param string $server type supports apache and nginx
750 */
751 public function download_rewrite_rules( $server ) {
752
753 $rules = '';
754 $filename = 'conf';
755
756 if ( 'apache' === $server ) {
757 $rules = $this->htaccess_rules();
758 $filename = '.htaccess_powered_cache';
759 }
760
761 if ( 'nginx' === $server ) {
762 $rules = $this->nginx_rules();
763 $filename = 'poweredcache.conf';
764 }
765
766 nocache_headers();
767 @header( 'Content-Type: text/plain' );
768 @header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
769 @header( 'Content-Transfer-Encoding: binary' );
770 @header( 'Content-Length: ' . strlen( $rules ) );
771 @header( 'Connection: close' );
772 echo $rules;
773 exit;
774 }
775
776
777 /**
778 * Make sure directory listing disabled
779 *
780 * @since 1.2
781 * @return bool
782 */
783 public function protect_cache_dir() {
784 global $powered_cache_fs;
785
786 $file = powered_cache_get_cache_dir() . '.htaccess';
787
788 $file_string = 'Options -Indexes';
789
790 if ( ! $powered_cache_fs->put_contents( $file, $file_string, FS_CHMOD_FILE ) ) {
791 return false;
792 }
793
794 return true;
795
796 }
797
798 }
799