PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.2.0
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.2.0
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
← All changes | includes/Shortcodes/SearchForm.php +18 -172 4.5.44.2.0 View file →
@@ -15,133 +15,8 @@
15 15 add_action( 'wp_ajax_nopriv_betterdocs_get_search_result', [ $this, 'get_search_results' ] );
16 16 add_action( 'wp_ajax_betterdocs_get_search_result', [ $this, 'get_search_results' ] );
17 17 }
18 18
19 - /**
20 - * Modify search query to properly handle non-English characters
21 - *
22 - * @param string $search The search SQL for WHERE clause
23 - * @param WP_Query $query The WP_Query instance
24 - * @return string Modified search SQL
25 - */
26 - public function improve_search_for_non_english( $search, $query ) {
27 - global $wpdb;
28 -
29 - // Only modify our BetterDocs search queries
30 - if ( ! isset( $query->query_vars['post_type'] ) || $query->query_vars['post_type'] !== 'docs' ) {
31 - return $search;
32 - }
33 -
34 - // Only modify if there's a search term
35 - if ( empty( $query->query_vars['s'] ) ) {
36 - return $search;
37 - }
38 -
39 - $search_term = $query->query_vars['s'];
40 -
41 - // If the search term contains non-ASCII characters, we need to ensure proper UTF-8 handling
42 - if ( preg_match('/[^\x00-\x7F]/', $search_term) ) {
43 - // Get the search term with proper escaping
44 - $like = '%' . $wpdb->esc_like( $search_term ) . '%';
45 -
46 - // Build a UTF-8 compatible search query
47 - // Search in post_title, post_content, and post_excerpt
48 - // Note: Removed COLLATE clause to avoid collation mismatch with TranslatePress tables
49 - $search = $wpdb->prepare(
50 - " AND (
51 - ({$wpdb->posts}.post_title LIKE %s)
52 - OR ({$wpdb->posts}.post_content LIKE %s)
53 - OR ({$wpdb->posts}.post_excerpt LIKE %s)",
54 - $like,
55 - $like,
56 - $like
57 - );
58 -
59 - // If TranslatePress is active, also search in the translation dictionary
60 - if ( class_exists( '\TRP_Translate_Press' ) ) {
61 - // Get language codes
62 - $lang_codes = $this->get_trp_language_code();
63 - $default_lang = $lang_codes['default_language'];
64 - $current_lang = $lang_codes['current_language'];
65 -
66 - // Only search in translation table if current language is different from default
67 - if ( $default_lang !== $current_lang ) {
68 - // TranslatePress table naming: wp_trp_dictionary_{default_lang}_{current_lang}
69 - $trp_table = $wpdb->prefix . 'trp_dictionary_' . $default_lang . '_' . $current_lang;
70 -
71 - if ( $this->table_exists( $trp_table ) ) {
72 -
73 - $trp_search = $wpdb->prepare(
74 - " OR EXISTS (
75 - SELECT 1 FROM {$trp_table} trp
76 - WHERE (trp.original LIKE %s OR trp.translated LIKE %s)
77 - AND trp.status != 2
78 - AND (
79 - {$wpdb->posts}.post_title COLLATE utf8mb4_unicode_ci = trp.original COLLATE utf8mb4_unicode_ci
80 - OR {$wpdb->posts}.post_content COLLATE utf8mb4_unicode_ci LIKE CONCAT('%%', trp.original COLLATE utf8mb4_unicode_ci, '%%')
81 - OR {$wpdb->posts}.post_excerpt COLLATE utf8mb4_unicode_ci = trp.original COLLATE utf8mb4_unicode_ci
82 - )
83 - )",
84 - $like,
85 - $like
86 - );
87 -
88 - $search .= $trp_search;
89 - }
90 - }
91 - }
92 -
93 -
94 - $search .= " ) ";
95 - }
96 -
97 - return $search;
98 - }
99 -
100 - /**
101 - * Get TranslatePress language codes (default and current) for table name construction
102 - *
103 - * @return array Array with 'default_language' and 'current_language' keys
104 - */
105 - private function get_trp_language_code() {
106 - $result = [
107 - 'default_language' => 'en_US',
108 - 'current_language' => 'en_US'
109 - ];
110 -
111 - if ( class_exists( '\TRP_Translate_Press' ) ) {
112 - $trp = \TRP_Translate_Press::get_trp_instance();
113 - if ( isset( $trp ) && method_exists( $trp, 'get_component' ) ) {
114 - $trp_settings = $trp->get_component( 'settings' );
115 -
116 - // Get default language from settings
117 - if ( $trp_settings ) {
118 - $settings = $trp_settings->get_settings();
119 - if ( isset( $settings['default-language'] ) ) {
120 - $result['default_language'] = strtolower( $settings['default-language'] );
121 - }
122 - }
123 -
124 - // Get current language from global variable
125 - global $TRP_LANGUAGE;
126 - if ( isset( $TRP_LANGUAGE ) && ! empty( $TRP_LANGUAGE ) ) {
127 - $result['current_language'] = strtolower( $TRP_LANGUAGE );
128 - }
129 - }
130 - }
131 -
132 - return $result;
133 - }
134 -
135 - /**
136 - * Check if a database table exists
137 - */
138 - private function table_exists( $table_name ) {
139 - global $wpdb;
140 - $result = $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table_name ) );
141 - return $result === $table_name;
142 - }
143 -
144 19 public function get_style_depends() {
145 20 $handlers = [ 'betterdocs-search' ];
146 21 return $handlers;
147 22 }
@@ -156,12 +31,12 @@
156 31 }
157 32
158 33 public function get_search_results() {
159 34 global $wpdb;
160 - $search_input = isset( $_POST['search_input'] ) ? sanitize_text_field( $_POST['search_input'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
161 - $search_cat = isset( $_POST['search_cat'] ) ? wp_strip_all_tags( $_POST['search_cat'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
162 - $lang = isset( $_POST['lang'] ) ? wp_strip_all_tags( $_POST['lang'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
163 - $kb_slug = isset( $_POST['kb_slug'] ) ? sanitize_text_field( $_POST['kb_slug'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
35 + $search_input = isset( $_POST['search_input'] ) ? sanitize_text_field( $_POST['search_input'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
36 + $search_cat = isset( $_POST['search_cat'] ) ? wp_strip_all_tags( $_POST['search_cat'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
37 + $lang = isset( $_POST['lang'] ) ? wp_strip_all_tags( $_POST['lang'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
38 + $search_input = preg_replace( '/[^A-Za-z0-9_\- ][]]/', '', strtolower( $search_input ) );
164 39
165 40 $tax_query = [];
166 41 if ( $search_cat ) {
167 42 $tax_query = [
@@ -174,11 +49,8 @@
174 49 ]
175 50 ];
176 51 }
177 52
178 - // Don't build KB tax_query here - let the MultipleKB filter handle it
179 - // We just pass kb_slug in the args
180 -
181 53 $term = get_term_by( 'slug', $search_cat );
182 54
183 55 $post_status = ['publish'];
184 56
@@ -186,47 +58,25 @@
186 58 array_push($post_status, 'private');
187 59 }
188 60
189 61 $args = [
190 - 'term_id' => isset( $term->term_id ) ? $term->term_id : 0,
191 - 'post_type' => 'docs',
192 - 'post_status' => $post_status,
193 - 'posts_per_page' => -1,
194 - 'suppress_filters' => false,
195 - 's' => $search_input,
196 - 'orderby' => 'relevance',
197 - 'tax_query' => $tax_query,
198 - 'kb_slug' => $kb_slug
62 + 'term_id' => isset( $term->term_id ) ? $term->term_id : 0,
63 + 'post_type' => 'docs',
64 + 'post_status' => $post_status,
65 + 'posts_per_page' => -1,
66 + 'suppress_filters' => true,
67 + 's' => $search_input,
68 + 'orderby' => 'relevance',
69 + 'tax_query' => $tax_query
199 70 ];
200 71
201 - // Handle WPML multilingual search
202 72 if ( is_plugin_active( 'sitepress-multilingual-cms/sitepress.php' ) ) {
203 - // If search term contains non-ASCII characters (e.g., Chinese, Japanese, Bangla),
204 - // search across all languages to find translated posts
205 - if ( preg_match('/[^\x00-\x7F]/', $search_input) ) {
206 - // Non-ASCII search: bypass WPML language filtering but allow posts_search filter
207 - // This allows searching across all languages
208 - $args['suppress_filters'] = true;
209 - } else {
210 - // ASCII-only search (English), use WPML filters to restrict to current language
211 - $args['suppress_filters'] = false;
212 - $args['lang'] = ICL_LANGUAGE_CODE;
213 - }
214 - }
215 - // Handle TranslatePress - always allow posts_search filter for non-ASCII
216 - elseif ( class_exists( '\TRP_Translate_Press' ) && preg_match('/[^\x00-\x7F]/', $search_input) ) {
217 - // For TranslatePress, we need posts_search filter to run
218 73 $args['suppress_filters'] = false;
74 + $args['lang'] = ICL_LANGUAGE_CODE;
219 75 }
220 76
221 - // Add filter to improve search for non-English characters
222 - add_filter( 'posts_search', [ $this, 'improve_search_for_non_english' ], 10, 2 );
223 -
224 77 $search_results = $this->query->get_posts( $args );
225 78
226 - // Remove filter after query to avoid affecting other queries
227 - remove_filter( 'posts_search', [ $this, 'improve_search_for_non_english' ], 10 );
228 -
229 79 $response = [];
230 80
231 81 ob_start();
232 82 betterdocs()->views->get(
@@ -266,27 +116,23 @@
266 116 public function default_attributes() {
267 117 return apply_filters(
268 118 'betterdocs_search_form_attr',
269 119 [
270 - 'placeholder' => __( 'Search', 'betterdocs' ),
271 - 'heading' => '',
272 - 'subheading' => '',
273 - 'heading_tag' => 'h1',
274 - 'subheading_tag' => 'p',
275 - 'kb_based_search' => ''
120 + 'placeholder' => __( 'Search', 'betterdocs' ),
121 + 'heading' => '',
122 + 'subheading' => '',
123 + 'heading_tag' => 'h1',
124 + 'subheading_tag' => 'p'
276 125 ]
277 126 );
278 127 }
279 128
280 129 public function render( $atts, $content = null ) {
281 - $kb_based_search = isset( $atts['kb_based_search'] ) ? sanitize_text_field( $atts['kb_based_search'] ) : '';
282 -
283 130 betterdocs()->assets->localize(
284 131 'betterdocs-search',
285 132 'betterdocsSearchConfigTwo',
286 133 [
287 134 'is_post_type_archive' => is_post_type_archive( 'docs' ),
288 - 'kb_based_search' => $kb_based_search
289 135 ]
290 136 );
291 137
292 138 $this->views( 'shortcodes/search' );