Cache Enabler – WordPress Cache - Version 1.2.3

Version Description

  • Fix expiry time
  • Allow to customize bypass cookies
  • Fix Autoptimize config warning
  • Pages can now be excluded from cache by a path matching regex
  • Plugin upgrades can now trigger cache clear
  • Scheduled posts and drafts are now properly handled
  • A missing trailing slash will now redirect like wordpress does by default
Download this release

Release Info

Developer keycdn
Plugin Icon 128x128 Cache Enabler – WordPress Cache
Version 1.2.3
Comparing to
See all releases

Code changes from version 1.2.2 to 1.2.3

advanced-cache.php CHANGED
@@ -5,92 +5,184 @@ if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || $_SERVER['REQUEST_METHOD'] != 'GET
5
  return false;
6
  }
7
 
8
- // check if request with query strings
9
- if ( ! empty($_GET) && ! isset( $_GET['utm_source'], $_GET['utm_medium'], $_GET['utm_campaign'] ) ) {
10
- return false;
11
- }
12
 
13
- // check cookie values
14
- if ( !empty($_COOKIE) ) {
15
- foreach ( $_COOKIE as $k => $v) {
16
- if ( preg_match('/^(wp-postpass|wordpress_logged_in|comment_author)_/', $k) ) {
17
- return false;
18
- }
19
- }
 
 
 
20
  }
21
 
22
- // base path
23
- $path = sprintf(
24
- '%s%s%s%s',
25
- WP_CONTENT_DIR . '/cache/cache-enabler',
26
- DIRECTORY_SEPARATOR,
27
  parse_url(
28
  'http://' .strtolower($_SERVER['HTTP_HOST']),
29
  PHP_URL_HOST
30
  ),
31
- parse_url(
32
- $_SERVER['REQUEST_URI'],
33
- PHP_URL_PATH
34
- )
35
  );
 
36
 
37
- // add trailing slash
38
- $path = rtrim( $path, '/\\' ) . '/';
 
39
 
40
- // path to cached variants
41
- $path_html = $path . 'index.html';
42
- $path_gzip = $path . 'index.html.gz';
43
- $path_webp_html = $path . 'index-webp.html';
44
- $path_webp_gzip = $path . 'index-webp.html.gz';
45
 
