__( '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 configuration script right at the start
$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
$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 ),
);
}
}