Redis Object Cache - Version 2.0.12

Version Description

  • Fixed bytes metrics calculation
  • Fixed an issue with non-standard Predis configurations
  • Improve WordPress Coding Standards
Download this release

Release Info

Developer tillkruess
Plugin Icon 128x128 Redis Object Cache
Version 2.0.12
Comparing to
See all releases

Code changes from version 2.0.11 to 2.0.12

assets/js/admin.js CHANGED
@@ -354,7 +354,7 @@
354
  time: function ( entry ) {
355
  return [ entry[0], entry[1] * 0.5 ]
356
  },
357
- ratio: function ( entry ) {
358
  return [ entry[0], entry[1] * 0.3 ]
359
  },
360
  calls: function ( entry ) {
@@ -449,9 +449,12 @@
449
  function ( event ) {
450
  event.preventDefault();
451
 
 
 
452
  $.post( ajaxurl, {
453
- notice: $( this ).parent().attr( 'data-dismissible' ),
454
  action: 'roc_dismiss_notice',
 
455
  } );
456
  }
457
  );
354
  time: function ( entry ) {
355
  return [ entry[0], entry[1] * 0.5 ]
356
  },
357
+ bytes: function ( entry ) {
358
  return [ entry[0], entry[1] * 0.3 ]
359
  },
360
  calls: function ( entry ) {
449
  function ( event ) {
450
  event.preventDefault();
451
 
452
+ var $parent = $( this ).parent();
453
+
454
  $.post( ajaxurl, {
455
+ notice: $parent.data( 'dismissible' ),
456
  action: 'roc_dismiss_notice',
457
+ _ajax_nonce: $parent.data( 'nonce' ),
458
  } );
459
  }
460
  );
includes/class-plugin.php CHANGED
@@ -12,12 +12,30 @@ use Exception;
12
 
13
  defined( '\\ABSPATH' ) || exit;
