settings = $settings; } private function request(string $method, string $path, array $body = array(), string $token = '') { if ($this->settings->get('service_consent') !== '1') { return new WP_Error('aiva_consent', __('Please authorize the connection to AI Integrations first.', 'ai-integrations-chatbot')); } $headers = array('Accept' => 'application/json', 'Content-Type' => 'application/json'); if ($token !== '') { $headers['Authorization'] = 'Bearer ' . $token; } $response = wp_safe_remote_request($this->settings->service_url('api') . '/api/wp-lite' . $path, array( 'method' => $method, 'timeout' => 20, 'redirection' => 0, 'headers' => $headers, 'body' => $body ? wp_json_encode($body) : null, )); if (is_wp_error($response)) { return $response; } $status = wp_remote_retrieve_response_code($response); $data = json_decode(wp_remote_retrieve_body($response), true); if ($status < 200 || $status >= 300 || !is_array($data)) { $message = is_array($data) && is_string($data['error'] ?? null) ? $data['error'] : __('AI Integrations could not complete this request. Please try again.', 'ai-integrations-chatbot'); return new WP_Error('aiva_api_error', $message, array('status' => $status)); } return $data; } public function connect(string $install_key) { return $this->request('POST', '/connect', array('install_key' => $install_key, 'site_url' => home_url(), 'plugin_version' => AIVA_LITE_VERSION)); } public function start_pairing(string $mode) { return $this->request('POST', '/pairing/start', array('site_url' => home_url(), 'admin_origin' => $this->admin_origin(), 'site_name' => get_bloginfo('name'), 'mode' => $mode, 'plugin_version' => AIVA_LITE_VERSION)); } public function poll_pairing() { return $this->request('POST', '/pairing/poll', array('request_id' => $this->settings->get('pairing_id'), 'site_url' => home_url()), $this->settings->get('pairing_secret')); } public function status(bool $force = false) { if ($force) { delete_transient('aiva_lite_summary_cache'); } return $this->cached('status', $force); } private function admin_origin(): string { $url = wp_parse_url(admin_url()); return $url['scheme'] . '://' . $url['host'] . (!empty($url['port']) ? ':' . $url['port'] : ''); } public function summary(bool $force = false) { return $this->cached('summary', $force); } private function cached(string $path, bool $force) { if (!$this->settings->get('site_token')) { return new WP_Error('aiva_reconnect', __('Connect your AI Integrations account to synchronize this site.', 'ai-integrations-chatbot')); } $key = 'aiva_lite_' . $path . '_cache'; if (!$force) { $cached = get_transient($key); if ($cached !== false) { return $cached; } } $data = $this->request('GET', '/' . $path, array(), $this->settings->get('site_token')); if (!is_wp_error($data)) { set_transient($key, $data, 5 * MINUTE_IN_SECONDS); } return $data; } public function disconnect() { $result = $this->request('POST', '/disconnect', array('site_url' => home_url()), $this->settings->get('site_token')); // An expired/revoked credential is already unable to authorize this site. if (is_wp_error($result) && ($result->get_error_data()['status'] ?? 0) === 401) { return array('disconnected' => true); } return $result; } }