46
- if ( is_readable( $path_html ) ) {
 
 
 
 
 
47
 
48
- // set cache handler header
49
- header('x-cache-handler: wp');
 
 
 
 
50
 
51
- // get if-modified request headers
52
- if ( function_exists( 'apache_request_headers' ) ) {
53
- $headers = apache_request_headers();
54
- $http_if_modified_since = ( isset( $headers[ 'If-Modified-Since' ] ) ) ? $headers[ 'If-Modified-Since' ] : '';
55
- $http_accept = ( isset( $headers[ 'Accept' ] ) ) ? $headers[ 'Accept' ] : '';
56
- $http_accept_encoding = ( isset( $headers[ 'Accept-Encoding' ] ) ) ? $headers[ 'Accept-Encoding' ] : '';
57
  } else {
58
- $http_if_modified_since = ( isset( $_SERVER[ 'HTTP_IF_MODIFIED_SINCE' ] ) ) ? $_SERVER[ 'HTTP_IF_MODIFIED_SINCE' ] : '';
59
- $http_accept = ( isset( $_SERVER[ 'HTTP_ACCEPT' ] ) ) ? $_SERVER[ 'HTTP_ACCEPT' ] : '';
60
- $http_accept_encoding = ( isset( $_SERVER[ 'HTTP_ACCEPT_ENCODING' ] ) ) ? $_SERVER[ 'HTTP_ACCEPT_ENCODING' ] : '';
61
  }
62
 
63
- // check modified since with cached file and return 304 if no difference
64
- if ( $http_if_modified_since && ( strtotime( $http_if_modified_since ) == filemtime( $path_html ) ) ) {
65
- header( $_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified', true, 304 );
66
- exit;
67
  }
 
68
 
69
- header( 'Last-Modified: ' . gmdate("D, d M Y H:i:s",filemtime( $path_html )).' GMT' );
70
-
71
- // check webp and deliver gzip webp file if support
72
- if ( $http_accept && ( strpos($http_accept, 'webp') !== false ) ) {
73
- if ( is_readable( $path_webp_gzip ) ) {
74
- header('Content-Encoding: gzip');
75
- readfile( $path_webp_gzip );
76
- exit;
77
- } elseif ( is_readable( $path_webp_html ) ) {
78
- readfile( $path_webp_html );
79
- exit;
80
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
- // check encoding and deliver gzip file if support
84
- if ( $http_accept_encoding && ( strpos($http_accept_encoding, 'gzip') !== false ) && is_readable( $path_gzip ) ) {
 
 
 
85
  header('Content-Encoding: gzip');
86
- readfile( $path_gzip );
 
 
 
87
  exit;
88
  }
 
89
 
90
- // deliver cached file (default)
91
- readfile( $path_html );
 
 
92
  exit;
 
93
 
94
- } else {
95
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  }
5
  return false;
6
  }
7
 
8
+ // base path
9
+ $path = _ce_file_path();
 
 
10
 
11
+ // path to cached variants
12
+ $path_html = $path . 'index.html';
13
+ $path_gzip = $path . 'index.html.gz';
14
+ $path_webp_html = $path . 'index-webp.html';
15
+ $path_webp_gzip = $path . 'index-webp.html.gz';
16
+
17
+
18
+ // if we don't have a cache copy, we do not need to proceed
19
+ if ( ! is_readable( $path_html ) ) {
20
+ return false;
21
  }
22
 
23
+ // check if there are settings passed out to us
24
+ $settings_file = sprintf('%s-%s%s.json',
25
+ WP_CONTENT_DIR. "/cache/cache-enabler-advcache",
 
 
26
  parse_url(
27
  'http://' .strtolower($_SERVER['HTTP_HOST']),
28
  PHP_URL_HOST
29
  ),
30
+ is_multisite() ? '-'. get_current_blog_id() : ''
 
 
 
31
  );
32
+ $settings = _read_settings($settings_file);
33
 
34
+ // if post path excluded
35
+ if ( !empty($settings['excl_regexp']) ) {
36
+ $url_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
37
 
38
+ if ( preg_match($settings['excl_regexp'], $url_path) ) {
39
+ return false;
40
+ }
41
+ }
 
42
 
43
+ // whitelisted query strings
44
+ if ( !empty($settings['excl_querystrings']) ) {
45
+ $query_strings_regex = $settings['excl_querystrings'];
46
+ } else {
47
+ $query_strings_regex = '/^utm_(source|medium|campaign|term|content)/';
48
+ }
49
 
50
+ // check request query strings
51
+ foreach ( (array)$_GET as $key => $value ) {
52
+ if ( preg_match($query_strings_regex, $key) ) {
53
+ return false;
54
+ }
55
+ }
56
 
57
+ // check cookie values
58
+ if ( !empty($_COOKIE) ) {
59
+ // check cookie values
60
+ if ( !empty($settings['excl_cookies']) ) {
61
+ // if custom cookie regexps exist, we merge them
62
+ $cookies_regex = $settings['excl_cookies'];
63
  } else {
64
+ $cookies_regex = '/^(wp-postpass|wordpress_logged_in|comment_author)_/';
 
 
65
  }
66
 
67
+ foreach ( $_COOKIE as $k => $v) {
68
+ if ( preg_match($cookies_regex, $k) ) {
69
+ return false;
70
+ }
71
  }
72
+ }
73
 
74
+ // if an expiry time is set, check the file against it
75
+ if ( isset($settings["expires"]) and $settings["expires"] > 0 ) {
76
+ $now = time();
77
+ $expires_seconds = 3600*$settings["expires"];
78
+
79
+ // check if asset has expired
80
+ if ( ( filemtime($path_html) + $expires_seconds ) <= $now ) {
81
+ return false;
82
+ }
83
+ }
84
+
85
+ // if a cache timeout is set, check if we have to bypass the cache
86
+ if ( !empty($settings["cache_timeout"]) ) {
87
+ $now = time();
88
+
89
+ // check if timeout has been reached
90
+ if ( $settings["cache_timeout"] <= $now ) {
91
+ unlink($timeout_file);
92
+ return false;
93
+ }
94
+ }
95
+
96
+ // check if we need drop the ball to cause a redirect
97
+ if ( isset($settings["permalink_trailing_slash"]) ) {
98
+ if ( ! preg_match("/\/$/", $_SERVER["REQUEST_URI"]) ) {
99
+ return false;
100
  }
101
+ }
102
+
103
+ // set cache handler header
104
+ header('x-cache-handler: wp');
105
+
106
+ // get if-modified request headers
107
+ if ( function_exists( 'apache_request_headers' ) ) {
108
+ $headers = apache_request_headers();
109
+ $http_if_modified_since = ( isset( $headers[ 'If-Modified-Since' ] ) ) ? $headers[ 'If-Modified-Since' ] : '';
110
+ $http_accept = ( isset( $headers[ 'Accept' ] ) ) ? $headers[ 'Accept' ] : '';
111
+ $http_accept_encoding = ( isset( $headers[ 'Accept-Encoding' ] ) ) ? $headers[ 'Accept-Encoding' ] : '';
112
+ } else {
113
+ $http_if_modified_since = ( isset( $_SERVER[ 'HTTP_IF_MODIFIED_SINCE' ] ) ) ? $_SERVER[ 'HTTP_IF_MODIFIED_SINCE' ] : '';
114
+ $http_accept = ( isset( $_SERVER[ 'HTTP_ACCEPT' ] ) ) ? $_SERVER[ 'HTTP_ACCEPT' ] : '';
115
+ $http_accept_encoding = ( isset( $_SERVER[ 'HTTP_ACCEPT_ENCODING' ] ) ) ? $_SERVER[ 'HTTP_ACCEPT_ENCODING' ] : '';
116
+ }
117
+
118
+ // check modified since with cached file and return 304 if no difference
119
+ if ( $http_if_modified_since && ( strtotime( $http_if_modified_since ) <= filemtime( $path_html ) ) ) {
120
+ header( $_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified', true, 304 );
121
+ exit;
122
+ }
123
 
124
+ header( 'Last-Modified: ' . gmdate("D, d M Y H:i:s",filemtime( $path_html )).' GMT' );
125
+
126
+ // check webp and deliver gzip webp file if support
127
+ if ( $http_accept && ( strpos($http_accept, 'webp') !== false ) ) {
128
+ if ( is_readable( $path_webp_gzip ) ) {
129
  header('Content-Encoding: gzip');
130
+ readfile( $path_webp_gzip );
131
+ exit;
132
+ } elseif ( is_readable( $path_webp_html ) ) {
133
+ readfile( $path_webp_html );
134
  exit;
135
  }
136
+ }
137
 
138
+ // check encoding and deliver gzip file if support
139
+ if ( $http_accept_encoding && ( strpos($http_accept_encoding, 'gzip') !== false ) && is_readable( $path_gzip ) ) {
140
+ header('Content-Encoding: gzip');
141
+ readfile( $path_gzip );
142
  exit;
143
+ }
144
 
145
+ // deliver cached file (default)
146
+ readfile( $path_html );
147
+ exit;
148
+
149
+
150
+ // generate cache path
151
+ function _ce_file_path($path = NULL) {
152
+ $path = sprintf(
153
+ '%s%s%s%s',
154
+ WP_CONTENT_DIR . '/cache/cache-enabler',
155
+ DIRECTORY_SEPARATOR,
156
+ parse_url(
157
+ 'http://' .strtolower($_SERVER['HTTP_HOST']),
158
+ PHP_URL_HOST
159
+ ),
160
+ parse_url(
161
+ ( $path ? $path : $_SERVER['REQUEST_URI'] ),
162
+ PHP_URL_PATH
163
+ )
164
+ );
165
+
166
+ if ( is_file($path) > 0 ) {
167
+ wp_die('Path is not valid.');
168
+ }
169
+
170
+ // add trailing slash
171
+ $path = rtrim( $path, '/\\' ) . '/';
172
+
173
+ return $path;
174
+ }
175
+
176
+ // read settings file
177
+ function _read_settings($settings_file) {
178
+ if (! file_exists($settings_file) ) {
179
+ return [];
180
+ }
181
+
182
+ if ( ! $settings = json_decode(file_get_contents($settings_file), true) ) {
183
+ // if there is an error reading our settings
184
+ return [];
185
+ }
186
+
187
+ return $settings;
188
  }
cache-enabler.php CHANGED
@@ -6,7 +6,7 @@ Description: Simple and fast WordPress disk caching plugin.
6
  Author: KeyCDN
7
  Author URI: https://www.keycdn.com
8
  License: GPLv2 or later
9
- Version: 1.2.2
10
  */
11
 
12
  /*
6
  Author: KeyCDN
7
  Author URI: https://www.keycdn.com
8
  License: GPLv2 or later
9
+ Version: 1.2.3
10
  */
11
 
12
  /*
inc/cache_enabler.class.php CHANGED
@@ -63,7 +63,7 @@ final class Cache_Enabler {
63
  * constructor
64
  *
65
  * @since 1.0.0
66
- * @change 1.2.0
67
  *
68
  * @param void
69
  * @return void
@@ -115,9 +115,18 @@ final class Cache_Enabler {
115
  );
116
  add_action(
117
  'wp_trash_post',
 
 
 
 
 
 
 
 
 
118
  array(
119
  __CLASS__,
120
- 'clear_total_cache'
121
  )
122
  );
123
  add_action(
@@ -127,6 +136,12 @@ final class Cache_Enabler {
127
  'clear_total_cache'
128
  )
129
  );
 
 
 
 
 
 
130
 
131
  // add admin clear link
132
  add_action(
@@ -346,6 +361,42 @@ final class Cache_Enabler {
346
  }
347
 
348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  /**
350
  * install on multisite setup
351
  *
@@ -550,7 +601,7 @@ final class Cache_Enabler {
550
  * get options
551
  *
552
  * @since 1.0.0
553
- * @change 1.2.1
554
  *
555
  * @return array options array
556
  */
@@ -570,13 +621,17 @@ final class Cache_Enabler {
570
  return wp_parse_args(
571
  get_option('cache-enabler'),
572
  array(
573
- 'expires' => 0,
574
- 'new_post' => 0,
575
- 'new_comment' => 0,
576
- 'compress' => 0,
577
- 'webp' => 0,
578
- 'excl_ids' => '',
579
- 'minify_html' => self::MINIFY_DISABLED,
 
 
 
 
580
  )
581
  );
582
  }
@@ -1017,7 +1072,7 @@ final class Cache_Enabler {
1017
  * register publish hooks for custom post types
1018
  *
1019
  * @since 1.0.0
1020
- * @since 1.0.0
1021
  *
1022
  * @param void
1023
  * @return void
@@ -1048,10 +1103,14 @@ final class Cache_Enabler {
1048
  );
1049
  add_action(
1050
  'publish_future_' .$post_type,
1051
- array(
1052
- __CLASS__,
1053
- 'clear_total_cache'
1054
- )
 
 
 
 
1055
  );
1056
  }
1057
  }
@@ -1146,7 +1205,7 @@ final class Cache_Enabler {
1146
  * clear page cache by url
1147
  *
1148
  * @since 1.0.0
1149
- * @change 1.0.0
1150
  *
1151
  * @param string $url url of a page
1152
  */
@@ -1165,6 +1224,9 @@ final class Cache_Enabler {
1165
  ),
1166
  $url
1167
  );
 
 
 
1168
  }
1169
 
1170
 
@@ -1172,7 +1234,7 @@ final class Cache_Enabler {
1172
  * clear home page cache
1173
  *
1174
  * @since 1.0.7
1175
- * @change 1.0.7
1176
  *
1177
  */
1178
 
@@ -1185,21 +1247,8 @@ final class Cache_Enabler {
1185
  )
1186
  );
1187
 
1188
- }
1189
-
1190
-
1191
- /**
1192
- * explode on comma
1193
- *
1194
- * @since 1.0.0
1195
- * @change 1.0.0
1196
- *
1197
- * @param string $input input string
1198
- * @return array array of strings
1199
- */
1200
-
1201
- private static function _preg_split($input) {
1202
- return (array)preg_split('/,/', $input, -1, PREG_SPLIT_NO_EMPTY);
1203
  }
