W3 Total Cache - Version 2.2.7

Version Description

  • Fix: Updated database cache connection class to avoid deprecated warnings in WordPress 6.1
  • Fix: Redis: Fixed handling of retry interval and timeout options for usage statistics
  • Enhancement: Redis: Added TLS/SSL certificate verification option
  • Enhancement: Page cache: Added query string exemptions
Download this release

Release Info

Developer joemoto
Plugin Icon 128x128 W3 Total Cache
Version 2.2.7
Comparing to
See all releases

Code changes from version 2.2.6 to 2.2.7

Cache_Redis.php CHANGED
@@ -450,6 +450,49 @@ class Cache_Redis extends Cache_Base {
450
  return $v;
451
  }
452
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
  /**
454
  * Get accessor.
455
  *
@@ -471,93 +514,15 @@ class Cache_Redis extends Cache_Base {
471
  $this->_accessors[ $index ] = null;
472
  } else {
473
  try {
474
- $server = $this->_servers[ $index ];
 
 
475
  $accessor = new \Redis();
476
 
477
- $phpredis_modern = version_compare( phpversion( 'redis' ), '5', '>=' );
478
-
479
- if ( substr( $server, 0, 5 ) === 'unix:' ) {
480
- if ( $this->_persistent ) {
481
- if ( $phpredis_modern ) {
482
- $accessor->pconnect(
483
- trim( substr( $server, 5 ) ),
484
- null,
485
- $this->_timeout,
486
- $this->_instance_id . '_' . $this->_dbid,
487
- $this->_retry_interval,
488
- $this->_read_timeout
489
- );
490
- } else { // Old phpredis only supports a subset of parameters.
491
- $accessor->pconnect(
492
- trim( substr( $server, 5 ) ),
493
- null,
494
- $this->_timeout,
495
- $this->_instance_id . '_' . $this->_dbid,
496
- $this->_retry_interval
497
- );
498
- }
499
- } else {
500
- if ( $phpredis_modern ) {
501
- $accessor->connect(
502
- trim( substr( $server, 5 ) ),
503
- $this->_timeout,
504
- null,
505
- $this->_retry_interval,
506
- $this->_read_timeout
507
- );
508
- } else { // Old phpredis only supports a subset of parameters.
509
- $accessor->connect(
510
- trim( substr( $server, 5 ) ),
511
- $this->_timeout,
512
- null,
513
- $this->_retry_interval
514
- );
515
- }
516
- }
517
  } else {
518
- list( $ip, $port ) = Util_Content::endpoint_to_host_port( $server, null );
519
-
520
- if ( $this->_persistent ) {
521
- if ( $phpredis_modern ) {
522
- $accessor->pconnect(
523
- $ip,
524
- $port,
525
- $this->_timeout,
526
- $this->_instance_id . '_' . $this->_dbid,
527
- $this->_retry_interval,
528
- $this->_read_timeout
529
- );
530
- } else { // Old phpredis only supports a subset of parameters.
531
- $accessor->pconnect(
532
- $ip,
533
- $port,
534
- $this->_timeout,
535
- $this->_instance_id . '_' . $this->_dbid,
536
- $this->_retry_interval
537
- );
538
- }
539
- } else {
540
- if ( $phpredis_modern ) {
541
- $accessor->connect(
542
- $ip,
543
- $port,
544
- $this->_timeout,
545
- null,
546
- $this->_retry_interval,
547
- $this->_read_timeout
548
- );
549
- } else { // Old phpredis only supports a subset of parameters.
550
- $accessor->connect(
551
- $ip,
552
- $port,
553
- $this->_timeout,
554
- null,
555
- $this->_retry_interval
556
- );
557
- }
558
- }
559
-
560
- restore_error_handler();
561
  }
562
 
563
  if ( ! empty( $this->_password ) ) {
450
  return $v;
451
  }
452
 
453
+ /**
454
+ * Build Redis connection arguments based on server URI
455
+ *
456
+ * @param string $server Server URI to connect to.
457
+ */
458
+ private function build_connect_args( $server ) {
459
+ $connect_args = array();
460
+
461
+ if ( substr( $server, 0, 5 ) === 'unix:' ) {
462
+ $connect_args[] = trim( substr( $server, 5 ) );
463
+ $connect_args[] = null; // port.
464
+ } else {
465
+ list( $ip, $port ) = Util_Content::endpoint_to_host_port( $server, null );
466
+ $connect_args[] = $ip;
467
+ $connect_args[] = $port;
468
+ }
469
+
470
+ $connect_args[] = $this->_timeout;
471
+ $connect_args[] = $this->_persistent ? $this->_instance_id . '_' . $this->_dbid : null;
472
+ $connect_args[] = $this->_retry_interval;
473
+
474
+ $phpredis_version = phpversion( 'redis' );
475
+
476
+ // The read_timeout parameter was added in phpredis 3.1.3.
477
+ if ( version_compare( $phpredis_version, '3.1.3', '>=' ) ) {
478
+ $connect_args[] = $this->_read_timeout;
479
+ }
480
+
481
+ // Support for stream context was added in phpredis 5.3.2.
482
+ if ( version_compare( $phpredis_version, '5.3.2', '>=' ) ) {
483
+ $context = array();
484
+ if ( 'tls:' === substr( $server, 0, 4 ) && ! $this->_verify_tls_certificates ) {
485
+ $context['stream'] = array(
486
+ 'verify_peer' => false,
487
+ 'verify_peer_name' => false,
488
+ );
489
+ }
490
+ $connect_args[] = $context;
491
+ }
492
+
493
+ return $connect_args;
494
+ }
495
+
496
  /**
497
  * Get accessor.
498
  *
514
  $this->_accessors[ $index ] = null;
515
  } else {
516
  try {
517
+ $server = $this->_servers[ $index ];
518
+ $connect_args = $this->build_connect_args( $server );
519
+
520
  $accessor = new \Redis();
521
 
522
+ if ( $this->_persistent ) {
523
+ $accessor->pconnect( ...$connect_args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
524
  } else {
525
+ $accessor->connect( ...$connect_args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
526
  }
527
 
528
  if ( ! empty( $this->_password ) ) {
ConfigCache.php CHANGED
@@ -1,4 +1,10 @@
1
  <?php
 
 
 
 
 
 
2
  namespace W3TC;
3
 
4
  /**
@@ -8,8 +14,13 @@ namespace W3TC;
8
  class ConfigCache {
9
  /**
10
  * Reads config from config cache
 
 
 
 
 
11
  */
12
- static public function util_array_from_storage( $blog_id, $preview ) {
13
  $cache = self::get_cache();
14
 
15
  $config = $cache->get( self::get_key( $blog_id, $preview ) );
@@ -20,98 +31,116 @@ class ConfigCache {
20
  return null;
21
  }
22
 
23
-
24
-
25
  /**
26
  * Removes config cache entry so that it can be read from original source
27
  * on next attempt
 
 
 
28
  */
29
- static public function remove_item( $blog_id, $preview ) {
30
  $cache = self::get_cache();
31
 
32
  $cache->hard_delete( self::get_key( $blog_id, false ) );
33
  $cache->hard_delete( self::get_key( $blog_id, true ) );
34
  }
35
 
36
-
37
-
38
- static public function save_item( $blog_id, $preview, $data ) {
 
 
 
 
 
39
  $cache = self::get_cache();
40
 
41
  $cache->set( self::get_key( $blog_id, $preview ), $data );
42
  }
43
 
44
-
45
-
46
- static private function get_cache() {
 
 
 
47
  static $cache = null;
48
 
49
- if ( !is_null( $cache ) ) {
50
  return $cache;
51
  }
52
 
53
  switch ( W3TC_CONFIG_CACHE_ENGINE ) {
54
- case 'memcached':
55
- $engineConfig = array(
56
- 'servers' => explode( ',', W3TC_CONFIG_CACHE_MEMCACHED_SERVERS ),
57
- 'persistent' =>
58
- ( defined( 'W3TC_CONFIG_CACHE_MEMCACHED_PERSISTENT' ) ?
59
- W3TC_CONFIG_CACHE_MEMCACHED_PERSISTENT : true ),
60
- 'aws_autodiscovery' =>
61
- ( defined( 'W3TC_CONFIG_CACHE_MEMCACHED_AWS_AUTODISCOVERY' ) ?
62
- W3TC_CONFIG_CACHE_MEMCACHED_AWS_AUTODISCOVERY : false ),
63
- 'username' =>
64
- ( defined( 'W3TC_CONFIG_CACHE_MEMCACHED_USERNAME' ) ?
65
- W3TC_CONFIG_CACHE_MEMCACHED_USERNAME : '' ),
66
- 'password' =>
67
- ( defined( 'W3TC_CONFIG_CACHE_MEMCACHED_PASSWORD' ) ?
68
- W3TC_CONFIG_CACHE_MEMCACHED_PASSWORD : '' ),
69
- 'key_version_mode' => 'disabled'
70
- );
71
- break;
72
-
73
- case 'redis':
74
- $engineConfig = array(
75
- 'servers' => explode( ',', W3TC_CONFIG_CACHE_REDIS_SERVERS ),
76
- 'persistent' =>
77
- ( defined( 'W3TC_CONFIG_CACHE_REDIS_PERSISTENT' ) ?
78
- W3TC_CONFIG_CACHE_REDIS_PERSISTENT : true ),
79
- 'dbid' =>
80
- ( defined( 'W3TC_CONFIG_CACHE_REDIS_DBID' ) ?
81
- W3TC_CONFIG_CACHE_REDIS_DBID : 0 ),
82
- 'password' =>
83
- ( defined( 'W3TC_CONFIG_CACHE_REDIS_PASSWORD' ) ?
84
- W3TC_CONFIG_CACHE_REDIS_PASSWORD : '' ),
85
- 'timeout' =>
86
- ( defined( 'W3TC_CONFIG_CACHE_REDIS_TIMEOUT' ) ?
87
- W3TC_CONFIG_CACHE_REDIS_TIMEOUT : 0 ),
88
- 'retry_interval' =>
89
- ( defined( 'W3TC_CONFIG_CACHE_REDIS_RETRY_INTERVAL' ) ?
90
- W3TC_CONFIG_CACHE_REDIS_RETRY_INTERVAL : 0 ),
91
- 'read_timeout' =>
92
- ( defined( 'W3TC_CONFIG_CACHE_REDIS_READ_TIMEOUT' ) ?
93
- W3TC_CONFIG_CACHE_REDIS_READ_TIMEOUT : 0 ),
94
- 'key_version_mode' => 'disabled'
95
- );
96
- break;
97
-
98
- default:
99
- $engineConfig = array();
 
 
 
100
  }
101
 
102
- $engineConfig['blog_id'] = '0';
103
- $engineConfig['module'] = 'config';
104
- $engineConfig['host'] = '';
105
- $engineConfig['instance_id'] =
106
- ( defined( 'W3TC_INSTANCE_ID' ) ? W3TC_INSTANCE_ID : 0 );
 
107
 
108
- $cache = Cache::instance( W3TC_CONFIG_CACHE_ENGINE, $engineConfig );
109
  return $cache;
110
  }
111
 
112
-
113
-
114
- static private function get_key( $blog_id, $preview ) {
 
 
 
 
 
 
115
  return 'w3tc_config_' . $blog_id . ( $preview ? '_preview' : '' );
116
  }
117
  }
1
  <?php
2
+ /**
3
+ * File: ConfigCache.php
4
+ *
5
+ * @package W3TC
6
+ */
7
+
8
  namespace W3TC;
9
 
10
  /**
14
  class ConfigCache {
15
  /**
16
  * Reads config from config cache
17
+ *
18
+ * @param int $blog_id Blog ID.
19
+ * @param bool $preview Preview flag.
20
+ *
21
+ * @return array|null
22
  */
23
+ public static function util_array_from_storage( $blog_id, $preview ) {
24
  $cache = self::get_cache();
25
 
26
  $config = $cache->get( self::get_key( $blog_id, $preview ) );
31
  return null;
32
  }
33
 
 
 
34
  /**
35
  * Removes config cache entry so that it can be read from original source
36
  * on next attempt
37
+ *
38
+ * @param int $blog_id Blog ID.
39
+ * @param bool $preview Preview flag.
40
  */
41
+ public static function remove_item( $blog_id, $preview ) {
42
  $cache = self::get_cache();
43
 
44
  $cache->hard_delete( self::get_key( $blog_id, false ) );
45
  $cache->hard_delete( self::get_key( $blog_id, true ) );
46
  }
47
 
48
+ /**
49
+ * Saves config cache entry.
50
+ *
51
+ * @param int $blog_id Blog ID.
52
+ * @param bool $preview Preview flag.
53
+ * @param mixed $data Data.
54
+ */
55
+ public static function save_item( $blog_id, $preview, $data ) {
56
  $cache = self::get_cache();
57
 
58
  $cache->set( self::get_key( $blog_id, $preview ), $data );
59
  }
60
 
61
+ /**
62
+ * Retrieves cache instance.
63
+ *
64
+ * @return object
65
+ */
66
+ private static function get_cache() {
67
  static $cache = null;
68
 
69
+ if ( ! is_null( $cache ) ) {
70
  return $cache;
71
  }
72
 
73
  switch ( W3TC_CONFIG_CACHE_ENGINE ) {
74
+ case 'memcached':
75
+ $engine_config = array(
76
+ 'servers' =>
77
+ explode( ',', W3TC_CONFIG_CACHE_MEMCACHED_SERVERS ),
78
+ 'persistent' =>
79
+ ( defined( 'W3TC_CONFIG_CACHE_MEMCACHED_PERSISTENT' ) ?
80
+ W3TC_CONFIG_CACHE_MEMCACHED_PERSISTENT : true ),
81
+ 'aws_autodiscovery' =>
82
+ ( defined( 'W3TC_CONFIG_CACHE_MEMCACHED_AWS_AUTODISCOVERY' ) ?
83
+ W3TC_CONFIG_CACHE_MEMCACHED_AWS_AUTODISCOVERY : false ),
84
+ 'username' =>
85
+ ( defined( 'W3TC_CONFIG_CACHE_MEMCACHED_USERNAME' ) ?
86
+ W3TC_CONFIG_CACHE_MEMCACHED_USERNAME : '' ),
87
+ 'password' =>
88
+ ( defined( 'W3TC_CONFIG_CACHE_MEMCACHED_PASSWORD' ) ?
89
+ W3TC_CONFIG_CACHE_MEMCACHED_PASSWORD : '' ),
90
+ 'key_version_mode' => 'disabled',
91
+ );
92
+ break;
93
+ case 'redis':
94
+ $engine_config = array(
95
+ 'servers' =>
96
+ explode( ',', W3TC_CONFIG_CACHE_REDIS_SERVERS ),
97
+ 'verify_tls_certificates' =>
98
+ ( defined( 'W3TC_CONFIG_CACHE_REDIS_VERIFY_TLS_CERTIFICATES' ) ?
99
+ W3TC_CONFIG_CACHE_REDIS_VERIFY_TLS_CERTIFICATES : true ),
100
+ 'persistent' =>
101
+ ( defined( 'W3TC_CONFIG_CACHE_REDIS_PERSISTENT' ) ?
102
+ W3TC_CONFIG_CACHE_REDIS_PERSISTENT : true ),
103
+ 'dbid' =>
104
+ ( defined( 'W3TC_CONFIG_CACHE_REDIS_DBID' ) ?
105
+ W3TC_CONFIG_CACHE_REDIS_DBID : 0 ),
106
+ 'password' =>
107
+ ( defined( 'W3TC_CONFIG_CACHE_REDIS_PASSWORD' ) ?
108
+ W3TC_CONFIG_CACHE_REDIS_PASSWORD : '' ),
109
+ 'timeout' =>
110
+ ( defined( 'W3TC_CONFIG_CACHE_REDIS_TIMEOUT' ) ?
111
+ W3TC_CONFIG_CACHE_REDIS_TIMEOUT : 0 ),
112
+ 'retry_interval' =>
113
+ ( defined( 'W3TC_CONFIG_CACHE_REDIS_RETRY_INTERVAL' ) ?
114
+ W3TC_CONFIG_CACHE_REDIS_RETRY_INTERVAL : 0 ),
115
+ 'read_timeout' =>
116
+ ( defined( 'W3TC_CONFIG_CACHE_REDIS_READ_TIMEOUT' ) ?
117
+ W3TC_CONFIG_CACHE_REDIS_READ_TIMEOUT : 0 ),
118
+ 'key_version_mode' => 'disabled',
119
+ );
120
+ break;
121
+ default:
122
+ $engine_config = array();
123
  }
124
 
125
+ $engine_config['blog_id'] = '0';
126
+ $engine_config['module'] = 'config';
127
+ $engine_config['host'] = '';
128
+ $engine_config['instance_id'] = ( defined( 'W3TC_INSTANCE_ID' ) ? W3TC_INSTANCE_ID : 0 );
129
+
130
+ $cache = Cache::instance( W3TC_CONFIG_CACHE_ENGINE, $engine_config );
131
 
 
132
  return $cache;
133
  }
