__( 'Search knowledge base...', 'aiohm-knowledge-assistant' ),
'show_categories' => 'true',
'show_results_count' => 'true',
'max_results' => '10',
'excerpt_length' => '150',
'show_content_type' => 'true',
'enable_instant_search' => 'true',
'min_chars' => '3',
),
$atts,
'aiohm_search'
);
static $search_counter = 0;
++$search_counter;
$search_id = 'aiohm-search-' . $search_counter;
// Enqueue search script and style
wp_enqueue_script( 'aiohm-search-shortcode' );
wp_enqueue_style( 'aiohm-search-shortcode' );
$output = '
';
$output .= '
';
$output .= '
';
$output .= '
';
if ( $atts['show_categories'] === 'true' ) {
$output .= '
';
$output .= '';
$output .= '
';
}
$output .= '
'; // .aiohm-search-controls
$output .= '
';
$output .= '' . __( 'Searching...', 'aiohm-knowledge-assistant' ) . '';
$output .= '
';
$output .= '
';
$output .= '
'; // .aiohm-search-container
$search_config = array(
'search_id' => $search_id,
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'aiohm_search_nonce' ),
'settings' => array(
'max_results' => intval( $atts['max_results'] ),
'excerpt_length' => intval( $atts['excerpt_length'] ),
'show_content_type' => $atts['show_content_type'] === 'true',
'enable_instant_search' => $atts['enable_instant_search'] === 'true',
'min_chars' => intval( $atts['min_chars'] ),
'show_results_count' => $atts['show_results_count'] === 'true',
),
'strings' => array(
'no_results' => __( 'No results found for your search.', 'aiohm-knowledge-assistant' ),
'error' => __( 'Search failed. Please try again.', 'aiohm-knowledge-assistant' ),
// translators: %d is the number of search results found
'results_count' => __( 'Found %d result(s)', 'aiohm-knowledge-assistant' ),
'searching' => __( 'Searching...', 'aiohm-knowledge-assistant' ),
),
);
// Localize script data instead of inline script
wp_add_inline_script(
'aiohm-search-shortcode',
'if (typeof window.aiohm_search_configs === "undefined") window.aiohm_search_configs = {};' .
'window.aiohm_search_configs["' . esc_js( $search_id ) . '"] = ' . wp_json_encode( $search_config ) . ';'
);
$output .= '
'; // .aiohm-search-wrapper
return $output;
}
/**
* Handles the AJAX request for searching the knowledge base.
*/
public static function handle_search_ajax() {
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'aiohm_search_nonce' ) ) {
wp_send_json_error( array( 'message' => __( 'Security check failed', 'aiohm-knowledge-assistant' ) ) );
wp_die();
}
$query = isset( $_POST['query'] ) ? sanitize_text_field( wp_unslash( $_POST['query'] ) ) : '';
$content_type_filter = isset( $_POST['content_type_filter'] ) ? sanitize_text_field( wp_unslash( $_POST['content_type_filter'] ) ) : '';
$max_results = isset( $_POST['max_results'] ) ? intval( $_POST['max_results'] ) : 10;
$excerpt_length = isset( $_POST['excerpt_length'] ) ? intval( $_POST['excerpt_length'] ) : 25;
if ( empty( $query ) ) {
wp_send_json_error( array( 'message' => __( 'Search query is required', 'aiohm-knowledge-assistant' ) ) );
wp_die();
}
try {
$results = self::perform_search( $query, $content_type_filter, $max_results, $excerpt_length );
wp_send_json_success( $results );
} catch ( Exception $e ) {
// translators: %s is the error message from the search operation
wp_send_json_error( array( 'message' => sprintf( __( 'Search failed: %s', 'aiohm-knowledge-assistant' ), $e->getMessage() ) ) );
}
wp_die();
}
/**
* Performs the knowledge base search and formats the results.
* This private method encapsulates the core search logic.
*
* @param string $query The search term.
* @param string $content_type_filter The content type to filter by.
* @param int $max_results The maximum number of results to return.
* @param int $excerpt_length The length of the result excerpts.
* @return array An array of formatted search results.
*/
private static function perform_search( $query, $content_type_filter, $max_results, $excerpt_length ) {
$rag_engine = new AIOHM_KB_RAG_Engine();
$results = $rag_engine->find_relevant_context( $query, $max_results );
$filtered_results = array();
if ( ! empty( $content_type_filter ) ) {
foreach ( $results as $result ) {
if ( $result['entry']['content_type'] === $content_type_filter ) {
$filtered_results[] = $result;
}
}
} else {
$filtered_results = $results;
}
$formatted_results = array();
foreach ( $filtered_results as $result ) {
$entry = $result['entry'];
$excerpt = wp_trim_words( $entry['content'], $excerpt_length, '...' );
$metadata = is_string( $entry['metadata'] ) ? json_decode( $entry['metadata'], true ) : $entry['metadata'];
// Generate appropriate URL based on content type and metadata
$url = '#';
if ( isset( $metadata['url'] ) ) {
$url = $metadata['url'];
} elseif ( isset( $metadata['attachment_id'] ) ) {
// For uploaded files (PDFs, documents, etc.)
$attachment_url = wp_get_attachment_url( $metadata['attachment_id'] );
$url = $attachment_url ?: '#';
} elseif ( isset( $metadata['post_id'] ) ) {
// For WordPress posts/pages
$url = get_permalink( $metadata['post_id'] );
}
$formatted_results[] = array(
'title' => $entry['title'],
'excerpt' => $excerpt,
'content_type' => $entry['content_type'],
'similarity' => round( $result['score'] * 100, 1 ),
'url' => $url ?: '#',
);
}
return array(
'results' => $formatted_results,
'total_count' => count( $formatted_results ),
);
}
}