Cache Enabler – WordPress Cache - Version 1.6.0

Version Description

  • Update cache clearing behavior for multisite networks when permalink structure has changed to prevent unnecessary cache clearing (#170)
  • Update cache clearing behavior for comment actions to prevent unnecessary cache clearing (#169)
  • Update output buffer timing to start earlier on the advanced-cache.php drop-in instead of the init hook (#168)
  • Update plugin upgrade handling (#166)
  • Add cache_enabler_clear_complete_cache, cache_enabler_clear_site_cache, cache_enabler_clear_site_cache_by_blog_id, cache_enabler_clear_page_cache_by_post_id, cache_enabler_clear_page_cache_by_url, cache_enabler_complete_cache_cleared, cache_enabler_site_cache_cleared, and cache_enabler_page_cache_cleared action hooks (#170)
  • Add cache_enabler_user_can_clear_cache, cache_enabler_exclude_search, cache_enabler_bypass_cache, cache_enabler_page_contents_before_store, cache_enabler_page_contents_after_webp_conversion, cache_enabler_minify_html_ignore_tags filter hooks (#170)
  • Add site cache clearing behavior (#167)
  • Fix requirement notices being shown to all users (#170)
  • Fix setting up new site in multisite network when new site is added outside of the admin interface (#170)
  • Fix getting cache size for main site in subdirectory network (#164)
  • Fix deleting cache size transient (#164)
  • Fix cache clearing (#164 and #167)
  • Fix clear cache request validation
  • Deprecate ce_clear_cache, ce_clear_post_cache, ce_action_cache_cleared, and ce_action_cache_by_url_cleared action hooks in favor of replacements (#170)
  • Deprecate user_can_clear_cache, bypass_cache, cache_enabler_before_store, cache_enabler_disk_webp_converted_data, and cache_minify_ignore_tags filter hooks in favor of replacements (#170)
Download this release

Release Info

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

Code changes from version 1.5.5 to 1.6.0

advanced-cache.php CHANGED
@@ -3,7 +3,7 @@
3
  * Cache Enabler advanced cache
4
  *
5
  * @since 1.2.0
6
- * @change 1.5.5
7
  */
8
 
9
  if ( ! defined( 'ABSPATH' ) ) {
@@ -20,6 +20,13 @@ if ( file_exists( $ce_engine_file ) && file_exists( $ce_disk_file ) ) {
20
  }
21
 
22
  if ( class_exists( 'Cache_Enabler_Engine' ) ) {
23
- Cache_Enabler_Engine::start();
24
- Cache_Enabler_Engine::deliver_cache();
 
 
 
 
 
 
 
25
  }
3
  * Cache Enabler advanced cache
4
  *
5
  * @since 1.2.0
6
+ * @change 1.6.0
7
  */
8
 
9
  if ( ! defined( 'ABSPATH' ) ) {
20
  }
21
 
22
  if ( class_exists( 'Cache_Enabler_Engine' ) ) {
23
+ $ce_engine_started = Cache_Enabler_Engine::start();
24
+
25
+ if ( $ce_engine_started ) {
26
+ $ce_cache_delivered = Cache_Enabler_Engine::deliver_cache();
27
+
28
+ if ( ! $ce_cache_delivered ) {
29
+ Cache_Enabler_Engine::start_buffering();
30
+ }
31
+ }
32
  }
cache-enabler.php CHANGED
@@ -6,7 +6,7 @@ Description: Simple and fast WordPress caching plugin.
6
  Author: KeyCDN
7
  Author URI: https://www.keycdn.com
8
  License: GPLv2 or later
9
- Version: 1.5.5
10
  */
11
 
12
  /*
@@ -32,7 +32,7 @@ if ( ! defined( 'ABSPATH' ) ) {
32
  }
33
 
34
  // constants
35
- define( 'CE_VERSION', '1.5.5' );
36
  define( 'CE_MIN_WP', '5.1' );
37
  define( 'CE_FILE', __FILE__ );
38
  define( 'CE_BASE', plugin_basename( __FILE__ ) );
6
  Author: KeyCDN
7
  Author URI: https://www.keycdn.com
8
  License: GPLv2 or later
9
+ Version: 1.6.0
10
  */
11
 
12
  /*
32
  }
33
 
34
  // constants
35
+ define( 'CE_VERSION', '1.6.0' );
36
  define( 'CE_MIN_WP', '5.1' );
37
  define( 'CE_FILE', __FILE__ );
38
  define( 'CE_BASE', plugin_basename( __FILE__ ) );
inc/cache_enabler.class.php CHANGED
@@ -27,70 +27,88 @@ final class Cache_Enabler {
27
  /**
28
  * settings from database (deprecated)
29
  *
 
30
  * @deprecated 1.5.0
31
  */
32
 
33
  public static $options;
34
 
35
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  /**
37
  * constructor
38
  *
39
  * @since 1.0.0
40
- * @change 1.5.2
41
  */
42
 
43
  public function __construct() {
44
 
45
  // init hooks
46
  add_action( 'init', array( 'Cache_Enabler_Engine', 'start' ) );
47
- add_action( 'init', array( 'Cache_Enabler_Engine', 'start_buffering' ) );
48
  add_action( 'init', array( __CLASS__, 'process_clear_cache_request' ) );
49
  add_action( 'init', array( __CLASS__, 'register_textdomain' ) );
50
 
51
- // clear cache hooks
52
- add_action( 'ce_clear_post_cache', array( __CLASS__, 'clear_page_cache_by_post_id' ) );
53
- add_action( 'ce_clear_cache', array( __CLASS__, 'clear_complete_cache' ) );
 
 
 
 
 
 
 
54
  add_action( '_core_updated_successfully', array( __CLASS__, 'clear_complete_cache' ) );
55
  add_action( 'upgrader_process_complete', array( __CLASS__, 'on_upgrade' ), 10, 2 );
56
  add_action( 'switch_theme', array( __CLASS__, 'clear_complete_cache' ) );
 
57
  add_action( 'activated_plugin', array( __CLASS__, 'on_plugin_activation_deactivation' ), 10, 2 );
58
  add_action( 'deactivated_plugin', array( __CLASS__, 'on_plugin_activation_deactivation' ), 10, 2 );
59
  add_action( 'save_post', array( __CLASS__, 'on_save_post' ) );
60
  add_action( 'post_updated', array( __CLASS__, 'on_post_updated' ), 10, 3 );
61
  add_action( 'wp_trash_post', array( __CLASS__, 'on_trash_post' ) );
62
  add_action( 'transition_post_status', array( __CLASS__, 'on_transition_post_status' ), 10, 3 );
63
- add_action( 'pre_comment_approved', array( __CLASS__, 'new_comment' ), 99, 2 );
64
- add_action( 'permalink_structure_changed', array( __CLASS__, 'clear_complete_cache' ) );
65
- // third party
 
 
66
  add_action( 'autoptimize_action_cachepurged', array( __CLASS__, 'clear_complete_cache' ) );
67
 
 
 
 
 
68
  // settings hooks
69
  add_action( 'permalink_structure_changed', array( __CLASS__, 'update_backend' ) );
70
  add_action( 'add_option_cache_enabler', array( __CLASS__, 'on_update_backend' ), 10, 2 );
71
  add_action( 'update_option_cache_enabler', array( __CLASS__, 'on_update_backend' ), 10, 2 );
72
 
73
-
74
  // admin bar hook
75
- add_action( 'admin_bar_menu', array( __CLASS__, 'add_admin_links' ), 90 );
76
 
77
  // admin interface hooks
78
  if ( is_admin() ) {
79
- // multisite
80
- add_action( 'wp_initialize_site', array( __CLASS__, 'install_later' ) );
81
- add_action( 'wp_uninitialize_site', array( __CLASS__, 'uninstall_later' ) );
82
  // settings
83
  add_action( 'admin_init', array( __CLASS__, 'register_settings' ) );
84
  add_action( 'admin_menu', array( __CLASS__, 'add_settings_page' ) );
85
  add_action( 'admin_enqueue_scripts', array( __CLASS__, 'add_admin_resources' ) );
86
- add_filter( 'plugin_row_meta', array( __CLASS__, 'add_plugin_row_meta' ), 10, 2 );
87
- // comments
88
- add_action( 'transition_comment_status', array( __CLASS__, 'change_comment' ), 10, 3 );
89
- add_action( 'comment_post', array( __CLASS__, 'comment_post' ), 99, 2 );
90
- add_action( 'edit_comment', array( __CLASS__, 'edit_comment' ) );
91
  // dashboard
92
  add_filter( 'dashboard_glance_items', array( __CLASS__, 'add_dashboard_cache_size' ) );
93
  add_filter( 'plugin_action_links_' . CE_BASE, array( __CLASS__, 'add_plugin_action_links' ) );
 
94
  // notices
95
  add_action( 'admin_notices', array( __CLASS__, 'requirements_check' ) );
96
  add_action( 'admin_notices', array( __CLASS__, 'cache_cleared_notice' ) );
@@ -103,15 +121,15 @@ final class Cache_Enabler {
103
  * activation hook
104
  *
105
  * @since 1.0.0
106
- * @change 1.5.0
107
  *
108
  * @param boolean $network_wide network activated
109
  */
110
 
111
  public static function on_activation( $network_wide ) {
112
 
113
- // install backend requirements, triggering the settings file(s) to be created
114
- self::each_site( $network_wide, 'self::install_backend' );
115
 
116
  // configure system files
117
  Cache_Enabler_Disk::setup();
@@ -122,7 +140,7 @@ final class Cache_Enabler {
122
  * upgrade hook
123
  *
124
  * @since 1.2.3
125
- * @change 1.5.0
126
  *
127
  * @param WP_Upgrader $obj upgrade instance
128
  * @param array $data update data
@@ -130,15 +148,14 @@ final class Cache_Enabler {
130
 
131
  public static function on_upgrade( $obj, $data ) {
132
 
133
- // if setting enabled clear complete cache on any plugin update
134
- if ( Cache_Enabler_Engine::$settings['clear_complete_cache_on_changed_plugin'] ) {
135
- self::clear_complete_cache();
136
  }
137
 
138
- // check updated plugins
139
  if ( $data['action'] === 'update' && $data['type'] === 'plugin' && array_key_exists( 'plugins', $data ) ) {
140
  foreach ( (array) $data['plugins'] as $plugin_file ) {
141
- // check if Cache Enabler has been updated
142
  if ( $plugin_file === CE_BASE ) {
143
  self::on_ce_update();
144
  }
@@ -151,23 +168,17 @@ final class Cache_Enabler {
151
  * Cache Enabler update actions
152
  *
153
  * @since 1.4.0
154
- * @change 1.5.0
155
  */
156
 
157
  public static function on_ce_update() {
158
 
159
- $network_wide = is_multisite();
160
- $plugin_update = true;
161
-
162
  // clean system files
163
- self::each_site( $network_wide, 'Cache_Enabler_Disk::clean' );
164
 
165
  // configure system files
166
  Cache_Enabler_Disk::setup();
167
 
168
- // update backend requirements, triggering new settings file(s) to be created
169
- self::each_site( $network_wide, 'self::update_backend', array( $plugin_update ) );
170
-
171
  // clear complete cache
172
  self::clear_complete_cache();
173
  }
@@ -177,7 +188,7 @@ final class Cache_Enabler {
177
  * deactivation hook
178
  *
179
  * @since 1.0.0
180
- * @change 1.5.0
181
  *
182
  * @param boolean $network_wide network deactivated
183
  */
@@ -187,13 +198,8 @@ final class Cache_Enabler {
187
  // clean system files
188
  self::each_site( $network_wide, 'Cache_Enabler_Disk::clean' );
189
 
190
- // clear site cache of deactivated site
191
- if ( is_multisite() && ! $network_wide ) {
192
- self::clear_site_cache_by_blog_id( get_current_blog_id() );
193
- // clear complete cache otherwise
194
- } else {
195
- self::clear_complete_cache();
196
- }
197
  }
198
 
199
 
@@ -201,16 +207,13 @@ final class Cache_Enabler {
201
  * uninstall hook
202
  *
203
  * @since 1.0.0
204
- * @change 1.5.0
205
  */
206
 
207
  public static function on_uninstall() {
208
 
209
  // uninstall backend requirements
210
  self::each_site( is_multisite(), 'self::uninstall_backend' );
211
-
212
- // clear complete cache
213
- self::clear_complete_cache();
214
  }
215
 
216
 
@@ -218,7 +221,7 @@ final class Cache_Enabler {
218
  * install on new site in multisite network
219
  *
220
  * @since 1.0.0
221
- * @change 1.4.0
222
  *
223
  * @param WP_Site $new_site new site instance
224
  */
@@ -233,8 +236,8 @@ final class Cache_Enabler {
233
  // switch to blog
234
  switch_to_blog( (int) $new_site->blog_id );
235
 
236
- // install backend requirements, triggering the settings file to be created
237
- self::install_backend();
238
 
239
  // restore blog
240
  restore_current_blog();
@@ -242,51 +245,20 @@ final class Cache_Enabler {
242
 
243
 
244
  /**
245
- * install backend requirements
246
- *
247
- * @since 1.0.0
248
- * @change 1.5.0
249
- */
250
-
251
- private static function install_backend() {
252
-
253
- // if old or current database option exists update backend requirements
254
- if ( get_option( 'cache-enabler' ) || get_option( 'cache_enabler' ) ) {
255
- self::update_backend();
256
- // add default database option otherwise
257
- } else {
258
- $default_settings = self::get_default_settings();
259
- add_option( 'cache_enabler', $default_settings );
260
-
261
- // create settings file if action was not fired, like when in activation hook
262
- if ( ! has_action( 'add_option_cache_enabler' ) ) {
263
- self::on_update_backend( 'cache_enabler', $default_settings );
264
- }
265
- }
266
- }
267
-
268
-
269
- /**
270
- * update backend requirements
271
  *
272
  * @since 1.5.0
273
- * @change 1.5.2
274
  *
275
- * @param $plugin_update whether or not an update is in progress
276
  * @return $new_option_value new or current database option value
277
  */
278
 
279
- public static function update_backend( $plugin_update = false ) {
280
-
281
- // check if backend should be updated
282
- if ( $plugin_update && ! is_plugin_active( CE_BASE ) ) {
283
- return;
284
- }
285
 
286
  // delete user(s) meta key from deleted publishing action (1.5.0)
287
  delete_metadata( 'user', 0, '_clear_post_cache_on_update', '', true );
288
 
289
- // rename database option (1.5.0)
290
  $old_option_value = get_option( 'cache-enabler' );
291
  if ( $old_option_value !== false ) {
292
  delete_option( 'cache-enabler' );
@@ -305,12 +277,12 @@ final class Cache_Enabler {
305
  // merge defined settings into default settings
306
  $new_option_value = wp_parse_args( $old_option_value, self::get_default_settings() );
307
 
308
- // update database option
309
  update_option( 'cache_enabler', $new_option_value );
310
 
311
- // create settings file if action was not fired, like when in upgrade hook or if a database update was unnecessary
312
- if ( ! has_action( 'update_option_cache_enabler' ) ) {
313
- self::on_update_backend( $old_option_value, $new_option_value );
314
  }
315
 
316
  return $new_option_value;
@@ -404,14 +376,14 @@ final class Cache_Enabler {
404
  * plugin activation and deactivation hooks
405
  *
406
  * @since 1.4.0
407
- * @change 1.4.0
408
  */
409
 
410
  public static function on_plugin_activation_deactivation() {
411
 
412
- // if setting enabled clear complete cache on any plugin activation or deactivation
413
- if ( Cache_Enabler_Engine::$settings['clear_complete_cache_on_changed_plugin'] ) {
414
- self::clear_complete_cache();
415
  }
416
  }
417
 
@@ -443,16 +415,43 @@ final class Cache_Enabler {
443
  * get blog IDs
444
  *
445
  * @since 1.0.0
446
- * @change 1.0.0
447
  *
448
- * @return array blog IDs array
449
  */
450
 
451
  private static function get_blog_ids() {
452
 
453
- global $wpdb;
 
 
 
 
 
454
 
455
- return $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
456
  }
457
 
458
 
@@ -460,16 +459,21 @@ final class Cache_Enabler {
460
  * get blog paths
461
  *
462
  * @since 1.4.0
463
- * @change 1.4.0
464
  *
465
- * @return array blog paths array
466
  */
467
 
468
- private static function get_blog_paths() {
 
 
469
 
470
- global $wpdb;
 
 
 
471
 
472
- return $wpdb->get_col( "SELECT path FROM $wpdb->blogs" );
473
  }
474
 
475
 
@@ -510,7 +514,7 @@ final class Cache_Enabler {
510
  * @since 1.0.0
511
  * @change 1.5.0
512
  *
513
- * @return integer $size cache size (bytes)
514
  */
515
 
516
  public static function get_cache_size() {
@@ -530,18 +534,14 @@ final class Cache_Enabler {
530
  * get the cache size transient name
531
  *
532
  * @since 1.5.0
533
- * @change 1.5.0
534
  *
535
- * @param integer $blog_id blog ID
536
- * @return string $transient_name transient name
537
  */
538
 
539
- private static function get_cache_size_transient_name( $blog_id = null ) {
540
-
541
- // set blog ID if provided, get current blog ID otherwise
542
- $blog_id = ( $blog_id ) ? $blog_id : get_current_blog_id();
543
 
544
- $transient_name = 'cache_enabler_cache_size_' . $blog_id;
545
 
546
  return $transient_name;
547
  }
@@ -568,10 +568,10 @@ final class Cache_Enabler {
568
  * get default settings
569
  *
570
  * @since 1.0.0
571
- * @change 1.5.0
572
  *
573
  * @param string $settings_type default `system` settings
574
- * @return array $system_default_settings|$default_settings system or all default settings
575
  */
576
 
577
  private static function get_default_settings( $settings_type = null ) {
@@ -586,19 +586,19 @@ final class Cache_Enabler {
586
  }
587
 
588
  $user_default_settings = array(
589
- 'cache_expires' => 0,
590
- 'cache_expiry_time' => 0,
591
- 'clear_complete_cache_on_saved_post' => 0,
592
- 'clear_complete_cache_on_new_comment' => 0,
593
- 'clear_complete_cache_on_changed_plugin' => 0,
594
- 'compress_cache' => 0,
595
- 'convert_image_urls_to_webp' => 0,
596
- 'excluded_post_ids' => '',
597
- 'excluded_page_paths' => '',
598
- 'excluded_query_strings' => '',
599
- 'excluded_cookies' => '',
600
- 'minify_html' => 0,
601
- 'minify_inline_css_js' => 0,
602
  );
603
 
604
  // merge default settings
@@ -612,7 +612,7 @@ final class Cache_Enabler {
612
  * convert settings to new structure
613
  *
614
  * @since 1.5.0
615
- * @change 1.5.0
616
  *
617
  * @param array $settings settings
618
  * @return array $settings converted settings if applicable, unchanged otherwise
@@ -637,18 +637,26 @@ final class Cache_Enabler {
637
 
638
  // renamed or removed settings
639
  $settings_names = array(
640
- 'expires' => 'cache_expiry_time',
641
- 'new_post' => 'clear_complete_cache_on_saved_post',
642
- 'update_product_stock' => '', // deprecated in 1.5.0
643
- 'new_comment' => 'clear_complete_cache_on_new_comment',
644
- 'clear_on_upgrade' => 'clear_complete_cache_on_changed_plugin',
645
- 'compress' => 'compress_cache',
646
- 'webp' => 'convert_image_urls_to_webp',
647
- 'excl_ids' => 'excluded_post_ids',
648
- 'excl_regexp' => 'excluded_page_paths', // < 1.4.0
649
- 'excl_paths' => 'excluded_page_paths',
650
- 'excl_cookies' => 'excluded_cookies',
651
- 'incl_parameters' => '', // deprecated in 1.5.0
 
 
 
 
 
 
 
 
652
  );
653
 
654
  foreach ( $settings_names as $old_name => $new_name ) {
@@ -745,7 +753,7 @@ final class Cache_Enabler {
745
  }
746
 
747
  // get cache size
748
- $size = self::get_cache_size();
749
 
750
  // display items
751
  $items = array(
@@ -753,7 +761,7 @@ final class Cache_Enabler {
753
  '<a href="%s" title="%s">%s %s</a>',
754
  admin_url( 'options-general.php?page=cache-enabler' ),
755
  esc_html__( 'Refreshes every 15 minutes', 'cache-enabler' ),
756
- ( empty( $size ) ) ? esc_html__( 'Empty', 'cache-enabler' ) : size_format( $size ),
757
  esc_html__( 'Cache Size', 'cache-enabler' )
758
  )
759
  );
@@ -763,30 +771,28 @@ final class Cache_Enabler {
763
 
764
 
765
  /**
766
- * add admin links
767
  *
768
  * @since 1.0.0
769
- * @change 1.5.0
770
  *
771
  * @param object menu properties
772
- *
773
- * @hook mixed user_can_clear_cache
774
  */
775
 
776
- public static function add_admin_links( $wp_admin_bar ) {
777
 
778
  // check user role
779
- if ( ! is_admin_bar_showing() || ! apply_filters( 'user_can_clear_cache', current_user_can( 'manage_options' ) ) ) {
780
  return;
781
  }
782
 
783
- // get clear complete cache button title
784
- $title = ( is_multisite() && is_network_admin() ) ? esc_html__( 'Clear Network Cache', 'cache-enabler' ) : esc_html__( 'Clear Cache', 'cache-enabler' );
785
 
786
- // add "Clear Network Cache" or "Clear Cache" button in admin bar
787
  $wp_admin_bar->add_menu(
788
  array(
789
- 'id' => 'clear-cache',
790
  'href' => wp_nonce_url( add_query_arg( array(
791
  '_cache' => 'cache-enabler',
792
  '_action' => 'clear',
@@ -797,18 +803,18 @@ final class Cache_Enabler {
797
  )
798
  );
799
 
800
- // add "Clear URL Cache" button in admin bar
801
  if ( ! is_admin() ) {
802
  $wp_admin_bar->add_menu(
803
  array(
804
- 'id' => 'clear-url-cache',
805
  'href' => wp_nonce_url( add_query_arg( array(
806
  '_cache' => 'cache-enabler',
807
  '_action' => 'clearurl',
808
  ) ), 'cache_enabler_clear_cache_nonce' ),
809
  'parent' => 'top-secondary',
810
- 'title' => '<span class="ab-item">' . esc_html__( 'Clear URL Cache', 'cache-enabler' ) . '</span>',
811
- 'meta' => array( 'title' => esc_html__( 'Clear URL Cache', 'cache-enabler' ) ),
812
  )
813
  );
814
  }
@@ -850,17 +856,40 @@ final class Cache_Enabler {
850
  }
851
 
852
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
853
  /**
854
  * process clear cache request
855
  *
856
  * @since 1.0.0
857
- * @change 1.5.0
858
  */
859
 
860
  public static function process_clear_cache_request() {
861
 
862
  // check if clear cache request
863
- if ( empty( $_GET['_cache'] ) || empty( $_GET['_action'] ) || $_GET['_cache'] !== 'cache-enabler' && ( $_GET['_action'] !== 'clear' || $_GET['_action'] !== 'clearurl' ) ) {
864
  return;
865
  }
866
 
@@ -870,39 +899,18 @@ final class Cache_Enabler {
870
  }
871
 
872
  // check user role
873
- if ( ! is_admin_bar_showing() || ! apply_filters( 'user_can_clear_cache', current_user_can( 'manage_options' ) ) ) {
874
  return;
875
  }
876
 
877
- // set clear URL without query string and check if installation is in a subdirectory
878
- $installation_dir = parse_url( home_url(), PHP_URL_PATH );
879
- $clear_url = str_replace( $installation_dir, '', home_url() ) . preg_replace( '/\?.*/', '', $_SERVER['REQUEST_URI'] );
880
-
881
- // network activated
882
- if ( is_multisite() ) {
883
- // network admin
884
- if ( is_network_admin() && $_GET['_action'] === 'clear' ) {
885
- // clear complete cache
886
- self::clear_complete_cache();
887
- // site admin
888
- } else {
889
- if ( $_GET['_action'] === 'clearurl' ) {
890
- // clear specific site URL cache
891
- self::clear_page_cache_by_url( $clear_url );
892
- } elseif ( $_GET['_action'] === 'clear' ) {
893
- // clear specific site complete cache
894
- self::clear_site_cache_by_blog_id( get_current_blog_id() );
895
- }
896
- }
897
- // site activated
898
- } else {
899
- if ( $_GET['_action'] === 'clearurl' ) {
900
- // clear URL cache
901
- self::clear_page_cache_by_url( $clear_url );
902
- } elseif ( $_GET['_action'] === 'clear' ) {
903
- // clear complete cache
904
- self::clear_complete_cache();
905
- }
906
  }
907
 
908
  // redirect to same page
@@ -922,22 +930,20 @@ final class Cache_Enabler {
922
  * admin notice after cache has been cleared
923
  *
924
  * @since 1.0.0
925
- * @change 1.5.0
926
- *
927
- * @hook mixed user_can_clear_cache
928
  */
929
 
930
  public static function cache_cleared_notice() {
931
 
932
  // check user role
933
- if ( ! is_admin_bar_showing() || ! apply_filters( 'user_can_clear_cache', current_user_can( 'manage_options' ) ) ) {
934
  return;
935
  }
936
 
937
  if ( get_transient( self::get_cache_cleared_transient_name() ) ) {
938
  echo sprintf(
939
  '<div class="notice notice-success is-dismissible"><p><strong>%s</strong></p></div>',
940
- ( is_multisite() && is_network_admin() ) ? esc_html__( 'Network cache cleared.', 'cache-enabler' ) : esc_html__( 'Cache cleared.', 'cache-enabler' )
941
  );
942
 
943
  delete_transient( self::get_cache_cleared_transient_name() );
@@ -978,7 +984,7 @@ final class Cache_Enabler {
978
 
979
  // if setting disabled and any published post type author changes
980
  if ( $post_before->post_author !== $post_after->post_author ) {
981
- if ( ! Cache_Enabler_Engine::$settings['clear_complete_cache_on_saved_post'] ) {
982
  // clear before the update author archives
983
  self::clear_author_archives_cache_by_user_id( $post_before->post_author );
984
  }
@@ -1019,29 +1025,30 @@ final class Cache_Enabler {
1019
  public static function on_transition_post_status( $new_status, $old_status, $post ) {
1020
 
1021
  // if any published post type status has changed
1022
- if ( $old_status === 'publish' && in_array( $new_status, array( 'future', 'draft', 'pending', 'private') ) ) {
1023
  self::clear_cache_on_post_save( $post->ID );
1024
  }
1025
  }
1026
 
1027
 
1028
  /**
1029
- * clear cache if post comment
1030
  *
1031
  * @since 1.2.0
1032
- * @change 1.4.0
1033
  *
1034
- * @param integer $comment_id comment ID
1035
- * @param mixed $approved approval status
1036
  */
1037
 
1038
- public static function comment_post( $comment_id, $approved ) {
1039
 
1040
- // check if comment is approved
1041
- if ( $approved === 1 ) {
1042
- // if setting enabled clear complete cache on new comment
1043
- if ( Cache_Enabler_Engine::$settings['clear_complete_cache_on_new_comment'] ) {
1044
- self::clear_complete_cache();
 
1045
  } else {
1046
  self::clear_page_cache_by_post_id( get_comment( $comment_id )->comment_post_ID );
1047
  }
@@ -1050,106 +1057,86 @@ final class Cache_Enabler {
1050
 
1051
 
1052
  /**
1053
- * clear cache if edit comment
1054
  *
1055
  * @since 1.0.0
1056
- * @change 1.4.0
1057
  *
1058
- * @param integer $comment_id comment ID
 
1059
  */
1060
 
1061
- public static function edit_comment( $comment_id ) {
1062
 
1063
- // if setting enabled clear complete cache on new comment
1064
- if ( Cache_Enabler_Engine::$settings['clear_complete_cache_on_new_comment'] ) {
1065
- self::clear_complete_cache();
1066
- } else {
1067
  self::clear_page_cache_by_post_id( get_comment( $comment_id )->comment_post_ID );
1068
  }
1069
  }
1070
 
1071
 
1072
  /**
1073
- * clear cache if new comment
1074
  *
1075
  * @since 1.0.0
1076
- * @change 1.0.0
1077
  *
1078
- * @param mixed $approved approval status
1079
- * @param array $comment
1080
- * @return mixed $approved approval status
1081
  */
1082
 
1083
- public static function new_comment( $approved, $comment ) {
1084
 
1085
- // check if comment is approved
1086
- if ( $approved === 1 ) {
1087
- // if setting enabled clear complete cache on new comment
1088
- if ( Cache_Enabler_Engine::$settings['clear_complete_cache_on_new_comment'] ) {
1089
- self::clear_complete_cache();
1090
- } else {
1091
- self::clear_page_cache_by_post_id( $comment['comment_post_ID'] );
1092
- }
1093
  }
1094
-
1095
- return $approved;
1096
  }
1097
 
1098
 
1099
  /**
1100
- * clear cache if comment status changes
1101
  *
1102
  * @since 1.0.0
1103
- * @change 1.0.0
1104
- *
1105
- * @param string $after_status
1106
- * @param string $before_status
1107
- * @param object $comment
1108
  */
1109
 
1110
- public static function change_comment( $after_status, $before_status, $comment ) {
1111
 
1112
- // check if changes occured
1113
- if ( $after_status !== $before_status ) {
1114
- // if setting enabled clear complete cache on new comment
1115
- if ( Cache_Enabler_Engine::$settings['clear_complete_cache_on_new_comment'] ) {
1116
- self::clear_complete_cache();
1117
- } else {
1118
- self::clear_page_cache_by_post_id( $comment->comment_post_ID );
1119
- }
1120
- }
1121
  }
1122
 
1123
 
1124
  /**
1125
- * clear complete cache
1126
  *
1127
- * @since 1.0.0
1128
- * @change 1.5.0
1129
  */
1130
 
1131
- public static function clear_complete_cache() {
1132
-
1133
- // clear complete cache
1134
- Cache_Enabler_Disk::clear_cache();
1135
-
1136
- // delete cache size transient
1137
- delete_transient( self::get_cache_size_transient_name() );
1138
 
1139
- // clear cache post hook
1140
- do_action( 'ce_action_cache_cleared' );
1141
  }
1142
 
1143
 
1144
  /**
1145
- * clear complete cache (deprecated)
1146
  *
1147
- * @deprecated 1.5.0
 
1148
  */
1149
 
1150
- public static function clear_total_cache() {
1151
 
1152
- self::clear_complete_cache();
1153
  }
1154
 
1155
 
@@ -1287,7 +1274,7 @@ final class Cache_Enabler {
1287
  * @change 1.5.0
1288
  *
1289
  * @param integer|string $post_id post ID
1290
- * @param string $clear_type clear the `pagination` or the entire `dir` instead of only the cached `page`
1291
  */
1292
 
1293
  public static function clear_page_cache_by_post_id( $post_id, $clear_type = 'page' ) {
@@ -1311,24 +1298,15 @@ final class Cache_Enabler {
1311
  * clear page cache by URL
1312
  *
1313
  * @since 1.0.0
1314
- * @change 1.5.0
1315
  *
1316
  * @param string $clear_url full URL to potentially cached page
1317
- * @param string $clear_type clear the `pagination` or the entire `dir` instead of only the cached `page`
1318
  */
1319
 
1320
  public static function clear_page_cache_by_url( $clear_url, $clear_type = 'page' ) {
1321
 
1322
- // validate URL
1323
- if ( ! filter_var( $clear_url, FILTER_VALIDATE_URL ) ) {
1324
- return;
1325
- }
1326
-
1327
- // clear URL
1328
  Cache_Enabler_Disk::clear_cache( $clear_url, $clear_type );
1329
-
1330
- // clear cache by URL post hook
1331
- do_action( 'ce_action_cache_by_url_cleared', $clear_url );
1332
  }
1333
 
1334
 
@@ -1336,7 +1314,7 @@ final class Cache_Enabler {
1336
  * clear site cache by blog ID
1337
  *
1338
  * @since 1.4.0
1339
- * @change 1.5.0
1340
  *
1341
  * @param integer|string $blog_id blog ID
1342
  * @param boolean $delete_cache_size_transient whether or not the cache size transient should be deleted
@@ -1344,11 +1322,6 @@ final class Cache_Enabler {
1344
 
1345
  public static function clear_site_cache_by_blog_id( $blog_id, $delete_cache_size_transient = true ) {
1346
 
1347
- // check if network
1348
- if ( ! is_multisite() ) {
1349
- return;
1350
- }
1351
-
1352
  // validate integer
1353
  if ( ! is_int( $blog_id ) ) {
1354
  // if string try to convert to integer
@@ -1364,47 +1337,32 @@ final class Cache_Enabler {
1364
  return;
1365
  }
1366
 
1367
- // get clear URL
1368
- $clear_url = get_home_url( $blog_id );
1369
 
1370
- // network with subdomain configuration
1371
- if ( is_subdomain_install() ) {
1372
- // clear main site or subsite cache
1373
- self::clear_page_cache_by_url( $clear_url, 'dir' );
1374
- // network with subdirectory configuration
1375
- } else {
1376
- // get blog path
1377
- $blog_path = get_blog_details( $blog_id )->path;
1378
-
1379
- // main site
1380
- if ( $blog_path === '/' ) {
1381
- $blog_paths = self::get_blog_paths();
1382
- $blog_domain = parse_url( $clear_url, PHP_URL_HOST );
1383
- $glob_path = Cache_Enabler_Disk::$cache_dir . '/' . $blog_domain;
1384
-
1385
- // get cached page paths
1386
- $page_paths = glob( $glob_path . '/*', GLOB_MARK | GLOB_ONLYDIR );
1387
- foreach ( $page_paths as $page_path ) {
1388
- $page_path = str_replace( $glob_path, '', $page_path );
1389
- // if cached page belongs to main site
1390
- if ( ! in_array( $page_path, $blog_paths ) ) {
1391
- // clear page cache
1392
- self::clear_page_cache_by_url( $clear_url . $page_path, 'dir' );
1393
- }
1394
- }
1395
 
1396
- // clear home page cache
1397
- self::clear_page_cache_by_url( $clear_url );
1398
- // subsite
1399
- } else {
1400
- // clear subsite cache
1401
- self::clear_page_cache_by_url( $clear_url, 'dir' );
1402
- }
1403
  }
1404
 
 
 
 
1405
  // delete cache size transient
1406
  if ( $delete_cache_size_transient ) {
1407
- delete_transient( self::get_cache_size_transient_name( $blog_id ) );
 
 
 
 
 
 
1408
  }
1409
  }
1410
 
@@ -1424,16 +1382,16 @@ final class Cache_Enabler {
1424
  // get post data
1425
  $post = get_post( $post_id );
1426
 
1427
- // if setting enabled clear complete cache
1428
- if ( Cache_Enabler_Engine::$settings['clear_complete_cache_on_saved_post'] ) {
1429
- self::clear_complete_cache();
1430
  // clear page and/or associated cache otherwise
1431
  } else {
1432
- // if updated or trashed
1433
  if ( strtotime( $post->post_modified_gmt ) > strtotime( $post->post_date_gmt ) || $trashed ) {
1434
- // clear page cache
1435
  self::clear_page_cache_by_post_id( $post_id );
1436
  }
 
1437
  // clear associated cache
1438
  self::clear_associated_cache( $post );
1439
  }
@@ -1444,11 +1402,16 @@ final class Cache_Enabler {
1444
  * check plugin requirements
1445
  *
1446
  * @since 1.1.0
1447
- * @change 1.5.0
1448
  */
1449
 
1450
  public static function requirements_check() {
1451
 
 
 
 
 
 
1452
  // check WordPress version
1453
  if ( version_compare( $GLOBALS['wp_version'], CE_MIN_WP . 'alpha', '<' ) ) {
1454
  echo sprintf(
@@ -1578,7 +1541,7 @@ final class Cache_Enabler {
1578
  * validate settings
1579
  *
1580
  * @since 1.0.0
1581
- * @change 1.5.0
1582
  *
1583
  * @param array $settings user defined settings
1584
  * @return array $validated_settings validated settings
@@ -1592,27 +1555,27 @@ final class Cache_Enabler {
1592
  }
1593
 
1594
  $validated_settings = array(
1595
- 'cache_expires' => (int) ( ! empty( $settings['cache_expires'] ) ),
1596
- 'cache_expiry_time' => (int) @$settings['cache_expiry_time'],
1597
- 'clear_complete_cache_on_saved_post' => (int) ( ! empty( $settings['clear_complete_cache_on_saved_post'] ) ),
1598
- 'clear_complete_cache_on_new_comment' => (int) ( ! empty( $settings['clear_complete_cache_on_new_comment'] ) ),
1599
- 'clear_complete_cache_on_changed_plugin' => (int) ( ! empty( $settings['clear_complete_cache_on_changed_plugin'] ) ),
1600
- 'compress_cache' => (int) ( ! empty( $settings['compress_cache'] ) ),
1601
- 'convert_image_urls_to_webp' => (int) ( ! empty( $settings['convert_image_urls_to_webp'] ) ),
1602
- 'excluded_post_ids' => (string) sanitize_text_field( @$settings['excluded_post_ids'] ),
1603
- 'excluded_page_paths' => (string) self::validate_regex( @$settings['excluded_page_paths'] ),
1604
- 'excluded_query_strings' => (string) self::validate_regex( @$settings['excluded_query_strings'] ),
1605
- 'excluded_cookies' => (string) self::validate_regex( @$settings['excluded_cookies'] ),
1606
- 'minify_html' => (int) ( ! empty( $settings['minify_html'] ) ),
1607
- 'minify_inline_css_js' => (int) ( ! empty( $settings['minify_inline_css_js'] ) ),
1608
  );
1609
 
1610
  // add default system settings
1611
  $validated_settings = wp_parse_args( $validated_settings, self::get_default_settings( 'system' ) );
1612
 
1613
- // check if cache should be cleared
1614
- if ( ! empty( $settings['clear_complete_cache_on_saved_settings'] ) ) {
1615
- self::clear_complete_cache();
1616
  set_transient( self::get_cache_cleared_transient_name(), 1 );
1617
  }
1618
 
@@ -1624,14 +1587,14 @@ final class Cache_Enabler {
1624
  * settings page
1625
  *
1626
  * @since 1.0.0
1627
- * @change 1.5.3
1628
  */
1629
 
1630
  public static function settings_page() {
1631
 
1632
  ?>
1633
 
1634
- <div id="cache-enabler-settings" class="wrap">
1635
  <h2>
1636
  <?php esc_html_e( 'Cache Enabler Settings', 'cache-enabler' ); ?>
1637
  </h2>
@@ -1688,24 +1651,23 @@ final class Cache_Enabler {
1688
  <br />
1689
 
1690
  <p class="subheading"><?php esc_html_e( 'Clearing', 'cache-enabler' ); ?></p>
1691
- <label for="clear_complete_cache_on_saved_post">
1692
- <input name="cache_enabler[clear_complete_cache_on_saved_post]" type="checkbox" id="clear_complete_cache_on_saved_post" value="1" <?php checked( '1', Cache_Enabler_Engine::$settings['clear_complete_cache_on_saved_post'] ); ?> />
1693
- <?php esc_html_e( 'Clear the complete cache if any post type has been published, updated, or trashed (instead of only the page and/or associated cache).', 'cache-enabler' ); ?>
1694
- <span class="badge badge--success"><?php esc_html_e( 'Updated', 'cache-enabler' ); ?></span>
1695
  </label>
1696
 
1697
  <br />
1698
 
1699
- <label for="clear_complete_cache_on_new_comment">
1700
- <input name="cache_enabler[clear_complete_cache_on_new_comment]" type="checkbox" id="clear_complete_cache_on_new_comment" value="1" <?php checked( '1', Cache_Enabler_Engine::$settings['clear_complete_cache_on_new_comment'] ); ?> />
1701
- <?php esc_html_e( 'Clear the complete cache if a new comment has been posted (instead of only the page cache).', 'cache-enabler' ); ?>
1702
  </label>
1703
 
1704
  <br />
1705
 
1706
- <label for="clear_complete_cache_on_changed_plugin">
1707
- <input name="cache_enabler[clear_complete_cache_on_changed_plugin]" type="checkbox" id="clear_complete_cache_on_changed_plugin" value="1" <?php checked( '1', Cache_Enabler_Engine::$settings['clear_complete_cache_on_changed_plugin'] ); ?> />
1708
- <?php esc_html_e( 'Clear the complete cache if any plugin has been activated, updated, or deactivated.', 'cache-enabler' ); ?>
1709
  </label>
1710
 
1711
  <br />
@@ -1752,7 +1714,6 @@ final class Cache_Enabler {
1752
  $minify_inline_css_js
1753
  );
1754
  ?>
1755
- <span class="badge badge--success"><?php esc_html_e( 'Updated', 'cache-enabler' ); ?></span>
1756
  </label>
1757
  </fieldset>
1758
  </td>
@@ -1787,7 +1748,7 @@ final class Cache_Enabler {
1787
 
1788
  <br />
1789
 
1790
- <p class="subheading"><?php esc_html_e( 'Query Strings', 'cache-enabler' ); ?><span class="badge badge--success"><?php esc_html_e( 'New', 'cache-enabler' ); ?></span></p>
1791
  <label for="excluded_query_strings">
1792
  <input name="cache_enabler[excluded_query_strings]" type="text" id="excluded_query_strings" value="<?php echo esc_attr( Cache_Enabler_Engine::$settings['excluded_query_strings'] ) ?>" class="regular-text code" />
1793
  <p class="description"><?php esc_html_e( 'A regex matching query strings that should bypass the cache.', 'cache-enabler' ); ?></p>
@@ -1811,7 +1772,7 @@ final class Cache_Enabler {
1811
 
1812
  <p class="submit">
1813
  <input type="submit" class="button-secondary" value="<?php esc_html_e( 'Save Changes', 'cache-enabler' ); ?>" />
1814
- <input name="cache_enabler[clear_complete_cache_on_saved_settings]" type="submit" class="button-primary" value="<?php esc_html_e( 'Save Changes and Clear Cache', 'cache-enabler' ); ?>" />
1815
  </p>
1816
  </form>
1817
  </div>
27
  /**
28
  * settings from database (deprecated)
29
  *
30
+ * @since 1.0.0
31
  * @deprecated 1.5.0
32
  */
33
 
34
  public static $options;
35
 
36
 
37
+ /**
38
+ * fire page cache cleared hook
39
+ *
40
+ * @since 1.6.0
41
+ * @change 1.6.0
42
+ *
43
+ * @var boolean
44
+ */
45
+
46
+ public static $fire_page_cache_cleared_hook = true;
47
+
48
+
49
  /**
50
  * constructor
51
  *
52
  * @since 1.0.0
53
+ * @change 1.6.0
54
  */
55
 
56
  public function __construct() {
57
 
58
  // init hooks
59
  add_action( 'init', array( 'Cache_Enabler_Engine', 'start' ) );
 
60
  add_action( 'init', array( __CLASS__, 'process_clear_cache_request' ) );
61
  add_action( 'init', array( __CLASS__, 'register_textdomain' ) );
62
 
63
+ // public clear cache hooks
64
+ add_action( 'cache_enabler_clear_complete_cache', array( __CLASS__, 'clear_complete_cache' ) );
65
+ add_action( 'cache_enabler_clear_site_cache', array( __CLASS__, 'clear_site_cache' ) );
66
+ add_action( 'cache_enabler_clear_site_cache_by_blog_id', array( __CLASS__, 'clear_site_cache_by_blog_id' ) );
67
+ add_action( 'cache_enabler_clear_page_cache_by_post_id', array( __CLASS__, 'clear_page_cache_by_post_id' ) );
68
+ add_action( 'cache_enabler_clear_page_cache_by_url', array( __CLASS__, 'clear_page_cache_by_url' ) );
69
+ add_action( 'ce_clear_cache', array( __CLASS__, 'clear_complete_cache' ) ); // deprecated in 1.6.0
70
+ add_action( 'ce_clear_post_cache', array( __CLASS__, 'clear_page_cache_by_post_id' ) ); // deprecated in 1.6.0
71
+
72
+ // system clear cache hooks
73
  add_action( '_core_updated_successfully', array( __CLASS__, 'clear_complete_cache' ) );
74
  add_action( 'upgrader_process_complete', array( __CLASS__, 'on_upgrade' ), 10, 2 );
75
  add_action( 'switch_theme', array( __CLASS__, 'clear_complete_cache' ) );
76
+ add_action( 'permalink_structure_changed', array( __CLASS__, 'clear_site_cache' ) );
77
  add_action( 'activated_plugin', array( __CLASS__, 'on_plugin_activation_deactivation' ), 10, 2 );
78
  add_action( 'deactivated_plugin', array( __CLASS__, 'on_plugin_activation_deactivation' ), 10, 2 );
79
  add_action( 'save_post', array( __CLASS__, 'on_save_post' ) );
80
  add_action( 'post_updated', array( __CLASS__, 'on_post_updated' ), 10, 3 );
81
  add_action( 'wp_trash_post', array( __CLASS__, 'on_trash_post' ) );
82
  add_action( 'transition_post_status', array( __CLASS__, 'on_transition_post_status' ), 10, 3 );
83
+ add_action( 'comment_post', array( __CLASS__, 'on_comment_post' ), 99, 2 );
84
+ add_action( 'edit_comment', array( __CLASS__, 'on_edit_comment' ), 10, 2 );
85
+ add_action( 'transition_comment_status', array( __CLASS__, 'on_transition_comment_status' ), 10, 3 );
86
+
87
+ // third party clear cache hooks
88
  add_action( 'autoptimize_action_cachepurged', array( __CLASS__, 'clear_complete_cache' ) );
89
 
90
+ // multisite hooks
91
+ add_action( 'wp_initialize_site', array( __CLASS__, 'install_later' ) );
92
+ add_action( 'wp_uninitialize_site', array( __CLASS__, 'uninstall_later' ) );
93
+
94
  // settings hooks
95
  add_action( 'permalink_structure_changed', array( __CLASS__, 'update_backend' ) );
96
  add_action( 'add_option_cache_enabler', array( __CLASS__, 'on_update_backend' ), 10, 2 );
97
  add_action( 'update_option_cache_enabler', array( __CLASS__, 'on_update_backend' ), 10, 2 );
98
 
 
99
  // admin bar hook
100
+ add_action( 'admin_bar_menu', array( __CLASS__, 'add_admin_bar_items' ), 90 );
101
 
102
  // admin interface hooks
103
  if ( is_admin() ) {
 
 
 
104
  // settings
105
  add_action( 'admin_init', array( __CLASS__, 'register_settings' ) );
106
  add_action( 'admin_menu', array( __CLASS__, 'add_settings_page' ) );
107
  add_action( 'admin_enqueue_scripts', array( __CLASS__, 'add_admin_resources' ) );
 
 
 
 
 
108
  // dashboard
109
  add_filter( 'dashboard_glance_items', array( __CLASS__, 'add_dashboard_cache_size' ) );
110
  add_filter( 'plugin_action_links_' . CE_BASE, array( __CLASS__, 'add_plugin_action_links' ) );
111
+ add_filter( 'plugin_row_meta', array( __CLASS__, 'add_plugin_row_meta' ), 10, 2 );
112
  // notices
113
  add_action( 'admin_notices', array( __CLASS__, 'requirements_check' ) );
114
  add_action( 'admin_notices', array( __CLASS__, 'cache_cleared_notice' ) );
121
  * activation hook
122
  *
123
  * @since 1.0.0
124
+ * @change 1.6.0
125
  *
126
  * @param boolean $network_wide network activated
127
  */
128
 
129
  public static function on_activation( $network_wide ) {
130
 
131
+ // add backend requirements, triggering the settings file(s) to be created
132
+ self::each_site( $network_wide, 'self::update_backend' );
133
 
134
  // configure system files
135
  Cache_Enabler_Disk::setup();
140
  * upgrade hook
141
  *
142
  * @since 1.2.3
143
+ * @change 1.6.0
144
  *
145
  * @param WP_Upgrader $obj upgrade instance
146
  * @param array $data update data
148
 
149
  public static function on_upgrade( $obj, $data ) {
150
 
151
+ // if setting enabled clear site cache on any plugin update
152
+ if ( Cache_Enabler_Engine::$settings['clear_site_cache_on_changed_plugin'] ) {
153
+ self::clear_site_cache();
154
  }
155
 
156
+ // check if Cache Enabler has been updated
157
  if ( $data['action'] === 'update' && $data['type'] === 'plugin' && array_key_exists( 'plugins', $data ) ) {
158
  foreach ( (array) $data['plugins'] as $plugin_file ) {
 
159
  if ( $plugin_file === CE_BASE ) {
160
  self::on_ce_update();
161
  }
168
  * Cache Enabler update actions
169
  *
170
  * @since 1.4.0
171
+ * @change 1.6.0
172
  */
173
 
174
  public static function on_ce_update() {
175
 
 
 
 
176
  // clean system files
177
+ self::each_site( is_multisite(), 'Cache_Enabler_Disk::clean' );
178
 
179
  // configure system files
180
  Cache_Enabler_Disk::setup();
181
 
 
 
 
182
  // clear complete cache
183
  self::clear_complete_cache();
184
  }
188
  * deactivation hook
189
  *
190
  * @since 1.0.0
191
+ * @change 1.6.0
192
  *
193
  * @param boolean $network_wide network deactivated
194
  */
198
  // clean system files
199
  self::each_site( $network_wide, 'Cache_Enabler_Disk::clean' );
200
 
201
+ // clear site(s) cache
202
+ self::each_site( $network_wide, 'self::clear_site_cache' );
 
 
 
 
 
203
  }
204
 
205
 
207
  * uninstall hook
208
  *
209
  * @since 1.0.0
210
+ * @change 1.6.0
211
  */
212
 
213
  public static function on_uninstall() {
214
 
215
  // uninstall backend requirements
216
  self::each_site( is_multisite(), 'self::uninstall_backend' );
 
 
 
217
  }
218
 
219
 
221
  * install on new site in multisite network
222
  *
223
  * @since 1.0.0
224
+ * @change 1.6.0
225
  *
226
  * @param WP_Site $new_site new site instance
227
  */
236
  // switch to blog
237
  switch_to_blog( (int) $new_site->blog_id );
238
 
239
+ // add backend requirements, triggering the settings file to be created
240
+ self::update_backend();
241
 
242
  // restore blog
243
  restore_current_blog();
245
 
246
 
247
  /**
248
+ * add or update backend requirements
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  *
250
  * @since 1.5.0
251
+ * @change 1.6.0
252
  *
 
253
  * @return $new_option_value new or current database option value
254
  */
255
 
256
+ public static function update_backend() {
 
 
 
 
 
257
 
258
  // delete user(s) meta key from deleted publishing action (1.5.0)
259
  delete_metadata( 'user', 0, '_clear_post_cache_on_update', '', true );
260
 
261
+ // maybe rename old database option (1.5.0)
262
  $old_option_value = get_option( 'cache-enabler' );
263
  if ( $old_option_value !== false ) {
264
  delete_option( 'cache-enabler' );
277
  // merge defined settings into default settings
278
  $new_option_value = wp_parse_args( $old_option_value, self::get_default_settings() );
279
 
280
+ // add or update database option
281
  update_option( 'cache_enabler', $new_option_value );
282
 
283
+ // create settings file if action has not been registered for hook yet, like when in activation hook
284
+ if ( has_action( 'update_option_cache_enabler', array( __CLASS__, 'on_update_backend' ) ) === false ) {
285
+ Cache_Enabler_Disk::create_settings_file( $new_option_value );
286
  }
287
 
288
  return $new_option_value;
376
  * plugin activation and deactivation hooks
377
  *
378
  * @since 1.4.0
379
+ * @change 1.6.0
380
  */
381
 
382
  public static function on_plugin_activation_deactivation() {
383
 
384
+ // if setting enabled clear site cache on any plugin activation or deactivation
385
+ if ( Cache_Enabler_Engine::$settings['clear_site_cache_on_changed_plugin'] ) {
386
+ self::clear_site_cache();
387
  }
388
  }
389
 
415
  * get blog IDs
416
  *
417
  * @since 1.0.0
418
+ * @change 1.6.0
419
  *
420
+ * @return array $blog_ids blog IDs
421
  */
422
 
423
  private static function get_blog_ids() {
424
 
425
+ $blog_ids = array( '1' );
426
+
427
+ if ( is_multisite() ) {
428
+ global $wpdb;
429
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
430
+ }
431
 
432
+ return $blog_ids;
433
+ }
434
+
435
+
436
+ /**
437
+ * get blog path
438
+ *
439
+ * @since 1.6.0
440
+ * @change 1.6.0
441
+ *
442
+ * @return string $blog_path blog path from site address URL, empty otherwise
443
+ */
444
+
445
+ public static function get_blog_path() {
446
+
447
+ $site_url_path = parse_url( home_url(), PHP_URL_PATH );
448
+ $site_url_path = rtrim( $site_url_path, '/' );
449
+ $site_url_path_pieces = explode( '/', $site_url_path );
450
+
451
+ // get last piece in case installation is in a subdirectory
452
+ $blog_path = ( ! empty( end( $site_url_path_pieces ) ) ) ? '/' . end( $site_url_path_pieces ) . '/' : '';
453
+
454
+ return $blog_path;
455
  }
456
 
457
 
459
  * get blog paths
460
  *
461
  * @since 1.4.0
462
+ * @change 1.6.0
463
  *
464
+ * @return array $blog_paths blog paths
465
  */
466
 
467
+ public static function get_blog_paths() {
468
+
469
+ $blog_paths = array( '/' );
470
 
471
+ if ( is_multisite() ) {
472
+ global $wpdb;
473
+ $blog_paths = $wpdb->get_col( "SELECT path FROM $wpdb->blogs" );
474
+ }
475
 
476
+ return $blog_paths;
477
  }
478
 
479
 
514
  * @since 1.0.0
515
  * @change 1.5.0
516
  *
517
+ * @return integer $cache_size cache size in bytes
518
  */
519
 
520
  public static function get_cache_size() {
534
  * get the cache size transient name
535
  *
536
  * @since 1.5.0
537
+ * @change 1.6.0
538
  *
539
+ * @return string $transient_name transient name
 
540
  */
541
 
542
+ private static function get_cache_size_transient_name() {
 
 
 
543
 
544
+ $transient_name = 'cache_enabler_cache_size';
545
 
546
  return $transient_name;
547
  }
568
  * get default settings
569
  *
570
  * @since 1.0.0
571
+ * @change 1.6.0
572
  *
573
  * @param string $settings_type default `system` settings
574
+ * @return array $system_default_settings|$default_settings only default system settings or all default settings
575
  */
576
 
577
  private static function get_default_settings( $settings_type = null ) {
586
  }
587
 
588
  $user_default_settings = array(
589
+ 'cache_expires' => 0,
590
+ 'cache_expiry_time' => 0,
591
+ 'clear_site_cache_on_saved_post' => 0,
592
+ 'clear_site_cache_on_new_comment' => 0,
593
+ 'clear_site_cache_on_changed_plugin' => 0,
594
+ 'compress_cache' => 0,
595
+ 'convert_image_urls_to_webp' => 0,
596
+ 'excluded_post_ids' => '',
597
+ 'excluded_page_paths' => '',
598
+ 'excluded_query_strings' => '',
599
+ 'excluded_cookies' => '',
600
+ 'minify_html' => 0,
601
+ 'minify_inline_css_js' => 0,
602
  );
603
 
604
  // merge default settings
612
  * convert settings to new structure
613
  *
614
  * @since 1.5.0
615
+ * @change 1.6.0
616
  *
617
  * @param array $settings settings
618
  * @return array $settings converted settings if applicable, unchanged otherwise
637
 
638
  // renamed or removed settings
639
  $settings_names = array(
640
+ // 1.4.0
641
+ 'excl_regexp' => 'excluded_page_paths',
642
+
643
+ // 1.5.0
644
+ 'expires' => 'cache_expiry_time',
645
+ 'new_post' => 'clear_site_cache_on_saved_post',
646
+ 'update_product_stock' => '', // deprecated
647
+ 'new_comment' => 'clear_site_cache_on_new_comment',
648
+ 'clear_on_upgrade' => 'clear_site_cache_on_changed_plugin',
649
+ 'compress' => 'compress_cache',
650
+ 'webp' => 'convert_image_urls_to_webp',
651
+ 'excl_ids' => 'excluded_post_ids',
652
+ 'excl_paths' => 'excluded_page_paths',
653
+ 'excl_cookies' => 'excluded_cookies',
654
+ 'incl_parameters' => '', // deprecated
655
+
656
+ // 1.6.0
657
+ 'clear_complete_cache_on_saved_post' => 'clear_site_cache_on_saved_post',
658
+ 'clear_complete_cache_on_new_comment' => 'clear_site_cache_on_new_comment',
659
+ 'clear_complete_cache_on_changed_plugin' => 'clear_site_cache_on_changed_plugin',
660
  );
661
 
662
  foreach ( $settings_names as $old_name => $new_name ) {
753
  }
754
 
755
  // get cache size
756
+ $cache_size = self::get_cache_size();
757
 
758
  // display items
759
  $items = array(
761
  '<a href="%s" title="%s">%s %s</a>',
762
  admin_url( 'options-general.php?page=cache-enabler' ),
763
  esc_html__( 'Refreshes every 15 minutes', 'cache-enabler' ),
764
+ ( empty( $cache_size ) ) ? esc_html__( 'Empty', 'cache-enabler' ) : size_format( $cache_size ),
765
  esc_html__( 'Cache Size', 'cache-enabler' )
766
  )
767
  );
771
 
772
 
773
  /**
774
+ * add admin bar items
775
  *
776
  * @since 1.0.0
777
+ * @change 1.6.0
778
  *
779
  * @param object menu properties
 
 
780
  */
781
 
782
+ public static function add_admin_bar_items( $wp_admin_bar ) {
783
 
784
  // check user role
785
+ if ( ! self::user_can_clear_cache() ) {
786
  return;
787
  }
788
 
789
+ // set clear cache button title
790
+ $title = ( is_multisite() && is_network_admin() ) ? esc_html__( 'Clear Network Cache', 'cache-enabler' ) : esc_html__( 'Clear Site Cache', 'cache-enabler' );
791
 
792
+ // add "Clear Network Cache" or "Clear Site Cache" button in admin bar
793
  $wp_admin_bar->add_menu(
794
  array(
795
+ 'id' => 'cache_enabler_clear_cache',
796
  'href' => wp_nonce_url( add_query_arg( array(
797
  '_cache' => 'cache-enabler',
798
  '_action' => 'clear',
803
  )
804
  );
805
 
806
+ // add "Clear Page Cache" button in admin bar
807
  if ( ! is_admin() ) {
808
  $wp_admin_bar->add_menu(
809
  array(
810
+ 'id' => 'cache_enabler_clear_page_cache',
811
  'href' => wp_nonce_url( add_query_arg( array(
812
  '_cache' => 'cache-enabler',
813
  '_action' => 'clearurl',
814
  ) ), 'cache_enabler_clear_cache_nonce' ),
815
  'parent' => 'top-secondary',
816
+ 'title' => '<span class="ab-item">' . esc_html__( 'Clear Page Cache', 'cache-enabler' ) . '</span>',
817
+ 'meta' => array( 'title' => esc_html__( 'Clear Page Cache', 'cache-enabler' ) ),
818
  )
819
  );
820
  }
856
  }
857
 
858
 
859
+ /**
860
+ * check if user can clear cache
861
+ *
862
+ * @since 1.6.0
863
+ * @change 1.6.0
864
+ *
865
+ * @return boolean true if user can clear cache, false otherwise
866
+ */
867
+
868
+ private static function user_can_clear_cache() {
869
+
870
+ if ( apply_filters( 'cache_enabler_user_can_clear_cache', current_user_can( 'manage_options' ) ) ) {
871
+ return true;
872
+ }
873
+
874
+ if ( apply_filters_deprecated( 'user_can_clear_cache', array( current_user_can( 'manage_options' ) ), '1.6.0', 'cache_enabler_user_can_clear_cache' ) ) {
875
+ return true;
876
+ }
877
+
878
+ return false;
879
+ }
880
+
881
+
882
  /**
883
  * process clear cache request
884
  *
885
  * @since 1.0.0
886
+ * @change 1.6.0
887
  */
888
 
889
  public static function process_clear_cache_request() {
890
 
891
  // check if clear cache request
892
+ if ( empty( $_GET['_cache'] ) || empty( $_GET['_action'] ) || $_GET['_cache'] !== 'cache-enabler' || ( $_GET['_action'] !== 'clear' && $_GET['_action'] !== 'clearurl' ) ) {
893
  return;
894
  }
895
 
899
  }
900
 
901
  // check user role
902
+ if ( ! self::user_can_clear_cache() ) {
903
  return;
904
  }
905
 
906
+ // clear page cache
907
+ if ( $_GET['_action'] === 'clearurl' ) {
908
+ // set clear URL without query string
909
+ $clear_url = parse_url( home_url(), PHP_URL_SCHEME ) . '://' . parse_url( home_url(), PHP_URL_HOST ) . preg_replace( '/\?.*/', '', $_SERVER['REQUEST_URI'] );
910
+ self::clear_page_cache_by_url( $clear_url );
911
+ // clear site(s) cache
912
+ } elseif ( $_GET['_action'] === 'clear' ) {
913
+ self::each_site( ( is_multisite() && is_network_admin() ), 'self::clear_site_cache' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
914
  }
915
 
916
  // redirect to same page
930
  * admin notice after cache has been cleared
931
  *
932
  * @since 1.0.0
933
+ * @change 1.6.0
 
 
934
  */
935
 
936
  public static function cache_cleared_notice() {
937
 
938
  // check user role
939
+ if ( ! self::user_can_clear_cache() ) {
940
  return;
941
  }
942
 
943
  if ( get_transient( self::get_cache_cleared_transient_name() ) ) {
944
  echo sprintf(
945
  '<div class="notice notice-success is-dismissible"><p><strong>%s</strong></p></div>',
946
+ ( is_multisite() && is_network_admin() ) ? esc_html__( 'Network cache cleared.', 'cache-enabler' ) : esc_html__( 'Site cache cleared.', 'cache-enabler' )
947
  );
948
 
949
  delete_transient( self::get_cache_cleared_transient_name() );
984
 
985
  // if setting disabled and any published post type author changes
986
  if ( $post_before->post_author !== $post_after->post_author ) {
987
+ if ( ! Cache_Enabler_Engine::$settings['clear_site_cache_on_saved_post'] ) {
988
  // clear before the update author archives
989
  self::clear_author_archives_cache_by_user_id( $post_before->post_author );
990
  }
1025
  public static function on_transition_post_status( $new_status, $old_status, $post ) {
1026
 
1027
  // if any published post type status has changed
1028
+ if ( $old_status === 'publish' && in_array( $new_status, array( 'future', 'draft', 'pending', 'private' ) ) ) {
1029
  self::clear_cache_on_post_save( $post->ID );
1030
  }
1031
  }
1032
 
1033
 
1034
  /**
1035
+ * comment post hook
1036
  *
1037
  * @since 1.2.0
1038
+ * @change 1.6.0
1039
  *
1040
+ * @param integer $comment_id comment ID
1041
+ * @param integer|string $comment_approved comment approval status
1042
  */
1043
 
1044
+ public static function on_comment_post( $comment_id, $comment_approved ) {
1045
 
1046
+ // if new approved comment is posted
1047
+ if ( $comment_approved === 1 ) {
1048
+ // if setting enabled clear site cache
1049
+ if ( Cache_Enabler_Engine::$settings['clear_site_cache_on_new_comment'] ) {
1050
+ self::clear_site_cache();
1051
+ // clear page cache otherwise
1052
  } else {
1053
  self::clear_page_cache_by_post_id( get_comment( $comment_id )->comment_post_ID );
1054
  }
1057
 
1058
 
1059
  /**
1060
+ * edit comment hook
1061
  *
1062
  * @since 1.0.0
1063
+ * @change 1.6.0
1064
  *
1065
+ * @param integer $comment_id comment ID
1066
+ * @param array $comment_data comment data
1067
  */
1068
 
1069
+ public static function on_edit_comment( $comment_id, $comment_data ) {
1070
 
1071
+ $comment_approved = (int) $comment_data['comment_approved'];
1072
+
1073
+ // if approved comment is edited
1074
+ if ( $comment_approved === 1 ) {
1075
  self::clear_page_cache_by_post_id( get_comment( $comment_id )->comment_post_ID );
1076
  }
1077
  }
1078
 
1079
 
1080
  /**
1081
+ * transition comment status hook
1082
  *
1083
  * @since 1.0.0
1084
+ * @change 1.6.0
1085
  *
1086
+ * @param integer|string $new_status new comment status
1087
+ * @param integer|string $old_status old comment status
1088
+ * @param WP_Comment $comment comment instance
1089
  */
1090
 
1091
+ public static function on_transition_comment_status( $new_status, $old_status, $comment ) {
1092
 
1093
+ // if comment status has changed from or to approved
1094
+ if ( $old_status === 'approved' || $new_status === 'approved' ) {
1095
+ self::clear_page_cache_by_post_id( $comment->comment_post_ID );
 
 
 
 
 
1096
  }
 
 
1097
  }
1098
 
1099
 
1100
  /**
1101
+ * clear complete cache
1102
  *
1103
  * @since 1.0.0
1104
+ * @change 1.6.0
 
 
 
 
1105
  */
1106
 
1107
+ public static function clear_complete_cache() {
1108
 
1109
+ // clear site(s) cache
1110
+ self::each_site( is_multisite(), 'self::clear_site_cache' );
1111
+
1112
+ // delete cache size transient(s)
1113
+ self::each_site( is_multisite(), 'delete_transient', array( self::get_cache_size_transient_name() ) );
 
 
 
 
1114
  }
1115
 
1116
 
1117
  /**
1118
+ * clear complete cache (deprecated)
1119
  *
1120
+ * @since 1.0.0
1121
+ * @deprecated 1.5.0
1122
  */
1123
 
1124
+ public static function clear_total_cache() {
 
 
 
 
 
 
1125
 
1126
+ self::clear_complete_cache();
 
1127
  }
1128
 
1129
 
1130
  /**
1131
+ * clear site cache
1132
  *
1133
+ * @since 1.6.0
1134
+ * @change 1.6.0
1135
  */
1136
 
1137
+ public static function clear_site_cache() {
1138
 
1139
+ self::clear_site_cache_by_blog_id( get_current_blog_id() );
1140
  }
1141
 
1142
 
1274
  * @change 1.5.0
1275
  *
1276
  * @param integer|string $post_id post ID
1277
+ * @param string $clear_type clear the `pagination` cache or all `subpages` cache instead of only the `page` cache
1278
  */
1279
 
1280
  public static function clear_page_cache_by_post_id( $post_id, $clear_type = 'page' ) {
1298
  * clear page cache by URL
1299
  *
1300
  * @since 1.0.0
1301
+ * @change 1.6.0
1302
  *
1303
  * @param string $clear_url full URL to potentially cached page
1304
+ * @param string $clear_type clear the `pagination` cache or all `subpages` cache instead of only the `page` cache
1305
  */
1306
 
1307
  public static function clear_page_cache_by_url( $clear_url, $clear_type = 'page' ) {
1308
 
 
 
 
 
 
 
1309
  Cache_Enabler_Disk::clear_cache( $clear_url, $clear_type );
 
 
 
1310
  }
1311
 
1312
 
1314
  * clear site cache by blog ID
1315
  *
1316
  * @since 1.4.0
1317
+ * @change 1.6.0
1318
  *
1319
  * @param integer|string $blog_id blog ID
1320
  * @param boolean $delete_cache_size_transient whether or not the cache size transient should be deleted
1322
 
1323
  public static function clear_site_cache_by_blog_id( $blog_id, $delete_cache_size_transient = true ) {
1324
 
 
 
 
 
 
1325
  // validate integer
1326
  if ( ! is_int( $blog_id ) ) {
1327
  // if string try to convert to integer
1337
  return;
1338
  }
1339
 
1340
+ // disable page cache cleared hook
1341
+ self::$fire_page_cache_cleared_hook = false;
1342
 
1343
+ // get site URL
1344
+ $site_url = get_home_url( $blog_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1345
 
1346
+ // get site objects
1347
+ $site_objects = Cache_Enabler_Disk::get_site_objects( $site_url );
1348
+
1349
+ // clear all first level pages and subpages cache
1350
+ foreach ( $site_objects as $site_object ) {
1351
+ self::clear_page_cache_by_url( trailingslashit( $site_url ) . $site_object, 'subpages' );
 
1352
  }
1353
 
1354
+ // clear home page cache
1355
+ self::clear_page_cache_by_url( $site_url );
1356
+
1357
  // delete cache size transient
1358
  if ( $delete_cache_size_transient ) {
1359
+ if ( is_multisite() ) {
1360
+ switch_to_blog( $blog_id );
1361
+ delete_transient( self::get_cache_size_transient_name() );
1362
+ restore_current_blog();
1363
+ } else {
1364
+ delete_transient( self::get_cache_size_transient_name() );
1365
+ }
1366
  }
1367
  }
1368
 
1382
  // get post data
1383
  $post = get_post( $post_id );
1384
 
1385
+ // if setting enabled clear site cache
1386
+ if ( Cache_Enabler_Engine::$settings['clear_site_cache_on_saved_post'] ) {
1387
+ self::clear_site_cache();
1388
  // clear page and/or associated cache otherwise
1389
  } else {
1390
+ // if updated or trashed clear page cache
1391
  if ( strtotime( $post->post_modified_gmt ) > strtotime( $post->post_date_gmt ) || $trashed ) {
 
1392
  self::clear_page_cache_by_post_id( $post_id );
1393
  }
1394
+
1395
  // clear associated cache
1396
  self::clear_associated_cache( $post );
1397
  }
1402
  * check plugin requirements
1403
  *
1404
  * @since 1.1.0
1405
+ * @change 1.6.0
1406
  */
1407
 
1408
  public static function requirements_check() {
1409
 
1410
+ // check user role
1411
+ if ( ! current_user_can( 'manage_options' ) ) {
1412
+ return;
1413
+ }
1414
+
1415
  // check WordPress version
1416
  if ( version_compare( $GLOBALS['wp_version'], CE_MIN_WP . 'alpha', '<' ) ) {
1417
  echo sprintf(
1541
  * validate settings
1542
  *
1543
  * @since 1.0.0
1544
+ * @change 1.6.0
1545
  *
1546
  * @param array $settings user defined settings
1547
  * @return array $validated_settings validated settings
1555
  }
1556
 
1557
  $validated_settings = array(
1558
+ 'cache_expires' => (int) ( ! empty( $settings['cache_expires'] ) ),
1559
+ 'cache_expiry_time' => (int) @$settings['cache_expiry_time'],
1560
+ 'clear_site_cache_on_saved_post' => (int) ( ! empty( $settings['clear_site_cache_on_saved_post'] ) ),
1561
+ 'clear_site_cache_on_new_comment' => (int) ( ! empty( $settings['clear_site_cache_on_new_comment'] ) ),
1562
+ 'clear_site_cache_on_changed_plugin' => (int) ( ! empty( $settings['clear_site_cache_on_changed_plugin'] ) ),
1563
+ 'compress_cache' => (int) ( ! empty( $settings['compress_cache'] ) ),
1564
+ 'convert_image_urls_to_webp' => (int) ( ! empty( $settings['convert_image_urls_to_webp'] ) ),
1565
+ 'excluded_post_ids' => (string) sanitize_text_field( @$settings['excluded_post_ids'] ),
1566
+ 'excluded_page_paths' => (string) self::validate_regex( @$settings['excluded_page_paths'] ),
1567
+ 'excluded_query_strings' => (string) self::validate_regex( @$settings['excluded_query_strings'] ),
1568
+ 'excluded_cookies' => (string) self::validate_regex( @$settings['excluded_cookies'] ),
1569
+ 'minify_html' => (int) ( ! empty( $settings['minify_html'] ) ),
1570
+ 'minify_inline_css_js' => (int) ( ! empty( $settings['minify_inline_css_js'] ) ),
1571
  );
1572
 
1573
  // add default system settings
1574
  $validated_settings = wp_parse_args( $validated_settings, self::get_default_settings( 'system' ) );
1575
 
1576
+ // check if site cache should be cleared
1577
+ if ( ! empty( $settings['clear_site_cache_on_saved_settings'] ) ) {
1578
+ self::clear_site_cache();
1579
  set_transient( self::get_cache_cleared_transient_name(), 1 );
1580
  }
1581
 
1587
  * settings page
1588
  *
1589
  * @since 1.0.0
1590
+ * @change 1.6.0
1591
  */
1592
 
1593
  public static function settings_page() {
1594
 
1595
  ?>
1596
 
1597
+ <div id="cache_enabler_settings" class="wrap">
1598
  <h2>
1599
  <?php esc_html_e( 'Cache Enabler Settings', 'cache-enabler' ); ?>
1600
  </h2>
1651
  <br />
1652
 
1653
  <p class="subheading"><?php esc_html_e( 'Clearing', 'cache-enabler' ); ?></p>
1654
+ <label for="clear_site_cache_on_saved_post">
1655
+ <input name="cache_enabler[clear_site_cache_on_saved_post]" type="checkbox" id="clear_site_cache_on_saved_post" value="1" <?php checked( '1', Cache_Enabler_Engine::$settings['clear_site_cache_on_saved_post'] ); ?> />
1656
+ <?php esc_html_e( 'Clear the site cache if any post type has been published, updated, or trashed (instead of only the page and/or associated cache).', 'cache-enabler' ); ?>
 
1657
  </label>
1658
 
1659
  <br />
1660
 
1661
+ <label for="clear_site_cache_on_new_comment">
1662
+ <input name="cache_enabler[clear_site_cache_on_new_comment]" type="checkbox" id="clear_site_cache_on_new_comment" value="1" <?php checked( '1', Cache_Enabler_Engine::$settings['clear_site_cache_on_new_comment'] ); ?> />
1663
+ <?php esc_html_e( 'Clear the site cache if a new comment has been posted (instead of only the page cache).', 'cache-enabler' ); ?>
1664
  </label>
1665
 
1666
  <br />
1667
 
1668
+ <label for="clear_site_cache_on_changed_plugin">
1669
+ <input name="cache_enabler[clear_site_cache_on_changed_plugin]" type="checkbox" id="clear_site_cache_on_changed_plugin" value="1" <?php checked( '1', Cache_Enabler_Engine::$settings['clear_site_cache_on_changed_plugin'] ); ?> />
1670
+ <?php esc_html_e( 'Clear the site cache if any plugin has been activated, updated, or deactivated.', 'cache-enabler' ); ?>
1671
  </label>
1672
 
1673
  <br />
1714
  $minify_inline_css_js
1715
  );
1716
  ?>
 
1717
  </label>
1718
  </fieldset>
1719
  </td>
1748
 
1749
  <br />
1750
 
1751
+ <p class="subheading"><?php esc_html_e( 'Query Strings', 'cache-enabler' ); ?></p>
1752
  <label for="excluded_query_strings">
1753
  <input name="cache_enabler[excluded_query_strings]" type="text" id="excluded_query_strings" value="<?php echo esc_attr( Cache_Enabler_Engine::$settings['excluded_query_strings'] ) ?>" class="regular-text code" />
1754
  <p class="description"><?php esc_html_e( 'A regex matching query strings that should bypass the cache.', 'cache-enabler' ); ?></p>
1772
 
1773
  <p class="submit">
1774
  <input type="submit" class="button-secondary" value="<?php esc_html_e( 'Save Changes', 'cache-enabler' ); ?>" />
1775
+ <input name="cache_enabler[clear_site_cache_on_saved_settings]" type="submit" class="button-primary" value="<?php esc_html_e( 'Save Changes and Clear Site Cache', 'cache-enabler' ); ?>" />
1776
  </p>
1777
  </form>
1778
  </div>
inc/cache_enabler_cli.class.php CHANGED
@@ -61,7 +61,7 @@ class Cache_Enabler_CLI {
61
  if ( empty( $assoc_args['ids'] ) && empty( $assoc_args['urls'] ) && empty( $assoc_args['sites'] ) ) {
62
  Cache_Enabler::clear_complete_cache();
63
 
64
- return WP_CLI::success( ( is_multisite() && is_plugin_active_for_network( CE_BASE ) ) ? esc_html__( 'Network cache cleared.', 'cache-enabler' ) : esc_html__( 'Cache cleared.', 'cache-enabler' ) );
65
  }
66
 
67
  // clear page(s) cache by post ID(s) and/or URL(s)
61
  if ( empty( $assoc_args['ids'] ) && empty( $assoc_args['urls'] ) && empty( $assoc_args['sites'] ) ) {
62
  Cache_Enabler::clear_complete_cache();
63
 
64
+ return WP_CLI::success( ( is_multisite() ) ? esc_html__( 'Network cache cleared.', 'cache-enabler' ) : esc_html__( 'Site cache cleared.', 'cache-enabler' ) );
65
  }
66
 
67
  // clear page(s) cache by post ID(s) and/or URL(s)
inc/cache_enabler_disk.class.php CHANGED
@@ -16,6 +16,8 @@ final class Cache_Enabler_Disk {
16
  *
17
  * @since 1.5.0
18
  * @change 1.5.0
 
 
19
  */
20
 
21
  public static $cache_dir = WP_CONTENT_DIR . '/cache/cache-enabler';
@@ -26,21 +28,34 @@ final class Cache_Enabler_Disk {
26
  *
27
  * @since 1.5.0
28
  * @change 1.5.0
 
 
29
  */
30
 
31
  private static $settings_dir = WP_CONTENT_DIR . '/settings/cache-enabler';
32
 
33
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  /**
35
  * base cache file names
36
  *
37
  * @since 1.0.7
38
- * @change 1.5.0
39
  *
40
  * @var string
41
  */
42
 
43
- const CACHE_FILE_GLOB = '*index*';
44
  const CACHE_FILE_HTML = 'index.html';
45
  const CACHE_FILE_GZIP = 'index.html.gz';
46
  const CACHE_FILE_WEBP_HTML = 'index-webp.html';
@@ -177,46 +192,41 @@ final class Cache_Enabler_Disk {
177
  * get cache size
178
  *
179
  * @since 1.0.0
180
- * @change 1.5.0
181
  *
182
- * @param string $dir file system directory
183
- * @return integer $size size in bytes
184
  */
185
 
186
  public static function cache_size( $dir = null ) {
187
 
188
- // set directory if provided, get directory otherwise
189
- $dir = ( $dir ) ? $dir : self::cache_file_dir_path( home_url() );
190
 
191
- // validate directory
192
- if ( ! is_dir( $dir ) ) {
193
- return;
 
 
 
194
  }
195
 
196
- // get directory data
197
- $dir_objects = self::get_dir_objects( $dir );
198
-
199
- // check if empty
200
  if ( empty( $dir_objects ) ) {
201
- return;
202
  }
203
 
204
- $size = 0;
205
-
206
  foreach ( $dir_objects as $dir_object ) {
207
  // get full path
208
- $dir_object = $dir . '/' . $dir_object;
209
 
210
- // check if directory
211
  if ( is_dir( $dir_object ) ) {
212
- $size += self::cache_size( $dir_object );
213
- // check if file otherwise
214
  } elseif ( is_file( $dir_object ) ) {
215
- $size += filesize( $dir_object );
216
  }
217
  }
218
 
219
- return $size;
220
  }
221
 
222
 
@@ -224,43 +234,79 @@ final class Cache_Enabler_Disk {
224
  * clear cached page(s)
225
  *
226
  * @since 1.0.0
227
- * @change 1.5.0
228
  *
229
  * @param string $clear_url full URL to potentially cached page
230
- * @param string $clear_type clear the `pagination` or the entire `dir` instead of only the cached `page`
231
  */
232
 
233
- public static function clear_cache( $clear_url = null, $clear_type = null ) {
234
 
235
- // check if complete cache should be cleared
236
- if ( empty( $clear_url ) || empty( $clear_type ) ) {
237
- self::clear_dir( self::$cache_dir );
238
  return;
239
  }
240
 
241
  // get directory
242
  $dir = self::cache_file_dir_path( $clear_url );
243
 
244
- // delete all cached variants in directory
245
- array_map( 'unlink', glob( $dir . self::CACHE_FILE_GLOB ) );
246
-
247
- // check if pagination needs to be cleared
248
- if ( $clear_type === 'pagination' ) {
249
- // get pagination base
250
- $pagination_base = $GLOBALS['wp_rewrite']->pagination_base;
251
- if ( strlen( $pagination_base ) > 0 ) {
252
- $pagination_dir = $dir . $pagination_base;
253
- // clear pagination page(s) cache
254
- self::clear_dir( $pagination_dir );
255
- }
256
  }
257
 
258
- // get directory data
259
- $dir_objects = self::get_dir_objects( $dir );
 
260
 
261
- // check if directory is now empty or if it needs to be cleared anyways
262
- if ( empty( $dir_objects ) || $clear_type === 'dir' ) {
263
  self::clear_dir( $dir );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  }
265
  }
266
 
@@ -269,64 +315,45 @@ final class Cache_Enabler_Disk {
269
  * clear directory
270
  *
271
  * @since 1.0.0
272
- * @change 1.5.0
273
  *
274
- * @param string $dir directory
 
275
  */
276
 
277
- private static function clear_dir( $dir ) {
278
 
279
  // remove trailing slash
280
  $dir = untrailingslashit( $dir );
281
 
282
- // validate directory
283
  if ( ! is_dir( $dir ) ) {
284
  return;
285
  }
286
 
287
- // get directory data
288
  $dir_objects = self::get_dir_objects( $dir );
289
 
290
- // check if directory is empty
291
- if ( empty( $dir_objects ) ) {
292
- // delete empty directory
293
- @rmdir( $dir );
294
-
295
- // clear file status cache
296
- clearstatcache();
297
-
298
- // get parent directory
299
- $parent_dir = preg_replace( '/\/[^\/]+$/', '', $dir );
300
-
301
- // get parent directory data
302
- $parent_dir_objects = self::get_dir_objects( $parent_dir );
303
-
304
- // check if parent directory is also empty
305
- if ( empty( $parent_dir_objects ) ) {
306
- self::clear_dir( $parent_dir );
307
- }
308
-
309
- return;
310
- }
311
-
312
  foreach ( $dir_objects as $dir_object ) {
313
  // get full path
314
  $dir_object = $dir . '/' . $dir_object;
315
 
316
- // check if directory
317
- if ( is_dir( $dir_object ) ) {
318
  self::clear_dir( $dir_object );
319
- // check if file otherwise
320
  } elseif ( is_file( $dir_object ) ) {
 
321
  unlink( $dir_object );
322
  }
323
  }
324
 
325
- // delete directory
326
  @rmdir( $dir );
327
 
328
  // clear file status cache
329
  clearstatcache();
 
 
 
330
  }
331
 
332
 
@@ -334,7 +361,7 @@ final class Cache_Enabler_Disk {
334
  * create files for cache
335
  *
336
  * @since 1.0.0
337
- * @change 1.5.0
338
  *
339
  * @param string $page_contents content of a page from the output buffer
340
  */
@@ -369,8 +396,11 @@ final class Cache_Enabler_Disk {
369
  // magic regex rule
370
  $image_urls_regex = '#(?:(?:(src|srcset|data-[^=]+)\s*=|(url)\()\s*[\'\"]?\s*)\K(?:[^\?\"\'\s>]+)(?:\.jpe?g|\.png)(?:\s\d+[wx][^\"\'>]*)?(?=\/?[\"\'\s\)>])(?=[^<{]*(?:\)[^<{]*\}|>))#i';
371
 
372
- // call the WebP converter callback
373
- $converted_page_contents = apply_filters( 'cache_enabler_disk_webp_converted_data', preg_replace_callback( $image_urls_regex, 'self::convert_webp', $page_contents ) );
 
 
 
374
 
375
  // create default WebP file
376
  self::create_cache_file( self::cache_file_webp_html(), $converted_page_contents . $cache_signature . ' (' . self::cache_file_scheme() . ' webp html) -->' );
@@ -420,9 +450,10 @@ final class Cache_Enabler_Disk {
420
  * create settings file
421
  *
422
  * @since 1.2.3
423
- * @change 1.5.0
424
  *
425
- * @param array $settings settings from database
 
426
  */
427
 
428
  public static function create_settings_file( $settings ) {
@@ -437,15 +468,15 @@ final class Cache_Enabler_Disk {
437
  return;
438
  }
439
 
440
- // get settings file
441
- $settings_file = self::get_settings_file();
442
 
443
  // make directory if necessary
444
- if ( ! wp_mkdir_p( dirname( $settings_file ) ) ) {
445
  wp_die( 'Unable to create directory.' );
446
  }
447
 
448
- // create new settings file
449
  $new_settings_file_contents = '<?php' . PHP_EOL;
450
  $new_settings_file_contents .= '/**' . PHP_EOL;
451
  $new_settings_file_contents .= ' * Cache Enabler settings for ' . home_url() . PHP_EOL;
@@ -458,7 +489,9 @@ final class Cache_Enabler_Disk {
458
  $new_settings_file_contents .= PHP_EOL;
459
  $new_settings_file_contents .= 'return ' . var_export( $settings, true ) . ';';
460
 
461
- file_put_contents( $settings_file, $new_settings_file_contents );
 
 
462
  }
463
 
464
 
@@ -466,7 +499,7 @@ final class Cache_Enabler_Disk {
466
  * get cache file directory path
467
  *
468
  * @since 1.0.0
469
- * @change 1.5.0
470
  *
471
  * @param string $url full URL to potentially cached page
472
  * @return string $file_dir_path file directory path to new or potentially cached page
@@ -474,6 +507,13 @@ final class Cache_Enabler_Disk {
474
 
475
  private static function cache_file_dir_path( $url = null ) {
476
 
 
 
 
 
 
 
 
477
  $file_dir_path = sprintf(
478
  '%s/%s%s',
479
  self::$cache_dir,
@@ -487,11 +527,6 @@ final class Cache_Enabler_Disk {
487
  )
488
  );
489
 
490
- if ( is_file( $file_dir_path ) ) {
491
- header( $_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found', true, 404 );
492
- exit;
493
- }
494
-
495
  // add trailing slash
496
  $file_dir_path = rtrim( $file_dir_path, '/\\' ) . '/';
497
 
@@ -651,7 +686,7 @@ final class Cache_Enabler_Disk {
651
  * get settings file name
652
  *
653
  * @since 1.5.5
654
- * @change 1.5.5
655
  *
656
  * @param boolean $fallback whether or not fallback settings file name should be returned
657
  * @param boolean $skip_blog_path whether or not blog path should be included in settings file name
@@ -668,11 +703,8 @@ final class Cache_Enabler_Disk {
668
 
669
  // subdirectory network
670
  if ( is_multisite() && defined( 'SUBDOMAIN_INSTALL' ) && ! SUBDOMAIN_INSTALL ) {
671
- $url_path = parse_url( home_url(), PHP_URL_PATH );
672
- $url_path = rtrim( $url_path, '/' ); // remove trailing slash if there happens to be one
673
- $url_path_pieces = explode( '/', $url_path );
674
- $blog_path = ( ! empty( end( $url_path_pieces ) ) ) ? end( $url_path_pieces ) : ''; // get last piece in case installation is in a subdirectory
675
- $settings_file_name .= ( ! empty( $blog_path ) ) ? '.' . $blog_path : '';
676
  }
677
 
678
  $settings_file_name .= '.php';
@@ -689,7 +721,7 @@ final class Cache_Enabler_Disk {
689
  // subdirectory network
690
  if ( defined( 'SUBDOMAIN_INSTALL' ) && ! SUBDOMAIN_INSTALL && ! $skip_blog_path ) {
691
  $url_path = $_SERVER['REQUEST_URI'];
692
- $url_path = trim( $url_path, '/'); // remove leading and trailing slash(es)
693
 
694
  if ( ! empty( $url_path ) ) {
695
  $url_path_regex = str_replace( '/', '|', $url_path );
@@ -745,7 +777,7 @@ final class Cache_Enabler_Disk {
745
  * get settings from settings file
746
  *
747
  * @since 1.5.0
748
- * @change 1.5.5
749
  *
750
  * @return array $settings current settings from settings file
751
  */
@@ -770,9 +802,13 @@ final class Cache_Enabler_Disk {
770
  }
771
  }
772
 
773
- // create settings file if cache exists but settings file does not
774
  if ( empty( $settings ) && class_exists( 'Cache_Enabler' ) ) {
775
- self::create_settings_file( Cache_Enabler::get_settings() );
 
 
 
 
776
  }
777
 
778
  return $settings;
@@ -783,7 +819,7 @@ final class Cache_Enabler_Disk {
783
  * get directory file system objects
784
  *
785
  * @since 1.4.7
786
- * @change 1.5.0
787
  *
788
  * @param string $dir directory path
789
  * @return array $dir_objects directory objects
@@ -791,13 +827,60 @@ final class Cache_Enabler_Disk {
791
 
792
  private static function get_dir_objects( $dir ) {
793
 
794
- // scan directory
795
- $dir_data = @scandir( $dir );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
796
 
797
- if ( is_array( $dir_data ) ) {
798
- $dir_objects = array_diff( $dir_data, array( '..', '.' ) );
799
- return $dir_objects;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
800
  }
 
 
801
  }
802
 
803
 
@@ -904,20 +987,15 @@ final class Cache_Enabler_Disk {
904
  $image_urls = explode( ',', $full_match );
905
 
906
  foreach ( $image_urls as &$image_url ) {
907
- // remove spaces if there are any
908
  $image_url = trim( $image_url, ' ' );
909
- // append .webp extension
910
- $image_url_webp = preg_replace( $image_extension_regex, '$1.webp', $image_url );
911
- // get WebP image path
912
  $image_path_webp = self::image_path( $image_url_webp );
913
 
914
  // check if WebP image exists
915
  if ( is_file( $image_path_webp ) ) {
916
  $image_url = $image_url_webp;
917
  } else {
918
- // remove default extension
919
- $image_url_webp = preg_replace( $image_extension_regex, '', $image_url_webp );
920
- // get WebP image path
921
  $image_path_webp = self::image_path( $image_url_webp );
922
 
923
  // check if WebP image exists
@@ -938,12 +1016,10 @@ final class Cache_Enabler_Disk {
938
  * minify HTML
939
  *
940
  * @since 1.0.0
941
- * @change 1.5.0
942
  *
943
  * @param string $page_contents content of a page from the output buffer
944
  * @return string $minified_html|$page_contents minified page contents if applicable, unchanged otherwise
945
- *
946
- * @hook array cache_minify_ignore_tags
947
  */
948
 
949
  private static function minify_html( $page_contents ) {
@@ -958,8 +1034,11 @@ final class Cache_Enabler_Disk {
958
  return $page_contents;
959
  }
960
 
961
- // HTML tags to ignore
962
- $ignore_tags = (array) apply_filters( 'cache_minify_ignore_tags', array( 'textarea', 'pre', 'code' ) );
 
 
 
963
 
964
  // if selected exclude inline CSS and JavaScript
965
  if ( ! Cache_Enabler_Engine::$settings['minify_inline_css_js'] ) {
@@ -996,6 +1075,33 @@ final class Cache_Enabler_Disk {
996
  }
997
 
998
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
999
  /**
1000
  * delete settings file
1001
  *
@@ -1019,6 +1125,7 @@ final class Cache_Enabler_Disk {
1019
  /**
1020
  * delete asset (deprecated)
1021
  *
 
1022
  * @deprecated 1.5.0
1023
  */
1024
 
16
  *
17
  * @since 1.5.0
18
  * @change 1.5.0
19
+ *
20
+ * @var string
21
  */
22
 
23
  public static $cache_dir = WP_CONTENT_DIR . '/cache/cache-enabler';
28
  *
29
  * @since 1.5.0
30
  * @change 1.5.0
31
+ *
32
+ * @var string
33
  */
34
 
35
  private static $settings_dir = WP_CONTENT_DIR . '/settings/cache-enabler';
36
 
37
 
38
+ /**
39
+ * directories cleared
40
+ *
41
+ * @since 1.6.0
42
+ * @change 1.6.0
43
+ *
44
+ * @var array
45
+ */
46
+
47
+ private static $dir_cleared = array();
48
+
49
+
50
  /**
51
  * base cache file names
52
  *
53
  * @since 1.0.7
54
+ * @change 1.6.0
55
  *
56
  * @var string
57
  */
58
 
 
59
  const CACHE_FILE_HTML = 'index.html';
60
  const CACHE_FILE_GZIP = 'index.html.gz';
61
  const CACHE_FILE_WEBP_HTML = 'index-webp.html';
192
  * get cache size
193
  *
194
  * @since 1.0.0
195
+ * @change 1.6.0
196
  *
197
+ * @param string $dir directory path
198
+ * @return integer $cache_size cache size in bytes
199
  */
200
 
201
  public static function cache_size( $dir = null ) {
202
 
203
+ $cache_size = 0;
 
204
 
205
+ // get directory objects if provided directory exists
206
+ if ( is_dir( $dir ) ) {
207
+ $dir_objects = self::get_dir_objects( $dir );
208
+ // get site objects otherwise
209
+ } else {
210
+ $dir_objects = self::get_site_objects( home_url() );
211
  }
212
 
213
+ // check if directory is empty
 
 
 
214
  if ( empty( $dir_objects ) ) {
215
+ return $cache_size;
216
  }
217
 
 
 
218
  foreach ( $dir_objects as $dir_object ) {
219
  // get full path
220
+ $dir_object = trailingslashit( ( $dir ) ? $dir : ( self::$cache_dir . '/' . parse_url( home_url(), PHP_URL_HOST ) . parse_url( home_url(), PHP_URL_PATH ) ) ) . $dir_object;
221
 
 
222
  if ( is_dir( $dir_object ) ) {
223
+ $cache_size += self::cache_size( $dir_object );
 
224
  } elseif ( is_file( $dir_object ) ) {
225
+ $cache_size += filesize( $dir_object );
226
  }
227
  }
228
 
229
+ return $cache_size;
230
  }
231
 
232
 
234
  * clear cached page(s)
235
  *
236
  * @since 1.0.0
237
+ * @change 1.6.0
238
  *
239
  * @param string $clear_url full URL to potentially cached page
240
+ * @param string $clear_type clear the `pagination` cache or all `subpages` cache instead of only the `page` cache
241
  */
242
 
243
+ public static function clear_cache( $clear_url = null, $clear_type = 'page' ) {
244
 
245
+ // check if cache should be cleared
246
+ if ( empty( $clear_url ) ) {
 
247
  return;
248
  }
249
 
250
  // get directory
251
  $dir = self::cache_file_dir_path( $clear_url );
252
 
253
+ // check if directory exists
254
+ if ( ! is_dir( $dir ) ) {
255
+ return;
 
 
 
 
 
 
 
 
 
256
  }
257
 
258
+ if ( $clear_type === 'dir' ) {
259
+ $clear_type = 'subpages';
260
+ }
261
 
262
+ // check if page and subpages cache should be cleared
263
+ if ( $clear_type === 'subpages' ) {
264
  self::clear_dir( $dir );
265
+ // clear page and/or pagination cache otherwise
266
+ } else {
267
+ $skip_child_dir = true;
268
+ self::clear_dir( $dir, $skip_child_dir );
269
+
270
+ if ( $clear_type === 'pagination' ) {
271
+ $pagination_base = $GLOBALS['wp_rewrite']->pagination_base;
272
+ if ( strlen( $pagination_base ) > 0 ) {
273
+ $pagination_dir = $dir . $pagination_base;
274
+ self::clear_dir( $pagination_dir );
275
+ }
276
+ }
277
+ }
278
+
279
+ // delete parent directory if empty
280
+ self::delete_parent_dir( $dir );
281
+
282
+ // cache cleared hooks
283
+ foreach ( self::$dir_cleared as $dir => $dir_objects ) {
284
+ if ( strpos( $dir, self::$cache_dir ) !== false ) {
285
+ if ( Cache_Enabler::$fire_page_cache_cleared_hook ) {
286
+ if ( ! empty( preg_grep( '/index/', $dir_objects ) ) ) {
287
+ // page cache cleared hook
288
+ $page_cleared_url = parse_url( home_url(), PHP_URL_SCHEME ) . '://' . str_replace( self::$cache_dir . '/', '', $dir );
289
+ $page_cleared_id = url_to_postid( $page_cleared_url );
290
+ do_action( 'cache_enabler_page_cache_cleared', $page_cleared_url, $page_cleared_id );
291
+ do_action( 'ce_action_cache_by_url_cleared', $page_cleared_url ); // deprecated in 1.6.0
292
+ }
293
+ } else {
294
+ // complete cache cleared hook
295
+ if ( $dir === self::$cache_dir ) {
296
+ do_action( 'cache_enabler_complete_cache_cleared' );
297
+ do_action( 'ce_action_cache_cleared' ); // deprecated in 1.6.0
298
+ }
299
+
300
+ // site cache cleared hook
301
+ if ( $dir === untrailingslashit( self::cache_file_dir_path( home_url() ) ) ) {
302
+ $site_cleared_url = home_url();
303
+ $site_cleared_id = get_current_blog_id();
304
+ do_action( 'cache_enabler_site_cache_cleared', $site_cleared_url, $site_cleared_id );
305
+ }
306
+ }
307
+
308
+ unset( self::$dir_cleared[ $dir ] );
309
+ }
310
  }
311
  }
312
 
315
  * clear directory
316
  *
317
  * @since 1.0.0
318
+ * @change 1.6.0
319
  *
320
+ * @param string $dir directory path
321
+ * @param boolean $skip_child_dir whether or not child directories should be skipped
322
  */
323
 
324
+ private static function clear_dir( $dir, $skip_child_dir = false ) {
325
 
326
  // remove trailing slash
327
  $dir = untrailingslashit( $dir );
328
 
329
+ // check if directory exists
330
  if ( ! is_dir( $dir ) ) {
331
  return;
332
  }
333
 
334
+ // get directory objects
335
  $dir_objects = self::get_dir_objects( $dir );
336
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
  foreach ( $dir_objects as $dir_object ) {
338
  // get full path
339
  $dir_object = $dir . '/' . $dir_object;
340
 
341
+ if ( is_dir( $dir_object ) && ! $skip_child_dir ) {
 
342
  self::clear_dir( $dir_object );
 
343
  } elseif ( is_file( $dir_object ) ) {
344
+ // clear cached page variant
345
  unlink( $dir_object );
346
  }
347
  }
348
 
349
+ // delete directory if empty
350
  @rmdir( $dir );
351
 
352
  // clear file status cache
353
  clearstatcache();
354
+
355
+ // add cleared directory to directories cleared list
356
+ self::$dir_cleared[ $dir ] = $dir_objects;
357
  }
358
 
359
 
361
  * create files for cache
362
  *
363
  * @since 1.0.0
364
+ * @change 1.6.0
365
  *
366
  * @param string $page_contents content of a page from the output buffer
367
  */
396
  // magic regex rule
397
  $image_urls_regex = '#(?:(?:(src|srcset|data-[^=]+)\s*=|(url)\()\s*[\'\"]?\s*)\K(?:[^\?\"\'\s>]+)(?:\.jpe?g|\.png)(?:\s\d+[wx][^\"\'>]*)?(?=\/?[\"\'\s\)>])(?=[^<{]*(?:\)[^<{]*\}|>))#i';
398
 
399
+ // page contents after WebP conversion hook
400
+ $converted_page_contents = apply_filters( 'cache_enabler_page_contents_after_webp_conversion', preg_replace_callback( $image_urls_regex, 'self::convert_webp', $page_contents ) );
401
+
402
+ // deprecated page contents after WebP conversion hook
403
+ $converted_page_contents = apply_filters_deprecated( 'cache_enabler_disk_webp_converted_data', array( $converted_page_contents ), '1.6.0', 'cache_enabler_page_contents_after_webp_conversion' );
404
 
405
  // create default WebP file
406
  self::create_cache_file( self::cache_file_webp_html(), $converted_page_contents . $cache_signature . ' (' . self::cache_file_scheme() . ' webp html) -->' );
450
  * create settings file
451
  *
452
  * @since 1.2.3
453
+ * @change 1.6.0
454
  *
455
+ * @param array $settings settings from database
456
+ * @return string $new_settings_file new settings file
457
  */
458
 
459
  public static function create_settings_file( $settings ) {
468
  return;
469
  }
470
 
471
+ // get new settings file
472
+ $new_settings_file = self::get_settings_file();
473
 
474
  // make directory if necessary
475
+ if ( ! wp_mkdir_p( dirname( $new_settings_file ) ) ) {
476
  wp_die( 'Unable to create directory.' );
477
  }
478
 
479
+ // add new settings file contents
480
  $new_settings_file_contents = '<?php' . PHP_EOL;
481
  $new_settings_file_contents .= '/**' . PHP_EOL;
482
  $new_settings_file_contents .= ' * Cache Enabler settings for ' . home_url() . PHP_EOL;
489
  $new_settings_file_contents .= PHP_EOL;
490
  $new_settings_file_contents .= 'return ' . var_export( $settings, true ) . ';';
491
 
492
+ file_put_contents( $new_settings_file, $new_settings_file_contents );
493
+
494
+ return $new_settings_file;
495
  }
496
 
497
 
499
  * get cache file directory path
500
  *
501
  * @since 1.0.0
502
+ * @change 1.6.0
503
  *
504
  * @param string $url full URL to potentially cached page
505
  * @return string $file_dir_path file directory path to new or potentially cached page
507
 
508
  private static function cache_file_dir_path( $url = null ) {
509
 
510
+ $file_dir_path = '';
511
+
512
+ // validate URL
513
+ if ( $url && ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
514
+ return $file_dir_path;
515
+ }
516
+
517
  $file_dir_path = sprintf(
518
  '%s/%s%s',
519
  self::$cache_dir,
527
  )
528
  );
529
 
 
 
 
 
 
530
  // add trailing slash
531
  $file_dir_path = rtrim( $file_dir_path, '/\\' ) . '/';
532
 
686
  * get settings file name
687
  *
688
  * @since 1.5.5
689
+ * @change 1.6.0
690
  *
691
  * @param boolean $fallback whether or not fallback settings file name should be returned
692
  * @param boolean $skip_blog_path whether or not blog path should be included in settings file name
703
 
704
  // subdirectory network
705
  if ( is_multisite() && defined( 'SUBDOMAIN_INSTALL' ) && ! SUBDOMAIN_INSTALL ) {
706
+ $blog_path = Cache_Enabler::get_blog_path();
707
+ $settings_file_name .= ( ! empty( $blog_path ) ) ? '.' . trim( $blog_path, '/' ) : '';
 
 
 
708
  }
709
 
710
  $settings_file_name .= '.php';
721
  // subdirectory network
722
  if ( defined( 'SUBDOMAIN_INSTALL' ) && ! SUBDOMAIN_INSTALL && ! $skip_blog_path ) {
723
  $url_path = $_SERVER['REQUEST_URI'];
724
+ $url_path = trim( $url_path, '/');
725
 
726
  if ( ! empty( $url_path ) ) {
727
  $url_path_regex = str_replace( '/', '|', $url_path );
777
  * get settings from settings file
778
  *
779
  * @since 1.5.0
780
+ * @change 1.6.0
781
  *
782
  * @return array $settings current settings from settings file
783
  */
802
  }
803
  }
804
 
805
+ // create settings file if it does not exist and in late engine start
806
  if ( empty( $settings ) && class_exists( 'Cache_Enabler' ) ) {
807
+ $new_settings_file = self::create_settings_file( Cache_Enabler::get_settings() );
808
+
809
+ if ( is_file( $new_settings_file ) ) {
810
+ $settings = include_once $new_settings_file;
811
+ }
812
  }
813
 
814
  return $settings;
819
  * get directory file system objects
820
  *
821
  * @since 1.4.7
822
+ * @change 1.6.0
823
  *
824
  * @param string $dir directory path
825
  * @return array $dir_objects directory objects
827
 
828
  private static function get_dir_objects( $dir ) {
829
 
830
+ $dir_objects = scandir( $dir );
831
+
832
+ if ( is_array( $dir_objects ) ) {
833
+ $dir_objects = array_diff( $dir_objects, array( '..', '.' ) );
834
+ } else {
835
+ $dir_objects = array();
836
+ }
837
+
838
+ return $dir_objects;
839
+ }
840
+
841
+
842
+ /**
843
+ * get site file system objects
844
+ *
845
+ * @since 1.6.0
846
+ * @change 1.6.0
847
+ *
848
+ * @param string $site_url site URL
849
+ * @return array $site_objects site objects
850
+ */
851
+
852
+ public static function get_site_objects( $site_url ) {
853
 
854
+ $site_objects = array();
855
+
856
+ // get directory
857
+ $dir = self::cache_file_dir_path( $site_url );
858
+
859
+ // check if directory exists
860
+ if ( ! is_dir( $dir ) ) {
861
+ return $site_objects;
862
+ }
863
+
864
+ // get site objects
865
+ $site_objects = self::get_dir_objects( $dir );
866
+
867
+ // maybe filter subdirectory network site objects
868
+ if ( is_multisite() && ! is_subdomain_install() ) {
869
+ $blog_path = Cache_Enabler::get_blog_path();
870
+ $blog_paths = Cache_Enabler::get_blog_paths();
871
+
872
+ // check if main site in subdirectory network
873
+ if ( ! in_array( $blog_path, $blog_paths ) ) {
874
+ foreach ( $site_objects as $key => $site_object ) {
875
+ // delete site object if it does not belong to main site
876
+ if ( in_array( '/' . $site_object . '/', $blog_paths ) ) {
877
+ unset( $site_objects[ $key ] );
878
+ }
879
+ }
880
+ }
881
  }
882
+
883
+ return $site_objects;
884
  }
885
 
886
 
987
  $image_urls = explode( ',', $full_match );
988
 
989
  foreach ( $image_urls as &$image_url ) {
 
990
  $image_url = trim( $image_url, ' ' );
991
+ $image_url_webp = preg_replace( $image_extension_regex, '$1.webp', $image_url ); // append .webp extension
 
 
992
  $image_path_webp = self::image_path( $image_url_webp );
993
 
994
  // check if WebP image exists
995
  if ( is_file( $image_path_webp ) ) {
996
  $image_url = $image_url_webp;
997
  } else {
998
+ $image_url_webp = preg_replace( $image_extension_regex, '', $image_url_webp ); // remove default extension
 
 
999
  $image_path_webp = self::image_path( $image_url_webp );
1000
 
1001
  // check if WebP image exists
1016
  * minify HTML
1017
  *
1018
  * @since 1.0.0
1019
+ * @change 1.6.0
1020
  *
1021
  * @param string $page_contents content of a page from the output buffer
1022
  * @return string $minified_html|$page_contents minified page contents if applicable, unchanged otherwise
 
 
1023
  */
1024
 
1025
  private static function minify_html( $page_contents ) {
1034
  return $page_contents;
1035
  }
1036
 
1037
+ // HTML tags to ignore hook
1038
+ $ignore_tags = (array) apply_filters( 'cache_enabler_minify_html_ignore_tags', array( 'textarea', 'pre', 'code' ) );
1039
+
1040
+ // deprecated HTML tags to ignore hook
1041
+ $ignore_tags = (array) apply_filters_deprecated( 'cache_minify_ignore_tags', array( $ignore_tags ), '1.6.0', 'cache_enabler_minify_html_ignore_tags' );
1042
 
1043
  // if selected exclude inline CSS and JavaScript
1044
  if ( ! Cache_Enabler_Engine::$settings['minify_inline_css_js'] ) {
1075
  }
1076
 
1077
 
1078
+ /**
1079
+ * delete empty parent directory
1080
+ *
1081
+ * @since 1.6.0
1082
+ * @change 1.6.0
1083
+ *
1084
+ * @param string $dir directory path
1085
+ */
1086
+
1087
+ private static function delete_parent_dir( $dir ) {
1088
+
1089
+ $parent_dir = dirname( $dir );
1090
+ $parent_dir_objects = self::get_dir_objects( $parent_dir );
1091
+
1092
+ if ( empty( $parent_dir_objects ) ) {
1093
+ // delete empty parent directory
1094
+ @rmdir( $parent_dir );
1095
+
1096
+ // add deleted parent directory to directories cleared list
1097
+ self::$dir_cleared[ $parent_dir ] = $parent_dir_objects;
1098
+
1099
+ // delete parent directory if empty
1100
+ self::delete_parent_dir( $parent_dir );
1101
+ }
1102
+ }
1103
+
1104
+
1105
  /**
1106
  * delete settings file
1107
  *
1125
  /**
1126
  * delete asset (deprecated)
1127
  *
1128
+ * @since 1.0.0
1129
  * @deprecated 1.5.0
1130
  */
1131
 
inc/cache_enabler_engine.class.php CHANGED
@@ -15,7 +15,9 @@ final class Cache_Enabler_Engine {
15
  * start engine
16
  *
17
  * @since 1.5.2
18
- * @change 1.5.2
 
 
19
  */
20
 
21
  public static function start() {
@@ -23,6 +25,8 @@ final class Cache_Enabler_Engine {
23
  if ( self::should_start() ) {
24
  new self();
25
  }
 
 
26
  }
27
 
28
  /**
@@ -53,15 +57,15 @@ final class Cache_Enabler_Engine {
53
  * constructor
54
  *
55
  * @since 1.5.0
56
- * @change 1.5.2
57
  */
58
 
59
  public function __construct() {
60
 
61
- // get settings from disk if cache exists
62
- if ( Cache_Enabler_Disk::cache_exists() ) {
63
  self::$settings = Cache_Enabler_Disk::get_settings();
64
- // get settings from database otherwise
65
  } elseif ( class_exists( 'Cache_Enabler' ) ) {
66
  self::$settings = Cache_Enabler::get_settings();
67
  // set deprecated settings
@@ -92,7 +96,7 @@ final class Cache_Enabler_Engine {
92
  return false;
93
  }
94
 
95
- // check if Ajax request in early start
96
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX && ! class_exists( 'Cache_Enabler' ) ) {
97
  return false;
98
  }
@@ -121,37 +125,16 @@ final class Cache_Enabler_Engine {
121
  }
122
 
123
 
124
- /**
125
- * check if output buffering should start
126
- *
127
- * @since 1.5.0
128
- * @change 1.5.0
129
- *
130
- * @return boolean true if output buffering should start, false otherwise
131
- */
132
-
133
- public static function should_buffer() {
134
-
135
- if ( self::$started && self::is_index() ) {
136
- return true;
137
- }
138
-
139
- return false;
140
- }
141
-
142
-
143
  /**
144
  * start output buffering
145
  *
146
  * @since 1.5.0
147
- * @change 1.5.0
148
  */
149
 
150
  public static function start_buffering() {
151
 
152
- if ( self::should_buffer() ) {
153
- ob_start( 'self::end_buffering' );
154
- }
155
  }
156
 
157
 
@@ -159,13 +142,11 @@ final class Cache_Enabler_Engine {
159
  * end output buffering and cache page if applicable
160
  *
161
  * @since 1.0.0
162
- * @change 1.5.0
163
  *
164
  * @param string $page_contents content of a page from the output buffer
165
  * @param integer $phase bitmask of PHP_OUTPUT_HANDLER_* constants
166
  * @return string $page_contents content of a page from the output buffer
167
- *
168
- * @hook string cache_enabler_before_store
169
  */
170
 
171
  private static function end_buffering( $page_contents, $phase ) {
@@ -175,7 +156,9 @@ final class Cache_Enabler_Engine {
175
  return $page_contents;
176
  }
177
 
178
- $page_contents = apply_filters( 'cache_enabler_before_store', $page_contents );
 
 
179
 
180
  Cache_Enabler_Disk::cache_page( $page_contents );
181
 
@@ -185,12 +168,12 @@ final class Cache_Enabler_Engine {
185
 
186
 
187
  /**
188
- * check if installation directory index
189
  *
190
  * @since 1.0.0
191
  * @change 1.5.0
192
  *
193
- * @return boolean true if installation directory index, false otherwise
194
  */
195
 
196
  private static function is_index() {
@@ -324,6 +307,25 @@ final class Cache_Enabler_Engine {
324
  }
325
 
326
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  /**
328
  * check if mobile template
329
  *
@@ -343,17 +345,20 @@ final class Cache_Enabler_Engine {
343
  * check if cache should be bypassed
344
  *
345
  * @since 1.0.0
346
- * @change 1.5.2
347
  *
348
  * @return boolean true if cache should be bypassed, false otherwise
349
- *
350
- * @hook boolean bypass_cache
351
  */
352
 
353
  private static function bypass_cache() {
354
 
355
  // bypass cache hook
356
- if ( apply_filters( 'bypass_cache', false ) ) {
 
 
 
 
 
357
  return true;
358
  }
359
 
@@ -367,11 +372,6 @@ final class Cache_Enabler_Engine {
367
  return true;
368
  }
369
 
370
- // check WP_CACHE constant
371
- if ( defined( 'WP_CACHE' ) && ! WP_CACHE ) {
372
- return true;
373
- }
374
-
375
  // check DONOTCACHEPAGE constant
376
  if ( defined( 'DONOTCACHEPAGE' ) && DONOTCACHEPAGE ) {
377
  return true;
@@ -384,7 +384,7 @@ final class Cache_Enabler_Engine {
384
 
385
  // check conditional tags when output buffering has ended
386
  if ( class_exists( 'WP' ) ) {
387
- if ( is_admin() || is_search() || is_feed() || is_trackback() || is_robots() || is_preview() || post_password_required() || self::is_mobile() ) {
388
  return true;
389
  }
390
  }
@@ -397,16 +397,18 @@ final class Cache_Enabler_Engine {
397
  * deliver cache
398
  *
399
  * @since 1.5.0
400
- * @change 1.5.5
 
 
401
  */
402
 
403
  public static function deliver_cache() {
404
 
405
- if ( ! self::$started || Cache_Enabler_Disk::cache_expired() || self::bypass_cache() ) {
406
- return;
 
407
  }
408
 
409
- readfile( Cache_Enabler_Disk::get_cache() );
410
- exit;
411
  }
412
  }
15
  * start engine
16
  *
17
  * @since 1.5.2
18
+ * @change 1.6.0
19
+ *
20
+ * @return boolean true if engine started, false otherwise
21
  */
22
 
23
  public static function start() {
25
  if ( self::should_start() ) {
26
  new self();
27
  }
28
+
29
+ return self::$started;
30
  }
31
 
32
  /**
57
  * constructor
58
  *
59
  * @since 1.5.0
60
+ * @change 1.6.0
61
  */
62
 
63
  public function __construct() {
64
 
65
+ // get settings from disk if directory index file
66
+ if ( self::is_index() ) {
67
  self::$settings = Cache_Enabler_Disk::get_settings();
68
+ // get settings from database in late engine start otherwise
69
  } elseif ( class_exists( 'Cache_Enabler' ) ) {
70
  self::$settings = Cache_Enabler::get_settings();
71
  // set deprecated settings
96
  return false;
97
  }
98
 
99
+ // check if Ajax request in early engine start
100
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX && ! class_exists( 'Cache_Enabler' ) ) {
101
  return false;
102
  }
125
  }
126
 
127
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  /**
129
  * start output buffering
130
  *
131
  * @since 1.5.0
132
+ * @change 1.6.0
133
  */
134
 
135
  public static function start_buffering() {
136
 
137
+ ob_start( 'self::end_buffering' );
 
 
138
  }
139
 
140
 
142
  * end output buffering and cache page if applicable
143
  *
144
  * @since 1.0.0
145
+ * @change 1.6.0
146
  *
147
  * @param string $page_contents content of a page from the output buffer
148
  * @param integer $phase bitmask of PHP_OUTPUT_HANDLER_* constants
149
  * @return string $page_contents content of a page from the output buffer
 
 
150
  */
151
 
152
  private static function end_buffering( $page_contents, $phase ) {
156
  return $page_contents;
157
  }
158
 
159
+ $page_contents = apply_filters( 'cache_enabler_page_contents_before_store', $page_contents );
160
+
161
+ $page_contents = apply_filters_deprecated( 'cache_enabler_before_store', array( $page_contents ), '1.6.0', 'cache_enabler_page_contents_before_store' );
162
 
163
  Cache_Enabler_Disk::cache_page( $page_contents );
164
 
168
 
169
 
170
  /**
171
+ * check if directory index file
172
  *
173
  * @since 1.0.0
174
  * @change 1.5.0
175
  *
176
+ * @return boolean true if directory index file, false otherwise
177
  */
178
 
179
  private static function is_index() {
307
  }
308
 
309
 
310
+ /**
311
+ * check if search page
312
+ *
313
+ * @since 1.6.0
314
+ * @change 1.6.0
315
+ *
316
+ * @return boolean true if search page, false otherwise
317
+ */
318
+
319
+ private static function is_search() {
320
+
321
+ if ( apply_filters( 'cache_enabler_exclude_search', is_search() ) ) {
322
+ return true;
323
+ }
324
+
325
+ return false;
326
+ }
327
+
328
+
329
  /**
330
  * check if mobile template
331
  *
345
  * check if cache should be bypassed
346
  *
347
  * @since 1.0.0
348
+ * @change 1.6.0
349
  *
350
  * @return boolean true if cache should be bypassed, false otherwise
 
 
351
  */
352
 
353
  private static function bypass_cache() {
354
 
355
  // bypass cache hook
356
+ if ( apply_filters( 'cache_enabler_bypass_cache', false ) ) {
357
+ return true;
358
+ }
359
+
360
+ // deprecated bypass cache hook
361
+ if ( apply_filters_deprecated( 'bypass_cache', array( false ), '1.6.0', 'cache_enabler_bypass_cache' ) ) {
362
  return true;
363
  }
364
 
372
  return true;
373
  }
374
 
 
 
 
 
 
375
  // check DONOTCACHEPAGE constant
376
  if ( defined( 'DONOTCACHEPAGE' ) && DONOTCACHEPAGE ) {
377
  return true;
384
 
385
  // check conditional tags when output buffering has ended
386
  if ( class_exists( 'WP' ) ) {
387
+ if ( is_admin() || self::is_search() || is_feed() || is_trackback() || is_robots() || is_preview() || post_password_required() || self::is_mobile() ) {
388
  return true;
389
  }
390
  }
397
  * deliver cache
398
  *
399
  * @since 1.5.0
400
+ * @change 1.6.0
401
+ *
402
+ * @return boolean false if cached page was not delivered
403
  */
404
 
405
  public static function deliver_cache() {
406
 
407
+ if ( Cache_Enabler_Disk::cache_exists() && ! Cache_Enabler_Disk::cache_expired() && ! self::bypass_cache() ) {
408
+ readfile( Cache_Enabler_Disk::get_cache() );
409
+ exit;
410
  }
411
 
412
+ return false;
 
413
  }
414
  }
readme.txt CHANGED
@@ -80,31 +80,43 @@ When combined with Optimus, the WordPress Cache Enabler allows you to easily del
80
 
81
  == Changelog ==
82
 
83
- = 1.5.5 =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
 
85
  * Update advanced cache to prevent potential errors (#161)
86
  * Update getting settings to create settings file if cache exists but settings file does not (#159)
87
  * Fix getting settings file edge cases (#158)
88
  * Fix cache expiry
89
 
90
  = 1.5.4 =
91
-
92
  * Update default query string exclusion (#155)
93
  * Update cache engine start check (#155)
94
 
95
  = 1.5.3 =
96
-
97
  * Add default query string exclusion (#154)
98
 
99
  = 1.5.2 =
100
-
101
  * Update late cache engine start to be on the `init` hook instead of `plugins_loaded` (#153)
102
  * Add deprecated variable that was previously deleted to improve backwards compatibility (#153)
103
  * Fix WP-CLI notice errors (#153)
104
  * Fix creating settings file on plugin update
105
 
106
  = 1.5.1 =
107
-
108
  * Fix getting settings file
109
 
110
  = 1.5.0 =
80
 
81
  == Changelog ==
82
 
83
+ = 1.6.0 =
84
+ * Update cache clearing behavior for multisite networks when permalink structure has changed to prevent unnecessary cache clearing (#170)
85
+ * Update cache clearing behavior for comment actions to prevent unnecessary cache clearing (#169)
86
+ * Update output buffer timing to start earlier on the `advanced-cache.php` drop-in instead of the `init` hook (#168)
87
+ * Update plugin upgrade handling (#166)
88
+ * Add `cache_enabler_clear_complete_cache`, `cache_enabler_clear_site_cache`, `cache_enabler_clear_site_cache_by_blog_id`, `cache_enabler_clear_page_cache_by_post_id`, `cache_enabler_clear_page_cache_by_url`, `cache_enabler_complete_cache_cleared`, `cache_enabler_site_cache_cleared`, and `cache_enabler_page_cache_cleared` action hooks (#170)
89
+ * Add `cache_enabler_user_can_clear_cache`, `cache_enabler_exclude_search`, `cache_enabler_bypass_cache`, `cache_enabler_page_contents_before_store`, `cache_enabler_page_contents_after_webp_conversion`, `cache_enabler_minify_html_ignore_tags` filter hooks (#170)
90
+ * Add site cache clearing behavior (#167)
91
+ * Fix requirement notices being shown to all users (#170)
92
+ * Fix setting up new site in multisite network when new site is added outside of the admin interface (#170)
93
+ * Fix getting cache size for main site in subdirectory network (#164)
94
+ * Fix deleting cache size transient (#164)
95
+ * Fix cache clearing (#164 and #167)
96
+ * Fix clear cache request validation
97
+ * Deprecate `ce_clear_cache`, `ce_clear_post_cache`, `ce_action_cache_cleared`, and `ce_action_cache_by_url_cleared` action hooks in favor of replacements (#170)
98
+ * Deprecate `user_can_clear_cache`, `bypass_cache`, `cache_enabler_before_store`, `cache_enabler_disk_webp_converted_data`, and `cache_minify_ignore_tags` filter hooks in favor of replacements (#170)
99
 
100
+ = 1.5.5 =
101
  * Update advanced cache to prevent potential errors (#161)
102
  * Update getting settings to create settings file if cache exists but settings file does not (#159)
103
  * Fix getting settings file edge cases (#158)
104
  * Fix cache expiry
105
 
106
  = 1.5.4 =
 
107
  * Update default query string exclusion (#155)
108
  * Update cache engine start check (#155)
109
 
110
  = 1.5.3 =
 
111
  * Add default query string exclusion (#154)
112
 
113
  = 1.5.2 =
 
114
  * Update late cache engine start to be on the `init` hook instead of `plugins_loaded` (#153)
115
  * Add deprecated variable that was previously deleted to improve backwards compatibility (#153)
116
  * Fix WP-CLI notice errors (#153)
117
  * Fix creating settings file on plugin update
118
 
119
  = 1.5.1 =
 
120
  * Fix getting settings file
121
 
122
  = 1.5.0 =