whoami7 - Manager
:
/
home
/
qbizpnmr
/
preflap.com
/
wp-content
/
plugins
/
templately
/
includes
/
API
/
Upload File:
files >> /home/qbizpnmr/preflap.com/wp-content/plugins/templately/includes/API/AIContent.php
<?php /** * Templately AI Content Importer * * @package Templately * @since 1.0.0 */ namespace Templately\API; use Error; use Exception; use Templately\Utils\Helper; use WP_REST_Request; use WP_Error; use Templately\Core\Importer\Utils\Utils; use Templately\Core\Importer\Utils\AIUtils; use Templately\Core\Importer\Parsers\WXR_Parser; class AIContent extends API { private $endpoint = 'ai-content'; private $dev_mode = false; /** * AIContent constructor. * * @param string $file File path. * @param array $settings Settings. */ public function __construct() { parent::__construct(); } public function _permission_check(WP_REST_Request $request) { $this->request = $request; $this->api_key = $this->utils('options')->get( 'api_key' ); $process_id = $this->get_param('process_id'); $_route = $request->get_route(); if ('/templately/v1/ai-content/ai-update' === $_route || '/templately/v1/ai-content/ai-update-preview' === $_route) { if (empty($process_id)) { return $this->error('invalid_id', __('Invalid ID.', 'templately'), 'calculate_credit', 400); } // Check AI process data using API key-based storage $ai_process_data = AIUtils::get_ai_process_data(); if (is_array($ai_process_data) && !empty($ai_process_data[$process_id])) { return true; } return (bool) AIUtils::get_matched_session_data($process_id); } // // Allow access to attachments endpoint // if ('/templately/v1/ai-content/attachments' === $_route) { // return true; // } return parent::permission_check($request); } public function register_routes() { // $this->get( $this->endpoint . '/calculate-credit', [ $this, 'calculate_credit' ] ); $this->post($this->endpoint . '/modify-content', [$this, 'modify_content']); $this->post($this->endpoint . '/ai-update', [$this, 'ai_update']); $this->post($this->endpoint . '/ai-update-preview', [$this, 'ai_update_preview']); $this->post($this->endpoint . '/generate-logo', [$this, 'generate_logo']); $this->post($this->endpoint . '/generate-meta', [$this, 'generate_meta']); $this->get($this->endpoint . '/attachments', [$this, 'get_attachments'], [ 'type' => [ 'default' => 'pack', 'required' => false, 'sanitize_callback' => 'sanitize_text_field', ], 'id' => [ 'required' => false, 'sanitize_callback' => 'sanitize_text_field', ], 'pack_id' => [ 'required' => false, 'sanitize_callback' => 'sanitize_text_field', ], ]); $this->get($this->endpoint . '/images', [$this, 'search_images'], [ 'query' => [ 'required' => false, 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => function($param, $request, $key) { return is_string($param) && strlen($param) <= 255; }, ], 'orientation' => [ 'required' => false, 'default' => 'all', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => function($param, $request, $key) { $allowed_orientations = ['all', 'landscape', 'portrait', 'square']; return in_array($param, $allowed_orientations, true); }, ], 'size' => [ 'required' => false, 'default' => 'medium', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => function($param, $request, $key) { $allowed_sizes = ['small', 'medium', 'large']; return in_array($param, $allowed_sizes, true); }, ], 'color' => [ 'required' => false, 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => function($param, $request, $key) { return is_string($param) && strlen($param) <= 50; }, ], 'page' => [ 'required' => false, 'default' => 1, 'sanitize_callback' => 'absint', 'validate_callback' => function($param, $request, $key) { return is_numeric($param) && $param > 0 && $param <= 1000; }, ], 'per_page' => [ 'required' => false, 'default' => 20, 'sanitize_callback' => 'absint', 'validate_callback' => function($param, $request, $key) { return is_numeric($param) && $param > 0 && $param <= 100; }, ], ]); // die(rest_url( 'templately/v1/ai-content/ai-update' )); } public function calculate_credit() { $pack_id = $this->get_param('pack_id'); return [ 'status' => 'success', 'data' => [ 'availableCredit' => 100, ], ]; if (empty($pack_id)) { return $this->error('invalid_id', __('Invalid ID.', 'templately'), 'calculate_credit', 400); } $extra_headers = [ 'Accept' => 'application/json', ]; $response = Helper::make_api_get_request("v2/ai/calculate-credit/pack/$pack_id", [], $extra_headers, 30); // return $response; if (is_wp_error($response)) { return $this->error('request_failed', __('Request failed.', 'templately'), 'calculate_credit', 500, $response); } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); // error status is ok if (! is_array($data) || ! isset($data['status'])) { return $this->error('invalid_response', __('Invalid response.', 'templately'), 'calculate_credit', 500); } return $data; } public function modify_content() { add_filter('wp_redirect', '__return_false', 999); set_time_limit(3 * MINUTE_IN_SECONDS); ini_set('max_execution_time', 3 * MINUTE_IN_SECONDS); $pack_id = $this->get_param('pack_id'); $isBusinessNichesNew = $this->get_param('isBusinessNichesNew', false); $ai_page_ids = $this->get_param('ai_page_ids', [], null); $content_ids = $this->get_param('content_ids', [], null); $session_id = $this->get_param('session_id'); // Add session_id parameter $preview_pages = $this->get_param('preview_pages', [], null); $image_replace = $this->get_param('imageReplace', [], null); $platform = $this->get_param('platform'); $language = $this->get_param('language', 'English'); // ai content fields $name = $this->get_param('name'); $category = $this->get_param('category'); $description = $this->get_param('description'); $email = $this->get_param('email'); $contactNumber = $this->get_param('contactNumber'); $businessAddress = $this->get_param('businessAddress'); $openingHour = $this->get_param('openingHour'); $requested_platform = $this->get_param('requested_platform', 'templately'); if (empty($pack_id)) { return $this->error('invalid_id', __('Invalid ID.', 'templately'), 'modify_content', 400); } if (empty($category)) { return $this->error('invalid_prompt', __('Invalid prompt.', 'templately'), 'modify_content', 400); } if (empty($content_ids) && empty($preview_pages)) { return $this->error('invalid_content_ids', __('Invalid content ids.', 'templately'), 'modify_content', 400); } if (empty($platform)) { return $this->error('invalid_platform', __('Invalid platform.', 'templately'), 'modify_content', 400); } // $response = get_transient( '__templately_ai_process_id' ); // if(empty($response)) { $extra_headers = [ 'Accept' => 'application/json', 'x-templately-session-id' => $session_id, 'x-templately-requested-platform' => $requested_platform, ]; $body_data = [ 'business_name' => $name, 'business_niches' => $category, 'prompt' => $description, 'email' => $email, 'phone' => $contactNumber, 'address' => $businessAddress, 'openingHour' => $openingHour, 'pack_id' => $pack_id, 'content_ids' => $content_ids, 'platform' => $platform, 'preview_pages' => $preview_pages, 'language' => $language, 'callback' => defined('TEMPLATELY_CALLBACK') ? TEMPLATELY_CALLBACK . '/wp-json/templately/v1/ai-content/ai-update' : rest_url('templately/v1/ai-content/ai-update'), ]; $response = Helper::make_api_post_request('v2/ai/modify-content/pack', $body_data, $extra_headers, 15 * MINUTE_IN_SECONDS); // set_transient( '__templately_ai_process_id', $response, 60 * 60 * 24 * 30 ); // } $bk_ai_business_niches = get_option('templately_ai_business_niches', []); if (!empty($business_niches) && $isBusinessNichesNew && ! in_array($business_niches, $bk_ai_business_niches)) { $bk_ai_business_niches[] = $business_niches; update_option('templately_ai_business_niches', $bk_ai_business_niches, false); } // return $response; if (is_wp_error($response)) { error_log(print_r($response, true)); return $this->error('request_failed', __('Request failed.', 'templately'), 'modify_content', 500, $response->get_error_data()); } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); // error status is ok, if status is error then return as is if (! is_array($data) || ! isset($data['status'])) { return $this->error('invalid_response', __('Invalid response.', 'templately'), 'modify_content', 500, $data); } // "{"status":"success","message":"The content is being generated in the queue","process_id":"01JRQQD39GNWTNF18EWF8YH0BG-271838-pack-408"}" if (isset($data['status']) && $data['status'] === 'success' && isset($data['process_id'])) { $process_id = $data['process_id']; // // Save templates to files if available using the common function // if (!empty($data['templates']) && is_array($data['templates'])) { // foreach ($data['templates'] as $content_id => $template_data) { // // Decode template if it's base64 encoded // if (! empty($template_data) && base64_decode($template_data, true) !== false) { // $data['templates'][$content_id] = base64_decode($template_data); // } // if (!empty($template_data)) { // AIUtils::save_template_to_file( // $process_id, // $content_id, // $template_data, // $ai_page_ids, // true, // Always use preview mode for AI content workflow // isset($template_data['isSkipped']) ? $template_data['isSkipped'] : false // ); // } // } // } $user = $this->utils('options')->get('user'); $ai_process_data[$process_id] = [ 'name' => $name, 'category' => $category, 'description' => $description, 'email' => $email, 'contactNumber' => $contactNumber, 'businessAddress' => $businessAddress, 'openingHour' => $openingHour, 'process_id' => $process_id, 'pack_id' => $pack_id, 'ai_page_ids' => $ai_page_ids, 'ai_preview_ids' => $preview_pages, 'content_ids' => $content_ids, 'platform' => $platform, 'api_key' => $this->api_key, 'user_id' => isset($user['id']) ? $user['id'] : null, 'session_id' => $session_id, // Store session_id for coordination 'imageReplace' => $image_replace, // Store session_id for coordination 'language' => $language, ]; // Update using API key-based storage with automatic count-based cleanup AIUtils::update_ai_process_data($ai_process_data); return [ 'status' => 'success', 'message' => __('The content is being generated in the queue', 'templately'), 'process_id' => $process_id, 'templates' => !empty($data['templates']) ? $data['templates'] : null, 'is_local_site' => !empty($data['is_local_site']) ? $data['is_local_site'] : null, ]; } return $data; } public function ai_update() { add_filter('wp_redirect', '__return_false', 999); $template = $this->get_param('template'); $process_id = $this->get_param('process_id'); $template_id = $this->get_param('template_id'); $content_id = $this->get_param('content_id'); $type = $this->get_param('type'); $isSkipped = $this->get_param('isSkipped', false); $credit_cost = $this->request->get_param('credit_cost'); error_log('process_id: ' . $process_id); // Handle credit cost updates separately if ($this->request->has_param('credit_cost')) { $processed_pages = get_option("templately_ai_processed_pages", []); $processed_pages[$process_id] = $processed_pages[$process_id] ?? []; $processed_pages[$process_id]['credit_cost'] = $credit_cost; update_option("templately_ai_processed_pages", $processed_pages, false); return [ 'status' => 'success', 'data' => [ 'process_id' => $process_id, 'credit_cost' => $credit_cost, ], ]; } // Always use preview mode for AI content workflow // Validate and get process data using centralized method $process_data = AIUtils::validate_and_get_process_data($process_id); if (is_wp_error($process_data)) { return $process_data; } $session_id = $process_data['session_id']; $ai_page_ids = $process_data['ai_page_ids']; // Use the common helper function to save the template $result = AIUtils::save_template_to_file( $process_id, $session_id, $content_id, $template, $ai_page_ids, $isSkipped ); if(is_wp_error($result)){ return $result; } // Return the result from the helper function if (isset($result['status']) && $result['status'] === 'success') { return $result; } // Return error if the helper function failed return $result; } public function ai_update_preview() { add_filter('wp_redirect', '__return_false', 999); $template = $this->get_param('templates'); // Now expects an array with content_id as keys $process_id = $this->get_param('process_id'); $isSkipped = $this->get_param('isSkipped', false); $error = $this->get_param('error', null); error_log('process_id: ' . $process_id); if (!empty($isSkipped) || !empty($error)) { // Update AI process data with error using API key-based storage $ai_process_data = AIUtils::get_ai_process_data(); if (isset($ai_process_data[$process_id])) { $ai_process_data[$process_id]['preview_error'] = $error; AIUtils::update_ai_process_data($ai_process_data); } wp_send_json_error([ 'status' => 'error', 'message' => $error, ]); } // Validate template parameter is an array if (!is_array($template) || empty($template)) { return $this->error('invalid_template', __('Template must be a non-empty array with content_id as keys.', 'templately'), 'ai-content/ai-update-preview', 400); } // Always use preview mode for AI content workflow // Validate and get process data using centralized method $process_data = AIUtils::validate_and_get_process_data($process_id); if (is_wp_error($process_data)) { return $process_data; } $session_id = $process_data['session_id']; $ai_page_ids = $process_data['ai_page_ids']; $results = []; $success_count = 0; $error_count = 0; // Process each content_id/template pair foreach ($template as $content_id => $template_data) { // Use the common helper function to save the template (always preview mode) $result = AIUtils::save_template_to_file( $process_id, $session_id, $content_id, $template_data, $ai_page_ids, $isSkipped ); $results[$content_id] = $result; // Track success/error counts if (isset($result['status']) && $result['status'] === 'success') { $success_count++; } else { $error_count++; } } // Return consolidated response $overall_status = $error_count === 0 ? 'success' : ($success_count === 0 ? 'error' : 'partial_success'); // Note: No cleanup needed with API key-based storage and count-based management return [ 'status' => $overall_status, 'message' => sprintf( __('Processed %d templates: %d successful, %d failed.', 'templately'), count($template), $success_count, $error_count ), ]; } /** * Get attachments from API endpoint * * @return array */ public function get_attachments() { // Get parameters from request $type = $this->get_param('type', 'pack'); $id = $this->get_param('pack_id'); // Require ID parameter - return error if not provided if (empty($id)) { return $this->error('missing_id', __('Pack ID or ID parameter is required.', 'templately'), 'get_attachments', 400); } try { // Construct API endpoint URL $api_endpoint = "get-xml-attachment/{$type}/{$id}"; // Make API call $extra_headers = [ 'Accept' => 'application/xml, text/xml', ]; $response = Helper::make_api_get_request("v2/$api_endpoint", [], $extra_headers, 30); // Check for HTTP errors if (is_wp_error($response)) { return $this->error('api_request_failed', __('Failed to fetch attachments from API.', 'templately'), 'get_attachments', 500, $response->get_error_message()); } $response_code = wp_remote_retrieve_response_code($response); $xml_content = wp_remote_retrieve_body($response); if ($response_code !== 200) { // check if $xml_content contains valid json // ex. '{"status":"error","message":"Attachment XML file not found in pack archive."}' $error_data = @json_decode($xml_content, true); if(is_array($error_data) && isset($error_data['status']) && $error_data['status'] === 'error' && !empty($error_data['message'])){ return $this->error('api_http_error', $error_data['message'], 'get_attachments', $response_code); } return $this->error('api_http_error', sprintf(__('API returned HTTP %d error.', 'templately'), $response_code), 'get_attachments', $response_code); } // Validate we have XML content if (empty($xml_content)) { return $this->error('no_xml_content', __('No XML content found in API response.', 'templately'), 'get_attachments', 404); } // Parse the XML content from API response $parsed_data = $this->parse_xml_content($xml_content); if (is_wp_error($parsed_data)) { return $this->error('xml_parse_error', __('Failed to parse XML content.', 'templately'), 'get_attachments', 500, $parsed_data->get_error_message()); } // Extract attachments from parsed data $attachments = $this->extract_attachments_from_parsed_data($parsed_data); return [ 'status' => 'success', 'data' => $attachments, 'message' => sprintf(__('Found %d attachments.', 'templately'), count($attachments)), ]; } catch (Exception $e) { return $this->error('exception', __('An unexpected error occurred while fetching attachments.', 'templately'), 'get_attachments', 500, $e->getMessage()); } } /** * Parse XML content string using WXR Parser * * @param string $xml_content XML content string * @return array|WP_Error Parsed data or error */ private function parse_xml_content($xml_content) { // Ensure WordPress filesystem functions are available if (!function_exists('wp_tempnam')) { require_once(ABSPATH . 'wp-admin/includes/file.php'); } // Create a temporary file to store XML content $temp_file = wp_tempnam('templately_attachments'); if (!$temp_file) { return new WP_Error('temp_file_failed', __('Failed to create temporary file.', 'templately')); } // Write XML content to temporary file $bytes_written = file_put_contents($temp_file, $xml_content); if ($bytes_written === false) { unlink($temp_file); return new WP_Error('write_failed', __('Failed to write XML content to temporary file.', 'templately')); } try { // Initialize WXR Parser $parser = new WXR_Parser(); // Parse the temporary XML file $parsed_data = $parser->parse($temp_file); // Clean up temporary file unlink($temp_file); return $parsed_data; } catch (Exception $e) { // Clean up temporary file on exception if (file_exists($temp_file)) { unlink($temp_file); } return new WP_Error('parse_exception', $e->getMessage()); } } /** * Extract attachments from parsed WXR data * * @param array $parsed_data Parsed WXR data * @return array Array of attachment data */ private function extract_attachments_from_parsed_data($parsed_data) { $attachments = []; if (isset($parsed_data['posts']) && is_array($parsed_data['posts'])) { foreach ($parsed_data['posts'] as $post) { // Check if this is an attachment if (isset($post['post_type']) && $post['post_type'] === 'attachment') { $attachment = [ 'id' => isset($post['post_id']) ? (int) $post['post_id'] : 0, 'url' => isset($post['attachment_url']) ? (string) $post['attachment_url'] : '', 'title' => isset($post['post_title']) ? (string) $post['post_title'] : '', 'type' => isset($post['attachment_type']) ? (string) $post['attachment_type'] : '', ]; // Extract metadata including dimensions and medium URL $metadata = $this->extract_medium_size_url($post, $attachment['url']); // Filter out small images (width or height <= 150px) to ignore small icons if ($metadata && isset($metadata['width']) && isset($metadata['height'])) { if ($metadata['width'] < 150 || $metadata['height'] < 150) { continue; // Skip small images/icons } // Add dimensions to attachment data $attachment['width'] = $metadata['width']; $attachment['height'] = $metadata['height']; // Add medium URL if available if (isset($metadata['medium_url'])) { $attachment['medium_url'] = $metadata['medium_url']; } } else { // Skip attachments without metadata or dimensions continue; } // Only add if we have the required data if ($attachment['id'] && $attachment['url'] && $attachment['title']) { $attachments[] = $attachment; } } } } return $attachments; } /** * Extract medium size URL from attachment metadata and get image dimensions * * @param array $post Post data from WXR parser * @param string $original_url Original attachment URL * @return array|null Array with medium_url and dimensions if found, null otherwise */ private function extract_medium_size_url($post, $original_url) { if (!isset($post['postmeta']) || !is_array($post['postmeta'])) { return null; } foreach ($post['postmeta'] as $meta) { if (!isset($meta['key']) || !isset($meta['value'])) { continue; } // Only check _wp_attachment_metadata if ($meta['key'] === '_wp_attachment_metadata') { $attachment_metadata = @unserialize($meta['value']); if (is_array($attachment_metadata)) { $result = []; // Get original image dimensions $width = isset($attachment_metadata['width']) ? (int) $attachment_metadata['width'] : 0; $height = isset($attachment_metadata['height']) ? (int) $attachment_metadata['height'] : 0; $result['width'] = $width; $result['height'] = $height; // Check if medium size exists if (isset($attachment_metadata['sizes']['medium']['file'])) { // Construct medium URL from original URL and medium filename $medium_filename = $attachment_metadata['sizes']['medium']['file']; $original_path = dirname(parse_url($original_url, PHP_URL_PATH)); $base_url = str_replace(parse_url($original_url, PHP_URL_PATH), '', $original_url); $result['medium_url'] = $base_url . $original_path . '/' . $medium_filename; } return $result; } } } return null; } /** * Search images endpoint * * @param WP_REST_Request $request * @return WP_REST_Response|WP_Error */ public function search_images(WP_REST_Request $request) { // Get and sanitize parameters $query = $this->get_param('query', ''); $orientation = $this->get_param('orientation', 'all'); $size = $this->get_param('size', 'medium'); $color = $this->get_param('color', ''); $page = $this->get_param('page', 1, 'absint'); $per_page = $this->get_param('per_page', 20, 'absint'); // Validate required query parameter if (empty($query)) { return $this->error( 'missing_query', __('Search query is required.', 'templately'), 'search_images', 400 ); } // Prepare API request parameters $api_params = [ 'query' => urlencode($query), 'page' => $page, 'per_page' => $per_page, ]; // Add optional parameters if provided if ($orientation !== 'all') { $api_params['orientation'] = $orientation; } if (!empty($size)) { $api_params['size'] = $size; } if (!empty($color)) { $api_params['color'] = $color; } // Make API request to external image service $extra_headers = [ 'Content-Type' => 'application/json', ]; $response = Helper::make_api_get_request('v2/images', $api_params, $extra_headers, 30); // Handle API response errors if (is_wp_error($response)) { return $this->error( 'api_request_failed', __('Failed to fetch images from external service.', 'templately'), 'search_images', 500 ); } $response_code = wp_remote_retrieve_response_code($response); $response_body = wp_remote_retrieve_body($response); if ($response_code !== 200) { return $this->error( 'api_response_error', sprintf(__('External API returned error code: %d', 'templately'), $response_code), 'search_images', $response_code ); } // Parse and validate response $data = json_decode($response_body, true); if (json_last_error() !== JSON_ERROR_NONE) { return $this->error( 'invalid_response', __('Invalid response from external service.', 'templately'), 'search_images', 500 ); } // Check if the response has the expected structure and success status if (!isset($data['status']) || $data['status'] !== 'success') { return $this->error( 'api_response_error', __('External API returned an error status.', 'templately'), 'search_images', 500 ); } // Extract nested data from the response $response_data = $data['data'] ?? []; $images = $response_data['images'] ?? []; $total_results = $response_data['total_results'] ?? 0; $current_page = $response_data['page'] ?? $page; $per_page_count = $response_data['per_page'] ?? $per_page; // Return successful response with properly mapped data return $this->success([ 'images' => $images, 'total' => $total_results, 'page' => $current_page, 'per_page' => $per_page_count, 'total_pages' => $total_results > 0 ? ceil($total_results / $per_page_count) : 0, ]); } /** * Generate logo using AI * * @return array|WP_Error */ public function generate_logo() { // Get parameters $business_name = $this->get_param('business_name', ''); $description = $this->get_param('description'); $logo_type = $this->get_param('logo_type'); $requested_platform = $this->get_param('requested_platform', 'templately'); // Validate required parameters if (empty($description)) { return $this->error( 'missing_description', __('Description is required for logo generation.', 'templately'), 'generate_logo', 400 ); } if (empty($logo_type)) { return $this->error( 'missing_logo_type', __('Logo type is required.', 'templately'), 'generate_logo', 400 ); } // Prepare request body $body_data = [ 'business_name' => $business_name, 'description' => $description, 'logo_type' => $logo_type, ]; // Make API request $extra_headers = [ 'Content-Type' => 'application/json', 'x-templately-requested-platform' => $requested_platform, ]; $response = Helper::make_api_post_request('v2/generate-logo', $body_data, $extra_headers, 60); // Handle API response errors if (is_wp_error($response)) { return $this->error( 'api_request_failed', __('Something went wrong. Please try again or contact support.', 'templately'), 'generate_logo', 500, $response->get_error_message() ); } $response_code = wp_remote_retrieve_response_code($response); $response_body = wp_remote_retrieve_body($response); if ($response_code !== 200) { // Try to parse the response body as JSON to get specific error details $data = json_decode($response_body, true); // If valid JSON, extract error message and return with proper status code if (json_last_error() === JSON_ERROR_NONE && is_array($data)) { $error_message = isset($data['message']) ? $data['message'] : __('Something went wrong. Please try again or contact support.', 'templately'); return $this->error( 'api_response_error', $error_message, 'generate_logo', $response_code ); } // Otherwise, return generic error return $this->error( 'api_response_error', __('Something went wrong. Please try again or contact support.', 'templately'), 'generate_logo', $response_code ); } // Parse and validate response $data = json_decode($response_body, true); if (json_last_error() !== JSON_ERROR_NONE) { return $this->error( 'invalid_response', __('Invalid response from API.', 'templately'), 'generate_logo', 500 ); } // Check if the response has the expected structure if (!isset($data['status'])) { return $this->error( 'api_response_error', __('API returned an unexpected response.', 'templately'), 'generate_logo', 500 ); } // Extract image_base64 from nested data field if present $image_base64 = null; if (isset($data['data']['image_base64'])) { $image_base64 = $data['data']['image_base64']; } elseif (isset($data['image_base64'])) { // Fallback for legacy response format $image_base64 = $data['image_base64']; } // Upload base64 image to media library if provided if (!empty($image_base64)) { $upload_result = Utils::upload_logo_base64($image_base64); if (is_array($upload_result) && isset($upload_result['error'])) { // Log error but don't fail the entire response error_log('Logo upload error: ' . $upload_result['error']); } else if (is_array($upload_result) && isset($upload_result['id'])) { // Return clean response with only essential uploaded logo information // Overwrite the data field to remove base64 image data and return only ID and URL return [ 'status' => 'success', 'data' => [ 'id' => $upload_result['id'], 'url' => $upload_result['url'], ], ]; } } // Return the original response if no logo was uploaded return $data; } /** * Generate meta (title or tagline) using AI * * @return array|WP_Error */ public function generate_meta() { // Get parameters $field = $this->get_param('field'); $text = $this->get_param('text'); $requested_platform = $this->get_param('requested_platform', 'templately'); // Validate required parameters if (empty($field)) { return $this->error( 'missing_field', __('Field is required.', 'templately'), 'generate_meta', 400 ); } if (empty($text)) { return $this->error( 'missing_text', __('Text is required for meta generation.', 'templately'), 'generate_meta', 400 ); } // Prepare request body $body_data = [ 'field' => $field, 'text' => $text, ]; // Make API request $extra_headers = [ 'Content-Type' => 'application/json', 'x-templately-requested-platform' => $requested_platform, ]; $response = Helper::make_api_post_request('v2/generate-meta', $body_data, $extra_headers, 30); // Handle API response errors if (is_wp_error($response)) { return $this->error( 'api_request_failed', __('Failed to generate meta.', 'templately'), 'generate_meta', 500, $response->get_error_message() ); } $response_code = wp_remote_retrieve_response_code($response); $response_body = wp_remote_retrieve_body($response); if ($response_code !== 200) { // Try to parse the response body as JSON to get specific error details $data = json_decode($response_body, true); // If valid JSON, extract error message and return with proper status code if (json_last_error() === JSON_ERROR_NONE && is_array($data)) { $error_message = isset($data['message']) ? $data['message'] : __('Something went wrong. Please try again or contact support.', 'templately'); return $this->error( 'api_response_error', $error_message, 'generate_meta', $response_code ); } // Otherwise, return generic error return $this->error( 'api_response_error', __('Something went wrong. Please try again or contact support.', 'templately'), 'generate_meta', $response_code ); } // Parse and validate response $data = json_decode($response_body, true); if (json_last_error() !== JSON_ERROR_NONE) { return $this->error( 'invalid_response', __('Invalid response from API.', 'templately'), 'generate_meta', 500 ); } // Check if the response has the expected structure if (!isset($data['status'])) { return $this->error( 'api_response_error', __('API returned an unexpected response.', 'templately'), 'generate_meta', 500 ); } // Return the response as-is return $data; } }
Copyright ©2021 || Defacer Indonesia