14
 
 
 
 
15
  class Plugin {
16
 
17
- private $page;
 
 
 
 
 
18
 
 
 
 
 
 
19
  private $screen = '';
20
 
 
 
 
 
 
21
  private $actions = array(
22
  'enable-cache',
23
  'disable-cache',
@@ -26,14 +44,14 @@ class Plugin {
26
  );
27
 
28
  /**
29
- * Plugin instance property.
30
  *
31
  * @var Plugin
32
  */
33
  private static $instance;
34
 
35
  /**
36
- * Plugin instanciation method.
37
  *
38
  * @return Plugin
39
  */
@@ -45,6 +63,9 @@ class Plugin {
45
  return self::$instance;
46
  }
47
 
 
 
 
48
  private function __construct() {
49
  require_once ABSPATH . 'wp-admin/includes/plugin.php';
50
 
@@ -66,6 +87,11 @@ class Plugin {
66
  }
67
  }
68
 
 
 
 
 
 
69
  public function add_actions_and_filters() {
70
  add_action( 'deactivate_plugin', array( $this, 'on_deactivation' ) );
71
  add_action( 'admin_init', array( $this, 'maybe_update_dropin' ) );
@@ -97,8 +123,12 @@ class Plugin {
97
  add_filter( 'qm/outputter/html', array( $this, 'register_qm_output' ) );
98
  }
99
 
 
 
 
 
 
100
  public function add_admin_menu_page() {
101
- // add sub-page to "Settings"
102
  add_submenu_page(
103
  is_multisite() ? 'settings.php' : 'options-general.php',
104
  __( 'Redis Object Cache', 'redis-cache' ),
@@ -109,18 +139,24 @@ class Plugin {
109
  );
110
  }
111
 
 
 
 
 
 
112
  public function show_admin_page() {
113
- // request filesystem credentials?
114
  if ( isset( $_GET['_wpnonce'], $_GET['action'] ) ) {
115
- $action = $_GET['action'];
 
116
 
117
  foreach ( $this->actions as $name ) {
118
- // verify nonce
119
- if ( $action === $name && wp_verify_nonce( $_GET['_wpnonce'], $action ) ) {
120
  $url = $this->action_link( $action );
121
 
122
  if ( $this->initialize_filesystem( $url ) === false ) {
123
- return; // request filesystem credentials
124
  }
125
  }
126
  }
@@ -147,10 +183,15 @@ class Plugin {
147
  __( 'Diagnostics', 'redis-cache' )
148
  );
149
 
150
- // show admin page
151
  require_once WP_REDIS_PLUGIN_PATH . '/includes/ui/settings.php';
152
  }
153
 
 
 
 
 
 
154
  public function setup_dashboard_widget() {
155
  if ( defined( 'WP_REDIS_DISABLE_METRICS' ) && WP_REDIS_DISABLE_METRICS ) {
156
  return;
@@ -163,18 +204,33 @@ class Plugin {
163
  );
164
  }
165
 
 
 
 
 
 
166
  public function show_dashboard_widget() {
167
  require_once WP_REDIS_PLUGIN_PATH . '/includes/ui/widget.php';
168
  }
169
 
 
 
 
 
 
 
170
  public function add_plugin_actions_links( $links ) {
171
- // add settings link to plugin actions
172
  return array_merge(
173
  [ sprintf( '<a href="%s">%s</a>', network_admin_url( $this->page ), esc_html__( 'Settings', 'redis-cache' ) ) ],
174
  $links
175
  );
176
  }
177
 
 
 
 
 
 
178
  public function enqueue_admin_styles() {
179
  $screen = get_current_screen();
180
 
@@ -188,13 +244,18 @@ class Plugin {
188
  'dashboard-network',
189
  );
190
 
191
- if ( ! in_array( $screen->id, $screens ) ) {
192
  return;
193
  }
194
 
195
  wp_enqueue_style( 'redis-cache', WP_REDIS_DIR . '/assets/css/admin.css', null, WP_REDIS_VERSION );
196
  }
197
 
 
 
 
 
 
198
  public function enqueue_admin_scripts() {
199
  $screen = get_current_screen();
200
 
@@ -211,7 +272,7 @@ class Plugin {
211
  'woocommerce_page_wc-admin',
212
  );
213
 
214
- if ( ! in_array( $screen->id, $screens ) ) {
215
  return;
216
  }
217
 
@@ -219,7 +280,8 @@ class Plugin {
219
  'redis-cache',
220
  plugins_url( 'assets/js/admin.js', WP_REDIS_FILE ),
221
  array( 'jquery', 'underscore' ),
222
- WP_REDIS_VERSION
 
223
  );
224
 
225
  wp_localize_script(
@@ -242,6 +304,11 @@ class Plugin {
242
  );
243
  }
244
 
 
 
 
 
 
245
  public function enqueue_redis_metrics() {
246
  global $wp_object_cache;
247
 
@@ -255,7 +322,7 @@ class Plugin {
255
  return;
256
  }
257
 
258
- if ( ! in_array( $screen->id, array( $this->screen, 'dashboard', 'dashboard-network' ) ) ) {
259
  return;
260
  }
261
 
@@ -263,7 +330,8 @@ class Plugin {
263
  'redis-cache-charts',
264
  plugins_url( 'assets/js/apexcharts.min.js', WP_REDIS_FILE ),
265
  null,
266
- WP_REDIS_VERSION
 
267
  );
268
 
269
  if ( ! method_exists( $wp_object_cache, 'redis_instance' ) ) {
@@ -279,17 +347,29 @@ class Plugin {
279
  );
280
 
281
  wp_localize_script( 'redis-cache', 'rediscache_metrics', $metrics );
282
- } catch (Exception $exception) {
283
- error_log($exception);
284
  }
285
  }
286
 
 
 
 
 
 
 
287
  public function register_qm_collector( array $collectors ) {
288
  $collectors['cache'] = new QM_Collector();
289
 
290
  return $collectors;
291
  }
292
 
 
 
 
 
 
 
293
  public function register_qm_output( $output ) {
294
  $collector = \QM_Collectors::get( 'cache' );
295
 
@@ -303,10 +383,20 @@ class Plugin {
303
  return $output;
304
  }
305
 
 
 
 
 
 
306
  public function object_cache_dropin_exists() {
307
  return file_exists( WP_CONTENT_DIR . '/object-cache.php' );
308
  }
309
 
 
 
 
 
 
310
  public function validate_object_cache_dropin() {
311
  if ( ! $this->object_cache_dropin_exists() ) {
312
  return false;
@@ -318,6 +408,11 @@ class Plugin {
318
  return $dropin['PluginURI'] === $plugin['PluginURI'];
319
  }
320
 
 
 
 
 
 
321
  public function object_cache_dropin_outdated() {
322
  if ( ! $this->object_cache_dropin_exists() ) {
323
  return false;
@@ -333,6 +428,11 @@ class Plugin {
333
  return false;
334
  }
335
 
 
 
 
 
 
336
  public function get_status() {
337
  global $wp_object_cache;
338
 
@@ -380,6 +480,12 @@ class Plugin {
380
  return $wp_object_cache->redis_status();
381
  }
382
 
 
 
 
 
 
 
383
  public function get_redis_version() {
384
  global $wp_object_cache;
385
 
@@ -392,6 +498,11 @@ class Plugin {
392
  }
393
  }
394
 
 
 
 
 
 
395
  public function get_redis_client_name() {
396
  global $wp_object_cache;
397
 
@@ -404,6 +515,11 @@ class Plugin {
404
  }
405
  }
406
 
 
 
 
 
 
407
  public function get_diagnostics() {
408
  global $wp_object_cache;
409
 
@@ -412,21 +528,36 @@ class Plugin {
412
  }
413
  }
414
 
 
 
 
 
 
415
  public function get_redis_prefix() {
416
  return defined( 'WP_REDIS_PREFIX' ) ? WP_REDIS_PREFIX : null;
417
  }
418
 
 
 
 
 
 
419
  public function get_redis_maxttl() {
420
  return defined( 'WP_REDIS_MAXTTL' ) ? WP_REDIS_MAXTTL : null;
421
  }
422
 
 
 
 
 
 
423
  public function show_admin_notices() {
424
  if ( ! defined( 'WP_REDIS_DISABLE_BANNERS' ) || ! WP_REDIS_DISABLE_BANNERS ) {
425
  $this->pro_notice();
426
  $this->wc_pro_notice();
427
  }
428
 
429
- // only show admin notices to users with the right capability
430
  if ( ! current_user_can( is_multisite() ? 'manage_network_options' : 'manage_options' ) ) {
431
  return;
432
  }
@@ -436,34 +567,40 @@ class Plugin {
436
 
437
  if ( $this->validate_object_cache_dropin() ) {
438
  if ( $this->object_cache_dropin_outdated() ) {
439
- // translators: %s = Action link to update the drop-in
440
  $message = sprintf( __( 'The Redis object cache drop-in is outdated. Please <a href="%s">update the drop-in</a>.', 'redis-cache' ), $url );
441
  }
442
  } else {
443
- // translators: %s = Action link to update the drop-in
444
  $message = sprintf( __( 'A foreign object cache drop-in was found. To use Redis for object caching, please <a href="%s">enable the drop-in</a>.', 'redis-cache' ), $url );
445
  }
446
 
447
  if ( isset( $message ) ) {
448
- printf( '<div class="update-nag">%s</div>', $message );
449
  }
450
  }
451
  }
452
 
 
 
 
 
 
453
  public function do_admin_actions() {
454
  global $wp_filesystem;
455
 
456
  if ( isset( $_GET['_wpnonce'], $_GET['action'] ) ) {
457
- $action = $_GET['action'];
 
458
 
459
- // verify nonce
460
  foreach ( $this->actions as $name ) {
461
- if ( $action === $name && ! wp_verify_nonce( $_GET['_wpnonce'], $action ) ) {
462
  return;
463
  }
464
  }
465
 
466
- if ( in_array( $action, $this->actions ) ) {
467
  $url = $this->action_link( $action );
468
 
469
  if ( $action === 'flush-cache' ) {
@@ -518,12 +655,14 @@ class Plugin {
518
  $result
519
  ? add_settings_error(
520
  'redis-cache',
521
- 'dropin', __( 'Object cache disabled.', 'redis-cache' ),
 
522
  'updated'
523
  )
524
  : add_settings_error(
525
  'redis-cache',
526
- 'dropin', __( 'Object cache could not be disabled.', 'redis-cache' ),
 
527
  'error'
528
  );
529
  }
@@ -552,7 +691,6 @@ class Plugin {
552
  'error'
553
  );
554
  }
555
-
556
  }
557
 
558
  $messages = get_settings_errors( 'redis-cache' );
@@ -569,17 +707,31 @@ class Plugin {
569
  }
570
  }
571
 
 
 
 
 
 
572
  public function dismiss_notice() {
573
- $notice = sprintf(
574
- 'roc_dismissed_%s',
575
- sanitize_key( $_POST['notice'] )
576
- );
 
 
 
577
 
578
- update_user_meta( get_current_user_id(), $notice, '1' );
 
579
 
580
  wp_die();
581
  }
582
 
 
 
 
 
 
583
  public function pro_notice() {
584
  $screen = get_current_screen();
585
 
@@ -587,7 +739,7 @@ class Plugin {
587
  return;
588
  }
589
 
590
- if ( ! in_array( $screen->id, array( 'dashboard', 'dashboard-network' ) ) ) {
591
  return;
592
  }
593
 
@@ -595,21 +747,27 @@ class Plugin {
595
  return;
596
  }
597
 
598
- if ( get_user_meta( get_current_user_id(), 'roc_dismissed_pro_release_notice', true ) == '1' ) {
599
  return;
600
  }
601
 
602
  printf(
603
- '<div class="notice notice-info is-dismissible" data-dismissible="pro_release_notice"><p><strong>%s</strong> %s</p></div>',
604
- __( 'Object Cache Pro is out!', 'redis-cache' ),
 
605
  sprintf(
606
- // translators: %s = Link to the plugin setting screen
607
- __( 'A <u>business class</u> object cache backend. Truly reliable, highly-optimized and fully customizable, with a <u>dedicated engineer</u> when you most need it. <a href="%s">Learn more »</a>', 'redis-cache' ),
608
- network_admin_url( $this->page )
609
  )
610
  );
611
  }
612
 
 
 
 
 
 
613
  public function wc_pro_notice() {
614
  if ( ! class_exists( 'WooCommerce' ) ) {
615
  return;
@@ -621,7 +779,7 @@ class Plugin {
621
  return;
622
  }
623
 
624
- if ( ! in_array( $screen->id, array( 'edit-shop_order', 'edit-product', 'woocommerce_page_wc-admin' ) ) ) {
625
  return;
626
  }
627
 
@@ -629,27 +787,38 @@ class Plugin {
629
  return;
630
  }
631
 
632
- if ( get_user_meta( get_current_user_id(), 'roc_dismissed_wc_pro_notice', true ) == '1' ) {
633
  return;
634
  }
635
 
636
  printf(
637
- '<div class="notice woocommerce-message woocommerce-admin-promo-messages is-dismissible" data-dismissible="wc_pro_notice"><p><strong>%s</strong></p><p>%s</p></div>',
638
- __( 'Object Cache Pro + WooCommerce = ❤️', 'redis-cache' ),
 
639
  sprintf(
640
- // translators: %s = Link to the plugin's settings screen
641
- __( 'Object Cache Pro is a <u>business class</u> object cache that’s highly-optimized for WooCommerce to provide true reliability, peace of mind and faster load times for your store. <a style="color: #bb77ae;" href="%s">Learn more »</a>', 'redis-cache' ),
642
- network_admin_url( $this->page )
643
  )
644
  );
645
  }
646
 
 
 
 
 
 
647
  public function register_shutdown_hooks() {
648
  if ( ! defined( 'WP_REDIS_DISABLE_COMMENT' ) || ! WP_REDIS_DISABLE_COMMENT ) {
649
  add_action( 'shutdown', array( $this, 'maybe_print_comment' ), 0 );
650
  }
651
  }
652
 
 
 
 
 
 
653
  public function record_metrics() {
654
  global $wp_object_cache;
655
 
@@ -683,11 +852,16 @@ class Plugin {
683
  time(),
684
  http_build_query( $metrics, null, ';' )
685
  );
686
- } catch (Exception $exception) {
687
- error_log($exception);
688
  }
689
  }
690
 
 
 
 
 
 
691
  public function discard_metrics() {
692
  global $wp_object_cache;
693
 
@@ -709,11 +883,16 @@ class Plugin {
709
  0,
710
  time() - HOUR_IN_SECONDS
711
  );
712
- } catch (Exception $exception) {
713
- error_log($exception);
714
  }
715
  }
716
 
 
 
 
 
 
717
  public function maybe_print_comment() {
718
  global $wp_object_cache;
719
 
@@ -747,12 +926,13 @@ class Plugin {
747
  );
748
 
749
  if ( ! WP_DEBUG ) {
 
750
  printf( "\n<!-- %s -->\n", $message );
751
 
752
  return;
753
  }
754
 
755
- $bytes = strlen( serialize( $wp_object_cache->cache ) );
756
 
757
  $debug = sprintf(
758
  // translators: %1$d = number of objects. %2$s = human-readable size of cache. %3$s = name of the used client.
@@ -762,15 +942,28 @@ class Plugin {
762
  $wp_object_cache->diagnostics['client']
763
  );
764
 
765
- printf( "<!--\n%s\n\n%s\n-->\n", $message, $debug );
 
 
 
 
766
  }
767
 
 
 
 
 
 
 
 
768
  public function initialize_filesystem( $url, $silent = false ) {
769
  if ( $silent ) {
770
  ob_start();
771
  }
772
 
773
- if ( ( $credentials = request_filesystem_credentials( $url ) ) === false ) {
 
 
774
  if ( $silent ) {
775
  ob_end_clean();
776
  }
@@ -791,8 +984,12 @@ class Plugin {
791
  return true;
792
  }
793
 
794
- public function test_filesystem_writing()
795
- {
 
 
 
 
796
  global $wp_filesystem;
797
 
798
  if ( ! $this->initialize_filesystem( '', true ) ) {
@@ -833,6 +1030,11 @@ class Plugin {
833
  return true;
834
  }
835
 
 
 
 
 
 
836
  public function maybe_update_dropin() {
837
  if ( defined( 'WP_REDIS_DISABLE_DROPIN_AUTOUPDATE' ) && WP_REDIS_DISABLE_DROPIN_AUTOUPDATE ) {
838
  return;
@@ -843,6 +1045,11 @@ class Plugin {
843
  }
844
  }
845
 
 
 
 
 
 
846
  public function update_dropin() {
847
  global $wp_filesystem;
848
 
@@ -862,13 +1069,21 @@ class Plugin {
862
  }
863
  }
864
 
 
 
 
 
 
 
865
  public function on_deactivation( $plugin ) {
866
  global $wp_filesystem;
867
 
868
  ob_start();
869
 
870
  if ( $plugin === WP_REDIS_BASENAME ) {
871
- if ( $timestamp = wp_next_scheduled( 'rediscache_discard_metrics' ) ) {
 
 
872
  wp_unschedule_event( $timestamp, 'rediscache_discard_metrics' );
873
  }
874
 
@@ -882,7 +1097,17 @@ class Plugin {
882
  ob_end_clean();
883
  }
884
 
 
 
 
 
 
 
885
  public function action_link( $action ) {
 
 
 
 
886
  return wp_nonce_url(
887
  network_admin_url( add_query_arg( 'action', $action, $this->page ) ),
888
  $action
12
 
13
  defined( '\\ABSPATH' ) || exit;
14
 
15
+ /**
16
+ * Main plugin class definition
17
+ */
18
  class Plugin {
19
 
20
+ /**
21
+ * Settings page uri
22
+ *
23
+ * @var string $page
24
+ */
25
+ private $page = '';
26
 
27
+ /**
28
+ * Settings page slug
29
+ *
30
+ * @var string $screen
31
+ */
32
  private $screen = '';
33
 
34
+ /**
35
+ * Allowed setting page actions
36
+ *
37
+ * @var string[] $actions
38
+ */
39
  private $actions = array(
40
  'enable-cache',
41
  'disable-cache',
44
  );
45
 
46
  /**
47
+ * Plugin instance property
48
  *
49
  * @var Plugin
50
  */
51
  private static $instance;
52
 
53
  /**
54
+ * Plugin instanciation method
55
  *
56
  * @return Plugin
57
  */
63
  return self::$instance;
64
  }
65
 
66
+ /**
67
+ * Constructor
68
+ */
69
  private function __construct() {
70
  require_once ABSPATH . 'wp-admin/includes/plugin.php';
71
 
87
  }
88
  }
89
 
90
+ /**
91
+ * Adds all necessary hooks
92
+ *
93
+ * @return void
94
+ */
95
  public function add_actions_and_filters() {
96
  add_action( 'deactivate_plugin', array( $this, 'on_deactivation' ) );
97
  add_action( 'admin_init', array( $this, 'maybe_update_dropin' ) );
123
  add_filter( 'qm/outputter/html', array( $this, 'register_qm_output' ) );
124
  }
125
 
126
+ /**
127
+ * Adds a submenu page to "Settings"
128
+ *
129
+ * @return void
130
+ */
131
  public function add_admin_menu_page() {
 
132
  add_submenu_page(
133
  is_multisite() ? 'settings.php' : 'options-general.php',
134
  __( 'Redis Object Cache', 'redis-cache' ),
139
  );
140
  }
141
 
142
+ /**
143
+ * Displays the settings page
144
+ *
145
+ * @return void
146
+ */
147
  public function show_admin_page() {
148
+ // Request filesystem credentials?
149
  if ( isset( $_GET['_wpnonce'], $_GET['action'] ) ) {
150
+ $action = sanitize_key( $_GET['action'] );
151
+ $nonce = sanitize_key( $_GET['_wpnonce'] );
152
 
153
  foreach ( $this->actions as $name ) {
154
+ // Nonce verification.
155
+ if ( $action === $name && wp_verify_nonce( $nonce, $action ) ) {
156
  $url = $this->action_link( $action );
157
 
158
  if ( $this->initialize_filesystem( $url ) === false ) {
159
+ return; // Request filesystem credentials.
160
  }
161
  }
162
  }
183
  __( 'Diagnostics', 'redis-cache' )
184
  );
185
 
186
+ // Show the admin page.
187
  require_once WP_REDIS_PLUGIN_PATH . '/includes/ui/settings.php';
188
  }
189
 
190
+ /**
191
+ * Adds the dashboard metrics widget
192
+ *
193
+ * @return void
194
+ */
195
  public function setup_dashboard_widget() {
196
  if ( defined( 'WP_REDIS_DISABLE_METRICS' ) && WP_REDIS_DISABLE_METRICS ) {
197
  return;
204
  );
205
  }
206
 
207
+ /**
208
+ * Displays the dashboard widget
209
+ *
210
+ * @return void
211
+ */
212
  public function show_dashboard_widget() {
213
  require_once WP_REDIS_PLUGIN_PATH . '/includes/ui/widget.php';
214
  }
215
 
216
+ /**
217
+ * Adds the settings page to the plugin action links on the plugin page
218
+ *
219
+ * @param string[] $links The current plugin action links.
220
+ * @return string[]
221
+ */
222
  public function add_plugin_actions_links( $links ) {
 
223
  return array_merge(
224
  [ sprintf( '<a href="%s">%s</a>', network_admin_url( $this->page ), esc_html__( 'Settings', 'redis-cache' ) ) ],
225
  $links
226
  );
227
  }
228
 
229
+ /**
230
+ * Enqueues admin style resources
231
+ *
232
+ * @return void
233
+ */
234
  public function enqueue_admin_styles() {
235
  $screen = get_current_screen();
236
 
244
  'dashboard-network',
245
  );
246
 
247
+ if ( ! in_array( $screen->id, $screens, true ) ) {
248
  return;
249
  }
250
 
251
  wp_enqueue_style( 'redis-cache', WP_REDIS_DIR . '/assets/css/admin.css', null, WP_REDIS_VERSION );
252
  }
253
 
254
+ /**
255
+ * Enqueues admin script resources
256
+ *
257
+ * @return void
258
+ */
259
  public function enqueue_admin_scripts() {
260
  $screen = get_current_screen();
261
 
272
  'woocommerce_page_wc-admin',
273
  );
274
 
275
+ if ( ! in_array( $screen->id, $screens, true ) ) {
276
  return;
277
  }
278
 
280
  'redis-cache',
281
  plugins_url( 'assets/js/admin.js', WP_REDIS_FILE ),
282
  array( 'jquery', 'underscore' ),
283
+ WP_REDIS_VERSION,
284
+ true
285
  );
286
 
287
  wp_localize_script(
304
  );
305
  }
306
 
307
+ /**
308
+ * Enqueues scripts to display recorded metrics
309
+ *
310
+ * @return void
311
+ */
312
  public function enqueue_redis_metrics() {
313
  global $wp_object_cache;
314
 
322
  return;
323
  }
324
 
325
+ if ( ! in_array( $screen->id, array( $this->screen, 'dashboard', 'dashboard-network' ), true ) ) {
326
  return;
327
  }
328
 
330
  'redis-cache-charts',
331
  plugins_url( 'assets/js/apexcharts.min.js', WP_REDIS_FILE ),
332
  null,
333
+ WP_REDIS_VERSION,
334
+ true
335
  );
336
 
337
  if ( ! method_exists( $wp_object_cache, 'redis_instance' ) ) {
347
  );
348
 
349
  wp_localize_script( 'redis-cache', 'rediscache_metrics', $metrics );
350
+ } catch ( Exception $exception ) {
351
+ error_log( $exception ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
352
  }
353
  }
354
 
355
+ /**
356
+ * Registers a new cache collector for the Query Monitor plugin
357
+ *
358
+ * @param array $collectors Array of currently registered collectors.
359
+ * @return array
360
+ */
361
  public function register_qm_collector( array $collectors ) {
362
  $collectors['cache'] = new QM_Collector();
363
 
364
  return $collectors;
365
  }
366
 
367
+ /**
368
+ * Registers a new cache output using our collector for the Query Monitor plugin
369
+ *
370
+ * @param array $output Array of current QM_Output handlers.
371
+ * @return array
372
+ */
373
  public function register_qm_output( $output ) {
374
  $collector = \QM_Collectors::get( 'cache' );
375
 
383
  return $output;
384
  }
385
 
386
+ /**
387
+ * Checks if the `object-cache.php` drop-in exists
388
+ *
389
+ * @return bool
390
+ */
391
  public function object_cache_dropin_exists() {
392
  return file_exists( WP_CONTENT_DIR . '/object-cache.php' );
393
  }
394
 
395
+ /**
396
+ * Validates the `object-cache.php` drop-in
397
+ *
398
+ * @return bool
399
+ */
400
  public function validate_object_cache_dropin() {
401
  if ( ! $this->object_cache_dropin_exists() ) {
402
  return false;
408
  return $dropin['PluginURI'] === $plugin['PluginURI'];
409
  }
410
 
411
+ /**
412
+ * Checks if the `object-cache.php` drop-in is outdated
413
+ *
414
+ * @return bool
415
+ */
416
  public function object_cache_dropin_outdated() {
417
  if ( ! $this->object_cache_dropin_exists() ) {
418
  return false;
428
  return false;
429
  }
430
 
431
+ /**
432
+ * Retrieves the current human-readable status
433
+ *
434
+ * @return string
435
+ */
436
  public function get_status() {
437
  global $wp_object_cache;
438
 
480
  return $wp_object_cache->redis_status();
481
  }
482
 
483
+ /**
484
+ * Returns the redis version if possible
485
+ *
486
+ * @see WP_Object_Cache::redis_version()
487
+ * @return null|string
488
+ */
489
  public function get_redis_version() {
490
  global $wp_object_cache;
491
 
498
  }
499
  }
500
 
501
+ /**
502
+ * Returns the currently used redis client (if any)
503
+ *
504
+ * @return null|string
505
+ */
506
  public function get_redis_client_name() {
507
  global $wp_object_cache;
508
 
515
  }
516
  }
517
 
518
+ /**
519
+ * Fetches the redis diagnostics data
520
+ *
521
+ * @return null|array
522
+ */
523
  public function get_diagnostics() {
524
  global $wp_object_cache;
525
 
528
  }
529
  }
530
 
531
+ /**
532
+ * Retrieves the redis prefix
533
+ *
534
+ * @return null|mixed
535
+ */
536
  public function get_redis_prefix() {
537
  return defined( 'WP_REDIS_PREFIX' ) ? WP_REDIS_PREFIX : null;
538
  }
539
 
540
+ /**
541
+ * Retrieves the redis maximum time to live
542
+ *
543
+ * @return null|mixed
544
+ */
545
  public function get_redis_maxttl() {
546
  return defined( 'WP_REDIS_MAXTTL' ) ? WP_REDIS_MAXTTL : null;
547
  }
548
 
549
+ /**
550
+ * Displays admin notices
551
+ *
552
+ * @return void
553
+ */
554
  public function show_admin_notices() {
555
  if ( ! defined( 'WP_REDIS_DISABLE_BANNERS' ) || ! WP_REDIS_DISABLE_BANNERS ) {
556
  $this->pro_notice();
557
  $this->wc_pro_notice();
558
  }
559
 
560
+ // Only show admin notices to users with the right capability.
561
  if ( ! current_user_can( is_multisite() ? 'manage_network_options' : 'manage_options' ) ) {
562
  return;
563
  }
567
 
568
  if ( $this->validate_object_cache_dropin() ) {
569
  if ( $this->object_cache_dropin_outdated() ) {
570
+ // translators: %s = Action link to update the drop-in.
571
  $message = sprintf( __( 'The Redis object cache drop-in is outdated. Please <a href="%s">update the drop-in</a>.', 'redis-cache' ), $url );
572
  }
573
  } else {
574
+ // translators: %s = Action link to update the drop-in.
575
  $message = sprintf( __( 'A foreign object cache drop-in was found. To use Redis for object caching, please <a href="%s">enable the drop-in</a>.', 'redis-cache' ), $url );
576
  }
577
 
578
  if ( isset( $message ) ) {
579
+ printf( '<div class="update-nag">%s</div>', wp_kses_post( $message ) );
580
  }
581
  }
582
  }
583
 
584
+ /**
585
+ * Executes admin actions
586
+ *
587
+ * @return void
588
+ */
589
  public function do_admin_actions() {
590
  global $wp_filesystem;
591
 
592
  if ( isset( $_GET['_wpnonce'], $_GET['action'] ) ) {
593
+ $action = sanitize_key( $_GET['action'] );
594
+ $nonce = sanitize_key( $_GET['_wpnonce'] );
595
 
596
+ // Nonce verification.
597
  foreach ( $this->actions as $name ) {
598
+ if ( $action === $name && ! wp_verify_nonce( $nonce, $action ) ) {
599
  return;
600
  }
601
  }
602
 
603
+ if ( in_array( $action, $this->actions, true ) ) {
604
  $url = $this->action_link( $action );
605
 
606
  if ( $action === 'flush-cache' ) {
655
  $result
656
  ? add_settings_error(
657
  'redis-cache',
658
+ 'dropin',
659
+ __( 'Object cache disabled.', 'redis-cache' ),
660
  'updated'
661
  )
662
  : add_settings_error(
663
  'redis-cache',
664
+ 'dropin',
665
+ __( 'Object cache could not be disabled.', 'redis-cache' ),
666
  'error'
667
  );
668
  }
691
  'error'
692
  );
693
  }
 
694
  }
695
 
696
  $messages = get_settings_errors( 'redis-cache' );
707
  }
708
  }
709
 
710
+ /**
711
+ * Dismisses the admin notice for the current user
712
+ *
713
+ * @return void
714
+ */
715
  public function dismiss_notice() {
716
+ if ( isset( $_POST['notice'] ) ) {
717
+ check_ajax_referer( 'roc_dismiss_notice' );
718
+
719
+ $notice = sprintf(
720
+ 'roc_dismissed_%s',
721
+ sanitize_key( $_POST['notice'] )
722
+ );
723
 
724
+ update_user_meta( get_current_user_id(), $notice, '1' );
725
+ }
726
 
727
  wp_die();
728
  }
729
 
730
+ /**
731
+ * Displays a redis cache pro admin notice
732
+ *
733
+ * @return void
734
+ */
735
  public function pro_notice() {
736
  $screen = get_current_screen();
737
 
739
  return;
740
  }
741
 
742
+ if ( ! in_array( $screen->id, array( 'dashboard', 'dashboard-network' ), true ) ) {
743
  return;
744
  }
745
 
747
  return;
748
  }
749
 
750
+ if ( 1 === intval( get_user_meta( get_current_user_id(), 'roc_dismissed_pro_release_notice', true ) ) ) {
751
  return;
752
  }
753
 
754
  printf(
755
+ '<div class="notice notice-info is-dismissible" data-dismissible="pro_release_notice" data-nonce="%s"><p><strong>%s</strong> %s</p></div>',
756
+ esc_attr( wp_create_nonce( 'roc_dismiss_notice' ) ),
757
+ esc_html__( 'Object Cache Pro is out!', 'redis-cache' ),
758
  sprintf(
759
+ // translators: %s = Link to the plugin setting screen.
760
+ wp_kses_post( __( 'A <u>business class</u> object cache backend. Truly reliable, highly-optimized and fully customizable, with a <u>dedicated engineer</u> when you most need it. <a href="%s">Learn more »</a>', 'redis-cache' ) ),
761
+ esc_url( network_admin_url( $this->page ) )
762
  )
763
  );
764
  }
765
 
766
+ /**
767
+ * Displays a redis cache pro admin notice specifically for WooCommerce
768
+ *
769
+ * @return void
770
+ */
771
  public function wc_pro_notice() {
772
  if ( ! class_exists( 'WooCommerce' ) ) {
773
  return;
779
  return;
780
  }
781
 
782
+ if ( ! in_array( $screen->id, array( 'edit-shop_order', 'edit-product', 'woocommerce_page_wc-admin' ), true ) ) {
783
  return;
784
  }
785
 
787
  return;
788
  }
789
 
790
+ if ( 1 === intval( get_user_meta( get_current_user_id(), 'roc_dismissed_wc_pro_notice', true ) ) ) {
791
  return;
792
  }
793
 
794
  printf(
795
+ '<div class="notice woocommerce-message woocommerce-admin-promo-messages is-dismissible" data-dismissible="wc_pro_notice" data-nonce="%s"><p><strong>%s</strong></p><p>%s</p></div>',
796
+ esc_attr( wp_create_nonce( 'roc_dismiss_notice' ) ),
797
+ esc_html__( 'Object Cache Pro + WooCommerce = ❤️', 'redis-cache' ),
798
  sprintf(
799
+ // translators: %s = Link to the plugin's settings screen.
800
+ wp_kses_post( __( 'Object Cache Pro is a <u>business class</u> object cache that’s highly-optimized for WooCommerce to provide true reliability, peace of mind and faster load times for your store. <a style="color: #bb77ae;" href="%s">Learn more »</a>', 'redis-cache' ) ),
801
+ esc_url( network_admin_url( $this->page ) )
802
  )
803
  );
804
  }
805
 
806
+ /**
807
+ * Registers all hooks associated with the shutdown hook
808
+ *
809
+ * @return void
810
+ */
811
  public function register_shutdown_hooks() {
812
  if ( ! defined( 'WP_REDIS_DISABLE_COMMENT' ) || ! WP_REDIS_DISABLE_COMMENT ) {
813
  add_action( 'shutdown', array( $this, 'maybe_print_comment' ), 0 );
814
  }
815
  }
816
 
817
+ /**
818
+ * Adds the recorded metrics to redis
819
+ *
820
+ * @return void
821
+ */
822
  public function record_metrics() {
823
  global $wp_object_cache;
824
 
852
  time(),
853
  http_build_query( $metrics, null, ';' )
854
  );
855
+ } catch ( Exception $exception ) {
856
+ error_log( $exception ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
857
  }
858
  }
859
 
860
+ /**
861
+ * Removes recorded metrics after an hour
862
+ *
863
+ * @return void
864
+ */
865
  public function discard_metrics() {
866
  global $wp_object_cache;
867
 
883
  0,
884
  time() - HOUR_IN_SECONDS
885
  );
886
+ } catch ( Exception $exception ) {
887
+ error_log( $exception ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
888
  }
889
  }
890
 
891
+ /**
892
+ * Displays the redis cache html comment
893
+ *
894
+ * @return void
895
+ */
896
  public function maybe_print_comment() {
897
  global $wp_object_cache;
898
 
926
  );
927
 
928
  if ( ! WP_DEBUG ) {
929
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
930
  printf( "\n<!-- %s -->\n", $message );
931
 
932
  return;
933
  }
934
 
935
+ $bytes = strlen( serialize( $wp_object_cache->cache ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
936
 
937
  $debug = sprintf(
938
  // translators: %1$d = number of objects. %2$s = human-readable size of cache. %3$s = name of the used client.
942
  $wp_object_cache->diagnostics['client']
943
  );
944
 
945
+ printf(
946
+ "<!--\n%s\n\n%s\n-->\n",
947
+ $message, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
948
+ esc_html( $debug )
949
+ );
950
  }
951
 
952
+ /**
953
+ * Initializes the WP filesystem API to be ready for use
954
+ *
955
+ * @param string $url The URL to post the form to.
956
+ * @param bool $silent Wheather to ask the user for credentials if necessary or not.
957
+ * @return bool
958
+ */
959
  public function initialize_filesystem( $url, $silent = false ) {
960
  if ( $silent ) {
961
  ob_start();
962
  }
963
 
964
+ $credentials = request_filesystem_credentials( $url );
965
+
966
+ if ( false === $credentials ) {
967
  if ( $silent ) {
968
  ob_end_clean();
969
  }
984
  return true;
985
  }
986
 
987
+ /**
988
+ * Test if we can write in the WP_CONTENT_DIR and modify the `object-cache.php` drop-in
989
+ *
990
+ * @return true|WP_Error
991
+ */
992
+ public function test_filesystem_writing() {
993
  global $wp_filesystem;
994
 
995
  if ( ! $this->initialize_filesystem( '', true ) ) {
1030
  return true;
1031
  }
1032
 
1033
+ /**
1034
+ * Calls the drop-in update method if necessary
1035
+ *
1036
+ * @return void
1037
+ */
1038
  public function maybe_update_dropin() {
1039
  if ( defined( 'WP_REDIS_DISABLE_DROPIN_AUTOUPDATE' ) && WP_REDIS_DISABLE_DROPIN_AUTOUPDATE ) {
1040
  return;
1045
  }
1046
  }
1047
 
1048
+ /**
1049
+ * Updates the `object-cache.php` drop-in
1050
+ *
1051
+ * @return void
1052
+ */
1053
  public function update_dropin() {
1054
  global $wp_filesystem;
1055
 
1069
  }
1070
  }
1071
 
1072
+ /**
1073
+ * Plugin deactivation hook
1074
+ *
1075
+ * @param string $plugin Plugin basename.
1076
+ * @return void
1077
+ */
1078
  public function on_deactivation( $plugin ) {
1079
  global $wp_filesystem;
1080
 
1081
  ob_start();
1082
 
1083
  if ( $plugin === WP_REDIS_BASENAME ) {
1084
+ $timestamp = wp_next_scheduled( 'rediscache_discard_metrics' );
1085
+
1086
+ if ( $timestamp ) {
1087
  wp_unschedule_event( $timestamp, 'rediscache_discard_metrics' );
1088
  }
1089
 
1097
  ob_end_clean();
1098
  }
1099
 
1100
+ /**
1101
+ * Helper method to retrieve a nonced plugin action link
1102
+ *
1103
+ * @param string $action The action to be executed once the link is followed.
1104
+ * @return string
1105
+ */
1106
  public function action_link( $action ) {
1107
+ if ( ! in_array( $action, $this->actions, true ) ) {
1108
+ return '';
1109
+ }
1110
+
1111
  return wp_nonce_url(
1112
  network_admin_url( add_query_arg( 'action', $action, $this->page ) ),
1113
  $action
includes/class-qm-collector.php CHANGED
@@ -11,24 +11,42 @@ use QM_Collector as Base_Collector;
11
 
12
  defined( '\\ABSPATH' ) || exit;
13
 
 
 
 
14
  class QM_Collector extends Base_Collector {
15
 
 
 
 
 
 
16
  public $id = 'cache';
17
 
 
 
 
 
 
18
  public function name() {
19
  return __( 'Object Cache', 'redis-cache' );
20
  }
21
 
 
 
 
 
 
22
  public function process() {
23
- global $wp_object_cache;
24
 
25
  $this->process_defaults();
26
 
27
- $plugin = Plugin::instance();
28
 
29
- $this->data['status'] = $plugin->get_status();
30
- $this->data['has_dropin'] = $plugin->object_cache_dropin_exists();
31
- $this->data['valid_dropin'] = $plugin->validate_object_cache_dropin();
32
 
33
  if ( ! method_exists( $wp_object_cache, 'info' ) ) {
34
  return;
@@ -54,12 +72,17 @@ class QM_Collector extends Base_Collector {
54
  'unflushable' => $info->groups->unflushable,
55
  ];
56
 
57
- // these are used by Query Monitor
58
  $this->data['stats']['cache_hits'] = $info->hits;
59
  $this->data['stats']['cache_misses'] = $info->misses;
60
  $this->data['cache_hit_percentage'] = $info->ratio;
61
  }
62
 
 
 
 
 
 
63
  public function process_defaults() {
64
  $this->data['hits'] = 0;
65
  $this->data['misses'] = 0;
11
 
12
  defined( '\\ABSPATH' ) || exit;
13
 
14
+ /**
15
+ * Query Monitor data collector class definition
16
+ */
17
  class QM_Collector extends Base_Collector {
18
 
19
+ /**
20
+ * Collector id
21
+ *
22
+ * @var string $id
23
+ */
24
  public $id = 'cache';
25
 
26
+ /**
27
+ * Retrieves the collector name
28
+ *
29
+ * @return string
30
+ */
31
  public function name() {
32
  return __( 'Object Cache', 'redis-cache' );
33
  }
34
 
35
+ /**
36
+ * Fills the collector with data
37
+ *
38
+ * @return void
39
+ */
40
  public function process() {
41
+ global $wp_object_cache;
42
 
43
  $this->process_defaults();
44
 
45
+ $roc = Plugin::instance();
46
 
47
+ $this->data['status'] = $roc->get_status();
48
+ $this->data['has_dropin'] = $roc->object_cache_dropin_exists();
49
+ $this->data['valid_dropin'] = $roc->validate_object_cache_dropin();
50
 
51
  if ( ! method_exists( $wp_object_cache, 'info' ) ) {
52
  return;
72
  'unflushable' => $info->groups->unflushable,
73
  ];
74
 
75
+ // These are used by Query Monitor.
76
  $this->data['stats']['cache_hits'] = $info->hits;
77
  $this->data['stats']['cache_misses'] = $info->misses;
78
  $this->data['cache_hit_percentage'] = $info->ratio;
79
  }
80
 
81
+ /**
82
+ * Sets collector defaults
83
+ *
84
+ * @return void
85
+ */
86
  public function process_defaults() {
87
  $this->data['hits'] = 0;
88
  $this->data['misses'] = 0;
includes/class-qm-output.php CHANGED
@@ -11,8 +11,16 @@ use QM_Output_Html;
11
 
12
  defined( '\\ABSPATH' ) || exit;
13
 
 
 
 
14
  class QM_Output extends QM_Output_Html {
15
 
 
 
 
 
 
16
  public function __construct( QM_Collector $collector ) {
17
  parent::__construct( $collector );
18
 
@@ -20,10 +28,20 @@ class QM_Output extends QM_Output_Html {
20
  add_filter( 'qm/output/panel_menus', [ $this, 'panel_menu' ] );
21
  }
22
 
 
 
 
 
 
23
  public function name() {
24
  return __( 'Object Cache', 'redis cache' );
25
  }
26
 
 
 
 
 
 
27
  public function admin_menu( array $menu ) {
28
  $data = $this->collector->get_data();
29
 
@@ -48,6 +66,11 @@ class QM_Output extends QM_Output_Html {
48
  return $menu;
49
  }
50
 
 
 
 
 
 
51
  public function panel_menu( array $menu ) {
52
  $ids = array_keys( $menu );
53
  $request = array_search( 'qm-request', $ids, true );
@@ -64,12 +87,20 @@ class QM_Output extends QM_Output_Html {
64
  );
65
  }
66
 
 
 
 
 
 
67
  public function output() {
68
  $data = $this->collector->get_data();
69
 
70
  if ( ! $data['has_dropin'] ) {
71
  $this->before_non_tabular_output();
72
- echo $this->build_notice( __( 'The Redis Object Cache drop-in is not installed. Use WP CLI or go to "Settings -> Redis" to enable drop-in.', 'redis-cache' ) );
 
 
 
73
  $this->after_non_tabular_output();
74
 
75
  return;
@@ -77,7 +108,10 @@ class QM_Output extends QM_Output_Html {
77
 
78
  if ( ! $data['valid_dropin'] ) {
79
  $this->before_non_tabular_output();
80
- echo $this->build_notice( __( 'WordPress is using a foreign object cache drop-in and Redis Object Cache is not being used. Use WP CLI or go to "Settings -> Redis" to enable drop-in.', 'redis-cache' ) );
 
 
 
81
  $this->after_non_tabular_output();
82
 
83
  return;
11
 
12
  defined( '\\ABSPATH' ) || exit;
13
 
14
+ /**
15
+ * Query Monitor output logic class definition
16
+ */
17
  class QM_Output extends QM_Output_Html {
18
 
19
+ /**
20
+ * Contructor
21
+ *
22
+ * @param QM_Collector $collector The corresponding collector instance.
23
+ */
24
  public function __construct( QM_Collector $collector ) {
25
  parent::__construct( $collector );
26
 
28
  add_filter( 'qm/output/panel_menus', [ $this, 'panel_menu' ] );
29
  }
30
 
31
+ /**
32
+ * Output class name
33
+ *
34
+ * @return string
35
+ */
36
  public function name() {
37
  return __( 'Object Cache', 'redis cache' );
38
  }
39
 
40
+ /**
41
+ * Adds a menu to the panel navigation menu in Query Monitor's output
42
+ *
43
+ * @param array $menu Array of menus.
44
+ */
45
  public function admin_menu( array $menu ) {
46
  $data = $this->collector->get_data();
47
 
66
  return $menu;
67
  }
68
 
69
+ /**
70
+ * Adds a menu item in the panel navigation menu in Query Monitor's output.
71
+ *
72
+ * @param array $menu Array of menus.
73
+ */
74
  public function panel_menu( array $menu ) {
75
  $ids = array_keys( $menu );
76
  $request = array_search( 'qm-request', $ids, true );
87
  );
88
  }
89
 
90
+ /**
91
+ * Renders the output
92
+ *
93
+ * @return void
94
+ */
95
  public function output() {
96
  $data = $this->collector->get_data();
97
 
98
  if ( ! $data['has_dropin'] ) {
99
  $this->before_non_tabular_output();
100
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
101
+ echo $this->build_notice(
102
+ esc_html__( 'The Redis Object Cache drop-in is not installed. Use WP CLI or go to "Settings -> Redis" to enable drop-in.', 'redis-cache' )
103
+ );
104
  $this->after_non_tabular_output();
105
 
106
  return;
108
 
109
  if ( ! $data['valid_dropin'] ) {
110
  $this->before_non_tabular_output();
111
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
112
+ echo $this->build_notice(
113
+ esc_html__( 'WordPress is using a foreign object cache drop-in and Redis Object Cache is not being used. Use WP CLI or go to "Settings -> Redis" to enable drop-in.', 'redis-cache' )
114
+ );
115
  $this->after_non_tabular_output();
116
 
117
  return;
includes/class-ui.php CHANGED
@@ -30,13 +30,7 @@ class UI {
30
  * @return void
31
  */
32
  public static function register_tab( $slug, $label, $args = [] ) {
33
- self::$tabs[ $slug ] = (object) wp_parse_args( $args, [
34
- 'label' => $label,
35
- 'file' => WP_REDIS_PLUGIN_PATH . "/includes/ui/tabs/{$slug}.php",
36
- 'slug' => $slug,
37
- 'default' => false,
38
- 'disabled' => false,
39
- ] );
40
  }
41
 
42
  /**
30
  * @return void
31
  */
32
  public static function register_tab( $slug, $label, $args = [] ) {
33
+ self::$tabs[ $slug ] = new UI\Tab( $slug, $label, $args );
 
 
 
 
 
 
34
  }
35
 
36
  /**
includes/object-cache.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Redis Object Cache Drop-In
4
  * Plugin URI: http://wordpress.org/plugins/redis-cache/
5
  * Description: A persistent object cache backend powered by Redis. Supports Predis, PhpRedis, Credis, HHVM, replication, clustering and WP-CLI.
6
- * Version: 2.0.11
7
  * Author: Till Krüss
8
  * Author URI: https://objectcache.pro
9
  * License: GPLv3
@@ -14,6 +14,7 @@
14
 
15
  defined( '\\ABSPATH' ) || exit;
16
 
 
17
  if ( ! defined( 'WP_REDIS_DISABLED' ) || ! WP_REDIS_DISABLED ) :
18
 
19
  /**
@@ -46,7 +47,7 @@ function wp_cache_add( $key, $value, $group = '', $expiration = 0 ) {
46
  * @return bool Always returns True
47
  */
48
  function wp_cache_close() {
49
- return true;
50
  }
51
 
52
  /**
@@ -102,7 +103,7 @@ function wp_cache_flush( $delay = 0 ) {
102
  * @param string $group The group value appended to the $key.
103
  * @param bool $force Optional. Whether to force an update of the local cache from the persistent
104
  * cache. Default false.
105
- * @param bool &$found Optional. Whether the key was found in the cache. Disambiguates a return of false,
106
  * a storable value. Passed by reference. Default null.
107
  *
108
  * @return bool|mixed Cached object value.
@@ -151,7 +152,7 @@ function wp_cache_incr( $key, $offset = 1, $group = '' ) {
151
  function wp_cache_init() {
152
  global $wp_object_cache;
153
 
154
- // backwards compatibility: map `WP_CACHE_KEY_SALT` constant to `WP_REDIS_PREFIX`
155
  if ( defined( 'WP_CACHE_KEY_SALT' ) && ! defined( 'WP_REDIS_PREFIX' ) ) {
156
  define( 'WP_REDIS_PREFIX', WP_CACHE_KEY_SALT );
157
  }
@@ -159,6 +160,8 @@ function wp_cache_init() {
159
  if ( ! ( $wp_object_cache instanceof WP_Object_Cache ) ) {
160
  $fail_gracefully = ! defined( 'WP_REDIS_GRACEFUL' ) || WP_REDIS_GRACEFUL;
161
 
 
 
162
  $wp_object_cache = new WP_Object_Cache( $fail_gracefully );
163
  }
164
  }
@@ -205,7 +208,7 @@ function wp_cache_set( $key, $value, $group = '', $expiration = 0 ) {
205
  *
206
  * This changes the blog id used to create keys in blog specific groups.
207
  *
208
- * @param int $_blog_id Blog ID
209
  *
210
  * @return bool
211
  */
@@ -241,6 +244,9 @@ function wp_cache_add_non_persistent_groups( $groups ) {
241
  $wp_object_cache->add_non_persistent_groups( $groups );
242
  }
243
 
 
 
 
244
  class WP_Object_Cache {
245
 
246
  /**
@@ -380,7 +386,7 @@ class WP_Object_Cache {
380
  /**
381
  * Instantiate the Redis class.
382
  *
383
- * @param bool $fail_gracefully
384
  */
385
  public function __construct( $fail_gracefully = true ) {
386
  global $blog_id, $table_prefix;
@@ -405,17 +411,17 @@ class WP_Object_Cache {
405
  try {
406
  switch ( $client ) {
407
  case 'hhvm':
408
- $this->connectUsingHHVM( $parameters );
409
  break;
410
  case 'phpredis':
411
- $this->connectUsingPhpRedis( $parameters );
412
  break;
413
  case 'credis':
414
- $this->connectUsingCredis( $parameters );
415
  break;
416
  case 'predis':
417
  default:
418
- $this->connectUsingPredis( $parameters );
419
  break;
420
  }
421
 
@@ -432,7 +438,7 @@ class WP_Object_Cache {
432
  $this->handle_exception( $exception );
433
  }
434
 
435
- // Assign global and blog prefixes for use with keys
436
  if ( function_exists( 'is_multisite' ) ) {
437
  $this->global_prefix = is_multisite() ? '' : $table_prefix;
438
  $this->blog_prefix = is_multisite() ? $blog_id : $table_prefix;
@@ -509,10 +515,10 @@ class WP_Object_Cache {
509
  /**
510
  * Connect to Redis using the PhpRedis (PECL) extention.
511
  *
512
- * @param array $parameters
513
  * @return void
514
  */
515
- protected function connectUsingPhpRedis( $parameters ) {
516
  $version = phpversion( 'redis' );
517
 
518
  $this->diagnostics[ 'client' ] = sprintf( 'PhpRedis (v%s)', $version );
@@ -593,25 +599,20 @@ class WP_Object_Cache {
593
  /**
594
  * Connect to Redis using the Predis library.
595
  *
596
- * @param array $parameters
 
597
  * @return void
598
  */
599
- protected function connectUsingPredis( $parameters ) {
600
  $client = 'Predis';
601
 
602
- // Require PHP 5.4 or greater
603
- if ( version_compare( PHP_VERSION, '5.4.0', '<' ) ) {
604
- throw new Exception( 'Predis requires PHP 5.4 or newer.' );
605
- }
606
-
607
- // Load bundled Predis library
608
  if ( ! class_exists( 'Predis\Client' ) ) {
609
  $predis = sprintf(
610
  '%s/redis-cache/dependencies/predis/predis/autoload.php',
611
  defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins'
612
  );
613
 
614
-
615
  if ( is_readable( $predis ) ) {
616
  require_once $predis;
617
  } else {
@@ -621,19 +622,24 @@ class WP_Object_Cache {
621
  }
622
  }
623
 
 
624
  $options = array();
625
 
626
  if ( defined( 'WP_REDIS_SHARDS' ) ) {
627
- $parameters = WP_REDIS_SHARDS;
 
628
  } elseif ( defined( 'WP_REDIS_SENTINEL' ) ) {
629
- $parameters = WP_REDIS_SERVERS;
 
630
  $options['replication'] = 'sentinel';
631
  $options['service'] = WP_REDIS_SENTINEL;
632
  } elseif ( defined( 'WP_REDIS_SERVERS' ) ) {
633
- $parameters = WP_REDIS_SERVERS;
 
634
  $options['replication'] = true;
635
  } elseif ( defined( 'WP_REDIS_CLUSTER' ) ) {
636
- $parameters = WP_REDIS_CLUSTER;
 
637
  $options['cluster'] = 'redis';
638
  }
639
 
@@ -653,7 +659,7 @@ class WP_Object_Cache {
653
  }
654
  }
655
 
656
- $this->redis = new Predis\Client( $parameters, $options );
657
  $this->redis->connect();
658
 
659
  $this->diagnostics = array_merge(
@@ -666,17 +672,15 @@ class WP_Object_Cache {
666
  /**
667
  * Connect to Redis using the Credis library.
668
  *
669
- * @param array $parameters
 
 
 
670
  * @return void
671
  */
672
- protected function connectUsingCredis( $parameters ) {
673
  $client = 'Credis';
674
 
675
- // Require PHP 5.4 or greater
676
- if ( version_compare( PHP_VERSION, '5.4.0', '<' ) ) {
677
- throw new Exception( 'Predis requires PHP 5.4 or newer.' );
678
- }
679
-
680
  $creds_path = sprintf(
681
  '%s/redis-cache/dependencies/colinmollenhour/credis/',
682
  defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins'
@@ -688,10 +692,12 @@ class WP_Object_Cache {
688
  $to_load[] = 'Client.php';
689
  }
690
 
691
- if (
692
- ( defined( 'WP_REDIS_SHARDS' ) || defined( 'WP_REDIS_SENTINEL' ) || defined( 'WP_REDIS_SERVERS' ) || defined( 'WP_REDIS_CLUSTER' ) ) &&
693
- ! class_exists( 'Credis_Cluster' )
694
- ) {
 
 
695
  $to_load[] = 'Cluster.php';
696
 
697
  if ( defined( 'WP_REDIS_SENTINEL' ) && ! class_exists( 'Credis_Sentinel' ) ) {
@@ -720,7 +726,7 @@ class WP_Object_Cache {
720
  if ( defined( 'WP_REDIS_SENTINEL' ) ) {
721
  if ( is_array( WP_REDIS_SERVERS ) && count( WP_REDIS_SERVERS ) > 1 ) {
722
  throw new Exception(
723
- 'Multipe sentinel servers are not supported by the bundled Credis library. Please review your Redis Cache configurations.'
724
  );
725
  }
726
 
@@ -735,7 +741,7 @@ class WP_Object_Cache {
735
  $clients = $is_cluster ? WP_REDIS_CLUSTER : WP_REDIS_SERVERS;
736
 
737
  foreach ( $clients as $index => &$connection_string ) {
738
- $url_components = parse_url( $connection_string );
739
  parse_str( $url_components['query'], $add_params );
740
 
741
  if ( ! $is_cluster && isset( $add_params['alias'] ) ) {
@@ -767,7 +773,7 @@ class WP_Object_Cache {
767
  $this->redis = new Credis_Client( ...array_values( $args ) );
768
  }
769
 
770
- // Don't use PhpRedis
771
  $this->redis->forceStandalone();
772
 
773
  $this->redis->connect();
@@ -786,13 +792,13 @@ class WP_Object_Cache {
786
  /**
787
  * Connect to Redis using HHVM's Redis extention.
788
  *
789
- * @param array $parameters
790
  * @return void
791
  */
792
- protected function connectUsingHHVM( $parameters ) {
793
  $this->redis = new Redis();
794
 
795
- // Adjust host and port, if the scheme is `unix`
796
  if ( strcasecmp( 'unix', $parameters['scheme'] ) === 0 ) {
797
  $parameters['host'] = 'unix://' . $parameters['path'];
798
  $parameters['port'] = 0;
@@ -863,7 +869,7 @@ class WP_Object_Cache {
863
  * @return bool
864
  */
865
  public function redis_status() {
866
- return (bool) $this->redis_connected;
867
  }
868
 
869
  /**
@@ -872,7 +878,7 @@ class WP_Object_Cache {
872
  * @return mixed
873
  */
874
  public function redis_instance() {
875
- return $this->redis;
876
  }
877
 
878
  /**
@@ -881,7 +887,7 @@ class WP_Object_Cache {
881
  * @return null|string
882
  */
883
  public function redis_version() {
884
- return $this->redis_version;
885
  }
886
 
887
  /**
@@ -921,7 +927,7 @@ class WP_Object_Cache {
921
  *
922
  * Add does not set the value if the key exists; replace does not replace if the value doesn't exist.
923
  *
924
- * @param bool $add True if should only add if value doesn't exist, false to only add when value already exists
925
  * @param string $key The key under which to store the value.
926
  * @param mixed $value The value to store.
927
  * @param string $group The group value appended to the $key.
@@ -940,7 +946,7 @@ class WP_Object_Cache {
940
  $result = true;
941
  $derived_key = $this->build_key( $key, $group );
942
 
943
- // save if group not excluded and redis is up
944
  if ( ! $this->is_ignored_group( $group ) && $this->redis_status() ) {
945
  try {
946
  $expiration = apply_filters( 'redis_cache_expiration', $this->validate_expiration( $expiration ), $key, $group );
@@ -993,7 +999,7 @@ class WP_Object_Cache {
993
 
994
  $exists = isset( $this->cache[ $derived_key ] );
995
 
996
- if ( $add == $exists ) {
997
  return false;
998
  }
999
 
@@ -1148,6 +1154,12 @@ class WP_Object_Cache {
1148
  }
1149
  }
1150
 
 
 
 
 
 
 
1151
  protected function glob_quote( $string ) {
1152
  $characters = [ '*', '+', '?', '!', '{', '}', '[', ']', '(', ')', '|', '@' ];
1153
 
@@ -1265,7 +1277,7 @@ LUA;
1265
  * @param string $group The group value appended to the $key.
1266
  * @param string $force Optional. Whether to force a refetch rather than relying on the local
1267
  * cache. Default false.
1268
- * @param bool &$found Optional. Whether the key was found in the cache. Disambiguates a return of
1269
  * false, a storable value. Passed by reference. Default null.
1270
  * @return bool|mixed Cached object value.
1271
  */
@@ -1368,9 +1380,12 @@ LUA;
1368
  }
1369
  }
1370
 
1371
- $remaining_keys = array_filter( $keys, function ( $key ) use ( $cache ) {
1372
- return ! isset( $cache[ $key ] );
1373
- } );
 
 
 
1374
 
1375
  if ( empty( $remaining_keys ) ) {
1376
  return $cache;
@@ -1379,9 +1394,12 @@ LUA;
1379
  $start_time = microtime( true );
1380
 
1381
  try {
1382
- $remaining_ids = array_map( function ( $key ) use ( $derived_keys ) {
1383
- return $derived_keys[ $key ];
1384
- }, $remaining_keys );
 
 
 
1385
 
1386
  $results = array_combine(
1387
  $remaining_keys,
@@ -1442,7 +1460,7 @@ LUA;
1442
 
1443
  $start_time = microtime( true );
1444
 
1445
- // save if group not excluded from redis and redis is up
1446
  if ( ! $this->is_ignored_group( $group ) && $this->redis_status() ) {
1447
  $expiration = apply_filters( 'redis_cache_expiration', $this->validate_expiration( $expiration ), $key, $group );
1448
 
@@ -1462,7 +1480,7 @@ LUA;
1462
  $this->cache_time += ( microtime( true ) - $start_time );
1463
  }
1464
 
1465
- // if the set was successful, or we didn't go to redis
1466
  if ( $result ) {
1467
  $this->add_to_internal_cache( $derived_key, $value );
1468
  }
@@ -1479,16 +1497,16 @@ LUA;
1479
  /**
1480
  * Increment a Redis counter by the amount specified
1481
  *
1482
- * @param string $key
1483
- * @param int $offset
1484
- * @param string $group
1485
  * @return int|bool
1486
  */
1487
  public function increment( $key, $offset = 1, $group = 'default' ) {
1488
  $offset = (int) $offset;
1489
  $derived_key = $this->build_key( $key, $group );
1490
 
1491
- // If group is a non-Redis group, save to internal cache, not Redis
1492
  if ( $this->is_ignored_group( $group ) || ! $this->redis_status() ) {
1493
  $value = $this->get_from_internal_cache( $derived_key );
1494
  $value += $offset;
@@ -1520,10 +1538,11 @@ LUA;
1520
  /**
1521
  * Alias of `increment()`.
1522
  *
1523
- * @param string $key
1524
- * @param int $offset
1525
- * @param string $group
1526
- * @return bool
 
1527
  */
1528
  public function incr( $key, $offset = 1, $group = 'default' ) {
1529
  return $this->increment( $key, $offset, $group );
@@ -1532,16 +1551,16 @@ LUA;
1532
  /**
1533
  * Decrement a Redis counter by the amount specified
1534
  *
1535
- * @param string $key
1536
- * @param int $offset
1537
- * @param string $group
1538
  * @return int|bool
1539
  */
1540
  public function decrement( $key, $offset = 1, $group = 'default' ) {
1541
  $derived_key = $this->build_key( $key, $group );
1542
  $offset = (int) $offset;
1543
 
1544
- // If group is a non-Redis group, save to internal cache, not Redis
1545
  if ( $this->is_ignored_group( $group ) || ! $this->redis_status() ) {
1546
  $value = $this->get_from_internal_cache( $derived_key );
1547
  $value -= $offset;
@@ -1553,7 +1572,7 @@ LUA;
1553
  $start_time = microtime( true );
1554
 
1555
  try {
1556
- // Save to Redis
1557
  $result = $this->parse_redis_response( $this->redis->decrBy( $derived_key, $offset ) );
1558
 
1559
  $this->add_to_internal_cache( $derived_key, (int) $this->redis->get( $derived_key ) );
@@ -1573,33 +1592,28 @@ LUA;
1573
 
1574
  /**
1575
  * Render data about current cache requests
 
1576
  *
1577
- * @return string
1578
  */
1579
  public function stats() {
1580
- $bytes = array_map(
1581
- function ( $key ) {
1582
- return strlen( serialize( $key ) );
1583
- },
1584
- $this->cache
1585
- );
1586
-
1587
- ?> <p>
1588
- <strong>Redis Status:</strong>
1589
- <?php echo $this->redis_status() ? 'Connected' : 'Not connected'; ?>
1590
- <br />
1591
- <strong>Redis Client:</strong>
1592
- <?php echo $this->diagnostics['client'] ?: 'Unknown'; ?>
1593
- <br />
1594
- <strong>Cache Hits:</strong>
1595
- <?php echo $this->cache_hits; ?>
1596
- <br />
1597
- <strong>Cache Misses:</strong>
1598
- <?php echo $this->cache_misses; ?>
1599
- <br />
1600
- <strong>Cache Size:</strong>
1601
- <?php echo number_format( array_sum( $bytes ) / 1024, 2 ); ?> kB
1602
- </p>
1603
  <?php
1604
  }
1605
 
@@ -1613,14 +1627,13 @@ LUA;
1613
 
1614
  $bytes = array_map(
1615
  function ( $keys ) {
 
1616
  return strlen( serialize( $keys ) );
1617
  },
1618
  $this->cache
1619
  );
1620
 
1621
  return (object) [
1622
- // Connected, Disabled, Unknown, Not connected
1623
- 'status' => '...',
1624
  'hits' => $this->cache_hits,
1625
  'misses' => $this->cache_misses,
1626
  'ratio' => $total > 0 ? round( $this->cache_hits / ( $total / 100 ), 1 ) : 100,
@@ -1671,13 +1684,13 @@ LUA;
1671
  * @return string Sanitized string.
1672
  */
1673
  protected function sanitize_key_part( $part ) {
1674
- return str_replace( ':', '-', $part );
1675
  }
1676
 
1677
  /**
1678
  * Checks if the given group is part the ignored group array
1679
  *
1680
- * @param string $group Name of the group to check
1681
  * @return bool
1682
  */
1683
  protected function is_ignored_group( $group ) {
@@ -1687,7 +1700,7 @@ LUA;
1687
  /**
1688
  * Checks if the given group is part the global group array
1689
  *
1690
- * @param string $group Name of the group to check
1691
  * @return bool
1692
  */
1693
  protected function is_global_group( $group ) {
@@ -1697,7 +1710,7 @@ LUA;
1697
  /**
1698
  * Checks if the given group is part the unflushable group array
1699
  *
1700
- * @param string $group Name of the group to check
1701
  * @return bool
1702
  */
1703
  protected function is_unflushable_group( $group ) {
@@ -1707,7 +1720,7 @@ LUA;
1707
  /**
1708
  * Convert Redis responses into something meaningful
1709
  *
1710
- * @param mixed $response
1711
  * @return mixed
1712
  */
1713
  protected function parse_redis_response( $response ) {
@@ -1762,7 +1775,7 @@ LUA;
1762
  /**
1763
  * In multisite, switch blog prefix when switching blogs
1764
  *
1765
- * @param int $_blog_id
1766
  * @return bool
1767
  */
1768
  public function switch_to_blog( $_blog_id ) {
@@ -1815,7 +1828,7 @@ LUA;
1815
  /**
1816
  * Wrapper to validate the cache keys expiration value
1817
  *
1818
- * @param mixed $expiration Incoming expiration value (whatever it is)
1819
  */
1820
  protected function validate_expiration( $expiration ) {
1821
  $expiration = is_int( $expiration ) || ctype_digit( $expiration ) ? (int) $expiration : 0;
@@ -1846,8 +1859,9 @@ LUA;
1846
  return igbinary_unserialize( $original );
1847
  }
1848
 
1849
- // don't attempt to unserialize data that wasn't serialized going in
1850
  if ( $this->is_serialized( $original ) ) {
 
1851
  $value = @unserialize( $original );
1852
 
1853
  return is_object( $value ) ? clone $value : $value;
@@ -1876,10 +1890,12 @@ LUA;
1876
  }
1877
 
1878
  if ( is_array( $data ) || is_object( $data ) ) {
 
1879
  return serialize( $data );
1880
  }
1881
 
1882
  if ( $this->is_serialized( $data, false ) ) {
 
1883
  return serialize( $data );
1884
  }
1885
 
@@ -1904,7 +1920,7 @@ LUA;
1904
 
1905
  $data = trim( $data );
1906
 
1907
- if ( 'N;' == $data ) {
1908
  return true;
1909
  }
1910
 
@@ -1951,8 +1967,8 @@ LUA;
1951
  } elseif ( false === strpos( $data, '"' ) ) {
1952
  return false;
1953
  }
1954
- // or else fall through
1955
- // no break
1956
  case 'a':
1957
  case 'O':
1958
  return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
@@ -1971,11 +1987,13 @@ LUA;
1971
  * Handle the redis failure gracefully or throw an exception.
1972
  *
1973
  * @param \Exception $exception Exception thrown.
 
 
1974
  */
1975
  protected function handle_exception( $exception ) {
1976
  $this->redis_connected = false;
1977
 
1978
- // When Redis is unavailable, fall back to the internal cache by forcing all groups to be "no redis" groups
1979
  $this->ignored_groups = array_unique( array_merge( $this->ignored_groups, $this->global_groups ) );
1980
 
1981
  if ( ! $this->fail_gracefully ) {
@@ -1984,7 +2002,7 @@ LUA;
1984
 
1985
  $this->errors[] = $exception->getMessage();
1986
 
1987
- error_log( $exception );
1988
 
1989
  if ( function_exists( 'do_action' ) ) {
1990
  do_action( 'redis_object_cache_error', $exception );
@@ -1994,12 +2012,13 @@ LUA;
1994
  /**
1995
  * Allows access to private properties for backwards compatibility.
1996
  *
1997
- * @param string $name
1998
  * @return mixed
1999
  */
2000
  public function __get( $name ) {
2001
- return isset($this->{$name}) ? $this->{$name} : null;
2002
  }
2003
  }
2004
 
2005
  endif;
 
3
  * Plugin Name: Redis Object Cache Drop-In
4
  * Plugin URI: http://wordpress.org/plugins/redis-cache/
5
  * Description: A persistent object cache backend powered by Redis. Supports Predis, PhpRedis, Credis, HHVM, replication, clustering and WP-CLI.
6
+ * Version: 2.0.12
7
  * Author: Till Krüss
8
  * Author URI: https://objectcache.pro
9
  * License: GPLv3
14
 
15
  defined( '\\ABSPATH' ) || exit;
16
 
17
+ // phpcs:disable Generic.WhiteSpace.ScopeIndent.IncorrectExact, Generic.WhiteSpace.ScopeIndent.Incorrect
18
  if ( ! defined( 'WP_REDIS_DISABLED' ) || ! WP_REDIS_DISABLED ) :
19
 
20
  /**
47
  * @return bool Always returns True
48
  */
49
  function wp_cache_close() {
50
+ return true;
51
  }
52
 
53
  /**
103
  * @param string $group The group value appended to the $key.
104
  * @param bool $force Optional. Whether to force an update of the local cache from the persistent
105
  * cache. Default false.
106
+ * @param bool $found Optional. Whether the key was found in the cache. Disambiguates a return of false,
107
  * a storable value. Passed by reference. Default null.
108
  *
109
  * @return bool|mixed Cached object value.
152
  function wp_cache_init() {
153
  global $wp_object_cache;
154
 
155
+ // Backwards compatibility: map `WP_CACHE_KEY_SALT` constant to `WP_REDIS_PREFIX`.
156
  if ( defined( 'WP_CACHE_KEY_SALT' ) && ! defined( 'WP_REDIS_PREFIX' ) ) {
157
  define( 'WP_REDIS_PREFIX', WP_CACHE_KEY_SALT );
158
  }
160
  if ( ! ( $wp_object_cache instanceof WP_Object_Cache ) ) {
161
  $fail_gracefully = ! defined( 'WP_REDIS_GRACEFUL' ) || WP_REDIS_GRACEFUL;
162
 
163
+ // We need to override this WordPress global in order to inject our cache.
164
+ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
165
  $wp_object_cache = new WP_Object_Cache( $fail_gracefully );
166
  }
167
  }
208
  *
209
  * This changes the blog id used to create keys in blog specific groups.
210
  *
211
+ * @param int $_blog_id The blog ID.
212
  *
213
  * @return bool
214
  */
244
  $wp_object_cache->add_non_persistent_groups( $groups );
245
  }
246
 
247
+ /**
248
+ * Object cache class definition
249
+ */
250
  class WP_Object_Cache {
251
 
252
  /**
386
  /**
387
  * Instantiate the Redis class.
388
  *
389
+ * @param bool $fail_gracefully Handles and logs errors if true throws exceptions otherwise.
390
  */
391
  public function __construct( $fail_gracefully = true ) {
392
  global $blog_id, $table_prefix;
411
  try {
412
  switch ( $client ) {
413
  case 'hhvm':
414
+ $this->connect_using_hhvm( $parameters );
415
  break;
416
  case 'phpredis':
417
+ $this->connect_using_phpredis( $parameters );
418
  break;
419
  case 'credis':
420
+ $this->connect_using_credis( $parameters );
421
  break;
422
  case 'predis':
423
  default:
424
+ $this->connect_using_predis( $parameters );
425
  break;
426
  }
427
 
438
  $this->handle_exception( $exception );
439
  }
440
 
441
+ // Assign global and blog prefixes for use with keys.
442
  if ( function_exists( 'is_multisite' ) ) {
443
  $this->global_prefix = is_multisite() ? '' : $table_prefix;
444
  $this->blog_prefix = is_multisite() ? $blog_id : $table_prefix;
515
  /**
516
  * Connect to Redis using the PhpRedis (PECL) extention.
517
  *
518
+ * @param array $parameters Connection parameters built by the `build_parameters` method.
519
  * @return void
520
  */
521
+ protected function connect_using_phpredis( $parameters ) {
522
  $version = phpversion( 'redis' );
523
 
524
  $this->diagnostics[ 'client' ] = sprintf( 'PhpRedis (v%s)', $version );
599
  /**
600
  * Connect to Redis using the Predis library.
601
  *
602
+ * @param array $parameters Connection parameters built by the `build_parameters` method.
603
+ * @throws \Exception If the Predis library was not found or is unreadable.
604
  * @return void
605
  */
606
+ protected function connect_using_predis( $parameters ) {
607
  $client = 'Predis';
608
 
609
+ // Load bundled Predis library.
 
 
 
 
 
610
  if ( ! class_exists( 'Predis\Client' ) ) {
611
  $predis = sprintf(
612
  '%s/redis-cache/dependencies/predis/predis/autoload.php',
613
  defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins'
614
  );
615
 
 
616
  if ( is_readable( $predis ) ) {
617
  require_once $predis;
618
  } else {
622
  }
623
  }
624
 
625
+ $servers = false;
626
  $options = array();
627
 
628
  if ( defined( 'WP_REDIS_SHARDS' ) ) {
629
+ $servers = WP_REDIS_SHARDS;
630
+ $parameters['shards'] = $servers;
631
  } elseif ( defined( 'WP_REDIS_SENTINEL' ) ) {
632
+ $servers = WP_REDIS_SERVERS;
633
+ $parameters['servers'] = $servers;
634
  $options['replication'] = 'sentinel';
635
  $options['service'] = WP_REDIS_SENTINEL;
636
  } elseif ( defined( 'WP_REDIS_SERVERS' ) ) {
637
+ $servers = WP_REDIS_SERVERS;
638
+ $parameters['servers'] = $servers;
639
  $options['replication'] = true;
640
  } elseif ( defined( 'WP_REDIS_CLUSTER' ) ) {
641
+ $servers = WP_REDIS_CLUSTER;
642
+ $parameters['cluster'] = $servers;
643
  $options['cluster'] = 'redis';
644
  }
645
 
659
  }
660
  }
661
 
662
+ $this->redis = new Predis\Client( $servers ?: $parameters, $options );
663
  $this->redis->connect();
664
 
665
  $this->diagnostics = array_merge(
672
  /**
673
  * Connect to Redis using the Credis library.
674
  *
675
+ * @param array $parameters Connection parameters built by the `build_parameters` method.
676
+ * @throws \Exception If the Credis library was not found or is unreadable.
677
+ * @throws \Exception If redis sharding should be configured as Credis does not support sharding.
678
+ * @throws \Exception If more than one seninel is configured as Credis does not support multiple sentinel servers.
679
  * @return void
680
  */
681
+ protected function connect_using_credis( $parameters ) {
682
  $client = 'Credis';
683
 
 
 
 
 
 
684
  $creds_path = sprintf(
685
  '%s/redis-cache/dependencies/colinmollenhour/credis/',
686
  defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins'
692
  $to_load[] = 'Client.php';
693
  }
694
 
695
+ $has_shards = defined( 'WP_REDIS_SHARDS' );
696
+ $has_sentinel = defined( 'WP_REDIS_SENTINEL' );
697
+ $has_servers = defined( 'WP_REDIS_SERVERS' );
698
+ $has_cluster = defined( 'WP_REDIS_CLUSTER' );
699
+
700
+ if ( ( $has_shards || $has_sentinel || $has_servers || $has_cluster ) && ! class_exists( 'Credis_Cluster' ) ) {
701
  $to_load[] = 'Cluster.php';
702
 
703
  if ( defined( 'WP_REDIS_SENTINEL' ) && ! class_exists( 'Credis_Sentinel' ) ) {
726
  if ( defined( 'WP_REDIS_SENTINEL' ) ) {
727
  if ( is_array( WP_REDIS_SERVERS ) && count( WP_REDIS_SERVERS ) > 1 ) {
728
  throw new Exception(
729
+ 'Multipe sentinel servers are not supported by the bundled Credis library. Please review your Redis Cache configuration.'
730
  );
731
  }
732
 
741
  $clients = $is_cluster ? WP_REDIS_CLUSTER : WP_REDIS_SERVERS;
742
 
743
  foreach ( $clients as $index => &$connection_string ) {
744
+ $url_components = wp_parse_url( $connection_string );
745
  parse_str( $url_components['query'], $add_params );
746
 
747
  if ( ! $is_cluster && isset( $add_params['alias'] ) ) {
773
  $this->redis = new Credis_Client( ...array_values( $args ) );
774
  }
775
 
776
+ // Don't use PhpRedis if it is available.
777
  $this->redis->forceStandalone();
778
 
779
  $this->redis->connect();
792
  /**
793
  * Connect to Redis using HHVM's Redis extention.
794
  *
795
+ * @param array $parameters Connection parameters built by the `build_parameters` method.
796
  * @return void
797
  */
798
+ protected function connect_using_hhvm( $parameters ) {
799
  $this->redis = new Redis();
800
 
801
+ // Adjust host and port if the scheme is `unix`.
802
  if ( strcasecmp( 'unix', $parameters['scheme'] ) === 0 ) {
803
  $parameters['host'] = 'unix://' . $parameters['path'];
804
  $parameters['port'] = 0;
869
  * @return bool
870
  */
871
  public function redis_status() {
872
+ return (bool) $this->redis_connected;
873
  }
874
 
875
  /**
878
  * @return mixed
879
  */
880
  public function redis_instance() {
881
+ return $this->redis;
882
  }
883
 
884
  /**
887
  * @return null|string
888
  */
889
  public function redis_version() {
890
+ return $this->redis_version;
891
  }
892
 
893
  /**
927
  *
928
  * Add does not set the value if the key exists; replace does not replace if the value doesn't exist.
929
  *
930
+ * @param bool $add True if should only add if value doesn't exist, false to only add when value already exists.
931
  * @param string $key The key under which to store the value.
932
  * @param mixed $value The value to store.
933
  * @param string $group The group value appended to the $key.
946
  $result = true;
947
  $derived_key = $this->build_key( $key, $group );
948
 
949
+ // Save if group not excluded and redis is up.
950
  if ( ! $this->is_ignored_group( $group ) && $this->redis_status() ) {
951
  try {
952
  $expiration = apply_filters( 'redis_cache_expiration', $this->validate_expiration( $expiration ), $key, $group );
999
 
1000
  $exists = isset( $this->cache[ $derived_key ] );
1001
 
1002
+ if ( (bool) $add === $exists ) {
1003
  return false;
1004
  }
1005
 
1154
  }
1155
  }
1156
 
1157
+ /**
1158
+ * Quotes a string for usage in the `glob` function
1159
+ *
1160
+ * @param string $string The string to quote.
1161
+ * @return string
1162
+ */
1163
  protected function glob_quote( $string ) {
1164
  $characters = [ '*', '+', '?', '!', '{', '}', '[', ']', '(', ')', '|', '@' ];
1165
 
1277
  * @param string $group The group value appended to the $key.
1278
  * @param string $force Optional. Whether to force a refetch rather than relying on the local
1279
  * cache. Default false.
1280
+ * @param bool $found Optional. Whether the key was found in the cache. Disambiguates a return of
1281
  * false, a storable value. Passed by reference. Default null.
1282
  * @return bool|mixed Cached object value.
1283
  */
1380
  }
1381
  }
1382
 
1383
+ $remaining_keys = array_filter(
1384
+ $keys,
1385
+ function ( $key ) use ( $cache ) {
1386
+ return ! isset( $cache[ $key ] );
1387
+ }
1388
+ );
1389
 
1390
  if ( empty( $remaining_keys ) ) {
1391
  return $cache;
1394
  $start_time = microtime( true );
1395
 
1396
  try {
1397
+ $remaining_ids = array_map(
1398
+ function ( $key ) use ( $derived_keys ) {
1399
+ return $derived_keys[ $key ];
1400
+ },
1401
+ $remaining_keys
1402
+ );
1403
 
1404
  $results = array_combine(
1405
  $remaining_keys,
1460
 
1461
  $start_time = microtime( true );
1462
 
1463
+ // Save if group not excluded from redis and redis is up.
1464
  if ( ! $this->is_ignored_group( $group ) && $this->redis_status() ) {
1465
  $expiration = apply_filters( 'redis_cache_expiration', $this->validate_expiration( $expiration ), $key, $group );
1466
 
1480
  $this->cache_time += ( microtime( true ) - $start_time );
1481
  }
1482
 
1483
+ // If the set was successful, or we didn't go to redis.
1484
  if ( $result ) {
1485
  $this->add_to_internal_cache( $derived_key, $value );
1486
  }
1497
  /**
1498
  * Increment a Redis counter by the amount specified
1499
  *
1500
+ * @param string $key The key name.
1501
+ * @param int $offset Optional. The increment. Defaults to 1.
1502
+ * @param string $group Optional. The key group. Default is 'default'.
1503
  * @return int|bool
1504
  */
1505
  public function increment( $key, $offset = 1, $group = 'default' ) {
1506
  $offset = (int) $offset;
1507
  $derived_key = $this->build_key( $key, $group );
1508
 
1509
+ // If group is a non-Redis group, save to internal cache, not Redis.
1510
  if ( $this->is_ignored_group( $group ) || ! $this->redis_status() ) {
1511
  $value = $this->get_from_internal_cache( $derived_key );
1512
  $value += $offset;
1538
  /**
1539
  * Alias of `increment()`.
1540
  *
1541
+ * @see self::increment()
1542
+ * @param string $key The key name.
1543
+ * @param int $offset Optional. The increment. Defaults to 1.
1544
+ * @param string $group Optional. The key group. Default is 'default'.
1545
+ * @return int|bool
1546
  */
1547
  public function incr( $key, $offset = 1, $group = 'default' ) {
1548
  return $this->increment( $key, $offset, $group );
1551
  /**
1552
  * Decrement a Redis counter by the amount specified
1553
  *
1554
+ * @param string $key The key name.
1555
+ * @param int $offset Optional. The decrement. Defaults to 1.
1556
+ * @param string $group Optional. The key group. Default is 'default'.
1557
  * @return int|bool
1558
  */
1559
  public function decrement( $key, $offset = 1, $group = 'default' ) {
1560
  $derived_key = $this->build_key( $key, $group );
1561
  $offset = (int) $offset;
1562
 
1563
+ // If group is a non-Redis group, save to internal cache, not Redis.
1564
  if ( $this->is_ignored_group( $group ) || ! $this->redis_status() ) {
1565
  $value = $this->get_from_internal_cache( $derived_key );
1566
  $value -= $offset;
1572
  $start_time = microtime( true );
1573
 
1574
  try {
1575
+ // Save to Redis.
1576
  $result = $this->parse_redis_response( $this->redis->decrBy( $derived_key, $offset ) );
1577
 
1578
  $this->add_to_internal_cache( $derived_key, (int) $this->redis->get( $derived_key ) );
1592
 
1593
  /**
1594
  * Render data about current cache requests
1595
+ * Used by the Debug bar plugin
1596
  *
1597
+ * @return void
1598
  */
1599
  public function stats() {
1600
+ ?>
1601
+ <p>
1602
+ <strong>Redis Status:</strong>
1603
+ <?php echo $this->redis_status() ? 'Connected' : 'Not connected'; ?>
1604
+ <br />
1605
+ <strong>Redis Client:</strong>
1606
+ <?php echo $this->diagnostics['client'] ?: 'Unknown'; ?>
1607
+ <br />
1608
+ <strong>Cache Hits:</strong>
1609
+ <?php echo intval( $this->cache_hits ); ?>
1610
+ <br />
1611
+ <strong>Cache Misses:</strong>
1612
+ <?php echo intval( $this->cache_misses ); ?>
1613
+ <br />
1614
+ <strong>Cache Size:</strong>
1615
+ <?php echo number_format( strlen( serialize( $this->cache ) ) / 1024, 2 ); ?> kB
1616
+ </p>
 
 
 
 
 
 
1617
  <?php
1618
  }
1619
 
1627
 
1628
  $bytes = array_map(
1629
  function ( $keys ) {
1630
+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
1631
  return strlen( serialize( $keys ) );
1632
  },
1633
  $this->cache
1634
  );
1635
 
1636
  return (object) [
 
 
1637
  'hits' => $this->cache_hits,
1638
  'misses' => $this->cache_misses,
1639
  'ratio' => $total > 0 ? round( $this->cache_hits / ( $total / 100 ), 1 ) : 100,
1684
  * @return string Sanitized string.
1685
  */
1686
  protected function sanitize_key_part( $part ) {
1687
+ return str_replace( ':', '-', $part );
1688
  }
1689
 
1690
  /**
1691
  * Checks if the given group is part the ignored group array
1692
  *
1693
+ * @param string $group Name of the group to check.
1694
  * @return bool
1695
  */
1696
  protected function is_ignored_group( $group ) {
1700
  /**
1701
  * Checks if the given group is part the global group array
1702
  *
1703
+ * @param string $group Name of the group to check.
1704
  * @return bool
1705
  */
1706
  protected function is_global_group( $group ) {
1710
  /**
1711
  * Checks if the given group is part the unflushable group array
1712
  *
1713
+ * @param string $group Name of the group to check.
1714
  * @return bool
1715
  */
1716
  protected function is_unflushable_group( $group ) {
1720
  /**
1721
  * Convert Redis responses into something meaningful
1722
  *
1723
+ * @param mixed $response Response sent from the redis instance.
1724
  * @return mixed
1725
  */
1726
  protected function parse_redis_response( $response ) {
1775
  /**
1776
  * In multisite, switch blog prefix when switching blogs
1777
  *
1778
+ * @param int $_blog_id Blog ID.
1779
  * @return bool
1780
  */
1781
  public function switch_to_blog( $_blog_id ) {
1828
  /**
1829
  * Wrapper to validate the cache keys expiration value
1830
  *
1831
+ * @param mixed $expiration Incoming expiration value (whatever it is).
1832
  */
1833
  protected function validate_expiration( $expiration ) {
1834
  $expiration = is_int( $expiration ) || ctype_digit( $expiration ) ? (int) $expiration : 0;
1859
  return igbinary_unserialize( $original );
1860
  }
1861
 
1862
+ // Don't attempt to unserialize data that wasn't serialized going in.
1863
  if ( $this->is_serialized( $original ) ) {
1864
+ // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
1865
  $value = @unserialize( $original );
1866
 
1867
  return is_object( $value ) ? clone $value : $value;
1890
  }
1891
 
1892
  if ( is_array( $data ) || is_object( $data ) ) {
1893
+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
1894
  return serialize( $data );
1895
  }
1896
 
1897
  if ( $this->is_serialized( $data, false ) ) {
1898
+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
1899
  return serialize( $data );
1900
  }
1901
 
1920
 
1921
  $data = trim( $data );
1922
 
1923
+ if ( 'N;' === $data ) {
1924
  return true;
1925
  }
1926
 
1967
  } elseif ( false === strpos( $data, '"' ) ) {
1968
  return false;
1969
  }
1970
+ // Or else fall through.
1971
+ // No break!
1972
  case 'a':
1973
  case 'O':
1974
  return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
1987
  * Handle the redis failure gracefully or throw an exception.
1988
  *
1989
  * @param \Exception $exception Exception thrown.
1990
+ * @throws \Exception If `fail_gracefully` flag is set to a falsy value.
1991
+ * @return void
1992
  */
1993
  protected function handle_exception( $exception ) {
1994
  $this->redis_connected = false;
1995
 
1996
+ // When Redis is unavailable, fall back to the internal cache by forcing all groups to be "no redis" groups.
1997
  $this->ignored_groups = array_unique( array_merge( $this->ignored_groups, $this->global_groups ) );
1998
 
1999
  if ( ! $this->fail_gracefully ) {
2002
 
2003
  $this->errors[] = $exception->getMessage();
2004
 
2005
+ error_log( $exception ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
2006
 
2007
  if ( function_exists( 'do_action' ) ) {
2008
  do_action( 'redis_object_cache_error', $exception );
2012
  /**
2013
  * Allows access to private properties for backwards compatibility.
2014
  *
2015
+ * @param string $name Name of the property.
2016
  * @return mixed
2017
  */
2018
  public function __get( $name ) {
2019
+ return isset( $this->{$name} ) ? $this->{$name} : null;
2020
  }
2021
  }
2022
 
2023
  endif;
2024
+ // phpcs:enable Generic.WhiteSpace.ScopeIndent.IncorrectExact, Generic.WhiteSpace.ScopeIndent.Incorrect
includes/ui/class-tab.php ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Tab utility class
4
+ *
5
+ * @package Rhubarb\RedisCache
6
+ */
7
+
8
+ namespace Rhubarb\RedisCache\UI;
9
+
10
+ use Rhubarb\RedisCache\Plugin;
11
+
12
+ defined( '\\ABSPATH' ) || exit;
13
+
14
+ /**
15
+ * Tab class definition
16
+ */
17
+ class Tab {
18
+
19
+ /**
20
+ * Tab slug
21
+ *
22
+ * @var string $slug
23
+ */
24
+ protected $slug = '';
25
+
26
+ /**
27
+ * Tab label
28
+ *
29
+ * @var string $label
30
+ */
31
+ protected $label = '';
32
+
33
+ /**
34
+ * Tab template file
35
+ *
36
+ * @var string $file
37
+ */
38
+ protected $file = '';
39
+
40
+ /**
41
+ * Tab default state
42
+ *
43
+ * @var bool $default
44
+ */
45
+ protected $default = false;
46
+
47
+ /**
48
+ * Tab disabled state
49
+ *
50
+ * @var bool $disabled
51
+ */
52
+ protected $disabled = false;
53
+
54
+ /**
55
+ * Tab custom data
56
+ *
57
+ * @var array $custom
58
+ */
59
+ protected $custom = [];
60
+
61
+ /**
62
+ * Constructor
63
+ *
64
+ * @param string $slug Slug to identify the tab.
65
+ * @param string $label Tab label.
66
+ * @param array $args Optional arguments describing the tab.
67
+ */
68
+ public function __construct( $slug, $label, $args = [] ) {
69
+ $args = wp_parse_args(
70
+ $args,
71
+ [
72
+ 'slug' => $slug,
73
+ 'label' => $label,
74
+ 'file' => WP_REDIS_PLUGIN_PATH . "/includes/ui/tabs/{$slug}.php",
75
+ ]
76
+ );
77
+ foreach ( $args ?: [] as $property => $value ) {
78
+ if ( property_exists( $this, $property ) ) {
79
+ $this->{$property} = $value;
80
+ } else {
81
+ $this->custom[ $property ] = $value;
82
+ }
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Getter for tab slug
88
+ *
89
+ * @return string
90
+ */
91
+ public function slug() {
92
+ return $this->slug;
93
+ }
94
+
95
+ /**
96
+ * Getter for tab label
97
+ *
98
+ * @return string
99
+ */
100
+ public function label() {
101
+ return $this->label;
102
+ }
103
+
104
+ /**
105
+ * Getter for tab file
106
+ *
107
+ * @return string
108
+ */
109
+ public function file() {
110
+ return $this->file;
111
+ }
112
+
113
+ /**
114
+ * Getter for tab disabled state
115
+ *
116
+ * @return bool
117
+ */
118
+ public function is_disabled() {
119
+ return $this->disabled;
120
+ }
121
+
122
+ /**
123
+ * Getter for tab default state
124
+ *
125
+ * @return bool
126
+ */
127
+ public function is_default() {
128
+ return $this->default;
129
+ }
130
+
131
+ /**
132
+ * Getter for tab custom data
133
+ *
134
+ * @param $string $key Custom data key.
135
+ * @return mixed
136
+ */
137
+ public function custom( $key ) {
138
+ if ( ! isset( $this->custom[ $key ] ) ) {
139
+ return null;
140
+ }
141
+ return $this->custom[ $key ];
142
+ }
143
+
144
+ /**
145
+ * Disabled notice for tab
146
+ *
147
+ * @return string
148
+ */
149
+ public function disabled_notice() {
150
+ return sprintf(
151
+ // translators: %s = Tab label.
152
+ __( '%s are disabled for this site.', 'redis-cache' ),
153
+ $this->label
154
+ );
155
+ }
156
+
157
+ /**
158
+ * Displays the tab template
159
+ *
160
+ * @return void
161
+ */
162
+ public function display() {
163
+ $roc = Plugin::instance();
164
+ include $this->file;
165
+ }
166
+
167
+ /**
168
+ * Returns the tab nav id attribute
169
+ *
170
+ * @return string
171
+ */
172
+ public function nav_id() {
173
+ return apply_filters( 'roc_tab_nav_id', "{$this->slug}-tab", $this );
174
+ }
175
+
176
+ /**
177
+ * Returns the tab nav css classes
178
+ *
179
+ * @return string
180
+ */
181
+ public function nav_classes() {
182
+ $classes = [
183
+ 'nav-tab',
184
+ ];
185
+ if ( $this->default ) {
186
+ $classes[] = 'nav-tab-active';
187
+ }
188
+ if ( $this->disabled ) {
189
+ $classes[] = 'nav-tab-disabled';
190
+ }
191
+ return implode( ' ', apply_filters( 'roc_tab_nav_classes', $classes, $this ) );
192
+ }
193
+
194
+ /**
195
+ * Returns the tab id attribute
196
+ *
197
+ * @return string
198
+ */
199
+ public function id() {
200
+ return apply_filters( 'roc_tab_id', "{$this->slug}-pane", $this );
201
+ }
202
+
203
+ /**
204
+ * Returns the tab css classes
205
+ *
206
+ * @return string
207
+ */
208
+ public function classes() {
209
+ $classes = [
210
+ 'tab-pane',
211
+ "tab-pane-{$this->slug}",
212
+ ];
213
+ if ( $this->default ) {
214
+ $classes[] = 'active';
215
+ }
216
+ return implode( ' ', apply_filters( 'roc_tab_classes', $classes, $this ) );
217
+ }
218
+
219
+ }
includes/ui/diagnostics.php CHANGED
@@ -10,14 +10,14 @@ defined( '\\ABSPATH' ) || exit;
10
  global $wp_object_cache;
11
 
12
  $info = [];
13
- $filesystem = $plugin->test_filesystem_writing();
14
- $dropin = $plugin->validate_object_cache_dropin();
15
  $disabled = defined( 'WP_REDIS_DISABLED' ) && WP_REDIS_DISABLED;
16
 
17
- $info['Status'] = $plugin->get_status();
18
- $info['Client'] = $plugin->get_redis_client_name();
19
- $info['Drop-in'] = $plugin->object_cache_dropin_exists()
20
- ? ($dropin ? 'Valid' : 'Invalid')
21
  : 'Not installed';
22
  $info['Disabled'] = $disabled ? 'Yes' : 'No';
23
  $info['Filesystem'] = is_wp_error( $filesystem ) ? $filesystem->get_error_message() : 'Working';
@@ -52,7 +52,7 @@ if ( defined( 'HHVM_VERSION' ) ) {
52
  }
53
 
54
  $info['Plugin Version'] = WP_REDIS_VERSION;
55
- $info['Redis Version'] = $plugin->get_redis_version() ?: 'Unknown';
56
 
57
  $info['Multisite'] = is_multisite() ? 'Yes' : 'No';
58
 
@@ -140,6 +140,6 @@ foreach ( $info as $name => $value ) {
140
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
141
  WP_CLI::line( "{$name}: $value" );
142
  } else {
143
- echo "{$name}: {$value}\r\n";
144
  }
145
  }
10
  global $wp_object_cache;
11
 
12
  $info = [];
13
+ $filesystem = $roc->test_filesystem_writing();
14
+ $dropin = $roc->validate_object_cache_dropin();
15
  $disabled = defined( 'WP_REDIS_DISABLED' ) && WP_REDIS_DISABLED;
16
 
17
+ $info['Status'] = $roc->get_status();
18
+ $info['Client'] = $roc->get_redis_client_name();
19
+ $info['Drop-in'] = $roc->object_cache_dropin_exists()
20
+ ? ( $dropin ? 'Valid' : 'Invalid' )
21
  : 'Not installed';
22
  $info['Disabled'] = $disabled ? 'Yes' : 'No';
23
  $info['Filesystem'] = is_wp_error( $filesystem ) ? $filesystem->get_error_message() : 'Working';
52
  }
53
 
54
  $info['Plugin Version'] = WP_REDIS_VERSION;
55
+ $info['Redis Version'] = $roc->get_redis_version() ?: 'Unknown';
56
 
57
  $info['Multisite'] = is_multisite() ? 'Yes' : 'No';
58
 
140
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
141
  WP_CLI::line( "{$name}: $value" );
142
  } else {
143
+ echo esc_textarea( "{$name}: {$value}\r\n" );
144
  }
145
  }
includes/ui/settings.php CHANGED
@@ -26,28 +26,24 @@ defined( '\\ABSPATH' ) || exit;
26
 
27
  <h2 class="nav-tab-wrapper">
28
  <?php foreach ( UI::get_tabs() as $ui_tab ) : ?>
29
- <?php if ( $ui_tab->disabled ) : ?>
30
 
31
  <span
32
- class="nav-tab nav-tab-disabled"
33
- title="<?php printf(
34
- // translators: %s = Tab label
35
- esc_html__( '%s are disabled for this site.', 'redis-cache' ),
36
- esc_html( $ui_tab->label )
37
- ) ?>"
38
  >
39
- <?php echo esc_html( $ui_tab->label ); ?>
40
  </span>
41
 
42
  <?php else : ?>
43
 
44
  <a
45
- id="<?php echo esc_attr( $ui_tab->slug ); ?>-tab"
46
- class="nav-tab <?php echo $ui_tab->default ? 'nav-tab-active' : ''; ?>"
47
- data-toggle="<?php echo esc_attr( $ui_tab->slug ); ?>"
48
- href="#<?php echo esc_attr( $ui_tab->slug ); ?>"
49
  >
50
- <?php echo esc_html( $ui_tab->label ); ?>
51
  </a>
52
 
53
  <?php endif; ?>
@@ -56,11 +52,11 @@ defined( '\\ABSPATH' ) || exit;
56
 
57
  <div class="tab-content">
58
  <?php foreach ( UI::get_tabs() as $ui_tab ) : ?>
59
- <?php if ( ! $ui_tab->disabled ) : ?>
60
- <div id="<?php echo esc_attr( $ui_tab->slug ); ?>-pane"
61
- class="tab-pane tab-pane-<?php echo esc_attr( $ui_tab->slug ); ?> <?php echo $ui_tab->default ? 'active' : ''; ?>"
62
  >
63
- <?php include $ui_tab->file; ?>
64
  </div>
65
  <?php endif; ?>
66
  <?php endforeach; ?>
26
 
27
  <h2 class="nav-tab-wrapper">
28
  <?php foreach ( UI::get_tabs() as $ui_tab ) : ?>
29
+ <?php if ( $ui_tab->is_disabled() ) : ?>
30
 
31
  <span
32
+ class="<?php echo esc_attr( $ui_tab->nav_classes() ); ?>"
33
+ title="<?php echo esc_attr( $ui_tab->disabled_notice() ); ?>"
 
 
 
 
34
  >
35
+ <?php echo esc_html( $ui_tab->label() ); ?>
36
  </span>
37
 
38
  <?php else : ?>
39
 
40
  <a
41
+ id="<?php echo esc_attr( $ui_tab->nav_id() ); ?>"
42
+ class="<?php echo esc_attr( $ui_tab->nav_classes() ); ?>"
43
+ data-toggle="<?php echo esc_attr( $ui_tab->slug() ); ?>"
44
+ href="#<?php echo esc_attr( $ui_tab->slug() ); ?>"
45
  >
46
+ <?php echo esc_html( $ui_tab->label() ); ?>
47
  </a>
48
 
49
  <?php endif; ?>
52
 
53
  <div class="tab-content">
54
  <?php foreach ( UI::get_tabs() as $ui_tab ) : ?>
55
+ <?php if ( ! $ui_tab->is_disabled() ) : ?>
56
+ <div id="<?php echo esc_attr( $ui_tab->id() ); ?>"
57
+ class="<?php echo esc_attr( $ui_tab->classes() ); ?>"
58
  >
59
+ <?php $ui_tab->display(); ?>
60
  </div>
61
  <?php endif; ?>
62
  <?php endforeach; ?>
includes/ui/tabs/diagnostics.php CHANGED
@@ -7,8 +7,6 @@
7
 
8
  defined( '\\ABSPATH' ) || exit;
9
 
10
- $plugin = $this;
11
-
12
  ?>
13
 
14
  <p>
7
 
8
  defined( '\\ABSPATH' ) || exit;
9
 
 
 
10
  ?>
11
 
12
  <p>
includes/ui/tabs/overview.php CHANGED
@@ -7,14 +7,12 @@
7
 
8
  defined( '\\ABSPATH' ) || exit;
9
 
10
- $plugin = redis_object_cache();
 
 
 
11
 
12
- $redis_client = $plugin->get_redis_client_name();
13
- $redis_prefix = $plugin->get_redis_prefix();
14
- $redis_maxttl = $plugin->get_redis_maxttl();
15
- $redis_version = $plugin->get_redis_version();
16
-
17
- $diagnostics = $plugin->get_diagnostics();
18
 
19
  ?>
20
 
@@ -37,14 +35,15 @@ $diagnostics = $plugin->get_diagnostics();
37
  <th><?php esc_html_e( 'Drop-in:', 'redis-cache' ); ?></th>
38
  <td>
39
  <code>
40
- <?php if ( ! $plugin->object_cache_dropin_exists() ) : ?>
41
  <?php esc_html_e( 'Not installed', 'redis-cache' ); ?>
42
- <?php elseif ( $plugin->object_cache_dropin_outdated() ) : ?>
43
  <?php esc_html_e( 'Outdated', 'redis-cache' ); ?>
44
  <?php else : ?>
45
- <?php $plugin->validate_object_cache_dropin()
46
- ? esc_html_e( 'Valid', 'redis-cache' )
47
- : esc_html_e( 'Invalid', 'redis-cache' );
 
48
  ?>
49
  <?php endif; ?>
50
  </code>
@@ -94,7 +93,7 @@ $diagnostics = $plugin->get_diagnostics();
94
 
95
  <tr>
96
  <th><?php esc_html_e( 'Status:', 'redis-cache' ); ?></th>
97
- <td><code><?php echo esc_html( $plugin->get_status() ); ?></code></td>
98
  </tr>
99
 
100
  <?php if ( ! empty( $diagnostics['host'] ) ) : ?>
@@ -161,7 +160,7 @@ $diagnostics = $plugin->get_diagnostics();
161
  <tr>
162
  <th><?php esc_html_e( 'Password:', 'redis-cache' ); ?></th>
163
  <td>
164
- <code><?php echo str_repeat( '&#8226;', 8 ); ?></code>
165
  </td>
166
  </tr>
167
  <?php endif; ?>
@@ -235,18 +234,18 @@ $diagnostics = $plugin->get_diagnostics();
235
 
236
  <p class="submit">
237
 
238
- <?php if ( $plugin->get_redis_status() ) : ?>
239
- <a href="<?php echo esc_attr( $plugin->action_link( 'flush-cache' ) ); ?>" class="button button-primary button-large">
240
  <?php esc_html_e( 'Flush Cache', 'redis-cache' ); ?>
241
  </a> &nbsp;
242
  <?php endif; ?>
243
 
244
- <?php if ( $plugin->validate_object_cache_dropin() ) : ?>
245
- <a href="<?php echo esc_attr( $plugin->action_link( 'disable-cache' ) ); ?>" class="button button-secondary button-large">
246
  <?php esc_html_e( 'Disable Object Cache', 'redis-cache' ); ?>
247
  </a>
248
  <?php else : ?>
249
- <a href="<?php echo esc_attr( $plugin->action_link( 'enable-cache' ) ); ?>" class="button button-primary button-large">
250
  <?php esc_html_e( 'Enable Object Cache', 'redis-cache' ); ?>
251
  </a>
252
  <?php endif; ?>
7
 
8
  defined( '\\ABSPATH' ) || exit;
9
 
10
+ $redis_client = $roc->get_redis_client_name();
11
+ $redis_prefix = $roc->get_redis_prefix();
12
+ $redis_maxttl = $roc->get_redis_maxttl();
13
+ $redis_version = $roc->get_redis_version();
14
 
15
+ $diagnostics = $roc->get_diagnostics();
 
 
 
 
 
16
 
17
  ?>
18
 
35
  <th><?php esc_html_e( 'Drop-in:', 'redis-cache' ); ?></th>
36
  <td>
37
  <code>
38
+ <?php if ( ! $roc->object_cache_dropin_exists() ) : ?>
39
  <?php esc_html_e( 'Not installed', 'redis-cache' ); ?>
40
+ <?php elseif ( $roc->object_cache_dropin_outdated() ) : ?>
41
  <?php esc_html_e( 'Outdated', 'redis-cache' ); ?>
42
  <?php else : ?>
43
+ <?php
44
+ $roc->validate_object_cache_dropin()
45
+ ? esc_html_e( 'Valid', 'redis-cache' )
46
+ : esc_html_e( 'Invalid', 'redis-cache' );
47
  ?>
48
  <?php endif; ?>
49
  </code>
93
 
94
  <tr>
95
  <th><?php esc_html_e( 'Status:', 'redis-cache' ); ?></th>
96
+ <td><code><?php echo esc_html( $roc->get_status() ); ?></code></td>
97
  </tr>
98
 
99
  <?php if ( ! empty( $diagnostics['host'] ) ) : ?>
160
  <tr>
161
  <th><?php esc_html_e( 'Password:', 'redis-cache' ); ?></th>
162
  <td>
163
+ <code>••••••••</code>
164
  </td>
165
  </tr>
166
  <?php endif; ?>
234
 
235
  <p class="submit">
236
 
237
+ <?php if ( $roc->get_redis_status() ) : ?>
238
+ <a href="<?php echo esc_attr( $roc->action_link( 'flush-cache' ) ); ?>" class="button button-primary button-large">
239
  <?php esc_html_e( 'Flush Cache', 'redis-cache' ); ?>
240
  </a> &nbsp;
241
  <?php endif; ?>
242
 
243
+ <?php if ( $roc->validate_object_cache_dropin() ) : ?>
244
+ <a href="<?php echo esc_attr( $roc->action_link( 'disable-cache' ) ); ?>" class="button button-secondary button-large">
245
  <?php esc_html_e( 'Disable Object Cache', 'redis-cache' ); ?>
246
  </a>
247
  <?php else : ?>
248
+ <a href="<?php echo esc_attr( $roc->action_link( 'enable-cache' ) ); ?>" class="button button-primary button-large">
249
  <?php esc_html_e( 'Enable Object Cache', 'redis-cache' ); ?>
250
  </a>
251
  <?php endif; ?>
languages/redis-cache.pot CHANGED
@@ -2,21 +2,21 @@
2
  # This file is distributed under the GPLv3.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Redis Object Cache 2.0.9\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/redis-cache\n"
7
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
  "Language-Team: LANGUAGE <LL@li.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2020-08-12T20:22:36+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: redis-cache\n"
16
 
17
  #. Plugin Name of the plugin
18
- #: includes/class-plugin.php:104
19
- #: includes/class-plugin.php:161
20
  #: includes/ui/settings.php:18
21
  msgid "Redis Object Cache"
22
  msgstr ""
@@ -37,198 +37,198 @@ msgstr ""
37
  msgid "https://objectcache.pro"
38
  msgstr ""
39
 
40
- #: includes/class-plugin.php:105
41
  msgid "Redis"
42
  msgstr ""
43
 
44
- #: includes/class-plugin.php:135
45
- #: includes/ui/tabs/overview.php:22
46
  msgid "Overview"
47
  msgstr ""
48
 
49
- #: includes/class-plugin.php:141
50
  msgid "Metrics"
51
  msgstr ""
52
 
53
- #: includes/class-plugin.php:147
54
  msgid "Diagnostics"
55
  msgstr ""
56
 
57
- #: includes/class-plugin.php:173
58
  msgid "Settings"
59
  msgstr ""
60
 
61
- #: includes/class-plugin.php:233
62
  #: includes/ui/tabs/metrics.php:17
63
  #: includes/ui/widget.php:16
64
  msgid "Time"
65
  msgstr ""
66
 
67
- #: includes/class-plugin.php:234
68
  #: includes/ui/tabs/metrics.php:22
69
  #: includes/ui/widget.php:21
70
  msgid "Bytes"
71
  msgstr ""
72
 
73
- #: includes/class-plugin.php:235
74
  #: includes/ui/tabs/metrics.php:27
75
  #: includes/ui/widget.php:26
76
  msgid "Ratio"
77
  msgstr ""
78
 
79
- #: includes/class-plugin.php:236
80
  #: includes/ui/tabs/metrics.php:32
81
  #: includes/ui/widget.php:31
82
  msgid "Calls"
83
  msgstr ""
84
 
85
- #: includes/class-plugin.php:237
86
  msgid "Not enough data collected, yet."
87
  msgstr ""
88
 
89
- #: includes/class-plugin.php:238
90
  msgid "Enable object cache to collect data."
91
  msgstr ""
92
 
93
- #: includes/class-plugin.php:340
94
- #: includes/class-qm-collector.php:48
95
  msgid "Disabled"
96
  msgstr ""
97
 
98
- #: includes/class-plugin.php:344
99
  msgid "Drop-in not installed"
100
  msgstr ""
101
 
102
- #: includes/class-plugin.php:348
103
  msgid "Drop-in is invalid"
104
  msgstr ""
105
 
106
- #: includes/class-plugin.php:353
107
  msgid "Connected"
108
  msgstr ""
109
 
110
- #: includes/class-plugin.php:354
111
  msgid "Not connected"
112
  msgstr ""
113
 
114
- #: includes/class-plugin.php:357
115
- #: includes/ui/tabs/overview.php:230
116
  msgid "Unknown"
117
  msgstr ""
118
 
119
- #. translators: %s = Action link to update the drop-in
120
- #: includes/class-plugin.php:440
121
  msgid "The Redis object cache drop-in is outdated. Please <a href=\"%s\">update the drop-in</a>."
122
  msgstr ""
123
 
124
- #. translators: %s = Action link to update the drop-in
125
- #: includes/class-plugin.php:444
126
  msgid "A foreign object cache drop-in was found. To use Redis for object caching, please <a href=\"%s\">enable the drop-in</a>."
127
  msgstr ""
128
 
129
- #: includes/class-plugin.php:474
130
  msgid "Object cache flushed."
131
  msgstr ""
132
 
133
- #: includes/class-plugin.php:480
134
  msgid "Object cache could not be flushed."
135
  msgstr ""
136
 
137
- #: includes/class-plugin.php:502
138
  #: includes/cli/class-commands.php:74
139
  msgid "Object cache enabled."
140
  msgstr ""
141
 
142
- #: includes/class-plugin.php:508
143
  #: includes/cli/class-commands.php:76
144
  msgid "Object cache could not be enabled."
145
  msgstr ""
146
 
147
- #: includes/class-plugin.php:521
148
  #: includes/cli/class-commands.php:113
149
  msgid "Object cache disabled."
150
  msgstr ""
151
 
152
- #: includes/class-plugin.php:526
153
  #: includes/cli/class-commands.php:115
154
  msgid "Object cache could not be disabled."
155
  msgstr ""
156
 
157
- #: includes/class-plugin.php:545
158
  #: includes/cli/class-commands.php:147
159
  msgid "Updated object cache drop-in and enabled Redis object cache."
160
  msgstr ""
161
 
162
- #: includes/class-plugin.php:551
163
  #: includes/cli/class-commands.php:149
164
  msgid "Object cache drop-in could not be updated."
165
  msgstr ""
166
 
167
- #: includes/class-plugin.php:604
168
  msgid "Object Cache Pro is out!"
169
  msgstr ""
170
 
171
- #. translators: %s = Link to the plugin setting screen
172
- #: includes/class-plugin.php:607
173
  msgid "A <u>business class</u> object cache backend. Truly reliable, highly-optimized and fully customizable, with a <u>dedicated engineer</u> when you most need it. <a href=\"%s\">Learn more »</a>"
174
  msgstr ""
175
 
176
- #: includes/class-plugin.php:638
177
  msgid "Object Cache Pro + WooCommerce = ❤️"
178
  msgstr ""
179
 
180
- #. translators: %s = Link to the plugin's settings screen
181
- #: includes/class-plugin.php:641
182
  msgid "Object Cache Pro is a <u>business class</u> object cache that’s highly-optimized for WooCommerce to provide true reliability, peace of mind and faster load times for your store. <a style=\"color: #bb77ae;\" href=\"%s\">Learn more »</a>"
183
  msgstr ""
184
 
185
  #. translators: %1$d = number of objects. %2$s = human-readable size of cache. %3$s = name of the used client.
186
- #: includes/class-plugin.php:759
187
  msgid "Retrieved %1$d objects (%2$s) from Redis using %3$s."
188
  msgstr ""
189
 
190
- #: includes/class-plugin.php:799
191
  msgid "Could not initialize filesystem."
192
  msgstr ""
193
 
194
- #: includes/class-plugin.php:806
195
  msgid "Object cache file doesn’t exist."
196
  msgstr ""
197
 
198
- #: includes/class-plugin.php:811
199
  msgid "Test file exists, but couldn’t be deleted."
200
  msgstr ""
201
 
202
- #: includes/class-plugin.php:816
203
  msgid "Failed to copy test file."
204
  msgstr ""
205
 
206
- #: includes/class-plugin.php:820
207
  msgid "Copied test file doesn’t exist."
208
  msgstr ""
209
 
210
- #: includes/class-plugin.php:826
211
  msgid "Couldn’t verify test file contents."
212
  msgstr ""
213
 
214
- #: includes/class-plugin.php:830
215
  msgid "Copied test file couldn’t be deleted."
216
  msgstr ""
217
 
218
- #: includes/class-qm-collector.php:19
219
  msgid "Object Cache"
220
  msgstr ""
221
 
222
- #: includes/class-qm-collector.php:48
223
- #: includes/ui/tabs/overview.php:58
224
  msgid "Yes"
225
  msgstr ""
226
 
227
- #: includes/class-qm-output.php:72
228
  msgid "The Redis Object Cache drop-in is not installed. Use WP CLI or go to \"Settings -> Redis\" to enable drop-in."
229
  msgstr ""
230
 
231
- #: includes/class-qm-output.php:80
232
  msgid "WordPress is using a foreign object cache drop-in and Redis Object Cache is not being used. Use WP CLI or go to \"Settings -> Redis\" to enable drop-in."
233
  msgstr ""
234
 
@@ -245,6 +245,11 @@ msgstr ""
245
  msgid "No object cache drop-in found."
246
  msgstr ""
247
 
 
 
 
 
 
248
  #: includes/ui/query-monitor.php:15
249
  msgid "Status"
250
  msgstr ""
@@ -285,152 +290,147 @@ msgstr ""
285
  msgid "Metadata"
286
  msgstr ""
287
 
288
- #. translators: %s = Tab label
289
- #: includes/ui/settings.php:35
290
- msgid "%s are disabled for this site."
291
- msgstr ""
292
-
293
- #: includes/ui/settings.php:74
294
  msgid "Resources"
295
  msgstr ""
296
 
297
- #: includes/ui/settings.php:112
298
  msgid "Your site meets the system requirements for the Pro version."
299
  msgstr ""
300
 
301
- #: includes/ui/settings.php:119
302
  msgid "Your site <i>does not</i> meet the requirements for the Pro version:"
303
  msgstr ""
304
 
305
  #. translators: %s = PHP Version.
306
- #: includes/ui/settings.php:128
307
  msgid "The current version of PHP (%s) is too old. PHP 7.0 or newer is required."
308
  msgstr ""
309
 
310
- #: includes/ui/settings.php:137
311
  msgid "The PhpRedis extension is not installed."
312
  msgstr ""
313
 
314
  #. translators: %s = Version of the PhpRedis extension.
315
- #: includes/ui/settings.php:144
316
  msgid "The current version of the PhpRedis extension (%s) is too old. PhpRedis 3.1.1 or newer is required."
317
  msgstr ""
318
 
319
- #: includes/ui/tabs/overview.php:29
320
  msgid "Client:"
321
  msgstr ""
322
 
323
- #: includes/ui/tabs/overview.php:37
324
  msgid "Drop-in:"
325
  msgstr ""
326
 
327
- #: includes/ui/tabs/overview.php:41
328
  msgid "Not installed"
329
  msgstr ""
330
 
331
- #: includes/ui/tabs/overview.php:43
332
  msgid "Outdated"
333
  msgstr ""
334
 
335
- #: includes/ui/tabs/overview.php:46
336
  msgid "Valid"
337
  msgstr ""
338
 
339
- #: includes/ui/tabs/overview.php:47
340
  msgid "Invalid"
341
  msgstr ""
342
 
343
- #: includes/ui/tabs/overview.php:56
344
  msgid "Disabled:"
345
  msgstr ""
346
 
347
- #: includes/ui/tabs/overview.php:65
348
  msgid "Key Prefix:"
349
  msgstr ""
350
 
351
- #: includes/ui/tabs/overview.php:74
352
  msgid "Max. TTL:"
353
  msgstr ""
354
 
355
- #: includes/ui/tabs/overview.php:80
356
  msgid "This doesn’t appear to be a valid number."
357
  msgstr ""
358
 
359
- #: includes/ui/tabs/overview.php:90
360
  msgid "Connection"
361
  msgstr ""
362
 
363
- #: includes/ui/tabs/overview.php:96
364
  msgid "Status:"
365
  msgstr ""
366
 
367
- #: includes/ui/tabs/overview.php:102
368
  msgid "Host:"
369
  msgstr ""
370
 
371
- #: includes/ui/tabs/overview.php:109
372
  msgid "Cluster:"
373
  msgstr ""
374
 
375
- #: includes/ui/tabs/overview.php:122
376
  msgid "Shards:"
377
  msgstr ""
378
 
379
- #: includes/ui/tabs/overview.php:135
380
  msgid "Servers:"
381
  msgstr ""
382
 
383
- #: includes/ui/tabs/overview.php:148
384
  msgid "Port:"
385
  msgstr ""
386
 
387
- #: includes/ui/tabs/overview.php:155
388
  msgid "Username:"
389
  msgstr ""
390
 
391
- #: includes/ui/tabs/overview.php:162
392
  msgid "Password:"
393
  msgstr ""
394
 
395
- #: includes/ui/tabs/overview.php:171
396
  msgid "Database:"
397
  msgstr ""
398
 
399
- #: includes/ui/tabs/overview.php:178
400
  msgid "Connection Timeout:"
401
  msgstr ""
402
 
403
  #. translators: %s = Redis connection/read timeout in seconds.
404
- #: includes/ui/tabs/overview.php:184
405
- #: includes/ui/tabs/overview.php:201
406
  msgid "%ss"
407
  msgstr ""
408
 
409
- #: includes/ui/tabs/overview.php:195
410
  msgid "Read Timeout:"
411
  msgstr ""
412
 
413
- #: includes/ui/tabs/overview.php:212
414
  msgid "Retry Interval:"
415
  msgstr ""
416
 
417
  #. translators: %s = Redis retry interval in milliseconds.
418
- #: includes/ui/tabs/overview.php:218
419
  msgid "%sms"
420
  msgstr ""
421
 
422
- #: includes/ui/tabs/overview.php:229
423
  msgid "Redis Version:"
424
  msgstr ""
425
 
426
- #: includes/ui/tabs/overview.php:240
427
  msgid "Flush Cache"
428
  msgstr ""
429
 
430
- #: includes/ui/tabs/overview.php:246
431
  msgid "Disable Object Cache"
432
  msgstr ""
433
 
434
- #: includes/ui/tabs/overview.php:250
435
  msgid "Enable Object Cache"
436
  msgstr ""
2
  # This file is distributed under the GPLv3.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Redis Object Cache 2.0.12\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/redis-cache\n"
7
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
  "Language-Team: LANGUAGE <LL@li.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2020-08-19T14:37:52+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: redis-cache\n"
16
 
17
  #. Plugin Name of the plugin
18
+ #: includes/class-plugin.php:134
19
+ #: includes/class-plugin.php:202
20
  #: includes/ui/settings.php:18
21
  msgid "Redis Object Cache"
22
  msgstr ""
37
  msgid "https://objectcache.pro"
38
  msgstr ""
39
 
40
+ #: includes/class-plugin.php:135
41
  msgid "Redis"
42
  msgstr ""
43
 
44
+ #: includes/class-plugin.php:171
45
+ #: includes/ui/tabs/overview.php:20
46
  msgid "Overview"
47
  msgstr ""
48
 
49
+ #: includes/class-plugin.php:177
50
  msgid "Metrics"
51
  msgstr ""
52
 
53
+ #: includes/class-plugin.php:183
54
  msgid "Diagnostics"
55
  msgstr ""
56
 
57
+ #: includes/class-plugin.php:224
58
  msgid "Settings"
59
  msgstr ""
60
 
61
+ #: includes/class-plugin.php:295
62
  #: includes/ui/tabs/metrics.php:17
63
  #: includes/ui/widget.php:16
64
  msgid "Time"
65
  msgstr ""
66
 
67
+ #: includes/class-plugin.php:296
68
  #: includes/ui/tabs/metrics.php:22
69
  #: includes/ui/widget.php:21
70
  msgid "Bytes"
71
  msgstr ""
72
 
73
+ #: includes/class-plugin.php:297
74
  #: includes/ui/tabs/metrics.php:27
75
  #: includes/ui/widget.php:26
76
  msgid "Ratio"
77
  msgstr ""
78
 
79
+ #: includes/class-plugin.php:298
80
  #: includes/ui/tabs/metrics.php:32
81
  #: includes/ui/widget.php:31
82
  msgid "Calls"
83
  msgstr ""
84
 
85
+ #: includes/class-plugin.php:299
86
  msgid "Not enough data collected, yet."
87
  msgstr ""
88
 
89
+ #: includes/class-plugin.php:300
90
  msgid "Enable object cache to collect data."
91
  msgstr ""
92
 
93
+ #: includes/class-plugin.php:440
94
+ #: includes/class-qm-collector.php:66
95
  msgid "Disabled"
96
  msgstr ""
97
 
98
+ #: includes/class-plugin.php:444
99
  msgid "Drop-in not installed"
100
  msgstr ""
101
 
102
+ #: includes/class-plugin.php:448
103
  msgid "Drop-in is invalid"
104
  msgstr ""
105
 
106
+ #: includes/class-plugin.php:453
107
  msgid "Connected"
108
  msgstr ""
109
 
110
+ #: includes/class-plugin.php:454
111
  msgid "Not connected"
112
  msgstr ""
113
 
114
+ #: includes/class-plugin.php:457
115
+ #: includes/ui/tabs/overview.php:229
116
  msgid "Unknown"
117
  msgstr ""
118
 
119
+ #. translators: %s = Action link to update the drop-in.
120
+ #: includes/class-plugin.php:571
121
  msgid "The Redis object cache drop-in is outdated. Please <a href=\"%s\">update the drop-in</a>."
122
  msgstr ""
123
 
124
+ #. translators: %s = Action link to update the drop-in.
125
+ #: includes/class-plugin.php:575
126
  msgid "A foreign object cache drop-in was found. To use Redis for object caching, please <a href=\"%s\">enable the drop-in</a>."
127
  msgstr ""
128
 
129
+ #: includes/class-plugin.php:611
130
  msgid "Object cache flushed."
131
  msgstr ""
132
 
133
+ #: includes/class-plugin.php:617
134
  msgid "Object cache could not be flushed."
135
  msgstr ""
136
 
137
+ #: includes/class-plugin.php:639
138
  #: includes/cli/class-commands.php:74
139
  msgid "Object cache enabled."
140
  msgstr ""
141
 
142
+ #: includes/class-plugin.php:645
143
  #: includes/cli/class-commands.php:76
144
  msgid "Object cache could not be enabled."
145
  msgstr ""
146
 
147
+ #: includes/class-plugin.php:659
148
  #: includes/cli/class-commands.php:113
149
  msgid "Object cache disabled."
150
  msgstr ""
151
 
152
+ #: includes/class-plugin.php:665
153
  #: includes/cli/class-commands.php:115
154
  msgid "Object cache could not be disabled."
155
  msgstr ""
156
 
157
+ #: includes/class-plugin.php:684
158
  #: includes/cli/class-commands.php:147
159
  msgid "Updated object cache drop-in and enabled Redis object cache."
160
  msgstr ""
161
 
162
+ #: includes/class-plugin.php:690
163
  #: includes/cli/class-commands.php:149
164
  msgid "Object cache drop-in could not be updated."
165
  msgstr ""
166
 
167
+ #: includes/class-plugin.php:757
168
  msgid "Object Cache Pro is out!"
169
  msgstr ""
170
 
171
+ #. translators: %s = Link to the plugin setting screen.
172
+ #: includes/class-plugin.php:760
173
  msgid "A <u>business class</u> object cache backend. Truly reliable, highly-optimized and fully customizable, with a <u>dedicated engineer</u> when you most need it. <a href=\"%s\">Learn more »</a>"
174
  msgstr ""
175
 
176
+ #: includes/class-plugin.php:797
177
  msgid "Object Cache Pro + WooCommerce = ❤️"
178
  msgstr ""
179
 
180
+ #. translators: %s = Link to the plugin's settings screen.
181
+ #: includes/class-plugin.php:800
182
  msgid "Object Cache Pro is a <u>business class</u> object cache that’s highly-optimized for WooCommerce to provide true reliability, peace of mind and faster load times for your store. <a style=\"color: #bb77ae;\" href=\"%s\">Learn more »</a>"
183
  msgstr ""
184
 
185
  #. translators: %1$d = number of objects. %2$s = human-readable size of cache. %3$s = name of the used client.
186
+ #: includes/class-plugin.php:939
187
  msgid "Retrieved %1$d objects (%2$s) from Redis using %3$s."
188
  msgstr ""
189
 
190
+ #: includes/class-plugin.php:996
191
  msgid "Could not initialize filesystem."
192
  msgstr ""
193
 
194
+ #: includes/class-plugin.php:1003
195
  msgid "Object cache file doesn’t exist."
196
  msgstr ""
197
 
198
+ #: includes/class-plugin.php:1008
199
  msgid "Test file exists, but couldn’t be deleted."
200
  msgstr ""
201
 
202
+ #: includes/class-plugin.php:1013
203
  msgid "Failed to copy test file."
204
  msgstr ""
205
 
206
+ #: includes/class-plugin.php:1017
207
  msgid "Copied test file doesn’t exist."
208
  msgstr ""
209
 
210
+ #: includes/class-plugin.php:1023
211
  msgid "Couldn’t verify test file contents."
212
  msgstr ""
213
 
214
+ #: includes/class-plugin.php:1027
215
  msgid "Copied test file couldn’t be deleted."
216
  msgstr ""
217
 
218
+ #: includes/class-qm-collector.php:32
219
  msgid "Object Cache"
220
  msgstr ""
221
 
222
+ #: includes/class-qm-collector.php:66
223
+ #: includes/ui/tabs/overview.php:57
224
  msgid "Yes"
225
  msgstr ""
226
 
227
+ #: includes/class-qm-output.php:102
228
  msgid "The Redis Object Cache drop-in is not installed. Use WP CLI or go to \"Settings -> Redis\" to enable drop-in."
229
  msgstr ""
230
 
231
+ #: includes/class-qm-output.php:113
232
  msgid "WordPress is using a foreign object cache drop-in and Redis Object Cache is not being used. Use WP CLI or go to \"Settings -> Redis\" to enable drop-in."
233
  msgstr ""
234
 
245
  msgid "No object cache drop-in found."
246
  msgstr ""
247
 
248
+ #. translators: %s = Tab label.
249
+ #: includes/ui/class-tab.php:152
250
+ msgid "%s are disabled for this site."
251
+ msgstr ""
252
+
253
  #: includes/ui/query-monitor.php:15
254
  msgid "Status"
255
  msgstr ""
290
  msgid "Metadata"
291
  msgstr ""
292
 
293
+ #: includes/ui/settings.php:70
 
 
 
 
 
294
  msgid "Resources"
295
  msgstr ""
296
 
297
+ #: includes/ui/settings.php:108
298
  msgid "Your site meets the system requirements for the Pro version."
299
  msgstr ""
300
 
301
+ #: includes/ui/settings.php:115
302
  msgid "Your site <i>does not</i> meet the requirements for the Pro version:"
303
  msgstr ""
304
 
305
  #. translators: %s = PHP Version.
306
+ #: includes/ui/settings.php:124
307
  msgid "The current version of PHP (%s) is too old. PHP 7.0 or newer is required."
308
  msgstr ""
309
 
310
+ #: includes/ui/settings.php:133
311
  msgid "The PhpRedis extension is not installed."
312
  msgstr ""
313
 
314
  #. translators: %s = Version of the PhpRedis extension.
315
+ #: includes/ui/settings.php:140
316
  msgid "The current version of the PhpRedis extension (%s) is too old. PhpRedis 3.1.1 or newer is required."
317
  msgstr ""
318
 
319
+ #: includes/ui/tabs/overview.php:27
320
  msgid "Client:"
321
  msgstr ""
322
 
323
+ #: includes/ui/tabs/overview.php:35
324
  msgid "Drop-in:"
325
  msgstr ""
326
 
327
+ #: includes/ui/tabs/overview.php:39
328
  msgid "Not installed"
329
  msgstr ""
330
 
331
+ #: includes/ui/tabs/overview.php:41
332
  msgid "Outdated"
333
  msgstr ""
334
 
335
+ #: includes/ui/tabs/overview.php:45
336
  msgid "Valid"
337
  msgstr ""
338
 
339
+ #: includes/ui/tabs/overview.php:46
340
  msgid "Invalid"
341
  msgstr ""
342
 
343
+ #: includes/ui/tabs/overview.php:55
344
  msgid "Disabled:"
345
  msgstr ""
346
 
347
+ #: includes/ui/tabs/overview.php:64
348
  msgid "Key Prefix:"
349
  msgstr ""
350
 
351
+ #: includes/ui/tabs/overview.php:73
352
  msgid "Max. TTL:"
353
  msgstr ""
354
 
355
+ #: includes/ui/tabs/overview.php:79
356
  msgid "This doesn’t appear to be a valid number."
357
  msgstr ""
358
 
359
+ #: includes/ui/tabs/overview.php:89
360
  msgid "Connection"
361
  msgstr ""
362
 
363
+ #: includes/ui/tabs/overview.php:95
364
  msgid "Status:"
365
  msgstr ""
366
 
367
+ #: includes/ui/tabs/overview.php:101
368
  msgid "Host:"
369
  msgstr ""
370
 
371
+ #: includes/ui/tabs/overview.php:108
372
  msgid "Cluster:"
373
  msgstr ""
374
 
375
+ #: includes/ui/tabs/overview.php:121
376
  msgid "Shards:"
377
  msgstr ""
378
 
379
+ #: includes/ui/tabs/overview.php:134
380
  msgid "Servers:"
381
  msgstr ""
382
 
383
+ #: includes/ui/tabs/overview.php:147
384
  msgid "Port:"
385
  msgstr ""
386
 
387
+ #: includes/ui/tabs/overview.php:154
388
  msgid "Username:"
389
  msgstr ""
390
 
391
+ #: includes/ui/tabs/overview.php:161
392
  msgid "Password:"
393
  msgstr ""
394
 
395
+ #: includes/ui/tabs/overview.php:170
396
  msgid "Database:"
397
  msgstr ""
398
 
399
+ #: includes/ui/tabs/overview.php:177
400
  msgid "Connection Timeout:"
401
  msgstr ""
402
 
403
  #. translators: %s = Redis connection/read timeout in seconds.
404
+ #: includes/ui/tabs/overview.php:183
405
+ #: includes/ui/tabs/overview.php:200
406
  msgid "%ss"
407
  msgstr ""
408
 
409
+ #: includes/ui/tabs/overview.php:194
410
  msgid "Read Timeout:"
411
  msgstr ""
412
 
413
+ #: includes/ui/tabs/overview.php:211
414
  msgid "Retry Interval:"
415
  msgstr ""
416
 
417
  #. translators: %s = Redis retry interval in milliseconds.
418
+ #: includes/ui/tabs/overview.php:217
419
  msgid "%sms"
420
  msgstr ""
421
 
422
+ #: includes/ui/tabs/overview.php:228
423
  msgid "Redis Version:"
424
  msgstr ""
425
 
426
+ #: includes/ui/tabs/overview.php:239
427
  msgid "Flush Cache"
428
  msgstr ""
429
 
430
+ #: includes/ui/tabs/overview.php:245
431
  msgid "Disable Object Cache"
432
  msgstr ""
433
 
434
+ #: includes/ui/tabs/overview.php:249
435
  msgid "Enable Object Cache"
436
  msgstr ""
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: redis, predis, phpredis, credis, hhvm, pecl, caching, cache, object cache,
5
  Requires at least: 3.3
6
  Tested up to: 5.5
7
  Requires PHP: 5.6
8
- Stable tag: 2.0.11
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
11
 
@@ -83,6 +83,12 @@ To see a list of all available WP-CLI commands, please see the [WP CLI commands
83
 
84
  == Changelog ==
85
 
 
 
 
 
 
 
86
  = 2.0.11 =
87
 
88
  - Fixed an issue in `wp_cache_get_multiple()` when using Predis
@@ -444,6 +450,6 @@ Since Predis isn't maintained any longer, it's highly recommended to switch over
444
 
445
  == Upgrade Notice ==
446
 
447
- = 2.0.11 =
448
 
449
  Version 2.0 is a significant rewrite of the plugin. Please read the v2.0.0 release notes.
5
  Requires at least: 3.3
6
  Tested up to: 5.5
7
  Requires PHP: 5.6
8
+ Stable tag: 2.0.12
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
11
 
83
 
84
  == Changelog ==
85
 
86
+ = 2.0.12 =
87
+
88
+ - Fixed bytes metrics calculation
89
+ - Fixed an issue with non-standard Predis configurations
90
+ - Improve WordPress Coding Standards
91
+
92
  = 2.0.11 =
93
 
94
  - Fixed an issue in `wp_cache_get_multiple()` when using Predis
450
 
451
  == Upgrade Notice ==
452
 
453
+ = 2.0.12 =
454
 
455
  Version 2.0 is a significant rewrite of the plugin. Please read the v2.0.0 release notes.
redis-cache.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Redis Object Cache
4
  * Plugin URI: https://wordpress.org/plugins/redis-cache/
5
  * Description: A persistent object cache backend powered by Redis. Supports Predis, PhpRedis, Credis, HHVM, replication, clustering and WP-CLI.
6
- * Version: 2.0.11
7
  * Text Domain: redis-cache
8
  * Domain Path: /languages
9
  * Network: true
3
  * Plugin Name: Redis Object Cache
4
  * Plugin URI: https://wordpress.org/plugins/redis-cache/
5
  * Description: A persistent object cache backend powered by Redis. Supports Predis, PhpRedis, Credis, HHVM, replication, clustering and WP-CLI.
6
+ * Version: 2.0.12
7
  * Text Domain: redis-cache
8
  * Domain Path: /languages
9
  * Network: true