base_url = rtrim(defined('XCRM_API_URL') ? XCRM_API_URL : 'https://xcrmforosh.com', '/') . '/api2/v1'; $this->load_credentials(); } private function load_credentials() { $this->api_key = get_option('xcrm_api_key', ''); $this->token = get_option('xcrm_token', ''); } public function set_credentials($api_key, $token = '') { $this->api_key = $api_key; $this->token = $token; update_option('xcrm_api_key', $api_key); update_option('xcrm_token', $token); } public function get($endpoint, $params = [], $use_api_key = false) { return $this->request('GET', $endpoint, $params, $use_api_key); } public function post($endpoint, $data = [], $use_api_key = false) { return $this->request('POST', $endpoint, $data, $use_api_key); } public function post_with_jwt($endpoint, $jwt, $data = [], $extra_headers = []) { return $this->request_with_jwt('POST', $endpoint, $jwt, $data, $extra_headers); } public function put($endpoint, $data = [], $use_api_key = false) { return $this->request('PUT', $endpoint, $data, $use_api_key); } public function delete($endpoint, $use_api_key = false) { return $this->request('DELETE', $endpoint, [], $use_api_key); } public function request($method, $endpoint, $data = [], $use_api_key = false) { $url = $this->base_url . '/' . ltrim($endpoint, '/'); if ($method === 'GET' && !empty($data)) { $url .= '?' . http_build_query($data); } $args = [ 'method' => $method, 'timeout' => 30, 'headers' => $this->get_headers($use_api_key), ]; if (!empty($data) && in_array($method, ['POST', 'PUT'])) { $args['body'] = wp_json_encode($data); $args['headers']['Content-Type'] = 'application/json'; } $response = wp_remote_request($url, $args); if (is_wp_error($response)) { $this->handle_auth_error(); return [ 'success' => false, 'error' => $response->get_error_message(), ]; } $body = wp_remote_retrieve_body($response); $decoded = json_decode($body, true); $status_code = wp_remote_retrieve_response_code($response); if (!$decoded) { return [ 'success' => false, 'error' => 'Invalid JSON response', ]; } $is_success = ($status_code >= 200 && $status_code < 300); $message = ''; $error_data = null; if (!$is_success) { if (isset($decoded['message'])) { $message = $decoded['message']; } elseif (isset($decoded['detail'])) { $message = $decoded['detail']; } else { $errors = []; foreach ($decoded as $key => $value) { if (is_array($value)) { foreach ($value as $msg) { $errors[] = $msg; } } } if (!empty($errors)) { $message = implode(' | ', $errors); } } $error_data = $decoded; } return [ 'success' => $is_success, 'status' => $decoded['status'] ?? ($is_success ? 'success' : 'error'), 'message' => $message, 'data' => $decoded['data'] ?? [], 'error' => $error_data, 'http_code' => $status_code, ]; } private function handle_auth_error() { // intentionally empty - previously only performed debug logging } public function get_error_message($response) { if (isset($response['message']) && !empty($response['message'])) { return $response['message']; } if (isset($response['error']['details'])) { return $response['error']['details']; } if (isset($response['error']) && is_string($response['error'])) { return $response['error']; } if (isset($response['error']) && is_array($response['error'])) { $errors = []; foreach ($response['error'] as $key => $value) { if (is_array($value)) { foreach ($value as $msg) { $errors[] = $msg; } } elseif (is_string($value)) { $errors[] = $value; } } if (!empty($errors)) { return implode(' | ', $errors); } } return 'خطای ناشناخته'; } public function request_with_jwt($method, $endpoint, $jwt, $data = [], $extra_headers = []) { $url = $this->base_url . '/' . ltrim($endpoint, '/'); $headers = array_merge([ 'Authorization' => 'Bearer ' . $jwt, 'Content-Type' => 'application/json', ], $extra_headers); $args = [ 'method' => $method, 'timeout' => 30, 'headers' => $headers, ]; if (!empty($data)) { $args['body'] = wp_json_encode($data); } $response = wp_remote_request($url, $args); if (is_wp_error($response)) { return [ 'success' => false, 'error' => $response->get_error_message(), ]; } $body = wp_remote_retrieve_body($response); $decoded = json_decode($body, true); $status_code = wp_remote_retrieve_response_code($response); if (!$decoded) { return [ 'success' => false, 'error' => 'Invalid JSON response', ]; } $is_success = ($status_code >= 200 && $status_code < 300); $message = ''; $error_data = null; if (!$is_success) { if (isset($decoded['message'])) { $message = $decoded['message']; } elseif (isset($decoded['detail'])) { $message = $decoded['detail']; } else { $errors = []; foreach ($decoded as $key => $value) { if (is_array($value)) { foreach ($value as $msg) { $errors[] = $msg; } } } if (!empty($errors)) { $message = implode(' | ', $errors); } } $error_data = $decoded; } return [ 'success' => $is_success, 'status' => $decoded['status'] ?? ($is_success ? 'success' : 'error'), 'message' => $message, 'data' => $decoded['data'] ?? [], 'error' => $error_data, 'http_code' => $status_code, ]; } private function get_headers($use_api_key = false) { $headers = []; if ($use_api_key) { $api_key = get_option('xcrm_api_key', ''); if (!empty($api_key)) { $headers[defined('XCRM_API_KEY_HEADER') ? XCRM_API_KEY_HEADER : 'X-API-Key'] = $api_key; } } return $headers; } public function is_connected() { return !empty($this->api_key); } public function get_base_url() { return $this->base_url; } private function mask_sensitive($data) { if (!is_array($data)) { return $data; } $sensitive_keys = ['password', 'token', 'raw_key', 'access', 'refresh', 'api_key', 'secret']; $masked = []; foreach ($data as $key => $value) { if (in_array(strtolower($key), $sensitive_keys, true)) { $masked[$key] = '***MASKED***'; } elseif (is_array($value)) { $masked[$key] = $this->mask_sensitive($value); } else { $masked[$key] = $value; } } return $masked; } }