1204
 
1205
 
@@ -1213,7 +1262,7 @@ final class Cache_Enabler {
1213
  */
1214
 
1215
  private static function _is_index() {
1216
- return basename($_SERVER['SCRIPT_NAME']) != 'index.php';
1217
  }
1218
 
1219
 
@@ -1253,19 +1302,50 @@ final class Cache_Enabler {
1253
  }
1254
 
1255
  // check cookie values
 
 
 
 
 
 
 
1256
  foreach ( $_COOKIE as $k => $v) {
1257
- if ( preg_match('/^(wp-postpass|wordpress_logged_in|comment_author)_/', $k) ) {
1258
  return true;
1259
  }
1260
  }
1261
  }
1262
 
1263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1264
  /**
1265
  * check to bypass the cache
1266
  *
1267
  * @since 1.0.0
1268
- * @change 1.0.7
1269
  *
1270
  * @return boolean true if exception
1271
  *
@@ -1297,9 +1377,18 @@ final class Cache_Enabler {
1297
  return true;
1298
  }
1299
 
1300
- // Request with query strings
1301
- if ( ! empty($_GET) && ! isset( $_GET['utm_source'], $_GET['utm_medium'], $_GET['utm_campaign'] ) && get_option('permalink_structure') ) {
1302
- return true;
 
 
 
 
 
 
 
 
 
1303
  }
1304
 
1305
  // if logged in
@@ -1314,7 +1403,16 @@ final class Cache_Enabler {
1314
 
1315
  // if post id excluded
1316
  if ( $options['excl_ids'] && is_singular() ) {
1317
- if ( in_array( $GLOBALS['wp_query']->get_queried_object_id(), self::_preg_split($options['excl_ids']) ) ) {
 
 
 
 
 
 
 
 
 
1318
  return true;
1319
  }
1320
  }
@@ -1395,16 +1493,21 @@ final class Cache_Enabler {
1395
  * clear complete cache
1396
  *
1397
  * @since 1.0.0
1398
- * @change 1.0.0
1399
  */
