*/ final class RestSelfTest { /** * Option holding the last self-test verdict (bool). * * @since 4.3.0 * @var string */ const OPTION_ENABLED = 'rest-api-enabled'; /** * Option holding the Unix timestamp of the last self-test. * * @since 4.3.0 * @var string */ const OPTION_LAST_TEST = 'rest-api-last-test'; /** * Option holding whether the last report reached the API (bool). * * A reachable REST API is only half of push: until the API has been told, * it pushes nothing, so the polling fallback must stay in charge. Kept * separate from OPTION_ENABLED, which records the local probe verdict only. * * @since 4.3.0 * @var string */ const OPTION_REPORTED = 'rest-api-reported'; /** * Timeout, in seconds, for the loopback probe. * * @since 4.3.0 * @var int */ const PROBE_TIMEOUT = 10; /** * Run the self-test: probe the loopback ping, persist the verdict locally, * and report the REST state + push URL to the API. * * @since 4.3.0 * @return bool Whether the plugin's REST API is reachable. */ public function run() { $base_path = PushController::REST_NAMESPACE . '/' . PushController::REST_BASE; $rest_url = rest_url( $base_path ); $ping_url = rest_url( $base_path . '/ping' ); $reachable = $this->probe( $ping_url ); Options::update( self::OPTION_ENABLED, $reachable ); Options::update( self::OPTION_LAST_TEST, time() ); $reporter = new PushCapabilityReporter(); $reported = $reporter->report( $reachable, $rest_url ); // The API only pushes once it has been told; a report that never landed // (no token or website uuid yet, gateway or ACL error) must leave the // polling fallback on, whatever the probe said. Options::update( self::OPTION_REPORTED, $reported ); return $reachable; } /** * Whether a loopback GET to the ping URL returns HTTP 200. * * @since 4.3.0 * @param string $ping_url Absolute URL of the public ping route. * @return bool */ private function probe( $ping_url ) { $response = wp_remote_get( $ping_url, array( 'timeout' => self::PROBE_TIMEOUT, 'sslverify' => false, ) ); if ( is_wp_error( $response ) ) { return false; } return (int) wp_remote_retrieve_response_code( $response ) === 200; } }