PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.6.0
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.6.0
8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 8.5.5 8.5.4 8.5.3 8.5.2 All 533 releases
chatbot / qcld-wpwbot-search.php

qcld-wpwbot-search.php in WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services 8.6.0, at qcld-wpwbot-search.php

1,098 lines 43.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) exit; // Exit if accessed directly
3 /**
4 * Product indexing, caching & searching features concept is taken from open source 'Advanced wp Search' Wp plugin by ILLID.
5 */
6 //include_once( 'includes/class-wpwbot-cache.php' );
7
8 include_once( 'includes/class-wpwbot-table.php' );
9 include_once( 'includes/class-wpwbot-search.php' );
10
11 // Helper function to generate variations for each word in a keyword
12 if ( ! function_exists( '_wpbot_generate_word_variations' ) ) {
13 function _wpbot_generate_word_variations($keyword) {
14 $keyword = strtolower(trim($keyword));
15 $words = preg_split('/\s+/', $keyword, -1, PREG_SPLIT_NO_EMPTY);
16 $all_word_variations = [];
17
18 foreach ($words as $word) {
19 $variations = [$word];
20
21 // Simple pluralization/singularization and common suffix handling
22 if (strlen($word) > 1) { // Avoid stemming single letters
23 // Remove 's' (e.g., 'inspections' -> 'inspection')
24 if (substr($word, -1) === 's') {
25 $variations[] = substr($word, 0, -1);
26 } else { // Add 's' (e.g., 'inspection' -> 'inspections')
27 $variations[] = $word . 's';
28 }
29 // Handle 'er' suffix (e.g., 'inspector' -> 'inspect')
30 if (substr($word, -2) === 'er') {
31 $variations[] = substr($word, 0, -2);
32 }
33 // Handle 'ing' suffix (e.g., 'inspecting' -> 'inspect')
34 if (substr($word, -3) === 'ing') {
35 $variations[] = substr($word, 0, -3);
36 }
37 // Add 'er' if the base word is 'inspect' and 'inspector' is not present
38 if (strpos($word, 'inspect') !== false && strpos($word, 'inspector') === false) {
39 $variations[] = str_replace('inspect', 'inspector', $word);
40 }
41 }
42 $all_word_variations[] = array_filter(array_unique($variations));
43 }
44 return $all_word_variations;
45 }
46 }
47
48 // Filter function to modify WP_Query search for flexible matching
49 if ( ! function_exists( 'wpbot_flexible_search_filter' ) ) {
50 function wpbot_flexible_search_filter($search, $wp_query) {
51 global $wpdb, $wpbot_search_word_variations;
52
53 // Only apply if it's the main search query and our variations are set
54 if (empty($wpbot_search_word_variations) || !$wp_query->is_search || !$wp_query->is_main_query()) {
55 return $search;
56 }
57
58 $search_parts_for_and = [];
59
60 foreach ($wpbot_search_word_variations as $word_variations) {
61 $search_parts_for_or = [];
62 foreach ($word_variations as $term) {
63 $term = $wpdb->esc_like($term);
64 // Search in both post_title and post_content
65 $search_parts_for_or[] = "(({$wpdb->posts}.post_title LIKE '%{$term}%') OR ({$wpdb->posts}.post_content LIKE '%{$term}%'))";
66 }
67 if (!empty($search_parts_for_or)) {
68 $search_parts_for_and[] = '(' . implode(' OR ', $search_parts_for_or) . ')';
69 }
70 }
71
72 if (!empty($search_parts_for_and)) {
73 // Completely replace the default search clause generated by WP_Query's 's' parameter
74 // This ensures our flexible matching takes precedence.
75 $search = ' AND ' . implode(' AND ', $search_parts_for_and);
76 }
77
78 return $search;
79 }
80 }
81
82 function wpbo_search_site() {
83 // Verify nonce for security
84 $nonce = isset($_POST['security']) ? sanitize_text_field(wp_unslash($_POST['security'])) : (isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '');
85 if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) && ! wp_verify_nonce( $nonce, 'qcsecretbotnonceval123qc' ) ) {
86 wp_send_json_error( array( 'status' => 'fail', 'message' => 'Security check failed.' ) );
87 wp_die();
88 }
89
90 global $wpdb;
91 // Limit results to 5 items.
92 $limit = 5;
93 $response = array('status' => 'fail', 'html' => ''); // Initialize response array
94
95 // Get default language for load more button text and other language-specific checks.
96 $default_language = get_locale();
97
98 if(get_option('enable_wp_chatbot_post_content') == 1){
99 $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : '';
100 $all_word_variations = _wpbot_generate_word_variations($keyword);
101
102 // Temporarily store the variations for the filter
103 global $wpbot_search_word_variations;
104 $wpbot_search_word_variations = $all_word_variations;
105
106 // Add the custom search filter
107 add_filter('posts_search', 'wpbot_flexible_search_filter', 10, 2);
108
109 $enable_post_types = array( 'post', 'page', 'product' );
110 $total_items = $limit;
111 $query_arg = array(
112 'post_type' => $enable_post_types,
113 'post_status' => 'publish',
114 'posts_per_page'=> $total_items,
115 's' => stripslashes( $keyword ), // Keep original for WP_Query to initiate search, filter will override
116 'paged' => 1,
117 'suppress_filters' => false // Crucial for filters to run
118 );
119 $resultss = new WP_Query( $query_arg );
120 $results = $resultss->posts;
121
122 // Remove the filter after the query to avoid affecting other queries
123 remove_filter('posts_search', 'wpbot_flexible_search_filter', 10);
124 unset($wpbot_search_word_variations); // Clean up global
125 }else{
126 $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : '';
127 $all_word_variations = _wpbot_generate_word_variations($keyword);
128
129 $sql_parts_for_and = [];
130 $sql_params = [];
131
132 foreach ($all_word_variations as $word_variations) {
133 $sql_parts_for_or = [];
134 foreach ($word_variations as $term) {
135 $sql_parts_for_or[] = "post_title LIKE %s";
136 $sql_params[] = '%' . $wpdb->esc_like($term) . '%';
137 }
138 if (!empty($sql_parts_for_or)) {
139 $sql_parts_for_and[] = '(' . implode(' OR ', $sql_parts_for_or) . ')';
140 }
141 }
142
143 $where_clause = '';
144 if (!empty($sql_parts_for_and)) {
145 $where_clause = ' AND ' . implode(' AND ', $sql_parts_for_and);
146 } else {
147 // Fallback to original behavior if no variations generated (e.g., empty keyword)
148 $where_clause = " AND (post_title LIKE %s)";
149 $sql_params[] = '%' . $wpdb->esc_like($keyword) . '%';
150 }
151
152 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
153 $results = $wpdb->get_results( $wpdb->prepare(
154 "SELECT * FROM " . $wpdb->prefix . "posts WHERE post_status = %s " . $where_clause . " ORDER BY ID DESC LIMIT %d",
155 array_merge(['publish'], $sql_params, [$limit])
156 ) );
157 }
158
159 if(!empty( $results )){
160
161 $response['status'] = 'success';
162 $response['html'] = '<div class="wpb-search-result">';
163 $total_post = 0;
164 $responses = '';
165
166 foreach ( $results as $result ) {
167 $featured_img_url = get_the_post_thumbnail_url( $result->ID, 'full' );
168 $excerpt = '';
169 if ( isset( $result->ID ) ) {
170 $post_obj = get_post( $result->ID );
171 if ( $post_obj ) {
172 if ( has_excerpt( $result->ID ) ) {
173 $excerpt = get_the_excerpt( $result->ID );
174 } else {
175 $content = $post_obj->post_content;
176
177 // Remove ALL WPBakery shortcodes (paired + self-closing)
178 $content = preg_replace( '/\[vc_[^\]]*\](.*?)\[\/vc_[^\]]*\]/s', '$1', $content ); // paired
179 $content = preg_replace( '/\[vc_[^\]]*\]/s', '', $content ); // self-closing
180 $content = preg_replace('/\[\/?[\w\-]+[^\]]*\]/', '', $content);
181 // Extra: remove any leftover [] shortcodes (just in case)
182 $content = strip_shortcodes( $content );
183
184 // Run through normal WP content filters
185 $content_filtered = apply_filters( 'the_content', $content );
186
187 // Strip HTML tags, then trim
188 $excerpt = wp_trim_words( wp_strip_all_tags( $content_filtered ), 20, '...' );
189 }
190
191
192 }
193 }
194
195 $total_post = $total_post + 1;
196 $responses .='<div class="wpbot_card_wraper">';
197 $responses .= '<div class="wpbot_card_image '.($result->post_type=='product'?'wp-chatbot-product':'').' '.( empty($featured_img_url) ?'wpbot_card_image_saas':'').'"><a href="'.esc_url(get_permalink($result->ID)).'" target="_blank" '.($result->post_type=='product'?'wp-chatbot-pid="'.$result->ID.'"':'').'>';
198 if( !empty($featured_img_url) ){
199 $responses .= '<img src="'.esc_url_raw($featured_img_url).'" />';
200 }
201 $responses .= '<div class="wpbot_card_caption '.( empty($featured_img_url) ?'wpbot_card_caption_saas':'').'">';
202 $responses .= '<p><span style="padding: 0 5px;color: #1d73b4;display: inline-block;margin: 0 5px 0 0;width: 18px;height: 18px;border-radius: 50%;font-size: 20px;line-height: 22px;"> ✓ </span> '.esc_html($result->post_title).'</p>';
203 $responses .= '<p>'.esc_html(wp_strip_all_tags($excerpt)).'</p>';
204 if($result->post_type=='product'){
205 if ( class_exists( 'WooCommerce' ) ) {
206 if ( $result->ID ) {
207 $product = wc_get_product( $result->ID );
208 $responses .= '<p class="wpbot_product_price">'.get_woocommerce_currency_symbol().$product->get_price_html().'</p>';
209 }
210 }
211 }
212 $responses .= '</div>';
213 $responses .= '</a></div>';
214 $responses .='</div>';
215
216 }
217 $response['html'] .= $responses;
218 $response['html'] .='</div>';
219 if($total_post >= $limit ){ // Use $limit for consistency
220 $load_more = maybe_unserialize(get_option('qlcd_wp_chatbot_load_more_search'));
221
222 $response['html'] .='<button type="button" class="wp-chatbot-loadmore" data-search-type="default-wp-search" data-keyword="'.esc_attr($keyword).'" data-page="2">'. ( !empty($load_more) && isset($load_more[$default_language]) ? $load_more[$default_language] : 'Load More').' <span id="wp-chatbot-loadmore-loader" class="wp-chatbot-loadmore-loader"></span></button>';
223
224 }
225 }else{
226 // Fuzzy search if initial search yields no results
227 $response['status'] = 'success';
228
229 // Use the same word variation logic for fuzzy search
230 $all_word_variations_for_fuzzy = _wpbot_generate_word_variations($keyword);
231
232 $unique_posts = array(); // Store unique post objects
233 $seen_ids = array(); // Keep track of seen post IDs
234
235 // Iterate through each word's variations to find matching posts
236 foreach ( $all_word_variations_for_fuzzy as $word_variations ) {
237 foreach ($word_variations as $term) {
238 $term = $wpdb->esc_like( $term );
239
240 $term_results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
241 $wpdb->prepare("SELECT * FROM ". $wpdb->prefix."posts WHERE post_type IN (%s, %s) AND post_status = %s AND (post_title LIKE %s) ORDER BY ID DESC", 'page', 'post', 'publish', '%'. $term .'%')
242 );
243
244 foreach ($term_results as $res) {
245 if (!in_array($res->ID, $seen_ids)) {
246 $unique_posts[] = $res;
247 $seen_ids[] = $res->ID;
248 }
249 }
250 }
251 }
252 $results = $unique_posts; // Now $results contains unique WP_Post objects
253
254 if( !empty( $results) ){
255 $response['html'] = '<div class="wpb-search-result">';
256 $total_post = 0;
257 $responses = '';
258 $selected_lan = get_option('qlcd_wp_chatbot_default_language');
259
260 foreach ($results as $value) { // $value is a single post object here
261 if(!empty($value->guid)){
262 $post_id = $value->ID;
263 $current_featured_img_url = get_the_post_thumbnail_url( $post_id, 'full' );
264
265 // Corrected URL segment parsing for language check
266 $url_path = wp_parse_url(get_permalink($post_id), PHP_URL_PATH);
267 $url_segments = array_filter(explode('/',$url_path));
268
269 // Assuming the language slug is the first non-empty segment of the URL path.
270 $first_segment = !empty($url_segments) ? reset($url_segments) : '';
271
272 // If $selected_lan is empty, the language check is effectively skipped.
273 $language_match = empty($selected_lan) || ($first_segment == $selected_lan);
274
275 if($language_match){
276 $total_post = $total_post + 1;
277 $responses .='<div class="wpbot_card_wraper">';
278 $responses .= '<div class="wpbot_card_image '.(empty($current_featured_img_url)?'wpbot_card_image_saas':'').'"><a href="'.esc_url(get_permalink($post_id)).'" target="_blank">';
279 if(!empty($current_featured_img_url)){
280 $responses .= '<img src="'.esc_url_raw($current_featured_img_url).'" />';
281 }
282 $responses .= '<div class="wpbot_card_caption '.(empty($current_featured_img_url)?'wpbot_card_caption_saas':'').'">';
283 $responses .= '<p><span style="padding: 0 5px;color: #1d73b4;display: inline-block;margin: 0 5px 0 0;width: 18px;height: 18px;border-radius: 50%;font-size: 20px;line-height: 22px;"> ✓ </span>'.esc_html($value->post_title).'</p>';
284 $responses .= '</div>';
285 $responses .= '</a></div>';
286 $responses .='</div>';
287 }
288 }
289 }
290 if($total_post > 2 ){ // This condition is different from the first block ($total_post >= $limit)
291 $load_more = maybe_unserialize(get_option('qlcd_wp_chatbot_load_more_search'));
292 $response['html'] .='<button type="button" class="wp-chatbot-loadmore2" data-search-type="default-wp-search" data-keyword="'.esc_attr($keyword).'" data-page="2">'. ( !empty($load_more) && isset($load_more[$default_language]) ? $load_more[$default_language] : 'Load More').' <span id="wp-chatbot-loadmore-loader" class="wp-chatbot-loadmore-loader"></span></button>';
293 $response['status'] = 'success';
294 }else{
295 $response['status'] = 'fail';
296 }
297
298 $response['html'] .= $responses;
299 $response['html'] .='</div>';
300 } else {
301 $response['status'] = 'fail'; // No results from fuzzy search either
302 }
303 }
304 echo wp_json_encode($response);
305 wp_die();
306 }
307
308
309 add_action( 'wp_ajax_wpbo_search_site', 'wpbo_search_site' );
310 add_action( 'wp_ajax_nopriv_wpbo_search_site', 'wpbo_search_site' );
311
312 if ( ! function_exists( 'qcld_wpbot_modified_keyword' ) ) {
313 function qcld_wpbot_modified_keyword( $keyword ) {
314 $keyword = rtrim( $keyword, '!' );
315 $pattern = '/[?\/]/';
316 $strings = preg_split( $pattern, $keyword );
317 $strings = array_filter( array_map( 'trim', $strings ) );
318 $keyword = rtrim( $strings[0], '!' );
319 return htmlspecialchars_decode( $keyword );
320 }
321 }
322
323 add_action( 'wp_ajax_wpbo_search_responseby_intent', 'qcld_wpbo_search_responseby_intent' );
324 add_action( 'wp_ajax_nopriv_wpbo_search_responseby_intent', 'qcld_wpbo_search_responseby_intent' );
325
326 if( !function_exists( 'wpbo_search_site_pagination' )){
327
328 function wpbo_search_site_pagination() {
329 global $wpdb;
330
331 // Verify nonce for security
332 $p_nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
333 if ( ! wp_verify_nonce( $p_nonce, 'wp_chatbot' ) && ! wp_verify_nonce( $p_nonce, 'qcsecretbotnonceval123qc' ) ) {
334 wp_send_json_error( array( 'message' => 'Security check failed' ) );
335 wp_die();
336 }
337
338 // Sanitize and validate inputs
339 $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : '';
340 $post_type = isset( $_POST['type'] ) ? sanitize_text_field(wp_unslash($_POST['type'])) : 'post';
341 $page = isset($_POST['page']) ? absint( wp_unslash($_POST['page']) ) : 0;
342
343 // Validate post type against allowed types
344 $allowed_post_types = array( 'post', 'page', 'product' );
345 if ( ! in_array( $post_type, $allowed_post_types, true ) ) {
346 $post_type = 'post';
347 }
348
349 $enable_post_types = get_option( 'wppt_post_types' );
350 $load_more = maybe_unserialize( get_option( 'qlcd_wp_chatbot_load_more' ) );
351
352 if ( is_array( $load_more ) && isset( $load_more[ get_locale() ] ) ) {
353 $load_more = $load_more[ get_locale() ];
354 }
355 if ( is_array( $load_more ) ) {
356 $load_more = $load_more[ array_rand( $load_more ) ];
357 }
358 $searchlimit = ( get_option( 'wppt_number_of_result' ) == '' ? 5 : absint( get_option( 'wppt_number_of_result' ) ) );
359 $orderby = ( get_option( 'wppt_result_orderby' ) == '' ? 'none' : get_option( 'wppt_result_orderby' ) );
360 $order = ( get_option( 'wppt_result_order' ) == '' ? 'ASC' : get_option( 'wppt_result_order' ) );
361 $thumb = ( get_option( 'wpbot_search_image_size' ) ? get_option( 'wpbot_search_image_size' ) : 'thumbnail' );
362 // order by setup
363 $new_window = get_option( 'wpbot_search_result_new_window' );
364
365 $total_items = absint( get_option( 'wppt_number_of_result' ) );
366 if ( $total_items < 1 ) {
367 $total_items = 5;
368 }
369
370 $searchkeyword = qcld_wpbot_modified_keyword( $keyword );
371
372 $response = array();
373 $response['status'] = 'fail';
374 $response['html'] = '';
375
376 // Use prepared statements to prevent SQL injection
377 if ( get_option( 'active_advance_query' ) != '1' ) {
378 // Simple query - search in post_title only
379 $total_results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
380 $wpdb->prepare(
381 "SELECT * FROM {$wpdb->prefix}posts
382 WHERE post_type = %s
383 AND post_status = 'publish'
384 AND post_title LIKE %s
385 ORDER BY ID DESC",
386 $post_type,
387 '%' . $wpdb->esc_like( $searchkeyword ) . '%'
388 ));
389 } else {
390 // Advanced query - search in both post_title and post_content
391 $total_results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
392 $wpdb->prepare(
393 "SELECT * FROM " . $wpdb->prefix . "posts
394 WHERE post_type = %s
395 AND post_status = %s
396 AND (post_title REGEXP %s OR post_content REGEXP %s)
397 ORDER BY ID DESC",
398 $post_type,
399 'publish',
400 '[[:<:]]' . $searchkeyword . '[[:>:]]',
401 '[[:<:]]' . $searchkeyword . '[[:>:]]'
402 ));
403 }
404
405 if ( ! empty( $total_results ) ) {
406
407 // Validate and sanitize orderby parameter
408 $valid_orderby = array( 'title', 'date', 'modified', 'none', 'rand' );
409 if ( ! in_array( $orderby, $valid_orderby, true ) ) {
410 $orderby = 'none';
411 }
412
413 if ( $orderby == 'title' ) {
414 $orderby = 'post_title';
415 }
416 if ( $orderby == 'date' ) {
417 $orderby = 'post_date';
418 }
419 if ( $orderby == 'modified' ) {
420 $orderby = 'post_modified';
421 }
422
423 // Validate order parameter
424 $order = strtoupper( $order );
425 if ( ! in_array( $order, array( 'ASC', 'DESC' ), true ) ) {
426 $order = 'ASC';
427 }
428
429 // Build query with pagination
430 $offset = absint( $total_items * $page );
431
432 if ( get_option( 'active_advance_query' ) != '1' ) {
433 if ( $orderby != 'none' && $orderby != 'rand' ) {
434 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
435 $results = $wpdb->get_results( $wpdb->prepare(
436 "SELECT * FROM {$wpdb->prefix}posts
437 WHERE post_type = %s
438 AND post_status = 'publish'
439 AND post_title LIKE %s
440 ORDER BY {$orderby} {$order}
441 LIMIT %d, %d",
442 $post_type,
443 '%' . $wpdb->esc_like( $searchkeyword ) . '%',
444 $offset,
445 $total_items
446 ) );
447 } else {
448 $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
449 $wpdb->prepare(
450 "SELECT * FROM {$wpdb->prefix}posts
451 WHERE post_type = %s
452 AND post_status = 'publish'
453 AND post_title LIKE %s
454 ORDER BY ID DESC
455 LIMIT %d, %d",
456 $post_type,
457 '%' . $wpdb->esc_like( $searchkeyword ) . '%',
458 $offset,
459 $total_items
460 ));
461 }
462 } else {
463 if ( $orderby != 'none' && $orderby != 'rand' ) {
464 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
465 $results = $wpdb->get_results( $wpdb->prepare(
466 "SELECT * FROM " . $wpdb->prefix . "posts
467 WHERE post_type = %s
468 AND post_status = %s
469 AND (post_title REGEXP %s OR post_content REGEXP %s)
470 ORDER BY " . $orderby . " " . $order . "
471 LIMIT %d, %d",
472 $post_type,
473 'publish',
474 '[[:<:]]' . $searchkeyword . '[[:>:]]',
475 '[[:<:]]' . $searchkeyword . '[[:>:]]',
476 $offset,
477 $total_items
478 ) );
479 } else {
480 $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
481 $wpdb->prepare(
482 "SELECT * FROM " . $wpdb->prefix . "posts
483 WHERE post_type = %s
484 AND post_status = %s
485 AND (post_title REGEXP %s OR post_content REGEXP %s)
486 ORDER BY ID DESC
487 LIMIT %d, %d",
488 $post_type,
489 'publish',
490 '[[:<:]]' . $searchkeyword . '[[:>:]]',
491 '[[:<:]]' . $searchkeyword . '[[:>:]]',
492 $offset,
493 $total_items
494 ));
495 }
496 }
497 } else {
498 if ( class_exists( 'SitePress' ) ) {
499 global $sitepress;
500 $selected_lan = isset( $_POST['language'] ) ? sanitize_text_field(wp_unslash($_POST['language'])) : '';
501 $selected_lan = explode( '_', $selected_lan );
502 if ( ! empty( $selected_lan[0] ) ) {
503 $sitepress->switch_lang( $selected_lan[0], true );
504 }
505 }
506
507 $query_arg = array(
508 'post_type' => $post_type,
509 'post_status' => 'publish',
510 'posts_per_page' => $total_items,
511 's' => stripslashes( $keyword ),
512 'paged' => ( $page + 1 ),
513 'orderby' => $orderby,
514 );
515
516 if ( class_exists( 'SitePress' ) ) {
517 global $sitepress;
518 $selected_lan = isset( $_POST['language'] ) ? sanitize_text_field(wp_unslash($_POST['language'])) : '';
519 $selected_lan = explode( '_', $selected_lan );
520 if ( ! empty( $selected_lan[0] ) ) {
521 $sitepress->switch_lang( $selected_lan[0], true );
522 }
523 }
524
525 $query_arg['suppress_filters'] = true;
526 if ( $orderby != 'none' && $orderby != 'rand' ) {
527 $query_arg['order'] = $order;
528 }
529
530 $totalresults = new WP_Query(
531 array(
532 'post_type' => $post_type,
533 'post_status' => 'publish',
534 's' => stripslashes( $keyword ),
535 )
536 );
537 $resultss = new WP_Query( $query_arg );
538 $total_results = $totalresults->posts;
539 $resultss = new WP_Query( $query_arg );
540 $results = $resultss->posts;
541 }
542
543 if ( ! empty( $total_results ) ) {
544
545 $selected_lan = isset( $_POST['language'] ) ? sanitize_text_field(wp_unslash($_POST['language'])) : '';
546 $urlss = get_option( 'wpbotml_url_urls' ) ? get_option( 'wpbotml_url_urls' ) : '';
547 $imagesize = ( get_option( 'wpbot_search_image_size' ) != '' ? get_option( 'wpbot_search_image_size' ) : 'thumbnail' );
548
549 $response['html'] .= '<div class="wpb-search-result">';
550
551 foreach ( $total_results as $result ) {
552
553 if ( $result->post_type == 'product' ) {
554 if ( ! class_exists( 'WooCommerce' ) ) {
555 continue;
556 }
557 }
558
559 $featured_img_url = get_the_post_thumbnail_url( $result->ID, $thumb );
560 $excerpt = '';
561 if ( isset( $result->ID ) ) {
562 $post_obj = get_post( $result->ID );
563 if ( $post_obj ) {
564 if ( has_excerpt( $result->ID ) ) {
565 $excerpt = get_the_excerpt( $result->ID );
566 } else {
567 $content = $post_obj->post_content;
568
569 // Remove ALL WPBakery shortcodes (paired + self-closing)
570 $content = preg_replace( '/\[vc_[^\]]*\](.*?)\[\/vc_[^\]]*\]/s', '$1', $content ); // paired
571 $content = preg_replace( '/\[vc_[^\]]*\]/s', '', $content ); // self-closing
572 $content = preg_replace('/\[\/?[\w\-]+[^\]]*\]/', '', $content);
573 // Extra: remove any leftover [] shortcodes (just in case)
574 $content = strip_shortcodes( $content );
575
576 // Run through normal WP content filters
577 $content_filtered = apply_filters( 'the_content', $content );
578
579 // Strip HTML tags, then trim
580 $excerpt = wp_trim_words( wp_strip_all_tags( $content_filtered ), 20, '...' );
581 }
582 }
583 }
584
585
586 $response['html'] .= '<div class="wpbot_card_wraper">';
587 $response['html'] .= '<div class="wpbot_card_image ' . ( $result->post_type == 'product' ? 'wp-chatbot-product' : '' ) . ' ' . ( $featured_img_url == '' ? 'wpbot_card_image_saas' : '' ) . '"><a href="' . esc_url( get_permalink( $result->ID ) ) . '" ' . ( $new_window == 1 ? 'target="_blank"' : '' ) . ' ' . ( $result->post_type == 'product' ? 'wp-chatbot-pid="' . absint( $result->ID ) . '"' : '' ) . '>';
588 if ( $featured_img_url != '' ) {
589 $response['html'] .= '<img src="' . esc_url_raw( $featured_img_url ) . '" />';
590 }
591
592 $response['html'] .= '<div class="wpbot_card_caption ' . ( $featured_img_url == '' ? 'wpbot_card_caption_saas' : '' ) . '">';
593 $response['html'] .= '<p class="wpbot_card_caption_title"><span style="padding: 0 5px;color: #1d73b4;display: inline-block;margin: 0 5px 0 0;width: 18px;height: 18px;border-radius: 50%;font-size: 20px;line-height: 22px;"> ✓ </span> ' . esc_html( $result->post_title ) . '</p>';
594 $response['html'] .= '<p class="wpbot_card_description">' . esc_html( $excerpt ) . '</p>';
595 if ( $result->post_type == 'product' ) {
596 if ( class_exists( 'WooCommerce' ) ) {
597 $product = wc_get_product( $result->ID );
598 $response['html'] .= '<p class="wpbot_product_price">' . get_woocommerce_currency_symbol() . $product->get_price_html() . '</p>';
599 }
600 }
601 $response['html'] .= '</div>';
602 $response['html'] .= '</a></div>';
603 $response['html'] .= '</div>';
604
605 }
606
607
608 $response['html'] .= '</div>';
609 $response['status'] = 'success';
610
611 }
612 wp_reset_query();
613
614 if ( $response['status'] != 'success' ) {
615 $texts = maybe_unserialize( get_option( 'qlcd_wp_chatbot_no_result' ) );
616 $selected_lan = isset( $_POST['language'] ) ? sanitize_text_field(wp_unslash($_POST['language'])) : '';
617 if ( ! empty( $texts ) && is_array( $texts ) && isset( $texts[ $selected_lan ][0] ) ) {
618 $texts = str_replace( "\'", "'", $texts[ $selected_lan ][0] );
619 $response['html'] = array( $texts );
620 } else {
621 $response['html'] = array( 'No results found' );
622 }
623 }
624 wp_send_json( $response );
625 die();
626 }
627
628 }
629
630
631
632 add_action( 'wp_ajax_wpbo_search_site_pagination', 'wpbo_search_site_pagination' );
633 add_action( 'wp_ajax_nopriv_wpbo_search_site_pagination', 'wpbo_search_site_pagination' );
634 function qcld_wpbo_search_responseby_intent(){
635
636 global $wpdb;
637
638 $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : '';
639
640 $table = $wpdb->prefix.'wpbot_response';
641
642 $result = $wpdb->get_row( $wpdb->prepare("SELECT `response` FROM %i WHERE 1 and `intent` = %s", $table, $keyword) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
643
644 $response = array('status'=>'fail');
645
646 if(!empty($result)){
647
648 $response['status'] = 'success';
649 $response['html'] = $result->response;
650
651 }
652
653 echo wp_json_encode($response);
654
655 die();
656
657 }
658 function qcld_wb_chatbot_email_subscription() {
659
660 global $wpdb;
661 $table = $wpdb->prefix . 'wpbot_subscription';
662
663 $name = sanitize_text_field( $_POST['name'] );// phpcs:ignore WordPress.Security.NonceVerification.Missing
664 $email = sanitize_email( $_POST['email'] );// phpcs:ignore WordPress.Security.NonceVerification.Missing
665 $url = esc_url_raw( $_POST['url'] );// phpcs:ignore WordPress.Security.NonceVerification.Missing
666 $user_agent = sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] );// phpcs:ignore WordPress.Security.NonceVerification.Missing
667
668 if ( isset( $_POST['phone'] ) && $_POST['phone'] != '' ) {// phpcs:ignore WordPress.Security.NonceVerification.Missing
669
670 $phone = sanitize_text_field( $_POST['phone'] );// phpcs:ignore WordPress.Security.NonceVerification.Missing
671 if ( $email != '' ) {
672
673 $email_exists = $wpdb->get_row( $wpdb->prepare( "select * from %i where 1 and email = %s", $table, $email ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
674 if ( ! empty( $email_exists ) ) {
675 $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
676 $table,
677 array(
678 'phone' => $phone,
679 ),
680 array( 'email' => $email ),
681 array(
682 '%s',
683 ),
684 array( '%s' )
685 );
686 } else {
687 $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
688 $table,
689 array(
690 'date' => current_time( 'mysql' ),
691 'name' => $name,
692 'email' => $email,
693 'phone' => $phone,
694 'url' => $url,
695 'user_agent' => $user_agent,
696 )
697 );
698 }
699 } else {
700 $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
701 $table,
702 array(
703 'date' => current_time( 'mysql' ),
704 'name' => $name,
705 'email' => $email,
706 'phone' => $phone,
707 'url' => $url,
708 'user_agent' => $user_agent,
709 )
710 );
711 }
712 $response['status'] = 'success';
713 echo json_encode( $response );
714 die();
715
716 } else {
717
718 $response = array();
719 $response['status'] = 'fail';
720
721 $email_exists = $wpdb->get_row( $wpdb->prepare( "select * from %i where 1 and email = %s", $table, $email ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
722 if ( empty( $email_exists ) ) {
723
724 $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
725 $table,
726 array(
727 'date' => current_time( 'mysql' ),
728 'name' => $name,
729 'email' => $email,
730 'url' => $url,
731 'user_agent' => $user_agent,
732 )
733 );
734 $response['status'] = 'success';
735 $texts = maybe_unserialize( get_option( 'qlcd_wp_email_subscription_success' ) );
736 if ( is_array( $texts ) && isset( $texts[ get_wpbot_locale() ] ) ) {
737 $texts = $texts[ get_wpbot_locale() ];
738 }
739 $response['msg'] = $texts[ array_rand( $texts ) ];
740
741 } else {
742 $texts = maybe_unserialize( get_option( 'qlcd_wp_email_already_subscribe' ) );
743
744 if ( is_array( $texts ) && isset( $texts[ get_wpbot_locale() ] ) ) {
745 $texts = $texts[ get_wpbot_locale() ];
746 }
747
748 $response['msg'] = $texts[ array_rand( $texts ) ];
749 }
750
751 do_action( 'qcld_mailing_list_subscription_success', $name, $email );
752
753 if ( get_option( 'qc_email_subscription_offer' ) == 1 ) {
754
755 $response['status'] = 'success';
756
757 if ( get_option( 'qlcd_wp_email_subscription_offer_subject' ) ) {
758 $offertextss = maybe_unserialize( get_option( 'qlcd_wp_email_subscription_offer_subject' ) );
759 if ( is_array( $offertextss ) && isset( $offertextss[ get_wpbot_locale() ] ) ) {
760 $offertextss = $offertextss[ get_wpbot_locale() ];
761 }
762 $subject = str_replace( '%%username%%', $name, $offertextss[ array_rand( $offertextss ) ] );
763
764 } else {
765 $subject = 'Email subscription offer';
766 }
767
768 // Extract Domain
769 $url = get_site_url();
770 $url = parse_url( $url );
771 $domain = $url['host'];
772 $toEmail = $email;
773 $fromEmail = 'wordpress@' . $domain;
774 $fromname = ( get_option( 'qlcd_wp_chatbot_from_name' ) ? get_option( 'qlcd_wp_chatbot_from_name' ) : 'WordPress' );
775
776 if ( get_option( 'qlcd_wp_chatbot_from_email' ) && get_option( 'qlcd_wp_chatbot_from_email' ) != '' ) {
777 $fromEmail = get_option( 'qlcd_wp_chatbot_from_email' );
778 }
779
780 $replyto = $fromEmail;
781
782 if ( get_option( 'qlcd_wp_chatbot_reply_to_email' ) && get_option( 'qlcd_wp_chatbot_reply_to_email' ) != '' ) {
783 $replyto = get_option( 'qlcd_wp_chatbot_reply_to_email' );
784 }
785
786 // Starting messaging and status.
787 $offertexts = maybe_unserialize( get_option( 'qlcd_wp_email_subscription_offer' ) );
788 if ( is_array( $offertexts ) && isset( $offertexts[ get_wpbot_locale() ] ) ) {
789 $offertexts = $offertexts[ get_wpbot_locale() ];
790 }
791 // build email body.
792 $bodyContent = '';
793 $bodyContent .= '<p><strong>' . esc_html__( 'Offer Details', 'wpchatbot' ) . ':</strong></p><hr>';
794 $bodyContent .= '<p>' . str_replace( '%%username%%', $name, $offertexts[ array_rand( $offertexts ) ] ) . '</p>';
795 $bodyContent .= '<p>' . esc_html__( 'Mail Generated on', 'wpchatbot' ) . ': ' . current_time( 'F j, Y, g:i a' ) . '</p>';
796 $to = $toEmail;
797 $body = $bodyContent;
798
799 $headers = array();
800 $headers[] = 'Content-Type: text/html; charset=UTF-8';
801 $headers[] = 'From: ' . $fromname . ' <' . $fromEmail . '>';
802 $headers[] = 'Reply-To: ' . $fromname . ' <' . ( $replyto ) . '>';
803 wp_mail( $to, $subject, $body, $headers );
804 $response['email'] = 'Send! to ' . $to . ' from ' . $fromEmail;
805
806 }
807
808 echo json_encode( $response );
809
810 die();
811 }
812 }
813
814 add_action( 'wp_ajax_qcld_wb_chatbot_email_subscription', 'qcld_wb_chatbot_email_subscription' );
815 add_action( 'wp_ajax_nopriv_qcld_wb_chatbot_email_subscription', 'qcld_wb_chatbot_email_subscription' );
816 add_action( 'admin_post_wpbprint.csv', 'qcld_wpb_export_email_csv' );
817
818 if ( ! function_exists( 'qcld_wpbd_array2csv' ) ) {
819 function qcld_wpbd_array2csv( array &$array ) {
820 if ( count( $array ) == 0 ) {
821 return null;
822 }
823 ob_start();
824 $df = fopen( 'php://output', 'w' );
825 fputcsv( $df, array( 'Name', 'Email' ), ',', '"', '\\' );
826 foreach ( $array as $row ) {
827 fputcsv( $df, $row, ',', '"', '\\' );
828 }
829 fclose( $df );
830 return ob_get_clean();
831 }
832 }
833
834 function qcld_wpb_export_email_csv() {
835 global $wpdb;
836 $table = $wpdb->prefix . 'wpbot_subscription';
837
838 if ( ! current_user_can( 'manage_options' ) ) {
839 return;
840 }
841
842 $emails = $wpdb->get_results( $wpdb->prepare( "select * from %i WHERE %d", $table, 1 ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
843 $childArray = array();
844 foreach ( $emails as $email ) {
845 $innerArray = array();
846 $innerArray[0] = $email->name;
847 $innerArray[1] = $email->email;
848 array_push( $childArray, $innerArray );
849 }
850 qcld_wpbd_download_send_headers( 'wpb_email_lists_' . current_time( 'Y-m-d' ) . '.csv' );
851
852 $result = qcld_wpbd_array2csv( $childArray );
853
854 print $result; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
855 die();
856 }
857 function qcld_wpbd_download_send_headers( $filename ) {
858 // disable caching
859 $now = gmdate( 'D, d M Y H:i:s' );
860 header( 'Expires: Tue, 03 Jul 2001 06:00:00 GMT' );
861 header( 'Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate' );
862 header( "Last-Modified: {$now} GMT" );
863
864 // force download
865 header( 'Content-Type: application/force-download' );
866
867 // disposition / encoding on response body
868 header( "Content-Disposition: attachment;filename={$filename}" );
869 header( 'Content-Transfer-Encoding: binary' );
870 }
871 add_action( 'wp_ajax_wpbo_search_response_catlist', 'wpbo_search_response_catlist' );
872 add_action( 'wp_ajax_nopriv_wpbo_search_response_catlist', 'wpbo_search_response_catlist' );
873
874 if( !function_exists( 'wpbo_search_response_catlist' )){
875 function wpbo_search_response_catlist(){
876 global $wpdb;
877 $table = $wpdb->prefix.'wpbot_response_category';
878 $status = array('status'=>'fail');
879 $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM %i", $table)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
880 $response_result = array();
881
882 if(!empty($results)){
883 foreach($results as $result){
884
885 $response_result[] = array('name'=>$result->name);
886
887 }
888 }
889
890 if(!empty($response_result)){
891
892 $status = array('status'=>'success', 'data'=>$response_result);
893
894
895 }
896
897 echo wp_json_encode($status);
898
899 die();
900
901 }
902 }
903 add_action( 'wp_ajax_wpbo_search_response', 'qcld_wpbo_search_response' );
904 add_action( 'wp_ajax_nopriv_wpbo_search_response', 'qcld_wpbo_search_response' );
905
906
907
908 function qcld_wpbo_search_response(){
909
910 global $wpdb;
911 $keyword = isset( $_POST['keyword'] ) ? (sanitize_text_field(wp_unslash($_POST['keyword']))) : '';
912 $strid = isset( $_POST['strid'] ) ? (sanitize_text_field(wp_unslash($_POST['strid']))) : '';
913 $table = $wpdb->prefix.'wpbot_response';
914
915
916 $response_result = array();
917
918 $status = array('status'=>'fail', 'multiple'=>false);
919 $field = "ID";
920 if(($strid != '') && empty($response_result)){
921 $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM %i WHERE %i = %d",$table,$field,$strid)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
922 if(!empty($results)){
923 foreach($results as $result){
924
925 $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
926
927 }
928 }
929 }
930 $field = "query";
931 $results = $wpdb->get_results( $wpdb->prepare("SELECT `id`, `query`, `response` FROM %i WHERE 1 and %i = %s", $table, $field,$keyword) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
932
933
934 if(!empty($results)){
935 foreach($results as $result){
936
937 $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
938
939 }
940 }
941
942 $field = "category";
943 if(empty($response_result)){
944 $results = $wpdb->get_results( $wpdb->prepare("SELECT `id`, `query`, `response` FROM %i WHERE 1 and %i = %s", $table,$field, $keyword) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
945
946
947 if(!empty($results)){
948 foreach($results as $result){
949 $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
950 }
951 if(count($response_result)>1){
952 $status = array('status'=>'success','category'=> true, 'multiple'=>true, 'data'=>$response_result);
953 }else{
954 $status = array('status'=>'success', 'category'=> true, 'multiple'=>false, 'data'=>$response_result);
955 }
956
957 echo wp_json_encode($status);
958
959 die();
960 }
961
962 }
963
964 if(class_exists('Qcld_str_pro')){
965 if(get_option('qc_bot_str_remove_stopwords') && get_option('qc_bot_str_remove_stopwords')==1){
966 $keyword = qcld_strpro_remove_stopwords($keyword);
967 }
968 }
969
970
971 if(empty($response_result)){
972
973 $fields = get_option('qc_bot_str_fields');
974
975 $allowed_fields = array('query', 'keyword', 'response');
976 $valid_fields = array();
977
978 if($fields && !empty($fields) && is_array($fields)){
979 foreach($fields as $field){
980 if(in_array($field, $allowed_fields)){
981 $valid_fields[] = '`' . $field . '`';
982 }
983 }
984 }
985
986 if(!empty($valid_fields)){
987 $qfields = implode(', ', $valid_fields);
988 }else{
989 $qfields = '`query`,`keyword`,`response`';
990 }
991
992
993
994 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
995 $results = $wpdb->get_results( $wpdb->prepare("SELECT `id`, `query`, `response`, MATCH($qfields) AGAINST(%s IN NATURAL LANGUAGE MODE) as score FROM %i WHERE MATCH($qfields) AGAINST(%s IN NATURAL LANGUAGE MODE) order by score desc limit 15",$keyword,$table,$keyword) );
996
997 $weight = get_option('qc_bot_str_weight')!=''?get_option('qc_bot_str_weight'):'0.4';
998
999 if(!empty($results)){
1000 $max_score = max(array_column($results, 'score'));
1001 if ($max_score <= 0) {
1002 $max_score = 1; // Set to 1 to avoid division by zero
1003 }
1004 foreach($results as $result){
1005 if(($result->score/$max_score) >= $weight){
1006 $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>$result->score);
1007 }
1008 }
1009 }
1010 }
1011 $field = "keyword";
1012 if( empty( $response_result ) ){
1013
1014 $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM %i WHERE %i REGEXP %s", $table,$field,$keyword)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1015
1016
1017 if(!empty($results)){
1018 foreach($results as $result){
1019 $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
1020 }
1021 }
1022 }
1023 if(!empty($response_result)){
1024
1025 if(count($response_result)>1){
1026 $status = array('status'=>'success', 'multiple'=>true, 'data'=>$response_result);
1027 }else{
1028 $status = array('status'=>'success', 'multiple'=>false, 'data'=>$response_result);
1029 }
1030
1031 }
1032 if(empty($result->query)){
1033 $status = array('status'=>'fail', 'multiple'=>false, 'data'=>$response_result);
1034 }
1035 if(empty($status['data']) || (isset($status['status']) && $status['status']==='fail')){
1036 // Check for space before question mark and try again.
1037 if(preg_match('/ \?$/', $keyword)){
1038 $keyword2 = preg_replace('/ \?$/', '?', $keyword);
1039 // Try again with new keyword.
1040 // Repeat the main search logic with $keyword2.
1041 $response_result = array();
1042 $field = "query";
1043 $results = $wpdb->get_results( $wpdb->prepare("SELECT `id`, `query`, `response` FROM %i WHERE 1 and %i = %s", $table, $field, $keyword2) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1044 if(!empty($results)){
1045 foreach($results as $result){
1046 $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
1047 }
1048 if(count($response_result)>1){
1049 $status = array('status'=>'success', 'multiple'=>true, 'data'=>$response_result);
1050 }else{
1051 $status = array('status'=>'success', 'multiple'=>false, 'data'=>$response_result);
1052 }
1053 }else{
1054 $status = array('status'=>'fail', 'multiple'=>false, 'data'=>[]);
1055 }
1056 }
1057 }
1058 if(empty($status['data']) || (isset($status['status']) && $status['status']==='fail')){
1059 // Try a partial match if still nothing found.
1060 if(empty($status['data'])) {
1061 $keyword_like = '%' . preg_replace('/[\\s\\?]+/', '%', $keyword) . '%';
1062 $results = $wpdb->get_results( $wpdb->prepare("SELECT `id`, `query`, `response` FROM %i WHERE `query` LIKE %s", $table, $keyword_like) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1063 $response_result = array();
1064 if(!empty($results)){
1065 foreach($results as $result){
1066 $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
1067 }
1068 if(count($response_result)>1){
1069 $status = array('status'=>'success', 'multiple'=>true, 'data'=>$response_result);
1070 }else{
1071 $status = array('status'=>'success', 'multiple'=>false, 'data'=>$response_result);
1072 }
1073 } else {
1074 $status = array('status'=>'fail', 'multiple'=>false, 'data'=>[], 'message'=>'Sorry, I found nothing');
1075 }
1076 }
1077 }
1078 if(empty($status['data'])){
1079 $status = array('status'=>'fail', 'multiple'=>false, 'data'=>[], 'message'=>'no result found');
1080 }
1081 echo wp_json_encode($status);
1082
1083 die();
1084
1085 }
1086
1087 function qcld_strpro_remove_stopwords($keyword){
1088
1089 if(get_option('qlcd_wp_chatbot_stop_words') && get_option('qlcd_wp_chatbot_stop_words')!=''){
1090 $commonWords = explode(',', get_option('qlcd_wp_chatbot_stop_words'));
1091 return preg_replace('/\b('.implode('|',$commonWords).')\b/','',$keyword);
1092 }else{
1093 return $keyword;
1094 }
1095
1096
1097
1098 }