Health Check - Version 1.2.0

Version Description

Download this release

Release Info

Developer Clorith
Plugin Icon 128x128 Health Check
Version 1.2.0
Comparing to
See all releases

Code changes from version 1.1.2 to 1.2.0

assets/javascript/health-check.js CHANGED
@@ -90,57 +90,111 @@ jQuery( document ).ready(function( $ ) {
90
  });
91
  });
92
 
93
- /* global HealthCheck, ajaxurl, healthCheckFailureModal */
94
- jQuery( document ).ready(function( $ ) {
95
- $( '#loopback-no-plugins' ).click(function( e ) {
96
- var $trigger = $( this ),
97
- $parent = $( this ).closest( 'td' ),
98
- data = {
99
- action: 'health-check-loopback-no-plugins'
100
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
- e.preventDefault();
103
-
104
- $( this ).html( '<span class="spinner" style="visibility: visible;"></span> ' + HealthCheck.string.please_wait );
105
-
106
- $.post(
107
- ajaxurl,
108
- data,
109
- function( response ) {
110
- $trigger.remove();
111
- if ( true === response.success ) {
112
- $parent.append( response.data.message );
113
- } else {
114
- healthCheckFailureModal( response.data, data.action, $parent );
115
- }
116
- },
117
- 'json'
118
- );
119
- });
120
-
121
- $( '.dashboard_page_health-check' ).on( 'click', '#loopback-individual-plugins', function( e ) {
122
- var $trigger = $( this ),
123
- $parent = $( this ).closest( 'td' ),
124
  data = {
125
- action: 'health-check-loopback-individual-plugins'
 
126
  };
127
 
128
- e.preventDefault();
129
-
130
- $( this ).html( '<span class="spinner" style="visibility: visible;"></span> ' + HealthCheck.string.please_wait );
131
-
132
  $.post(
133
  ajaxurl,
134
  data,
135
  function( response ) {
136
- $trigger.remove();
137
- if ( true === response.success ) {
138
- $parent.append( response.data.message );
139
- } else {
140
- healthCheckFailureModal( response.data, data.action, $parent );
141
- }
142
- },
143
- 'json'
144
  );
145
  });
146
  });
90
  });
91
  });
92
 
93
+ /* global HealthCheck, ajaxurl, healthCheckFailureModal */
94
+ jQuery( document ).ready(function( $ ) {
95
+ function testDefaultTheme() {
96
+ var $parent = $( '.individual-loopback-test-status', '#test-single-no-theme' ),
97
+ data = {
98
+ action: 'health-check-loopback-default-theme'
99
+ };
100
+
101
+ $.post(
102
+ ajaxurl,
103
+ data,
104
+ function( response ) {
105
+ if ( true === response.success ) {
106
+ $parent.html( response.data.message );
107
+ } else {
108
+ healthCheckFailureModal( response.data, data.action, $parent );
109
+ }
110
+ },
111
+ 'json'
112
+ );
113
+ }
114
+
115
+ function testSinglePlugin() {
116
+ var $testLines = $( '.not-tested', '#loopback-individual-plugins-list' );
117
+ var $parentField,
118
+ $testLine,
119
+ data;
120
+
121
+ if ( $testLines.length < 1 ) {
122
+ testDefaultTheme();
123
+ return null;
124
+ }
125
+
126
+ $testLine = $testLines.first();
127
+ data = {
128
+ action: 'health-check-loopback-individual-plugins',
129
+ plugin: $testLine.data( 'test-plugin' )
130
+ };
131
+
132
+ $parentField = $( '.individual-loopback-test-status', $testLine );
133
+
134
+ $parentField.html( HealthCheck.string.running_tests );
135
+
136
+ $.post(
137
+ ajaxurl,
138
+ data,
139
+ function( response ) {
140
+ if ( true === response.success ) {
141
+ $testLine.removeClass( 'not-tested' );
142
+ $parentField.html( response.data.message );
143
+ testSinglePlugin();
144
+ } else {
145
+ healthCheckFailureModal( response.data, data.action, $parentField );
146
+ }
147
+ },
148
+ 'json'
149
+ );
150
+ }
151
+
152
+ $( '.dashboard_page_health-check' ).on( 'click', '#loopback-no-plugins', function( e ) {
153
+ var $trigger = $( this ),
154
+ $parent = $( this ).closest( 'td' ),
155
+ data = {
156
+ action: 'health-check-loopback-no-plugins'
157
+ };
158
+
159
+ e.preventDefault();
160
+
161
+ $( this ).html( '<span class="spinner" style="visibility: visible;"></span> ' + HealthCheck.string.please_wait );
162
+
163
+ $.post(
164
+ ajaxurl,
165
+ data,
166
+ function( response ) {
167
+ $trigger.remove();
168
+ if ( true === response.success ) {
169
+ $parent.append( response.data.message );
170
+ } else {
171
+ healthCheckFailureModal( response.data, data.action, $parent );
172
+ }
173
+ },
174
+ 'json'
175
+ );
176
+ }).on( 'click', '#loopback-individual-plugins', function( e ) {
177
+ e.preventDefault();
178
+
179
+ testSinglePlugin();
180
+ });
181
+ });
182
 