1400
 
1401
  public static function clear_total_cache() {
 
 
1402
 
1403
  // clear disk cache
1404
  Cache_Enabler_Disk::clear_cache();
1405
 
1406
  // delete transient
1407
  delete_transient('cache_size');
 
 
 
1408
  }
1409
 
1410
 
@@ -1480,6 +1583,11 @@ final class Cache_Enabler {
1480
  return;
1481
  }
1482
 
 
 
 
 
 
1483
  // return cached asset
1484
  call_user_func(
1485
  array(
@@ -1684,7 +1792,7 @@ final class Cache_Enabler {
1684
  }
1685
 
1686
  // autoptimize minification check
1687
- if ( defined('AUTOPTIMIZE_PLUGIN_DIR') && $options['minify_html'] ) {
1688
  show_message(
1689
  sprintf(
1690
  '<div class="error"><p>%s</p></div>',
@@ -1715,6 +1823,35 @@ final class Cache_Enabler {
1715
  );
1716
  }
1717
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1718
 
1719
  /**
1720
  * register settings
@@ -1736,11 +1873,37 @@ final class Cache_Enabler {
1736
  }
1737
 
1738
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1739
  /**
1740
  * validate settings
1741
  *
1742
  * @since 1.0.0
1743
- * @change 1.0.9
1744
  *
1745
  * @param array $data array form data
1746
  * @return array array form data valid
@@ -1756,14 +1919,53 @@ final class Cache_Enabler {
1756
  // clear complete cache
1757
  self::clear_total_cache(true);
1758
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1759
  return array(
1760
- 'expires' => (int)$data['expires'],
1761
- 'new_post' => (int)(!empty($data['new_post'])),
1762
- 'new_comment' => (int)(!empty($data['new_comment'])),
1763
- 'webp' => (int)(!empty($data['webp'])),
1764
- 'compress' => (int)(!empty($data['compress'])),
1765
- 'excl_ids' => (string)sanitize_text_field(@$data['excl_ids']),
1766
- 'minify_html' => (int)$data['minify_html']
 
 
 
 
1767
  );
1768
  }
1769
 
@@ -1772,7 +1974,7 @@ final class Cache_Enabler {
1772
  * settings page
1773
  *
1774
  * @since 1.0.0
1775
- * @change 1.2.2
1776
  */
1777
 
1778
  public static function settings_page() {
@@ -1852,6 +2054,13 @@ final class Cache_Enabler {
1852
  <input type="checkbox" name="cache-enabler[webp]" id="cache_webp" value="1" <?php checked('1', $options['webp']); ?> />
1853
  <?php _e("Create an additional cached version for WebP image support. Convert your images to WebP with <a href=\"https://optimus.io/en/\" target=\"_blank\">Optimus</a>.", "cache-enabler") ?>
1854
  </label>
 
 
 
 
 
 
 
1855
  </fieldset>
1856
  </td>
1857
  </tr>
@@ -1866,6 +2075,30 @@ final class Cache_Enabler {
1866
  <input type="text" name="cache-enabler[excl_ids]" id="cache_excl_ids" value="<?php echo esc_attr($options['excl_ids']) ?>" />
1867
  <p class="description"><?php _e("Post or Pages IDs separated by a <code>,</code> that should not be cached.", "cache-enabler"); ?></p>
1868
  </label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1869
  </fieldset>
1870
  </td>
1871
  </tr>
63
  * constructor
64
  *
65
  * @since 1.0.0
66
+ * @change 1.2.3
67
  *
68
  * @param void
69
  * @return void
115
  );
116
  add_action(
117
  'wp_trash_post',
118
+ function( $post_id ) {
119
+ if ( get_post_status ( $post_id ) == 'publish' ) {
120
+ self::clear_total_cache();
121
+ }
122
+ self::check_future_posts();
123
+ }
124
+ );
125
+ add_action(
126
+ 'save_post',
127
  array(
128
  __CLASS__,
129
+ 'check_future_posts'
130
  )
131
  );
132
  add_action(
136
  'clear_total_cache'
137
  )
138
  );
139
+ add_action(
140
+ 'upgrader_process_complete',
141
+ array(
142
+ __CLASS__,
143
+ 'on_upgrade_hook'
144
+ ), 10, 2);
145
 
146
  // add admin clear link
147
  add_action(
361
  }
362
 
363
 
364
+ /**
365
+ * upgrade hook actions
366
+ *
367
+ * @since 1.2.3
368
+ */
369
+
370
+ public static function on_upgrade_hook( $obj, $options ) {
371
+ // clear cache on other plugins being upgraded
372
+ if ( self::$options['clear_on_upgrade'] ) {
373
+ self::clear_total_cache();
374
+ }
375
+
376
+ // check if we got upgraded ourselves
377
+ if ( $options['action'] == 'update' && $options['type'] == 'plugin' ) {
378
+ foreach ( $options['plugins'] as $each_plugin ) {
379
+ if ( preg_match("/^cache-enabler\//", $each_plugin) ) {
380
+ // we got updated!
381
+ self::on_upgrade();
382
+ }
383
+ }
384
+ }
385
+ }
386
+
387
+
388
+ /**
389
+ * upgrade actions
390
+ *
391
+ * @since 1.2.3
392
+ */
393
+
394
+ public static function on_upgrade() {
395
+ // copy advanced cache file which might have changed
396
+ copy(CE_DIR . '/advanced-cache.php', WP_CONTENT_DIR . '/advanced-cache.php');
397
+ }
398
+
399
+
400
  /**
401
  * install on multisite setup
402
  *
601
  * get options
602
  *
603
  * @since 1.0.0
604
+ * @change 1.2.3
605
  *
606
  * @return array options array
607
  */
621
  return wp_parse_args(
622
  get_option('cache-enabler'),
623
  array(
624
+ 'expires' => 0,
625
+ 'new_post' => 0,
626
+ 'new_comment' => 0,
627
+ 'compress' => 0,
628
+ 'webp' => 0,
629
+ 'clear_on_upgrade' => 0,
630
+ 'excl_ids' => '',
631
+ 'excl_regexp' => '',
632
+ 'excl_cookies' => '',
633
+ 'excl_querystrings' => '',
634
+ 'minify_html' => self::MINIFY_DISABLED,
635
  )
636
  );
637
  }
1072
  * register publish hooks for custom post types
1073
  *
1074
  * @since 1.0.0
1075
+ * @since 1.2.3
1076
  *
1077
  * @param void
1078
  * @return void
1103
  );
1104
  add_action(
1105
  'publish_future_' .$post_type,
1106
+ function( $post_id ) {
1107
+ // clear complete cache if option enabled
1108
+ if ( self::$options['new_post'] ) {
1109
+ self::clear_total_cache();
1110
+ } else {
1111
+ self::clear_home_page_cache();
1112
+ }
1113
+ }
1114
  );
1115
  }
1116
  }
1205
  * clear page cache by url
1206
  *
1207
  * @since 1.0.0
1208
+ * @change 1.2.3
1209
  *
1210
  * @param string $url url of a page
1211
  */
1224
  ),
