'No request data provided' ); } $endpoint = ( 'category' === $type ) ? Endpoints::get_cat_opt_req_url() : Endpoints::get_prod_opt_req_url(); $response = wp_remote_post( $endpoint, self::get_request_args( $request_data ) ); if ( is_wp_error( $response ) ) { return array( 'error' => $response->get_error_message() ); } $code = wp_remote_retrieve_response_code( $response ); $msg = wp_remote_retrieve_response_message( $response ); $body = wp_remote_retrieve_body( $response ); if ( $code < 200 || $code >= 300 ) { Logger::write_log( 'error', "API request failed: HTTP {$code} {$msg}", array( 'endpoint' => $endpoint, 'status' => $code, 'body' => substr( (string) $body, 0, 2048 ), ) ); return array( 'error' => "HTTP $code $msg", 'body' => $body, 'endpoint' => $endpoint, 'status_code' => $code, ); } $decoded = json_decode( $body, true ); if ( json_last_error() === JSON_ERROR_NONE && is_array( $decoded ) ) { return $decoded; } $body = str_replace( '"', '', $body ); return array( 'batch_id' => $body ); } /** * Get the batch request status for a given batch request ID. * * @param string $id The batch request ID. * @return string The raw response from the API. */ public static function get_batch_request_status( $id ) { if ( null === $id || '' === $id ) { return 'Invalid batch request ID'; } $api_url = Endpoints::get_batch_opt_status_url( '' ) . rawurlencode( $id ) . '/status'; $response = wp_remote_get( $api_url, self::get_request_args() ); if ( is_wp_error( $response ) ) { return 'API request failed: ' . $response->get_error_message(); } $body = wp_remote_retrieve_body( $response ); return $body; } /** * Get a human-readable label for the batch request status. * * @param string $id The batch request ID. * @return string The status label. */ public static function get_batch_request_status_label( $id ) { if ( null === $id || '' === $id ) { return __( 'Null ID', 'ai-content-by-parallax' ); } $status = self::get_batch_request_status_decoded( $id )['status'] ?? null; if ( isset( $status ) ) { // API v1 returns numeric status codes. Treat any numeric value (including numeric strings) as a v1 code. if ( is_numeric( $status ) ) { $enum_case = BatchRequestStatus::from_api_code( (int) $status ); return $enum_case ? BatchRequestStatus::to_human_readable( $enum_case ) : __( 'Status Error', 'ai-content-by-parallax' ); } // API v2 returns string status labels, so if it's already a non-numeric string, map it directly. if ( is_string( $status ) ) { $enum_case = BatchRequestStatus::from_api_status( $status ); return $enum_case ? BatchRequestStatus::to_human_readable( $enum_case ) : __( 'Status Error', 'ai-content-by-parallax' ); } return __( 'Status Unrecognized', 'ai-content-by-parallax' ); } return __( 'API response error', 'ai-content-by-parallax' ); } /** * Get both the human-readable label and raw status for a given batch request ID. * * @param string $id The batch request ID. * @return array { * An associative array containing the human-readable label and raw status. * * @type string $label The human-readable status label. * @type string $status The raw status value. * } */ public static function get_batch_request_status_info( $id ): array { return array( 'label' => self::get_batch_request_status_label( $id ), 'status' => self::get_batch_request_status( $id ), ); } /** * Get and decode the batch request status for a given batch request ID. * * @param string $id The batch request ID. * @return array The decoded batch request status or an error message. */ public static function get_batch_request_status_decoded( $id ) { if ( null === $id || '' === $id ) { return array( 'error' => 'Invalid batch request ID' ); } $status_response = self::get_batch_request_status( $id ); $decoded = json_decode( $status_response, true ); if ( json_last_error() === JSON_ERROR_NONE && is_array( $decoded ) ) { return $decoded; } return array( 'error' => 'Failed to decode API response', 'body' => $status_response, ); } /** * Get the count of failed items for a given batch request ID. * * @param string $id The batch request ID. * @return int The count of failed items. */ public static function get_failed_count( $id ) { if ( null === $id || '' === $id ) { return 0; } $decoded = self::get_batch_request_status_decoded( $id ); $failed_products = isset( $decoded['failedProductItems'] ) ? (int) $decoded['failedProductItems'] : 0; $failed_categories = isset( $decoded['failedCategoryItems'] ) ? (int) $decoded['failedCategoryItems'] : 0; return $failed_products + $failed_categories; } /** * Get the count of processed items for a given batch request ID. * * @param string $id Batch request ID. * @return int */ public static function get_processed_count( $id ) { if ( null === $id || '' === $id ) { return 0; } $decoded = self::get_batch_request_status_decoded( $id ); $processed_products = isset( $decoded['processedProductItems'] ) ? (int) $decoded['processedProductItems'] : 0; $processed_categories = isset( $decoded['processedCategoryItems'] ) ? (int) $decoded['processedCategoryItems'] : 0; return $processed_products + $processed_categories; } /** * Get the total item count for a batch request ID. * * @param string $id Batch request ID. * @return int */ public static function get_total_count( $id ) { if ( null === $id || '' === $id ) { return 0; } return self::get_batch_request_status_decoded( $id )['totalItems'] ?? 0; } /** * Get the count of remaining items to be processed for a given batch request ID. * * @param string $id The batch request ID. * @return int The count of remaining items. */ public static function get_remaining_count( $id ) { if ( null === $id || '' === $id ) { return 0; } return self::get_total_count( $id ) - ( self::get_failed_count( $id ) + self::get_processed_count( $id ) ); } /** * Get a paged list of items for a given batch request ID and type. * * @param string $id The batch request ID. * @param string $type The type of items ('product' or 'category'). * @param int $page The page number to retrieve. * @return string The raw response from the API. */ public static function get_batch_request_paged( $id, $type, $page = 1 ) { if ( null === $id || '' === $id ) { return 'Invalid batch request ID'; } $type_plural = ( 'category' === $type ) ? 'categories' : $type . 's'; $api_url = Endpoints::get_batch_opt_status_url( '' ) . rawurlencode( $id ) . '/paged-' . $type_plural . '?Page=' . intval( $page ); $response = wp_remote_get( $api_url, self::get_request_args() ); if ( is_wp_error( $response ) ) { return 'API request failed: ' . $response->get_error_message(); } $body = wp_remote_retrieve_body( $response ); return $body; } /** * Helper to construct request arguments for wp_remote_get/post. * * @param mixed $body The request body, if any. * @param string|null $key Optional API key to use instead of the logged-in user's key. * @return array The request arguments. */ private static function get_request_args( $body = null, $key = null ): array { $key = $key ?? Client::load()->get_api_key(); return array( 'headers' => array( 'accept' => 'text/plain', 'Content-Type' => 'application/json', 'X-API-Key' => $key, 'Expect' => '', 'Accept-Encoding' => 'identity', ), 'body' => ( $body ? wp_json_encode( $body, JSON_UNESCAPED_UNICODE ) : null ), 'timeout' => 30, 'httpversion' => '1.1', 'data_format' => 'body', ); } /** * Fetch client information from the Parallax API. * * @return array The client information or an error message. */ public static function get_client_info() { $client_id = Client::load()->get_client_id(); if ( ! $client_id ) { return array( 'error' => 'Client ID not found' ); } $api_url = Endpoints::get_admin_client_url() . '/' . rawurlencode( $client_id ); // If define is added (likely in wp-config.php or plugin) use that key instead of the logged in user's key to query the client admin endpoint. if ( defined( 'EPARALLAX_ADMIN_API_KEY' ) ) { $response = wp_remote_get( $api_url, self::get_request_args( null, EPARALLAX_ADMIN_API_KEY ) ); } else { $response = wp_remote_get( $api_url, self::get_request_args() ); } if ( is_wp_error( $response ) ) { return array( 'error' => 'API request failed: ' . $response->get_error_message() ); } $body = wp_remote_retrieve_body( $response ); $decoded = json_decode( $body, true ); if ( json_last_error() === JSON_ERROR_NONE && is_array( $decoded ) ) { return $decoded; } return array( 'error' => 'Failed to decode API response', 'body' => $body, ); } }