'POST', 'callback' => array($this, 'handle_chat'), 'permission_callback' => array($this, 'check_chat_permission'), 'args' => array( 'message' => array( 'required' => true, 'type' => 'string', 'sanitize_callback' => 'sanitize_textarea_field' ), 'conversation_id' => array( 'required' => false, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ), 'category' => array( 'required' => false, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ) ) )); register_rest_route(self::NAMESPACE, '/config', array( 'methods' => 'GET', 'callback' => array($this, 'get_config'), 'permission_callback' => '__return_true' )); register_rest_route(self::NAMESPACE, '/product/(?P\d+)', array( 'methods' => 'GET', 'callback' => array($this, 'get_product'), 'permission_callback' => '__return_true', 'args' => array( 'id' => array( 'validate_callback' => function($param) { return is_numeric($param); } ) ) )); register_rest_route(self::NAMESPACE, '/categories', array( 'methods' => 'GET', 'callback' => array($this, 'get_categories'), 'permission_callback' => '__return_true' )); register_rest_route(self::NAMESPACE, '/blog-categories', array( 'methods' => 'GET', 'callback' => array($this, 'get_blog_categories'), 'permission_callback' => '__return_true' )); register_rest_route(self::NAMESPACE, '/cpt-categories', array( 'methods' => 'GET', 'callback' => array($this, 'get_cpt_categories'), 'permission_callback' => '__return_true' )); register_rest_route(self::NAMESPACE, '/category-link', array( 'methods' => 'GET', 'callback' => array($this, 'get_category_link'), 'permission_callback' => '__return_true', 'args' => array( 'category' => array( 'required' => true, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ) ) )); register_rest_route(self::NAMESPACE, '/rating', array( 'methods' => 'POST', 'callback' => array($this, 'save_rating'), 'permission_callback' => array($this, 'check_chat_permission'), 'args' => array( 'chat_id' => array( 'required' => true, 'type' => 'integer', 'sanitize_callback' => 'absint' ), 'rating' => array( 'required' => true, 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => function($param) { return is_numeric($param) && $param >= 0 && $param <= 100; } ) ) )); } public function check_chat_permission() { $require_login = get_option('aieo_chat_require_login', '0') === '1'; if ($require_login && !is_user_logged_in()) { return new WP_Error( 'unauthorized', __('Please log in to use chat', 'ai-eshop-optimizer'), array('status' => 401) ); } return true; } public function handle_chat($request) { $message = $request->get_param('message'); $conversation_id = $request->get_param('conversation_id'); $category = $request->get_param('category'); if (empty($conversation_id)) { $conversation_id = wp_generate_uuid4(); } $args = array(); if (!empty($category)) { $args['category'] = $category; } $chat_api = AI_eShop_Chat_API::get_instance(); $result = $chat_api->process_chat_message($message, $conversation_id, $args); if (is_wp_error($result)) { return new WP_Error( $result->get_error_code(), $result->get_error_message(), array('status' => 400) ); } return rest_ensure_response($result); } public function get_config() { $chat_api = AI_eShop_Chat_API::get_instance(); return rest_ensure_response($chat_api->get_chat_config()); } public function get_product($request) { $product_id = (int) $request->get_param('id'); $product_data = AI_eShop_Chat_Content_Extractor::get_product_data($product_id); if (!$product_data) { return new WP_Error( 'product_not_found', __('Product not found', 'ai-eshop-optimizer'), array('status' => 404) ); } return rest_ensure_response($product_data); } public function get_categories() { $cached_categories = get_option('aieo_chat_cached_categories', false); if ($cached_categories !== false && is_array($cached_categories) && !empty($cached_categories)) { return rest_ensure_response(array( 'categories' => $cached_categories )); } global $wpdb; $categories = array(); $categories[] = array( 'id' => 0, 'name' => __('All Categories', 'ai-eshop-optimizer') ); $hidden_cat_ids = array(); if (get_option('aieo_chat_honor_navigator_hidden_terms', '1') === '1' && class_exists('AIEO_DMM_Settings')) { $raw = (string) AIEO_DMM_Settings::get('navigator_excluded_terms', ''); foreach (preg_split('/[,\s]+/', $raw) as $tok) { $tok = trim($tok); if ($tok === '') continue; if (strpos($tok, ':') === false) { $hidden_cat_ids[(int) $tok] = true; } else { list($tax, $id) = explode(':', $tok, 2); if (sanitize_key($tax) === 'product_cat') { $hidden_cat_ids[(int) $id] = true; } } } } $top_categories = $wpdb->get_results( "SELECT h.top_category, MIN(h.top_category_id) as top_category_id FROM {$wpdb->prefix}aieo_core_product_category_hierarchy h INNER JOIN {$wpdb->posts} p ON p.ID = h.product_id AND p.post_status = 'publish' WHERE h.top_category IS NOT NULL AND h.top_category != '' GROUP BY h.top_category ORDER BY h.top_category ASC", ARRAY_A ); if (!empty($top_categories)) { foreach ($top_categories as $cat) { $cat_id = (int) $cat['top_category_id']; if (isset($hidden_cat_ids[$cat_id])) continue; $categories[] = array( 'id' => $cat_id, 'name' => $cat['top_category'] ); } } if (!empty($categories)) { update_option('aieo_chat_cached_categories', $categories, false); } return rest_ensure_response(array( 'categories' => $categories )); } public function get_blog_categories() { $cached_categories = get_option('aieo_chat_cached_blog_categories', false); if ($cached_categories !== false && is_array($cached_categories) && !empty($cached_categories)) { return rest_ensure_response(array( 'categories' => $cached_categories )); } $categories = array(); $categories[] = array( 'id' => 0, 'name' => __('All Categories', 'ai-eshop-optimizer') ); $blog_categories = get_terms(array( 'taxonomy' => 'category', 'hide_empty' => true, 'parent' => 0, 'orderby' => 'name', 'order' => 'ASC' )); if (!empty($blog_categories) && !is_wp_error($blog_categories)) { foreach ($blog_categories as $term) { $categories[] = array( 'id' => $term->term_id, 'name' => $term->name ); } } if (!empty($categories)) { update_option('aieo_chat_cached_blog_categories', $categories, false); } return rest_ensure_response(array( 'categories' => $categories )); } public function get_cpt_categories() { $cpt_taxonomy = get_option('aieo_chat_cpt_taxonomy_slug', ''); if (empty($cpt_taxonomy)) { return rest_ensure_response(array('categories' => array())); } $cache_key = 'aieo_chat_cached_cpt_categories_' . $cpt_taxonomy; $cached_categories = get_option($cache_key, false); if ($cached_categories !== false && is_array($cached_categories) && !empty($cached_categories)) { return rest_ensure_response(array( 'categories' => $cached_categories )); } $categories = array(); $categories[] = array( 'id' => 0, 'name' => __('All Categories', 'ai-eshop-optimizer') ); $cpt_categories = get_terms(array( 'taxonomy' => $cpt_taxonomy, 'hide_empty' => true, 'parent' => 0, 'orderby' => 'name', 'order' => 'ASC' )); if (!empty($cpt_categories) && !is_wp_error($cpt_categories)) { foreach ($cpt_categories as $term) { $categories[] = array( 'id' => $term->term_id, 'name' => $term->name ); } } if (!empty($categories)) { update_option($cache_key, $categories, false); } return rest_ensure_response(array( 'categories' => $categories )); } public function get_category_link($request) { $category_name = $request->get_param('category'); if (empty($category_name)) { return rest_ensure_response(array('url' => '')); } $term = get_term_by('name', $category_name, 'product_cat'); if (!$term || is_wp_error($term)) { return rest_ensure_response(array('url' => '')); } $category_url = get_term_link($term); if (is_wp_error($category_url)) { return rest_ensure_response(array('url' => '')); } return rest_ensure_response(array( 'url' => $category_url )); } public function save_rating($request) { global $wpdb; $chat_id = $request->get_param('chat_id'); $rating = $request->get_param('rating'); if ($rating == 50) { return rest_ensure_response(array( 'success' => true, 'message' => __('Rating unchanged from default', 'ai-eshop-optimizer') )); } $table_name = $wpdb->prefix . 'aieo_chat_history'; $result = $wpdb->update( $table_name, array('user_rating' => $rating), array('id' => $chat_id), array('%d'), array('%d') ); if ($result === false) { return new WP_Error( 'update_failed', __('Failed to save rating', 'ai-eshop-optimizer'), array('status' => 500) ); } return rest_ensure_response(array( 'success' => true, 'message' => __('Rating saved successfully', 'ai-eshop-optimizer'), 'rating' => $rating )); } }