1225
  $url
1226
  );
1227
+
1228
+ // clear cache by url post hook
1229
+ do_action('ce_action_cache_by_url_cleared');
1230
  }
1231
 
1232
 
1234
  * clear home page cache
1235
  *
1236
  * @since 1.0.7
1237
+ * @change 1.2.3
1238
  *
1239
  */
1240
 
1247
  )
1248
  );
1249
 
1250
+ // clear home page cache post hook
1251
+ do_action('ce_action_home_page_cache_cleared');
 
 
 
 
 
 
 
 
 
 
 
 
 
1252
  }
1253
 
1254
 
1262
  */
1263
 
1264
  private static function _is_index() {
1265
+ return strtolower(basename($_SERVER['SCRIPT_NAME'])) != 'index.php';
1266
  }
1267
 
1268
 
1302
  }
1303
 
1304
  // check cookie values
1305
+ $options = self::$options;
1306
+ if ( !empty($options['excl_cookies']) ) {
1307
+ $cookies_regex = $options['excl_cookies'];
1308
+ } else {
1309
+ $cookies_regex = '/^(wp-postpass|wordpress_logged_in|comment_author)_/';
1310
+ }
1311
+
1312
  foreach ( $_COOKIE as $k => $v) {
1313
+ if ( preg_match($cookies_regex, $k) ) {
1314
  return true;
1315
  }
1316
  }
1317
  }
1318
 
1319
 
1320
+ /**
1321
+ * check if there are post to be published in the future
1322
+ *
1323
+ * @since 1.2.3
1324
+ *
1325
+ * @return void
1326
+ *
1327
+ */
1328
+
1329
+ public static function check_future_posts() {
1330
+
1331
+ $future_posts = new WP_Query(array('post_status' => array('future')));
1332
+
1333
+ if ( $future_posts->have_posts() ) {
1334
+ $post_dates = array_column($future_posts->get_posts(), "post_date");
1335
+ sort($post_dates);
1336
+ Cache_Enabler_Disk::record_advcache_settings(array(
1337
+ "cache_timeout" => strtotime($post_dates[0])));
1338
+ } else {
1339
+ Cache_Enabler_Disk::delete_advcache_settings(array("cache_timeout"));
1340
+ }
1341
+ }
1342
+
1343
+
1344
  /**
1345
  * check to bypass the cache
1346
  *
1347
  * @since 1.0.0
1348
+ * @change 1.2.3
1349
  *
1350
  * @return boolean true if exception
1351
  *
1377
  return true;
1378
  }
1379
 
1380
+ // whitelisted query strings
1381
+ if ( !empty($options['excl_querystrings']) ) {
1382
+ $query_strings_regex = $options['excl_querystrings'];
1383
+ } else {
1384
+ $query_strings_regex = '/^utm_(source|medium|campaign|term|content)/';
1385
+ }
1386
+
1387
+ // check request query strings
1388
+ foreach ( (array)$_GET as $key => $value ) {
1389
+ if ( preg_match($query_strings_regex, $key) ) {
1390
+ return true;
1391
+ }
1392
  }
1393
 
1394
  // if logged in
1403
 
1404
  // if post id excluded
1405
  if ( $options['excl_ids'] && is_singular() ) {
1406
+ if ( in_array( $GLOBALS['wp_query']->get_queried_object_id(), (array)explode(',', $options['excl_ids']) ) ) {
1407
+ return true;
1408
+ }
1409
+ }
1410
+
1411
+ // if post path excluded
1412
+ if ( !empty($options['excl_regexp']) ) {
1413
+ $url_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
1414
+
1415
+ if ( preg_match($options['excl_regexp'], $url_path) ) {
1416
  return true;
1417
  }
1418
  }
1493
  * clear complete cache
1494
  *
1495
  * @since 1.0.0
1496
+ * @change 1.2.3
1497
  */
