Add upstream
This commit is contained in:
24
wp-content/plugins/jetpack/_inc/lib/debugger/0-load.php
Normal file
24
wp-content/plugins/jetpack/_inc/lib/debugger/0-load.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* Loading the various functions used for Jetpack Debugging.
|
||||
*
|
||||
* @package Jetpack.
|
||||
*/
|
||||
|
||||
global $wp_version;
|
||||
|
||||
/* Jetpack Connection Testing Framework */
|
||||
require_once 'class-jetpack-cxn-test-base.php';
|
||||
/* Jetpack Connection Tests */
|
||||
require_once 'class-jetpack-cxn-tests.php';
|
||||
/* Jetpack Debug Data */
|
||||
require_once 'class-jetpack-debug-data.php';
|
||||
/* The "In-Plugin Debugger" admin page. */
|
||||
require_once 'class-jetpack-debugger.php';
|
||||
|
||||
if ( version_compare( $wp_version, '5.2-alpha', 'ge' ) ) {
|
||||
require_once 'debug-functions-for-php53.php';
|
||||
add_filter( 'debug_information', array( 'Jetpack_Debug_Data', 'core_debug_data' ) );
|
||||
add_filter( 'site_status_tests', 'jetpack_debugger_site_status_tests' );
|
||||
add_action( 'wp_ajax_health-check-jetpack-local_testing_suite', 'jetpack_debugger_ajax_local_testing_suite' );
|
||||
}
|
||||
@@ -0,0 +1,471 @@
|
||||
<?php
|
||||
/**
|
||||
* Jetpack Connection Testing
|
||||
*
|
||||
* Framework for various "unit tests" against the Jetpack connection.
|
||||
*
|
||||
* Individual tests should be added to the class-jetpack-cxn-tests.php file.
|
||||
*
|
||||
* @author Brandon Kraft
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* "Unit Tests" for the Jetpack connection.
|
||||
*
|
||||
* @since 7.1.0
|
||||
*/
|
||||
class Jetpack_Cxn_Test_Base {
|
||||
|
||||
/**
|
||||
* Tests to run on the Jetpack connection.
|
||||
*
|
||||
* @var array $tests
|
||||
*/
|
||||
protected $tests = array();
|
||||
|
||||
/**
|
||||
* Results of the Jetpack connection tests.
|
||||
*
|
||||
* @var array $results
|
||||
*/
|
||||
protected $results = array();
|
||||
|
||||
/**
|
||||
* Status of the testing suite.
|
||||
*
|
||||
* Used internally to determine if a test should be skipped since the tests are already failing. Assume passing.
|
||||
*
|
||||
* @var bool $pass
|
||||
*/
|
||||
protected $pass = true;
|
||||
|
||||
/**
|
||||
* Jetpack_Cxn_Test constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->tests = array();
|
||||
$this->results = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new test to the Jetpack Connection Testing suite.
|
||||
*
|
||||
* @since 7.1.0
|
||||
* @since 7.3.0 Adds name parameter and returns WP_Error on failure.
|
||||
*
|
||||
* @param callable $callable Test to add to queue.
|
||||
* @param string $name Unique name for the test.
|
||||
* @param string $type Optional. Core Site Health type: 'direct' if test can be run during initial load or 'async' if test should run async.
|
||||
* @param array $groups Optional. Testing groups to add test to.
|
||||
*
|
||||
* @return mixed True if successfully added. WP_Error on failure.
|
||||
*/
|
||||
public function add_test( $callable, $name, $type = 'direct', $groups = array( 'default' ) ) {
|
||||
if ( is_array( $name ) ) {
|
||||
// Pre-7.3.0 method passed the $groups parameter here.
|
||||
return new WP_Error( __( 'add_test arguments changed in 7.3.0. Please reference inline documentation.', 'jetpack' ) );
|
||||
}
|
||||
if ( array_key_exists( $name, $this->tests ) ) {
|
||||
return new WP_Error( __( 'Test names must be unique.', 'jetpack' ) );
|
||||
}
|
||||
if ( ! is_callable( $callable ) ) {
|
||||
return new WP_Error( __( 'Tests must be valid PHP callables.', 'jetpack' ) );
|
||||
}
|
||||
|
||||
$this->tests[ $name ] = array(
|
||||
'name' => $name,
|
||||
'test' => $callable,
|
||||
'group' => $groups,
|
||||
'type' => $type,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all tests to run.
|
||||
*
|
||||
* @since 7.3.0
|
||||
*
|
||||
* @param string $type Optional. Core Site Health type: 'direct' or 'async'. All by default.
|
||||
* @param string $group Optional. A specific testing group. All by default.
|
||||
*
|
||||
* @return array $tests Array of tests with test information.
|
||||
*/
|
||||
public function list_tests( $type = 'all', $group = 'all' ) {
|
||||
if ( ! ( 'all' === $type || 'direct' === $type || 'async' === $type ) ) {
|
||||
_doing_it_wrong( 'Jetpack_Cxn_Test_Base->list_tests', 'Type must be all, direct, or async', '7.3.0' );
|
||||
}
|
||||
|
||||
$tests = array();
|
||||
foreach ( $this->tests as $name => $value ) {
|
||||
// Get all valid tests by group staged.
|
||||
if ( 'all' === $group || $group === $value['group'] ) {
|
||||
$tests[ $name ] = $value;
|
||||
}
|
||||
|
||||
// Next filter out any that do not match the type.
|
||||
if ( 'all' !== $type && $type !== $value['type'] ) {
|
||||
unset( $tests[ $name ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a specific test.
|
||||
*
|
||||
* @since 7.3.0
|
||||
*
|
||||
* @param string $name Name of test.
|
||||
*
|
||||
* @return mixed $result Test result array or WP_Error if invalid name. {
|
||||
* @type string $name Test name
|
||||
* @type mixed $pass True if passed, false if failed, 'skipped' if skipped.
|
||||
* @type string $message Human-readable test result message.
|
||||
* @type string $resolution Human-readable resolution steps.
|
||||
* }
|
||||
*/
|
||||
public function run_test( $name ) {
|
||||
if ( array_key_exists( $name, $this->tests ) ) {
|
||||
return call_user_func( $this->tests[ $name ]['test'] );
|
||||
}
|
||||
return new WP_Error( __( 'There is no test by that name: ', 'jetpack' ) . $name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the Jetpack connection suite.
|
||||
*/
|
||||
public function run_tests() {
|
||||
foreach ( $this->tests as $test ) {
|
||||
$result = call_user_func( $test['test'] );
|
||||
$result['group'] = $test['group'];
|
||||
$result['type'] = $test['type'];
|
||||
$this->results[] = $result;
|
||||
if ( false === $result['pass'] ) {
|
||||
$this->pass = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full results array.
|
||||
*
|
||||
* @since 7.1.0
|
||||
* @since 7.3.0 Add 'type'
|
||||
*
|
||||
* @param string $type Test type, async or direct.
|
||||
* @param string $group Testing group whose results we want. Defaults to all tests.
|
||||
* @return array Array of test results.
|
||||
*/
|
||||
public function raw_results( $type = 'all', $group = 'all' ) {
|
||||
if ( ! $this->results ) {
|
||||
$this->run_tests();
|
||||
}
|
||||
|
||||
$results = $this->results;
|
||||
|
||||
if ( 'all' !== $group ) {
|
||||
foreach ( $results as $test => $result ) {
|
||||
if ( ! in_array( $group, $result['group'], true ) ) {
|
||||
unset( $results[ $test ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'all' !== $type ) {
|
||||
foreach ( $results as $test => $result ) {
|
||||
if ( $type !== $result['type'] ) {
|
||||
unset( $results[ $test ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the connection suite.
|
||||
*
|
||||
* @since 7.1.0
|
||||
* @since 7.3.0 Add 'type'
|
||||
*
|
||||
* @param string $type Test type, async or direct. Optional, direct all tests.
|
||||
* @param string $group Testing group to check status of. Optional, default all tests.
|
||||
*
|
||||
* @return true|array True if all tests pass. Array of failed tests.
|
||||
*/
|
||||
public function pass( $type = 'all', $group = 'all' ) {
|
||||
$results = $this->raw_results( $type, $group );
|
||||
|
||||
foreach ( $results as $result ) {
|
||||
// 'pass' could be true, false, or 'skipped'. We only want false.
|
||||
if ( isset( $result['pass'] ) && false === $result['pass'] ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of failed test messages.
|
||||
*
|
||||
* @since 7.1.0
|
||||
* @since 7.3.0 Add 'type'
|
||||
*
|
||||
* @param string $type Test type, direct or async.
|
||||
* @param string $group Testing group whose failures we want. Defaults to "all".
|
||||
*
|
||||
* @return false|array False if no failed tests. Otherwise, array of failed tests.
|
||||
*/
|
||||
public function list_fails( $type = 'all', $group = 'all' ) {
|
||||
$results = $this->raw_results( $type, $group );
|
||||
|
||||
foreach ( $results as $test => $result ) {
|
||||
// We do not want tests that passed or ones that are misconfigured (no pass status or no failure message).
|
||||
if ( ! isset( $result['pass'] ) || false !== $result['pass'] || ! isset( $result['message'] ) ) {
|
||||
unset( $results[ $test ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return consistent responses for a passing test.
|
||||
*
|
||||
* @param string $name Test name.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
public static function passing_test( $name = 'Unnamed' ) {
|
||||
return array(
|
||||
'name' => $name,
|
||||
'pass' => true,
|
||||
'message' => __( 'Test Passed!', 'jetpack' ),
|
||||
'resolution' => false,
|
||||
'severity' => false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return consistent responses for a skipped test.
|
||||
*
|
||||
* @param string $name Test name.
|
||||
* @param string $message Reason for skipping the test. Optional.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
public static function skipped_test( $name = 'Unnamed', $message = false ) {
|
||||
return array(
|
||||
'name' => $name,
|
||||
'pass' => 'skipped',
|
||||
'message' => $message,
|
||||
'resolution' => false,
|
||||
'severity' => false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return consistent responses for a failing test.
|
||||
*
|
||||
* @since 7.1.0
|
||||
* @since 7.3.0 Added $action for resolution action link, $severity for issue severity.
|
||||
*
|
||||
* @param string $name Test name.
|
||||
* @param string $message Message detailing the failure.
|
||||
* @param string $resolution Optional. Steps to resolve.
|
||||
* @param string $action Optional. URL to direct users to self-resolve.
|
||||
* @param string $severity Optional. "critical" or "recommended" for failure stats. "good" for passing.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
public static function failing_test( $name, $message, $resolution = false, $action = false, $severity = 'critical' ) {
|
||||
// Provide standard resolutions steps, but allow pass-through of non-standard ones.
|
||||
switch ( $resolution ) {
|
||||
case 'cycle_connection':
|
||||
$resolution = __( 'Please disconnect and reconnect Jetpack.', 'jetpack' ); // @todo: Link.
|
||||
break;
|
||||
case 'outbound_requests':
|
||||
$resolution = __( 'Please ask your hosting provider to confirm your server can make outbound requests to jetpack.com.', 'jetpack' );
|
||||
break;
|
||||
case 'support':
|
||||
case false:
|
||||
$resolution = __( 'Please contact Jetpack support.', 'jetpack' ); // @todo: Link to support.
|
||||
break;
|
||||
}
|
||||
|
||||
return array(
|
||||
'name' => $name,
|
||||
'pass' => false,
|
||||
'message' => $message,
|
||||
'resolution' => $resolution,
|
||||
'action' => $action,
|
||||
'severity' => $severity,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide WP_CLI friendly testing results.
|
||||
*
|
||||
* @since 7.1.0
|
||||
* @since 7.3.0 Add 'type'
|
||||
*
|
||||
* @param string $type Test type, direct or async.
|
||||
* @param string $group Testing group whose results we are outputting. Default all tests.
|
||||
*/
|
||||
public function output_results_for_cli( $type = 'all', $group = 'all' ) {
|
||||
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
||||
if ( Jetpack::is_development_mode() ) {
|
||||
WP_CLI::line( __( 'Jetpack is in Development Mode:', 'jetpack' ) );
|
||||
WP_CLI::line( Jetpack::development_mode_trigger_text() );
|
||||
}
|
||||
WP_CLI::line( __( 'TEST RESULTS:', 'jetpack' ) );
|
||||
foreach ( $this->raw_results( $group ) as $test ) {
|
||||
if ( true === $test['pass'] ) {
|
||||
WP_CLI::log( WP_CLI::colorize( '%gPassed:%n ' . $test['name'] ) );
|
||||
} elseif ( 'skipped' === $test['pass'] ) {
|
||||
WP_CLI::log( WP_CLI::colorize( '%ySkipped:%n ' . $test['name'] ) );
|
||||
if ( $test['message'] ) {
|
||||
WP_CLI::log( ' ' . $test['message'] ); // Number of spaces to "tab indent" the reason.
|
||||
}
|
||||
} else { // Failed.
|
||||
WP_CLI::log( WP_CLI::colorize( '%rFailed:%n ' . $test['name'] ) );
|
||||
WP_CLI::log( ' ' . $test['message'] ); // Number of spaces to "tab indent" the reason.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output results of failures in format expected by Core's Site Health tool for async tests.
|
||||
*
|
||||
* Specifically not asking for a testing group since we're opinionated that Site Heath should see all.
|
||||
*
|
||||
* @since 7.3.0
|
||||
*
|
||||
* @return array Array of test results
|
||||
*/
|
||||
public function output_results_for_core_async_site_health() {
|
||||
$result = array(
|
||||
'label' => __( 'Jetpack passed all async tests.', 'jetpack' ),
|
||||
'status' => 'good',
|
||||
'badge' => array(
|
||||
'label' => __( 'Jetpack', 'jetpack' ),
|
||||
'color' => 'green',
|
||||
),
|
||||
'description' => sprintf(
|
||||
'<p>%s</p>',
|
||||
__( "Jetpack's async local testing suite passed all tests!", 'jetpack' )
|
||||
),
|
||||
'actions' => '',
|
||||
'test' => 'jetpack_debugger_local_testing_suite_core',
|
||||
);
|
||||
|
||||
if ( $this->pass() ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$fails = $this->list_fails( 'async' );
|
||||
$error = false;
|
||||
foreach ( $fails as $fail ) {
|
||||
if ( ! $error ) {
|
||||
$error = true;
|
||||
$result['label'] = $fail['message'];
|
||||
$result['status'] = $fail['severity'];
|
||||
$result['description'] = sprintf(
|
||||
'<p>%s</p>',
|
||||
$fail['resolution']
|
||||
);
|
||||
if ( ! empty( $fail['action'] ) ) {
|
||||
$result['actions'] = sprintf(
|
||||
'<a class="button button-primary" href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
|
||||
esc_url( $fail['action'] ),
|
||||
__( 'Resolve', 'jetpack' ),
|
||||
/* translators: accessibility text */
|
||||
__( '(opens in a new tab)', 'jetpack' )
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$result['description'] .= sprintf(
|
||||
'<p>%s</p>',
|
||||
__( 'There was another problem:', 'jetpack' )
|
||||
) . ' ' . $fail['message'] . ': ' . $fail['resolution'];
|
||||
if ( 'critical' === $fail['severity'] ) { // In case the initial failure is only "recommended".
|
||||
$result['status'] = 'critical';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide single WP Error instance of all failures.
|
||||
*
|
||||
* @since 7.1.0
|
||||
* @since 7.3.0 Add 'type'
|
||||
*
|
||||
* @param string $type Test type, direct or async.
|
||||
* @param string $group Testing group whose failures we want converted. Default all tests.
|
||||
*
|
||||
* @return WP_Error|false WP_Error with all failed tests or false if there were no failures.
|
||||
*/
|
||||
public function output_fails_as_wp_error( $type = 'all', $group = 'all' ) {
|
||||
if ( $this->pass( $group ) ) {
|
||||
return false;
|
||||
}
|
||||
$fails = $this->list_fails( $type, $group );
|
||||
$error = false;
|
||||
|
||||
foreach ( $fails as $result ) {
|
||||
$code = 'failed_' . $result['name'];
|
||||
$message = $result['message'];
|
||||
$data = array(
|
||||
'resolution' => $result['resolution'],
|
||||
);
|
||||
if ( ! $error ) {
|
||||
$error = new WP_Error( $code, $message, $data );
|
||||
} else {
|
||||
$error->add( $code, $message, $data );
|
||||
}
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt data for sending to WordPress.com.
|
||||
*
|
||||
* @todo When PHP minimum is 5.3+, add cipher detection to use an agreed better cipher than RC4. RC4 should be the last resort.
|
||||
*
|
||||
* @param string $data Data to encrypt with the WP.com Public Key.
|
||||
*
|
||||
* @return false|array False if functionality not available. Array of encrypted data, encryption key.
|
||||
*/
|
||||
public function encrypt_string_for_wpcom( $data ) {
|
||||
$return = false;
|
||||
if ( ! function_exists( 'openssl_get_publickey' ) || ! function_exists( 'openssl_seal' ) ) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
$public_key = openssl_get_publickey( JETPACK__DEBUGGER_PUBLIC_KEY );
|
||||
|
||||
if ( $public_key && openssl_seal( $data, $encrypted_data, $env_key, array( $public_key ) ) ) {
|
||||
// We are returning base64-encoded values to ensure they're characters we can use in JSON responses without issue.
|
||||
$return = array(
|
||||
'data' => base64_encode( $encrypted_data ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
|
||||
'key' => base64_encode( $env_key[0] ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
|
||||
'cipher' => 'RC4', // When Jetpack's minimum WP version is at PHP 5.3+, we will add in detecting and using a stronger one.
|
||||
);
|
||||
}
|
||||
|
||||
openssl_free_key( $public_key );
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
<?php
|
||||
/**
|
||||
* Collection of tests to run on the Jetpack connection locally.
|
||||
*
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Connection\Client;
|
||||
|
||||
/**
|
||||
* Class Jetpack_Cxn_Tests contains all of the actual tests.
|
||||
*/
|
||||
class Jetpack_Cxn_Tests extends Jetpack_Cxn_Test_Base {
|
||||
|
||||
/**
|
||||
* Jetpack_Cxn_Tests constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$methods = get_class_methods( 'Jetpack_Cxn_Tests' );
|
||||
|
||||
foreach ( $methods as $method ) {
|
||||
if ( false === strpos( $method, 'test__' ) ) {
|
||||
continue;
|
||||
}
|
||||
$this->add_test( array( $this, $method ), $method, 'direct' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after loading default Jetpack Connection tests.
|
||||
*
|
||||
* @since 7.1.0
|
||||
*/
|
||||
do_action( 'jetpack_connection_tests_loaded' );
|
||||
|
||||
/**
|
||||
* Determines if the WP.com testing suite should be included.
|
||||
*
|
||||
* @since 7.1.0
|
||||
*
|
||||
* @param bool $run_test To run the WP.com testing suite. Default true.
|
||||
*/
|
||||
if ( apply_filters( 'jetpack_debugger_run_self_test', true ) ) {
|
||||
/**
|
||||
* Intentionally added last as it checks for an existing failure state before attempting.
|
||||
* Generally, any failed location condition would result in the WP.com check to fail too, so
|
||||
* we will skip it to avoid confusing error messages.
|
||||
*
|
||||
* Note: This really should be an 'async' test.
|
||||
*/
|
||||
$this->add_test( array( $this, 'last__wpcom_self_test' ), 'test__wpcom_self_test', 'direct' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to look up the expected master user and return the local WP_User.
|
||||
*
|
||||
* @return WP_User Jetpack's expected master user.
|
||||
*/
|
||||
protected function helper_retrieve_local_master_user() {
|
||||
$master_user = Jetpack_Options::get_option( 'master_user' );
|
||||
return new WP_User( $master_user );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Jetpack even connected and supposed to be talking to WP.com?
|
||||
*/
|
||||
protected function helper_is_jetpack_connected() {
|
||||
return ( Jetpack::is_active() && ! Jetpack::is_development_mode() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if Jetpack is connected.
|
||||
*/
|
||||
protected function test__check_if_connected() {
|
||||
$name = __FUNCTION__;
|
||||
if ( $this->helper_is_jetpack_connected() ) {
|
||||
$result = self::passing_test( $name );
|
||||
} elseif ( Jetpack::is_development_mode() ) {
|
||||
$result = self::skipped_test( $name, __( 'Jetpack is in Development Mode:', 'jetpack' ) . ' ' . Jetpack::development_mode_trigger_text(), __( 'Disable development mode.', 'jetpack' ) );
|
||||
} else {
|
||||
$result = self::failing_test( $name, __( 'Jetpack is not connected.', 'jetpack' ), 'cycle_connection' );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the master user still exists on this site.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
protected function test__master_user_exists_on_site() {
|
||||
$name = __FUNCTION__;
|
||||
if ( ! $this->helper_is_jetpack_connected() ) {
|
||||
return self::skipped_test( $name, __( 'Jetpack is not connected. No master user to check.', 'jetpack' ) ); // Skip test.
|
||||
}
|
||||
$local_user = $this->helper_retrieve_local_master_user();
|
||||
|
||||
if ( $local_user->exists() ) {
|
||||
$result = self::passing_test( $name );
|
||||
} else {
|
||||
$result = self::failing_test( $name, __( 'The user who setup the Jetpack connection no longer exists on this site.', 'jetpack' ), 'cycle_connection' );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the master user has the manage options capability (e.g. is an admin).
|
||||
*
|
||||
* Generic calls from WP.com execute on Jetpack as the master user. If it isn't an admin, random things will fail.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
protected function test__master_user_can_manage_options() {
|
||||
$name = __FUNCTION__;
|
||||
if ( ! $this->helper_is_jetpack_connected() ) {
|
||||
return self::skipped_test( $name, __( 'Jetpack is not connected.', 'jetpack' ) ); // Skip test.
|
||||
}
|
||||
$master_user = $this->helper_retrieve_local_master_user();
|
||||
|
||||
if ( user_can( $master_user, 'manage_options' ) ) {
|
||||
$result = self::passing_test( $name );
|
||||
} else {
|
||||
/* translators: a WordPress username */
|
||||
$result = self::failing_test( $name, sprintf( __( 'The user (%s) who setup the Jetpack connection is not an administrator.', 'jetpack' ), $master_user->user_login ), __( 'Either upgrade the user or disconnect and reconnect Jetpack.', 'jetpack' ) ); // @todo: Link to the right places.
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the PHP's XML library is installed.
|
||||
*
|
||||
* While it should be installed by default, increasingly in PHP 7, some OSes require an additional php-xml package.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
protected function test__xml_parser_available() {
|
||||
$name = __FUNCTION__;
|
||||
if ( function_exists( 'xml_parser_create' ) ) {
|
||||
$result = self::passing_test( $name );
|
||||
} else {
|
||||
$result = self::failing_test( $name, __( 'PHP XML manipluation libraries are not available.', 'jetpack' ), __( "Please ask your hosting provider to refer to our server requirements at https://jetpack.com/support/server-requirements/ and enable PHP's XML module.", 'jetpack' ) );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the server is able to send an outbound http communication.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
protected function test__outbound_http() {
|
||||
$name = __FUNCTION__;
|
||||
$request = wp_remote_get( preg_replace( '/^https:/', 'http:', JETPACK__API_BASE ) . 'test/1/' );
|
||||
$code = wp_remote_retrieve_response_code( $request );
|
||||
|
||||
if ( 200 === intval( $code ) ) {
|
||||
$result = self::passing_test( $name );
|
||||
} else {
|
||||
$result = self::failing_test( $name, __( 'Your server did not successfully connect to the Jetpack server using HTTP', 'jetpack' ), 'outbound_requests' );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the server is able to send an outbound https communication.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
protected function test__outbound_https() {
|
||||
$name = __FUNCTION__;
|
||||
$request = wp_remote_get( preg_replace( '/^http:/', 'https:', JETPACK__API_BASE ) . 'test/1/' );
|
||||
$code = wp_remote_retrieve_response_code( $request );
|
||||
|
||||
if ( 200 === intval( $code ) ) {
|
||||
$result = self::passing_test( $name );
|
||||
} else {
|
||||
$result = self::failing_test( $name, __( 'Your server did not successfully connect to the Jetpack server using HTTPS', 'jetpack' ), 'outbound_requests' );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for an IDC.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
protected function test__identity_crisis() {
|
||||
$name = __FUNCTION__;
|
||||
if ( ! $this->helper_is_jetpack_connected() ) {
|
||||
return self::skipped_test( $name, __( 'Jetpack is not connected.', 'jetpack' ) ); // Skip test.
|
||||
}
|
||||
$identity_crisis = Jetpack::check_identity_crisis();
|
||||
|
||||
if ( ! $identity_crisis ) {
|
||||
$result = self::passing_test( $name );
|
||||
} else {
|
||||
$message = sprintf(
|
||||
/* translators: Two URLs. The first is the locally-recorded value, the second is the value as recorded on WP.com. */
|
||||
__( 'Your url is set as `%1$s`, but your WordPress.com connection lists it as `%2$s`!', 'jetpack' ),
|
||||
$identity_crisis['home'],
|
||||
$identity_crisis['wpcom_home']
|
||||
);
|
||||
$result = self::failing_test( $name, $message, 'support' );
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests connection status against wp.com's test-connection endpoint
|
||||
*
|
||||
* @todo: Compare with the wpcom_self_test. We only need one of these.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
protected function test__wpcom_connection_test() {
|
||||
$name = __FUNCTION__;
|
||||
|
||||
if ( ! Jetpack::is_active() || Jetpack::is_development_mode() || Jetpack::is_staging_site() || ! $this->pass ) {
|
||||
return self::skipped_test( $name );
|
||||
}
|
||||
|
||||
$response = Client::wpcom_json_api_request_as_blog(
|
||||
sprintf( '/jetpack-blogs/%d/test-connection', Jetpack_Options::get_option( 'id' ) ),
|
||||
Client::WPCOM_JSON_API_VERSION
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
/* translators: %1$s is the error code, %2$s is the error message */
|
||||
$message = sprintf( __( 'Connection test failed (#%1$s: %2$s)', 'jetpack' ), $response->get_error_code(), $response->get_error_message() );
|
||||
return self::failing_test( $name, $message );
|
||||
}
|
||||
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
if ( ! $body ) {
|
||||
$message = __( 'Connection test failed (empty response body)', 'jetpack' ) . wp_remote_retrieve_response_code( $response );
|
||||
return self::failing_test( $name, $message );
|
||||
}
|
||||
|
||||
if ( 404 === wp_remote_retrieve_response_code( $response ) ) {
|
||||
return self::skipped_test( $name, __( 'The WordPress.com API returned a 404 error.', 'jetpack' ) );
|
||||
}
|
||||
|
||||
$result = json_decode( $body );
|
||||
$is_connected = (bool) $result->connected;
|
||||
$message = $result->message . ': ' . wp_remote_retrieve_response_code( $response );
|
||||
|
||||
if ( $is_connected ) {
|
||||
return self::passing_test( $name );
|
||||
} else {
|
||||
return self::failing_test( $name, $message );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the port number to ensure it is an expected value.
|
||||
*
|
||||
* We expect that sites on be on one of:
|
||||
* port 80,
|
||||
* port 443 (https sites only),
|
||||
* the value of JETPACK_SIGNATURE__HTTP_PORT,
|
||||
* unless the site is intentionally on a different port (e.g. example.com:8080 is the site's URL).
|
||||
*
|
||||
* If the value isn't one of those and the site's URL doesn't include a port, then the signature verification will fail.
|
||||
*
|
||||
* This happens most commonly on sites with reverse proxies, so the edge (e.g. Varnish) is running on 80/443, but nginx
|
||||
* or Apache is responding internally on a different port (e.g. 81).
|
||||
*
|
||||
* @return array Test results
|
||||
*/
|
||||
protected function test__server_port_value() {
|
||||
$name = __FUNCTION__;
|
||||
if ( ! isset( $_SERVER['HTTP_X_FORWARDED_PORT'] ) && ! isset( $_SERVER['SERVER_PORT'] ) ) {
|
||||
$message = 'The server port values are not defined. This is most common when running PHP via a CLI.';
|
||||
return self::skipped_test( $name, $message );
|
||||
}
|
||||
$site_port = wp_parse_url( home_url(), PHP_URL_PORT );
|
||||
$server_port = isset( $_SERVER['HTTP_X_FORWARDED_PORT'] ) ? (int) $_SERVER['HTTP_X_FORWARDED_PORT'] : (int) $_SERVER['SERVER_PORT'];
|
||||
$http_ports = array( 80 );
|
||||
$https_ports = array( 80, 443 );
|
||||
|
||||
if ( defined( 'JETPACK_SIGNATURE__HTTP_PORT' ) ) {
|
||||
$http_ports[] = JETPACK_SIGNATURE__HTTP_PORT;
|
||||
}
|
||||
|
||||
if ( defined( 'JETPACK_SIGNATURE__HTTPS_PORT' ) ) {
|
||||
$https_ports[] = JETPACK_SIGNATURE__HTTPS_PORT;
|
||||
}
|
||||
|
||||
if ( $site_port ) {
|
||||
return self::skipped_test( $name ); // Not currently testing for this situation.
|
||||
}
|
||||
|
||||
if ( is_ssl() && in_array( $server_port, $https_ports, true ) ) {
|
||||
return self::passing_test( $name );
|
||||
} elseif ( in_array( $server_port, $http_ports, true ) ) {
|
||||
return self::passing_test( $name );
|
||||
} else {
|
||||
if ( is_ssl() ) {
|
||||
$needed_constant = 'JETPACK_SIGNATURE__HTTPS_PORT';
|
||||
} else {
|
||||
$needed_constant = 'JETPACK_SIGNATURE__HTTP_PORT';
|
||||
}
|
||||
$message = __( 'The server port value is unexpected.', 'jetpack' );
|
||||
$resolution = __( 'Try adding the following to your wp-config.php file:', 'jetpack' ) . " define( '$needed_constant', $server_port );";
|
||||
return self::failing_test( $name, $message, $resolution );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls to WP.com to run the connection diagnostic testing suite.
|
||||
*
|
||||
* Intentionally added last as it will be skipped if any local failed conditions exist.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
protected function last__wpcom_self_test() {
|
||||
$name = 'test__wpcom_self_test';
|
||||
if ( ! Jetpack::is_active() || Jetpack::is_development_mode() || Jetpack::is_staging_site() || ! $this->pass ) {
|
||||
return self::skipped_test( $name );
|
||||
}
|
||||
|
||||
$self_xml_rpc_url = site_url( 'xmlrpc.php' );
|
||||
|
||||
$testsite_url = Jetpack::fix_url_for_bad_hosts( JETPACK__API_BASE . 'testsite/1/?url=' );
|
||||
|
||||
add_filter( 'http_request_timeout', array( 'Jetpack_Debugger', 'jetpack_increase_timeout' ) );
|
||||
|
||||
$response = wp_remote_get( $testsite_url . $self_xml_rpc_url );
|
||||
|
||||
remove_filter( 'http_request_timeout', array( 'Jetpack_Debugger', 'jetpack_increase_timeout' ) );
|
||||
|
||||
if ( 200 === wp_remote_retrieve_response_code( $response ) ) {
|
||||
return self::passing_test( $name );
|
||||
} else {
|
||||
return self::failing_test( $name, __( 'Jetpack.com detected an error.', 'jetpack' ), __( 'Visit the Jetpack.com debugging page for more information or contact support.', 'jetpack' ) ); // @todo direct links.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
<?php
|
||||
/**
|
||||
* Jetpack Debug Data for the legacy Jetpack debugger page and the WP 5.2-era Site Health sections.
|
||||
*
|
||||
* @package jetpack
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Constants;
|
||||
use Automattic\Jetpack\Sync\Modules;
|
||||
use Automattic\Jetpack\Sync\Functions;
|
||||
use Automattic\Jetpack\Sync\Sender;
|
||||
|
||||
/**
|
||||
* Class Jetpack_Debug_Data
|
||||
*
|
||||
* Collect and return debug data for Jetpack.
|
||||
*
|
||||
* @since 7.3.0
|
||||
*/
|
||||
class Jetpack_Debug_Data {
|
||||
/**
|
||||
* Determine the active plan and normalize it for the debugger results.
|
||||
*
|
||||
* @since 7.3.0
|
||||
*
|
||||
* @return string The plan slug.
|
||||
*/
|
||||
public static function what_jetpack_plan() {
|
||||
$plan = Jetpack_Plan::get();
|
||||
return ! empty( $plan['class'] ) ? $plan['class'] : 'undefined';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert seconds to human readable time.
|
||||
*
|
||||
* A dedication function instead of using Core functionality to allow for output in seconds.
|
||||
*
|
||||
* @since 7.3.0
|
||||
*
|
||||
* @param int $seconds Number of seconds to convert to human time.
|
||||
*
|
||||
* @return string Human readable time.
|
||||
*/
|
||||
public static function seconds_to_time( $seconds ) {
|
||||
$seconds = intval( $seconds );
|
||||
$units = array(
|
||||
'week' => WEEK_IN_SECONDS,
|
||||
'day' => DAY_IN_SECONDS,
|
||||
'hour' => HOUR_IN_SECONDS,
|
||||
'minute' => MINUTE_IN_SECONDS,
|
||||
'second' => 1,
|
||||
);
|
||||
// specifically handle zero.
|
||||
if ( 0 === $seconds ) {
|
||||
return '0 seconds';
|
||||
}
|
||||
$human_readable = '';
|
||||
foreach ( $units as $name => $divisor ) {
|
||||
$quot = intval( $seconds / $divisor );
|
||||
if ( $quot ) {
|
||||
$human_readable .= "$quot $name";
|
||||
$human_readable .= ( abs( $quot ) > 1 ? 's' : '' ) . ', ';
|
||||
$seconds -= $quot * $divisor;
|
||||
}
|
||||
}
|
||||
return substr( $human_readable, 0, -2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return debug data in the format expected by Core's Site Health Info tab.
|
||||
*
|
||||
* @since 7.3.0
|
||||
*
|
||||
* @param array $debug {
|
||||
* The debug information already compiled by Core.
|
||||
*
|
||||
* @type string $label The title for this section of the debug output.
|
||||
* @type string $description Optional. A description for your information section which may contain basic HTML
|
||||
* markup: `em`, `strong` and `a` for linking to documentation or putting emphasis.
|
||||
* @type boolean $show_count Optional. If set to `true` the amount of fields will be included in the title for
|
||||
* this section.
|
||||
* @type boolean $private Optional. If set to `true` the section and all associated fields will be excluded
|
||||
* from the copy-paste text area.
|
||||
* @type array $fields {
|
||||
* An associative array containing the data to be displayed.
|
||||
*
|
||||
* @type string $label The label for this piece of information.
|
||||
* @type string $value The output that is of interest for this field.
|
||||
* @type boolean $private Optional. If set to `true` the field will not be included in the copy-paste text area
|
||||
* on top of the page, allowing you to show, for example, API keys here.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @return array $args Debug information in the same format as the initial argument.
|
||||
*/
|
||||
public static function core_debug_data( $debug ) {
|
||||
$support_url = Jetpack::is_development_version()
|
||||
? 'https://jetpack.com/contact-support/beta-group/'
|
||||
: 'https://jetpack.com/contact-support/';
|
||||
|
||||
$jetpack = array(
|
||||
'jetpack' => array(
|
||||
'label' => __( 'Jetpack', 'jetpack' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s is URL to jetpack.com's contact support page. %2$s accessibility text */
|
||||
__(
|
||||
'Diagnostic information helpful to <a href="%1$s" target="_blank" rel="noopener noreferrer">your Jetpack Happiness team<span class="screen-reader-text">%2$s</span></a>',
|
||||
'jetpack'
|
||||
),
|
||||
esc_url( $support_url ),
|
||||
__( '(opens in a new tab)', 'jetpack' )
|
||||
),
|
||||
'fields' => self::debug_data(),
|
||||
),
|
||||
);
|
||||
$debug = array_merge( $debug, $jetpack );
|
||||
return $debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile and return array of debug information.
|
||||
*
|
||||
* @since 7.3.0
|
||||
*
|
||||
* @return array $args {
|
||||
* Associated array of arrays with the following.
|
||||
* @type string $label The label for this piece of information.
|
||||
* @type string $value The output that is of interest for this field.
|
||||
* @type boolean $private Optional. Set to true if data is sensitive (API keys, etc).
|
||||
* }
|
||||
*/
|
||||
public static function debug_data() {
|
||||
$debug_info = array();
|
||||
|
||||
/* Add various important Jetpack options */
|
||||
$debug_info['site_id'] = array(
|
||||
'label' => 'Jetpack Site ID',
|
||||
'value' => Jetpack_Options::get_option( 'id' ),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['ssl_cert'] = array(
|
||||
'label' => 'Jetpack SSL Verfication Bypass',
|
||||
'value' => ( Jetpack_Options::get_option( 'fallback_no_verify_ssl_certs' ) ) ? 'Yes' : 'No',
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['time_diff'] = array(
|
||||
'label' => "Offset between Jetpack server's time and this server's time.",
|
||||
'value' => Jetpack_Options::get_option( 'time_diff' ),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['version_option'] = array(
|
||||
'label' => 'Current Jetpack Version Option',
|
||||
'value' => Jetpack_Options::get_option( 'version' ),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['old_version'] = array(
|
||||
'label' => 'Previous Jetpack Version',
|
||||
'value' => Jetpack_Options::get_option( 'old_version' ),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['public'] = array(
|
||||
'label' => 'Jetpack Site Public',
|
||||
'value' => ( Jetpack_Options::get_option( 'public' ) ) ? 'Public' : 'Private',
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['master_user'] = array(
|
||||
'label' => 'Jetpack Master User',
|
||||
'value' => self::human_readable_master_user(),
|
||||
'private' => false,
|
||||
);
|
||||
|
||||
/**
|
||||
* Token information is private, but awareness if there one is set is helpful.
|
||||
*
|
||||
* To balance out information vs privacy, we only display and include the "key",
|
||||
* which is a segment of the token prior to a period within the token and is
|
||||
* technically not private.
|
||||
*
|
||||
* If a token does not contain a period, then it is malformed and we report it as such.
|
||||
*/
|
||||
$user_id = get_current_user_id();
|
||||
$blog_token = Jetpack_Data::get_access_token();
|
||||
$user_token = Jetpack_Data::get_access_token( $user_id );
|
||||
|
||||
$tokenset = '';
|
||||
if ( $blog_token ) {
|
||||
$tokenset = 'Blog ';
|
||||
$blog_key = substr( $blog_token->secret, 0, strpos( $blog_token->secret, '.' ) );
|
||||
// Intentionally not translated since this is helpful when sent to Happiness.
|
||||
$blog_key = ( $blog_key ) ? $blog_key : 'Potentially Malformed Token.';
|
||||
}
|
||||
if ( $user_token ) {
|
||||
$tokenset .= 'User';
|
||||
$user_key = substr( $user_token->secret, 0, strpos( $user_token->secret, '.' ) );
|
||||
// Intentionally not translated since this is helpful when sent to Happiness.
|
||||
$user_key = ( $user_key ) ? $user_key : 'Potentially Malformed Token.';
|
||||
}
|
||||
if ( ! $tokenset ) {
|
||||
$tokenset = 'None';
|
||||
}
|
||||
|
||||
$debug_info['current_user'] = array(
|
||||
'label' => 'Current User',
|
||||
'value' => self::human_readable_user( $user_id ),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['tokens_set'] = array(
|
||||
'label' => 'Tokens defined',
|
||||
'value' => $tokenset,
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['blog_token'] = array(
|
||||
'label' => 'Blog Public Key',
|
||||
'value' => ( $blog_token ) ? $blog_key : 'Not set.',
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['user_token'] = array(
|
||||
'label' => 'User Public Key',
|
||||
'value' => ( $user_token ) ? $user_key : 'Not set.',
|
||||
'private' => false,
|
||||
);
|
||||
|
||||
/** Jetpack Environmental Information */
|
||||
$debug_info['version'] = array(
|
||||
'label' => 'Jetpack Version',
|
||||
'value' => JETPACK__VERSION,
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['jp_plugin_dir'] = array(
|
||||
'label' => 'Jetpack Directory',
|
||||
'value' => JETPACK__PLUGIN_DIR,
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['plan'] = array(
|
||||
'label' => 'Plan Type',
|
||||
'value' => self::what_jetpack_plan(),
|
||||
'private' => false,
|
||||
);
|
||||
|
||||
foreach ( array(
|
||||
'HTTP_HOST',
|
||||
'SERVER_PORT',
|
||||
'HTTPS',
|
||||
'GD_PHP_HANDLER',
|
||||
'HTTP_AKAMAI_ORIGIN_HOP',
|
||||
'HTTP_CF_CONNECTING_IP',
|
||||
'HTTP_CLIENT_IP',
|
||||
'HTTP_FASTLY_CLIENT_IP',
|
||||
'HTTP_FORWARDED',
|
||||
'HTTP_FORWARDED_FOR',
|
||||
'HTTP_INCAP_CLIENT_IP',
|
||||
'HTTP_TRUE_CLIENT_IP',
|
||||
'HTTP_X_CLIENTIP',
|
||||
'HTTP_X_CLUSTER_CLIENT_IP',
|
||||
'HTTP_X_FORWARDED',
|
||||
'HTTP_X_FORWARDED_FOR',
|
||||
'HTTP_X_IP_TRAIL',
|
||||
'HTTP_X_REAL_IP',
|
||||
'HTTP_X_VARNISH',
|
||||
'REMOTE_ADDR',
|
||||
) as $header ) {
|
||||
if ( isset( $_SERVER[ $header ] ) ) {
|
||||
$debug_info[ $header ] = array(
|
||||
'label' => 'Server Variable ' . $header,
|
||||
'value' => ( $_SERVER[ $header ] ) ? $_SERVER[ $header ] : 'false',
|
||||
'private' => false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$debug_info['protect_header'] = array(
|
||||
'label' => 'Trusted IP',
|
||||
'value' => wp_json_encode( get_site_option( 'trusted_ip_header' ) ),
|
||||
'private' => false,
|
||||
);
|
||||
|
||||
/** Sync Debug Information */
|
||||
$sync_module = Modules::get_module( 'full-sync' );
|
||||
if ( $sync_module ) {
|
||||
$sync_statuses = $sync_module->get_status();
|
||||
$human_readable_sync_status = array();
|
||||
foreach ( $sync_statuses as $sync_status => $sync_status_value ) {
|
||||
$human_readable_sync_status[ $sync_status ] =
|
||||
in_array( $sync_status, array( 'started', 'queue_finished', 'send_started', 'finished' ), true )
|
||||
? date( 'r', $sync_status_value ) : $sync_status_value;
|
||||
}
|
||||
$debug_info['full_sync'] = array(
|
||||
'label' => 'Full Sync Status',
|
||||
'value' => wp_json_encode( $human_readable_sync_status ),
|
||||
'private' => false,
|
||||
);
|
||||
}
|
||||
|
||||
$queue = Sender::get_instance()->get_sync_queue();
|
||||
|
||||
$debug_info['sync_size'] = array(
|
||||
'label' => 'Sync Queue Size',
|
||||
'value' => $queue->size(),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['sync_lag'] = array(
|
||||
'label' => 'Sync Queue Lag',
|
||||
'value' => self::seconds_to_time( $queue->lag() ),
|
||||
'private' => false,
|
||||
);
|
||||
|
||||
$full_sync_queue = Sender::get_instance()->get_full_sync_queue();
|
||||
|
||||
$debug_info['full_sync_size'] = array(
|
||||
'label' => 'Full Sync Queue Size',
|
||||
'value' => $full_sync_queue->size(),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['full_sync_lag'] = array(
|
||||
'label' => 'Full Sync Queue Lag',
|
||||
'value' => self::seconds_to_time( $full_sync_queue->lag() ),
|
||||
'private' => false,
|
||||
);
|
||||
|
||||
/**
|
||||
* IDC Information
|
||||
*
|
||||
* Must follow sync debug since it depends on sync functionality.
|
||||
*/
|
||||
$idc_urls = array(
|
||||
'home' => Functions::home_url(),
|
||||
'siteurl' => Functions::site_url(),
|
||||
'WP_HOME' => Constants::is_defined( 'WP_HOME' ) ? Constants::get_constant( 'WP_HOME' ) : '',
|
||||
'WP_SITEURL' => Constants::is_defined( 'WP_SITEURL' ) ? Constants::get_constant( 'WP_SITEURL' ) : '',
|
||||
);
|
||||
|
||||
$debug_info['idc_urls'] = array(
|
||||
'label' => 'IDC URLs',
|
||||
'value' => wp_json_encode( $idc_urls ),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['idc_error_option'] = array(
|
||||
'label' => 'IDC Error Option',
|
||||
'value' => wp_json_encode( Jetpack_Options::get_option( 'sync_error_idc' ) ),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['idc_optin'] = array(
|
||||
'label' => 'IDC Opt-in',
|
||||
'value' => Jetpack::sync_idc_optin(),
|
||||
'private' => false,
|
||||
);
|
||||
|
||||
// @todo -- Add testing results?
|
||||
$cxn_tests = new Jetpack_Cxn_Tests();
|
||||
$debug_info['cxn_tests'] = array(
|
||||
'label' => 'Connection Tests',
|
||||
'value' => '',
|
||||
'private' => false,
|
||||
);
|
||||
if ( $cxn_tests->pass() ) {
|
||||
$debug_info['cxn_tests']['value'] = 'All Pass.';
|
||||
} else {
|
||||
$debug_info['cxn_tests']['value'] = wp_json_encode( $cxn_tests->list_fails() );
|
||||
}
|
||||
|
||||
return $debug_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable string for which user is the master user.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function human_readable_master_user() {
|
||||
$master_user = Jetpack_Options::get_option( 'master_user' );
|
||||
|
||||
if ( ! $master_user ) {
|
||||
return __( 'No master user set.', 'jetpack' );
|
||||
}
|
||||
|
||||
$user = new WP_User( $master_user );
|
||||
|
||||
if ( ! $user ) {
|
||||
return __( 'Master user no longer exists. Please disconnect and reconnect Jetpack.', 'jetpack' );
|
||||
}
|
||||
|
||||
return self::human_readable_user( $user );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return human readable string for a given user object.
|
||||
*
|
||||
* @param WP_User|int $user Object or ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function human_readable_user( $user ) {
|
||||
$user = new WP_User( $user );
|
||||
|
||||
return sprintf( '#%1$d %2$s (%3$s)', $user->ID, $user->user_login, $user->user_email ); // Format: "#1 username (user@example.com)".
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
<?php
|
||||
/**
|
||||
* Jetpack Debugger functionality allowing for self-service diagnostic information via the legacy jetpack debugger.
|
||||
*
|
||||
* @package jetpack
|
||||
*/
|
||||
|
||||
/** Ensure the Jetpack_Debug_Data class is available. It should be via the library loaded, but defense is good. */
|
||||
require_once 'class-jetpack-debug-data.php';
|
||||
|
||||
/**
|
||||
* Class Jetpack_Debugger
|
||||
*
|
||||
* A namespacing class for functionality related to the legacy in-plugin diagnostic tooling.
|
||||
*/
|
||||
class Jetpack_Debugger {
|
||||
|
||||
/**
|
||||
* Determine the active plan and normalize it for the debugger results.
|
||||
*
|
||||
* @return string The plan slug prepended with "JetpackPlan"
|
||||
*/
|
||||
private static function what_jetpack_plan() {
|
||||
// Specifically not deprecating this function since it modifies the output of the Jetpack_Debug_Data::what_jetpack_plan return.
|
||||
return 'JetpackPlan' . Jetpack_Debug_Data::what_jetpack_plan();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert seconds to human readable time.
|
||||
*
|
||||
* A dedication function instead of using Core functionality to allow for output in seconds.
|
||||
*
|
||||
* @deprecated 7.3.0
|
||||
*
|
||||
* @param int $seconds Number of seconds to convert to human time.
|
||||
*
|
||||
* @return string Human readable time.
|
||||
*/
|
||||
public static function seconds_to_time( $seconds ) {
|
||||
_deprecated_function( 'Jetpack_Debugger::seconds_to_time', 'Jetpack 7.3.0', 'Jeptack_Debug_Data::seconds_to_time' );
|
||||
return Jetpack_Debug_Data::seconds_to_time( $seconds );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 30 for use with a filter.
|
||||
*
|
||||
* To allow time for WP.com to run upstream testing, this function exists to increase the http_request_timeout value
|
||||
* to 30.
|
||||
*
|
||||
* @return int 30
|
||||
*/
|
||||
public static function jetpack_increase_timeout() {
|
||||
return 30; // seconds.
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect Jetpack and redirect user to connection flow.
|
||||
*/
|
||||
public static function disconnect_and_redirect() {
|
||||
if ( ! ( isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], 'jp_disconnect' ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset( $_GET['disconnect'] ) && $_GET['disconnect'] ) {
|
||||
if ( Jetpack::is_active() ) {
|
||||
Jetpack::disconnect();
|
||||
wp_safe_redirect( Jetpack::admin_url() );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles output to the browser for the in-plugin debugger.
|
||||
*/
|
||||
public static function jetpack_debug_display_handler() {
|
||||
global $wp_version;
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'jetpack' ) );
|
||||
}
|
||||
|
||||
$support_url = Jetpack::is_development_version()
|
||||
? 'https://jetpack.com/contact-support/beta-group/'
|
||||
: 'https://jetpack.com/contact-support/';
|
||||
|
||||
$data = Jetpack_Debug_Data::debug_data();
|
||||
$debug_info = '';
|
||||
foreach ( $data as $datum ) {
|
||||
$debug_info .= $datum['label'] . ': ' . $datum['value'] . "\r\n";
|
||||
}
|
||||
|
||||
$debug_info .= "\r\n" . esc_html( 'PHP_VERSION: ' . PHP_VERSION );
|
||||
$debug_info .= "\r\n" . esc_html( 'WORDPRESS_VERSION: ' . $GLOBALS['wp_version'] );
|
||||
$debug_info .= "\r\n" . esc_html( 'SITE_URL: ' . site_url() );
|
||||
$debug_info .= "\r\n" . esc_html( 'HOME_URL: ' . home_url() );
|
||||
|
||||
$debug_info .= "\r\n\r\nTEST RESULTS:\r\n\r\n";
|
||||
|
||||
$cxntests = new Jetpack_Cxn_Tests();
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h2><?php esc_html_e( 'Debugging Center', 'jetpack' ); ?></h2>
|
||||
<h3><?php esc_html_e( "Testing your site's compatibility with Jetpack...", 'jetpack' ); ?></h3>
|
||||
<div class="jetpack-debug-test-container">
|
||||
<?php
|
||||
if ( $cxntests->pass() ) {
|
||||
echo '<div class="jetpack-tests-succeed">' . esc_html__( 'Your Jetpack setup looks a-okay!', 'jetpack' ) . '</div>';
|
||||
$debug_info .= "All tests passed.\r\n";
|
||||
$debug_info .= print_r( $cxntests->raw_results(), true ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
|
||||
} else {
|
||||
$failures = $cxntests->list_fails();
|
||||
foreach ( $failures as $fail ) {
|
||||
echo '<div class="jetpack-test-error">';
|
||||
echo '<p><a class="jetpack-test-heading" href="#">' . esc_html( $fail['message'] );
|
||||
echo '<span class="noticon noticon-collapse"></span></a></p>';
|
||||
echo '<p class="jetpack-test-details">' . esc_html( $fail['resolution'] ) . '</p>';
|
||||
echo '</div>';
|
||||
|
||||
$debug_info .= "FAILED TESTS!\r\n";
|
||||
$debug_info .= $fail['name'] . ': ' . $fail['message'] . "\r\n";
|
||||
$debug_info .= print_r( $cxntests->raw_results(), true ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="entry-content">
|
||||
<h3><?php esc_html_e( 'Trouble with Jetpack?', 'jetpack' ); ?></h3>
|
||||
<h4><?php esc_html_e( 'It may be caused by one of these issues, which you can diagnose yourself:', 'jetpack' ); ?></h4>
|
||||
<ol>
|
||||
<li><b><em>
|
||||
<?php
|
||||
esc_html_e( 'A known issue.', 'jetpack' );
|
||||
?>
|
||||
</em></b>
|
||||
<?php
|
||||
echo sprintf(
|
||||
wp_kses(
|
||||
/* translators: URLs to Jetpack support pages. */
|
||||
__( 'Some themes and plugins have <a href="%1$s" target="_blank">known conflicts</a> with Jetpack – check the <a href="%2$s" target="_blank">list</a>. (You can also browse the <a href="%3$s" target="_blank">Jetpack support pages</a> or <a href="%4$s" target="_blank">Jetpack support forum</a> to see if others have experienced and solved the problem.)', 'jetpack' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
)
|
||||
),
|
||||
'http://jetpack.com/support/getting-started-with-jetpack/known-issues/',
|
||||
'http://jetpack.com/support/getting-started-with-jetpack/known-issues/',
|
||||
'http://jetpack.com/support/',
|
||||
'https://wordpress.org/support/plugin/jetpack'
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
<li><b><em><?php esc_html_e( 'An incompatible plugin.', 'jetpack' ); ?></em></b> <?php esc_html_e( "Find out by disabling all plugins except Jetpack. If the problem persists, it's not a plugin issue. If the problem is solved, turn your plugins on one by one until the problem pops up again – there's the culprit! Let us know, and we'll try to help.", 'jetpack' ); ?></li>
|
||||
<li>
|
||||
<b><em><?php esc_html_e( 'A theme conflict.', 'jetpack' ); ?></em></b>
|
||||
<?php
|
||||
$default_theme = wp_get_theme( WP_DEFAULT_THEME );
|
||||
|
||||
if ( $default_theme->exists() ) {
|
||||
/* translators: %s is the name of a theme */
|
||||
echo esc_html( sprintf( __( "If your problem isn't known or caused by a plugin, try activating %s (the default WordPress theme).", 'jetpack' ), $default_theme->get( 'Name' ) ) );
|
||||
} else {
|
||||
esc_html_e( "If your problem isn't known or caused by a plugin, try activating the default WordPress theme.", 'jetpack' );
|
||||
}
|
||||
?>
|
||||
<?php esc_html_e( "If this solves the problem, something in your theme is probably broken – let the theme's author know.", 'jetpack' ); ?>
|
||||
</li>
|
||||
<li><b><em><?php esc_html_e( 'A problem with your XMLRPC file.', 'jetpack' ); ?></em></b>
|
||||
<?php
|
||||
echo sprintf(
|
||||
wp_kses(
|
||||
/* translators: The URL to the site's xmlrpc.php file. */
|
||||
__( 'Load your <a href="%s">XMLRPC file</a>. It should say “XML-RPC server accepts POST requests only.” on a line by itself.', 'jetpack' ),
|
||||
array( 'a' => array( 'href' => array() ) )
|
||||
),
|
||||
esc_attr( site_url( 'xmlrpc.php' ) )
|
||||
);
|
||||
?>
|
||||
<ul>
|
||||
<li>- <?php esc_html_e( "If it's not by itself, a theme or plugin is displaying extra characters. Try steps 2 and 3.", 'jetpack' ); ?></li>
|
||||
<li>- <?php esc_html_e( 'If you get a 404 message, contact your web host. Their security may block XMLRPC.', 'jetpack' ); ?></li>
|
||||
</ul>
|
||||
</li>
|
||||
<?php if ( current_user_can( 'jetpack_disconnect' ) && Jetpack::is_active() ) : ?>
|
||||
<li>
|
||||
<strong><em><?php esc_html_e( 'A connection problem with WordPress.com.', 'jetpack' ); ?></em></strong>
|
||||
<?php
|
||||
echo sprintf(
|
||||
wp_kses(
|
||||
/* translators: URL to disconnect and reconnect Jetpack. */
|
||||
__( 'Jetpack works by connecting to WordPress.com for a lot of features. Sometimes, when the connection gets messed up, you need to disconnect and reconnect to get things working properly. <a href="%s">Disconnect from WordPress.com</a>', 'jetpack' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'class' => array(),
|
||||
),
|
||||
)
|
||||
),
|
||||
esc_attr(
|
||||
wp_nonce_url(
|
||||
Jetpack::admin_url(
|
||||
array(
|
||||
'page' => 'jetpack-debugger',
|
||||
'disconnect' => true,
|
||||
)
|
||||
),
|
||||
'jp_disconnect',
|
||||
'nonce'
|
||||
)
|
||||
)
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ol>
|
||||
<h4><?php esc_html_e( 'Still having trouble?', 'jetpack' ); ?></h4>
|
||||
<p><b><em><?php esc_html_e( 'Ask us for help!', 'jetpack' ); ?></em></b>
|
||||
<?php
|
||||
/**
|
||||
* Offload to new WordPress debug data in WP 5.2+
|
||||
*
|
||||
* @todo remove fallback when 5.2 is the minimum supported.
|
||||
*/
|
||||
if ( version_compare( $wp_version, '5.2-alpha', '>=' ) ) {
|
||||
echo sprintf(
|
||||
wp_kses(
|
||||
/* translators: URL for Jetpack support. URL for WordPress's Site Health */
|
||||
__( '<a href="%1$s">Contact our Happiness team</a>. When you do, please include the <a href="%2$s">full debug information from your site</a>.', 'jetpack' ),
|
||||
array( 'a' => array( 'href' => array() ) )
|
||||
),
|
||||
esc_url( $support_url ),
|
||||
esc_url( admin_url() . 'site-health.php?tab=debug' )
|
||||
);
|
||||
$hide_debug = true;
|
||||
} else { // Versions before 5.2, fallback.
|
||||
echo sprintf(
|
||||
wp_kses(
|
||||
/* translators: URL for Jetpack support. */
|
||||
__( '<a href="%s">Contact our Happiness team</a>. When you do, please include the full debug information below.', 'jetpack' ),
|
||||
array( 'a' => array( 'href' => array() ) )
|
||||
),
|
||||
esc_url( $support_url )
|
||||
);
|
||||
$hide_debug = false;
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
<hr />
|
||||
<?php if ( Jetpack::is_active() ) : ?>
|
||||
<div id="connected-user-details">
|
||||
<h3><?php esc_html_e( 'More details about your Jetpack settings', 'jetpack' ); ?></h3>
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
wp_kses(
|
||||
/* translators: %s is an e-mail address */
|
||||
__( 'The primary connection is owned by <strong>%s</strong>\'s WordPress.com account.', 'jetpack' ),
|
||||
array( 'strong' => array() )
|
||||
),
|
||||
esc_html( Jetpack::get_master_user_email() )
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div id="dev-mode-details">
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
wp_kses(
|
||||
/* translators: Link to a Jetpack support page. */
|
||||
__( 'Would you like to use Jetpack on your local development site? You can do so thanks to <a href="%s">Jetpack\'s development mode</a>.', 'jetpack' ),
|
||||
array( 'a' => array( 'href' => array() ) )
|
||||
),
|
||||
'https://jetpack.com/support/development-mode/'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
if (
|
||||
current_user_can( 'jetpack_manage_modules' )
|
||||
&& ( Jetpack::is_development_mode() || Jetpack::is_active() )
|
||||
) {
|
||||
printf(
|
||||
wp_kses(
|
||||
'<p><a href="%1$s">%2$s</a></p>',
|
||||
array(
|
||||
'a' => array( 'href' => array() ),
|
||||
'p' => array(),
|
||||
)
|
||||
),
|
||||
esc_attr( Jetpack::admin_url( 'page=jetpack_modules' ) ),
|
||||
esc_html__( 'Access the full list of Jetpack modules available on your site.', 'jetpack' )
|
||||
);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<hr />
|
||||
<?php
|
||||
if ( ! $hide_debug ) {
|
||||
?>
|
||||
<div id="toggle_debug_info"><?php esc_html_e( 'Advanced Debug Results', 'jetpack' ); ?></div>
|
||||
<div id="debug_info_div">
|
||||
<h4><?php esc_html_e( 'Debug Info', 'jetpack' ); ?></h4>
|
||||
<div id="debug_info"><pre><?php echo esc_html( $debug_info ); ?></pre></div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs html needed within the <head> for the in-plugin debugger page.
|
||||
*/
|
||||
public static function jetpack_debug_admin_head() {
|
||||
|
||||
Jetpack_Admin_Page::load_wrapper_styles();
|
||||
?>
|
||||
<style type="text/css">
|
||||
|
||||
.jetpack-debug-test-container {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.jetpack-tests-succeed {
|
||||
font-size: large;
|
||||
color: #8BAB3E;
|
||||
}
|
||||
|
||||
.jetpack-test-details {
|
||||
margin: 4px 6px;
|
||||
padding: 10px;
|
||||
overflow: auto;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jetpack-test-error {
|
||||
margin-bottom: 10px;
|
||||
background: #FFEBE8;
|
||||
border: solid 1px #C00;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.jetpack-test-error p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
p.jetpack-test-details {
|
||||
margin: 4px 6px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.jetpack-test-error a.jetpack-test-heading {
|
||||
padding: 4px 6px;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.jetpack-test-error .noticon {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.formbox {
|
||||
margin: 0 0 25px 0;
|
||||
}
|
||||
|
||||
.formbox input[type="text"], .formbox input[type="email"], .formbox input[type="url"], .formbox textarea, #debug_info_div {
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 11px;
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,0.1);
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
width: 97%;
|
||||
}
|
||||
#debug_info_div {
|
||||
border-radius: 0;
|
||||
margin-top: 16px;
|
||||
background: #FFF;
|
||||
padding: 16px;
|
||||
}
|
||||
.formbox .contact-support input[type="submit"] {
|
||||
float: right;
|
||||
margin: 0 !important;
|
||||
border-radius: 20px !important;
|
||||
cursor: pointer;
|
||||
font-size: 13pt !important;
|
||||
height: auto !important;
|
||||
margin: 0 0 2em 10px !important;
|
||||
padding: 8px 16px !important;
|
||||
background-color: #ddd;
|
||||
border: 1px solid rgba(0,0,0,0.05);
|
||||
border-top-color: rgba(255,255,255,0.1);
|
||||
border-bottom-color: rgba(0,0,0,0.15);
|
||||
color: #333;
|
||||
font-weight: 400;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.formbox span.errormsg {
|
||||
margin: 0 0 10px 10px;
|
||||
color: #d00;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.formbox.error span.errormsg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#debug_info_div, #toggle_debug_info, #debug_info_div p {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#category_div ul li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
jQuery( document ).ready( function($) {
|
||||
|
||||
$( '#debug_info' ).prepend( 'jQuery version: ' + jQuery.fn.jquery + "\r\n" );
|
||||
$( '#debug_form_info' ).prepend( 'jQuery version: ' + jQuery.fn.jquery + "\r\n" );
|
||||
|
||||
$( '.jetpack-test-error .jetpack-test-heading' ).on( 'click', function() {
|
||||
$( this ).parents( '.jetpack-test-error' ).find( '.jetpack-test-details' ).slideToggle();
|
||||
return false;
|
||||
} );
|
||||
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* WP Site Health functionality temporarily stored in this file until all of Jetpack is PHP 5.3+
|
||||
*
|
||||
* @package Jetpack.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test runner for Core's Site Health module.
|
||||
*
|
||||
* @since 7.3.0
|
||||
*/
|
||||
function jetpack_debugger_ajax_local_testing_suite() {
|
||||
check_ajax_referer( 'health-check-site-status' );
|
||||
if ( ! current_user_can( 'jetpack_manage_modules' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
$tests = new Jetpack_Cxn_Tests();
|
||||
wp_send_json_success( $tests->output_results_for_core_async_site_health() );
|
||||
}
|
||||
/**
|
||||
* Adds the Jetpack Local Testing Suite to the Core Site Health system.
|
||||
*
|
||||
* @since 7.3.0
|
||||
*
|
||||
* @param array $core_tests Array of tests from Core's Site Health.
|
||||
*
|
||||
* @return array $core_tests Array of tests for Core's Site Health.
|
||||
*/
|
||||
function jetpack_debugger_site_status_tests( $core_tests ) {
|
||||
$cxn_tests = new Jetpack_Cxn_Tests();
|
||||
$tests = $cxn_tests->list_tests( 'direct' );
|
||||
foreach ( $tests as $test ) {
|
||||
$core_tests['direct'][ $test['name'] ] = array(
|
||||
'label' => __( 'Jetpack: ', 'jetpack' ) . $test['name'],
|
||||
'test' => function() use ( $test, $cxn_tests ) { // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewClosure.Found
|
||||
$results = $cxn_tests->run_test( $test['name'] );
|
||||
// Test names are, by default, `test__some_string_of_text`. Let's convert to "Some String Of Text" for humans.
|
||||
$label = ucwords(
|
||||
str_replace(
|
||||
'_',
|
||||
' ',
|
||||
str_replace( 'test__', '', $test['name'] )
|
||||
)
|
||||
);
|
||||
$return = array(
|
||||
'label' => $label,
|
||||
'status' => 'good',
|
||||
'badge' => array(
|
||||
'label' => __( 'Jetpack', 'jetpack' ),
|
||||
'color' => 'green',
|
||||
),
|
||||
'description' => sprintf(
|
||||
'<p>%s</p>',
|
||||
__( 'This test successfully passed!', 'jetpack' )
|
||||
),
|
||||
'actions' => '',
|
||||
'test' => 'jetpack_' . $test['name'],
|
||||
);
|
||||
if ( is_wp_error( $results ) ) {
|
||||
return;
|
||||
}
|
||||
if ( false === $results['pass'] ) {
|
||||
$return['label'] = $results['message'];
|
||||
$return['status'] = $results['severity'];
|
||||
$return['description'] = sprintf(
|
||||
'<p>%s</p>',
|
||||
$results['resolution']
|
||||
);
|
||||
if ( ! empty( $results['action'] ) ) {
|
||||
$return['actions'] = sprintf(
|
||||
'<a class="button button-primary" href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
|
||||
esc_url( $results['action'] ),
|
||||
__( 'Resolve', 'jetpack' ),
|
||||
/* translators: accessibility text */
|
||||
__( '(opens in a new tab)', 'jetpack' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
},
|
||||
);
|
||||
}
|
||||
$core_tests['async']['jetpack_test_suite'] = array(
|
||||
'label' => __( 'Jetpack Tests', 'jetpack' ),
|
||||
'test' => 'jetpack_local_testing_suite',
|
||||
);
|
||||
|
||||
return $core_tests;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user