PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.8.2
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.8.2
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / FrontEnd / SearchExtender.php

SearchExtender.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.8.2, at includes/FrontEnd/SearchExtender.php

76 lines 2.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPDeveloper\BetterDocs\FrontEnd;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 /**
10 * Extends WordPress search SQL on `docs` queries to also match docs whose
11 * assigned `doc_tag` or `doc_category` term names contain the search term.
12 *
13 * The filter is registered globally so it applies to every search query against
14 * the `docs` post type — including WP core's `GET /wp/v2/docs?search=...`,
15 * BetterDocs' `/betterdocs/v1/search`, and the shortcode/widget AJAX paths.
16 */
17 class SearchExtender {
18 public function __construct() {
19 add_filter( 'posts_search', [ $this, 'extend_search' ], 20, 2 );
20 }
21
22 /**
23 * Inject an OR clause that matches docs whose related taxonomy term names
24 * contain the search term.
25 *
26 * @param string $search The search SQL clause (already begins with " AND (").
27 * @param \WP_Query $query The WP_Query instance.
28 * @return string Modified search SQL.
29 */
30 public function extend_search( $search, $query ) {
31 global $wpdb;
32
33 if ( empty( $search ) ) {
34 return $search;
35 }
36
37 $post_type = isset( $query->query_vars['post_type'] ) ? $query->query_vars['post_type'] : '';
38 if ( is_array( $post_type ) ) {
39 if ( ! in_array( 'docs', $post_type, true ) ) {
40 return $search;
41 }
42 } elseif ( $post_type !== 'docs' ) {
43 return $search;
44 }
45
46 $search_term = isset( $query->query_vars['s'] ) ? (string) $query->query_vars['s'] : '';
47 if ( $search_term === '' ) {
48 return $search;
49 }
50
51 $taxonomies = [ 'doc_tag', 'doc_category' ];
52 $like = '%' . $wpdb->esc_like( $search_term ) . '%';
53
54 $placeholders = implode( ',', array_fill( 0, count( $taxonomies ), '%s' ) );
55 $args = $taxonomies;
56 $args[] = $like;
57
58 // $placeholders is a generated run of %s tokens bound via $args below; all
59 // interpolated identifiers are $wpdb core table names, not user input.
60 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
61 $subquery = $wpdb->prepare(
62 "{$wpdb->posts}.ID IN (
63 SELECT DISTINCT tr.object_id
64 FROM {$wpdb->term_relationships} tr
65 INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
66 INNER JOIN {$wpdb->terms} t ON tt.term_id = t.term_id
67 WHERE tt.taxonomy IN ({$placeholders}) AND t.name LIKE %s
68 )",
69 $args
70 );
71 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
72
73 return preg_replace( '/^\s*AND\s*\(/', " AND ({$subquery} OR ", $search, 1 );
74 }
75 }
76