183
+ /* global ajaxurl */
184
+ jQuery( document ).ready(function( $ ) {
185
+ $( '.health-check-site-status-test' ).each( function() {
186
+ var $check = $( this ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  data = {
188
+ action: 'health-check-site-status',
189
+ feature: $( this ).data( 'site-status' )
190
  };
191
 
 
 
 
 
192
  $.post(
193
  ajaxurl,
194
  data,
195
  function( response ) {
196
+ $check.html( response );
197
+ }
 
 
 
 
 
 
198
  );
199
  });
200
  });
assets/mu-plugin/health-check-troubleshooting-mode.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: Health Check Troubleshooting Mode
4
  Description: Conditionally disabled themes or plugins on your site for a given session, used to rule out conflicts during troubleshooting.
5
- Version: 1.4.1
6
  */
7
 
8
  if ( ! defined( 'ABSPATH' ) ) {
@@ -10,9 +10,11 @@ if ( ! defined( 'ABSPATH' ) ) {
10
  }
11
 
12
  class Health_Check_Troubleshooting_MU {
 
13
  private $override_active = true;
14
  private $default_theme = true;
15
  private $active_plugins = array();
 
16
  private $current_theme;
17
  private $current_theme_details;
18
  private $self_fetching_theme = false;
@@ -55,15 +57,18 @@ class Health_Check_Troubleshooting_MU {
55
  add_filter( 'option_active_plugins', array( $this, 'health_check_loopback_test_disable_plugins' ) );
56
  add_filter( 'option_active_sitewide_plugins', array( $this, 'health_check_loopback_test_disable_plugins' ) );
57
 
58
- add_filter( 'stylesheet', array( $this, 'health_check_troubleshoot_theme' ) );
59
- add_filter( 'template', array( $this, 'health_check_troubleshoot_theme' ) );
60
 
61
- add_action( 'admin_notices', array( $this, 'plugin_list_admin_notice' ) );
62
  add_action( 'admin_notices', array( $this, 'prompt_install_default_theme' ) );
63
  add_filter( 'user_has_cap', array( $this, 'remove_plugin_theme_install' ) );
64
 
65
  add_action( 'plugin_action_links', array( $this, 'plugin_actions' ), 50, 4 );
66
 
 
 
 
 
67
  add_action( 'wp_logout', array( $this, 'health_check_troubleshooter_mode_logout' ) );
68
  add_action( 'init', array( $this, 'health_check_troubleshoot_get_captures' ) );
69
 
@@ -75,9 +80,20 @@ class Health_Check_Troubleshooting_MU {
75
  */
76
  add_action( 'activated_plugin', array( $this, 'plugin_activated' ) );
77
 
78
- $this->default_theme = ( 'yes' === get_option( 'health-check-default-theme', 'yes' ) ? true : false );
79
- $this->active_plugins = $this->get_unfiltered_plugin_list();
80
- $this->current_theme = get_option( 'health-check-current-theme', false );
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
 
83
  /**
@@ -154,33 +170,6 @@ class Health_Check_Troubleshooting_MU {
154
  update_option( 'active_plugins', $this->active_plugins );
155
  }
156
 
157
- /**
158
- * Add a notice to the plugins screen.
159
- *
160
- * Make sure users are informed that all plugin actions are
161
- * stripped away when they are troubleshooting.
162
- *
163
- * @return void
164
- */
165
- public function plugin_list_admin_notice() {
166
- if ( ! $this->is_troubleshooting() ) {
167
- return;
168
- }
169
- global $current_screen;
170
-
171
- // Only output our notice on the plugins screen.
172
- if ( 'plugins' !== $current_screen->base ) {
173
- return;
174
- }
175
-
176
- printf(
177
- '<div class="notice notice-warning"><p>%s</p><p>%s</p><p>%s</p></div>',
178
- esc_html__( 'Plugin actions are not available while in Troubleshooting Mode.', 'health-check' ),
179
- esc_html__( 'By enabling the Troubleshooting Mode, all plugins will appear inactive and your site will switch to the default theme only for you. All other users will see your site as usual.', 'health-check' ),
180
- esc_html__( 'A Troubleshooting Mode menu is added to your admin bar, which will allow you to enable plugins individually, switch back to your current theme, and disable Troubleshooting Mode.', 'health-check' )
181
- );
182
- }
183
-
184
  /**
185
  * Modify plugin actions.
186
  *
@@ -223,11 +212,9 @@ class Health_Check_Troubleshooting_MU {
223
  $plugin_data['slug'] = $plugin_file;
224
  }
225
 
226
- $allowed_plugins = get_option( 'health-check-allowed-plugins', array() );
227
-
228
  $plugin_slug = ( isset( $plugin_data['slug'] ) ? $plugin_data['slug'] : sanitize_title( $plugin_data['Name'] ) );
229
 
230
- if ( in_array( $plugin_slug, $allowed_plugins ) ) {
231
  $actions['troubleshoot-disable'] = sprintf(
232
  '<a href="%s">%s</a>',
233
  esc_url( add_query_arg( array(
@@ -270,7 +257,7 @@ class Health_Check_Troubleshooting_MU {
270
  *
271
  * @return bool
272
  */
273
- public static function is_troubleshooting() {
274
  // Check if a session cookie to disable plugins has been set.
275
  if ( isset( $_COOKIE['health-check-disable-plugins'] ) ) {
276
  $_GET['health-check-disable-plugin-hash'] = $_COOKIE['health-check-disable-plugins'];
@@ -281,9 +268,12 @@ class Health_Check_Troubleshooting_MU {
281
  return false;
282
  }
283
 
 
 
 
 
284
  // If the plugin hash is not valid, we also break out
285
- $disable_hash = get_option( 'health-check-disable-plugin-hash', '' );
286
- if ( $disable_hash !== $_GET['health-check-disable-plugin-hash'] ) {
287
  return false;
288
  }
289
 
@@ -302,11 +292,9 @@ class Health_Check_Troubleshooting_MU {
302
  return $plugins;
303
  }
304
 
305
- $allowed_plugins = get_option( 'health-check-allowed-plugins', array() );
306
-
307
  // If we've received a comma-separated list of allowed plugins, we'll add them to the array of allowed plugins.
308
  if ( isset( $_GET['health-check-allowed-plugins'] ) ) {
309
- $allowed_plugins = explode( ',', $_GET['health-check-allowed-plugins'] );
310
  }
311
 
312
  foreach ( $plugins as $plugin_no => $plugin_path ) {
@@ -314,7 +302,7 @@ class Health_Check_Troubleshooting_MU {
314
  $plugin_parts = explode( '/', $plugin_path );
315
 
316
  // We may want to allow individual, or groups of plugins, so introduce a skip-mechanic for those scenarios.
317
- if ( in_array( $plugin_parts[0], $allowed_plugins ) ) {
318
  continue;
319
  }
320
 
@@ -368,25 +356,22 @@ class Health_Check_Troubleshooting_MU {
368
  }
369
 
370
  /**
371
- * Use a default theme.
372
  *
373
- * Attempt to set one of the default themes as the active one
374
- * during Troubleshooting Mode, if one exists, if not fall
375
- * back to always showing the active theme.
376
  *
377
- * @param string $theme The users active theme slug.
378
  *
379
- * @return string Theme slug to be perceived as the active theme.
380
  */
381
- function health_check_troubleshoot_theme( $theme ) {
382
- // Check if this is us fetching theme details, we then want to just return things as usual.
383
  if ( $this->self_fetching_theme ) {
384
- return $theme;
385
  }
386
 
387
- // Check if overrides are triggered if not break out.
388
  if ( ! $this->override_theme() ) {
389
- return $theme;
390
  }
391
 
392
  if ( empty( $this->current_theme_details ) ) {
@@ -395,25 +380,54 @@ class Health_Check_Troubleshooting_MU {
395
  $this->self_fetching_theme = false;
396
  }
397
 
398
- // Check if this is a parent theme request, if so return it as usual.
399
- if ( $this->current_theme_details->parent() ) {
400
- if ( $this->current_theme_details->get_template() === $theme ) {
401
- return $theme;
 
402
  }
403
  }
404
 
405
- // Check if a default theme exists, and if so use it as a default.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
406
  $default_theme = $this->has_default_theme();
407
- if ( $default_theme ) {
408
- $theme = $default_theme;
 
 
409
  }
410
 
411
- // If a specific theme has been chosen, use it.
412
- if ( false !== $this->current_theme ) {
413
- $theme = $this->current_theme;
414
  }
415
 
416
- return $theme;
417
  }
418
 
419
  /**
@@ -466,12 +480,35 @@ class Health_Check_Troubleshooting_MU {
466
  die();
467
  }
468
 
 
 
 
 
 
 
 
 
469
  // Enable an individual plugin.
470
  if ( isset( $_GET['health-check-troubleshoot-enable-plugin'] ) ) {
471
- $allowed_plugins = get_option( 'health-check-allowed-plugins', array() );
472
- $allowed_plugins[ $_GET['health-check-troubleshoot-enable-plugin'] ] = $_GET['health-check-troubleshoot-enable-plugin'];
 
473
 
474
- update_option( 'health-check-allowed-plugins', $allowed_plugins );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
 
476
  wp_redirect( remove_query_arg( $this->available_query_args ) );
477
  die();
@@ -479,10 +516,25 @@ class Health_Check_Troubleshooting_MU {
479
 
480
  // Disable an individual plugin.
481
  if ( isset( $_GET['health-check-troubleshoot-disable-plugin'] ) ) {
482
- $allowed_plugins = get_option( 'health-check-allowed-plugins', array() );
483
- unset( $allowed_plugins[ $_GET['health-check-troubleshoot-disable-plugin'] ] );
 
 
 
484
 
485
- update_option( 'health-check-allowed-plugins', $allowed_plugins );
 
 
 
 
 
 
 
 
 
 
 
 
486
 
487
  wp_redirect( remove_query_arg( $this->available_query_args ) );
488
  die();
@@ -490,13 +542,40 @@ class Health_Check_Troubleshooting_MU {
490
 
491
  // Change the active theme for this session.
492
  if ( isset( $_GET['health-check-change-active-theme'] ) ) {
 
 
493
  update_option( 'health-check-current-theme', $_GET['health-check-change-active-theme'] );
494
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
  wp_redirect( remove_query_arg( $this->available_query_args ) );
496
  die();
497
  }
498
  }
499
 
 
 
 
 
 
 
 
 
 
 
 
 
500
  /**
501
  * Extend the admin bar.
502
  *
@@ -527,8 +606,6 @@ class Health_Check_Troubleshooting_MU {
527
  'title' => esc_html__( 'Troubleshooting Mode', 'health-check' ),
528
  ) );
529
 
530
- $allowed_plugins = get_option( 'health-check-allowed-plugins', array() );
531
-
532
  // Add a link to manage plugins if there are more than 20 set to be active.
533
  if ( count( $this->active_plugins ) > 20 ) {
534
  $wp_menu->add_node( array(
@@ -561,7 +638,7 @@ class Health_Check_Troubleshooting_MU {
561
 
562
  $enabled = true;
563
 
564
- if ( in_array( $plugin_slug, $allowed_plugins ) ) {
565
  $label = sprintf(
566
  // Translators: %s: Plugin slug.
567
  esc_html__( 'Disable %s', 'health-check' ),
@@ -643,6 +720,368 @@ class Health_Check_Troubleshooting_MU {
643
  ) );
644
  }
645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
646
  }
647
 
648
  new Health_Check_Troubleshooting_MU();
2
  /*
3
  Plugin Name: Health Check Troubleshooting Mode
4
  Description: Conditionally disabled themes or plugins on your site for a given session, used to rule out conflicts during troubleshooting.
5
+ Version: 1.5.0
6
  */
7
 
8
  if ( ! defined( 'ABSPATH' ) ) {
10
  }
11
 
12
  class Health_Check_Troubleshooting_MU {
13
+ private $disable_hash = null;
14
  private $override_active = true;
15
  private $default_theme = true;
16
  private $active_plugins = array();
17
+ private $allowed_plugins = array();
18
  private $current_theme;
19
  private $current_theme_details;
20
  private $self_fetching_theme = false;
57
  add_filter( 'option_active_plugins', array( $this, 'health_check_loopback_test_disable_plugins' ) );
58
  add_filter( 'option_active_sitewide_plugins', array( $this, 'health_check_loopback_test_disable_plugins' ) );
59
 
60
+ add_filter( 'pre_option_template', array( $this, 'health_check_troubleshoot_theme_template' ) );
61
+ add_filter( 'pre_option_stylesheet', array( $this, 'health_check_troubleshoot_theme_stylesheet' ) );
62
 
 
63
  add_action( 'admin_notices', array( $this, 'prompt_install_default_theme' ) );
64
  add_filter( 'user_has_cap', array( $this, 'remove_plugin_theme_install' ) );
65
 
66
  add_action( 'plugin_action_links', array( $this, 'plugin_actions' ), 50, 4 );
67
 
68
+ add_action( 'admin_notices', array( $this, 'display_dashboard_widget' ) );
69
+ add_action( 'admin_head', array( $this, 'dashboard_widget_styles' ) );
70
+ add_action( 'admin_footer', array( $this, 'dashboard_widget_scripts' ) );
71
+
72
  add_action( 'wp_logout', array( $this, 'health_check_troubleshooter_mode_logout' ) );
73
  add_action( 'init', array( $this, 'health_check_troubleshoot_get_captures' ) );
74
 
80
  */
81
  add_action( 'activated_plugin', array( $this, 'plugin_activated' ) );
82
 
83
+ $this->load_options();
84
+ }
85
+
86
+ /**
87
+ * Set up the class variables based on option table entries.
88
+ *
89
+ * @return void
90
+ */
91
+ public function load_options() {
92
+ $this->disable_hash = get_option( 'health-check-disable-plugin-hash', null );
93
+ $this->allowed_plugins = get_option( 'health-check-allowed-plugins', array() );
94
+ $this->default_theme = ( 'yes' === get_option( 'health-check-default-theme', 'yes' ) ? true : false );
95
+ $this->active_plugins = $this->get_unfiltered_plugin_list();
96
+ $this->current_theme = get_option( 'health-check-current-theme', false );
97
  }
98
 
99
  /**
170
  update_option( 'active_plugins', $this->active_plugins );
171
  }
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  /**
174
  * Modify plugin actions.
175
  *
212
  $plugin_data['slug'] = $plugin_file;
213
  }
214
 
 
 
215
  $plugin_slug = ( isset( $plugin_data['slug'] ) ? $plugin_data['slug'] : sanitize_title( $plugin_data['Name'] ) );
216
 
217
+ if ( in_array( $plugin_slug, $this->allowed_plugins ) ) {
218
  $actions['troubleshoot-disable'] = sprintf(
219
  '<a href="%s">%s</a>',
220
  esc_url( add_query_arg( array(
257
  *
258
  * @return bool
259
  */
260
+ public function is_troubleshooting() {
261
  // Check if a session cookie to disable plugins has been set.
262
  if ( isset( $_COOKIE['health-check-disable-plugins'] ) ) {
263
  $_GET['health-check-disable-plugin-hash'] = $_COOKIE['health-check-disable-plugins'];
268
  return false;
269
  }
270
 
271
+ if ( empty( $this->disable_hash ) ) {
272
+ return false;
273
+ }
274
+
275
  // If the plugin hash is not valid, we also break out
276
+ if ( $this->disable_hash !== $_GET['health-check-disable-plugin-hash'] ) {
 
277
  return false;
278
  }
279
 
292
  return $plugins;
293
  }
294
 
 
 
295
  // If we've received a comma-separated list of allowed plugins, we'll add them to the array of allowed plugins.
296
  if ( isset( $_GET['health-check-allowed-plugins'] ) ) {
297
+ $this->allowed_plugins = explode( ',', $_GET['health-check-allowed-plugins'] );
298
  }
299
 
300
  foreach ( $plugins as $plugin_no => $plugin_path ) {
302
  $plugin_parts = explode( '/', $plugin_path );
303
 
304
  // We may want to allow individual, or groups of plugins, so introduce a skip-mechanic for those scenarios.
305
+ if ( in_array( $plugin_parts[0], $this->allowed_plugins ) ) {
306
  continue;
307
  }
308
 
356
  }
357
 
358
  /**
359
+ * Override the default theme.
360
  *
361
+ * Attempt to set one of the default themes, or a theme of the users choosing, as the active one
362
+ * during Troubleshooting Mode.
 
363
  *
364
+ * @param $default
365
  *
366
+ * @return bool|string
367
  */
368
+ function health_check_troubleshoot_theme_stylesheet( $default ) {
 
369
  if ( $this->self_fetching_theme ) {
370
+ return $default;
371
  }
372
 
 
373
  if ( ! $this->override_theme() ) {
374
+ return $default;
375
  }
376
 
377
  if ( empty( $this->current_theme_details ) ) {
380
  $this->self_fetching_theme = false;
381
  }
382
 
383
+ // If no theme has been chosen, start off by troubleshooting as a default theme if one exists.
384
+ $default_theme = $this->has_default_theme();
385
+ if ( false === $this->current_theme ) {
386
+ if ( $default_theme ) {
387
+ return $default_theme;
388
  }
389
  }
390
 
391
+ return $this->current_theme;
392
+ }
393
+
394
+ /**
395
+ * Override the default parent theme.
396
+ *
397
+ * If this is a child theme, override the parent and provide our users chosen themes parent instead.
398
+ *
399
+ * @param $default
400
+ *
401
+ * @return bool|string
402
+ */
403
+ function health_check_troubleshoot_theme_template( $default ) {
404
+ if ( $this->self_fetching_theme ) {
405
+ return $default;
406
+ }
407
+
408
+ if ( ! $this->override_theme() ) {
409
+ return $default;
410
+ }
411
+
412
+ if ( empty( $this->current_theme_details ) ) {
413
+ $this->self_fetching_theme = true;
414
+ $this->current_theme_details = wp_get_theme( $this->current_theme );
415
+ $this->self_fetching_theme = false;
416
+ }
417
+
418
+ // If no theme has been chosen, start off by troubleshooting as a default theme if one exists.
419
  $default_theme = $this->has_default_theme();
420
+ if ( false === $this->current_theme ) {
421
+ if ( $default_theme ) {
422
+ return $default_theme;
423
+ }
424
  }
425
 
426
+ if ( $this->current_theme_details->parent() ) {
427
+ return $this->current_theme_details->get_template();
 
428
  }
429
 
430
+ return $this->current_theme;
431
  }
432
 
433
  /**
480
  die();
481
  }
482
 
483
+ // Dismiss notices.
484
+ if ( isset( $_GET['health-check-dismiss-notices'] ) && $this->is_troubleshooting() && is_admin() ) {
485
+ update_option( 'health-check-dashboard-notices', array() );
486
+
487
+ wp_redirect( admin_url() );
488
+ die();
489
+ }
490
+
491
  // Enable an individual plugin.
492
  if ( isset( $_GET['health-check-troubleshoot-enable-plugin'] ) ) {
493
+ $old_allowed_plugins = $this->allowed_plugins;
494
+
495
+ $this->allowed_plugins[ $_GET['health-check-troubleshoot-enable-plugin'] ] = $_GET['health-check-troubleshoot-enable-plugin'];
496
 
497
+ update_option( 'health-check-allowed-plugins', $this->allowed_plugins );
498
+
499
+ if ( ! $this->test_site_state() ) {
500
+ $this->allowed_plugins = $old_allowed_plugins;
501
+ update_option( 'health-check-allowed-plugins', $old_allowed_plugins );
502
+
503
+ $this->add_dashboard_notice(
504
+ sprintf(
505
+ // translators: %s: The plugin slug that was enabled.
506
+ __( 'When enabling the plugin, %s, a site failure occurred. Because of this the change was automatically reverted.', 'health-check' ),
507
+ $_GET['health-check-troubleshoot-enable-plugin']
508
+ ),
509
+ 'warning'
510
+ );
511
+ }
512
 
513
  wp_redirect( remove_query_arg( $this->available_query_args ) );
514
  die();
516
 
517
  // Disable an individual plugin.
518
  if ( isset( $_GET['health-check-troubleshoot-disable-plugin'] ) ) {
519
+ $old_allowed_plugins = $this->allowed_plugins;
520
+
521
+ unset( $this->allowed_plugins[ $_GET['health-check-troubleshoot-disable-plugin'] ] );
522
+
523
+ update_option( 'health-check-allowed-plugins', $this->allowed_plugins );
524
 
525
+ if ( ! $this->test_site_state() ) {
526
+ $this->allowed_plugins = $old_allowed_plugins;
527
+ update_option( 'health-check-allowed-plugins', $old_allowed_plugins );
528
+
529
+ $this->add_dashboard_notice(
530
+ sprintf(
531
+ // translators: %s: The plugin slug that was disabled.
532
+ __( 'When disabling the plugin, %s, a site failure occurred. Because of this the change was automatically reverted.', 'health-check' ),
533
+ $_GET['health-check-troubleshoot-enable-plugin']
534
+ ),
535
+ 'warning'
536
+ );
537
+ }
538
 
539
  wp_redirect( remove_query_arg( $this->available_query_args ) );
540
  die();
542
 
543
  // Change the active theme for this session.
544
  if ( isset( $_GET['health-check-change-active-theme'] ) ) {
545
+ $old_theme = get_option( 'health-check-current-theme' );
546
+
547
  update_option( 'health-check-current-theme', $_GET['health-check-change-active-theme'] );
548
 
549
+ if ( ! $this->test_site_state() ) {
550
+ update_option( 'health-check-current-theme', $old_theme );
551
+
552
+ $this->add_dashboard_notice(
553
+ sprintf(
554
+ // translators: %s: The theme slug that was switched to.
555
+ __( 'When switching the active theme to %s, a site failure occurred. Because of this we reverted the theme to the one you used previously.', 'health-check' ),
556
+ $_GET['health-check-change-active-theme']
557
+ ),
558
+ 'warning'
559
+ );
560
+ }
561
+
562
  wp_redirect( remove_query_arg( $this->available_query_args ) );
563
  die();
564
  }
565
  }
566
 
567
+ private function add_dashboard_notice( $message, $severity = 'notice' ) {
568
+ $notices = get_option( 'health-check-dashboard-notices', array() );
569
+
570
+ $notices[] = array(
571
+ 'severity' => $severity,
572
+ 'message' => $message,
573
+ 'time' => date( 'Y-m-d H:i' ),
574
+ );
575
+
576
+ update_option( 'health-check-dashboard-notices', $notices );
577
+ }
578
+
579
  /**
580
  * Extend the admin bar.
581
  *
606
  'title' => esc_html__( 'Troubleshooting Mode', 'health-check' ),
607
  ) );
608
 
 
 
609
  // Add a link to manage plugins if there are more than 20 set to be active.
610
  if ( count( $this->active_plugins ) > 20 ) {
611
  $wp_menu->add_node( array(
638
 
639
  $enabled = true;
640
 
641
+ if ( in_array( $plugin_slug, $this->allowed_plugins ) ) {
642
  $label = sprintf(
643
  // Translators: %s: Plugin slug.
644
  esc_html__( 'Disable %s', 'health-check' ),
720
  ) );
721
  }
722
 
723
+ public function test_site_state() {
724
+
725
+ // Make sure the Health_Check_Loopback class is available to us, in case the primary plugin is disabled.
726
+ if ( ! method_exists( 'Health_Check_Loopback', 'can_perform_loopback' ) ) {
727
+ $plugin_file = trailingslashit( WP_PLUGIN_DIR ) . 'health-check/includes/class-health-check-loopback.php';
728
+
729
+ // Make sure the file exists, in case someone deleted the plugin manually, we don't want any errors.
730
+ if ( ! file_exists( $plugin_file ) ) {
731
+
732
+ // If the plugin files are inaccessible, we can't guarantee for the state of the site, so the default is a bad response.
733
+ return false;
734
+ }
735
+
736
+ require_once( $plugin_file );
737
+ }
738
+
739
+ $loopback_state = Health_Check_Loopback::can_perform_loopback();
740
+
741
+ if ( 'good' !== $loopback_state->status ) {
742
+ return false;
743
+ }
744
+
745
+ return true;
746
+ }
747
+
748
+ public function dashboard_widget_styles() {
749
+ if ( ! $this->is_troubleshooting() ) {
750
+ return;
751
+ }
752
+
753
+ // Check that it's the dashboard page, we don't want to disturb any other pages.
754
+ $screen = get_current_screen();
755
+ if ( 'dashboard' !== $screen->id && 'plugins' !== $screen->id ) {
756
+ return;
757
+ }
758
+ ?>
759
+ <style type="text/css">
760
+ @media all and (min-width: 783px) {
761
+ #health-check-dashboard-widget {
762
+ margin-top: 3rem;
763
+ }
764
+ }
765
+
766
+ #health-check-dashboard-widget .welcome-panel-content {
767
+ max-width: initial;
768
+ }
769
+
770
+ #health-check-dashboard-widget .notices .no-notices p {
771
+ color: #bfc3c7;
772
+ font-size: 1.2rem;
773
+ }
774
+ #health-check-dashboard-widget .notices .notice {
775
+ margin-left: 0;
776
+ }
777
+ #health-check-dashboard-widget .notices .dismiss-notices {
778
+ float: right;
779
+ margin-right: 1rem;
780
+ }
781
+
782
+ #health-check-dashboard-widget .disable-troubleshooting-mode {
783
+ margin-bottom: 1rem;
784
+ }
785
+ @media all and (min-width: 960px) {
786
+ #health-check-dashboard-widget .disable-troubleshooting-mode {
787
+ position: absolute;
788
+ bottom: 1rem;
789
+ right: 1rem;
790
+ }
791
+ }
792
+
793
+ #health-check-dashboard-widget .toggle-visibility {
794
+ display: none;
795
+ }
796
+ #health-check-dashboard-widget .toggle-visibility.visible {
797
+ display: block;
798
+ }
799
+
800
+ #health-check-dashboard-widget .welcome-panel-column-container {
801
+ position: initial;
802
+ }
803
+
804
+ #health-check-dashboard-widget .welcome-panel-column.is-standalone-button {
805
+ width: 100%;
806
+ text-align: right;
807
+ }
808
+ #health-check-dashboard-widget .welcome-panel-column.is-standalone-button .disable-troubleshooting-mode {
809
+ position: relative;
810
+ }
811
+ </style>
812
+ <?php
813
+ }
814
+
815
+ public function dashboard_widget_scripts() {
816
+ if ( ! $this->is_troubleshooting() ) {
817
+ return;
818
+ }
819
+
820
+ // Check that it's the dashboard page, we don't want to disturb any other pages.
821
+ $screen = get_current_screen();
822
+ if ( 'dashboard' !== $screen->id && 'plugins' !== $screen->id ) {
823
+ return;
824
+ }
825
+ ?>
826
+ <script type="text/javascript">
827
+ jQuery( document ).ready(function( $ ) {
828
+ $( '.health-check-toggle-visibility' ).click(function( e ) {
829
+ var $elements = $( '.toggle-visibility', $( '#' + $ ( this ).data( 'element' ) ) );
830
+
831
+ if ( $elements.is( ':visible' ) ) {
832
+ $elements.attr( 'aria-hidden', 'true' ).toggle();
833
+ } else {
834
+ $elements.attr( 'aria-hidden', 'false' ).toggle();
835
+ }
836
+ });
837
+ });
838
+ </script>
839
+ <?php
840
+ }
841
+
842
+ public function display_dashboard_widget() {
843
+ if ( ! $this->is_troubleshooting() ) {
844
+ return;
845
+ }
846
+
847
+ // Check that it's the dashboard page, we don't want to disturb any other pages.
848
+ $screen = get_current_screen();
849
+ if ( 'dashboard' !== $screen->id && 'plugins' !== $screen->id ) {
850
+ return;
851
+ }
852
+
853
+ $notices = get_option( 'health-check-dashboard-notices', array() );
854
+ ?>
855
+ <div class="wrap">
856
+ <div id="health-check-dashboard-widget" class="welcome-panel">
857
+ <div class="welcome-panel-content">
858
+ <h2>
859
+ <?php esc_html_e( 'Health Check &mdash; Troubleshooting Mode', 'health-check' ); ?>
860
+ </h2>
861
+
862
+ <p class="about-description">
863
+ <?php esc_html_e( 'Your site is currently in Troubleshooting Mode. This has no effect on your site visitors, they will continue to view your site as usual, but for you it will look as if you had just installed WordPress for the first time.', 'health-check' ); ?>
864
+ </p>
865
+
866
+ <p class="about-description">
867
+ <?php esc_html_e( 'Here you can enable individual plugins or themes, helping you to find out what might be causing strange behaviors on your site. Do note that any changes you make to settings will be kept when you disable Troubleshooting Mode.', 'health-check' ); ?>
868
+ </p>
869
+
870
+ <div class="notices">
871
+ <h3>
872
+ <span class="dashicons dashicons-flag"></span>
873
+ <?php esc_html_e( 'Notices', 'health-check' ); ?>
874
+ </h3>
875
+
876
+ <?php if ( empty( $notices ) && 'plugins' !== $screen->id ) : ?>
877
+ <div class="no-notices">
878
+ <p>
879
+ <?php esc_html_e( 'There are no notices to show.', 'health-check' ); ?>
880
+ </p>
881
+ </div>
882
+ <?php endif; ?>
883
+
884
+ <?php if ( 'plugins' === $screen->id ) : ?>
885
+ <div class="notice notice-warning inline">
886
+ <p>
887
+ <?php esc_html_e( 'Plugin actions, such as activating and deactivating, are not available while in Troubleshooting Mode.', 'health-check' ); ?>
888
+ </p>
889
+ </div>
890
+ <?php endif; ?>
891
+
892
+ <?php
893
+ foreach ( $notices as $notice ) {
894
+ printf(
895
+ '<div class="notice notice-%s inline"><p>%s</p></div>',
896
+ esc_attr( $notice['severity'] ),
897
+ esc_html( $notice['message'] )
898
+ );
899
+ }
900
+ ?>
901
+
902
+ <?php
903
+ if ( ! empty( $notices ) ) {
904
+ printf(
905
+ '<a href="%s" class="dismiss-notices">%s</a>',
906
+ esc_url( add_query_arg( array(
907
+ 'health-check-dismiss-notices' => true,
908
+ ) ) ),
909
+ esc_html__( 'Dismiss notices', 'health-check' )
910
+ );
911
+ }
912
+ ?>
913
+ </div>
914
+
915
+ <div class="welcome-panel-column-container">
916
+ <div class="welcome-panel-column">
917
+ <?php if ( 'plugins' !== $screen->id ) : ?>
918
+ <h3>
919
+ <span class="dashicons dashicons-admin-plugins"></span>
920
+ <?php esc_html_e( 'Available Plugins', 'health-check' ); ?>
921
+ </h3>
922
+
923
+ <ul id="health-check-plugins">
924
+ <?php
925
+ $active_plugins = array();
926
+ $inactive_plugins = array();
927
+
928
+ foreach ( $this->active_plugins as $count => $single_plugin ) {
929
+ $plugin_slug = explode( '/', $single_plugin );
930
+ $plugin_slug = $plugin_slug[0];
931
+
932
+ $plugin_is_visible = true;
933
+ if ( $count >= 5 ) {
934
+ $plugin_is_visible = false;
935
+ }
936
+
937
+ $plugin_data = get_plugin_data( trailingslashit( WP_PLUGIN_DIR ) . $single_plugin );
938
+
939
+ $actions = array();
940
+
941
+ if ( in_array( $plugin_slug, $this->allowed_plugins ) ) {
942
+ $actions[] = sprintf(
943
+ '<a href="%s" aria-label="%s">%s</a>',
944
+ esc_url( add_query_arg( array(
945
+ 'health-check-troubleshoot-disable-plugin' => $plugin_slug,
946
+ ) ) ),
947
+ esc_attr(
948
+ sprintf(
949
+ // translators: %s: Plugin name.
950
+ __( 'Disable the plugin, %s, while troubleshooting.', 'health-check' ),
951
+ $plugin_data['Name']
952
+ )
953
+ ),
954
+ esc_html__( 'Disable', 'health-check' )
955
+ );
956
+ } else {
957
+ $actions[] = sprintf(
958
+ '<a href="%s" aria-label="%s">%s</a>',
959
+ esc_url( add_query_arg( array(
960
+ 'health-check-troubleshoot-enable-plugin' => $plugin_slug,
961
+ ) ) ),
962
+ esc_attr(
963
+ sprintf(
964
+ // translators: %s: Plugin name.
965
+ __( 'Enable the plugin, %s, while troubleshooting.', 'health-check' ),
966
+ $plugin_data['Name']
967
+ )
968
+ ),
969
+ esc_html__( 'Enable', 'health-check' )
970
+ );
971
+ }
972
+
973
+ printf(
974
+ '<li class="%s" aria-hidden="%s">%s - %s</li>',
975
+ ( ! $plugin_is_visible ? 'toggle-visibility' : '' ),
976
+ ( ! $plugin_is_visible ? 'true' : 'false' ),
977
+ esc_html( $plugin_data['Name'] ),
978
+ implode( ' | ', $actions )
979
+ );
980
+ }
981
+ ?>
982
+ </ul>
983
+
984
+ <?php if ( count( $this->active_plugins ) > 5 ) : ?>
985
+ <p>
986
+ <button type="button" class="button button-link health-check-toggle-visibility toggle-visibility visible" aria-hidden="false" data-element="health-check-plugins">
987
+ <?php esc_html_e( 'Show all plugins', 'health-check' ); ?>
988
+ </button>
989
+
990
+ <button type="button" class="button button-link health-check-toggle-visibility toggle-visibility" aria-hidden="true" data-element="health-check-plugins">
991
+ <?php esc_html_e( 'Show fewer plugins', 'health-check' ); ?>
992
+ </button>
993
+ </p>
994
+ <?php endif; ?>
995
+ <?php endif; ?>
996
+ </div>
997
+
998
+ <div class="welcome-panel-column">
999
+ <?php if ( 'plugins' !== $screen->id ) : ?>
1000
+ <h3>
1001
+ <span class="dashicons dashicons-admin-appearance"></span>
1002
+ <?php esc_html_e( 'Available Themes', 'health-check' ); ?>
1003
+ </h3>
1004
+
1005
+ <ul id="health-check-themes">
1006
+ <?php
1007
+ $themes = wp_prepare_themes_for_js();
1008
+
1009
+ foreach ( $themes as $count => $theme ) {
1010
+ $active = $theme['active'];
1011
+
1012
+ $theme_is_visible = true;
1013
+ if ( $count >= 5 ) {
1014
+ $theme_is_visible = false;
1015
+ }
1016
+
1017
+ $actions = sprintf(
1018
+ '<a href="%s" aria-label="%s">%s</a>',
1019
+ esc_url( add_query_arg( array(
1020
+ 'health-check-change-active-theme' => $theme['id'],
1021
+ ) ) ),
1022
+ esc_attr(
1023
+ sprintf(
1024
+ // translators: %s: Theme name.
1025
+ __( 'Switch the active theme to %s', 'health-check' ),
1026
+ $theme['name']
1027
+ )
1028
+ ),
1029
+ esc_html__( 'Switch to this theme', 'health-check' )
1030
+ );
1031
+
1032
+ $plugin_label = sprintf(
1033
+ '%s %s',
1034
+ // translators: Prefix for the active theme in a listing.
1035
+ ( $theme['active'] ? esc_html__( 'Active:', 'health-check' ) : '' ),
1036
+ $theme['name']
1037
+ );
1038
+
1039
+ if ( ! $theme['active'] ) {
1040
+ $plugin_label .= ' - ' . $actions;
1041
+ }
1042
+
1043
+ printf(
1044
+ '<li class="%s" aria-hidden="%s">%s</li>',
1045
+ ( $theme_is_visible ? '' : 'toggle-visibility' ),
1046
+ ( $theme_is_visible ? 'false' : 'true' ),
1047
+ $plugin_label
1048
+ );
1049
+ }
1050
+ ?>
1051
+ </ul>
1052
+
1053
+ <?php if ( count( $themes ) > 5 ) : ?>
1054
+ <p>
1055
+ <button type="button" class="button button-link health-check-toggle-visibility toggle-visibility visible" aria-hidden="false" data-element="health-check-themes">
1056
+ <?php esc_html_e( 'Show all themes', 'health-check' ); ?>
1057
+ </button>
1058
+
1059
+ <button type="button" class="button button-link health-check-toggle-visibility toggle-visibility" aria-hidden="true">
1060
+ <?php esc_html_e( 'Show fewer themes', 'health-check' ); ?>
1061
+ </button>
1062
+ </p>
1063
+ <?php endif; ?>
1064
+ <?php endif; ?>
1065
+ </div>
1066
+
1067
+ <div class="welcome-panel-column <?php echo ( 'plugins' === $screen->id ? 'is-standalone-button' : '' ); ?>">
1068
+ <?php
1069
+ printf(
1070
+ '<a href="%s" class="button button-primary button-hero disable-troubleshooting-mode">%s</a>',
1071
+ esc_url( add_query_arg( array(
1072
+ 'health-check-disable-troubleshooting' => true,
1073
+ ) ) ),
1074
+ esc_html__( 'Disable Troubleshooting Mode', 'health-check' )
1075
+ );
1076
+ ?>
1077
+ </div>
1078
+ </div>
1079
+ </div>
1080
+ </div>
1081
+ </div>
1082
+ <?php
1083
+ }
1084
+
1085
  }
1086
 
1087
  new Health_Check_Troubleshooting_MU();
changelog.txt CHANGED
@@ -1,3 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  = v 1.0.1 =
2
  * Fixed email tester having the wrong class reference, preventing it from running.
3
  * Add some missing text domains preventing full translations.
1
+ = v 1.1.2 =
2
+ * Fixed child themes not displaying properly in Troubleshooting Mode.
3
+ * Improved styling for the backup warning, shown when activating the plugin, so it doesn't block mobile users.
4
+ * Added explanations to the plugins screen if you enter Troubleshooting Mode there, so users know what is going on.
5
+ * Fixed admin menu overflowing if too many plugins exist.
6
+
7
+ = v 1.1.1 =
8
+ * Fixed a fatal error that would occur if a user had an older version of Troubleshooting Mode on their system.
9
+
10
+ = v 1.1.0 =
11
+ * Check for theme, plugin and WordPress updates when visiting the debug tab.
12
+ * Improved wording on some failure situations.
13
+ * Made the Debug Information tab a bit easier to read with fixed table styles.
14
+ * Redesigned tools page, with added accordion to avoid information overload, and different features mixing together.
15
+ * Mail test tool now allows you to include an optional customized message.
16
+ * Users can now change between any installed theme while in troubleshooting mode.
17
+ * Renamed the Must-Use plugin, making it align with what features present in the file.
18
+ * Improved the plugin cleanup process, when the plugin is deleted.
19
+ * Show full plugin names, and not slugs, in the troubleshooting admin bar menu.
20
+ * Check if the .htaccess file contains any rules not added by WordPress core in the debug section.
21
+ * Allow the disabling of Troubleshooting Mode from the same page as you previously enabled it from.
22
+ * Removed cURL checks from the automated test page, this was more confusion than help.
23
+ * Add installation size to the debug information.
24
+
25
  = v 1.0.1 =
26
  * Fixed email tester having the wrong class reference, preventing it from running.
27
  * Add some missing text domains preventing full translations.
health-check.php CHANGED
@@ -4,11 +4,11 @@
4
  *
5
  * @package Health Check
6
  *
7
- * Plugin Name: Health Check
8
  * Plugin URI: http://wordpress.org/plugins/health-check/
9
  * Description: Checks the health of your WordPress install.
10
  * Author: The WordPress.org community
11
- * Version: 1.1.2
12
  * Author URI: http://wordpress.org/plugins/health-check/
13
  * Text Domain: health-check
14
  */
@@ -34,7 +34,7 @@ define( 'HEALTH_CHECK_MYSQL_MIN_VERSION', '5.0' );
34
  define( 'HEALTH_CHECK_MYSQL_REC_VERSION', '5.6' );
35
 
36
  // Set the plugin version.
37
- define( 'HEALTH_CHECK_PLUGIN_VERSION', '1.1.2' );
38
 
39
  // Set the absolute path for the plugin.
40
  define( 'HEALTH_CHECK_PLUGIN_DIRECTORY', plugin_dir_path( __FILE__ ) );
@@ -49,7 +49,7 @@ define( 'HEALTH_CHECK_CURL_VERSION', '7.58' );
49
  define( 'HEALTH_CHECK_CURL_MIN_VERSION', '7.38' );
50
 
51
  // Include class-files used by our plugin.
52
- require_once( dirname( __FILE__ ) . '/includes/class-healthcheck.php' );
53
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-auto-updates.php' );
54
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-wp-cron.php' );
55
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-debug-data.php' );
@@ -57,6 +57,7 @@ require_once( dirname( __FILE__ ) . '/includes/class-health-check-loopback.php'
57
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-troubleshoot.php' );
58
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-files-integrity.php' );
59
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-mail-check.php' );
 
60
 
61
  // Initialize our plugin.
62
- new HealthCheck();
4
  *
5
  * @package Health Check
6
  *
7
+ * Plugin Name: Health Check & Troubleshooting
8
  * Plugin URI: http://wordpress.org/plugins/health-check/
9
  * Description: Checks the health of your WordPress install.
10
  * Author: The WordPress.org community
11
+ * Version: 1.2.0
12
  * Author URI: http://wordpress.org/plugins/health-check/
13
  * Text Domain: health-check
14
  */
34
  define( 'HEALTH_CHECK_MYSQL_REC_VERSION', '5.6' );
35
 
36
  // Set the plugin version.
37
+ define( 'HEALTH_CHECK_PLUGIN_VERSION', '1.2.0' );
38
 
39
  // Set the absolute path for the plugin.
40
  define( 'HEALTH_CHECK_PLUGIN_DIRECTORY', plugin_dir_path( __FILE__ ) );
49
  define( 'HEALTH_CHECK_CURL_MIN_VERSION', '7.38' );
50
 
51
  // Include class-files used by our plugin.
52
+ require_once( dirname( __FILE__ ) . '/includes/class-health-check.php' );
53
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-auto-updates.php' );
54
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-wp-cron.php' );
55
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-debug-data.php' );
57
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-troubleshoot.php' );
58
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-files-integrity.php' );
59
  require_once( dirname( __FILE__ ) . '/includes/class-health-check-mail-check.php' );
60
+ require_once( dirname( __FILE__ ) . '/includes/class-health-check-site-status.php' );
61
 
62
  // Initialize our plugin.
63
+ new Health_Check();
includes/class-health-check-auto-updates.php CHANGED
@@ -1,512 +1,531 @@
1
- <?php
2
- /**
3
- * Class for testing automatic updates in the WordPress code.
4
- *
5
- * @package Health Check
6
- */
7
-
8
- /**
9
- * Class Health_Check_Auto_Updates
10
- */
11
- class Health_Check_Auto_Updates {
12
- /**
13
- * Health_Check_Auto_Updates constructor.
14
- *
15
- * @uses HealthCheck::init()
16
- *
17
- * @return void
18
- */
19
- public function __construct() {
20
- $this->init();
21
- }
22
-
23
- /**
24
- * Initiate the plugin class.
25
- *
26
- * @return void
27
- */
28
- public function init() {
29
- include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
30
- }
31
-
32
- /**
33
- * Run tests to determine if auto-updates can run.
34
- *
35
- * @uses get_class_methods()
36
- * @uses substr()
37
- * @uses call_user_func()
38
- *
39
- * @return array
40
- */
41
- public function run_tests() {
42
- $tests = array();
43
-
44
- foreach ( get_class_methods( $this ) as $method ) {
45
- if ( 'test_' !== substr( $method, 0, 5 ) ) {
46
- continue;
47
- }
48
-
49
- $result = call_user_func( array( $this, $method ) );
50
-
51
- if ( false === $result || null === $result ) {
52
- continue;
53
- }
54
-
55
- $result = (object) $result;
56
-
57
- if ( empty( $result->severity ) ) {
58
- $result->severity = 'warning';
59
- }
60
-
61
- $tests[ $method ] = $result;
62
- }
63
-
64
- return $tests;
65
- }
66
-
67
- /**
68
- * Test if file modifications are possible.
69
- *
70
- * @uses defined()
71
- * @uses sprintf()
72
- * @uses esc_html__()
73
- *
74
- * @return array
75
- */
76
- function test_constant_FILE_MODS() {
77
- if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) {
78
- return array(
79
- 'desc' => sprintf(
80
- /* translators: %s: Name of the constant used. */
81
- esc_html__( 'The %s constant is defined and enabled.', 'health-check' ),
82
- '<code>DISALLOW_FILE_MODS</code>'
83
- ),
84
- 'severity' => 'fail',
85
- );
86
- }
87
- }
88
-
89
- /**
90
- * Check if automatic updates are disabled with a constant.
91
- *
92
- * @uses defined()
93
- * @uses sprintf()
94
- * @uses esc_html__()
95
- *
96
- * @return array
97
- */
98
- function test_constant_AUTOMATIC_UPDATER_DISABLED() {
99
- if ( defined( 'AUTOMATIC_UPDATER_DISABLED' ) && AUTOMATIC_UPDATER_DISABLED ) {
100
- return array(
101
- 'desc' => sprintf(
102
- /* translators: %s: Name of the constant used. */
103
- esc_html__( 'The %s constant is defined and enabled.', 'health-check' ),
104
- '<code>AUTOMATIC_UPDATER_DISABLED</code>'
105
- ),
106
- 'severity' => 'fail',
107
- );
108
- }
109
- }
110
-
111
- /**
112
- * Check if automatic core updates are disabled with a constant.
113
- *
114
- * @uses defined()
115
- * @uses sprintf()
116
- * @uses esc_html__()
117
- *
118
- * @return array
119
- */
120
- function test_constant_WP_AUTO_UPDATE_CORE() {
121
- if ( defined( 'WP_AUTO_UPDATE_CORE' ) && false === WP_AUTO_UPDATE_CORE ) {
122
- return array(
123
- 'desc' => sprintf(
124
- /* translators: %s: Name of the constant used. */
125
- esc_html__( 'The %s constant is defined and enabled.', 'health-check' ),
126
- '<code>WP_AUTO_UPDATE_CORE</code>'
127
- ),
128
- 'severity' => 'fail',
129
- );
130
- }
131
- }
132
-
133
- /**
134
- * Check if updates are intercepted by a filter.
135
- *
136
- * @uses has_filter()
137
- * @uses sprintf()
138
- * @uses esc_html__()
139
- *
140
- * @return array
141
- */
142
- function test_wp_version_check_attached() {
143
- if ( ! has_filter( 'wp_version_check', 'wp_version_check' ) ) {
144
- return array(
145
- 'desc' => sprintf(
146
- /* translators: %s: Name of the filter used. */
147
- esc_html__( 'A plugin has prevented updates by disabling %s.', 'health-check' ),
148
- '<code>wp_version_check()</code>'
149
- ),
150
- 'severity' => 'fail',
151
- );
152
- }
153
- }
154
-
155
- /**
156
- * Check if automatic updates are disabled by a filter.
157
- *
158
- * @uses apply_filters()
159
- * @uses sprintf()
160
- * @uses esc_html__()
161
- *
162
- * @return array
163
- */
164
- function test_filters_automatic_updater_disabled() {
165
- if ( apply_filters( 'automatic_updater_disabled', false ) ) {
166
- return array(
167
- 'desc' => sprintf(
168
- /* translators: %s: Name of the filter used. */
169
- esc_html__( 'The %s filter is enabled.', 'health-check' ),
170
- '<code>automatic_updater_disabled</code>'
171
- ),
172
- 'severity' => 'fail',
173
- );
174
- }
175
- }
176
-
177
- /**
178
- * Check if automatic updates have tried to run, but failed, previously.
179
- *
180
- * @uses get_site_option()
181
- * @uses esc_html__()
182
- * @uses sprintf()
183
- *
184
- * @return array|bool
185
- */
186
- function test_if_failed_update() {
187
- $failed = get_site_option( 'auto_core_update_failed' );
188
-
189
- if ( ! $failed ) {
190
- return false;
191
- }
192
-
193
- if ( ! empty( $failed['critical'] ) ) {
194
- $desc = esc_html__( 'A previous automatic background update ended with a critical failure, so updates are now disabled.', 'health-check' );
195
- $desc .= ' ' . esc_html__( 'You would have received an email because of this.', 'health-check' );
196
- $desc .= ' ' . esc_html__( "When you've been able to update using the \"Update Now\" button on Dashboard > Updates, we'll clear this error for future update attempts.", 'health-check' );
197
- $desc .= ' ' . sprintf(
198
- /* translators: %s: Code of error shown. */
199
- esc_html__( 'The error code was %s.', 'health-check' ),
200
- '<code>' . $failed['error_code'] . '</code>'
201
- );
202
- return array(
203
- 'desc' => $desc,
204
- 'severity' => 'warning',
205
- );
206
- }
207
-
208
- $desc = esc_html__( 'A previous automatic background update could not occur.', 'health-check' );
209
- if ( empty( $failed['retry'] ) ) {
210
- $desc .= ' ' . esc_html__( 'You would have received an email because of this.', 'health-check' );
211
- }
212
-
213
- $desc .= ' ' . esc_html__( "We'll try again with the next release.", 'health-check' );
214
- $desc .= ' ' . sprintf(
215
- /* translators: %s: Code of error shown. */
216
- esc_html__( 'The error code was %s.', 'health-check' ),
217
- '<code>' . $failed['error_code'] . '</code>'
218
- );
219
- return array(
220
- 'desc' => $desc,
221
- 'severity' => 'warning',
222
- );
223
- }
224
-
225
- /**
226
- * Check if WordPress is controlled by a VCS (Git, Subversion etc).
227
- *
228
- * @uses dirname()
229
- * @uses array_unique()
230
- * @uses is_dir()
231
- * @uses rtrim()
232
- * @uses apply_filters()
233
- * @uses sprintf()
234
- * @uses esc_html__()
235
- *
236
- * @param string $context The path to check from.
237
- *
238
- * @return array
239
- */
240
- function _test_is_vcs_checkout( $context ) {
241
- $context_dirs = array( ABSPATH );
242
- $vcs_dirs = array( '.svn', '.git', '.hg', '.bzr' );
243
- $check_dirs = array();
244
-
245
- foreach ( $context_dirs as $context_dir ) {
246
- // Walk up from $context_dir to the root.
247
- do {
248
- $check_dirs[] = $context_dir;
249
-
250
- // Once we've hit '/' or 'C:\', we need to stop. dirname will keep returning the input here.
251
- if ( dirname( $context_dir ) == $context_dir ) {
252
- break;
253
- }
254
-
255
- // Continue one level at a time.
256
- } while ( $context_dir = dirname( $context_dir ) );
257
- }
258
-
259
- $check_dirs = array_unique( $check_dirs );
260
-
261
- // Search all directories we've found for evidence of version control.
262
- foreach ( $vcs_dirs as $vcs_dir ) {
263
- foreach ( $check_dirs as $check_dir ) {
264
- // phpcs:ignore
265
- if ( $checkout = @is_dir( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" ) ) {
266
- break 2;
267
- }
268
- }
269
- }
270
-
271
- if ( $checkout && ! apply_filters( 'automatic_updates_is_vcs_checkout', true, $context ) ) {
272
- return array(
273
- 'desc' => sprintf(
274
- // translators: %1$s: Folder name. %2$s: Version control directory. %3$s: Filter name.
275
- esc_html__( 'The folder %1$s was detected as being under version control (%2$s), but the %3$s filter is allowing updates.', 'health-check' ),
276
- '<code>' . $check_dir . '</code>',
277
- "<code>$vcs_dir</code>",
278
- '<code>automatic_updates_is_vcs_checkout</code>'
279
- ),
280
- 'severity' => 'info',
281
- );
282
- }
283
-
284
- if ( $checkout ) {
285
- return array(
286
- 'desc' => sprintf(
287
- // translators: %1$s: Folder name. %2$s: Version control directory.
288
- esc_html__( 'The folder %1$s was detected as being under version control (%2$s).', 'health-check' ),
289
- '<code>' . $check_dir . '</code>',
290
- "<code>$vcs_dir</code>"
291
- ),
292
- 'severity' => 'fail',
293
- );
294
- }
295
-
296
- return array(
297
- 'desc' => esc_html__( 'No version control systems were detected.', 'health-check' ),
298
- 'severity' => 'pass',
299
- );
300
- }
301
-
302
- /**
303
- * Check if the absolute path is under Version Control.
304
- *
305
- * @uses Health_Check_Auto_Updates::_test_is_vcs_checkout()
306
- *
307
- * @return array
308
- */
309
- function test_vcs_ABSPATH() {
310
- $result = $this->_test_is_vcs_checkout( ABSPATH );
311
- return $result;
312
- }
313
-
314
- /**
315
- * Check if we can access files without providing credentials.
316
- *
317
- * @uses Automatic_Upgrader_Skin
318
- * @uses Automatic_Upgrader_Skin::request_filesystem_credentials()
319
- * @uses esc_html__()
320
- *
321
- * @return array
322
- */
323
- function test_check_wp_filesystem_method() {
324
- $skin = new Automatic_Upgrader_Skin;
325
- $success = $skin->request_filesystem_credentials( false, ABSPATH );
326
-
327
- if ( ! $success ) {
328
- $desc = esc_html__( 'Your installation of WordPress prompts for FTP credentials to perform updates.', 'health-check' );
329
- $desc .= ' ' . esc_html__( '(Your site is performing updates over FTP due to file ownership. Talk to your hosting company.)', 'health-check' );
330
-
331
- return array(
332
- 'desc' => $desc,
333
- 'severity' => 'fail',
334
- );
335
- }
336
-
337
- return array(
338
- 'desc' => esc_html__( "Your installation of WordPress doesn't require FTP credentials to perform updates.", 'health-check' ),
339
- 'severity' => 'pass',
340
- );
341
- }
342
-
343
- /**
344
- * Check if core files are writeable by the web user/group.
345
- *
346
- * @global $wp_filesystem
347
- *
348
- * @uses Automatic_Upgrader_Skin
349
- * @uses Automatic_Upgrader_Skin::request_filesystem_credentials()
350
- * @uses WP_Filesystem
351
- * @uses WP_Filesystem::method
352
- * @uses get_core_checksums()
353
- * @uses strpos()
354
- * @uses sprintf()
355
- * @uses esc_html__()
356
- * @uses array_keys()
357
- * @uses substr()
358
- * @uses file_exists()
359
- * @uses is_writable()
360
- * @uses count()
361
- * @uses array_slice()
362
- * @uses implode()
363
- *
364
- * @return array|bool
365
- */
366
- function test_all_files_writable() {
367
- global $wp_filesystem;
368
- include ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
369
-
370
- $skin = new Automatic_Upgrader_Skin;
371
- $success = $skin->request_filesystem_credentials( false, ABSPATH );
372
-
373
- if ( ! $success ) {
374
- return false;
375
- }
376
-
377
- WP_Filesystem();
378
-
379
- if ( 'direct' != $wp_filesystem->method ) {
380
- return false;
381
- }
382
-
383
- $checksums = get_core_checksums( $wp_version, 'en_US' );
384
- $dev = ( false !== strpos( $wp_version, '-' ) );
385
- // Get the last stable version's files and test against that
386
- if ( ! $checksums && $dev ) {
387
- $checksums = get_core_checksums( (float) $wp_version - 0.1, 'en_US' );
388
- }
389
-
390
- // There aren't always checksums for development releases, so just skip the test if we still can't find any
391
- if ( ! $checksums && $dev ) {
392
- return false;
393
- }
394
-
395
- if ( ! $checksums ) {
396
- $desc = sprintf(
397
- // translators: %s: WordPress version
398
- esc_html__( "Couldn't retrieve a list of the checksums for WordPress %s.", 'health-check' ),
399
- $wp_version
400
- );
401
- $desc .= ' ' . esc_html__( 'This could mean that connections are failing to WordPress.org.', 'health-check' );
402
- return array(
403
- 'desc' => $desc,
404
- 'severity' => 'warning',
405
- );
406
- }
407
-
408
- $unwritable_files = array();
409
- foreach ( array_keys( $checksums ) as $file ) {
410
- if ( 'wp-content' == substr( $file, 0, 10 ) ) {
411
- continue;
412
- }
413
- if ( ! file_exists( ABSPATH . '/' . $file ) ) {
414
- continue;
415
- }
416
- if ( ! is_writable( ABSPATH . '/' . $file ) ) {
417
- $unwritable_files[] = $file;
418
- }
419
- }
420
-
421
- if ( $unwritable_files ) {
422
- if ( count( $unwritable_files ) > 20 ) {
423
- $unwritable_files = array_slice( $unwritable_files, 0, 20 );
424
- $unwritable_files[] = '...';
425
- }
426
- return array(
427
- 'desc' => esc_html__( 'Some files are not writable by WordPress:', 'health-check' ) . ' <ul><li>' . implode( '</li><li>', $unwritable_files ) . '</li></ul>',
428
- 'severity' => 'fail',
429
- );
430
- } else {
431
- return array(
432
- 'desc' => esc_html__( 'All of your WordPress files are writable.', 'health-check' ),
433
- 'severity' => 'pass',
434
- );
435
- }
436
- }
437
-
438
- /**
439
- * Check if the install is using a development branch and can use nightly packages.
440
- *
441
- * @uses strpos()
442
- * @uses defined()
443
- * @uses sprintf()
444
- * @uses esc_html__()
445
- * @uses apply_filters()
446
- *
447
- * @return array|bool
448
- */
449
- function test_accepts_dev_updates() {
450
- include ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
451
- // Only for dev versions
452
- if ( false === strpos( $wp_version, '-' ) ) {
453
- return false;
454
- }
455
-
456
- if ( defined( 'WP_AUTO_UPDATE_CORE' ) && ( 'minor' === WP_AUTO_UPDATE_CORE || false === WP_AUTO_UPDATE_CORE ) ) {
457
- return array(
458
- 'desc' => sprintf(
459
- /* translators: %s: Name of the constant used. */
460
- esc_html__( 'WordPress development updates are blocked by the %s constant.', 'health-check' ),
461
- '<code>WP_AUTO_UPDATE_CORE</code>'
462
- ),
463
- 'severity' => 'fail',
464
- );
465
- }
466
-
467
- if ( ! apply_filters( 'allow_dev_auto_core_updates', $wp_version ) ) {
468
- return array(
469
- 'desc' => sprintf(
470
- /* translators: %s: Name of the filter used. */
471
- esc_html__( 'WordPress development updates are blocked by the %s filter.', 'health-check' ),
472
- '<code>allow_dev_auto_core_updates</code>'
473
- ),
474
- 'severity' => 'fail',
475
- );
476
- }
477
- }
478
-
479
- /**
480
- * Check if the site supports automatic minor updates.
481
- *
482
- * @uses defined()
483
- * @uses sprintf()
484
- * @uses esc_html__()
485
- * @uses apply_filters()
486
- *
487
- * @return array
488
- */
489
- function test_accepts_minor_updates() {
490
- if ( defined( 'WP_AUTO_UPDATE_CORE' ) && false === WP_AUTO_UPDATE_CORE ) {
491
- return array(
492
- 'desc' => sprintf(
493
- /* translators: %s: Name of the constant used. */
494
- esc_html__( 'WordPress security and maintenance releases are blocked by %s.', 'health-check' ),
495
- "<code>define( 'WP_AUTO_UPDATE_CORE', false );</code>"
496
- ),
497
- 'severity' => 'fail',
498
- );
499
- }
500
-
501
- if ( ! apply_filters( 'allow_minor_auto_core_updates', true ) ) {
502
- return array(
503
- 'desc' => sprintf(
504
- /* translators: %s: Name of the filter used. */
505
- esc_html__( 'WordPress security and maintenance releases are blocked by the %s filter.', 'health-check' ),
506
- '<code>allow_minor_auto_core_updates</code>'
507
- ),
508
- 'severity' => 'fail',
509
- );
510
- }
511
- }
512
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class for testing automatic updates in the WordPress code.
4
+ *
5
+ * @package Health Check
6
+ */
7
+
8
+ /**
9
+ * Class Health_Check_Auto_Updates
10
+ */
11
+ class Health_Check_Auto_Updates {
12
+ /**
13
+ * Health_Check_Auto_Updates constructor.
14
+ *
15
+ * @uses Health_Check::init()
16
+ *
17
+ * @return void
18
+ */
19
+ public function __construct() {
20
+ $this->init();
21
+ }
22
+
23
+ /**
24
+ * Initiate the plugin class.
25
+ *
26
+ * @return void
27
+ */
28
+ public function init() {
29
+ include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
30
+ }
31
+
32
+ /**
33
+ * Run tests to determine if auto-updates can run.
34
+ *
35
+ * @uses get_class_methods()
36
+ * @uses substr()
37
+ * @uses call_user_func()
38
+ *
39
+ * @return array
40
+ */
41
+ public function run_tests() {
42
+ $tests = array();
43
+
44
+ foreach ( get_class_methods( $this ) as $method ) {
45
+ if ( 'test_' !== substr( $method, 0, 5 ) ) {
46
+ continue;
47
+ }
48
+
49
+ $result = call_user_func( array( $this, $method ) );
50
+
51
+ if ( false === $result || null === $result ) {
52
+ continue;
53
+ }
54
+
55
+ $result = (object) $result;
56
+
57
+ if ( empty( $result->severity ) ) {
58
+ $result->severity = 'warning';
59
+ }
60
+
61
+ $tests[ $method ] = $result;
62
+ }
63
+
64
+ return $tests;
65
+ }
66
+
67
+ /**
68
+ * Test if file modifications are possible.
69
+ *
70
+ * @uses defined()
71
+ * @uses sprintf()
72
+ * @uses esc_html__()
73
+ *
74
+ * @return array
75
+ */
76
+ function test_constant_FILE_MODS() {
77
+ if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) {
78
+ return array(
79
+ 'desc' => sprintf(
80
+ /* translators: %s: Name of the constant used. */
81
+ esc_html__( 'The %s constant is defined and enabled.', 'health-check' ),
82
+ '<code>DISALLOW_FILE_MODS</code>'
83
+ ),
84
+ 'severity' => 'fail',
85
+ );
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Check if automatic updates are disabled with a constant.
91
+ *
92
+ * @uses defined()
93
+ * @uses sprintf()
94
+ * @uses esc_html__()
95
+ *
96
+ * @return array
97
+ */
98
+ function test_constant_AUTOMATIC_UPDATER_DISABLED() {
99
+ if ( defined( 'AUTOMATIC_UPDATER_DISABLED' ) && AUTOMATIC_UPDATER_DISABLED ) {
100
+ return array(
101
+ 'desc' => sprintf(
102
+ /* translators: %s: Name of the constant used. */
103
+ esc_html__( 'The %s constant is defined and enabled.', 'health-check' ),
104
+ '<code>AUTOMATIC_UPDATER_DISABLED</code>'
105
+ ),
106
+ 'severity' => 'fail',
107
+ );
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Check if automatic core updates are disabled with a constant.
113
+ *
114
+ * @uses defined()
115
+ * @uses sprintf()
116
+ * @uses esc_html__()
117
+ *
118
+ * @return array
119
+ */
120
+ function test_constant_WP_AUTO_UPDATE_CORE() {
121
+ if ( defined( 'WP_AUTO_UPDATE_CORE' ) && false === WP_AUTO_UPDATE_CORE ) {
122
+ return array(
123
+ 'desc' => sprintf(
124
+ /* translators: %s: Name of the constant used. */
125
+ esc_html__( 'The %s constant is defined and enabled.', 'health-check' ),
126
+ '<code>WP_AUTO_UPDATE_CORE</code>'
127
+ ),
128
+ 'severity' => 'fail',
129
+ );
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Check if updates are intercepted by a filter.
135
+ *
136
+ * @uses has_filter()
137
+ * @uses sprintf()
138
+ * @uses esc_html__()
139
+ *
140
+ * @return array
141
+ */
142
+ function test_wp_version_check_attached() {
143
+ $cookies = wp_unslash( $_COOKIE );
144
+ $timeout = 10;
145
+ $headers = array(
146
+ 'Cache-Control' => 'no-cache',
147
+ );
148
+
149
+ // Include Basic auth in loopback requests.
150
+ if ( isset( $_SERVER['PHP_AUTH_USER'] ) && isset( $_SERVER['PHP_AUTH_PW'] ) ) {
151
+ $headers['Authorization'] = 'Basic ' . base64_encode( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) . ':' . wp_unslash( $_SERVER['PHP_AUTH_PW'] ) );
152
+ }
153
+
154
+ $url = add_query_arg( array(
155
+ 'health-check-test-wp_version_check' => true,
156
+ ), admin_url() );
157
+
158
+ $test = wp_remote_get( $url, compact( 'cookies', 'headers', 'timeout' ) );
159
+
160
+ $response = wp_remote_retrieve_body( $test );
161
+
162
+ if ( 'yes' !== $response ) {
163
+ return array(
164
+ 'desc' => sprintf(
165
+ /* translators: %s: Name of the filter used. */
166
+ esc_html__( 'A plugin has prevented updates by disabling %s.', 'health-check' ),
167
+ '<code>wp_version_check()</code>'
168
+ ),
169
+ 'severity' => 'fail',
170
+ );
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Check if automatic updates are disabled by a filter.
176
+ *
177
+ * @uses apply_filters()
178
+ * @uses sprintf()
179
+ * @uses esc_html__()
180
+ *
181
+ * @return array
182
+ */
183
+ function test_filters_automatic_updater_disabled() {
184
+ if ( apply_filters( 'automatic_updater_disabled', false ) ) {
185
+ return array(
186
+ 'desc' => sprintf(
187
+ /* translators: %s: Name of the filter used. */
188
+ esc_html__( 'The %s filter is enabled.', 'health-check' ),
189
+ '<code>automatic_updater_disabled</code>'
190
+ ),
191
+ 'severity' => 'fail',
192
+ );
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Check if automatic updates have tried to run, but failed, previously.
198
+ *
199
+ * @uses get_site_option()
200
+ * @uses esc_html__()
201
+ * @uses sprintf()
202
+ *
203
+ * @return array|bool
204
+ */
205
+ function test_if_failed_update() {
206
+ $failed = get_site_option( 'auto_core_update_failed' );
207
+
208
+ if ( ! $failed ) {
209
+ return false;
210
+ }
211
+
212
+ if ( ! empty( $failed['critical'] ) ) {
213
+ $desc = esc_html__( 'A previous automatic background update ended with a critical failure, so updates are now disabled.', 'health-check' );
214
+ $desc .= ' ' . esc_html__( 'You would have received an email because of this.', 'health-check' );
215
+ $desc .= ' ' . esc_html__( "When you've been able to update using the \"Update Now\" button on Dashboard > Updates, we'll clear this error for future update attempts.", 'health-check' );
216
+ $desc .= ' ' . sprintf(
217
+ /* translators: %s: Code of error shown. */
218
+ esc_html__( 'The error code was %s.', 'health-check' ),
219
+ '<code>' . $failed['error_code'] . '</code>'
220
+ );
221
+ return array(
222
+ 'desc' => $desc,
223
+ 'severity' => 'warning',
224
+ );
225
+ }
226
+
227
+ $desc = esc_html__( 'A previous automatic background update could not occur.', 'health-check' );
228
+ if ( empty( $failed['retry'] ) ) {
229
+ $desc .= ' ' . esc_html__( 'You would have received an email because of this.', 'health-check' );
230
+ }
231
+
232
+ $desc .= ' ' . esc_html__( "We'll try again with the next release.", 'health-check' );
233
+ $desc .= ' ' . sprintf(
234
+ /* translators: %s: Code of error shown. */
235
+ esc_html__( 'The error code was %s.', 'health-check' ),
236
+ '<code>' . $failed['error_code'] . '</code>'
237
+ );
238
+ return array(
239
+ 'desc' => $desc,
240
+ 'severity' => 'warning',
241
+ );
242
+ }
243
+
244
+ /**
245
+ * Check if WordPress is controlled by a VCS (Git, Subversion etc).
246
+ *
247
+ * @uses dirname()
248
+ * @uses array_unique()
249
+ * @uses is_dir()
250
+ * @uses rtrim()
251
+ * @uses apply_filters()
252
+ * @uses sprintf()
253
+ * @uses esc_html__()
254
+ *
255
+ * @param string $context The path to check from.
256
+ *
257
+ * @return array
258
+ */
259
+ function _test_is_vcs_checkout( $context ) {
260
+ $context_dirs = array( ABSPATH );
261
+ $vcs_dirs = array( '.svn', '.git', '.hg', '.bzr' );
262
+ $check_dirs = array();
263
+
264
+ foreach ( $context_dirs as $context_dir ) {
265
+ // Walk up from $context_dir to the root.
266
+ do {
267
+ $check_dirs[] = $context_dir;
268
+
269
+ // Once we've hit '/' or 'C:\', we need to stop. dirname will keep returning the input here.
270
+ if ( dirname( $context_dir ) == $context_dir ) {
271
+ break;
272
+ }
273
+
274
+ // Continue one level at a time.
275
+ } while ( $context_dir = dirname( $context_dir ) );
276
+ }
277
+
278
+ $check_dirs = array_unique( $check_dirs );
279
+
280
+ // Search all directories we've found for evidence of version control.
281
+ foreach ( $vcs_dirs as $vcs_dir ) {
282
+ foreach ( $check_dirs as $check_dir ) {
283
+ // phpcs:ignore
284
+ if ( $checkout = @is_dir( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" ) ) {
285
+ break 2;
286
+ }
287
+ }
288
+ }
289
+
290
+ if ( $checkout && ! apply_filters( 'automatic_updates_is_vcs_checkout', true, $context ) ) {
291
+ return array(
292
+ 'desc' => sprintf(
293
+ // translators: %1$s: Folder name. %2$s: Version control directory. %3$s: Filter name.
294
+ esc_html__( 'The folder %1$s was detected as being under version control (%2$s), but the %3$s filter is allowing updates.', 'health-check' ),
295
+ '<code>' . $check_dir . '</code>',
296
+ "<code>$vcs_dir</code>",
297
+ '<code>automatic_updates_is_vcs_checkout</code>'
298
+ ),
299
+ 'severity' => 'info',
300
+ );
301
+ }
302
+
303
+ if ( $checkout ) {
304
+ return array(
305
+ 'desc' => sprintf(
306
+ // translators: %1$s: Folder name. %2$s: Version control directory.
307
+ esc_html__( 'The folder %1$s was detected as being under version control (%2$s).', 'health-check' ),
308
+ '<code>' . $check_dir . '</code>',
309
+ "<code>$vcs_dir</code>"
310
+ ),
311
+ 'severity' => 'fail',
312
+ );
313
+ }
314
+
315
+ return array(
316
+ 'desc' => esc_html__( 'No version control systems were detected.', 'health-check' ),
317
+ 'severity' => 'pass',
318
+ );
319
+ }
320
+
321
+ /**
322
+ * Check if the absolute path is under Version Control.
323
+ *
324
+ * @uses Health_Check_Auto_Updates::_test_is_vcs_checkout()
325
+ *
326
+ * @return array
327
+ */
328
+ function test_vcs_ABSPATH() {
329
+ $result = $this->_test_is_vcs_checkout( ABSPATH );
330
+ return $result;
331
+ }
332
+
333
+ /**
334
+ * Check if we can access files without providing credentials.
335
+ *
336
+ * @uses Automatic_Upgrader_Skin
337
+ * @uses Automatic_Upgrader_Skin::request_filesystem_credentials()
338
+ * @uses esc_html__()
339
+ *
340
+ * @return array
341
+ */
342
+ function test_check_wp_filesystem_method() {
343
+ $skin = new Automatic_Upgrader_Skin;
344
+ $success = $skin->request_filesystem_credentials( false, ABSPATH );
345
+
346
+ if ( ! $success ) {
347
+ $desc = esc_html__( 'Your installation of WordPress prompts for FTP credentials to perform updates.', 'health-check' );
348
+ $desc .= ' ' . esc_html__( '(Your site is performing updates over FTP due to file ownership. Talk to your hosting company.)', 'health-check' );
349
+
350
+ return array(
351
+ 'desc' => $desc,
352
+ 'severity' => 'fail',
353
+ );
354
+ }
355
+
356
+ return array(
357
+ 'desc' => esc_html__( "Your installation of WordPress doesn't require FTP credentials to perform updates.", 'health-check' ),
358
+ 'severity' => 'pass',
359
+ );
360
+ }
361
+
362
+ /**
363
+ * Check if core files are writeable by the web user/group.
364
+ *
365
+ * @global $wp_filesystem
366
+ *
367
+ * @uses Automatic_Upgrader_Skin
368
+ * @uses Automatic_Upgrader_Skin::request_filesystem_credentials()
369
+ * @uses WP_Filesystem
370
+ * @uses WP_Filesystem::method
371
+ * @uses get_core_checksums()
372
+ * @uses strpos()
373
+ * @uses sprintf()
374
+ * @uses esc_html__()
375
+ * @uses array_keys()
376
+ * @uses substr()
377
+ * @uses file_exists()
378
+ * @uses is_writable()
379
+ * @uses count()
380
+ * @uses array_slice()
381
+ * @uses implode()
382
+ *
383
+ * @return array|bool
384
+ */
385
+ function test_all_files_writable() {
386
+ global $wp_filesystem;
387
+ include ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
388
+
389
+ $skin = new Automatic_Upgrader_Skin;
390
+ $success = $skin->request_filesystem_credentials( false, ABSPATH );
391
+
392
+ if ( ! $success ) {
393
+ return false;
394
+ }
395
+
396
+ WP_Filesystem();
397
+
398
+ if ( 'direct' != $wp_filesystem->method ) {
399
+ return false;
400
+ }
401
+
402
+ $checksums = get_core_checksums( $wp_version, 'en_US' );
403
+ $dev = ( false !== strpos( $wp_version, '-' ) );
404
+ // Get the last stable version's files and test against that
405
+ if ( ! $checksums && $dev ) {
406
+ $checksums = get_core_checksums( (float) $wp_version - 0.1, 'en_US' );
407
+ }
408
+
409
+ // There aren't always checksums for development releases, so just skip the test if we still can't find any
410
+ if ( ! $checksums && $dev ) {
411
+ return false;
412
+ }
413
+
414
+ if ( ! $checksums ) {
415
+ $desc = sprintf(
416
+ // translators: %s: WordPress version
417
+ esc_html__( "Couldn't retrieve a list of the checksums for WordPress %s.", 'health-check' ),
418
+ $wp_version
419
+ );
420
+ $desc .= ' ' . esc_html__( 'This could mean that connections are failing to WordPress.org.', 'health-check' );
421
+ return array(
422
+ 'desc' => $desc,
423
+ 'severity' => 'warning',
424
+ );
425
+ }
426
+
427
+ $unwritable_files = array();
428
+ foreach ( array_keys( $checksums ) as $file ) {
429
+ if ( 'wp-content' == substr( $file, 0, 10 ) ) {
430
+ continue;
431
+ }
432
+ if ( ! file_exists( ABSPATH . '/' . $file ) ) {
433
+ continue;
434
+ }
435
+ if ( ! is_writable( ABSPATH . '/' . $file ) ) {
436
+ $unwritable_files[] = $file;
437
+ }
438
+ }
439
+
440
+ if ( $unwritable_files ) {
441
+ if ( count( $unwritable_files ) > 20 ) {
442
+ $unwritable_files = array_slice( $unwritable_files, 0, 20 );
443
+ $unwritable_files[] = '...';
444
+ }
445
+ return array(
446
+ 'desc' => esc_html__( 'Some files are not writable by WordPress:', 'health-check' ) . ' <ul><li>' . implode( '</li><li>', $unwritable_files ) . '</li></ul>',
447
+ 'severity' => 'fail',
448
+ );
449
+ } else {
450
+ return array(
451
+ 'desc' => esc_html__( 'All of your WordPress files are writable.', 'health-check' ),
452
+ 'severity' => 'pass',
453
+ );
454
+ }
455
+ }
456
+
457
+ /**
458
+ * Check if the install is using a development branch and can use nightly packages.
459
+ *
460
+ * @uses strpos()
461
+ * @uses defined()
462
+ * @uses sprintf()
463
+ * @uses esc_html__()
464
+ * @uses apply_filters()
465
+ *
466
+ * @return array|bool
467
+ */
468
+ function test_accepts_dev_updates() {
469
+ include ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
470
+ // Only for dev versions
471
+ if ( false === strpos( $wp_version, '-' ) ) {
472
+ return false;
473
+ }
474
+
475
+ if ( defined( 'WP_AUTO_UPDATE_CORE' ) && ( 'minor' === WP_AUTO_UPDATE_CORE || false === WP_AUTO_UPDATE_CORE ) ) {
476
+ return array(
477
+ 'desc' => sprintf(
478
+ /* translators: %s: Name of the constant used. */
479
+ esc_html__( 'WordPress development updates are blocked by the %s constant.', 'health-check' ),
480
+ '<code>WP_AUTO_UPDATE_CORE</code>'
481
+ ),
482
+ 'severity' => 'fail',
483
+ );
484
+ }
485
+
486
+ if ( ! apply_filters( 'allow_dev_auto_core_updates', $wp_version ) ) {
487
+ return array(
488
+ 'desc' => sprintf(
489
+ /* translators: %s: Name of the filter used. */
490
+ esc_html__( 'WordPress development updates are blocked by the %s filter.', 'health-check' ),
491
+ '<code>allow_dev_auto_core_updates</code>'
492
+ ),
493
+ 'severity' => 'fail',
494
+ );
495
+ }
496
+ }
497
+
498
+ /**
499
+ * Check if the site supports automatic minor updates.
500
+ *
501
+ * @uses defined()
502
+ * @uses sprintf()
503
+ * @uses esc_html__()
504
+ * @uses apply_filters()
505
+ *
506
+ * @return array
507
+ */
508
+ function test_accepts_minor_updates() {
509
+ if ( defined( 'WP_AUTO_UPDATE_CORE' ) && false === WP_AUTO_UPDATE_CORE ) {
510
+ return array(
511
+ 'desc' => sprintf(
512
+ /* translators: %s: Name of the constant used. */
513
+ esc_html__( 'WordPress security and maintenance releases are blocked by %s.', 'health-check' ),
514
+ "<code>define( 'WP_AUTO_UPDATE_CORE', false );</code>"
515
+ ),
516
+ 'severity' => 'fail',
517
+ );
518
+ }
519
+
520
+ if ( ! apply_filters( 'allow_minor_auto_core_updates', true ) ) {
521
+ return array(
522
+ 'desc' => sprintf(
523
+ /* translators: %s: Name of the filter used. */
524
+ esc_html__( 'WordPress security and maintenance releases are blocked by the %s filter.', 'health-check' ),
525
+ '<code>allow_minor_auto_core_updates</code>'
526
+ ),
527
+ 'severity' => 'fail',
528
+ );
529
+ }
530
+ }
531
+ }
includes/class-health-check-loopback.php CHANGED
@@ -101,7 +101,7 @@ class Health_Check_Loopback {
101
  *
102
  * @uses ob_start()
103
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
104
- * @uses HealthCheck::get_filesystem_credentials()
105
  * @uses Health_Check_Troubleshoot::setup_must_use_plugin()
106
  * @uses Health_Check_Troubleshoot::maybe_update_must_use_plugin()
107
  * @uses ob_get_clean()
@@ -124,7 +124,7 @@ class Health_Check_Loopback {
124
  $needs_creds = false;
125
 
126
  if ( ! Health_Check_Troubleshoot::mu_plugin_exists() ) {
127
- if ( ! HealthCheck::get_filesystem_credentials() ) {
128
  $needs_creds = true;
129
  } else {
130
  $check_output = Health_Check_Troubleshoot::setup_must_use_plugin();
@@ -159,6 +159,34 @@ class Health_Check_Loopback {
159
  );
160
 
161
  if ( 'error' !== $no_plugin_test->status ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  $message .= '<br><button type="button" id="loopback-individual-plugins" class="button button-primary">Test individual plugins</button>';
163
  }
164
 
@@ -180,7 +208,7 @@ class Health_Check_Loopback {
180
  *
181
  * @uses ob_start()
182
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
183
- * @uses HealthCheck::get_filesystem_credentials()
184
  * @uses Health_Check_Troubleshoot::setup_must_use_plugin()
185
  * @uses ob_get_clean()
186
  * @uses wp_send_json_error()
@@ -205,7 +233,7 @@ class Health_Check_Loopback {
205
  $needs_creds = false;
206
 
207
  if ( ! Health_Check_Troubleshoot::mu_plugin_exists() ) {
208
- if ( ! HealthCheck::get_filesystem_credentials() ) {
209
  $needs_creds = true;
210
  } else {
211
  Health_Check_Troubleshoot::setup_must_use_plugin();
@@ -221,40 +249,64 @@ class Health_Check_Loopback {
221
 
222
  delete_option( 'health-check-disable-plugin-hash' );
223
 
224
- $all_plugins = get_option( 'active_plugins' );
225
-
226
  $loopback_hash = md5( rand() );
227
  update_option( 'health-check-disable-plugin-hash', $loopback_hash );
228
 
229
- $message = '';
 
230
 
231
- foreach ( $all_plugins as $single_plugin ) {
232
- $plugin_slug = explode( '/', $single_plugin );
233
- $plugin_slug = $plugin_slug[0];
234
 
235
- $single_test = Health_Check_Loopback::can_perform_loopback( $loopback_hash, $plugin_slug );
 
 
 
 
236
 
237
- $message .= sprintf(
238
- '<br><span class="%s"></span> %s: %s',
239
- esc_attr( $single_test->status ),
240
- sprintf(
241
- // Translators: %s: Plugin slug being tested.
242
- esc_html__( 'Testing %s', 'health-check' ),
243
- $plugin_slug
244
- ),
245
- $single_test->message
246
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
248
 
 
 
 
 
 
 
 
249
  // Test without a theme active.
250
  update_option( 'health-check-default-theme', 'yes' );
251
 
252
  $theme_test = Health_Check_Loopback::can_perform_loopback( $loopback_hash, '' );
253
 
254
  $message .= sprintf(
255
- '<br><span class="%s"></span> %s: %s',
256
  esc_attr( $theme_test->status ),
257
- esc_html__( 'Testing a default theme', 'health-check' ),
258
  $theme_test->message
259
  );
260
 
101
  *
102
  * @uses ob_start()
103
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
104
+ * @uses Health_Check::get_filesystem_credentials()
105
  * @uses Health_Check_Troubleshoot::setup_must_use_plugin()
106
  * @uses Health_Check_Troubleshoot::maybe_update_must_use_plugin()
107
  * @uses ob_get_clean()
124
  $needs_creds = false;
125
 
126
  if ( ! Health_Check_Troubleshoot::mu_plugin_exists() ) {
127
+ if ( ! Health_Check::get_filesystem_credentials() ) {
128
  $needs_creds = true;
129
  } else {
130
  $check_output = Health_Check_Troubleshoot::setup_must_use_plugin();
159
  );
160
 
161
  if ( 'error' !== $no_plugin_test->status ) {
162
+ $plugins = wp_get_active_and_valid_plugins();
163
+ $theme = wp_get_theme();
164
+
165
+ $message .= '<table id="loopback-individual-plugins-list">';
166
+
167
+ foreach ( $plugins as $single_plugin ) {
168
+ $plugin = get_plugin_data( $single_plugin );
169
+
170
+ $message .= sprintf(
171
+ '<tr data-test-plugin="%s" class="not-tested"><td>%s</td><td class="individual-loopback-test-status">%s</td></tr>',
172
+ esc_attr( plugin_basename( $single_plugin ) ),
173
+ esc_html( $plugin['Name'] ),
174
+ esc_html__( 'Waiting...', 'health-check' )
175
+ );
176
+ }
177
+
178
+ $message .= sprintf(
179
+ '<tr id="test-single-no-theme"><td>%s</td><td class="individual-loopback-test-status">%s</td></tr>',
180
+ sprintf(
181
+ // translators: %s: The active theme name.
182
+ esc_html__( 'Active theme: %s', 'health-check' ),
183
+ $theme->name
184
+ ),
185
+ esc_html__( 'Waiting...', 'health-check' )
186
+ );
187
+
188
+ $message .= '</table>';
189
+
190
  $message .= '<br><button type="button" id="loopback-individual-plugins" class="button button-primary">Test individual plugins</button>';
191
  }
192
 
208
  *
209
  * @uses ob_start()
210
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
211
+ * @uses Health_Check::get_filesystem_credentials()
212
  * @uses Health_Check_Troubleshoot::setup_must_use_plugin()
213
  * @uses ob_get_clean()
214
  * @uses wp_send_json_error()
233
  $needs_creds = false;
234
 
235
  if ( ! Health_Check_Troubleshoot::mu_plugin_exists() ) {
236
+ if ( ! Health_Check::get_filesystem_credentials() ) {
237
  $needs_creds = true;
238
  } else {
239
  Health_Check_Troubleshoot::setup_must_use_plugin();
249
 
250
  delete_option( 'health-check-disable-plugin-hash' );
251
 
 
 
252
  $loopback_hash = md5( rand() );
253
  update_option( 'health-check-disable-plugin-hash', $loopback_hash );
254
 
255
+ $plugin_slug = explode( '/', $_POST['plugin'] );
256
+ $plugin_slug = $plugin_slug[0];
257
 
258
+ $single_test = Health_Check_Loopback::can_perform_loopback( $loopback_hash, $plugin_slug );
 
 
259
 
260
+ $message = sprintf(
261
+ '<span class="%s"></span> %s',
262
+ esc_attr( $single_test->status ),
263
+ $single_test->message
264
+ );
265
 
266
+ $response = array(
267
+ 'message' => $message,
268
+ );
269
+
270
+ wp_send_json_success( $response );
271
+
272
+ die();
273
+ }
274
+
275
+ static function loopback_test_default_theme() {
276
+ ob_start();
277
+
278
+ $needs_creds = false;
279
+
280
+ if ( ! Health_Check_Troubleshoot::mu_plugin_exists() ) {
281
+ if ( ! Health_Check::get_filesystem_credentials() ) {
282
+ $needs_creds = true;
283
+ } else {
284
+ Health_Check_Troubleshoot::setup_must_use_plugin();
285
+ }
286
+ }
287
+
288
+ $result = ob_get_clean();
289
+
290
+ if ( $needs_creds ) {
291
+ wp_send_json_error( $result );
292
+ die();
293
  }
294
 
295
+ delete_option( 'health-check-disable-plugin-hash' );
296
+
297
+ $loopback_hash = md5( rand() );
298
+ update_option( 'health-check-disable-plugin-hash', $loopback_hash );
299
+
300
+ $message = '';
301
+
302
  // Test without a theme active.
303
  update_option( 'health-check-default-theme', 'yes' );
304
 
305
  $theme_test = Health_Check_Loopback::can_perform_loopback( $loopback_hash, '' );
306
 
307
  $message .= sprintf(
308
+ '<span class="%s"></span> %s',
309
  esc_attr( $theme_test->status ),
 
310
  $theme_test->message
311
  );
312
 
includes/class-health-check-site-status.php ADDED
@@ -0,0 +1,689 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Health_Check_Site_Status {
4
+ private $php_min_version_check;
5
+ private $php_supported_version_check;
6
+ private $php_rec_version_check;
7
+
8
+ private $mysql_min_version_check;
9
+ private $mysql_rec_version_check;
10
+
11
+ public $mariadb = false;
12
+ private $mysql_server_version = null;
13
+ private $health_check_mysql_rec_version = null;
14
+
15
+ public function __construct() {
16
+ $this->init();
17
+ }
18
+
19
+ public function init() {
20
+ $this->php_min_version_check = version_compare( HEALTH_CHECK_PHP_MIN_VERSION, PHP_VERSION, '<=' );
21
+ $this->php_supported_version_check = version_compare( HEALTH_CHECK_PHP_SUPPORTED_VERSION, PHP_VERSION, '<=' );
22
+ $this->php_rec_version_check = version_compare( HEALTH_CHECK_PHP_REC_VERSION, PHP_VERSION, '<=' );
23
+
24
+ $this->prepare_sql_data();
25
+
26
+ add_action( 'wp_ajax_health-check-site-status', array( $this, 'site_status' ) );
27
+
28
+ add_action( 'wp_loaded', array( $this, 'check_wp_version_check_exists' ) );
29
+ }
30
+
31
+ private function prepare_sql_data() {
32
+ global $wpdb;
33
+
34
+ if ( method_exists( $wpdb, 'db_version' ) ) {
35
+ if ( $wpdb->use_mysqli ) {
36
+ // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_server_info
37
+ $mysql_server_type = mysqli_get_server_info( $wpdb->dbh );
38
+ } else {
39
+ // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_server_info
40
+ $mysql_server_type = mysql_get_server_info( $wpdb->dbh );
41
+ }
42
+
43
+ $this->mysql_server_version = $wpdb->get_var( 'SELECT VERSION()' );
44
+ }
45
+
46
+ $this->health_check_mysql_rec_version = HEALTH_CHECK_MYSQL_REC_VERSION;
47
+
48
+ if ( stristr( $mysql_server_type, 'mariadb' ) ) {
49
+ $this->mariadb = true;
50
+ $this->health_check_mysql_rec_version = '10.0';
51
+ }
52
+
53
+ $this->mysql_min_version_check = version_compare( HEALTH_CHECK_MYSQL_MIN_VERSION, $this->mysql_server_version, '<=' );
54
+ $this->mysql_rec_version_check = version_compare( $this->health_check_mysql_rec_version, $this->mysql_server_version, '<=' );
55
+ }
56
+
57
+ public function check_wp_version_check_exists() {
58
+ if ( ! is_admin() || ! is_user_logged_in() || ! current_user_can( 'manage_options' ) || ! isset( $_GET['health-check-test-wp_version_check'] ) ) {
59
+ return;
60
+ }
61
+
62
+ echo ( has_filter( 'wp_version_check', 'wp_version_check' ) ? 'yes' : 'no' );
63
+
64
+ die();
65
+ }
66
+
67
+ public function site_status() {
68
+ $function = sprintf(
69
+ 'test_%s',
70
+ $_POST['feature']
71
+ );
72
+
73
+ if ( ! method_exists( $this, $function ) || ! is_callable( array( $this, $function ) ) ) {
74
+ die();
75
+ }
76
+
77
+ $call = call_user_func( array( $this, $function ) );
78
+
79
+ die();
80
+ }
81
+
82
+ public function test_wordpress_version() {
83
+ $core_current_version = get_bloginfo( 'version' );
84
+ $core_updates = get_core_updates();
85
+
86
+ if ( ! is_array( $core_updates ) ) {
87
+ printf(
88
+ '<span class="warning"></span> %s',
89
+ sprintf(
90
+ // translators: %s: Your current version of WordPress.
91
+ esc_html__( '%s - We were unable to check if any new versions are available.', 'health-check' ),
92
+ $core_current_version
93
+ )
94
+ );
95
+ } else {
96
+ foreach ( $core_updates as $core => $update ) {
97
+ if ( 'upgrade' === $update->response ) {
98
+ $current_version = explode( '.', $core_current_version );
99
+ $new_version = explode( '.', $update->version );
100
+
101
+ $current_major = $current_version[0] . '.' . $current_version[1];
102
+ $new_major = $new_version[0] . '.' . $new_version[1];
103
+
104
+ if ( $current_major !== $new_major ) {
105
+ // This is a major version mismatch.
106
+ printf(
107
+ '<span class="warning"></span> %s',
108
+ sprintf(
109
+ // translators: %1$s: Your current version of WordPress. %2$s The latest version of WordPress available.
110
+ esc_html__( '%1$s ( Latest version: %2$s )', 'health-check' ),
111
+ $core_current_version,
112
+ $update->version
113
+ )
114
+ );
115
+ } else {
116
+ // This is a minor version, sometimes considered more critical.
117
+ printf(
118
+ '<span class="error"></span> %s',
119
+ sprintf(
120
+ // translators: %1$s: Your current version of WordPress. %2$s The latest version of WordPress available.
121
+ esc_html__( '%1$s ( Latest version: %2$s ) - We strongly urge you to update, as minor updates are often security related.', 'health-check' ),
122
+ $core_current_version,
123
+ $update->version
124
+ )
125
+ );
126
+ }
127
+ } else {
128
+ printf(
129
+ '<span class="good"></span> %s',
130
+ esc_html( $core_current_version )
131
+ );
132
+ }
133
+ }
134
+ }
135
+ }
136
+
137
+ public function test_plugin_version() {
138
+ $plugins = get_plugins();
139
+ $plugin_updates = get_plugin_updates();
140
+
141
+ $show_unused_plugins = true;
142
+ $plugins_have_updates = false;
143
+ $plugins_active = 0;
144
+ $plugins_total = 0;
145
+ $plugins_needs_update = 0;
146
+
147
+ if ( class_exists( 'Health_Check_Troubleshooting_MU' ) ) {
148
+ $troubleshooting = new Health_Check_Troubleshooting_MU();
149
+
150
+ if ( $troubleshooting->is_troubleshooting() ) {
151
+ $show_unused_plugins = false;
152
+ }
153
+ }
154
+
155
+ foreach ( $plugins as $plugin_path => $plugin ) {
156
+ $plugins_total++;
157
+
158
+ if ( is_plugin_active( $plugin_path ) ) {
159
+ $plugins_active++;
160
+ }
161
+
162
+ $plugin_version = $plugin['Version'];
163
+
164
+ if ( array_key_exists( $plugin_path, $plugin_updates ) ) {
165
+ $plugins_needs_update++;
166
+ $plugins_have_updates = true;
167
+ }
168
+ }
169
+
170
+ echo '<ul>';
171
+
172
+ if ( $plugins_needs_update > 0 ) {
173
+ printf(
174
+ '<li><span class="error"></span> %s',
175
+ sprintf(
176
+ // translators: %d: The amount of outdated plugins.
177
+ esc_html( _n(
178
+ 'Your site has %d plugin waiting to be updated.',
179
+ 'Your site has %d plugins waiting to be updated.',
180
+ $plugins_needs_update,
181
+ 'health-check'
182
+ ) ),
183
+ $plugins_needs_update
184
+ )
185
+ );
186
+ } else {
187
+ printf(
188
+ '<li><span class="good"></span> %s',
189
+ sprintf(
190
+ // translators: %d: The amount of plugins.
191
+ esc_html( _n(
192
+ 'Your site has %d active plugin, and it is up to date.',
193
+ 'Your site has %d active plugins, and they are all up to date.',
194
+ $plugins_total,
195
+ 'health-check'
196
+ ) ),
197
+ $plugins_total
198
+ )
199
+ );
200
+ }
201
+
202
+ if ( ( $plugins_total > $plugins_active ) && $show_unused_plugins ) {
203
+ $unused_plugins = $plugins_total - $plugins_active;
204
+ printf(
205
+ '<li><span class="warning"></span> %s',
206
+ sprintf(
207
+ // translators: %d: The amount of inactive plugins.
208
+ esc_html( _n(
209
+ 'Your site has %d inactive plugin, it is recommended to remove any unused plugins to enhance your site security.',
210
+ 'Your site has %d inactive plugins, it is recommended to remove any unused plugins to enhance your site security.',
211
+ $unused_plugins,
212
+ 'health-check'
213
+ ) ),
214
+ $unused_plugins
215
+ )
216
+ );
217
+ }
218
+
219
+ echo '</ul>';
220
+ }
221
+
222
+ public function test_theme_version() {
223
+ $theme_updates = get_theme_updates();
224
+
225
+ $themes_total = 0;
226
+ $themes_need_updates = 0;
227
+ $themes_inactive = 0;
228
+
229
+ // This value is changed dduring processing to determine how many themes are considered a reasonable amount.
230
+ $allowed_theme_count = 1;
231
+
232
+ $has_default_theme = false;
233
+ $has_unused_themes = false;
234
+ $show_unused_themes = true;
235
+
236
+ if ( class_exists( 'Health_Check_Troubleshooting_MU' ) ) {
237
+ $troubleshooting = new Health_Check_Troubleshooting_MU();
238
+
239
+ if ( $troubleshooting->is_troubleshooting() ) {
240
+ $show_unused_themes = false;
241
+ }
242
+ }
243
+
244
+ // Populate a list of all themes available in the install.
245
+ $all_themes = wp_get_themes();
246
+ $active_theme = wp_get_theme();
247
+
248
+ foreach ( $all_themes as $theme_slug => $theme ) {
249
+ $themes_total++;
250
+
251
+ if ( WP_DEFAULT_THEME === $theme_slug ) {
252
+ $has_default_theme = true;
253
+ }
254
+
255
+ if ( array_key_exists( $theme_slug, $theme_updates ) ) {
256
+ $themes_need_updates++;
257
+ }
258
+ }
259
+
260
+ // If this is a child theme, increase the allowed theme count by one, to account for the parent.
261
+ if ( $active_theme->parent() ) {
262
+ $allowed_theme_count++;
263
+ }
264
+
265
+ // If there's a default theme installed, we count that as allowed as well.
266
+ if ( $has_default_theme ) {
267
+ $allowed_theme_count++;
268
+ }
269
+
270
+ if ( $themes_total > $allowed_theme_count ) {
271
+ $has_unused_themes = true;
272
+ $themes_inactive = ( $themes_total - $allowed_theme_count );
273
+ }
274
+
275
+ echo '<ul>';
276
+
277
+ if ( $themes_need_updates > 0 ) {
278
+ printf(
279
+ '<li><span class="error"></span> %s',
280
+ sprintf(
281
+ // translators: %d: The amount of outdated themes.
282
+ esc_html( _n(
283
+ 'Your site has %d theme waiting to be updated.',
284
+ 'Your site has %d themes waiting to be updated.',
285
+ $themes_need_updates,
286
+ 'health-check'
287
+ ) ),
288
+ $themes_need_updates
289
+ )
290
+ );
291
+ } else {
292
+ printf(
293
+ '<li><span class="good"></span> %s',
294
+ sprintf(
295
+ // translators: %d: The amount of themes.
296
+ esc_html( _n(
297
+ 'Your site has %d installed theme, and it is up to date.',
298
+ 'Your site has %d installed themes, and they are all up to date.',
299
+ $themes_total,
300
+ 'health-check'
301
+ ) ),
302
+ $themes_total
303
+ )
304
+ );
305
+ }
306
+
307
+ if ( $has_unused_themes && $show_unused_themes ) {
308
+
309
+ // This is a child theme, so we want to be a bit more explicit in our messages.
310
+ if ( $active_theme->parent() ) {
311
+ printf(
312
+ '<li><span class="warning"></span> %s',
313
+ sprintf(
314
+ // translators: %1$d: The amount of inactive themes. %2$s: The default theme for WordPress. %3$s: The currently active theme. %4$s: The active themes parent theme.
315
+ esc_html( _n(
316
+ 'Your site has %1$d inactive theme. To enhance your sites security it is recommended to remove any unused themes. You should keep %2$s, the default WordPress theme, %3$s, your current theme and %4$s, the parent theme.',
317
+ 'Your site has %1$d inactive themes. To enhance your sites security it is recommended to remove any unused themes. You should keep %2$s, the default WordPress theme, %3$s, your current theme and %4$s, the parent theme. ',
318
+ $themes_inactive,
319
+ 'health-check'
320
+ ) ),
321
+ $themes_inactive,
322
+ WP_DEFAULT_THEME,
323
+ $active_theme->name,
324
+ $active_theme->parent()->name
325
+ )
326
+ );
327
+
328
+ } else {
329
+ printf(
330
+ '<li><span class="warning"></span> %s',
331
+ sprintf(
332
+ // translators: %1$d: The amount of inactive themes. %2$s: The default theme for WordPress. %3$s: The currently active theme.
333
+ esc_html( _n(
334
+ 'Your site has %1$d inactive theme, other than %2$s, the default WordPress theme, and %3$s, your active theme. It is recommended to remove any unused themes to enhance your sites security.',
335
+ 'Your site has %1$d inactive themes, other than %2$s, the default WordPress theme, and %3$s, your active theme. It is recommended to remove any unused themes to enhance your sites security.',
336
+ $themes_inactive,
337
+ 'health-check'
338
+ ) ),
339
+ $themes_inactive,
340
+ WP_DEFAULT_THEME,
341
+ $active_theme->name
342
+ )
343
+ );
344
+
345
+ }
346
+ }
347
+
348
+ if ( ! $has_default_theme ) {
349
+ printf(
350
+ '<li><span class="warning"></span> %s',
351
+ esc_html__( 'Your site does not have a default theme, default themes are used by WordPress automatically if anything is wrong with your normal theme.', 'health-check' )
352
+ );
353
+ }
354
+
355
+ echo '</ul>';
356
+ }
357
+
358
+ public function test_php_version() {
359
+ $status = 'good';
360
+ $notice = array();
361
+
362
+ if ( ! $this->php_min_version_check ) {
363
+ $status = 'error';
364
+ $notice[] = sprintf(
365
+ '<a href="%s">%s</a>',
366
+ esc_url(
367
+ _x( 'https://wordpress.org/support/upgrade-php/', 'The link to the Update PHP page, which may be localized.', 'health-check' )
368
+ ),
369
+ sprintf(
370
+ // translators: %1$s: Current PHP version. %2$s: Recommended PHP version. %3$s: Minimum PHP version.
371
+ esc_html__( 'Your version of PHP, %1$s, is very outdated and no longer receiving security updates and is not supported by WordPress. You should contact your host for an upgrade, WordPress recommends using PHP version %2$s, but will work with version %3$s or newer.', 'health-check' ),
372
+ PHP_VERSION,
373
+ HEALTH_CHECK_PHP_REC_VERSION,
374
+ HEALTH_CHECK_PHP_MIN_VERSION
375
+ )
376
+ );
377
+ } elseif ( ! $this->php_supported_version_check ) {
378
+ $status = 'warning';
379
+ $notice[] = sprintf(
380
+ '<a href="%s">%s</a>',
381
+ esc_url(
382
+ _x( 'https://wordpress.org/support/upgrade-php/', 'The link to the Update PHP page, which may be localized.', 'health-check' )
383
+ ),
384
+ sprintf(
385
+ // translators: %1$s: Current PHP version. %2$s: Recommended PHP version.
386
+ esc_html__( 'Your version of PHP, %1$s, is very outdated and no longer receiving security updates. You should contact your host for an upgrade, WordPress recommends using PHP version %2$s.', 'health-check' ),
387
+ PHP_VERSION,
388
+ HEALTH_CHECK_PHP_REC_VERSION
389
+ )
390
+ );
391
+ } elseif ( ! $this->php_rec_version_check ) {
392
+ $status = 'warning';
393
+ $notice[] = sprintf(
394
+ '<a href="%s">%s</a>',
395
+ esc_url(
396
+ _x( 'https://wordpress.org/support/upgrade-php/', 'The link to the Update PHP page, which may be localized.', 'health-check' )
397
+ ),
398
+ sprintf(
399
+ // translators: %s: Recommended PHP version
400
+ esc_html__( 'For best performance we recommend using PHP %s or higher.', 'health-check' ),
401
+ HEALTH_CHECK_PHP_REC_VERSION
402
+ )
403
+ );
404
+ }
405
+
406
+ printf(
407
+ '<span class="%s"></span> %s',
408
+ esc_attr( $status ),
409
+ sprintf(
410
+ '%s%s',
411
+ PHP_VERSION,
412
+ ( ! empty( $notice ) ? ' - ' . implode( '<br>', $notice ) : '' )
413
+ )
414
+ );
415
+ }
416
+
417
+ public function test_json_extension() {
418
+ $json_check = Health_Check::json_check();
419
+
420
+ $status = 'good';
421
+ $notice = array();
422
+
423
+ if ( ! $json_check ) {
424
+ printf(
425
+ '<span class="error"> %s',
426
+ esc_html__( 'The PHP install on your server has the JSON extension disabled and is therefore not compatible with WordPress 3.2 or newer.', 'health-check' )
427
+ );
428
+ } else {
429
+ printf(
430
+ '<span class="good"> %s',
431
+ esc_html__( 'Your PHP install supports JSON.', 'health-check' )
432
+ );
433
+ }
434
+ }
435
+
436
+ public function test_sql_server() {
437
+ $status = 'good';
438
+ $notice = array();
439
+
440
+ $db_dropin = file_exists( WP_CONTENT_DIR . '/db.php' );
441
+
442
+ if ( ! $this->mysql_rec_version_check ) {
443
+ $status = 'warning';
444
+ $notice[] = sprintf(
445
+ // translators: %1$s: The database engine in use (MySQL or MariaDB). %2$s: Database server recommended version number.
446
+ esc_html__( 'For performance and security reasons, we strongly recommend running %1$s version %2$s or higher.', 'health-check' ),
447
+ ( $this->mariadb ? 'MariaDB' : 'MySQL' ),
448
+ $this->health_check_mysql_rec_version
449
+ );
450
+ }
451
+
452
+ if ( ! $this->mysql_min_version_check ) {
453
+ $status = 'error';
454
+ $notice[] = sprintf(
455
+ // translators: %1$s: The database engine in use (MySQL or MariaDB). %2$s: Database server minimum version number.
456
+ esc_html__( 'WordPress 3.2+ requires %1$s version %2$s or higher.', 'health-check' ),
457
+ ( $this->mariadb ? 'MariaDB' : 'MySQL' ),
458
+ HEALTH_CHECK_MYSQL_MIN_VERSION
459
+ );
460
+ }
461
+
462
+ if ( $db_dropin ) {
463
+ // translators: %s: The database engine in use (MySQL or MariaDB).
464
+ $notice[] = wp_kses(
465
+ sprintf(
466
+ // translators: %s: The name of the database engine being used.
467
+ __( 'You are using a <code>wp-content/db.php</code> drop-in which might mean that a %s database is not being used.', 'health-check' ),
468
+ ( $this->mariadb ? 'MariaDB' : 'MySQL' )
469
+ ),
470
+ array(
471
+ 'code' => true,
472
+ )
473
+ );
474
+ }
475
+
476
+ printf(
477
+ '<span class="%s"></span> %s',
478
+ esc_attr( $status ),
479
+ sprintf(
480
+ '%s%s',
481
+ esc_html( $this->mysql_server_version ),
482
+ ( ! empty( $notice ) ? '<br> - ' . implode( '<br>', $notice ) : '' )
483
+ )
484
+ );
485
+ }
486
+
487
+ public function test_utf8mb4_support() {
488
+ global $wpdb;
489
+
490
+ if ( ! $this->mariadb ) {
491
+ if ( version_compare( $this->mysql_server_version, '5.5.3', '<' ) ) {
492
+ printf(
493
+ '<span class="warning"></span> %s',
494
+ sprintf(
495
+ /* translators: %s: Number of version. */
496
+ esc_html__( 'WordPress\' utf8mb4 support requires MySQL version %s or greater', 'health-check' ),
497
+ '5.5.3'
498
+ )
499
+ );
500
+ } else {
501
+ printf(
502
+ '<span class="good"></span> %s',
503
+ esc_html__( 'Your MySQL version supports utf8mb4', 'health-check' )
504
+ );
505
+ }
506
+ } else { // MariaDB introduced utf8mb4 support in 5.5.0
507
+ if ( version_compare( $this->mysql_server_version, '5.5.0', '<' ) ) {
508
+ printf(
509
+ '<span class="warning"></span> %s',
510
+ sprintf(
511
+ /* translators: %s: Number of version. */
512
+ esc_html__( 'WordPress\' utf8mb4 support requires MariaDB version %s or greater', 'health-check' ),
513
+ '5.5.0'
514
+ )
515
+ );
516
+ } else {
517
+ printf(
518
+ '<span class="good"></span> %s',
519
+ esc_html__( 'Your MariaDB version supports utf8mb4', 'health-check' )
520
+ );
521
+ }
522
+ }
523
+
524
+ if ( $wpdb->use_mysqli ) {
525
+ // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_client_info
526
+ $mysql_client_version = mysqli_get_client_info();
527
+ } else {
528
+ // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info
529
+ $mysql_client_version = mysql_get_client_info();
530
+ }
531
+
532
+ /*
533
+ * libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server.
534
+ * mysqlnd has supported utf8mb4 since 5.0.9.
535
+ */
536
+ if ( false !== strpos( $mysql_client_version, 'mysqlnd' ) ) {
537
+ $mysql_client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $mysql_client_version );
538
+ if ( version_compare( $mysql_client_version, '5.0.9', '<' ) ) {
539
+ printf(
540
+ '<br><span class="warning"></span> %s',
541
+ sprintf(
542
+ /* translators: %1$s: Name of the library, %2$s: Number of version. */
543
+ __( 'WordPress\' utf8mb4 support requires MySQL client library (%1$s) version %2$s or newer.', 'health-check' ),
544
+ 'mysqlnd',
545
+ '5.0.9'
546
+ )
547
+ );
548
+ }
549
+ } else {
550
+ if ( version_compare( $mysql_client_version, '5.5.3', '<' ) ) {
551
+ printf(
552
+ '<br><span class="warning"></span> %s',
553
+ sprintf(
554
+ /* translators: %1$s: Name of the library, %2$s: Number of version. */
555
+ __( 'WordPress\' utf8mb4 support requires MySQL client library (%1$s) version %2$s or newer.', 'health-check' ),
556
+ 'libmysql',
557
+ '5.5.3'
558
+ )
559
+ );
560
+ }
561
+ }
562
+ }
563
+
564
+ public function test_dotorg_communication() {
565
+ $wp_dotorg = wp_remote_get( 'https://wordpress.org', array(
566
+ 'timeout' => 10,
567
+ ) );
568
+ if ( ! is_wp_error( $wp_dotorg ) ) {
569
+ printf(
570
+ '<span class="good"></span> %s',
571
+ esc_html__( 'WordPress.org is reachable from your server.', 'health-check' )
572
+ );
573
+ } else {
574
+ printf(
575
+ '<span class="error"></span> %s',
576
+ sprintf(
577
+ // translators: %1$s: The IP address WordPress.org resolves to. %2$s: The error returned by the lookup.
578
+ __( 'Unable to reach WordPress.org at %1$s: %2$s', 'health-check' ),
579
+ gethostbyname( 'wordpress.org' ),
580
+ $wp_dotorg->get_error_message()
581
+ )
582
+ );
583
+ }
584
+ }
585
+
586
+ public function test_https_status() {
587
+ if ( is_ssl() ) {
588
+ $wp_url = get_bloginfo( 'wpurl' );
589
+ $site_url = get_bloginfo( 'url' );
590
+
591
+ if ( 'https' !== substr( $wp_url, 0, 5 ) || 'https' !== substr( $site_url, 0, 5 ) ) {
592
+ printf(
593
+ '<span class="warning"></span> %s',
594
+ sprintf(
595
+ // translators: %s: URL to Settings > General to change options.
596
+ __( 'You are accessing this website using HTTPS, but your <a href="%s">WordPress Address</a> is not set up to use HTTPS by default.', 'health-check' ),
597
+ esc_url( admin_url( 'options-general.php' ) )
598
+ )
599
+ );
600
+ } else {
601
+ printf(
602
+ '<span class="good"></span> %s',
603
+ esc_html__( 'You are accessing this website using HTTPS.', 'health-check' )
604
+ );
605
+ }
606
+ } else {
607
+ printf(
608
+ '<span class="warning"></span> %s',
609
+ esc_html__( 'You are not using HTTPS to access this website.', 'health-check' )
610
+ );
611
+ }
612
+ }
613
+
614
+ public function test_ssl_support() {
615
+ $supports_https = wp_http_supports( array( 'ssl' ) );
616
+
617
+ if ( $supports_https ) {
618
+ printf(
619
+ '<span class="good"></span> %s',
620
+ esc_html__( 'Your WordPress install can communicate securely with other services.', 'health-check' )
621
+ );
622
+ } else {
623
+ printf(
624
+ '<span class="error"></span> %s',
625
+ esc_html__( 'Your WordPress install cannot communicate securely with other services. Talk to your web host about OpenSSL support for PHP.', 'health-check' )
626
+ );
627
+ }
628
+ }
629
+
630
+ public function test_scheduled_events() {
631
+ $scheduled_events = new Health_Check_WP_Cron();
632
+
633
+ if ( is_wp_error( $scheduled_events->has_missed_cron() ) ) {
634
+ printf(
635
+ '<span class="error"></span> %s',
636
+ esc_html( $scheduled_events->has_missed_cron()->get_error_message() )
637
+ );
638
+ } else {
639
+ if ( $scheduled_events->has_missed_cron() ) {
640
+ printf(
641
+ '<span class="warning"></span> %s',
642
+ sprintf(
643
+ // translators: %s: The name of the failed cron event.
644
+ esc_html__( 'A scheduled event (%s) has failed to run. Your site still works, but this may indicate that scheduling posts or automated updates may not work as intended.', 'health-check' ),
645
+ $scheduled_events->last_missed_cron
646
+ )
647
+ );
648
+ } else {
649
+ printf(
650
+ '<span class="good"></span> %s',
651
+ esc_html__( 'No scheduled events have been missed.', 'health-check' )
652
+ );
653
+ }
654
+ }
655
+ }
656
+
657
+ public function test_background_updates() {
658
+ $automatic_updates = new Health_Check_Auto_Updates();
659
+ $tests = $automatic_updates->run_tests();
660
+
661
+ echo '<ul>';
662
+
663
+ foreach ( $tests as $test ) {
664
+ printf(
665
+ '<li><span class="%s"></span> %s</li>',
666
+ esc_attr( $test->severity ),
667
+ $test->desc
668
+ );
669
+ }
670
+
671
+ echo '</ul>';
672
+ }
673
+
674
+ public function test_loopback_requests() {
675
+ $check_loopback = Health_Check_Loopback::can_perform_loopback();
676
+
677
+ printf(
678
+ '<span class="%s"></span> %s',
679
+ esc_attr( $check_loopback->status ),
680
+ $check_loopback->message
681
+ );
682
+
683
+ if ( 'error' === $check_loopback->status ) {
684
+ echo '<br><button type="button" id="loopback-no-plugins" class="button button-primary">Test without plugins</button>';
685
+ }
686
+ }
687
+ }
688
+
689
+ new Health_Check_Site_Status();
includes/class-health-check-troubleshoot.php CHANGED
@@ -111,7 +111,7 @@ class Health_Check_Troubleshoot {
111
  *
112
  * @uses is_dir()
113
  * @uses WP_Filesystem::mkdir()
114
- * @uses HealthCheck::display_notice()
115
  * @uses esc_html__()
116
  * @uses WP_Filesystem::copy()
117
  * @uses trailingslashit()
@@ -125,7 +125,7 @@ class Health_Check_Troubleshoot {
125
  // Make sure the `mu-plugins` directory exists.
126
  if ( ! is_dir( WPMU_PLUGIN_DIR ) ) {
127
  if ( ! $wp_filesystem->mkdir( WPMU_PLUGIN_DIR ) ) {
128
- HealthCheck::display_notice( esc_html__( 'We were unable to create the mu-plugins directory.', 'health-check' ), 'error' );
129
  return false;
130
  }
131
  }
@@ -133,14 +133,14 @@ class Health_Check_Troubleshoot {
133
  // Remove instances of the old plugin, to avoid collisions.
134
  if ( Health_Check_Troubleshoot::old_mu_plugin_exists() ) {
135
  if ( ! $wp_filesystem->delete( trailingslashit( WPMU_PLUGIN_DIR ) . 'health-check-disable-plugins.php' ) ) {
136
- HealthCheck::display_notice( esc_html__( 'We could not remove the old must-use plugin.', 'health-check' ), 'error' );
137
  return false;
138
  }
139
  }
140
 
141
  // Copy the must-use plugin to the local directory.
142
  if ( ! $wp_filesystem->copy( trailingslashit( HEALTH_CHECK_PLUGIN_DIRECTORY ) . 'assets/mu-plugin/health-check-troubleshooting-mode.php', trailingslashit( WPMU_PLUGIN_DIR ) . 'health-check-troubleshooting-mode.php' ) ) {
143
- HealthCheck::display_notice( esc_html__( 'We were unable to copy the plugin file required to enable the Troubleshooting Mode.', 'health-check' ), 'error' );
144
  return false;
145
  }
146
 
@@ -157,7 +157,7 @@ class Health_Check_Troubleshoot {
157
  * @global $wp_filesystem
158
  *
159
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
160
- * @uses HealthCheck::get_filesystem_credentials()
161
  * @uses get_plugin_data()
162
  * @uses trailingslashit()
163
  * @uses version_compare()
@@ -170,7 +170,7 @@ class Health_Check_Troubleshoot {
170
  if ( ! Health_Check_Troubleshoot::mu_plugin_exists() ) {
171
  return false;
172
  }
173
- if ( ! HealthCheck::get_filesystem_credentials() ) {
174
  return false;
175
  }
176
 
@@ -184,7 +184,7 @@ class Health_Check_Troubleshoot {
184
  global $wp_filesystem;
185
 
186
  if ( ! $wp_filesystem->copy( trailingslashit( HEALTH_CHECK_PLUGIN_DIRECTORY ) . 'assets/mu-plugin/health-check-troubleshooting-mode.php', trailingslashit( WPMU_PLUGIN_DIR ) . 'health-check-troubleshooting-mode.php', true ) ) {
187
- HealthCheck::display_notice( esc_html__( 'We were unable to replace the plugin file required to enable the Troubleshooting Mode.', 'health-check' ), 'error' );
188
  return false;
189
  }
190
  }
@@ -195,7 +195,7 @@ class Health_Check_Troubleshoot {
195
  /**
196
  * Output a notice if our Troubleshooting Mode has been initiated.
197
  *
198
- * @uses HealthCheck::display_notice()
199
  * @uses sprintf()
200
  * @uses esc_html__()
201
  * @uses esc_url()
@@ -204,10 +204,10 @@ class Health_Check_Troubleshoot {
204
  * @return void
205
  */
206
  static function session_started() {
207
- HealthCheck::display_notice(
208
  sprintf(
209
  '%s<br>%s',
210
- esc_html__( 'You have successfully enabled Troubleshooting Mode, all plugins will appear inactive until you log out and back in again.', 'health-check' ),
211
  sprintf(
212
  '<a href="%1$s">%2$s</a><script type="text/javascript">window.location = "%1$s";</script>',
213
  esc_url( admin_url( '/' ) ),
@@ -225,7 +225,7 @@ class Health_Check_Troubleshoot {
225
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
226
  * @uses Health_Check_Troubleshoot::maybe_update_must_use_plugin()
227
  * @uses Health_Check_Troubleshoot::session_started()
228
- * @uses HealthCheck::get_filesystem_credentials()
229
  * @uses Health_Check_Troubleshoot::setup_must_use_plugin()
230
  * @uses esc_html_e()
231
  *
@@ -240,7 +240,7 @@ class Health_Check_Troubleshoot {
240
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
241
  * @uses Health_Check_Troubleshoot::maybe_update_must_use_plugin()
242
  * @uses Health_Check_Troubleshoot::session_started()
243
- * @uses HealthCheck::get_filesystem_credentials()
244
  * @uses Health_Check_Troubleshoot::setup_must_use_plugin()
245
  * @uses Health_Check_Troubleshooting_MU::is_troubleshooting()
246
  * @uses esc_url()
@@ -257,7 +257,7 @@ class Health_Check_Troubleshoot {
257
  }
258
  Health_Check_Troubleshoot::session_started();
259
  } else {
260
- if ( ! HealthCheck::get_filesystem_credentials() ) {
261
  return;
262
  } else {
263
  Health_Check_Troubleshoot::setup_must_use_plugin();
@@ -268,8 +268,15 @@ class Health_Check_Troubleshoot {
268
  ?>
269
  <div class="notice inline">
270
 
271
- <?php if ( class_exists( 'Health_Check_Troubleshooting_MU' ) && is_callable( array( 'Health_Check_Troubleshooting_MU', 'is_troubleshooting' ) ) && Health_Check_Troubleshooting_MU::is_troubleshooting() ) : ?>
 
 
 
 
 
272
 
 
 
273
  <p style="text-align: center;">
274
  <a class="button button-primary" href="<?php echo esc_url( add_query_arg( array( 'health-check-disable-troubleshooting' => true ) ) ); ?>">
275
  <?php esc_html_e( 'Disable Troubleshooting Mode', 'health-check' ); ?>
111
  *
112
  * @uses is_dir()
113
  * @uses WP_Filesystem::mkdir()
114
+ * @uses Health_Check::display_notice()
115
  * @uses esc_html__()
116
  * @uses WP_Filesystem::copy()
117
  * @uses trailingslashit()
125
  // Make sure the `mu-plugins` directory exists.
126
  if ( ! is_dir( WPMU_PLUGIN_DIR ) ) {
127
  if ( ! $wp_filesystem->mkdir( WPMU_PLUGIN_DIR ) ) {
128
+ Health_Check::display_notice( esc_html__( 'We were unable to create the mu-plugins directory.', 'health-check' ), 'error' );
129
  return false;
130
  }
131
  }
133
  // Remove instances of the old plugin, to avoid collisions.
134
  if ( Health_Check_Troubleshoot::old_mu_plugin_exists() ) {
135
  if ( ! $wp_filesystem->delete( trailingslashit( WPMU_PLUGIN_DIR ) . 'health-check-disable-plugins.php' ) ) {
136
+ Health_Check::display_notice( esc_html__( 'We could not remove the old must-use plugin.', 'health-check' ), 'error' );
137
  return false;
138
  }
139
  }
140
 
141
  // Copy the must-use plugin to the local directory.
142
  if ( ! $wp_filesystem->copy( trailingslashit( HEALTH_CHECK_PLUGIN_DIRECTORY ) . 'assets/mu-plugin/health-check-troubleshooting-mode.php', trailingslashit( WPMU_PLUGIN_DIR ) . 'health-check-troubleshooting-mode.php' ) ) {
143
+ Health_Check::display_notice( esc_html__( 'We were unable to copy the plugin file required to enable the Troubleshooting Mode.', 'health-check' ), 'error' );
144
  return false;
145
  }
146
 
157
  * @global $wp_filesystem
158
  *
159
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
160
+ * @uses Health_Check::get_filesystem_credentials()
161
  * @uses get_plugin_data()
162
  * @uses trailingslashit()
163
  * @uses version_compare()
170
  if ( ! Health_Check_Troubleshoot::mu_plugin_exists() ) {
171
  return false;
172
  }
173
+ if ( ! Health_Check::get_filesystem_credentials() ) {
174
  return false;
175
  }
176
 
184
  global $wp_filesystem;
185
 
186
  if ( ! $wp_filesystem->copy( trailingslashit( HEALTH_CHECK_PLUGIN_DIRECTORY ) . 'assets/mu-plugin/health-check-troubleshooting-mode.php', trailingslashit( WPMU_PLUGIN_DIR ) . 'health-check-troubleshooting-mode.php', true ) ) {
187
+ Health_Check::display_notice( esc_html__( 'We were unable to replace the plugin file required to enable the Troubleshooting Mode.', 'health-check' ), 'error' );
188
  return false;
189
  }
190
  }
195
  /**
196
  * Output a notice if our Troubleshooting Mode has been initiated.
197
  *
198
+ * @uses Health_Check::display_notice()
199
  * @uses sprintf()
200
  * @uses esc_html__()
201
  * @uses esc_url()
204
  * @return void
205
  */
206
  static function session_started() {
207
+ Health_Check::display_notice(
208
  sprintf(
209
  '%s<br>%s',
210
+ esc_html__( 'You have successfully enabled Troubleshooting Mode, all plugins will appear inactive until you disable Troubleshooting Mode, or log out and back in again.', 'health-check' ),
211
  sprintf(
212
  '<a href="%1$s">%2$s</a><script type="text/javascript">window.location = "%1$s";</script>',
213
  esc_url( admin_url( '/' ) ),
225
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
226
  * @uses Health_Check_Troubleshoot::maybe_update_must_use_plugin()
227
  * @uses Health_Check_Troubleshoot::session_started()
228
+ * @uses Health_Check::get_filesystem_credentials()
229
  * @uses Health_Check_Troubleshoot::setup_must_use_plugin()
230
  * @uses esc_html_e()
231
  *
240
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
241
  * @uses Health_Check_Troubleshoot::maybe_update_must_use_plugin()
242
  * @uses Health_Check_Troubleshoot::session_started()
243
+ * @uses Health_Check::get_filesystem_credentials()
244
  * @uses Health_Check_Troubleshoot::setup_must_use_plugin()
245
  * @uses Health_Check_Troubleshooting_MU::is_troubleshooting()
246
  * @uses esc_url()
257
  }
258
  Health_Check_Troubleshoot::session_started();
259
  } else {
260
+ if ( ! Health_Check::get_filesystem_credentials() ) {
261
  return;
262
  } else {
263
  Health_Check_Troubleshoot::setup_must_use_plugin();
268
  ?>
269
  <div class="notice inline">
270
 
271
+ <?php
272
+ $troubleshooting = null;
273
+
274
+ if ( class_exists( 'Health_Check_Troubleshooting_MU' ) ) {
275
+ $troubleshooting = new Health_Check_Troubleshooting_MU();
276
+ }
277
 
278
+ if ( null !== $troubleshooting && $troubleshooting->is_troubleshooting() ) :
279
+ ?>
280
  <p style="text-align: center;">
281
  <a class="button button-primary" href="<?php echo esc_url( add_query_arg( array( 'health-check-disable-troubleshooting' => true ) ) ); ?>">
282
  <?php esc_html_e( 'Disable Troubleshooting Mode', 'health-check' ); ?>
includes/{class-healthcheck.php → class-health-check.php} RENAMED
@@ -8,7 +8,7 @@
8
  /**
9
  * Class HealthCheck
10
  */
11
- class HealthCheck {
12
 
13
  /**
14
  * Notices to show at the head of the admin screen.
@@ -22,7 +22,7 @@ class HealthCheck {
22
  /**
23
  * HealthCheck constructor.
24
  *
25
- * @uses HealthCheck::init()
26
  *
27
  * @return void
28
  */
@@ -60,6 +60,7 @@ class HealthCheck {
60
 
61
  add_action( 'wp_ajax_health-check-loopback-no-plugins', array( 'Health_Check_Loopback', 'loopback_no_plugins' ) );
62
  add_action( 'wp_ajax_health-check-loopback-individual-plugins', array( 'Health_Check_Loopback', 'loopback_test_individual_plugins' ) );
 
63
  add_action( 'wp_ajax_health-check-files-integrity-check', array( 'Health_Check_Files_Integrity', 'run_files_integrity_check' ) );
64
  add_action( 'wp_ajax_health-check-view-file-diff', array( 'Health_Check_Files_Integrity', 'view_file_diff' ) );
65
  add_action( 'wp_ajax_health-check-mail-check', array( 'Health_Check_Mail_Check', 'run_mail_check' ) );
@@ -111,7 +112,7 @@ class HealthCheck {
111
  * @uses current_user_can()
112
  * @uses ob_start()
113
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
114
- * @uses HealthCheck::get_filesystem_credentials()
115
  * @uses Health_Check_Troubleshoot::setup_must_use_plugin()
116
  * @uses Health_Check_Troubleshoot::maybe_update_must_use_plugin()
117
  * @uses ob_get_clean()
@@ -131,7 +132,7 @@ class HealthCheck {
131
  $needs_credentials = false;
132
 
133
  if ( ! Health_Check_Troubleshoot::mu_plugin_exists() ) {
134
- if ( ! HealthCheck::get_filesystem_credentials() ) {
135
  $needs_credentials = true;
136
  } else {
137
  $check_output = Health_Check_Troubleshoot::setup_must_use_plugin( false );
@@ -210,8 +211,9 @@ class HealthCheck {
210
 
211
  wp_localize_script( 'health-check', 'HealthCheck', array(
212
  'string' => array(
213
- 'please_wait' => esc_html__( 'Please wait...', 'health-check' ),
214
- 'copied' => esc_html__( 'Copied', 'health-check' ),
 
215
  ),
216
  'warning' => array(
217
  'seen_backup' => Health_Check_Troubleshoot::has_seen_warning(),
@@ -309,14 +311,14 @@ class HealthCheck {
309
 
310
  <?php
311
  $tabs = array(
312
- 'health-check' => esc_html_x( 'Health Check', 'Menu, Section and Page Title', 'health-check' ),
313
  'debug' => esc_html__( 'Debug Information', 'health-check' ),
314
  'troubleshoot' => esc_html__( 'Troubleshooting', 'health-check' ),
315
  'phpinfo' => esc_html__( 'PHP Information', 'health-check' ),
316
  'tools' => esc_html__( 'Tools', 'health-check' ),
317
  );
318
 
319
- $current_tab = ( isset( $_GET['tab'] ) ? $_GET['tab'] : 'health-check' );
320
  ?>
321
 
322
  <h2 class="nav-tab-wrapper wp-clearfix">
@@ -350,9 +352,9 @@ class HealthCheck {
350
  case 'tools':
351
  include_once( HEALTH_CHECK_PLUGIN_DIRECTORY . '/pages/tools.php' );
352
  break;
353
- case 'health-check':
354
  default:
355
- include_once( HEALTH_CHECK_PLUGIN_DIRECTORY . '/pages/health-check.php' );
356
  }
357
  ?>
358
  </div>
8
  /**
9
  * Class HealthCheck
10
  */
11
+ class Health_Check {
12
 
13
  /**
14
  * Notices to show at the head of the admin screen.
22
  /**
23
  * HealthCheck constructor.
24
  *
25
+ * @uses Health_Check::init()
26
  *
27
  * @return void
28
  */
60
 
61
  add_action( 'wp_ajax_health-check-loopback-no-plugins', array( 'Health_Check_Loopback', 'loopback_no_plugins' ) );
62
  add_action( 'wp_ajax_health-check-loopback-individual-plugins', array( 'Health_Check_Loopback', 'loopback_test_individual_plugins' ) );
63
+ add_action( 'wp_ajax_health-check-loopback-default-theme', array( 'Health_Check_Loopback', 'loopback_test_default_theme' ) );
64
  add_action( 'wp_ajax_health-check-files-integrity-check', array( 'Health_Check_Files_Integrity', 'run_files_integrity_check' ) );
65
  add_action( 'wp_ajax_health-check-view-file-diff', array( 'Health_Check_Files_Integrity', 'view_file_diff' ) );
66
  add_action( 'wp_ajax_health-check-mail-check', array( 'Health_Check_Mail_Check', 'run_mail_check' ) );
112
  * @uses current_user_can()
113
  * @uses ob_start()
114
  * @uses Health_Check_Troubleshoot::mu_plugin_exists()
115
+ * @uses Health_Check::get_filesystem_credentials()
116
  * @uses Health_Check_Troubleshoot::setup_must_use_plugin()
117
  * @uses Health_Check_Troubleshoot::maybe_update_must_use_plugin()
118
  * @uses ob_get_clean()
132
  $needs_credentials = false;
133
 
134
  if ( ! Health_Check_Troubleshoot::mu_plugin_exists() ) {
135
+ if ( ! Health_Check::get_filesystem_credentials() ) {
136
  $needs_credentials = true;
137
  } else {
138
  $check_output = Health_Check_Troubleshoot::setup_must_use_plugin( false );
211
 
212
  wp_localize_script( 'health-check', 'HealthCheck', array(
213
  'string' => array(
214
+ 'please_wait' => esc_html__( 'Please wait...', 'health-check' ),
215
+ 'copied' => esc_html__( 'Copied', 'health-check' ),
216
+ 'running_tests' => esc_html__( 'Currently being tested...', 'health-check' ),
217
  ),
218
  'warning' => array(
219
  'seen_backup' => Health_Check_Troubleshoot::has_seen_warning(),
311
 
312
  <?php
313
  $tabs = array(
314
+ 'site-status' => esc_html__( 'Site Status', 'health-check' ),
315
  'debug' => esc_html__( 'Debug Information', 'health-check' ),
316
  'troubleshoot' => esc_html__( 'Troubleshooting', 'health-check' ),
317
  'phpinfo' => esc_html__( 'PHP Information', 'health-check' ),
318
  'tools' => esc_html__( 'Tools', 'health-check' ),
319
  );
320
 
321
+ $current_tab = ( isset( $_GET['tab'] ) ? $_GET['tab'] : 'site-status' );
322
  ?>
323
 
324
  <h2 class="nav-tab-wrapper wp-clearfix">
352
  case 'tools':
353
  include_once( HEALTH_CHECK_PLUGIN_DIRECTORY . '/pages/tools.php' );
354
  break;
355
+ case 'site-status':
356
  default:
357
+ include_once( HEALTH_CHECK_PLUGIN_DIRECTORY . '/pages/site-status.php' );
358
  }
359
  ?>
360
  </div>
pages/debug-data.php CHANGED
@@ -36,7 +36,7 @@ $info = Health_Check_Debug_Data::debug_data();
36
  if ( ! is_textdomain_loaded( 'health-check' ) && _get_path_to_translation( 'health-check' ) ) {
37
  load_textdomain( 'health-check', _get_path_to_translation( 'health-check' ) );
38
  }
39
- ?>
40
  <div id="system-information-english-copy-wrapper" style="display: none;">
41
  <textarea id="system-information-english-copy-field" class="widefat" rows="10">`
42
  <?php
36
  if ( ! is_textdomain_loaded( 'health-check' ) && _get_path_to_translation( 'health-check' ) ) {
37
  load_textdomain( 'health-check', _get_path_to_translation( 'health-check' ) );
38
  }
39
+ ?>
40
  <div id="system-information-english-copy-wrapper" style="display: none;">
41
  <textarea id="system-information-english-copy-field" class="widefat" rows="10">`
42
  <?php
pages/health-check.php DELETED
@@ -1,425 +0,0 @@
1
- <?php
2
- /**
3
- * Health Check tab contents.
4
- *
5
- * @package Health Check
6
- */
7
-
8
- // Make sure the file is not directly accessible.
9
- if ( ! defined( 'ABSPATH' ) ) {
10
- die( 'We\'re sorry, but you can not directly access this file.' );
11
- }
12
-
13
- global $wpdb;
14
-
15
- $php_min_version_check = version_compare( HEALTH_CHECK_PHP_MIN_VERSION, PHP_VERSION, '<=' );
16
- $php_supported_version_check = version_compare( HEALTH_CHECK_PHP_SUPPORTED_VERSION, PHP_VERSION, '<=' );
17
- $php_rec_version_check = version_compare( HEALTH_CHECK_PHP_REC_VERSION, PHP_VERSION, '<=' );
18
-
19
- $mariadb = false;
20
- $mysql_server_version = null;
21
- if ( method_exists( $wpdb, 'db_version' ) ) {
22
- if ( $wpdb->use_mysqli ) {
23
- // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_server_info
24
- $mysql_server_type = mysqli_get_server_info( $wpdb->dbh );
25
- } else {
26
- // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_server_info
27
- $mysql_server_type = mysql_get_server_info( $wpdb->dbh );
28
- }
29
-
30
- $mysql_server_version = $wpdb->get_var( 'SELECT VERSION()' );
31
- }
32
-
33
- $health_check_mysql_rec_version = HEALTH_CHECK_MYSQL_REC_VERSION;
34
-
35
- if ( stristr( $mysql_server_type, 'mariadb' ) ) {
36
- $mariadb = true;
37
- $health_check_mysql_rec_version = '10.0';
38
- }
39
-
40
- $mysql_min_version_check = version_compare( HEALTH_CHECK_MYSQL_MIN_VERSION, $mysql_server_version, '<=' );
41
- $mysql_rec_version_check = version_compare( $health_check_mysql_rec_version, $mysql_server_version, '<=' );
42
-
43
- $json_check = HealthCheck::json_check();
44
- $db_dropin = file_exists( WP_CONTENT_DIR . '/db.php' );
45
- ?>
46
-
47
- <div class="notice notice-info inline">
48
- <p>
49
- <?php esc_html_e( 'The health check shows critical information about your WordPress configuration and items that require your attention.', 'health-check' ); ?>
50
- </p>
51
- </div>
52
-
53
- <table class="widefat striped health-check-table">
54
- <tbody>
55
- <tr>
56
- <td><?php esc_html_e( 'PHP Version', 'health-check' ); ?></td>
57
- <td>
58
- <?php
59
- $status = 'good';
60
- $notice = array();
61
-
62
- if ( ! $php_min_version_check ) {
63
- $status = 'error';
64
- $notice[] = sprintf(
65
- '<a href="%s">%s</a>',
66
- esc_url(
67
- _x( 'https://wordpress.org/support/upgrade-php/', 'The link to the Update PHP page, which may be localized.', 'health-check' )
68
- ),
69
- sprintf(
70
- // translators: %1$s: Current PHP version. %2$s: Recommended PHP version. %3$s: Minimum PHP version.
71
- esc_html__( 'Your version of PHP, %1$s, is very outdated and no longer receiving security updates and is not supported by WordPress. You should contact your host for an upgrade, WordPress recommends using PHP version %2$s, but will work with version %3$s or newer.', 'health-check' ),
72
- PHP_VERSION,
73
- HEALTH_CHECK_PHP_REC_VERSION,
74
- HEALTH_CHECK_PHP_MIN_VERSION
75
- )
76
- );
77
- } elseif ( ! $php_supported_version_check ) {
78
- $status = 'warning';
79
- $notice[] = sprintf(
80
- '<a href="%s">%s</a>',
81
- esc_url(
82
- _x( 'https://wordpress.org/support/upgrade-php/', 'The link to the Update PHP page, which may be localized.', 'health-check' )
83
- ),
84
- sprintf(
85
- // translators: %1$s: Current PHP version. %2$s: Recommended PHP version.
86
- esc_html__( 'Your version of PHP, %1$s, is very outdated and no longer receiving security updates. You should contact your host for an upgrade, WordPress recommends using PHP version %2$s.', 'health-check' ),
87
- PHP_VERSION,
88
- HEALTH_CHECK_PHP_REC_VERSION
89
- )
90
- );
91
- } elseif ( ! $php_rec_version_check ) {
92
- $status = 'warning';
93
- $notice[] = sprintf(
94
- '<a href="%s">%s</a>',
95
- esc_url(
96
- _x( 'https://wordpress.org/support/upgrade-php/', 'The link to the Update PHP page, which may be localized.', 'health-check' )
97
- ),
98
- sprintf(
99
- // translators: %s: Recommended PHP version
100
- esc_html__( 'For best performance we recommend using PHP %s or higher.', 'health-check' ),
101
- HEALTH_CHECK_PHP_REC_VERSION
102
- )
103
- );
104
- }
105
-
106
- printf(
107
- '<span class="%s"></span> %s',
108
- esc_attr( $status ),
109
- sprintf(
110
- '%s%s',
111
- PHP_VERSION,
112
- ( ! empty( $notice ) ? ' - ' . implode( '<br>', $notice ) : '' )
113
- )
114
- );
115
- ?>
116
-
117
- </td>
118
- </tr>
119
-
120
- <tr>
121
- <td>
122
- <?php
123
- if ( ! $mariadb ) {
124
- esc_html_e( 'MySQL Server version', 'health-check' );
125
- } else {
126
- esc_html_e( 'MariaDB Server version', 'health-check' );
127
- }
128
- ?>
129
- </td>
130
- <td>
131
- <?php
132
- $status = 'good';
133
- $notice = array();
134
-
135
- if ( ! $mysql_rec_version_check ) {
136
- $status = 'warning';
137
- $notice[] = sprintf(
138
- // translators: %1$s: The database engine in use (MySQL or MariaDB). %2$s: Database server recommended version number.
139
- esc_html__( 'For performance and security reasons, we strongly recommend running %1$s version %2$s or higher.', 'health-check' ),
140
- ( $mariadb ? 'MariaDB' : 'MySQL' ),
141
- $health_check_mysql_rec_version
142
- );
143
- }
144
-
145
- if ( ! $mysql_min_version_check ) {
146
- $status = 'error';
147
- $notice[] = sprintf(
148
- // translators: %1$s: The database engine in use (MySQL or MariaDB). %2$s: Database server minimum version number.
149
- esc_html__( 'WordPress 3.2+ requires %1$s version %2$s or higher.', 'health-check' ),
150
- ( $mariadb ? 'MariaDB' : 'MySQL' ),
151
- HEALTH_CHECK_MYSQL_MIN_VERSION
152
- );
153
- }
154
-
155
- if ( $db_dropin ) {
156
- // translators: %s: The database engine in use (MySQL or MariaDB).
157
- $notice[] = wp_kses(
158
- sprintf(
159
- // translators: %s: The name of the database engine being used.
160
- __( 'You are using a <code>wp-content/db.php</code> drop-in which might mean that a %s database is not being used.', 'health-check' ),
161
- ( $mariadb ? 'MariaDB' : 'MySQL' )
162
- ),
163
- array(
164
- 'code' => true,
165
- )
166
- );
167
- }
168
-
169
- printf(
170
- '<span class="%s"></span> %s',
171
- esc_attr( $status ),
172
- sprintf(
173
- '%s%s',
174
- esc_html( $mysql_server_version ),
175
- ( ! empty( $notice ) ? '<br> - ' . implode( '<br>', $notice ) : '' )
176
- )
177
- );
178
- ?>
179
- </td>
180
- </tr>
181
-
182
- <tr>
183
- <td><?php esc_html_e( 'JSON Extension', 'health-check' ); ?></td>
184
- <td>
185
- <?php
186
- $status = 'good';
187
- $notice = array();
188
-
189
- if ( ! $json_check ) {
190
- printf(
191
- '<span class="error"> %s',
192
- esc_html__( 'The PHP install on your server has the JSON extension disabled and is therefore not compatible with WordPress 3.2 or newer.', 'health-check' )
193
- );
194
- } else {
195
- printf(
196
- '<span class="good"> %s',
197
- esc_html__( 'Your PHP install supports JSON.', 'health-check' )
198
- );
199
- }
200
- ?>
201
- </td>
202
- </tr>
203
-
204
- <tr>
205
- <td><?php esc_html_e( 'MySQL utf8mb4 support', 'health-check' ); ?></td>
206
- <td>
207
- <?php
208
- if ( ! $mariadb ) {
209
- if ( version_compare( $mysql_server_version, '5.5.3', '<' ) ) {
210
- printf(
211
- '<span class="warning"></span> %s',
212
- sprintf(
213
- /* translators: %s: Number of version. */
214
- esc_html__( 'WordPress\' utf8mb4 support requires MySQL version %s or greater', 'health-check' ),
215
- '5.5.3'
216
- )
217
- );
218
- } else {
219
- printf(
220
- '<span class="good"></span> %s',
221
- esc_html__( 'Your MySQL version supports utf8mb4', 'health-check' )
222
- );
223
- }
224
- } else { // MariaDB introduced utf8mb4 support in 5.5.0
225
- if ( version_compare( $mysql_server_version, '5.5.0', '<' ) ) {
226
- printf(
227
- '<span class="warning"></span> %s',
228
- sprintf(
229
- /* translators: %s: Number of version. */
230
- esc_html__( 'WordPress\' utf8mb4 support requires MariaDB version %s or greater', 'health-check' ),
231
- '5.5.0'
232
- )
233
- );
234
- } else {
235
- printf(
236
- '<span class="good"></span> %s',
237
- esc_html__( 'Your MariaDB version supports utf8mb4', 'health-check' )
238
- );
239
- }
240
- }
241
-
242
- if ( $wpdb->use_mysqli ) {
243
- // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_client_info
244
- $mysql_client_version = mysqli_get_client_info();
245
- } else {
246
- // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info
247
- $mysql_client_version = mysql_get_client_info();
248
- }
249
-
250
- /*
251
- * libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server.
252
- * mysqlnd has supported utf8mb4 since 5.0.9.
253
- */
254
- if ( false !== strpos( $mysql_client_version, 'mysqlnd' ) ) {
255
- $mysql_client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $mysql_client_version );
256
- if ( version_compare( $mysql_client_version, '5.0.9', '<' ) ) {
257
- printf(
258
- '<br><span class="warning"></span> %s',
259
- sprintf(
260
- /* translators: %1$s: Name of the library, %2$s: Number of version. */
261
- __( 'WordPress\' utf8mb4 support requires MySQL client library (%1$s) version %2$s or newer.', 'health-check' ),
262
- 'mysqlnd',
263
- '5.0.9'
264
- )
265
- );
266
- }
267
- } else {
268
- if ( version_compare( $mysql_client_version, '5.5.3', '<' ) ) {
269
- printf(
270
- '<br><span class="warning"></span> %s',
271
- sprintf(
272
- /* translators: %1$s: Name of the library, %2$s: Number of version. */
273
- __( 'WordPress\' utf8mb4 support requires MySQL client library (%1$s) version %2$s or newer.', 'health-check' ),
274
- 'libmysql',
275
- '5.5.3'
276
- )
277
- );
278
- }
279
- }
280
- ?>
281
- </td>
282
- </tr>
283
-
284
- <tr>
285
- <td><?php esc_html_e( 'Communication with WordPress.org', 'health-check' ); ?></td>
286
- <td>
287
- <?php
288
- $wp_dotorg = wp_remote_get( 'https://wordpress.org', array(
289
- 'timeout' => 10,
290
- ) );
291
- if ( ! is_wp_error( $wp_dotorg ) ) {
292
- printf(
293
- '<span class="good"></span> %s',
294
- esc_html__( 'WordPress.org is reachable from your server.', 'health-check' )
295
- );
296
- } else {
297
- printf(
298
- '<span class="error"></span> %s',
299
- sprintf(
300
- // translators: %1$s: The IP address WordPress.org resolves to. %2$s: The error returned by the lookup.
301
- __( 'Unable to reach WordPress.org at %1$s: %2$s', 'health-check' ),
302
- gethostbyname( 'wordpress.org' ),
303
- $wp_dotorg->get_error_message()
304
- )
305
- );
306
- }
307
- ?>
308
- </td>
309
- </tr>
310
-
311
- <tr>
312
- <td><?php esc_html_e( 'HTTPS status', 'health-check' ); ?></td>
313
- <td>
314
- <?php
315
- if ( is_ssl() ) {
316
- printf(
317
- '<span class="good"></span> %s',
318
- esc_html__( 'You are accessing this website using HTTPS.', 'health-check' )
319
- );
320
- } else {
321
- printf(
322
- '<span class="warning"></span> %s',
323
- esc_html__( 'You are not using HTTPS to access this website.', 'health-check' )
324
- );
325
- }
326
- ?>
327
- </td>
328
- </tr>
329
-
330
- <tr>
331
- <td><?php esc_html_e( 'Secure communication', 'health-check' ); ?></td>
332
- <td>
333
- <?php
334
- $supports_https = wp_http_supports( array( 'ssl' ) );
335
-
336
- if ( $supports_https ) {
337
- printf(
338
- '<span class="good"></span> %s',
339
- esc_html__( 'Your WordPress install can communicate securely with other services.', 'health-check' )
340
- );
341
- } else {
342
- printf(
343
- '<span class="error"></span> %s',
344
- esc_html__( 'Your WordPress install cannot communicate securely with other services. Talk to your web host about OpenSSL support for PHP.', 'health-check' )
345
- );
346
- }
347
- ?>
348
- </td>
349
- </tr>
350
-
351
- <tr>
352
- <td><?php esc_html_e( 'Scheduled events', 'health-check' ); ?></td>
353
- <td>
354
- <?php
355
- $scheduled_events = new Health_Check_WP_Cron();
356
-
357
- if ( is_wp_error( $scheduled_events->has_missed_cron() ) ) {
358
- printf(
359
- '<span class="error"></span> %s',
360
- esc_html( $scheduled_events->has_missed_cron()->get_error_message() )
361
- );
362
- } else {
363
- if ( $scheduled_events->has_missed_cron() ) {
364
- printf(
365
- '<span class="warning"></span> %s',
366
- sprintf(
367
- // translators: %s: The name of the failed cron event.
368
- esc_html__( 'A scheduled event (%s) has failed to run. Your site still works, but this may indicate that scheduling posts or automated updates may not work as intended.', 'health-check' ),
369
- $scheduled_events->last_missed_cron
370
- )
371
- );
372
- } else {
373
- printf(
374
- '<span class="good"></span> %s',
375
- esc_html__( 'No scheduled events have been missed.', 'health-check' )
376
- );
377
- }
378
- }
379
- ?>
380
- </td>
381
- </tr>
382
-
383
- <tr>
384
- <td><?php esc_html_e( 'Background updates', 'health-check' ); ?></td>
385
- <td>
386
- <ul>
387
- <?php
388
- $automatic_updates = new Health_Check_Auto_Updates();
389
- $tests = $automatic_updates->run_tests();
390
-
391
- foreach ( $tests as $test ) {
392
- printf(
393
- '<li><span class="%s"></span> %s</li>',
394
- esc_attr( $test->severity ),
395
- $test->desc
396
- );
397
- }
398
- ?>
399
- </ul>
400
- </td>
401
- </tr>
402
-
403
- <tr>
404
- <td><?php esc_html_e( 'Loopback request', 'health-check' ); ?></td>
405
- <td>
406
- <?php
407
- $check_loopback = Health_Check_Loopback::can_perform_loopback();
408
-
409
- printf(
410
- '<span class="%s"></span> %s',
411
- esc_attr( $check_loopback->status ),
412
- $check_loopback->message
413
- );
414
-
415
- if ( 'error' === $check_loopback->status ) {
416
- echo '<br><button type="button" id="loopback-no-plugins" class="button button-primary">Test without plugins</button>';
417
- }
418
- ?>
419
- </td>
420
- </tr>
421
- </tbody>
422
- </table>
423
-
424
- <?php
425
- include_once( HEALTH_CHECK_PLUGIN_DIRECTORY . '/modals/js-result-warnings.php' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/site-status.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Health Check tab contents.
4
+ *
5
+ * @package Health Check
6
+ */
7
+
8
+ // Make sure the file is not directly accessible.
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ die( 'We\'re sorry, but you can not directly access this file.' );
11
+ }
12
+ ?>
13
+
14
+ <div class="notice notice-info inline">
15
+ <p>
16
+ <?php esc_html_e( 'The health check shows critical information about your WordPress configuration and items that require your attention.', 'health-check' ); ?>
17
+ </p>
18
+ </div>
19
+
20
+ <table class="widefat striped health-check-table">
21
+ <tbody>
22
+ <tr>
23
+ <td><?php esc_html_e( 'WordPress Version', 'health-check' ); ?></td>
24
+ <td class="health-check-site-status-test" data-site-status="wordpress_version">
25
+ <span class="spinner is-active"></span>
26
+ </td>
27
+ </tr>
28
+
29
+ <tr>
30
+ <td><?php esc_html_e( 'Plugin Versions', 'health-check' ); ?></td>
31
+ <td class="health-check-site-status-test" data-site-status="plugin_version">
32
+ <span class="spinner is-active"></span>
33
+ </td>
34
+ </tr>
35
+
36
+ <tr>
37
+ <td><?php esc_html_e( 'Theme Versions', 'health-check' ); ?></td>
38
+ <td class="health-check-site-status-test" data-site-status="theme_version">
39
+ <span class="spinner is-active"></span>
40
+ </td>
41
+ </tr>
42
+
43
+ <tr>
44
+ <td><?php esc_html_e( 'PHP Version', 'health-check' ); ?></td>
45
+ <td class="health-check-site-status-test" data-site-status="php_version">
46
+ <span class="spinner is-active"></span>
47
+ </td>
48
+ </tr>
49
+
50
+ <tr>
51
+ <td>
52
+ <?php esc_html_e( 'Database Server version', 'health-check' ); ?>
53
+ </td>
54
+ <td class="health-check-site-status-test" data-site-status="sql_server">
55
+ <span class="spinner is-active"></span>
56
+ </td>
57
+ </tr>
58
+
59
+ <tr>
60
+ <td><?php esc_html_e( 'JSON Extension', 'health-check' ); ?></td>
61
+ <td class="health-check-site-status-test" data-site-status="json_extension">
62
+ <span class="spinner is-active"></span>
63
+ </td>
64
+ </tr>
65
+
66
+ <tr>
67
+ <td><?php esc_html_e( 'MySQL utf8mb4 support', 'health-check' ); ?></td>
68
+ <td class="health-check-site-status-test" data-site-status="utf8mb4_support">
69
+ <span class="spinner is-active"></span>
70
+ </td>
71
+ </tr>
72
+
73
+ <tr>
74
+ <td><?php esc_html_e( 'Communication with WordPress.org', 'health-check' ); ?></td>
75
+ <td class="health-check-site-status-test" data-site-status="dotorg_communication">
76
+ <span class="spinner is-active"></span>
77
+ </td>
78
+ </tr>
79
+
80
+ <tr>
81
+ <td><?php esc_html_e( 'HTTPS status', 'health-check' ); ?></td>
82
+ <td class="health-check-site-status-test" data-site-status="https_status">
83
+ <span class="spinner is-active"></span>
84
+ </td>
85
+ </tr>
86
+
87
+ <tr>
88
+ <td><?php esc_html_e( 'Secure communication', 'health-check' ); ?></td>
89
+ <td class="health-check-site-status-test" data-site-status="ssl_support">
90
+ <span class="spinner is-active"></span>
91
+ </td>
92
+ </tr>
93
+
94
+ <tr>
95
+ <td><?php esc_html_e( 'Scheduled events', 'health-check' ); ?></td>
96
+ <td class="health-check-site-status-test" data-site-status="scheduled_events">
97
+ <span class="spinner is-active"></span>
98
+ </td>
99
+ </tr>
100
+
101
+ <tr>
102
+ <td><?php esc_html_e( 'Background updates', 'health-check' ); ?></td>
103
+ <td class="health-check-site-status-test" data-site-status="background_updates">
104
+ <span class="spinner is-active"></span>
105
+ </td>
106
+ </tr>
107
+
108
+ <tr>
109
+ <td><?php esc_html_e( 'Loopback request', 'health-check' ); ?></td>
110
+ <td class="health-check-site-status-test" data-site-status="loopback_requests">
111
+ <span class="spinner is-active"></span>
112
+ </td>
113
+ </tr>
114
+ </tbody>
115
+ </table>
116
+
117
+ <?php
118
+ include_once( HEALTH_CHECK_PLUGIN_DIRECTORY . '/modals/js-result-warnings.php' );
pages/tools.php CHANGED
@@ -14,10 +14,30 @@ if ( ! defined( 'ABSPATH' ) ) {
14
 
15
  <dl id="health-check-tools" role="presentation" class="health-check-accordion">
16
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  $tabs = apply_filters( 'health_check_tools_tab', array() );
18
 
19
  foreach ( $tabs as $count => $tab ) :
20
- ?>
21
 
22
  <dt role="heading" aria-level="2">
23
  <button aria-expanded="false" class="health-check-accordion-trigger" aria-controls="health-check-accordion-block-<?php echo esc_attr( $count ); ?>" id="health-check-accordion-heading-<?php echo esc_attr( $count ); ?>" type="button">
14
 
15
  <dl id="health-check-tools" role="presentation" class="health-check-accordion">
16
  <?php
17
+ /**
18
+ * Filter the features available under the Tools tab.
19
+ *
20
+ * You may introduce your own, or modify the behavior of existing tools here,
21
+ * although we recommend not modifying anything provided by the plugin it self.
22
+ *
23
+ * Any interactive elements should be introduced using JavaScript and/or CSS, either
24
+ * inline, or by enqueueing them via the appropriate actions.
25
+ *
26
+ * @param array $args {
27
+ * An unassociated array of tabs, listed in the order they are registered.
28
+ *
29
+ * @type array $tab {
30
+ * An associated array containing the tab title, and content.
31
+ *
32
+ * @type string $label A pre-escaped string used to label your tool section.
33
+ * @type string $content The content of your tool tab, with any code you may need.
34
+ * }
35
+ * }
36
+ */
37
  $tabs = apply_filters( 'health_check_tools_tab', array() );
38
 
39
  foreach ( $tabs as $count => $tab ) :
40
+ ?>
41
 
42
  <dt role="heading" aria-level="2">
43
  <button aria-expanded="false" class="health-check-accordion-trigger" aria-controls="health-check-accordion-block-<?php echo esc_attr( $count ); ?>" id="health-check-accordion-heading-<?php echo esc_attr( $count ); ?>" type="button">
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
- === Health Check ===
2
  Tags: health check
3
  Contributors: wordpressdotorg, westi, pento, Clorith
4
- Requires at least: 3.8
5
  Tested up to: 4.9
6
- Stable tag: 1.1.2
7
  License: GPLv2
8
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -21,11 +21,13 @@ For a more extensive example of how to efficiently use the Health Check plugin,
21
 
22
  In the future we may introduce more checks, and welcome feedback both through the [WordPress.org forums](https://wordpress.org/support/plugin/health-check), and the [GitHub project page](https://github.com/WordPress/health-check).
23
 
24
- == Installation ==
25
 
26
- 1. Upload to your plugins folder, usually `wp-content/plugins/`
27
- 2. Activate the plugin on the plugin screen.
28
- 3. Once activated the plugin will appear under your `Dashboard` menu.
 
 
29
 
30
  == Screenshots ==
31
 
@@ -35,26 +37,14 @@ In the future we may introduce more checks, and welcome feedback both through th
35
 
36
  == Changelog ==
37
 
38
- = v 1.1.2 =
39
- * Fixed child themes not displaying properly in Troubleshooting Mode.
40
- * Improved styling for the backup warning, shown when activating the plugin, so it doesn't block mobile users.
41
- * Added explanations to the plugins screen if you enter Troubleshooting Mode there, so users know what is going on.
42
- * Fixed admin menu overflowing if too many plugins exist.
43
-
44
- = v 1.1.1 =
45
- * Fixed a fatal error that would occur if a user had an older version of Troubleshooting Mode on their system.
46
-
47
- = v 1.1.0 =
48
- * Check for theme, plugin and WordPress updates when visiting the debug tab.
49
- * Improved wording on some failure situations.
50
- * Made the Debug Information tab a bit easier to read with fixed table styles.
51
- * Redesigned tools page, with added accordion to avoid information overload, and different features mixing together.
52
- * Mail test tool now allows you to include an optional customized message.
53
- * Users can now change between any installed theme while in troubleshooting mode.
54
- * Renamed the Must-Use plugin, making it align with what features present in the file.
55
- * Improved the plugin cleanup process, when the plugin is deleted.
56
- * Show full plugin names, and not slugs, in the troubleshooting admin bar menu.
57
- * Check if the .htaccess file contains any rules not added by WordPress core in the debug section.
58
- * Allow the disabling of Troubleshooting Mode from the same page as you previously enabled it from.
59
- * Removed cURL checks from the automated test page, this was more confusion than help.
60
- * Add installation size to the debug information.
1
+ === Health Check & Troubleshooting ===
2
  Tags: health check
3
  Contributors: wordpressdotorg, westi, pento, Clorith
4
+ Requires at least: 4.0
5
  Tested up to: 4.9
6
+ Stable tag: 1.2.0
7
  License: GPLv2
8
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
9
 
21
 
22
  In the future we may introduce more checks, and welcome feedback both through the [WordPress.org forums](https://wordpress.org/support/plugin/health-check), and the [GitHub project page](https://github.com/WordPress/health-check).
23
 
24
+ == Frequently Asked Questions ==
25
 
26
+ = I am unable to access my site after enabling troubleshooting =
27
+
28
+ If you should find your self stuck in Troubleshooting Mode for any reason, you can easily disable it by clearing your cookies.
29
+
30
+ Are you unfamiliar with how to clear your cookies? No worries, you may also close all your browser windows, or perform a computer restart and it will clear this specific cookie automatically.
31
 
32
  == Screenshots ==
33
 
37
 
38
  == Changelog ==
39
 
40
+ = v 1.2.0 =
41
+ * Changed plugin name, it now better describes the plugins two primary purposes.
42
+ * Changed the `Health Check` tab, it's now named `Site Status`, as we used the old name too many places and it was confusing.
43
+ * Site status tests now run asynchronously, making the page load much faster.
44
+ * The HTTPS tests now also check your Site URL settings to make sure they are following recommended best practices.
45
+ * Fixed a warning preventing plugin names from displaying on the front-end in some cases.
46
+ * Fixed an issue where you might get a 500 error if you tried using Troubleshooting Mode while using a child theme.
47
+ * Automatically disable/enable a plugin or theme in Troubleshooting Mode if they are detected to cause errors.
48
+ * Introduce a new dashboard widget during Troubleshooting Mode (and a simplified version on the plugins screen) to better explain what is going on, and make available actions more discoverable than the admin menu is.
49
+ * Some text improvements throughout the plugin.
50
+ * When loopback tests fail, we previously tested all plugins at once, for sites that have many plugins this may fail as the request times out. We now test one plugin at a time to avoid this, while also showing more information at the tests are running to the end user.
 
 
 
 
 
 
 
 
 
 
 
 
uninstall.php CHANGED
@@ -16,6 +16,7 @@ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
16
  delete_option( 'health-check-disable-plugin-hash' );
17
  delete_option( 'health-check-default-theme' );
18
  delete_option( 'health-check-current-theme' );
 
19
 
20
  /*
21
  * Remove any user meta entries we made, done with a custom query as core
16
  delete_option( 'health-check-disable-plugin-hash' );
17
  delete_option( 'health-check-default-theme' );
18
  delete_option( 'health-check-current-theme' );
19
+ delete_option( 'health-check-dashboard-notices' );
20
 
21
  /*
22
  * Remove any user meta entries we made, done with a custom query as core