134
 
135
+ /**
136
+ * Retrieves config cache key.
137
+ *
138
+ * @param int $blog_id Blog ID.
139
+ * @param bool $preview Preview flag.
140
+ *
141
+ * @return string
142
+ */
143
+ private static function get_key( $blog_id, $preview ) {
144
  return 'w3tc_config_' . $blog_id . ( $preview ? '_preview' : '' );
145
  }
146
  }
DbCache_Plugin.php CHANGED
@@ -1,4 +1,12 @@
1
  <?php
 
 
 
 
 
 
 
 
2
  namespace W3TC;
3
 
4
  /**
@@ -6,110 +14,53 @@ namespace W3TC;
6
  */
7
  class DbCache_Plugin {
8
  /**
9
- * Config
 
 
10
  */
11
  private $_config = null;
12
 
13
- function __construct() {
 
 
 
14
  $this->_config = Dispatcher::config();
15
  }
16
 
17
  /**
18
  * Runs plugin
19
  */
20
- function run() {
21
- add_filter( 'cron_schedules', array(
22
- $this,
23
- 'cron_schedules'
24
- ) );
25
 
26
- if ( $this->_config->get_string( 'dbcache.engine' ) == 'file' ) {
27
- add_action( 'w3_dbcache_cleanup', array(
28
- $this,
29
- 'cleanup'
30
- ) );
31
  }
32
 
33
- add_action( 'publish_phone', array(
34
- $this,
35
- 'on_change'
36
- ), 0 );
37
-
38
- add_action( 'wp_trash_post', array(
39
- $this,
40
- 'on_post_change'
41
- ), 0 );
42
-
43
- add_action( 'save_post', array(
44
- $this,
45
- 'on_post_change'
46
- ), 0 );
47
-
48
- add_action( 'clean_post_cache', array(
49
- $this,
50
- 'on_post_change'
51
- ), 0, 2 );
52
-
53
- add_action( 'comment_post', array(
54
- $this,
55
- 'on_comment_change'
56
- ), 0 );
57
-
58
- add_action( 'edit_comment', array(
59
- $this,
60
- 'on_comment_change'
61
- ), 0 );
62
-
63
- add_action( 'delete_comment', array(
64
- $this,
65
- 'on_comment_change'
66
- ), 0 );
67
-
68
- add_action( 'wp_set_comment_status', array(
69
- $this,
70
- 'on_comment_status'
71
- ), 0, 2 );
72
-
73
- add_action( 'trackback_post', array(
74
- $this,
75
- 'on_comment_change'
76
- ), 0 );
77
-
78
- add_action( 'pingback_post', array(
79
- $this,
80
- 'on_comment_change'
81
- ), 0 );
82
-
83
- add_action( 'switch_theme', array(
84
- $this,
85
- 'on_change'
86
- ), 0 );
87
-
88
- add_action( 'edit_user_profile_update', array(
89
- $this,
90
- 'on_change'
91
- ), 0 );
92
 
93
  if ( Util_Environment::is_wpmu() ) {
94
- add_action( 'delete_blog', array(
95
- $this,
96
- 'on_change'
97
- ), 0 );
98
  }
99
 
100
- add_action( 'delete_post', array(
101
- $this,
102
- 'on_post_change'
103
- ), 0 );
104
-
105
- add_filter( 'w3tc_admin_bar_menu',
106
- array( $this, 'w3tc_admin_bar_menu' ) );
107
 
108
- // usage statistics handling
109
- add_filter( 'w3tc_usage_statistics_metrics', array(
110
- $this, 'w3tc_usage_statistics_metrics' ) );
111
- add_filter( 'w3tc_usage_statistics_sources', array(
112
- $this, 'w3tc_usage_statistics_sources' ) );
113
  }
114
 
115
  /**
@@ -117,11 +68,13 @@ class DbCache_Plugin {
117
  *
118
  * @return void
119
  */
120
- function cleanup() {
121
- $w3_cache_file_cleaner = new Cache_File_Cleaner( array(
122
- 'cache_dir' => Util_Environment::cache_blog_dir( 'db' ),
123
- 'clean_timelimit' => $this->_config->get_integer( 'timelimit.cache_gc' )
124
- ) );
 
 
125
 
126
  $w3_cache_file_cleaner->clean();
127
  }
@@ -129,27 +82,35 @@ class DbCache_Plugin {
129
  /**
130
  * Cron schedules filter
131
  *
132
- * @param array $schedules
 
133
  * @return array
134
  */
135
- function cron_schedules( $schedules ) {
136
  $gc = $this->_config->get_integer( 'dbcache.file.gc' );
137
 
138
- return array_merge( $schedules, array(
 
 
139
  'w3_dbcache_cleanup' => array(
140
  'interval' => $gc,
141
- 'display' => sprintf( '[W3TC] Database Cache file GC (every %d seconds)', $gc )
142
- )
143
- ) );
 
 
 
 
 
144
  }
145
 
146
  /**
147
  * Change action
148
  */
149
- function on_change() {
150
  static $flushed = false;
151
 
152
- if ( !$flushed ) {
153
  $flusher = Dispatcher::component( 'CacheFlush' );
154
  $flusher->dbcache_flush();
155
 
@@ -159,18 +120,19 @@ class DbCache_Plugin {
159
 
160
  /**
161
  * Change post action
 
 
 
162
  */
163
- function on_post_change( $post_id = 0, $post = null ) {
164
  static $flushed = false;
165
 
166
- if ( !$flushed ) {
167
  if ( is_null( $post ) ) {
168
  $post = $post_id;
169
  }
170
 
171
- if ( $post_id > 0 &&
172
- !Util_Environment::is_flushable_post(
173
- $post, 'dbcache', $this->_config ) ) {
174
  return;
175
  }
176
 
@@ -184,14 +146,14 @@ class DbCache_Plugin {
184
  /**
185
  * Comment change action
186
  *
187
- * @param integer $comment_id
188
  */
189
- function on_comment_change( $comment_id ) {
190
  $post_id = 0;
191
 
192
  if ( $comment_id ) {
193
  $comment = get_comment( $comment_id, ARRAY_A );
194
- $post_id = !empty( $comment['comment_post_ID'] ) ? (int) $comment['comment_post_ID'] : 0;
195
  }
196
 
197
  $this->on_post_change( $post_id );
@@ -200,70 +162,89 @@ class DbCache_Plugin {
200
  /**
201
  * Comment status action
202
  *
203
- * @param integer $comment_id
204
- * @param string $status
205
  */
206
- function on_comment_status( $comment_id, $status ) {
207
- if ( $status === 'approve' || $status === '1' ) {
208
  $this->on_comment_change( $comment_id );
209
  }
210
  }
211
 
212
-
213
-
 
 
 
214
  public function w3tc_admin_bar_menu( $menu_items ) {
215
  $menu_items['20310.dbcache'] = array(
216
- 'id' => 'w3tc_flush_dbcache',
217
  'parent' => 'w3tc_flush',
218
- 'title' => __( 'Database', 'w3-total-cache' ),
219
- 'href' => wp_nonce_url( admin_url(
220
- 'admin.php?page=w3tc_dashboard&amp;w3tc_flush_dbcache' ),
221
- 'w3tc' )
 
222
  );
223
 
224
  return $menu_items;
225
  }
226
 
227
-
228
-
 
 
 
229
  public function w3tc_usage_statistics_of_request( $storage ) {
230
  $o = Dispatcher::component( 'ObjectCache_WpObjectCache_Regular' );
231
  $o->w3tc_usage_statistics_of_request( $storage );
232
  }
233
 
234
-
235
-
 
 
 
236
  public function w3tc_usage_statistics_metrics( $metrics ) {
237
- return array_merge( $metrics, array(
 
 
238
  'dbcache_calls_total',
239
  'dbcache_calls_hits',
240
  'dbcache_flushes',
241
- 'dbcache_time_ms'
242
- ) );
 
243
  }
244
 
245
-
246
-
 
 
 
 
 
247
  public function w3tc_usage_statistics_sources( $sources ) {
248
  $c = Dispatcher::config();
249
- if ( $c->get_string( 'dbcache.engine' ) == 'apc' ) {
250
  $sources['apc_servers']['dbcache'] = array(
251
- 'name' => __( 'Database Cache', 'w3-total-cache' )
252
  );
253
- } elseif ( $c->get_string( 'dbcache.engine' ) == 'memcached' ) {
254
  $sources['memcached_servers']['dbcache'] = array(
255
- 'servers' => $c->get_array( 'dbcache.memcached.servers' ),
256
  'username' => $c->get_string( 'dbcache.memcached.username' ),
257
  'password' => $c->get_string( 'dbcache.memcached.password' ),
258
- 'name' => __( 'Database Cache', 'w3-total-cache' )
259
  );
260
- } elseif ( $c->get_string( 'dbcache.engine' ) == 'redis' ) {
261
  $sources['redis_servers']['dbcache'] = array(
262
- 'servers' => $c->get_array( 'dbcache.redis.servers' ),
263
- 'username' => $c->get_boolean( 'dbcache.redis.username' ),
264
- 'dbid' => $c->get_integer( 'dbcache.redis.dbid' ),
265
- 'password' => $c->get_string( 'dbcache.redis.password' ),
266
- 'name' => __( 'Database Cache', 'w3-total-cache' )
 
267
  );
268
  }
269
 
1
  <?php
2
+ /**
3
+ * File: DbCache_Plugin.php
4
+ *
5
+ * @package W3TC
6
+ *
7
+ * phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
8
+ */
9
+
10
  namespace W3TC;
11
 
12
  /**
14
  */
15
  class DbCache_Plugin {
16
  /**
17
+ * Config.
18
+ *
19
+ * @var array
20
  */
21
  private $_config = null;
22
 
23
+ /**
24
+ * Constructor.
25
+ */
26
+ public function __construct() {
27
  $this->_config = Dispatcher::config();
28
  }
29
 
30
  /**
31
  * Runs plugin
32
  */
33
+ public function run() {
34
+ // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected
35
+ add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) );
 
 
36
 
37
+ if ( 'file' === $this->_config->get_string( 'dbcache.engine' ) ) {
38
+ add_action( 'w3_dbcache_cleanup', array( $this, 'cleanup' ) );
 
 
 
39
  }
40
 
41
+ add_action( 'publish_phone', array( $this, 'on_change' ), 0 );
42
+ add_action( 'wp_trash_post', array( $this, 'on_post_change' ), 0 );
43
+ add_action( 'save_post', array( $this, 'on_post_change' ), 0 );
44
+ add_action( 'clean_post_cache', array( $this, 'on_post_change' ), 0, 2 );
45
+ add_action( 'comment_post', array( $this, 'on_comment_change' ), 0 );
46
+ add_action( 'edit_comment', array( $this, 'on_comment_change' ), 0 );
47
+ add_action( 'delete_comment', array( $this, 'on_comment_change' ), 0 );
48
+ add_action( 'wp_set_comment_status', array( $this, 'on_comment_status' ), 0, 2 );
49
+ add_action( 'trackback_post', array( $this, 'on_comment_change' ), 0 );
50
+ add_action( 'pingback_post', array( $this, 'on_comment_change' ), 0 );
51
+ add_action( 'switch_theme', array( $this, 'on_change' ), 0 );
52
+ add_action( 'edit_user_profile_update', array( $this, 'on_change' ), 0 );
53
+ add_action( 'delete_post', array( $this, 'on_post_change' ), 0 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
  if ( Util_Environment::is_wpmu() ) {
56
+ add_action( 'delete_blog', array( $this, 'on_change' ), 0 );
 
 
 
57
  }
58
 
59
+ add_filter( 'w3tc_admin_bar_menu', array( $this, 'w3tc_admin_bar_menu' ) );
 
 
 
 
 
 
60
 
61
+ // usage statistics handling.
62
+ add_filter( 'w3tc_usage_statistics_metrics', array( $this, 'w3tc_usage_statistics_metrics' ) );
63
+ add_filter( 'w3tc_usage_statistics_sources', array( $this, 'w3tc_usage_statistics_sources' ) );
 
 
64
  }
65
 
66
  /**
68
  *
69
  * @return void
70
  */
71
+ public function cleanup() {
72
+ $w3_cache_file_cleaner = new Cache_File_Cleaner(
73
+ array(
74
+ 'cache_dir' => Util_Environment::cache_blog_dir( 'db' ),
75
+ 'clean_timelimit' => $this->_config->get_integer( 'timelimit.cache_gc' ),
76
+ )
77
+ );
78
 
79
  $w3_cache_file_cleaner->clean();
80
  }
82
  /**
83
  * Cron schedules filter
84
  *
85
+ * @param array $schedules Schedules.
86
+ *
87
  * @return array
88
  */
89
+ public function cron_schedules( $schedules ) {
90
  $gc = $this->_config->get_integer( 'dbcache.file.gc' );
91
 
92
+ return array_merge(
93
+ $schedules,
94
+ array(
95
  'w3_dbcache_cleanup' => array(
96
  'interval' => $gc,
97
+ 'display' => sprintf(
98
+ // translators: 1 interval in seconds.
99
+ __( '[W3TC] Database Cache file GC (every %d seconds)', 'w3-total-cache' ),
100
+ $gc
101
+ ),
102
+ ),
103
+ )
104
+ );
105
  }
106
 
107
  /**
108
  * Change action
109
  */
110
+ public function on_change() {
111
  static $flushed = false;
112
 
113
+ if ( ! $flushed ) {
114
  $flusher = Dispatcher::component( 'CacheFlush' );
115
  $flusher->dbcache_flush();
116
 
120
 
121
  /**
122
  * Change post action
123
+ *
124
+ * @param int $post_id Post ID.
125
+ * @param mixed $post Post.
126
  */
127
+ public function on_post_change( $post_id = 0, $post = null ) {
128
  static $flushed = false;
129
 
130
+ if ( ! $flushed ) {
131
  if ( is_null( $post ) ) {
132
  $post = $post_id;
133
  }
134
 
135
+ if ( $post_id > 0 && ! Util_Environment::is_flushable_post( $post, 'dbcache', $this->_config ) ) {
 
 
136
  return;
137
  }
138
 
146
  /**
147
  * Comment change action
148
  *
149
+ * @param integer $comment_id Comment ID.
150
  */
151
+ public function on_comment_change( $comment_id ) {
152
  $post_id = 0;
153
 
154
  if ( $comment_id ) {
155
  $comment = get_comment( $comment_id, ARRAY_A );
156
+ $post_id = ! empty( $comment['comment_post_ID'] ) ? (int) $comment['comment_post_ID'] : 0;
157
  }
158
 
159
  $this->on_post_change( $post_id );
162
  /**
163
  * Comment status action
164
  *
165
+ * @param integer $comment_id Comment ID.
166
+ * @param string $status Status.
167
  */
168
+ public function on_comment_status( $comment_id, $status ) {
169
+ if ( 'approve' === $status || '1' === $status ) {
170
  $this->on_comment_change( $comment_id );
171
  }
172
  }
173
 
174
+ /**
175
+ * Setup admin menu elements
176
+ *
177
+ * @param array $menu_items Menu items.
178
+ */
179
  public function w3tc_admin_bar_menu( $menu_items ) {
180
  $menu_items['20310.dbcache'] = array(
181
+ 'id' => 'w3tc_flush_dbcache',
182
  'parent' => 'w3tc_flush',
183
+ 'title' => __( 'Database', 'w3-total-cache' ),
184
+ 'href' => wp_nonce_url(
185
+ admin_url( 'admin.php?page=w3tc_dashboard&amp;w3tc_flush_dbcache' ),
186
+ 'w3tc'
187
+ ),
188
  );
189
 
190
  return $menu_items;
191
  }
192
 
193
+ /**
194
+ * Usage statistics of request filter
195
+ *
196
+ * @param object $storage Storage object.
197
+ */
198
  public function w3tc_usage_statistics_of_request( $storage ) {
199
  $o = Dispatcher::component( 'ObjectCache_WpObjectCache_Regular' );
200
  $o->w3tc_usage_statistics_of_request( $storage );
201
  }
202
 
203
+ /**
204
+ * Retrive usage statistics metrics
205
+ *
206
+ * @param array $metrics Metrics.
207
+ */
208
  public function w3tc_usage_statistics_metrics( $metrics ) {
209
+ return array_merge(
210
+ $metrics,
211
+ array(
212
  'dbcache_calls_total',
213
  'dbcache_calls_hits',
214
  'dbcache_flushes',
215
+ 'dbcache_time_ms',
216
+ )
217
+ );
218
  }
219
 
220
+ /**
221
+ * Usage Statisitcs sources filter.
222
+ *
223
+ * @param array $sources Sources.
224
+ *
225
+ * @return array
226
+ */
227
  public function w3tc_usage_statistics_sources( $sources ) {
228
  $c = Dispatcher::config();
229
+ if ( 'apc' === $c->get_string( 'dbcache.engine' ) ) {
230
  $sources['apc_servers']['dbcache'] = array(
231
+ 'name' => __( 'Database Cache', 'w3-total-cache' ),
232
  );
233
+ } elseif ( 'memcached' === $c->get_string( 'dbcache.engine' ) ) {
234
  $sources['memcached_servers']['dbcache'] = array(
235
+ 'servers' => $c->get_array( 'dbcache.memcached.servers' ),
236
  'username' => $c->get_string( 'dbcache.memcached.username' ),
237
  'password' => $c->get_string( 'dbcache.memcached.password' ),
238
+ 'name' => __( 'Database Cache', 'w3-total-cache' ),
239
  );
240
+ } elseif ( 'redis' === $c->get_string( 'dbcache.engine' ) ) {
241
  $sources['redis_servers']['dbcache'] = array(
242
+ 'servers' => $c->get_array( 'dbcache.redis.servers' ),
243
+ 'verify_tls_certificates' => $c->get_boolean( 'dbcache.redis.verify_tls_certificates' ),
244
+ 'username' => $c->get_boolean( 'dbcache.redis.username' ),
245
+ 'dbid' => $c->get_integer( 'dbcache.redis.dbid' ),
246
+ 'password' => $c->get_string( 'dbcache.redis.password' ),
247
+ 'name' => __( 'Database Cache', 'w3-total-cache' ),
248
  );
249
  }
250
 
DbCache_WpdbBase.php CHANGED
@@ -1,7 +1,13 @@
1
  <?php
2
  namespace W3TC;
3
 
4
- require_once ABSPATH . 'wp-includes/wp-db.php';
 
 
 
 
 
 
5
 
6
  class DbCache_WpdbBase extends \wpdb {
7
  }
1
  <?php
2
  namespace W3TC;
3
 
4
+ global $wp_version;
5
+
6
+ if ( version_compare( $wp_version, '6.1-beta1', '>=' ) ) {
7
+ require_once ABSPATH . WPINC . '/class-wpdb.php';
8
+ } else {
9
+ require_once ABSPATH . WPINC . '/wp-db.php';
10
+ }
11
 
12
  class DbCache_WpdbBase extends \wpdb {
13
  }
ObjectCache_Plugin.php CHANGED
@@ -1,4 +1,12 @@
1
  <?php
 
 
 
 
 
 
 
 
2
  namespace W3TC;
3
 
4
  /**
@@ -6,122 +14,65 @@ namespace W3TC;
6
  */
7
  class ObjectCache_Plugin {
8
  /**
9
- * Config
 
 
10
  */
11
  private $_config = null;
12
 
13
- function __construct() {
 
 
 
14
  $this->_config = Dispatcher::config();
15
  }
16
 
17
  /**
18
  * Runs plugin
19
  */
20
- function run() {
21
- add_filter( 'cron_schedules', array(
22
- $this,
23
- 'cron_schedules'
24
- ) );
25
-
26
- add_filter( 'w3tc_footer_comment', array(
27
- $this,
28
- 'w3tc_footer_comment'
29
- ) );
30
-
31
- if ( $this->_config->get_string( 'objectcache.engine' ) == 'file' ) {
32
- add_action( 'w3_objectcache_cleanup', array(
33
- $this,
34
- 'cleanup'
35
- ) );
36
  }
37
 
38
  if ( $this->_do_flush() ) {
39
- add_action( 'clean_post_cache', array(
40
- $this,
41
- 'on_post_change'
42
- ), 0, 2 );
43
  }
44
 
45
  if ( $this->_do_flush() ) {
46
- add_action( 'comment_post', array(
47
- $this,
48
- 'on_comment_change'
49
- ), 0 );
50
-
51
- add_action( 'edit_comment', array(
52
- $this,
53
- 'on_comment_change'
54
- ), 0 );
55
-
56
- add_action( 'delete_comment', array(
57
- $this,
58
- 'on_comment_change'
59
- ), 0 );
60
-
61
- add_action( 'wp_set_comment_status', array(
62
- $this,
63
- 'on_comment_status'
64
- ), 0, 2 );
65
-
66
- add_action( 'trackback_post', array(
67
- $this,
68
- 'on_comment_change'
69
- ), 0 );
70
-
71
- add_action( 'pingback_post', array(
72
- $this,
73
- 'on_comment_change'
74
- ), 0 );
75
  }
76
 
77
- add_action( 'switch_theme', array(
78
- $this,
79
- 'on_change'
80
- ), 0 );
81
 
82
  if ( $this->_do_flush() ) {
83
- add_action( 'updated_option', array(
84
- $this,
85
- 'on_change_option'
86
- ), 0, 1 );
87
- add_action( 'added_option', array(
88
- $this,
89
- 'on_change_option'
90
- ), 0, 1 );
91
-
92
- add_action( 'delete_option', array(
93
- $this,
94
- 'on_change_option'
95
- ), 0, 1 );
96
  }
97
 
98
- add_action( 'edit_user_profile_update', array(
99
- $this,
100
- 'on_change_profile'
101
- ), 0 );
102
 
103
- add_filter( 'w3tc_admin_bar_menu',
104
- array( $this, 'w3tc_admin_bar_menu' ) );
105
-
106
- // usage statistics handling
107
- add_action( 'w3tc_usage_statistics_of_request', array(
108
- $this, 'w3tc_usage_statistics_of_request' ), 10, 1 );
109
- add_filter( 'w3tc_usage_statistics_metrics', array(
110
- $this, 'w3tc_usage_statistics_metrics' ) );
111
- add_filter( 'w3tc_usage_statistics_sources', array(
112
- $this, 'w3tc_usage_statistics_sources' ) );
113
 
 
 
 
 
114
 
115
  if ( Util_Environment::is_wpmu() ) {
116
- add_action( 'delete_blog', array(
117
- $this,
118
- 'on_change'
119
- ), 0 );
120
-
121
- add_action( 'switch_blog', array(
122
- $this,
123
- 'switch_blog'
124
- ), 0, 2 );
125
  }
126
  }
127
 
@@ -130,11 +81,13 @@ class ObjectCache_Plugin {
130
  *
131
  * @return void
132
  */
133
- function cleanup() {
134
- $w3_cache_file_cleaner = new Cache_File_Cleaner( array(
135
- 'cache_dir' => Util_Environment::cache_blog_dir( 'object' ),
136
- 'clean_timelimit' => $this->_config->get_integer( 'timelimit.cache_gc' )
137
- ) );
 
 
138
 
139
  $w3_cache_file_cleaner->clean();
140
  }
@@ -142,27 +95,35 @@ class ObjectCache_Plugin {
142
  /**
143
  * Cron schedules filter
144
  *
145
- * @param array $schedules
 
146
  * @return array
147
  */
148
- function cron_schedules( $schedules ) {
149
  $gc = $this->_config->get_integer( 'objectcache.file.gc' );
150
 
151
- return array_merge( $schedules, array(
 
 
152
  'w3_objectcache_cleanup' => array(
153
  'interval' => $gc,
154
- 'display' => sprintf( '[W3TC] Object Cache file GC (every %d seconds)', $gc )
155
- )
156
- ) );
 
 
 
 
 
157
  }
158
 
159
  /**
160
  * Change action
161
  */
162
- function on_change() {
163
  static $flushed = false;
164
 
165
- if ( !$flushed ) {
166
  $flush = Dispatcher::component( 'CacheFlush' );
167
  $flush->objectcache_flush();
168
  $flushed = true;
@@ -171,16 +132,19 @@ class ObjectCache_Plugin {
171
 
172
  /**
173
  * Change post action
 
 
 
174
  */
175
- function on_post_change( $post_id = 0, $post = null ) {
176
  static $flushed = false;
177
 
178
- if ( !$flushed ) {
179
- if ( is_null( $post ) )
180
  $post = $post_id;
 
181
 
182
- if ( $post_id> 0 && !Util_Environment::is_flushable_post(
183
- $post, 'objectcache', $this->_config ) ) {
184
  return;
185
  }
186
 
@@ -192,28 +156,32 @@ class ObjectCache_Plugin {
192
 
193
  /**
194
  * Change action
 
 
195
  */
196
- function on_change_option( $option ) {
197
  static $flushed = false;
198
- /*
199
- if ( !$flushed ) {
200
- if ( $option != 'cron' ) {
 
201
  $flush = Dispatcher::component( 'CacheFlush' );
202
  $flush->objectcache_flush();
203
  $flushed = true;
204
  }
205
- }*/
 
206
  }
207
 
208
  /**
209
  * Flush cache when user profile is updated
210
  *
211
- * @param int $user_id
212
  */
213
- function on_change_profile( $user_id ) {
214
  static $flushed = false;
215
 
216
- if ( !$flushed ) {
217
  if ( Util_Environment::is_wpmu() ) {
218
  $blogs = get_blogs_of_user( $user_id, true );
219
  if ( $blogs ) {
@@ -231,8 +199,11 @@ class ObjectCache_Plugin {
231
 
232
  /**
233
  * Switch blog action
 
 
 
234
  */
235
- function switch_blog( $blog_id, $previous_blog_id ) {
236
  $o = Dispatcher::component( 'ObjectCache_WpObjectCache_Regular' );
237
  $o->switch_blog( $blog_id );
238
  }
@@ -241,15 +212,14 @@ class ObjectCache_Plugin {
241
  /**
242
  * Comment change action
243
  *
244
- * @param integer $comment_id
245
  */
246
- function on_comment_change( $comment_id ) {
247
  $post_id = 0;
248
 
249
  if ( $comment_id ) {
250
  $comment = get_comment( $comment_id, ARRAY_A );
251
- $post_id = ( !empty( $comment['comment_post_ID'] ) ?
252
- (int) $comment['comment_post_ID'] : 0 );
253
  }
254
 
255
  $this->on_post_change( $post_id );
@@ -258,72 +228,102 @@ class ObjectCache_Plugin {
258
  /**
259
  * Comment status action
260
  *
261
- * @param integer $comment_id
262
- * @param string $status
263
  */
264
- function on_comment_status( $comment_id, $status ) {
265
- if ( $status === 'approve' || $status === '1' ) {
266
  $this->on_comment_change( $comment_id );
267
  }
268
  }
269
 
 
 
 
 
 
270
  public function w3tc_admin_bar_menu( $menu_items ) {
271
  $menu_items['20410.objectcache'] = array(
272
- 'id' => 'w3tc_flush_objectcache',
273
  'parent' => 'w3tc_flush',
274
- 'title' => __( 'Object Cache', 'w3-total-cache' ),
275
- 'href' => wp_nonce_url( admin_url(
276
- 'admin.php?page=w3tc_dashboard&amp;w3tc_flush_objectcache' ), 'w3tc' )
277
  );
278
 
279
  return $menu_items;
280
  }
281
 
 
 
 
 
 
282
  public function w3tc_footer_comment( $strings ) {
283
- $o = Dispatcher::component( 'ObjectCache_WpObjectCache_Regular' );
284
  $strings = $o->w3tc_footer_comment( $strings );
285
 
286
  return $strings;
287
  }
288
 
 
 
 
 
 
289
  public function w3tc_usage_statistics_of_request( $storage ) {
290
  $o = Dispatcher::component( 'ObjectCache_WpObjectCache_Regular' );
291
  $o->w3tc_usage_statistics_of_request( $storage );
292
  }
293
 
 
 
 
 
 
294
  public function w3tc_usage_statistics_metrics( $metrics ) {
295
- $metrics = array_merge( $metrics, array(
296
- 'objectcache_get_total',
297
- 'objectcache_get_hits',
298
- 'objectcache_sets',
299
- 'objectcache_flushes',
300
- 'objectcache_time_ms'
301
- ) );
 
 
 
302
 
303
  return $metrics;
304
  }
305
 
306
- public function w3tc_usage_statistics_sources($sources) {
 
 
 
 
 
 
 
307
  $c = Dispatcher::config();
308
- if ( $c->get_string( 'objectcache.engine' ) == 'apc' ) {
309
  $sources['apc_servers']['objectcache'] = array(
310
- 'name' => __( 'Object Cache', 'w3-total-cache' )
311
  );
312
- } elseif ( $c->get_string( 'objectcache.engine' ) == 'memcached' ) {
313
  $sources['memcached_servers']['objectcache'] = array(
314
- 'servers' => $c->get_array( 'objectcache.memcached.servers' ),
315
- 'username' => $c->get_string( 'objectcache.memcached.username' ),
316
- 'password' => $c->get_string( 'objectcache.memcached.password' ),
317
  'binary_protocol' => $c->get_boolean( 'objectcache.memcached.binary_protocol' ),
318
- 'name' => __( 'Object Cache', 'w3-total-cache' )
319
  );
320
- } elseif ( $c->get_string( 'objectcache.engine' ) == 'redis' ) {
321
  $sources['redis_servers']['objectcache'] = array(
322
- 'servers' => $c->get_array( 'objectcache.redis.servers' ),
323
- 'username' => $c->get_boolean( 'objectcache.redis.username' ),
324
- 'dbid' => $c->get_integer( 'objectcache.redis.dbid' ),
325
- 'password' => $c->get_string( 'objectcache.redis.password' ),
326
- 'name' => __( 'Object Cache', 'w3-total-cache' )
 
327
  );
328
  }
329
 
@@ -331,12 +331,12 @@ class ObjectCache_Plugin {
331
  }
332
 
333
  /**
334
- *
335
  *
336
  * @return bool
337
  */
338
- private function _do_flush() {
339
- //TODO: Requires admin flush until OC can make changes in Admin backend
340
  return $this->_config->get_boolean( 'cluster.messagebus.enabled' )
341
  || $this->_config->get_boolean( 'objectcache.purge.all' )
342
  || defined( 'WP_ADMIN' );
1
  <?php
2
+ /**
3
+ * File: ObjectCache_Plugin.php
4
+ *
5
+ * @package W3TC
6
+ *
7
+ * phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
8
+ */
9
+
10
  namespace W3TC;
11
 
12
  /**
14
  */
15
  class ObjectCache_Plugin {
16
  /**
17
+ * Config.
18
+ *
19
+ * @var array
20
  */
21
  private $_config = null;
22
 
23
+ /**
24
+ * Constructor.
25
+ */
26
+ public function __construct() {
27
  $this->_config = Dispatcher::config();
28
  }
29
 
30
  /**
31
  * Runs plugin
32
  */
33
+ public function run() {
34
+ // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected
35
+ add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) );
36
+
37
+ add_filter( 'w3tc_footer_comment', array( $this, 'w3tc_footer_comment' ) );
38
+
39
+ if ( 'file' === $this->_config->get_string( 'objectcache.engine' ) ) {
40
+ add_action( 'w3_objectcache_cleanup', array( $this, 'cleanup' ) );
 
 
 
 
 
 
 
 
41
  }
42
 
43
  if ( $this->_do_flush() ) {
44
+ add_action( 'clean_post_cache', array( $this, 'on_post_change' ), 0, 2 );
 
 
 
45
  }
46
 
47
  if ( $this->_do_flush() ) {
48
+ add_action( 'comment_post', array( $this, 'on_comment_change' ), 0 );
49
+ add_action( 'edit_comment', array( $this, 'on_comment_change' ), 0 );
50
+ add_action( 'delete_comment', array( $this, 'on_comment_change' ), 0 );
51
+ add_action( 'wp_set_comment_status', array( $this, 'on_comment_status' ), 0, 2 );
52
+ add_action( 'trackback_post', array( $this, 'on_comment_change' ), 0 );
53
+ add_action( 'pingback_post', array( $this, 'on_comment_change' ), 0 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  }
55
 
56
+ add_action( 'switch_theme', array( $this, 'on_change' ), 0 );
 
 
 
57
 
58
  if ( $this->_do_flush() ) {
59
+ add_action( 'updated_option', array( $this, 'on_change_option' ), 0, 1 );
60
+ add_action( 'added_option', array( $this, 'on_change_option' ), 0, 1 );
61
+ add_action( 'delete_option', array( $this, 'on_change_option' ), 0, 1 );
 
 
 
 
 
 
 
 
 
 
62
  }
63
 
64
+ add_action( 'edit_user_profile_update', array( $this, 'on_change_profile' ), 0 );
 
 
 
65
 
66
+ add_filter( 'w3tc_admin_bar_menu', array( $this, 'w3tc_admin_bar_menu' ) );
 
 
 
 
 
 
 
 
 
67
 
68
+ // usage statistics handling.
69
+ add_action( 'w3tc_usage_statistics_of_request', array( $this, 'w3tc_usage_statistics_of_request' ), 10, 1 );
70
+ add_filter( 'w3tc_usage_statistics_metrics', array( $this, 'w3tc_usage_statistics_metrics' ) );
71
+ add_filter( 'w3tc_usage_statistics_sources', array( $this, 'w3tc_usage_statistics_sources' ) );
72
 
73
  if ( Util_Environment::is_wpmu() ) {
74
+ add_action( 'delete_blog', array( $this, 'on_change' ), 0 );
75
+ add_action( 'switch_blog', array( $this, 'switch_blog' ), 0, 2 );
 
 
 
 
 
 
 
76
  }
77
  }
78
 
81
  *
82
  * @return void
83
  */
84
+ public function cleanup() {
85
+ $w3_cache_file_cleaner = new Cache_File_Cleaner(
86
+ array(
87
+ 'cache_dir' => Util_Environment::cache_blog_dir( 'object' ),
88
+ 'clean_timelimit' => $this->_config->get_integer( 'timelimit.cache_gc' ),
89
+ )
90
+ );
91
 
92
  $w3_cache_file_cleaner->clean();
93
  }
95
  /**
96
  * Cron schedules filter
97
  *
98
+ * @param array $schedules Schedules.
99
+ *
100
  * @return array
101
  */
102
+ public function cron_schedules( $schedules ) {
103
  $gc = $this->_config->get_integer( 'objectcache.file.gc' );
104
 
105
+ return array_merge(
106
+ $schedules,
107
+ array(
108
  'w3_objectcache_cleanup' => array(
109
  'interval' => $gc,
110
+ 'display' => sprintf(
111
+ // translators: 1 interval in seconds.
112
+ __( '[W3TC] Object Cache file GC (every %d seconds)', 'w3-total-cache' ),
113
+ $gc
114
+ ),
115
+ ),
116
+ )
117
+ );
118
  }
119
 
120
  /**
121
  * Change action
122
  */
123
+ public function on_change() {
124
  static $flushed = false;
125
 
126
+ if ( ! $flushed ) {
127
  $flush = Dispatcher::component( 'CacheFlush' );
128
  $flush->objectcache_flush();
129
  $flushed = true;
132
 
133
  /**
134
  * Change post action
135
+ *
136
+ * @param integer $post_id Post ID.
137
+ * @param mixed $post Post.
138
  */
139
+ public function on_post_change( $post_id = 0, $post = null ) {
140
  static $flushed = false;
141
 
142
+ if ( ! $flushed ) {
143
+ if ( is_null( $post ) ) {
144
  $post = $post_id;
145
+ }
146
 
147
+ if ( $post_id > 0 && ! Util_Environment::is_flushable_post( $post, 'objectcache', $this->_config ) ) {
 
148
  return;
149
  }
150
 
156
 
157
  /**
158
  * Change action
159
+ *
160
+ * @param string $option Option key.
161
  */
162
+ public function on_change_option( $option ) {
163
  static $flushed = false;
164
+
165
+ /* // phpcs:ignore Squiz.PHP.CommentedOutCode.Found
166
+ if ( ! $flushed ) {
167
+ if ( 'cron' !== $option ) {
168
  $flush = Dispatcher::component( 'CacheFlush' );
169
  $flush->objectcache_flush();
170
  $flushed = true;
171
  }
172
+ }
173
+ */
174
  }
175
 
176
  /**
177
  * Flush cache when user profile is updated
178
  *
179
+ * @param integer $user_id User ID.
180
  */
181
+ public function on_change_profile( $user_id ) {
182
  static $flushed = false;
183
 
184
+ if ( ! $flushed ) {
185
  if ( Util_Environment::is_wpmu() ) {
186
  $blogs = get_blogs_of_user( $user_id, true );
187
  if ( $blogs ) {
199
 
200
  /**
201
  * Switch blog action
202
+ *
203
+ * @param integer $blog_id Blog ID.
204
+ * @param integer $previous_blog_id Previous Blog ID.
205
  */
206
+ public function switch_blog( $blog_id, $previous_blog_id ) {
207
  $o = Dispatcher::component( 'ObjectCache_WpObjectCache_Regular' );
208
  $o->switch_blog( $blog_id );
209
  }
212
  /**
213
  * Comment change action
214
  *
215
+ * @param integer $comment_id Comment ID.
216
  */
217
+ public function on_comment_change( $comment_id ) {
218
  $post_id = 0;
219
 
220
  if ( $comment_id ) {
221
  $comment = get_comment( $comment_id, ARRAY_A );
222
+ $post_id = ( ! empty( $comment['comment_post_ID'] ) ? (int) $comment['comment_post_ID'] : 0 );
 
223
  }
224
 
225
  $this->on_post_change( $post_id );
228
  /**
229
  * Comment status action
230
  *
231
+ * @param integer $comment_id Comment ID.
232
+ * @param string $status Status.
233
  */
234
+ public function on_comment_status( $comment_id, $status ) {
235
+ if ( 'approve' === $status || '1' === $status ) {
236
  $this->on_comment_change( $comment_id );
237
  }
238
  }
239
 
240
+ /**
241
+ * Setup admin menu elements
242
+ *
243
+ * @param array $menu_items Menu items.
244
+ */
245
  public function w3tc_admin_bar_menu( $menu_items ) {
246
  $menu_items['20410.objectcache'] = array(
247
+ 'id' => 'w3tc_flush_objectcache',
248
  'parent' => 'w3tc_flush',
249
+ 'title' => __( 'Object Cache', 'w3-total-cache' ),
250
+ 'href' => wp_nonce_url( admin_url( 'admin.php?page=w3tc_dashboard&amp;w3tc_flush_objectcache' ), 'w3tc' ),
 
251
  );
252
 
253
  return $menu_items;
254
  }
255
 
256
+ /**
257
+ * Setup admin menu elements
258
+ *
259
+ * @param array $strings Strings.
260
+ */
261
  public function w3tc_footer_comment( $strings ) {
262
+ $o = Dispatcher::component( 'ObjectCache_WpObjectCache_Regular' );
263
  $strings = $o->w3tc_footer_comment( $strings );
264
 
265
  return $strings;
266
  }
267
 
268
+ /**
269
+ * Usage statistics of request filter
270
+ *
271
+ * @param object $storage Storage object.
272
+ */
273
  public function w3tc_usage_statistics_of_request( $storage ) {
274
  $o = Dispatcher::component( 'ObjectCache_WpObjectCache_Regular' );
275
  $o->w3tc_usage_statistics_of_request( $storage );
276
  }
277
 
278
+ /**
279
+ * Retrive usage statistics metrics
280
+ *
281
+ * @param array $metrics Metrics.
282
+ */
283
  public function w3tc_usage_statistics_metrics( $metrics ) {
284
+ $metrics = array_merge(
285
+ $metrics,
286
+ array(
287
+ 'objectcache_get_total',
288
+ 'objectcache_get_hits',
289
+ 'objectcache_sets',
290
+ 'objectcache_flushes',
291
+ 'objectcache_time_ms',
292
+ )
293
+ );
294
 
295
  return $metrics;
296
  }
297
 
298
+ /**
299
+ * Usage Statisitcs sources filter.
300
+ *
301
+ * @param array $sources Sources.
302
+ *
303
+ * @return array
304
+ */
305
+ public function w3tc_usage_statistics_sources( $sources ) {
306
  $c = Dispatcher::config();
307
+ if ( 'apc' === $c->get_string( 'objectcache.engine' ) ) {
308
  $sources['apc_servers']['objectcache'] = array(
309
+ 'name' => __( 'Object Cache', 'w3-total-cache' ),
310
  );
311
+ } elseif ( 'memcached' === $c->get_string( 'objectcache.engine' ) ) {
312
  $sources['memcached_servers']['objectcache'] = array(
313
+ 'servers' => $c->get_array( 'objectcache.memcached.servers' ),
314
+ 'username' => $c->get_string( 'objectcache.memcached.username' ),
315
+ 'password' => $c->get_string( 'objectcache.memcached.password' ),
316
  'binary_protocol' => $c->get_boolean( 'objectcache.memcached.binary_protocol' ),
317
+ 'name' => __( 'Object Cache', 'w3-total-cache' ),
318
  );
319
+ } elseif ( 'redis' === $c->get_string( 'objectcache.engine' ) ) {
320
  $sources['redis_servers']['objectcache'] = array(
321
+ 'servers' => $c->get_array( 'objectcache.redis.servers' ),
322
+ 'verify_tls_certificates' => $c->get_boolean( 'objectcache.redis.verify_tls_certificates' ),
323
+ 'username' => $c->get_boolean( 'objectcache.redis.username' ),
324
+ 'dbid' => $c->get_integer( 'objectcache.redis.dbid' ),
325
+ 'password' => $c->get_string( 'objectcache.redis.password' ),
326
+ 'name' => __( 'Object Cache', 'w3-total-cache' ),
327
  );
328
  }
329
 
331
  }
332
 
333
  /**
334
+ * Returns flag for flushable.
335
  *
336
  * @return bool
337
  */
338
+ private function _do_flush() { // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore
339
+ // TODO: Requires admin flush until OC can make changes in Admin backend.
340
  return $this->_config->get_boolean( 'cluster.messagebus.enabled' )
341
  || $this->_config->get_boolean( 'objectcache.purge.all' )
342
  || defined( 'WP_ADMIN' );
PgCache_ContentGrabber.php CHANGED
@@ -2020,6 +2020,7 @@ class PgCache_ContentGrabber {
2020
 
2021
  private function _normalize_querystring( $querystring ) {
2022
  $ignore_qs = $this->_config->get_array( 'pgcache.accept.qs' );
 
2023
  $ignore_qs = w3tc_apply_filters( 'pagecache_extract_accept_qs', $ignore_qs );
2024
  Util_Rule::array_trim( $ignore_qs );
2025
 
2020
 
2021
  private function _normalize_querystring( $querystring ) {
2022
  $ignore_qs = $this->_config->get_array( 'pgcache.accept.qs' );
2023
+ $ignore_qs = array_merge( $ignore_qs, PgCache_QsExempts::get_qs_exempts() );
2024
  $ignore_qs = w3tc_apply_filters( 'pagecache_extract_accept_qs', $ignore_qs );
2025
  Util_Rule::array_trim( $ignore_qs );
2026
 
PgCache_Plugin.php CHANGED
@@ -1,4 +1,12 @@
1
  <?php
 
 
 
 
 
 
 
 
2
  namespace W3TC;
3
 
4
  /**
@@ -6,137 +14,110 @@ namespace W3TC;
6
  */
7
  class PgCache_Plugin {
8
  /**
9
- * Config
 
 
10
  */
11
  private $_config = null;
12
 
13
- function __construct() {
 
 
 
14
  $this->_config = Dispatcher::config();
15
  }
16
 
17
  /**
18
  * Runs plugin
19
  */
20
- function run() {
21
- add_action( 'w3tc_flush_all',
22
- array( $this, 'w3tc_flush_posts' ),
23
- 1100, 1 );
24
- add_action( 'w3tc_flush_group',
25
- array( $this, 'w3tc_flush_group' ),
26
- 1100, 2 );
27
- add_action( 'w3tc_flush_post',
28
- array( $this, 'w3tc_flush_post' ),
29
- 1100, 1 );
30
- add_action( 'w3tc_flushable_posts',
31
- '__return_true',
32
- 1100 );
33
- add_action( 'w3tc_flush_posts',
34
- array( $this, 'w3tc_flush_posts' ),
35
- 1100 );
36
- add_action( 'w3tc_flush_url',
37
- array( $this, 'w3tc_flush_url' ),
38
- 1100, 1 );
39
-
40
- add_filter( 'w3tc_pagecache_set_header',
41
- array( $this, 'w3tc_pagecache_set_header' ), 10, 3 );
42
- add_filter( 'w3tc_admin_bar_menu',
43
- array( $this, 'w3tc_admin_bar_menu' ) );
44
-
45
- add_filter( 'cron_schedules',
46
- array( $this, 'cron_schedules' ) );
47
-
48
- add_action( 'w3tc_config_save',
49
- array( $this, 'w3tc_config_save' ),
50
- 10, 1 );
51
 
52
- $o = Dispatcher::component( 'PgCache_ContentGrabber' );
 
 
 
 
53
 
54
- add_filter( 'w3tc_footer_comment',
55
- array( $o, 'w3tc_footer_comment' ) );
56
 
57
- add_action( 'w3tc_usage_statistics_of_request',
58
- array( $o, 'w3tc_usage_statistics_of_request' ),
59
- 10, 1 );
60
- add_filter( 'w3tc_usage_statistics_metrics',
61
- array( $this, 'w3tc_usage_statistics_metrics' ) );
62
- add_filter( 'w3tc_usage_statistics_sources', array(
63
- $this, 'w3tc_usage_statistics_sources' ) );
64
 
 
 
 
 
65
 
66
- if ( $this->_config->get_string( 'pgcache.engine' ) == 'file' ||
67
- $this->_config->get_string( 'pgcache.engine' ) == 'file_generic' ) {
68
- add_action( 'w3_pgcache_cleanup',
69
- array( $this, 'cleanup' ) );
70
  }
71
 
72
  add_action( 'w3_pgcache_prime', array( $this, 'prime' ) );
73
 
74
  Util_AttachToActions::flush_posts_on_actions();
75
 
76
- add_filter( 'comment_cookie_lifetime',
77
- array( $this, 'comment_cookie_lifetime' ) );
78
 
79
- if ( $this->_config->get_string( 'pgcache.engine' ) == 'file_generic' ) {
80
- add_action( 'wp_logout',
81
- array( $this, 'on_logout' ),
82
- 0 );
83
-
84
- add_action( 'wp_login',
85
- array( $this, 'on_login' ),
86
- 0 );
87
  }
88
 
89
  if ( $this->_config->get_boolean( 'pgcache.prime.post.enabled', false ) ) {
90
- add_action( 'publish_post',
91
- array( $this, 'prime_post' ),
92
- 30 );
93
  }
94
 
95
  if ( ( $this->_config->get_boolean( 'pgcache.late_init' ) ||
96
- $this->_config->get_boolean( 'pgcache.late_caching' ) ) &&
97
- !is_admin() ) {
98
  $o = Dispatcher::component( 'PgCache_ContentGrabber' );
99
- add_action( 'init',
100
- array( $o, 'delayed_cache_print' ),
101
- 99999 );
102
  }
103
 
104
- if ( !$this->_config->get_boolean( 'pgcache.mirrors.enabled' ) &&
105
- !Util_Environment::is_wpmu_subdomain() ) {
106
- add_action( 'init',
107
- array( $this, 'redirect_on_foreign_domain' ) );
108
  }
109
- if ( $this->_config->get_string( 'pgcache.rest' ) == 'disable' ) {
110
- // remove XMLRPC edit link
111
  remove_action( 'xmlrpc_rsd_apis', 'rest_output_rsd' );
112
- // remove wp-json in <head>
113
  remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
114
- // remove HTTP Header
115
  remove_action( 'template_redirect', 'rest_output_link_header', 11 );
116
 
117
- add_filter( 'rest_authentication_errors',
118
- array( $this, 'rest_authentication_errors' ),
119
- 100 );
120
  }
121
  }
122
 
123
-
124
-
 
 
 
 
 
125
  public function rest_authentication_errors( $result ) {
126
  $error_message = __( 'REST API disabled.', 'w3-total-cache' );
127
 
128
  return new \WP_Error( 'rest_disabled', $error_message, array( 'status' => rest_authorization_required_code() ) );
129
  }
130
 
131
-
132
-
133
  /**
134
  * Does disk cache cleanup
135
  *
136
  * @return void
137
  */
138
- function cleanup() {
139
- $this->_get_admin()->cleanup();
140
  }
141
 
142
  /**
@@ -144,117 +125,149 @@ class PgCache_Plugin {
144
  *
145
  * @return void
146
  */
147
- function prime() {
148
- $this->_get_admin()->prime();
149
  }
150
 
151
  /**
152
  * Instantiates worker on demand
153
  */
154
- private function _get_admin() {
155
  return Dispatcher::component( 'PgCache_Plugin_Admin' );
156
  }
157
 
158
  /**
159
  * Cron schedules filter
160
  *
161
- * @param array $schedules
 
162
  * @return array
163
  */
164
- function cron_schedules( $schedules ) {
165
  $c = $this->_config;
166
 
167
  if ( $c->get_boolean( 'pgcache.enabled' ) &&
168
- ( $c->get_string( 'pgcache.engine' ) == 'file' ||
169
- $c->get_string( 'pgcache.engine' ) == 'file_generic' ) ) {
170
- $v = $c->get_integer( 'pgcache.file.gc' );
171
  $schedules['w3_pgcache_cleanup'] = array(
172
  'interval' => $v,
173
- 'display' => sprintf( '[W3TC] Page Cache file GC (every %d seconds)',
174
- $v )
 
 
 
175
  );
176
  }
177
 
178
  if ( $c->get_boolean( 'pgcache.enabled' ) &&
179
  $c->get_boolean( 'pgcache.prime.enabled' ) ) {
180
- $v = $c->get_integer( 'pgcache.prime.interval' );
181
  $schedules['w3_pgcache_prime'] = array(
182
  'interval' => $v,
183
- 'display' => sprintf( '[W3TC] Page Cache prime (every %d seconds)',
184
- $v )
 
 
 
185
  );
186
  }
187
 
188
  return $schedules;
189
  }
190
 
 
 
 
191
  public function redirect_on_foreign_domain() {
192
  $request_host = Util_Environment::host();
193
- // host not known, potentially we are in console mode not http request
194
- if ( empty( $request_host ) || defined( 'WP_CLI' ) && WP_CLI )
 
195
  return;
 
196
 
197
- $home_url = get_home_url();
198
- $parsed_url = @parse_url( $home_url );
199
 
200
  if ( isset( $parsed_url['host'] ) &&
201
- strtolower( $parsed_url['host'] ) != strtolower( $request_host ) ) {
202
  $redirect_url = $parsed_url['scheme'] . '://';
203
- if ( !empty( $parsed_url['user'] ) ) {
 
204
  $redirect_url .= $parsed_url['user'];
205
- if ( !empty( $parsed_url['pass'] ) )
206
  $redirect_url .= ':' . $parsed_url['pass'];
 
207
  }
208
- if ( !empty( $parsed_url['host'] ) )
 
209
  $redirect_url .= $parsed_url['host'];
 
210
 
211
- if ( !empty( $parsed_url['port'] ) && $parsed_url['port'] != 80 ) {
212
- $redirect_url .= ':' . (int)$parsed_url['port'];
213
  }
214
 
215
  $redirect_url .= isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
216
 
217
- wp_redirect( $redirect_url, 301 );
 
218
  exit();
219
  }
220
  }
221
 
222
- function comment_cookie_lifetime( $lifetime ) {
 
 
 
 
 
223
  $l = $this->_config->get_integer( 'pgcache.comment_cookie_ttl' );
224
- if ( $l != -1 )
225
  return $l;
226
- else
227
  return $lifetime;
 
228
  }
229
 
230
  /**
231
  * Add cookie on logout to circumvent pagecache due to browser cache resulting in 304s
232
  */
233
- function on_logout() {
234
  setcookie( 'w3tc_logged_out' );
235
  }
236
 
237
  /**
238
  * Remove logout cookie on logins
239
  */
240
- function on_login() {
241
- if ( isset( $_COOKIE['w3tc_logged_out'] ) )
242
  setcookie( 'w3tc_logged_out', '', 1 );
 
243
  }
244
 
245
  /**
 
246
  *
 
247
  *
248
- * @param unknown $post_id
249
  * @return boolean
250
  */
251
- function prime_post( $post_id ) {
252
  $w3_pgcache = Dispatcher::component( 'CacheFlush' );
253
  return $w3_pgcache->prime_post( $post_id );
254
  }
255
 
 
 
 
 
 
256
  public function w3tc_usage_statistics_metrics( $metrics ) {
257
- return array_merge( $metrics, array(
 
 
258
  'php_requests_pagecache_hit',
259
  'php_requests_pagecache_miss_404',
260
  'php_requests_pagecache_miss_ajax',
@@ -266,65 +279,89 @@ class PgCache_Plugin {
266
  'php_requests_pagecache_miss_query_string',
267
  'php_requests_pagecache_miss_third_party',
268
  'php_requests_pagecache_miss_wp_admin',
269
- 'pagecache_requests_time_10ms' ) );
 
 
270
  }
271
 
 
 
 
 
 
 
 
272
  public function w3tc_usage_statistics_sources( $sources ) {
273
  $c = Dispatcher::config();
274
- if ( $c->get_string( 'pgcache.engine' ) == 'apc' ) {
275
  $sources['apc_servers']['pgcache'] = array(
276
- 'name' => __( 'Page Cache', 'w3-total-cache' )
277
  );
278
- } elseif ( $c->get_string( 'pgcache.engine' ) == 'memcached' ) {
279
  $sources['memcached_servers']['pgcache'] = array(
280
- 'servers' => $c->get_array( 'pgcache.memcached.servers' ),
281
- 'username' => $c->get_string( 'pgcache.memcached.username' ),
282
- 'password' => $c->get_string( 'pgcache.memcached.password' ),
283
  'binary_protocol' => $c->get_boolean( 'pgcache.memcached.binary_protocol' ),
284
- 'name' => __( 'Page Cache', 'w3-total-cache' )
285
  );
286
- } elseif ( $c->get_string( 'pgcache.engine' ) == 'redis' ) {
287
  $sources['redis_servers']['pgcache'] = array(
288
- 'servers' => $c->get_array( 'pgcache.redis.servers' ),
289
- 'dbid' => $c->get_integer( 'pgcache.redis.dbid' ),
290
- 'password' => $c->get_string( 'pgcache.redis.password' ),
291
- 'name' => __( 'Page Cache', 'w3-total-cache' )
 
292
  );
293
  }
294
 
295
  return $sources;
296
  }
297
 
 
 
 
 
 
298
  public function w3tc_admin_bar_menu( $menu_items ) {
299
  $menu_items['20110.pagecache'] = array(
300
- 'id' => 'w3tc_flush_pgcache',
301
  'parent' => 'w3tc_flush',
302
- 'title' => __( 'Page Cache: All', 'w3-total-cache' ),
303
- 'href' => wp_nonce_url( admin_url(
304
- 'admin.php?page=w3tc_dashboard&amp;w3tc_flush_pgcache' ),
305
- 'w3tc' )
306
  );
307
 
308
- if ( Util_Environment::detect_post_id() && ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) ) {
309
  $menu_items['20120.pagecache'] = array(
310
- 'id' => 'w3tc_pgcache_flush_post',
311
  'parent' => 'w3tc_flush',
312
- 'title' => __( 'Page Cache: Current Page', 'w3-total-cache' ),
313
- 'href' => wp_nonce_url( admin_url(
 
314
  'admin.php?page=w3tc_dashboard&amp;w3tc_flush_post&amp;post_id=' .
315
- Util_Environment::detect_post_id() ), 'w3tc' )
 
 
 
316
  );
317
  }
318
 
319
  return $menu_items;
320
  }
321
 
322
- function w3tc_flush_group( $group, $extras = array() ) {
323
- if ( isset( $extras['only'] ) && $extras['only'] != 'pagecache' )
 
 
 
 
 
 
324
  return;
 
325
 
326
  $pgcacheflush = Dispatcher::component( 'PgCache_Flush' );
327
- $v = $pgcacheflush->flush_group( $group );
328
 
329
  return $v;
330
  }
@@ -332,14 +369,17 @@ class PgCache_Plugin {
332
  /**
333
  * Flushes all caches
334
  *
 
 
335
  * @return boolean
336
  */
337
- function w3tc_flush_posts( $extras = array() ) {
338
- if ( isset( $extras['only'] ) && $extras['only'] != 'pagecache' )
339
  return;
 
340
 
341
  $pgcacheflush = Dispatcher::component( 'PgCache_Flush' );
342
- $v = $pgcacheflush->flush();
343
 
344
  return $v;
345
  }
@@ -347,12 +387,13 @@ class PgCache_Plugin {
347
  /**
348
  * Flushes post cache
349
  *
350
- * @param integer $post_id
 
351
  * @return boolean
352
  */
353
- function w3tc_flush_post( $post_id ) {
354
  $pgcacheflush = Dispatcher::component( 'PgCache_Flush' );
355
- $v = $pgcacheflush->flush_post( $post_id );
356
 
357
  return $v;
358
  }
@@ -360,12 +401,13 @@ class PgCache_Plugin {
360
  /**
361
  * Flushes post cache
362
  *
363
- * @param string $url
 
364
  * @return boolean
365
  */
366
- function w3tc_flush_url( $url ) {
367
  $pgcacheflush = Dispatcher::component( 'PgCache_Flush' );
368
- $v = $pgcacheflush->flush_url( $url );
369
 
370
  return $v;
371
  }
@@ -374,23 +416,30 @@ class PgCache_Plugin {
374
 
375
  /**
376
  * By default headers are not cached by file_generic
 
 
 
 
 
 
377
  */
378
- public function w3tc_pagecache_set_header( $header, $header_original,
379
- $pagecache_engine ) {
380
- if ( $pagecache_engine == 'file_generic' ) {
381
  return null;
382
  }
383
 
384
  return $header;
385
  }
386
 
387
-
388
-
 
 
 
389
  public function w3tc_config_save( $config ) {
390
- // frontend activity
391
  if ( $config->get_boolean( 'pgcache.cache.feed' ) ) {
392
  $config->set( 'pgcache.cache.nginx_handle_xml', true );
393
  }
394
  }
395
-
396
  }
1
  <?php
2
+ /**
3
+ * File: PgCache_Plugin.php
4
+ *
5
+ * @package W3TC
6
+ *
7
+ * phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
8
+ */
9
+
10
  namespace W3TC;
11
 
12
  /**
14
  */
15
  class PgCache_Plugin {
16
  /**
17
+ * Config.
18
+ *
19
+ * @var array
20
  */
21
  private $_config = null;
22
 
23
+ /**
24
+ * Constructor.
25
+ */
26
+ public function __construct() {
27
  $this->_config = Dispatcher::config();
28
  }
29
 
30
  /**
31
  * Runs plugin
32
  */
33
+ public function run() {
34
+ add_action( 'w3tc_flush_all', array( $this, 'w3tc_flush_posts' ), 1100, 1 );
35
+ add_action( 'w3tc_flush_group', array( $this, 'w3tc_flush_group' ), 1100, 2 );
36
+ add_action( 'w3tc_flush_post', array( $this, 'w3tc_flush_post' ), 1100, 1 );
37
+ add_action( 'w3tc_flushable_posts', '__return_true', 1100 );
38
+ add_action( 'w3tc_flush_posts', array( $this, 'w3tc_flush_posts' ), 1100 );
39
+ add_action( 'w3tc_flush_url', array( $this, 'w3tc_flush_url' ), 1100, 1 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ add_filter( 'w3tc_pagecache_set_header', array( $this, 'w3tc_pagecache_set_header' ), 10, 3 );
42
+ add_filter( 'w3tc_admin_bar_menu', array( $this, 'w3tc_admin_bar_menu' ) );
43
+
44
+ // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected
45
+ add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) );
46
 
47
+ add_action( 'w3tc_config_save', array( $this, 'w3tc_config_save' ), 10, 1 );
 
48
 
49
+ $o = Dispatcher::component( 'PgCache_ContentGrabber' );
50
+
51
+ add_filter( 'w3tc_footer_comment', array( $o, 'w3tc_footer_comment' ) );
 
 
 
 
52
 
53
+ // usage statistics handling.
54
+ add_action( 'w3tc_usage_statistics_of_request', array( $o, 'w3tc_usage_statistics_of_request' ), 10, 1 );
55
+ add_filter( 'w3tc_usage_statistics_metrics', array( $this, 'w3tc_usage_statistics_metrics' ) );
56
+ add_filter( 'w3tc_usage_statistics_sources', array( $this, 'w3tc_usage_statistics_sources' ) );
57
 
58
+ if ( 'file' === $this->_config->get_string( 'pgcache.engine' ) ||
59
+ 'file_generic' === $this->_config->get_string( 'pgcache.engine' ) ) {
60
+ add_action( 'w3_pgcache_cleanup', array( $this, 'cleanup' ) );
 
61
  }
62
 
63
  add_action( 'w3_pgcache_prime', array( $this, 'prime' ) );
64
 
65
  Util_AttachToActions::flush_posts_on_actions();
66
 
67
+ add_filter( 'comment_cookie_lifetime', array( $this, 'comment_cookie_lifetime' ) );
 
68
 
69
+ if ( 'file_generic' === $this->_config->get_string( 'pgcache.engine' ) ) {
70
+ add_action( 'wp_logout', array( $this, 'on_logout' ), 0 );
71
+ add_action( 'wp_login', array( $this, 'on_login' ), 0 );
 
 
 
 
 
72
  }
73
 
74
  if ( $this->_config->get_boolean( 'pgcache.prime.post.enabled', false ) ) {
75
+ add_action( 'publish_post', array( $this, 'prime_post' ), 30 );
 
 
76
  }
77
 
78
  if ( ( $this->_config->get_boolean( 'pgcache.late_init' ) ||
79
+ $this->_config->get_boolean( 'pgcache.late_caching' ) ) &&
80
+ ! is_admin() ) {
81
  $o = Dispatcher::component( 'PgCache_ContentGrabber' );
82
+ add_action( 'init', array( $o, 'delayed_cache_print' ), 99999 );
 
 
83
  }
84
 
85
+ if ( ! $this->_config->get_boolean( 'pgcache.mirrors.enabled' ) &&
86
+ ! Util_Environment::is_wpmu_subdomain() ) {
87
+ add_action( 'init', array( $this, 'redirect_on_foreign_domain' ) );
 
88
  }
89
+ if ( 'disable' === $this->_config->get_string( 'pgcache.rest' ) ) {
90
+ // remove XMLRPC edit link.
91
  remove_action( 'xmlrpc_rsd_apis', 'rest_output_rsd' );
92
+ // remove wp-json in <head>.
93
  remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
94
+ // remove HTTP Header.
95
  remove_action( 'template_redirect', 'rest_output_link_header', 11 );
96
 
97
+ add_filter( 'rest_authentication_errors', array( $this, 'rest_authentication_errors' ), 100 );
 
 
98
  }
99
  }
100
 
101
+ /**
102
+ * Get authentication WP Error.
103
+ *
104
+ * @param mixed $result Result.
105
+ *
106
+ * @return WP_Error
107
+ */
108
  public function rest_authentication_errors( $result ) {
109
  $error_message = __( 'REST API disabled.', 'w3-total-cache' );
110
 
111
  return new \WP_Error( 'rest_disabled', $error_message, array( 'status' => rest_authorization_required_code() ) );
112
  }
113
 
 
 
114
  /**
115
  * Does disk cache cleanup
116
  *
117
  * @return void
118
  */
119
+ public function cleanup() {
120
+ $this->get_admin()->cleanup();
121
  }
122
 
123
  /**
125
  *
126
  * @return void
127
  */
128
+ public function prime() {
129
+ $this->get_admin()->prime();
130
  }
131
 
132
  /**
133
  * Instantiates worker on demand
134
  */
135
+ private function get_admin() {
136
  return Dispatcher::component( 'PgCache_Plugin_Admin' );
137
  }
138
 
139
  /**
140
  * Cron schedules filter
141
  *
142
+ * @param array $schedules Schedules.
143
+ *
144
  * @return array
145
  */
146
+ public function cron_schedules( $schedules ) {
147
  $c = $this->_config;
148
 
149
  if ( $c->get_boolean( 'pgcache.enabled' ) &&
150
+ ( 'file' === $c->get_string( 'pgcache.engine' ) ||
151
+ 'file_generic' === $c->get_string( 'pgcache.engine' ) ) ) {
152
+ $v = $c->get_integer( 'pgcache.file.gc' );
153
  $schedules['w3_pgcache_cleanup'] = array(
154
  'interval' => $v,
155
+ 'display' => sprintf(
156
+ // translators: 1 interval in seconds.
157
+ __( '[W3TC] Page Cache file GC (every %d seconds)', 'w3-total-cache' ),
158
+ $v
159
+ ),
160
  );
161
  }
162
 
163
  if ( $c->get_boolean( 'pgcache.enabled' ) &&
164
  $c->get_boolean( 'pgcache.prime.enabled' ) ) {
165
+ $v = $c->get_integer( 'pgcache.prime.interval' );
166
  $schedules['w3_pgcache_prime'] = array(
167
  'interval' => $v,
168
+ 'display' => sprintf(
169
+ // translators: 1 interval in seconds.
170
+ __( '[W3TC] Page Cache prime (every %d seconds)', 'w3-total-cache' ),
171
+ $v
172
+ ),
173
  );
174
  }
175
 
176
  return $schedules;
177
  }
178
 
179
+ /**
180
+ * Redirect if foreign domain or WP_CLI.
181
+ */
182
  public function redirect_on_foreign_domain() {
183
  $request_host = Util_Environment::host();
184
+
185
+ // host not known, potentially we are in console mode not http request.
186
+ if ( empty( $request_host ) || defined( 'WP_CLI' ) && WP_CLI ) {
187
  return;
188
+ }
189
 
190
+ $home_url = get_home_url();
191
+ $parsed_url = @wp_parse_url( $home_url ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
192
 
193
  if ( isset( $parsed_url['host'] ) &&
194
+ strtolower( $parsed_url['host'] ) !== strtolower( $request_host ) ) {
195
  $redirect_url = $parsed_url['scheme'] . '://';
196
+
197
+ if ( ! empty( $parsed_url['user'] ) ) {
198
  $redirect_url .= $parsed_url['user'];
199
+ if ( ! empty( $parsed_url['pass'] ) ) {
200
  $redirect_url .= ':' . $parsed_url['pass'];
201
+ }
202
  }
203
+
204
+ if ( ! empty( $parsed_url['host'] ) ) {
205
  $redirect_url .= $parsed_url['host'];
206
+ }
207
 
208
+ if ( ! empty( $parsed_url['port'] ) && 80 !== (int) $parsed_url['port'] ) {
209
+ $redirect_url .= ':' . (int) $parsed_url['port'];
210
  }
211
 
212
  $redirect_url .= isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
213
 
214
+ wp_safe_redirect( $redirect_url, 301 );
215
+
216
  exit();
217
  }
218
  }
219
 
220
+ /**
221
+ * Get comment cookie lifetime
222
+ *
223
+ * @param integer $lifetime Comment cookie lifetime.
224
+ */
225
+ public function comment_cookie_lifetime( $lifetime ) {
226
  $l = $this->_config->get_integer( 'pgcache.comment_cookie_ttl' );
227
+ if ( -1 !== $l ) {
228
  return $l;
229
+ } else {
230
  return $lifetime;
231
+ }
232
  }
233
 
234
  /**
235
  * Add cookie on logout to circumvent pagecache due to browser cache resulting in 304s
236
  */
237
+ public function on_logout() {
238
  setcookie( 'w3tc_logged_out' );
239
  }
240
 
241
  /**
242
  * Remove logout cookie on logins
243
  */
244
+ public function on_login() {
245
+ if ( isset( $_COOKIE['w3tc_logged_out'] ) ) {
246
  setcookie( 'w3tc_logged_out', '', 1 );
247
+ }
248
  }
249
 
250
  /**
251
+ * Primes post.
252
  *
253
+ * @param integer $post_id Post ID.
254
  *
 
255
  * @return boolean
256
  */
257
+ public function prime_post( $post_id ) {
258
  $w3_pgcache = Dispatcher::component( 'CacheFlush' );
259
  return $w3_pgcache->prime_post( $post_id );
260
  }
261
 
262
+ /**
263
+ * Retrive usage statistics metrics
264
+ *
265
+ * @param array $metrics Metrics.
266
+ */
267
  public function w3tc_usage_statistics_metrics( $metrics ) {
268
+ return array_merge(
269
+ $metrics,
270
+ array(
271
  'php_requests_pagecache_hit',
272
  'php_requests_pagecache_miss_404',
273
  'php_requests_pagecache_miss_ajax',
279
  'php_requests_pagecache_miss_query_string',
280
  'php_requests_pagecache_miss_third_party',
281
  'php_requests_pagecache_miss_wp_admin',
282
+ 'pagecache_requests_time_10ms',
283
+ )
284
+ );
285
  }
286
 
287
+ /**
288
+ * Usage Statisitcs sources filter.
289
+ *
290
+ * @param array $sources Sources.
291
+ *
292
+ * @return array
293
+ */
294
  public function w3tc_usage_statistics_sources( $sources ) {
295
  $c = Dispatcher::config();
296
+ if ( 'apc' === $c->get_string( 'pgcache.engine' ) ) {
297
  $sources['apc_servers']['pgcache'] = array(
298
+ 'name' => __( 'Page Cache', 'w3-total-cache' ),
299
  );
300
+ } elseif ( 'memcached' === $c->get_string( 'pgcache.engine' ) ) {
301
  $sources['memcached_servers']['pgcache'] = array(
302
+ 'servers' => $c->get_array( 'pgcache.memcached.servers' ),
303
+ 'username' => $c->get_string( 'pgcache.memcached.username' ),
304
+ 'password' => $c->get_string( 'pgcache.memcached.password' ),
305
  'binary_protocol' => $c->get_boolean( 'pgcache.memcached.binary_protocol' ),
306
+ 'name' => __( 'Page Cache', 'w3-total-cache' ),
307
  );
308
+ } elseif ( 'redis' === $c->get_string( 'pgcache.engine' ) ) {
309
  $sources['redis_servers']['pgcache'] = array(
310
+ 'servers' => $c->get_array( 'pgcache.redis.servers' ),
311
+ 'verify_tls_certificates' => $c->get_boolean( 'pgcache.redis.verify_tls_certificates' ),
312
+ 'dbid' => $c->get_integer( 'pgcache.redis.dbid' ),
313
+ 'password' => $c->get_string( 'pgcache.redis.password' ),
314
+ 'name' => __( 'Page Cache', 'w3-total-cache' ),
315
  );
316
  }
317
 
318
  return $sources;
319
  }
320
 
321
+ /**
322
+ * Setup admin menu elements
323
+ *
324
+ * @param array $menu_items Menu items.
325
+ */
326
  public function w3tc_admin_bar_menu( $menu_items ) {
327
  $menu_items['20110.pagecache'] = array(
328
+ 'id' => 'w3tc_flush_pgcache',
329
  'parent' => 'w3tc_flush',
330
+ 'title' => __( 'Page Cache: All', 'w3-total-cache' ),
331
+ 'href' => wp_nonce_url( admin_url( 'admin.php?page=w3tc_dashboard&amp;w3tc_flush_pgcache' ), 'w3tc' ),
 
 
332
  );
333
 
334
+ if ( Util_Environment::detect_post_id() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) ) {
335
  $menu_items['20120.pagecache'] = array(
336
+ 'id' => 'w3tc_pgcache_flush_post',
337
  'parent' => 'w3tc_flush',
338
+ 'title' => __( 'Page Cache: Current Page', 'w3-total-cache' ),
339
+ 'href' => wp_nonce_url(
340
+ admin_url(
341
  'admin.php?page=w3tc_dashboard&amp;w3tc_flush_post&amp;post_id=' .
342
+ Util_Environment::detect_post_id()
343
+ ),
344
+ 'w3tc'
345
+ ),
346
  );
347
  }
348
 
349
  return $menu_items;
350
  }
351
 
352
+ /**
353
+ * Flush cache group.
354
+ *
355
+ * @param string $group Group name.
356
+ * @param array $extras Additionals to flush.
357
+ */
358
+ public function w3tc_flush_group( $group, $extras = array() ) {
359
+ if ( isset( $extras['only'] ) && 'pagecache' !== (string) $extras['only'] ) {
360
  return;
361
+ }
362
 
363
  $pgcacheflush = Dispatcher::component( 'PgCache_Flush' );
364
+ $v = $pgcacheflush->flush_group( $group );
365
 
366
  return $v;
367
  }
369
  /**
370
  * Flushes all caches
371
  *
372
+ * @param array $extras Additionals to flush.
373
+ *
374
  * @return boolean
375
  */
376
+ public function w3tc_flush_posts( $extras = array() ) {
377
+ if ( isset( $extras['only'] ) && 'pagecache' !== (string) $extras['only'] ) {
378
  return;
379
+ }
380
 
381
  $pgcacheflush = Dispatcher::component( 'PgCache_Flush' );
382
+ $v = $pgcacheflush->flush();
383
 
384
  return $v;
385
  }
387
  /**
388
  * Flushes post cache
389
  *
390
+ * @param integer $post_id Post ID.
391
+ *
392
  * @return boolean
393
  */
394
+ public function w3tc_flush_post( $post_id ) {
395
  $pgcacheflush = Dispatcher::component( 'PgCache_Flush' );
396
+ $v = $pgcacheflush->flush_post( $post_id );
397
 
398
  return $v;
399
  }
401
  /**
402
  * Flushes post cache
403
  *
404
+ * @param string $url URL.
405
+ *
406
  * @return boolean
407
  */
408
+ public function w3tc_flush_url( $url ) {
409
  $pgcacheflush = Dispatcher::component( 'PgCache_Flush' );
410
+ $v = $pgcacheflush->flush_url( $url );
411
 
412
  return $v;
413
  }
416
 
417
  /**
418
  * By default headers are not cached by file_generic
419
+ *
420
+ * @param mixed $header New header.
421
+ * @param mixed $header_original Original header.
422
+ * @param string $pagecache_engine Engine name.
423
+ *
424
+ * @return mixed|null
425
  */
426
+ public function w3tc_pagecache_set_header( $header, $header_original, $pagecache_engine ) {
427
+ if ( 'file_generic' === (string) $pagecache_engine ) {
 
428
  return null;
429
  }
430
 
431
  return $header;
432
  }
433
 
434
+ /**
435
+ * Save config item
436
+ *
437
+ * @param array $config Config.
438
+ */
439
  public function w3tc_config_save( $config ) {
440
+ // frontend activity.
441
  if ( $config->get_boolean( 'pgcache.cache.feed' ) ) {
442
  $config->set( 'pgcache.cache.nginx_handle_xml', true );
443
  }
444
  }
 
445
  }
PgCache_QsExempts.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: PgCache_QsExempts.php
4
+ *
5
+ * @package W3TC
6
+ */
7
+
8
+ namespace W3TC;
9
+
10
+ /**
11
+ * Class: PgCache_QsExempts
12
+ */
13
+ class PgCache_QsExempts {
14
+ /**
15
+ * Returns list of default accepted QS key/values to be ignored when generating the Page Cache.
16
+ */
17
+ public static function get_qs_exempts() {
18
+ return array(
19
+ '_branch_match_id',
20
+ '_bta_c',
21
+ '_bta_tid',
22
+ '_ga',
23
+ '_gl',
24
+ '_ke',
25
+ 'adgroupid',
26
+ 'adid',
27
+ 'age-verified',
28
+ 'ao_noptimize',
29
+ 'campaignid',
30
+ 'campid',
31
+ 'cn-reloaded',
32
+ 'customid',
33
+ 'dm_i',
34
+ 'ef_id',
35
+ 'epik',
36
+ 'fb_action_ids',
37
+ 'fb_action_types',
38
+ 'fb_source',
39
+ 'fbclid',
40
+ 'gclid',
41
+ 'gclsrc',
42
+ 'gdffi',
43
+ 'gdfms',
44
+ 'gdftrk',
45
+ 'hsa_acc',
46
+ 'hsa_ad',
47
+ 'hsa_cam',
48
+ 'hsa_grp',
49
+ 'hsa_kw',
50
+ 'hsa_mt',
51
+ 'hsa_net',
52
+ 'hsa_src',
53
+ 'hsa_tgt',
54
+ 'hsa_ver',
55
+ 'igshid',
56
+ 'matomo_campaign',
57
+ 'matomo_cid',
58
+ 'matomo_content',
59
+ 'matomo_group',
60
+ 'matomo_keyword',
61
+ 'matomo_medium',
62
+ 'matomo_placement',
63
+ 'matomo_source',
64
+ 'mc_cid',
65
+ 'mc_eid',
66
+ 'mkcid',
67
+ 'mkevt',
68
+ 'mkrid',
69
+ 'mkwid',
70
+ 'msclkid',
71
+ 'mtm_campaign',
72
+ 'mtm_cid',
73
+ 'mtm_content',
74
+ 'mtm_group',
75
+ 'mtm_keyword',
76
+ 'mtm_medium',
77
+ 'mtm_placement',
78
+ 'mtm_source',
79
+ 'pcrid',
80
+ 'piwik_campaign',
81
+ 'piwik_keyword',
82
+ 'piwik_kwd',
83
+ 'pk_campaign',
84
+ 'pk_cid',
85
+ 'pk_content',
86
+ 'pk_keyword',
87
+ 'pk_kwd',
88
+ 'pk_medium',
89
+ 'pk_source',
90
+ 'pp',
91
+ 'redirect_log_mongo_id',
92
+ 'redirect_mongo_id',
93
+ 'ref',
94
+ 's_kwcid',
95
+ 's_kwcid',
96
+ 'sb_referer_host',
97
+ 'si',
98
+ 'sscid',
99
+ 'toolid',
100
+ 'trk_contact',
101
+ 'trk_module',
102
+ 'trk_msg',
103
+ 'trk_sid',
104
+ 'usqp',
105
+ 'utm_campaign',
106
+ 'utm_content',
107
+ 'utm_expid',
108
+ 'utm_id',
109
+ 'utm_medium',
110
+ 'utm_source',
111
+ 'utm_term',
112
+ );
113
+ }
114
+ }
UsageStatistics_Sources_Redis.php CHANGED
@@ -1,44 +1,66 @@
1
  <?php
2
- namespace W3TC;
3
-
 
 
 
4
 
 
5
 
 
 
 
6
  class UsageStatistics_Sources_Redis {
 
 
 
 
 
7
  private $servers;
8
 
9
-
10
-
 
 
 
11
  public function __construct( $server_descriptors ) {
12
  $this->servers = array();
13
 
14
  foreach ( $server_descriptors as $i ) {
15
  foreach ( $i['servers'] as $host_port ) {
16
- if ( !isset( $this->servers[$host_port] ) )
17
- $this->servers[$host_port] = array(
18
- 'password' => $i['password'],
19
- 'dbid' => $i['dbid'],
20
- 'module_names' => array( $i['name'] )
21
  );
22
- else
23
- $this->servers[$host_port]['module_names'][] = $i['name'];
 
24
  }
25
  }
26
  }
27
 
28
-
29
-
 
30
  public function get_snapshot() {
31
  $size_used = 0;
32
  $get_calls = 0;
33
- $get_hits = 0;
34
 
35
  foreach ( $this->servers as $host_port => $i ) {
36
- $cache = Cache::instance( 'redis',
 
37
  array(
38
- 'servers' => array( $host_port ),
39
- 'password' => $i['password'],
40
- 'dbid' => $i['dbid']
41
- ) );
 
 
 
 
42
 
43
  $stats = $cache->get_statistics();
44
 
@@ -46,94 +68,62 @@ class UsageStatistics_Sources_Redis {
46
  $get_calls +=
47
  Util_UsageStatistics::v3( $stats, 'keyspace_hits' ) +
48
  Util_UsageStatistics::v3( $stats, 'keyspace_misses' );
49
- $get_hits += Util_UsageStatistics::v( $stats, 'keyspace_hits' );
50
  }
51
 
52
  return array(
53
  'size_used' => $size_used,
54
  'get_calls' => $get_calls,
55
- 'get_hits' => $get_hits
56
  );
57
  }
58
 
59
-
60
-
 
61
  public function get_summary() {
62
  $sum = array(
63
- 'module_names' => array(),
64
- 'size_used' => 0,
65
  'size_maxbytes' => 0,
66
- 'get_total' => 0,
67
- 'get_hits' => 0,
68
- 'evictions' => 0,
69
- 'uptime' => 0
70
  );
71
 
72
  foreach ( $this->servers as $host_port => $i ) {
73
- $cache = Cache::instance( 'redis',
 
74
  array(
75
- 'servers' => array( $host_port ),
76
- 'password' => $i['password'],
77
- 'dbid' => $i['dbid']
78
- ) );
 
 
 
 
79
 
80
  $stats = $cache->get_statistics();
81
 
82
- $sum['module_names'] =
83
- array_merge( $sum['module_names'], $i['module_names'] );
84
- $sum['size_used'] += Util_UsageStatistics::v3( $stats, 'used_memory');
85
- $sum['get_total'] +=
86
  Util_UsageStatistics::v3( $stats, 'keyspace_hits' ) +
87
  Util_UsageStatistics::v3( $stats, 'keyspace_misses' );
88
- $sum['get_hits'] += Util_UsageStatistics::v3( $stats, 'keyspace_hits' );
89
- $sum['evictions'] += Util_UsageStatistics::v3( $stats, 'evicted_keys' );
90
- $sum['uptime'] += Util_UsageStatistics::v3( $stats, 'uptime_in_seconds' );
91
  }
92
 
93
  $summary = array(
94
- 'module_names' => implode( ',', $sum['module_names'] ),
95
- 'size_used' => Util_UsageStatistics::bytes_to_size2(
96
- $sum, 'size_used' ),
97
- 'get_hit_rate' => Util_UsageStatistics::percent2(
98
- $sum, 'get_hits', 'get_total' ),
99
- 'evictions_per_second' => Util_UsageStatistics::value_per_second(
100
- $sum, 'evictions', 'uptime' )
101
  );
102
 
103
  return $summary;
104
-
105
-
106
- $summary = array();
107
-
108
- foreach ( $servers as $host_port => $i ) {
109
- $cache = Cache::instance( 'redis',
110
- array(
111
- 'servers' => array( $host_port ),
112
- 'password' => $i['password'],
113
- 'dbid' => $i['dbid']
114
- ) );
115
-
116
- $stats = $cache->get_statistics();
117
-
118
- if ( isset( $stats['keyspace_hits'] ) && $stats['keyspace_misses'] )
119
- $stats['_keyspace_total'] =
120
- (int)$stats['keyspace_hits'] + (int)$stats['keyspace_misses'];
121
-
122
- $id = md5( $host_port );
123
- $summary[$id] = array(
124
- 'name' => $host_port,
125
- 'module_names' => $i['module_names'],
126
- 'size_used' =>
127
- Util_UsageStatistics::bytes_to_size2( $stats, 'used_memory' ),
128
- 'hit_rate' =>
129
- Util_UsageStatistics::percent2( $stats, 'keyspace_hits', '_keyspace_total' ),
130
- 'expirations_per_second' => Util_UsageStatistics::value_per_second(
131
- $stats, 'expired_keys', 'uptime_in_seconds' ),
132
- 'evictions_per_second' => Util_UsageStatistics::value_per_second(
133
- $stats, 'evicted_keys', 'uptime_in_seconds' )
134
- );
135
- }
136
-
137
- return $summary;
138
  }
139
  }
1
  <?php
2
+ /**
3
+ * File: UsageStatistics_Sources_Redis.php
4
+ *
5
+ * @package W3TC
6
+ */
7
 
8
+ namespace W3TC;
9
 
10
+ /**
11
+ * Usage Statistics Sources for Redis
12
+ */
13
  class UsageStatistics_Sources_Redis {
14
+ /**
15
+ * Servers.
16
+ *
17
+ * @var array
18
+ */
19
  private $servers;
20
 
21
+ /**
22
+ * Constructor.
23
+ *
24
+ * @param array $server_descriptors Server desriptors.
25
+ */
26
  public function __construct( $server_descriptors ) {
27
  $this->servers = array();
28
 
29
  foreach ( $server_descriptors as $i ) {
30
  foreach ( $i['servers'] as $host_port ) {
31
+ if ( ! isset( $this->servers[ $host_port ] ) ) {
32
+ $this->servers[ $host_port ] = array(
33
+ 'password' => $i['password'],
34
+ 'dbid' => $i['dbid'],
35
+ 'module_names' => array( $i['name'] ),
36
  );
37
+ } else {
38
+ $this->servers[ $host_port ]['module_names'][] = $i['name'];
39
+ }
40
  }
41
  }
42
  }
43
 
44
+ /**
45
+ * Get snapshot stats.
46
+ */
47
  public function get_snapshot() {
48
  $size_used = 0;
49
  $get_calls = 0;
50
+ $get_hits = 0;
51
 
52
  foreach ( $this->servers as $host_port => $i ) {
53
+ $cache = Cache::instance(
54
+ 'redis',
55
  array(
56
+ 'servers' => array( $host_port ),
57
+ 'password' => $i['password'],
58
+ 'dbid' => $i['dbid'],
59
+ 'timeout' => 0,
60
+ 'retry_interval' => 0,
61
+ 'read_timeout' => 0,
62
+ )
63
+ );
64
 
65
  $stats = $cache->get_statistics();
66
 
68
  $get_calls +=
69
  Util_UsageStatistics::v3( $stats, 'keyspace_hits' ) +
70
  Util_UsageStatistics::v3( $stats, 'keyspace_misses' );
71
+ $get_hits += Util_UsageStatistics::v( $stats, 'keyspace_hits' );
72
  }
73
 
74
  return array(
75
  'size_used' => $size_used,
76
  'get_calls' => $get_calls,
77
+ 'get_hits' => $get_hits,
78
  );
79
  }
80
 
81
+ /**
82
+ * Get stats summary.
83
+ */
84
  public function get_summary() {
85
  $sum = array(
86
+ 'module_names' => array(),
87
+ 'size_used' => 0,
88
  'size_maxbytes' => 0,
89
+ 'get_total' => 0,
90
+ 'get_hits' => 0,
91
+ 'evictions' => 0,
92
+ 'uptime' => 0,
93
  );
94
 
95
  foreach ( $this->servers as $host_port => $i ) {
96
+ $cache = Cache::instance(
97
+ 'redis',
98
  array(
99
+ 'servers' => array( $host_port ),
100
+ 'password' => $i['password'],
101
+ 'dbid' => $i['dbid'],
102
+ 'timeout' => 0,
103
+ 'retry_interval' => 0,
104
+ 'read_timeout' => 0,
105
+ )
106
+ );
107
 
108
  $stats = $cache->get_statistics();
109
 
110
+ $sum['module_names'] = array_merge( $sum['module_names'], $i['module_names'] );
111
+ $sum['size_used'] += Util_UsageStatistics::v3( $stats, 'used_memory' );
112
+ $sum['get_total'] +=
 
113
  Util_UsageStatistics::v3( $stats, 'keyspace_hits' ) +
114
  Util_UsageStatistics::v3( $stats, 'keyspace_misses' );
115
+ $sum['get_hits'] += Util_UsageStatistics::v3( $stats, 'keyspace_hits' );
116
+ $sum['evictions'] += Util_UsageStatistics::v3( $stats, 'evicted_keys' );
117
+ $sum['uptime'] += Util_UsageStatistics::v3( $stats, 'uptime_in_seconds' );
118
  }
119
 
120
  $summary = array(
121
+ 'module_names' => implode( ',', $sum['module_names'] ),
122
+ 'size_used' => Util_UsageStatistics::bytes_to_size2( $sum, 'size_used' ),
123
+ 'get_hit_rate' => Util_UsageStatistics::percent2( $sum, 'get_hits', 'get_total' ),
124
+ 'evictions_per_second' => Util_UsageStatistics::value_per_second( $sum, 'evictions', 'uptime' ),
 
 
 
125
  );
126
 
127
  return $summary;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  }
129
  }
inc/options/parts/redis.php CHANGED
@@ -30,13 +30,20 @@ if ( ! defined( 'W3TC' ) ) {
30
  <p class="description"><?php esc_html_e( 'Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122. To use TLS, prefix server with tls://', 'w3-total-cache' ); ?></p>
31
  </td>
32
  </tr>
33
- <tr class="hidden">
34
- <th><label><?php esc_html_e( 'Verify TLS Certificates:', 'w3-total-cache' ); ?></label></th>
35
- <td>
36
- <?php $this->checkbox( $module . '.redis.verify_tls_certificates' ); ?> <?php echo wp_kses( Util_ConfigLabel::get( 'redis.verify_tls_certificates' ), array( 'acronym' => array( 'title' => array() ) ) ); ?></label>
37
- <p class="description"><?php esc_html_e( 'Verify the server\'s certificate when connecting via TLS.', 'w3-total-cache' ); ?></p>
38
- </td>
39
- </tr>
 
 
 
 
 
 
 
40
  <tr>
41
  <th><label><?php esc_html_e( 'Use persistent connection:', 'w3-total-cache' ); ?></label></th>
42
  <td>
@@ -65,19 +72,19 @@ if ( ! defined( 'W3TC' ) ) {
65
  </td>
66
  </tr>
67
  <?php
68
- if ( version_compare( phpversion( 'redis' ), '5', '>=' ) ) {
69
- // PHP Redis 5 supports the read_timeout setting.
70
  ?>
71
- <tr>
72
- <th style="width: 250px;"><label for="redis_read_timeout"><?php echo wp_kses( Util_ConfigLabel::get( 'redis.read_timeout' ), array( 'acronym' => array( 'title' => array() ) ) ); ?></label></th>
73
- <td>
74
- <input id="redis_read_timeout" type="number" name="<?php echo esc_attr( $module ); ?>__redis__read_timeout"
75
- <?php Util_Ui::sealing_disabled( $module ); ?>
76
- value="<?php echo esc_attr( $this->_config->get_integer( $module . '.redis.read_timeout' ) ); ?>"
77
- size="8" step="1" min="0" />
78
- <p class="description"><?php esc_html_e( 'In seconds', 'w3-total-cache' ); ?></p>
79
- </td>
80
- </tr>
81
  <?php
82
  }
83
  ?>
30
  <p class="description"><?php esc_html_e( 'Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122. To use TLS, prefix server with tls://', 'w3-total-cache' ); ?></p>
31
  </td>
32
  </tr>
33
+ <?php
34
+ // PHP Redis 5.3.2+ supports SSL/TLS.
35
+ if ( version_compare( phpversion( 'redis' ), '5.3.2', '>=' ) ) {
36
+ ?>
37
+ <tr>
38
+ <th><label><?php esc_html_e( 'Verify TLS Certificates:', 'w3-total-cache' ); ?></label></th>
39
+ <td>
40
+ <?php $this->checkbox( $module . '.redis.verify_tls_certificates' ); ?> <?php echo wp_kses( Util_ConfigLabel::get( 'redis.verify_tls_certificates' ), array( 'acronym' => array( 'title' => array() ) ) ); ?></label>
41
+ <p class="description"><?php esc_html_e( 'Verify the server\'s certificate when connecting via TLS.', 'w3-total-cache' ); ?></p>
42
+ </td>
43
+ </tr>
44
+ <?php
45
+ }
46
+ ?>
47
  <tr>
48
  <th><label><?php esc_html_e( 'Use persistent connection:', 'w3-total-cache' ); ?></label></th>
49
  <td>
72
  </td>
73
  </tr>
74
  <?php
75
+ // PHP Redis 3.1.3+ supports the read_timeout setting.
76
+ if ( version_compare( phpversion( 'redis' ), '3.1.3', '>=' ) ) {
77
  ?>
78
+ <tr>
79
+ <th style="width: 250px;"><label for="redis_read_timeout"><?php echo wp_kses( Util_ConfigLabel::get( 'redis.read_timeout' ), array( 'acronym' => array( 'title' => array() ) ) ); ?></label></th>
80
+ <td>
81
+ <input id="redis_read_timeout" type="number" name="<?php echo esc_attr( $module ); ?>__redis__read_timeout"
82
+ <?php Util_Ui::sealing_disabled( $module ); ?>
83
+ value="<?php echo esc_attr( $this->_config->get_integer( $module . '.redis.read_timeout' ) ); ?>"
84
+ size="8" step="1" min="0" />
85
+ <p class="description"><?php esc_html_e( 'In seconds', 'w3-total-cache' ); ?></p>
86
+ </td>
87
+ </tr>
88
  <?php
89
  }
90
  ?>
ini/config-db-sample.php CHANGED
@@ -1,34 +1,36 @@
1
  <?php
 
 
 
 
 
2
 
3
  define( 'W3TC_CONFIG_DATABASE', true );
4
 
5
- // optional - specify table to store
6
  define( 'W3TC_CONFIG_DATABASE_TABLE', 'wp_options' );
7
 
8
  // cache config in cache to prevent db queries on each http request.
9
  // if multiple http servers used - use only shared cache storage used by all
10
  // machines, since distributed flush operations are not supported for config
11
- // cache
12
 
13
- //
14
- // memcached cache config
15
- //
16
- define( 'W3TC_CONFIG_CACHE_ENGINE', 'memcached');
17
  define( 'W3TC_CONFIG_CACHE_MEMCACHED_SERVERS', '127.0.0.1:11211' );
18
 
19
- // optional memcached settings
20
  define( 'W3TC_CONFIG_CACHE_MEMCACHED_PERSISTENT', true );
21
  define( 'W3TC_CONFIG_CACHE_MEMCACHED_AWS_AUTODISCOVERY', false );
22
  define( 'W3TC_CONFIG_CACHE_MEMCACHED_USERNAME', '' );
23
  define( 'W3TC_CONFIG_CACHE_MEMCACHED_PASSWORD', '' );
24
 
25
- //
26
- // redis config cache
27
- //
28
- define( 'W3TC_CONFIG_CACHE_ENGINE', 'redis');
29
  define( 'W3TC_CONFIG_CACHE_REDIS_SERVERS', '127.0.0.1:6379' );
 
30
 
31
- // optional redis settings
32
  define( 'W3TC_CONFIG_CACHE_REDIS_PERSISTENT', true );
33
  define( 'W3TC_CONFIG_CACHE_REDIS_DBID', 0 );
34
  define( 'W3TC_CONFIG_CACHE_REDIS_PASSWORD', '' );
1
  <?php
2
+ /**
3
+ * File: config-db-sample.php
4
+ *
5
+ * @package W3TC
6
+ */
7
 
8
  define( 'W3TC_CONFIG_DATABASE', true );
9
 
10
+ // optional - specify table to store.
11
  define( 'W3TC_CONFIG_DATABASE_TABLE', 'wp_options' );
12
 
13
  // cache config in cache to prevent db queries on each http request.
14
  // if multiple http servers used - use only shared cache storage used by all
15
  // machines, since distributed flush operations are not supported for config
16
+ // cache.
17
 
18
+ // memcached cache config.
19
+ define( 'W3TC_CONFIG_CACHE_ENGINE', 'memcached' );
 
 
20
  define( 'W3TC_CONFIG_CACHE_MEMCACHED_SERVERS', '127.0.0.1:11211' );
21
 
22
+ // optional memcached settings.
23
  define( 'W3TC_CONFIG_CACHE_MEMCACHED_PERSISTENT', true );
24
  define( 'W3TC_CONFIG_CACHE_MEMCACHED_AWS_AUTODISCOVERY', false );
25
  define( 'W3TC_CONFIG_CACHE_MEMCACHED_USERNAME', '' );
26
  define( 'W3TC_CONFIG_CACHE_MEMCACHED_PASSWORD', '' );
27
 
28
+ // redis config cache.
29
+ define( 'W3TC_CONFIG_CACHE_ENGINE', 'redis' );
 
 
30
  define( 'W3TC_CONFIG_CACHE_REDIS_SERVERS', '127.0.0.1:6379' );
31
+ define( 'W3TC_CONFIG_CACHE_REDIS_VERIFY_TLS_CERTIFICATES', true );
32
 
33
+ // optional redis settings.
34
  define( 'W3TC_CONFIG_CACHE_REDIS_PERSISTENT', true );
35
  define( 'W3TC_CONFIG_CACHE_REDIS_DBID', 0 );
36
  define( 'W3TC_CONFIG_CACHE_REDIS_PASSWORD', '' );
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: boldgrid, fredericktownes, maxicusc, gidomanders, bwmarkle, harryjackson1221, joemoto, vmarko, jacobd91
3
  Tags: seo, cache, CDN, pagespeed, caching, performance, compression, optimize, cloudflare, nginx, apache, varnish, redis, aws, amazon web services, s3, cloudfront, azure
4
  Requires at least: 5.3
5
- Tested up to: 6.0
6
- Stable tag: 2.2.6
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -285,6 +285,12 @@ Please reach out to all of these people and support their projects if you're so
285
 
286
  == Changelog ==
287
 
 
 
 
 
 
 
288
  = 2.2.6 =
289
  * Fix: Error clearing all cache when using Cloudfront full CDN in Pro
290
 
@@ -293,7 +299,7 @@ Please reach out to all of these people and support their projects if you're so
293
  * Fix: DB cache syntax error in PHP 5.6
294
  * Fix: Added missing space to S3 CDN bucket label
295
  * Fix: JS error for CloudFront CDN related check on non-W3TC pages
296
- * Fix: Page cache unpack warning for empty/malformed files
297
  * Enhancement: Image Service pre_get_posts anonymous action now hooked (w3tc_modify_query_obj)
298
  * Enhancement: Image Service ajax_query_attachments_args anonymous action now hooked (w3tc_filter_ajax_args)
299
 
2
  Contributors: boldgrid, fredericktownes, maxicusc, gidomanders, bwmarkle, harryjackson1221, joemoto, vmarko, jacobd91
3
  Tags: seo, cache, CDN, pagespeed, caching, performance, compression, optimize, cloudflare, nginx, apache, varnish, redis, aws, amazon web services, s3, cloudfront, azure
4
  Requires at least: 5.3
5
+ Tested up to: 6.1
6
+ Stable tag: 2.2.7
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
285
 
286
  == Changelog ==
287
 
288
+ = 2.2.7 =
289
+ * Fix: Updated database cache connection class to avoid deprecated warnings in WordPress 6.1
290
+ * Fix: Redis: Fixed handling of retry interval and timeout options for usage statistics
291
+ * Enhancement: Redis: Added TLS/SSL certificate verification option
292
+ * Enhancement: Page cache: Added query string exemptions
293
+
294
  = 2.2.6 =
295
  * Fix: Error clearing all cache when using Cloudfront full CDN in Pro
296
 
299
  * Fix: DB cache syntax error in PHP 5.6
300
  * Fix: Added missing space to S3 CDN bucket label
301
  * Fix: JS error for CloudFront CDN related check on non-W3TC pages
302
+ * Fix: Page cache unpack warning for empty/malformed files
303
  * Enhancement: Image Service pre_get_posts anonymous action now hooked (w3tc_modify_query_obj)
304
  * Enhancement: Image Service ajax_query_attachments_args anonymous action now hooked (w3tc_filter_ajax_args)
305
 
w3-total-cache-api.php CHANGED
@@ -12,7 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  }
13
 
14
  define( 'W3TC', true );
15
- define( 'W3TC_VERSION', '2.2.6' );
16
  define( 'W3TC_POWERED_BY', 'W3 Total Cache' );
17
  define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' );
18
  define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' );
12
  }
13
 
14
  define( 'W3TC', true );
15
+ define( 'W3TC_VERSION', '2.2.7' );
16
  define( 'W3TC_POWERED_BY', 'W3 Total Cache' );
17
  define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' );
18
  define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' );
w3-total-cache.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: W3 Total Cache
4
  * Plugin URI: https://www.boldgrid.com/totalcache/
5
  * Description: The highest rated and most complete WordPress performance plugin. Dramatically improve the speed and user experience of your site. Add browser, page, object and database caching as well as minify and content delivery network (CDN) to WordPress.
6
- * Version: 2.2.6
7
  * Requires at least: 5.3
8
  * Requires PHP: 5.6
9
  * Author: BoldGrid
3
  * Plugin Name: W3 Total Cache
4
  * Plugin URI: https://www.boldgrid.com/totalcache/
5
  * Description: The highest rated and most complete WordPress performance plugin. Dramatically improve the speed and user experience of your site. Add browser, page, object and database caching as well as minify and content delivery network (CDN) to WordPress.
6
+ * Version: 2.2.7
7
  * Requires at least: 5.3
8
  * Requires PHP: 5.6
9
  * Author: BoldGrid
wp-content/db.php CHANGED
@@ -16,8 +16,14 @@ if ( ! defined( 'W3TC_DIR' ) ) {
16
  */
17
  if ( ! @is_dir( W3TC_DIR ) || ! file_exists( W3TC_DIR . '/w3-total-cache-api.php' ) ) {
18
  if ( ! defined( 'WP_ADMIN' ) ) {
 
 
19
  // lets don't show error on front end.
20
- require_once ABSPATH . WPINC . '/wp-db.php';
 
 
 
 
21
  } else {
22
  echo wp_kses(
23
  sprintf(
16
  */
17
  if ( ! @is_dir( W3TC_DIR ) || ! file_exists( W3TC_DIR . '/w3-total-cache-api.php' ) ) {
18
  if ( ! defined( 'WP_ADMIN' ) ) {
19
+ global $wp_version;
20
+
21
  // lets don't show error on front end.
22
+ if ( version_compare( $wp_version, '6.1-beta1', '>=' ) ) {
23
+ require_once ABSPATH . WPINC . '/class-wpdb.php';
24
+ } else {
25
+ require_once ABSPATH . WPINC . '/wp-db.php';
26
+ }
27
  } else {
28
  echo wp_kses(
29
  sprintf(