container = $container; } public function init() { add_action('rest_api_init', [$this, 'register_routes']); } public function register_routes() { register_rest_route('awas/v1', '/search', [ 'methods' => \WP_REST_Server::READABLE, 'callback' => [$this, 'handle_search'], 'permission_callback' => '__return_true' ]); register_rest_route('awas/v1', '/log', [ 'methods' => \WP_REST_Server::CREATABLE, 'callback' => [$this, 'handle_log'], 'permission_callback' => '__return_true' ]); register_rest_route('awas/v1', '/log-click', [ 'methods' => \WP_REST_Server::CREATABLE, 'callback' => [$this, 'handle_log_click'], 'permission_callback' => '__return_true' ]); register_rest_route('awas/v1', '/popular', [ 'methods' => \WP_REST_Server::READABLE, 'callback' => [$this, 'handle_popular'], 'permission_callback' => '__return_true' ]); register_rest_route('awas/v1', '/build-index', [ 'methods' => \WP_REST_Server::CREATABLE, 'callback' => [$this, 'handle_build_index'], 'permission_callback' => function() { return current_user_can('manage_options'); } ]); } public function handle_search(WP_REST_Request $request) { $keyword = $request->get_param('q'); $category = $request->get_param('cat'); if (empty($keyword)) { return new WP_REST_Response(['results' => []], 200); } $engine = $this->container->get(Engine::class); // Measure performance $time_start = microtime(true); $results = $engine->search($keyword, $category); $time_end = microtime(true); $execution_time = round(($time_end - $time_start) * 1000, 2); // ms $response = [ 'results' => [], 'time_ms' => $execution_time ]; if (isset($results['did_you_mean'])) { $response['did_you_mean'] = $results['did_you_mean']; } else { $response['results'] = $results; } return rest_ensure_response($response); } public function handle_log(WP_REST_Request $request) { $keyword = sanitize_text_field(strtolower(trim($request->get_param('q')))); $has_results = filter_var($request->get_param('has_results'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? true; if (empty($keyword) || strlen($keyword) < 3) { return new WP_REST_Response(['success' => false], 400); } global $wpdb; $table = $wpdb->prefix . 'awas_search_logs'; $no_results_increment = $has_results ? 0 : 1; // Insert or update hits and no_results $wpdb->query($wpdb->prepare(" INSERT INTO $table (keyword, hits, no_results, clicks) VALUES (%s, 1, %d, 0) ON DUPLICATE KEY UPDATE hits = hits + 1, no_results = no_results + %d, last_searched = CURRENT_TIMESTAMP ", $keyword, $no_results_increment, $no_results_increment)); return new WP_REST_Response(['success' => true], 200); } public function handle_log_click(WP_REST_Request $request) { $keyword = sanitize_text_field(strtolower(trim($request->get_param('q')))); if (empty($keyword) || strlen($keyword) < 3) { return new WP_REST_Response(['success' => false], 400); } global $wpdb; $table = $wpdb->prefix . 'awas_search_logs'; // We only increment clicks if the keyword exists $wpdb->query($wpdb->prepare(" UPDATE $table SET clicks = clicks + 1 WHERE keyword = %s ", $keyword)); return new WP_REST_Response(['success' => true], 200); } public function handle_popular(WP_REST_Request $request) { global $wpdb; $table = $wpdb->prefix . 'awas_search_logs'; $results = $wpdb->get_col("SELECT keyword FROM $table ORDER BY hits DESC LIMIT 5"); return rest_ensure_response([ 'popular' => $results ]); } public function handle_build_index(WP_REST_Request $request) { $page = (int) $request->get_param('page') ?: 1; $clear = filter_var($request->get_param('clear'), FILTER_VALIDATE_BOOLEAN); $limit = 50; $indexer = $this->container->get(\Awas\AdvancedSearch\Indexing\Indexer::class); if ($page === 1 && $clear) { $indexer->truncate_index(); } $args = [ 'status' => 'publish', 'limit' => $limit, 'page' => $page, 'paginate' => true, 'return' => 'ids', ]; $results = wc_get_products($args); $product_ids = $results->products; $total_pages = $results->max_num_pages; $total_products = $results->total; $processed = 0; foreach ($product_ids as $id) { if ($indexer->index_product($id)) { $processed++; } } $is_done = ($page >= $total_pages || empty($product_ids)); return rest_ensure_response([ 'success' => true, 'page' => $page, 'total_pages' => $total_pages, 'total_products' => $total_products, 'processed_this_batch' => $processed, 'done' => $is_done ]); } }