initial
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Legacy base class for Jetpack's debugging tests.
|
||||
*
|
||||
* @deprecated Use Connection_Health_Test_Base or Connection_Health_Tests from the connection package directly.
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Connection\Connection_Health_Test_Base;
|
||||
|
||||
/**
|
||||
* "Unit Tests" for the Jetpack connection.
|
||||
*
|
||||
* @since 7.1.0
|
||||
* @deprecated Use Connection_Health_Test_Base or Connection_Health_Tests from the connection package directly.
|
||||
*/
|
||||
class Jetpack_Cxn_Test_Base extends Connection_Health_Test_Base {
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Jetpack-specific connection tests.
|
||||
*
|
||||
* Extends the connection package's Connection_Health_Test_Base with Jetpack-specific
|
||||
* tests (sync health) and Jetpack-specific helper overrides.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Connection\Connection_Health_Test_Base;
|
||||
use Automattic\Jetpack\Redirect;
|
||||
use Automattic\Jetpack\Sync\Health as Sync_Health;
|
||||
use Automattic\Jetpack\Sync\Settings as Sync_Settings;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Jetpack_Cxn_Tests contains the Jetpack-specific connection tests.
|
||||
*
|
||||
* Extends the connection package's framework and provides Jetpack-specific
|
||||
* tests (sync health), encryption, and Jetpack-specific helper overrides.
|
||||
*
|
||||
* Jetpack-specific tests are also registered with the connection package's
|
||||
* Site Health integration via the jetpack_connection_tests_loaded action.
|
||||
*/
|
||||
class Jetpack_Cxn_Tests extends Connection_Health_Test_Base {
|
||||
|
||||
/**
|
||||
* Register Jetpack-specific tests on an external test suite instance.
|
||||
*
|
||||
* Used to add Jetpack tests to the connection package's Site Health integration
|
||||
* via the jetpack_connection_tests_loaded action.
|
||||
*
|
||||
* @param Connection_Health_Test_Base $target The test suite to register tests on.
|
||||
*/
|
||||
public function register_tests_on( $target ) {
|
||||
$methods = get_class_methods( static::class );
|
||||
foreach ( $methods as $method ) {
|
||||
if ( ! str_contains( $method, 'test__' ) ) {
|
||||
continue;
|
||||
}
|
||||
$target->add_test( array( $this, $method ), $method, 'direct' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync Health Tests.
|
||||
*
|
||||
* @return array Test results.
|
||||
*/
|
||||
protected function test__sync_health() {
|
||||
$name = 'test__sync_health';
|
||||
|
||||
if ( ! $this->helper_is_connected() ) {
|
||||
return self::skipped_test(
|
||||
array(
|
||||
'name' => $name,
|
||||
'show_in_site_health' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! Sync_Settings::is_sync_enabled() ) {
|
||||
return self::failing_test(
|
||||
array(
|
||||
'name' => $name,
|
||||
'label' => __( 'Jetpack Sync has been disabled on your site.', 'jetpack' ),
|
||||
'severity' => 'recommended',
|
||||
'action' => 'https://github.com/Automattic/jetpack/blob/trunk/projects/packages/sync/src/class-settings.php',
|
||||
'action_label' => __( 'See GitHub for more on Sync Settings', 'jetpack' ),
|
||||
'short_description' => __( 'Jetpack Sync has been disabled on your site. This could be impacting some of your site\'s Jetpack-powered features. Developers may enable / disable syncing using the Sync Settings API.', 'jetpack' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( Sync_Health::get_status() === Sync_Health::STATUS_OUT_OF_SYNC ) {
|
||||
return self::failing_test(
|
||||
array(
|
||||
'name' => $name,
|
||||
'label' => __( 'Jetpack has detected a problem with the communication between your site and WordPress.com', 'jetpack' ),
|
||||
'severity' => 'critical',
|
||||
'action' => Redirect::get_url( 'jetpack-contact-support' ),
|
||||
'action_label' => __( 'Contact Jetpack Support', 'jetpack' ),
|
||||
'short_description' => __( 'There is a problem with the communication between your site and WordPress.com. This could be impacting some of your site\'s Jetpack-powered features. If you continue to see this error, please contact support for assistance.', 'jetpack' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return self::passing_test( array( 'name' => $name ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,413 @@
|
||||
<?php
|
||||
/**
|
||||
* Jetpack Debug Data for the Site Health sections.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Connection\Tokens;
|
||||
use Automattic\Jetpack\Connection\Urls;
|
||||
use Automattic\Jetpack\Constants;
|
||||
use Automattic\Jetpack\Current_Plan as Jetpack_Plan;
|
||||
use Automattic\Jetpack\Identity_Crisis;
|
||||
use Automattic\Jetpack\Redirect;
|
||||
use Automattic\Jetpack\Status;
|
||||
use Automattic\Jetpack\Sync\Modules;
|
||||
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 = (int) $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 = (int) ( $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()
|
||||
? Redirect::get_url( 'jetpack-contact-support-beta-group' )
|
||||
: Redirect::get_url( 'jetpack-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(), // Only ID number and user name.
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['is_offline_mode'] = array(
|
||||
'label' => 'Jetpack Offline Mode',
|
||||
'value' => ( new Status() )->is_offline_mode() ? 'on' : 'off',
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['is_offline_mode_constant'] = array(
|
||||
'label' => 'JETPACK_DEV_DEBUG Constant',
|
||||
'value' => ( defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG ) ? 'on' : 'off',
|
||||
'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 = ( new Tokens() )->get_access_token();
|
||||
$user_token = ( new Tokens() )->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_key ?? 'Not set.',
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['user_token'] = array(
|
||||
'label' => 'User Public Key',
|
||||
'value' => $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' => empty( $_SERVER[ $header ] ) ? 'false' : filter_var( wp_unslash( $_SERVER[ $header ] ) ),
|
||||
'private' => true, // This isn't really 'private' information, but we don't want folks to easily paste these into public forums.
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$debug_info['protect_header'] = array(
|
||||
'label' => 'Trusted IP',
|
||||
'value' => wp_json_encode( get_site_option( 'trusted_ip_header' ), JSON_UNESCAPED_SLASHES ),
|
||||
'private' => false,
|
||||
);
|
||||
|
||||
/** Sync Debug Information */
|
||||
$sync_module = Modules::get_module( 'full-sync' );
|
||||
'@phan-var \Automattic\Jetpack\Sync\Modules\Full_Sync_Immediately|\Automattic\Jetpack\Sync\Modules\Full_Sync $sync_module';
|
||||
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 )
|
||||
? gmdate( 'r', $sync_status_value ) : $sync_status_value;
|
||||
}
|
||||
$debug_info['full_sync'] = array(
|
||||
'label' => 'Full Sync Status',
|
||||
'value' => wp_json_encode( $human_readable_sync_status, JSON_UNESCAPED_SLASHES ),
|
||||
'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' => Urls::home_url(),
|
||||
'siteurl' => Urls::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, JSON_UNESCAPED_SLASHES ),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['idc_error_option'] = array(
|
||||
'label' => 'IDC Error Option',
|
||||
'value' => wp_json_encode( Jetpack_Options::get_option( 'sync_error_idc' ), JSON_UNESCAPED_SLASHES ),
|
||||
'private' => false,
|
||||
);
|
||||
$debug_info['idc_optin'] = array(
|
||||
'label' => 'IDC Opt-in',
|
||||
'value' => Identity_Crisis::should_handle_idc(),
|
||||
'private' => false,
|
||||
);
|
||||
|
||||
// @todo -- Add testing results?
|
||||
$cxn_tests = new Automattic\Jetpack\Connection\Connection_Health_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(), JSON_UNESCAPED_SLASHES );
|
||||
}
|
||||
|
||||
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->exists() ) {
|
||||
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', $user->ID, $user->user_login ); // Format: "#1 username".
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
<?php
|
||||
/**
|
||||
* Jetpack Debugger functionality allowing for self-service diagnostic information via the legacy jetpack debugger.
|
||||
*
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Redirect;
|
||||
use Automattic\Jetpack\Status;
|
||||
|
||||
/**
|
||||
* Class Jetpack_Debugger
|
||||
*
|
||||
* A namespacing class for functionality related to the legacy in-plugin diagnostic tooling.
|
||||
*/
|
||||
class Jetpack_Debugger {
|
||||
/**
|
||||
* Disconnect Jetpack and redirect user to connection flow.
|
||||
*
|
||||
* Used in class.jetpack-admin.php.
|
||||
*/
|
||||
public static function disconnect_and_redirect() {
|
||||
if ( ! ( isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], 'jp_disconnect' ) ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $_GET['disconnect'] ) ) {
|
||||
if ( Jetpack::is_connection_ready() ) {
|
||||
Jetpack::disconnect();
|
||||
wp_safe_redirect( Jetpack::admin_url() );
|
||||
exit( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles output to the browser for the in-plugin debugger.
|
||||
*/
|
||||
public static function jetpack_debug_display_handler() {
|
||||
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()
|
||||
? Redirect::get_url( 'jetpack-contact-support-beta-group' )
|
||||
: Redirect::get_url( 'jetpack-contact-support' );
|
||||
|
||||
$cxntests = new Automattic\Jetpack\Connection\Connection_Health_Tests();
|
||||
?>
|
||||
<div class="wrap">
|
||||
<div class="jp-static-block">
|
||||
<h2><?php esc_html_e( 'Debugging Center', 'jetpack' ); ?></h2>
|
||||
|
||||
<div class="jp-static-block-body">
|
||||
<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>';
|
||||
} else {
|
||||
$failures = $cxntests->list_fails();
|
||||
foreach ( $failures as $fail ) {
|
||||
?>
|
||||
<div class="notice notice-error inline">
|
||||
<div class="notice-icon-wrapper">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 24 24" width="24" height="24" class="y_IPyP1wIAOhyNaqvXJq" aria-hidden="true" focusable="false"><path d="M10 2c4.42 0 8 3.58 8 8s-3.58 8-8 8-8-3.58-8-8 3.58-8 8-8zm1.13 9.38l.35-6.46H8.52l.35 6.46h2.26zm-.09 3.36c.24-.23.37-.55.37-.96 0-.42-.12-.74-.36-.97s-.59-.35-1.06-.35-.82.12-1.07.35-.37.55-.37.97c0 .41.13.73.38.96.26.23.61.34 1.06.34s.8-.11 1.05-.34z"></path></svg>
|
||||
</div>
|
||||
|
||||
<div class="notice-main-content">
|
||||
<div class="notice-title"><?php echo esc_html( $fail['short_description'] ); ?></div>
|
||||
|
||||
<div class="notice-action-bar">
|
||||
<div>
|
||||
<a href="<?php echo esc_attr( $fail['action'] ); ?>" aria-disabled="false" class="components-button is-primary"><span><?php echo esc_html( $fail['action_label'] ); ?></span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="entry-content">
|
||||
<h4><?php esc_html_e( 'Trouble with Jetpack?', 'jetpack' ); ?></h4>
|
||||
<p><?php esc_html_e( 'It may be caused by one of these issues, which you can diagnose yourself:', 'jetpack' ); ?></p>
|
||||
<ol>
|
||||
<li><?php esc_html_e( 'A known issue.', 'jetpack' ); ?>
|
||||
<?php
|
||||
printf(
|
||||
wp_kses(
|
||||
/* translators: URLs to Jetpack support pages. */
|
||||
__( 'Some themes and plugins have <a href="%1$s" target="_blank" rel="noopener noreferrer">known conflicts</a> with Jetpack – check the list. (You can also browse the <a href="%2$s" target="_blank" rel="noopener noreferrer">Jetpack support pages</a> or <a href="%3$s" target="_blank" rel="noopener noreferrer">Jetpack support forum</a> to see if others have experienced and solved the problem.)', 'jetpack' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'target' => array(),
|
||||
'rel' => array(),
|
||||
),
|
||||
)
|
||||
),
|
||||
esc_url( Redirect::get_url( 'jetpack-contact-support-known-issues' ) ),
|
||||
esc_url( Redirect::get_url( 'jetpack-support' ) ),
|
||||
esc_url( Redirect::get_url( 'wporg-support-plugin-jetpack' ) )
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php esc_html_e( 'An incompatible plugin.', 'jetpack' ); ?>
|
||||
<?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>
|
||||
<?php esc_html_e( 'A theme conflict.', 'jetpack' ); ?>
|
||||
<?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>
|
||||
<?php esc_html_e( 'A problem with your XML-RPC file.', 'jetpack' ); ?>
|
||||
<?php
|
||||
printf(
|
||||
wp_kses(
|
||||
/* translators: The URL to the site's xmlrpc.php file. */
|
||||
__( 'Load your <a href="%s">XML-RPC 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 the XML-RPC file.', 'jetpack' ); ?></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<?php if ( current_user_can( 'jetpack_disconnect' ) && Jetpack::is_connection_ready() ) : ?>
|
||||
<li>
|
||||
<?php esc_html_e( 'A connection problem with WordPress.com.', 'jetpack' ); ?>
|
||||
<?php
|
||||
printf(
|
||||
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>
|
||||
<?php esc_html_e( 'Ask us for help!', 'jetpack' ); ?>
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Offload to new WordPress debug data.
|
||||
*/
|
||||
printf(
|
||||
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' )
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="jp-static-block">
|
||||
<h2><?php esc_html_e( 'More details about your Jetpack settings', 'jetpack' ); ?></h2>
|
||||
|
||||
<div class="jp-static-block-body">
|
||||
<?php if ( Jetpack::is_connection_ready() ) : ?>
|
||||
<div id="connected-user-details">
|
||||
<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 offline mode</a>.', 'jetpack' ),
|
||||
array( 'a' => array( 'href' => array() ) )
|
||||
),
|
||||
esc_url( Redirect::get_url( 'jetpack-support-development-mode' ) )
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
if (
|
||||
current_user_can( 'jetpack_manage_modules' )
|
||||
&& ( ( new Status() )->is_offline_mode() || Jetpack::is_connection_ready() )
|
||||
) {
|
||||
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>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs html needed within the <head> for the in-plugin debugger page.
|
||||
*/
|
||||
public static function jetpack_debug_admin_head() {
|
||||
|
||||
$min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
|
||||
wp_enqueue_style( 'jetpack-admin', plugins_url( "css/jetpack-admin{$min}.css", JETPACK__PLUGIN_FILE ), array( 'genericons', 'jetpack-connection' ), JETPACK__VERSION . '-20121016' );
|
||||
wp_style_add_data( 'jetpack-admin', 'rtl', 'replace' );
|
||||
wp_style_add_data( 'jetpack-admin', 'suffix', $min );
|
||||
|
||||
Jetpack_Admin_Page::load_wrapper_styles();
|
||||
?>
|
||||
<style type="text/css">
|
||||
|
||||
.jetpack-debug-test-container {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
#connected-user-details p strong {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.jetpack-tests-succeed {
|
||||
font-size: large;
|
||||
color: #069E08;
|
||||
}
|
||||
|
||||
.jetpack-test-details {
|
||||
margin: 4px 6px;
|
||||
padding: 10px;
|
||||
overflow: auto;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.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 var(--wpds-color-stroke-surface-neutral-weak, #e4e4e4);
|
||||
border-radius: var(--wpds-border-radius-md, 4px);
|
||||
color: #646970;
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
width: 97%;
|
||||
}
|
||||
#debug_info_div {
|
||||
border-radius: var(--wpds-border-radius-lg, 8px);
|
||||
margin-top: 16px;
|
||||
background: var(--wpds-color-bg-surface-neutral-strong, #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: #dcdcde;
|
||||
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,125 @@
|
||||
<?php
|
||||
/**
|
||||
* WP Site Health debugging functions.
|
||||
*
|
||||
* @deprecated 15.9 Site Health integration is now handled by the connection package.
|
||||
* @package automattic/jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test runner for Core's Site Health module.
|
||||
*
|
||||
* @since 7.3.0
|
||||
* @deprecated 15.9 Use Automattic\Jetpack\Connection\Site_Health instead.
|
||||
*/
|
||||
function jetpack_debugger_ajax_local_testing_suite() {
|
||||
_deprecated_function( __FUNCTION__, 'jetpack-15.9' );
|
||||
check_ajax_referer( 'health-check-site-status' );
|
||||
if ( ! current_user_can( 'jetpack_manage_modules' ) ) {
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- It takes null, but its phpdoc only says int.
|
||||
wp_send_json_error( null, null, JSON_UNESCAPED_SLASHES );
|
||||
}
|
||||
$tests = new Automattic\Jetpack\Connection\Connection_Health_Tests();
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- It takes null, but its phpdoc only says int.
|
||||
wp_send_json_success( $tests->output_results_for_core_async_site_health(), null, JSON_UNESCAPED_SLASHES );
|
||||
}
|
||||
/**
|
||||
* Adds the Jetpack Local Testing Suite to the Core Site Health system.
|
||||
*
|
||||
* @since 7.3.0
|
||||
* @deprecated 15.9 Use Automattic\Jetpack\Connection\Site_Health instead.
|
||||
*
|
||||
* @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 ) {
|
||||
_deprecated_function( __FUNCTION__, 'jetpack-15.9' );
|
||||
$cxn_tests = new Automattic\Jetpack\Connection\Connection_Health_Tests();
|
||||
$tests = $cxn_tests->list_tests( 'direct' );
|
||||
foreach ( $tests as $test ) {
|
||||
|
||||
$core_tests['direct'][ $test['name'] ] = array(
|
||||
'label' => __( 'Jetpack: ', 'jetpack' ) . $test['name'],
|
||||
/**
|
||||
* Callable for Core's Site Health system to execute.
|
||||
*
|
||||
* @var array $test A Jetpack Testing Suite test array.
|
||||
* @var Automattic\Jetpack\Connection\Connection_Health_Tests $cxn_tests An instance of the connection test suite.
|
||||
*
|
||||
* @return array {
|
||||
* A results array to match the format expected by WordPress Core.
|
||||
*
|
||||
* @type string $label Name for the test.
|
||||
* @type string $status 'critical', 'recommended', or 'good'.
|
||||
* @type array $badge Array for Site Health status. Keys label and color.
|
||||
* @type string $description Description of the test result.
|
||||
* @type string $action HTML to a link to resolve issue.
|
||||
* @type string $test Unique test identifier.
|
||||
* }
|
||||
*/
|
||||
'test' => function () use ( $test, $cxn_tests ) {
|
||||
$results = $cxn_tests->run_test( $test['name'] );
|
||||
if ( is_wp_error( $results ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$label = $results['label'] ?
|
||||
$results['label'] :
|
||||
ucwords(
|
||||
str_replace(
|
||||
'_',
|
||||
' ',
|
||||
str_replace( 'test__', '', $test['name'] )
|
||||
)
|
||||
);
|
||||
if ( $results['long_description'] ) {
|
||||
$description = $results['long_description'];
|
||||
} elseif ( $results['short_description'] ) {
|
||||
$description = sprintf(
|
||||
'<p>%s</p>',
|
||||
$results['short_description']
|
||||
);
|
||||
} else {
|
||||
$description = sprintf(
|
||||
'<p>%s</p>',
|
||||
__( 'This test successfully passed!', 'jetpack' )
|
||||
);
|
||||
}
|
||||
|
||||
$return = array(
|
||||
'label' => $label,
|
||||
'status' => 'good',
|
||||
'badge' => array(
|
||||
'label' => __( 'Jetpack', 'jetpack' ),
|
||||
'color' => 'green',
|
||||
),
|
||||
'description' => $description,
|
||||
'actions' => '',
|
||||
'test' => 'jetpack_' . $test['name'],
|
||||
);
|
||||
|
||||
if ( false === $results['pass'] ) {
|
||||
$return['status'] = $results['severity'];
|
||||
if ( ! empty( $results['action'] ) ) {
|
||||
$return['actions'] = sprintf(
|
||||
'<a 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'] ),
|
||||
$results['action_label'],
|
||||
/* 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