table_article = Config::get_table_name('article'); add_action('wp_ajax_aizl_article_upload', array($this, 'aizl_article_upload')); add_action('wp_ajax_aizl_process_s3_file', array($this, 'aizl_process_s3_file')); add_action('wp_ajax_aizl_get_article_list', array($this, 'aizl_get_article_list')); add_action('wp_ajax_aizl_delete_article', array($this, 'aizl_delete_article')); } public function aizl_article_upload() { if (!check_ajax_referer('aizl_setting', 'nonce', false)) { wp_send_json_error('Invalid nonce.'); return; } if (!isset($_POST['file_name']) || !isset($_POST['file_size'])) { wp_send_json_error('No file information provided.'); return; } $db_handler = new DBHandler(); $access_key = $db_handler->get_access_key(); if(!$access_key) { wp_send_json_error('Invalid Access Key'); return; } $file_name = sanitize_text_field(wp_unslash($_POST['file_name'])); $file_size = intval($_POST['file_size']); // Normalize filename extension to lowercase for OpenAI compatibility $name_parts = explode('.', $file_name); if (count($name_parts) > 1) { $name_parts[count($name_parts) - 1] = strtolower($name_parts[count($name_parts) - 1]); $file_name = implode('.', $name_parts); } // Check file size against processing limit if ($file_size > 10 * 1024 * 1024) { wp_send_json_error('File too large. Maximum 10MB allowed.'); return; } // Get presigned URL for S3 upload $presigned_response = $this->get_presigned_url($file_name, $file_size, $access_key); if (is_wp_error($presigned_response)) { wp_send_json_error('Failed to get upload URL.'); return; } if (wp_remote_retrieve_response_code($presigned_response) != 200) { wp_send_json_error('Failed to get upload URL.'); return; } $presigned_data = json_decode(wp_remote_retrieve_body($presigned_response), true); // Return upload URL to frontend for S3 upload wp_send_json_success(array( 'upload_url' => $presigned_data['upload_url'], 'file_key' => $presigned_data['file_key'], 'file_name' => $file_name, 'file_size' => $file_size, 'action' => 'upload_to_s3' )); } private function get_presigned_url($file_name, $file_size, $access_key) { $api_url = Config::get_api_endpoint('presign'); $api_response = wp_remote_post($api_url, array( 'method' => 'POST', 'body' => json_encode(array( 'file_name' => $file_name, 'file_size' => $file_size )), 'headers' => array( 'Content-Type' => 'application/json', 'x-access-key' => $access_key, 'x-plugin-source' => 'aizlabs_chat_agent' ), 'timeout' => 60, )); return $api_response; } public function aizl_process_s3_file() { if (!check_ajax_referer('aizl_setting', 'nonce', false)) { wp_send_json_error('Invalid nonce.'); return; } if (!isset($_POST['file_key']) || !isset($_POST['file_name'])) { wp_send_json_error('Missing file information.'); return; } $file_key = sanitize_text_field(wp_unslash($_POST['file_key'])); $file_name = sanitize_text_field(wp_unslash($_POST['file_name'])); $file_size = isset($_POST['file_size']) ? intval($_POST['file_size']) : 0; $db_handler = new DBHandler(); $access_key = $db_handler->get_access_key(); if(!$access_key) { wp_send_json_error('Invalid Access Key'); return; } // Call vector store lambda with S3 reference $api_url = Config::get_api_endpoint('upload'); $api_response = wp_remote_post($api_url, array( 'body' => json_encode(array( 's3_bucket' => 'aizlabs-ai-agent-bucket', 's3_key' => $file_key, 'file_name' => $file_name )), 'headers' => array( 'Content-Type' => 'application/json', 'x-access-key' => $access_key, 'x-plugin-source' => 'aizlabs_chat_agent' ), 'timeout' => 60, )); if (is_wp_error($api_response)) { $api_error_msg = $api_response->get_error_message(); wp_send_json_error('Failed to process file: ' . $api_error_msg); return; } if (wp_remote_retrieve_response_code($api_response) != 200) { error_log('Upload API Error Response: ' . print_r($api_response, true)); wp_send_json_error('Failed to create file.'); return; } $api_response_body = json_decode(wp_remote_retrieve_body($api_response), true); $file_id = $api_response_body['file_id']; // Save to database // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $article_id = $this->save_article_s3($file_name, $file_size, $file_id); if ($article_id) { wp_send_json_success('File uploaded and processed successfully.'); } else { wp_send_json_error('File processed but failed to save to database.'); } } private function save_article_s3($file_name, $file_size, $file_id) { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Inserting into custom plugin table $result = $wpdb->insert($this->table_article, array( 'file_type' => 'application/octet-stream', 'file_name' => $file_name, 'file_size' => $file_size, 'file_id' => $file_id, 'created_time' => gmdate('Y-m-d H:i:s'), )); if ($result === false) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log error_log('Database insert error: ' . $wpdb->last_error); return false; } return $wpdb->insert_id; } public function aizl_get_article_list() { if (!check_ajax_referer('aizl_setting', 'nonce', false)) { wp_send_json_error('Invalid nonce.'); return; } //require_once __DIR__ . '/class-dbhandler.php'; $db_handler = new DBHandler(); $articles = $db_handler->get_articles(); ob_start(); if ($articles && count($articles) > 0) { foreach ($articles as $article) { ?>