1498
 
1499
  public static function clear_total_cache() {
1500
+ // we need this here to update advanced-cache.php for the 1.2.3 upgrade
1501
+ self::on_upgrade();
1502
 
1503
  // clear disk cache
1504
  Cache_Enabler_Disk::clear_cache();
1505
 
1506
  // delete transient
1507
  delete_transient('cache_size');
1508
+
1509
+ // clear cache post hook
1510
+ do_action('ce_action_cache_cleared');
1511
  }
1512
 
1513
 
1583
  return;
1584
  }
1585
 
1586
+ // check if we are missing a trailing slash
1587
+ if ( self::missing_trailing_slash() ) {
1588
+ return;
1589
+ }
1590
+
1591
  // return cached asset
1592
  call_user_func(
1593
  array(
1792
  }
1793
 
1794
  // autoptimize minification check
1795
+ if ( defined('AUTOPTIMIZE_PLUGIN_DIR') && $options['minify_html'] && get_option('autoptimize_html', '') != '' ) {
1796
  show_message(
1797
  sprintf(
1798
  '<div class="error"><p>%s</p></div>',
1823
  );
1824
  }
1825
 
1826
+ /**
1827
+ * missing training slash
1828
+ *
1829
+ * we only have to really check that in advanced-cache.php
1830
+ *
1831
+ * @since 1.2.3
1832
+ *
1833
+ * @return boolean true if we need to redirct, otherwise false
1834
+ */
1835
+
1836
+ public static function missing_trailing_slash() {
1837
+ if ( ($permalink_structure = get_option('permalink_structure')) &&
1838
+ preg_match("/\/$/", $permalink_structure) ) {
1839
+
1840
+ // record permalink structure for advanced-cache
1841
+ Cache_Enabler_Disk::record_advcache_settings(array(
1842
+ "permalink_trailing_slash" => true
1843
+ ));
1844
+
1845
+ if ( ! preg_match("/\/$/", $_SERVER["REQUEST_URI"]) ) {
1846
+ return true;
1847
+ }
1848
+ } else {
1849
+ Cache_Enabler_Disk::delete_advcache_settings(array(
1850
+ "permalink_trailing_slash"));
1851
+ }
1852
+
1853
+ return false;
1854
+ }
1855
 
1856
  /**
1857
  * register settings
1873
  }
1874
 
1875
 
1876
+ /**
1877
+ * validate regexps
1878
+ *
1879
+ * @since 1.2.3
1880
+ *
1881
+ * @param string $re string containing regexps
1882
+ * @return string string containing regexps or emty string if input invalid
1883
+ */
1884
+
1885
+ public static function validate_regexps($re) {
1886
+ if ( $re != '' ) {
1887
+
1888
+ if ( ! preg_match('/^\/.*\/$/', $re) ) {
1889
+ $re = '/'.$re.'/';
1890
+ }
1891
+
1892
+ if ( @preg_match($re, null) === false ) {
1893
+ return '';
1894
+ }
1895
+
1896
+ return sanitize_text_field($re);
1897
+ }
1898
+
1899
+ return '';
1900
+ }
1901
+
1902
  /**
1903
  * validate settings
1904
  *
1905
  * @since 1.0.0
1906
+ * @change 1.2.3
1907
  *
1908
  * @param array $data array form data
1909
  * @return array array form data valid
1919
  // clear complete cache
1920
  self::clear_total_cache(true);
1921
 
1922
+ // ignore result, but call for settings recording
1923
+ self::missing_trailing_slash();
1924
+
1925
+ // record expiry time value for advanced-cache.php
1926
+ if ( $data['expires'] > 0 ){
1927
+ Cache_Enabler_Disk::record_advcache_settings(array(
1928
+ "expires" => $data['expires']));
1929
+ } else {
1930
+ Cache_Enabler_Disk::delete_advcache_settings(array("expires"));
1931
+ }
1932
+
1933
+ // path bypass regexp
1934
+ if ( strlen($data["excl_regexp"]) > 0 ) {
1935
+ Cache_Enabler_Disk::record_advcache_settings(array(
1936
+ "excl_regexp" => $data["excl_regexp"]));
1937
+ } else {
1938
+ Cache_Enabler_Disk::delete_advcache_settings(array("excl_regexp"));
1939
+ }
1940
+
1941
+ // custom cookie exceptions
1942
+ if ( strlen($data["excl_cookies"]) > 0 ) {
1943
+ Cache_Enabler_Disk::record_advcache_settings(array(
1944
+ "excl_cookies" => $data["excl_cookies"]));
1945
+ } else {
1946
+ Cache_Enabler_Disk::delete_advcache_settings(array("excl_cookies"));
1947
+ }
1948
+
1949
+ // custom querystrings exceptions
1950
+ if ( strlen($data["excl_querystrings"]) > 0 ) {
1951
+ Cache_Enabler_Disk::record_advcache_settings(array(
1952
+ "excl_querystrings" => $data["excl_querystrings"]));
1953
+ } else {
1954
+ Cache_Enabler_Disk::delete_advcache_settings(array("excl_querystrings"));
1955
+ }
1956
+
1957
  return array(
1958
+ 'expires' => (int)$data['expires'],
1959
+ 'new_post' => (int)(!empty($data['new_post'])),
1960
+ 'new_comment' => (int)(!empty($data['new_comment'])),
1961
+ 'webp' => (int)(!empty($data['webp'])),
1962
+ 'clear_on_upgrade' => (int)(!empty($data['clear_on_upgrade'])),
1963
+ 'compress' => (int)(!empty($data['compress'])),
1964
+ 'excl_ids' => (string)sanitize_text_field(@$data['excl_ids']),
1965
+ 'excl_regexp' => (string)self::validate_regexps(@$data['excl_regexp']),
1966
+ 'excl_cookies' => (string)self::validate_regexps(@$data['excl_cookies']),
1967
+ 'excl_querystrings' => (string)self::validate_regexps(@$data['excl_querystrings']),
1968
+ 'minify_html' => (int)$data['minify_html']
1969
  );
1970
  }
1971
 
1974
  * settings page
1975
  *
1976
  * @since 1.0.0
1977
+ * @change 1.2.3
1978
  */
1979
 
1980
  public static function settings_page() {
2054
  <input type="checkbox" name="cache-enabler[webp]" id="cache_webp" value="1" <?php checked('1', $options['webp']); ?> />
2055
  <?php _e("Create an additional cached version for WebP image support. Convert your images to WebP with <a href=\"https://optimus.io/en/\" target=\"_blank\">Optimus</a>.", "cache-enabler") ?>
2056
  </label>
2057
+
2058
+ <br />
2059
+
2060
+ <label for="cache_clear_on_upgrade">
2061
+ <input type="checkbox" name="cache-enabler[clear_on_upgrade]" id="cache_clear_on_upgrade" value="1" <?php checked('1', $options['clear_on_upgrade']); ?> />
2062
+ <?php _e("Clear the complete cache if any plugin has been upgraded.", "cache-enabler") ?>
2063
+ </label>
2064
  </fieldset>
2065
  </td>
2066
  </tr>
2075
  <input type="text" name="cache-enabler[excl_ids]" id="cache_excl_ids" value="<?php echo esc_attr($options['excl_ids']) ?>" />
2076
  <p class="description"><?php _e("Post or Pages IDs separated by a <code>,</code> that should not be cached.", "cache-enabler"); ?></p>
2077
  </label>
2078
+
2079
+ <br />
2080
+
2081
+ <label for="cache_excl_regexp">
2082
+ <input type="text" name="cache-enabler[excl_regexp]" id="cache_excl_regexp" value="<?php echo esc_attr($options['excl_regexp']) ?>" />
2083
+ <p class="description"><?php _e("Regexp matching page paths that should not be cached. e.g. <code>/(^\/$|\/robot\/$|^\/2018\/.*\/test\/)/</code>", "cache-enabler"); ?></p>
2084
+ </label>
2085
+
2086
+ <br />
2087
+
2088
+ <label for="cache_excl_cookies">
2089
+ <input type="text" name="cache-enabler[excl_cookies]" id="cache_excl_cookies" value="<?php echo esc_attr($options['excl_cookies']) ?>" />
2090
+ <p class="description"><?php _e("Regexp matching cookies that should cause the cache to be bypassed. <br>
2091
+ <nobr>e.g. <code>/^(wp-postpass|wordpress_logged_in|comment_author|(woocommerce_items_in_cart|wp_woocommerce_session)_?)/</code></nobr><br>
2092
+ default if unset: <nobr><code>/^(wp-postpass|wordpress_logged_in|comment_author)_/</code></nobr>", "cache-enabler"); ?></p>
2093
+ </label>
2094
+
2095
+ <br />
2096
+
2097
+ <label for="cache_excl_querystrings">
2098
+ <input type="text" name="cache-enabler[excl_querystrings]" id="cache_excl_querystrings" value="<?php echo esc_attr($options['excl_querystrings']) ?>" />
2099
+ <p class="description"><?php _e("Regexp matching query strings that should cause the cache to be bypassed. <br>
2100
+ default if unset: <nobr><code>/^utm_(source|medium|campaign|term|content)/</code></nobr>", "cache-enabler"); ?></p>
2101
+ </label>
2102
  </fieldset>
2103
  </td>
2104
  </tr>
inc/cache_enabler_disk.class.php CHANGED
@@ -515,6 +515,117 @@ final class Cache_Enabler_Disk {
515
  }
516
 
517
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  /**
519
  * convert to webp
520
  *
@@ -576,7 +687,6 @@ final class Cache_Enabler_Disk {
576
  return $src_webp_appended;
577
  }
578
  }
579
-
580
  }
581
 
582
  return $src;
515
  }
516
 
517
 
518
+ /**
519
+ * read settings file
520
+ *
521
+ * @since 1.2.3
522
+ *
523
+ * @return array settings or emtpy
524
+ */
525
+
526
+ private static function _read_settings($settings_file) {
527
+ if (! file_exists($settings_file) ) {
528
+ return [];
529
+ }
530
+
531
+ if ( ! $settings = json_decode(file_get_contents($settings_file), true) ) {
532
+ // if there is an error reading our settings
533
+ return [];
534
+ }
535
+
536
+ return $settings;
537
+ }
538
+
539
+
540
+ /**
541
+ * write settings file
542
+ *
543
+ * @since 1.2.3
544
+ *
545
+ * @return void
546
+ */
547
+
548
+ private static function _write_settings($settings_file, $settings) {
549
+ file_put_contents( $settings_file, wp_json_encode($settings) );
550
+ }
551
+
552
+
553
+ /**
554
+ * record settings for advanced-cache.php
555
+ *
556
+ * @since 1.2.3
557
+ *
558
+ * @param array settings as array pairs
559
+ * @return boolean true if successful
560
+ */
561
+
562
+ public static function record_advcache_settings($settings) {
563
+ $settings_file = sprintf('%s-%s%s.json',
564
+ WP_CONTENT_DIR. "/cache/cache-enabler-advcache",
565
+ parse_url(
566
+ 'http://' .strtolower($_SERVER['HTTP_HOST']),
567
+ PHP_URL_HOST
568
+ ),
569
+ is_multisite() ? '-'. get_current_blog_id() : ''
570
+ );
571
+
572
+ // create folder if neccessary
573
+ if ( ! wp_mkdir_p(dirname($settings_file)) ) {
574
+ wp_die('Unable to create directory.');
575
+ }
576
+
577
+ // merge with old settings
578
+ $settings = array_merge(self::_read_settings($settings_file), $settings);
579
+
580
+ // update settings file
581
+ self::_write_settings($settings_file, $settings);
582
+
583
+ return true;
584
+ }
585
+
586
+
587
+ /**
588
+ * delete settings for advanced-cache.php
589
+ *
590
+ * @since 1.2.3
591
+ *
592
+ * @param array settings as array or empty for delete all
593
+ * @return boolean true if successful
594
+ */
595
+
596
+ public static function delete_advcache_settings($remsettings = array()) {
597
+ $settings_file = sprintf('%s-%s%s.json',
598
+ WP_CONTENT_DIR. "/cache/cache-enabler-advcache",
599
+ parse_url(
600
+ 'http://' .strtolower($_SERVER['HTTP_HOST']),
601
+ PHP_URL_HOST
602
+ ),
603
+ is_multisite() ? '-'. get_current_blog_id() : ''
604
+ );
605
+
606
+ if ( ! file_exists($settings_file) or empty($remsettings)) {
607
+ return true;
608
+ }
609
+
610
+ $settings = self::_read_settings($settings_file);
611
+ foreach ($remsettings as $key) {
612
+ if ( array_key_exists($key, $settings) ) {
613
+ unset($settings[$key]);
614
+ }
615
+ }
616
+
617
+ if (empty($settings)) {
618
+ unlink($settings_file);
619
+ return true;
620
+ }
621
+
622
+ // update settings file
623
+ self::_write_settings($settings_file, $settings);
624
+
625
+ return true;
626
+ }
627
+
628
+
629
  /**
630
  * convert to webp
631
  *
687
  return $src_webp_appended;
688
  }
689
  }
 
690
  }
691
 
692
  return $src;
js/post.js CHANGED
File without changes
readme.txt CHANGED
@@ -1,8 +1,8 @@
1
  === Cache Enabler - WordPress Cache ===
2
  Contributors: keycdn
3
  Tags: cache, caching, wordpress cache, wp cache, performance, gzip, webp, http2
4
- Requires at least: 4.1
5
- Tested up to: 4.7
6
  Stable tag: trunk
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -50,8 +50,13 @@ When combined with Optimus, the Wordpress Cache Enabler allows you to easily del
50
 
51
 
52
  = System Requirements =
53
- * PHP >=5.3
54
- * WordPress >=4.1
 
 
 
 
 
55
 
56
 
57
  = Maintainer =
@@ -59,11 +64,20 @@ When combined with Optimus, the Wordpress Cache Enabler allows you to easily del
59
 
60
 
61
  = Credits =
62
- This WordPress cache plugin is partially based on Cachify developed by [Sergej Müller](https://wordpress.org/plugins/cachify/ "Author Sergej Müller").
63
 
64
 
65
  == Changelog ==
66
 
 
 
 
 
 
 
 
 
 
67
  = 1.2.2 =
68
  * Fixed settings form issue
69
 
1
  === Cache Enabler - WordPress Cache ===
2
  Contributors: keycdn
3
  Tags: cache, caching, wordpress cache, wp cache, performance, gzip, webp, http2
4
+ Requires at least: 4.6
5
+ Tested up to: 4.9
6
  Stable tag: trunk
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
50
 
51
 
52
  = System Requirements =
53
+ * PHP >=5.4
54
+ * WordPress >=4.6
55
+
56
+
57
+ = Contribute =
58
+ * Anyone is welcome to contribute to the plugin on [GitHub](https://github.com/keycdn/cache-enabler).
59
+ * Please merge (squash) all your changes into a single commit before you open a pull request.
60
 
61
 
62
  = Maintainer =
64
 
65
 
66
  = Credits =
67
+ * Inspired by [Cachify](https://wordpress.org/plugins/cachify/).
68
 
69
 
70
  == Changelog ==
71
 
72
+ = 1.2.3 =
73
+ * Fix expiry time
74
+ * Allow to customize bypass cookies
75
+ * Fix Autoptimize config warning
76
+ * Pages can now be excluded from cache by a path matching regex
77
+ * Plugin upgrades can now trigger cache clear
78
+ * Scheduled posts and drafts are now properly handled
79
+ * A missing trailing slash will now redirect like wordpress does by default
80
+
81
  = 1.2.2 =
82
  * Fixed settings form issue
83