ru-se.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

class-wp-rest-site-health-controller.php (9166B)


      1 <?php
      2 /**
      3  * REST API: WP_REST_Site_Health_Controller class
      4  *
      5  * @package WordPress
      6  * @subpackage REST_API
      7  * @since 5.6.0
      8  */
      9 
     10 /**
     11  * Core class for interacting with Site Health tests.
     12  *
     13  * @since 5.6.0
     14  *
     15  * @see WP_REST_Controller
     16  */
     17 class WP_REST_Site_Health_Controller extends WP_REST_Controller {
     18 
     19 	/**
     20 	 * An instance of the site health class.
     21 	 *
     22 	 * @since 5.6.0
     23 	 *
     24 	 * @var WP_Site_Health
     25 	 */
     26 	private $site_health;
     27 
     28 	/**
     29 	 * Site Health controller constructor.
     30 	 *
     31 	 * @since 5.6.0
     32 	 *
     33 	 * @param WP_Site_Health $site_health An instance of the site health class.
     34 	 */
     35 	public function __construct( $site_health ) {
     36 		$this->namespace = 'wp-site-health/v1';
     37 		$this->rest_base = 'tests';
     38 
     39 		$this->site_health = $site_health;
     40 	}
     41 
     42 	/**
     43 	 * Registers API routes.
     44 	 *
     45 	 * @since 5.6.0
     46 	 *
     47 	 * @see register_rest_route()
     48 	 */
     49 	public function register_routes() {
     50 		register_rest_route(
     51 			$this->namespace,
     52 			sprintf(
     53 				'/%s/%s',
     54 				$this->rest_base,
     55 				'background-updates'
     56 			),
     57 			array(
     58 				array(
     59 					'methods'             => 'GET',
     60 					'callback'            => array( $this, 'test_background_updates' ),
     61 					'permission_callback' => function () {
     62 						return $this->validate_request_permission( 'background_updates' );
     63 					},
     64 				),
     65 				'schema' => array( $this, 'get_public_item_schema' ),
     66 			)
     67 		);
     68 
     69 		register_rest_route(
     70 			$this->namespace,
     71 			sprintf(
     72 				'/%s/%s',
     73 				$this->rest_base,
     74 				'loopback-requests'
     75 			),
     76 			array(
     77 				array(
     78 					'methods'             => 'GET',
     79 					'callback'            => array( $this, 'test_loopback_requests' ),
     80 					'permission_callback' => function () {
     81 						return $this->validate_request_permission( 'loopback_requests' );
     82 					},
     83 				),
     84 				'schema' => array( $this, 'get_public_item_schema' ),
     85 			)
     86 		);
     87 
     88 		register_rest_route(
     89 			$this->namespace,
     90 			sprintf(
     91 				'/%s/%s',
     92 				$this->rest_base,
     93 				'https-status'
     94 			),
     95 			array(
     96 				array(
     97 					'methods'             => 'GET',
     98 					'callback'            => array( $this, 'test_https_status' ),
     99 					'permission_callback' => function () {
    100 						return $this->validate_request_permission( 'https_status' );
    101 					},
    102 				),
    103 				'schema' => array( $this, 'get_public_item_schema' ),
    104 			)
    105 		);
    106 
    107 		register_rest_route(
    108 			$this->namespace,
    109 			sprintf(
    110 				'/%s/%s',
    111 				$this->rest_base,
    112 				'dotorg-communication'
    113 			),
    114 			array(
    115 				array(
    116 					'methods'             => 'GET',
    117 					'callback'            => array( $this, 'test_dotorg_communication' ),
    118 					'permission_callback' => function () {
    119 						return $this->validate_request_permission( 'dotorg_communication' );
    120 					},
    121 				),
    122 				'schema' => array( $this, 'get_public_item_schema' ),
    123 			)
    124 		);
    125 
    126 		register_rest_route(
    127 			$this->namespace,
    128 			sprintf(
    129 				'/%s/%s',
    130 				$this->rest_base,
    131 				'authorization-header'
    132 			),
    133 			array(
    134 				array(
    135 					'methods'             => 'GET',
    136 					'callback'            => array( $this, 'test_authorization_header' ),
    137 					'permission_callback' => function () {
    138 						return $this->validate_request_permission( 'authorization_header' );
    139 					},
    140 				),
    141 				'schema' => array( $this, 'get_public_item_schema' ),
    142 			)
    143 		);
    144 
    145 		register_rest_route(
    146 			$this->namespace,
    147 			sprintf(
    148 				'/%s',
    149 				'directory-sizes'
    150 			),
    151 			array(
    152 				'methods'             => 'GET',
    153 				'callback'            => array( $this, 'get_directory_sizes' ),
    154 				'permission_callback' => function() {
    155 					return $this->validate_request_permission( 'debug_enabled' ) && ! is_multisite();
    156 				},
    157 			)
    158 		);
    159 	}
    160 
    161 	/**
    162 	 * Validates if the current user can request this REST endpoint.
    163 	 *
    164 	 * @since 5.6.0
    165 	 *
    166 	 * @param string $check The endpoint check being ran.
    167 	 * @return bool
    168 	 */
    169 	protected function validate_request_permission( $check ) {
    170 		$default_capability = 'view_site_health_checks';
    171 
    172 		/**
    173 		 * Filters the capability needed to run a given Site Health check.
    174 		 *
    175 		 * @since 5.6.0
    176 		 *
    177 		 * @param string $default_capability The default capability required for this check.
    178 		 * @param string $check              The Site Health check being performed.
    179 		 */
    180 		$capability = apply_filters( "site_health_test_rest_capability_{$check}", $default_capability, $check );
    181 
    182 		return current_user_can( $capability );
    183 	}
    184 
    185 	/**
    186 	 * Checks if background updates work as expected.
    187 	 *
    188 	 * @since 5.6.0
    189 	 *
    190 	 * @return array
    191 	 */
    192 	public function test_background_updates() {
    193 		$this->load_admin_textdomain();
    194 		return $this->site_health->get_test_background_updates();
    195 	}
    196 
    197 	/**
    198 	 * Checks that the site can reach the WordPress.org API.
    199 	 *
    200 	 * @since 5.6.0
    201 	 *
    202 	 * @return array
    203 	 */
    204 	public function test_dotorg_communication() {
    205 		$this->load_admin_textdomain();
    206 		return $this->site_health->get_test_dotorg_communication();
    207 	}
    208 
    209 	/**
    210 	 * Checks that loopbacks can be performed.
    211 	 *
    212 	 * @since 5.6.0
    213 	 *
    214 	 * @return array
    215 	 */
    216 	public function test_loopback_requests() {
    217 		$this->load_admin_textdomain();
    218 		return $this->site_health->get_test_loopback_requests();
    219 	}
    220 
    221 	/**
    222 	 * Checks that the site's frontend can be accessed over HTTPS.
    223 	 *
    224 	 * @since 5.7.0
    225 	 *
    226 	 * @return array
    227 	 */
    228 	public function test_https_status() {
    229 		$this->load_admin_textdomain();
    230 		return $this->site_health->get_test_https_status();
    231 	}
    232 
    233 	/**
    234 	 * Checks that the authorization header is valid.
    235 	 *
    236 	 * @since 5.6.0
    237 	 *
    238 	 * @return array
    239 	 */
    240 	public function test_authorization_header() {
    241 		$this->load_admin_textdomain();
    242 		return $this->site_health->get_test_authorization_header();
    243 	}
    244 
    245 	/**
    246 	 * Gets the current directory sizes for this install.
    247 	 *
    248 	 * @since 5.6.0
    249 	 *
    250 	 * @return array|WP_Error
    251 	 */
    252 	public function get_directory_sizes() {
    253 		if ( ! class_exists( 'WP_Debug_Data' ) ) {
    254 			require_once ABSPATH . 'wp-admin/includes/class-wp-debug-data.php';
    255 		}
    256 
    257 		$this->load_admin_textdomain();
    258 
    259 		$sizes_data = WP_Debug_Data::get_sizes();
    260 		$all_sizes  = array( 'raw' => 0 );
    261 
    262 		foreach ( $sizes_data as $name => $value ) {
    263 			$name = sanitize_text_field( $name );
    264 			$data = array();
    265 
    266 			if ( isset( $value['size'] ) ) {
    267 				if ( is_string( $value['size'] ) ) {
    268 					$data['size'] = sanitize_text_field( $value['size'] );
    269 				} else {
    270 					$data['size'] = (int) $value['size'];
    271 				}
    272 			}
    273 
    274 			if ( isset( $value['debug'] ) ) {
    275 				if ( is_string( $value['debug'] ) ) {
    276 					$data['debug'] = sanitize_text_field( $value['debug'] );
    277 				} else {
    278 					$data['debug'] = (int) $value['debug'];
    279 				}
    280 			}
    281 
    282 			if ( ! empty( $value['raw'] ) ) {
    283 				$data['raw'] = (int) $value['raw'];
    284 			}
    285 
    286 			$all_sizes[ $name ] = $data;
    287 		}
    288 
    289 		if ( isset( $all_sizes['total_size']['debug'] ) && 'not available' === $all_sizes['total_size']['debug'] ) {
    290 			return new WP_Error( 'not_available', __( 'Directory sizes could not be returned.' ), array( 'status' => 500 ) );
    291 		}
    292 
    293 		return $all_sizes;
    294 	}
    295 
    296 	/**
    297 	 * Loads the admin textdomain for Site Health tests.
    298 	 *
    299 	 * The {@see WP_Site_Health} class is defined in WP-Admin, while the REST API operates in a front-end context.
    300 	 * This means that the translations for Site Health won't be loaded by default in {@see load_default_textdomain()}.
    301 	 *
    302 	 * @since 5.6.0
    303 	 */
    304 	protected function load_admin_textdomain() {
    305 		// Accounts for inner REST API requests in the admin.
    306 		if ( ! is_admin() ) {
    307 			$locale = determine_locale();
    308 			load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo" );
    309 		}
    310 	}
    311 
    312 	/**
    313 	 * Gets the schema for each site health test.
    314 	 *
    315 	 * @since 5.6.0
    316 	 *
    317 	 * @return array The test schema.
    318 	 */
    319 	public function get_item_schema() {
    320 		if ( $this->schema ) {
    321 			return $this->schema;
    322 		}
    323 
    324 		$this->schema = array(
    325 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
    326 			'title'      => 'wp-site-health-test',
    327 			'type'       => 'object',
    328 			'properties' => array(
    329 				'test'        => array(
    330 					'type'        => 'string',
    331 					'description' => __( 'The name of the test being run.' ),
    332 					'readonly'    => true,
    333 				),
    334 				'label'       => array(
    335 					'type'        => 'string',
    336 					'description' => __( 'A label describing the test.' ),
    337 					'readonly'    => true,
    338 				),
    339 				'status'      => array(
    340 					'type'        => 'string',
    341 					'description' => __( 'The status of the test.' ),
    342 					'enum'        => array( 'good', 'recommended', 'critical' ),
    343 					'readonly'    => true,
    344 				),
    345 				'badge'       => array(
    346 					'type'        => 'object',
    347 					'description' => __( 'The category this test is grouped in.' ),
    348 					'properties'  => array(
    349 						'label' => array(
    350 							'type'     => 'string',
    351 							'readonly' => true,
    352 						),
    353 						'color' => array(
    354 							'type'     => 'string',
    355 							'enum'     => array( 'blue', 'orange', 'red', 'green', 'purple', 'gray' ),
    356 							'readonly' => true,
    357 						),
    358 					),
    359 					'readonly'    => true,
    360 				),
    361 				'description' => array(
    362 					'type'        => 'string',
    363 					'description' => __( 'A more descriptive explanation of what the test looks for, and why it is important for the user.' ),
    364 					'readonly'    => true,
    365 				),
    366 				'actions'     => array(
    367 					'type'        => 'string',
    368 					'description' => __( 'HTML containing an action to direct the user to where they can resolve the issue.' ),
    369 					'readonly'    => true,
    370 				),
    371 			),
    372 		);
    373 
    374 		return $this->schema;
    375 	}
    376 }