/ wordpress / restai / includes / class-restai-search.php
class-restai-search.php
 1  <?php
 2  /**
 3   * AI-powered site search. When enabled, intercepts the standard WP search
 4   * query and asks the Support Bot project for an answer + relevant sources.
 5   *
 6   * The native search results page is augmented with the AI answer at the top.
 7   *
 8   * @package RESTai
 9   */
10  
11  namespace RESTai;
12  
13  if ( ! defined( 'ABSPATH' ) ) {
14  	exit;
15  }
16  
17  class Search {
18  
19  	/** @var Client */
20  	private $client;
21  
22  	public function __construct( Client $client ) {
23  		$this->client = $client;
24  		add_action( 'pre_get_posts', array( $this, 'noop' ) );
25  		add_filter( 'the_content', array( $this, 'inject_ai_answer' ), 5 );
26  	}
27  
28  	public function noop( $q ) {
29  		// reserved for future query rewrites
30  	}
31  
32  	public function inject_ai_answer( $content ) {
33  		$settings = get_option( 'restai_settings', array() );
34  		if ( empty( $settings['enable_search'] ) ) {
35  			return $content;
36  		}
37  		if ( ! is_search() ) {
38  			return $content;
39  		}
40  		static $injected = false;
41  		if ( $injected ) {
42  			return $content;
43  		}
44  		$injected = true;
45  
46  		$q = get_search_query();
47  		if ( '' === $q ) {
48  			return $content;
49  		}
50  
51  		$plugin     = Plugin::instance();
52  		$project_id = $plugin->provisioner->project_for( 'support_bot' );
53  		if ( $project_id <= 0 ) {
54  			return $content;
55  		}
56  
57  		$key = 'restai_search_' . md5( $q );
58  		$cached = get_transient( $key );
59  		if ( false === $cached ) {
60  			$ans = $this->client->ask( $project_id, $q );
61  			$cached = is_wp_error( $ans ) ? '' : $ans;
62  			set_transient( $key, $cached, HOUR_IN_SECONDS );
63  		}
64  		if ( '' === $cached ) {
65  			return $content;
66  		}
67  		$panel = sprintf(
68  			'<div class="restai-ai-answer" style="background:#f6f7f9;border:1px solid #e0e0e6;border-radius:8px;padding:16px;margin-bottom:16px;"><strong>%s</strong><div style="margin-top:8px;">%s</div></div>',
69  			esc_html__( 'AI answer', 'restai' ),
70  			wp_kses_post( $cached )
71  		);
72  		return $panel . $content;
73  	}
74  }