, error: string|null} */ public function exchangeToken($code, $verifier) { return $this->request('POST', '/site/token', array( 'code' => $code, 'code_verifier' => $verifier, ), false); } /** * @param array $inventory * @return array{ok: bool, status: int, body: array, error: string|null} */ public function pushInventory(array $inventory) { return $this->request('POST', '/site/inventory', $inventory, true); } /** * Revokes the token on Ladon's side, so a copy left in a backup or a database dump stops working too. * * @return array{ok: bool, status: int, body: array, error: string|null} */ public function revokeToken() { return $this->request('DELETE', '/site/token', null, true); } /** * @return array{ok: bool, status: int, body: array, error: string|null} */ public function status() { return $this->request('GET', '/site', null, true); } /** * @param array|null $body * @return array{ok: bool, status: int, body: array, error: string|null} */ private function request($method, $path, $body, $withToken) { $args = array( 'method' => $method, 'timeout' => 15, 'redirection' => 0, 'headers' => array( 'Accept' => 'application/json', 'User-Agent' => 'Ladon-WP/' . LADON_VERSION . '; ' . home_url('/'), ), ); if ($withToken) { $token = Settings::token(); if ($token === null) { return $this->fail(0, __('This site is not connected to Ladon.', 'hackindex-ladon')); } $args['headers']['Authorization'] = 'Bearer ' . $token; } if ($body !== null) { $args['headers']['Content-Type'] = 'application/json'; $args['body'] = wp_json_encode($body); } $response = wp_remote_request(self::apiUrl() . $path, $args); if (is_wp_error($response)) { return $this->fail(0, $response->get_error_message()); } $status = (int) wp_remote_retrieve_response_code($response); $decoded = json_decode(wp_remote_retrieve_body($response), true); $decoded = is_array($decoded) ? $decoded : array(); if ($status >= 200 && $status < 300) { return array('ok' => true, 'status' => $status, 'body' => $decoded, 'error' => null); } $detail = isset($decoded['detail']) && is_string($decoded['detail']) ? $decoded['detail'] : sprintf(/* translators: %d: HTTP status code */ __('Ladon returned an error (HTTP %d).', 'hackindex-ladon'), $status); return array('ok' => false, 'status' => $status, 'body' => $decoded, 'error' => $detail); } private function fail($status, $message) { return array('ok' => false, 'status' => (int) $status, 'body' => array(), 'error' => $message); } }