PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 3.4.2
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v3.4.2
8.7.8 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 All 534 releases
← All changes | qcld-wpwbot-search.php +1 -1122 8.7.03.4.2 View file →
@@ -1,1122 +1 @@
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 ) && ! empty( $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, WordPress.DB.DirectDatabaseQuery.NoCaching
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 - if ( is_array( $texts ) && ! empty( $texts ) ) {
740 - $response['msg'] = $texts[ array_rand( $texts ) ];
741 - } elseif ( is_string( $texts ) && ! empty( $texts ) ) {
742 - $response['msg'] = $texts;
743 - } else {
744 - $response['msg'] = 'Thank you for subscribing.';
745 - }
746 -
747 - } else {
748 - $texts = maybe_unserialize( get_option( 'qlcd_wp_email_already_subscribe' ) );
749 -
750 - if ( is_array( $texts ) && isset( $texts[ get_wpbot_locale() ] ) ) {
751 - $texts = $texts[ get_wpbot_locale() ];
752 - }
753 -
754 - if ( is_array( $texts ) && ! empty( $texts ) ) {
755 - $response['msg'] = $texts[ array_rand( $texts ) ];
756 - } elseif ( is_string( $texts ) && ! empty( $texts ) ) {
757 - $response['msg'] = $texts;
758 - } else {
759 - $response['msg'] = 'You have already subscribed!';
760 - }
761 - }
762 -
763 - do_action( 'qcld_mailing_list_subscription_success', $name, $email );
764 -
765 - if ( get_option( 'qc_email_subscription_offer' ) == 1 ) {
766 -
767 - $response['status'] = 'success';
768 -
769 - if ( get_option( 'qlcd_wp_email_subscription_offer_subject' ) ) {
770 - $offertextss = maybe_unserialize( get_option( 'qlcd_wp_email_subscription_offer_subject' ) );
771 - if ( is_array( $offertextss ) && isset( $offertextss[ get_wpbot_locale() ] ) ) {
772 - $offertextss = $offertextss[ get_wpbot_locale() ];
773 - }
774 - if ( is_array( $offertextss ) && ! empty( $offertextss ) ) {
775 - $subject = str_replace( '%%username%%', $name, $offertextss[ array_rand( $offertextss ) ] );
776 - } elseif ( is_string( $offertextss ) && ! empty( $offertextss ) ) {
777 - $subject = str_replace( '%%username%%', $name, $offertextss );
778 - } else {
779 - $subject = 'Email subscription offer';
780 - }
781 -
782 - } else {
783 - $subject = 'Email subscription offer';
784 - }
785 -
786 - // Extract Domain
787 - $url = get_site_url();
788 - $url = parse_url( $url );
789 - $domain = $url['host'];
790 - $toEmail = $email;
791 - $fromEmail = 'wordpress@' . $domain;
792 - $fromname = ( get_option( 'qlcd_wp_chatbot_from_name' ) ? get_option( 'qlcd_wp_chatbot_from_name' ) : 'WordPress' );
793 -
794 - if ( get_option( 'qlcd_wp_chatbot_from_email' ) && get_option( 'qlcd_wp_chatbot_from_email' ) != '' ) {
795 - $fromEmail = get_option( 'qlcd_wp_chatbot_from_email' );
796 - }
797 -
798 - $replyto = $fromEmail;
799 -
800 - if ( get_option( 'qlcd_wp_chatbot_reply_to_email' ) && get_option( 'qlcd_wp_chatbot_reply_to_email' ) != '' ) {
801 - $replyto = get_option( 'qlcd_wp_chatbot_reply_to_email' );
802 - }
803 -
804 - // Starting messaging and status.
805 - $offertexts = maybe_unserialize( get_option( 'qlcd_wp_email_subscription_offer' ) );
806 - if ( is_array( $offertexts ) && isset( $offertexts[ get_wpbot_locale() ] ) ) {
807 - $offertexts = $offertexts[ get_wpbot_locale() ];
808 - }
809 - // build email body.
810 - $bodyContent = '';
811 - $bodyContent .= '<p><strong>' . esc_html__( 'Offer Details', 'wpchatbot' ) . ':</strong></p><hr>';
812 - if ( is_array( $offertexts ) && ! empty( $offertexts ) ) {
813 - $bodyContent .= '<p>' . str_replace( '%%username%%', $name, $offertexts[ array_rand( $offertexts ) ] ) . '</p>';
814 - } elseif ( is_string( $offertexts ) && ! empty( $offertexts ) ) {
815 - $bodyContent .= '<p>' . str_replace( '%%username%%', $name, $offertexts ) . '</p>';
816 - } else {
817 - $bodyContent .= '<p></p>';
818 - }
819 - $bodyContent .= '<p>' . esc_html__( 'Mail Generated on', 'wpchatbot' ) . ': ' . current_time( 'F j, Y, g:i a' ) . '</p>';
820 - $to = $toEmail;
821 - $body = $bodyContent;
822 -
823 - $headers = array();
824 - $headers[] = 'Content-Type: text/html; charset=UTF-8';
825 - $headers[] = 'From: ' . $fromname . ' <' . $fromEmail . '>';
826 - $headers[] = 'Reply-To: ' . $fromname . ' <' . ( $replyto ) . '>';
827 - wp_mail( $to, $subject, $body, $headers );
828 - $response['email'] = 'Send! to ' . $to . ' from ' . $fromEmail;
829 -
830 - }
831 -
832 - echo json_encode( $response );
833 -
834 - die();
835 - }
836 -}
837 -
838 -add_action( 'wp_ajax_qcld_wb_chatbot_email_subscription', 'qcld_wb_chatbot_email_subscription' );
839 -add_action( 'wp_ajax_nopriv_qcld_wb_chatbot_email_subscription', 'qcld_wb_chatbot_email_subscription' );
840 -add_action( 'admin_post_wpbprint.csv', 'qcld_wpb_export_email_csv' );
841 -
842 -if ( ! function_exists( 'qcld_wpbd_array2csv' ) ) {
843 - function qcld_wpbd_array2csv( array &$array ) {
844 - if ( count( $array ) == 0 ) {
845 - return null;
846 - }
847 - ob_start();
848 - $df = fopen( 'php://output', 'w' );
849 - fputcsv( $df, array( 'Name', 'Email' ), ',', '"', '\\' );
850 - foreach ( $array as $row ) {
851 - fputcsv( $df, $row, ',', '"', '\\' );
852 - }
853 - fclose( $df );
854 - return ob_get_clean();
855 - }
856 -}
857 -
858 -function qcld_wpb_export_email_csv() {
859 - global $wpdb;
860 - $table = $wpdb->prefix . 'wpbot_subscription';
861 -
862 - if ( ! current_user_can( 'manage_options' ) ) {
863 - return;
864 - }
865 -
866 - $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
867 - $childArray = array();
868 - foreach ( $emails as $email ) {
869 - $innerArray = array();
870 - $innerArray[0] = $email->name;
871 - $innerArray[1] = $email->email;
872 - array_push( $childArray, $innerArray );
873 - }
874 - qcld_wpbd_download_send_headers( 'wpb_email_lists_' . current_time( 'Y-m-d' ) . '.csv' );
875 -
876 - $result = qcld_wpbd_array2csv( $childArray );
877 -
878 - print $result; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
879 - die();
880 -}
881 -function qcld_wpbd_download_send_headers( $filename ) {
882 - // disable caching
883 - $now = gmdate( 'D, d M Y H:i:s' );
884 - header( 'Expires: Tue, 03 Jul 2001 06:00:00 GMT' );
885 - header( 'Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate' );
886 - header( "Last-Modified: {$now} GMT" );
887 -
888 - // force download
889 - header( 'Content-Type: application/force-download' );
890 -
891 - // disposition / encoding on response body
892 - header( "Content-Disposition: attachment;filename={$filename}" );
893 - header( 'Content-Transfer-Encoding: binary' );
894 -}
895 -add_action( 'wp_ajax_wpbo_search_response_catlist', 'wpbo_search_response_catlist' );
896 -add_action( 'wp_ajax_nopriv_wpbo_search_response_catlist', 'wpbo_search_response_catlist' );
897 -
898 -if( !function_exists( 'wpbo_search_response_catlist' )){
899 - function wpbo_search_response_catlist(){
900 - global $wpdb;
901 - $table = $wpdb->prefix.'wpbot_response_category';
902 - $status = array('status'=>'fail');
903 - $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM %i", $table)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
904 - $response_result = array();
905 -
906 - if(!empty($results)){
907 - foreach($results as $result){
908 -
909 - $response_result[] = array('name'=>$result->name);
910 -
911 - }
912 - }
913 -
914 - if(!empty($response_result)){
915 -
916 - $status = array('status'=>'success', 'data'=>$response_result);
917 -
918 -
919 - }
920 -
921 - echo wp_json_encode($status);
922 -
923 - die();
924 -
925 - }
926 -}
927 -add_action( 'wp_ajax_wpbo_search_response', 'qcld_wpbo_search_response' );
928 -add_action( 'wp_ajax_nopriv_wpbo_search_response', 'qcld_wpbo_search_response' );
929 -
930 -
931 -
932 -function qcld_wpbo_search_response(){
933 -
934 - global $wpdb;
935 - $keyword = isset( $_POST['keyword'] ) ? (sanitize_text_field(wp_unslash($_POST['keyword']))) : '';
936 - $strid = isset( $_POST['strid'] ) ? (sanitize_text_field(wp_unslash($_POST['strid']))) : '';
937 - $table = $wpdb->prefix.'wpbot_response';
938 -
939 -
940 - $response_result = array();
941 -
942 - $status = array('status'=>'fail', 'multiple'=>false);
943 - $field = "ID";
944 - if(($strid != '') && empty($response_result)){
945 - $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
946 - if(!empty($results)){
947 - foreach($results as $result){
948 -
949 - $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
950 -
951 - }
952 - }
953 - }
954 - $field = "query";
955 - $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
956 -
957 -
958 - if(!empty($results)){
959 - foreach($results as $result){
960 -
961 - $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
962 -
963 - }
964 - }
965 -
966 - $field = "category";
967 - if(empty($response_result)){
968 - $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
969 -
970 -
971 - if(!empty($results)){
972 - foreach($results as $result){
973 - $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
974 - }
975 - if(count($response_result)>1){
976 - $status = array('status'=>'success','category'=> true, 'multiple'=>true, 'data'=>$response_result);
977 - }else{
978 - $status = array('status'=>'success', 'category'=> true, 'multiple'=>false, 'data'=>$response_result);
979 - }
980 -
981 - echo wp_json_encode($status);
982 -
983 - die();
984 - }
985 -
986 - }
987 -
988 - if(class_exists('Qcld_str_pro')){
989 - if(get_option('qc_bot_str_remove_stopwords') && get_option('qc_bot_str_remove_stopwords')==1){
990 - $keyword = qcld_strpro_remove_stopwords($keyword);
991 - }
992 - }
993 -
994 -
995 - if(empty($response_result)){
996 -
997 - $fields = get_option('qc_bot_str_fields');
998 -
999 - $allowed_fields = array('query', 'keyword', 'response');
1000 - $valid_fields = array();
1001 -
1002 - if($fields && !empty($fields) && is_array($fields)){
1003 - foreach($fields as $field){
1004 - if(in_array($field, $allowed_fields)){
1005 - $valid_fields[] = '`' . $field . '`';
1006 - }
1007 - }
1008 - }
1009 -
1010 - if(!empty($valid_fields)){
1011 - $qfields = implode(', ', $valid_fields);
1012 - }else{
1013 - $qfields = '`query`,`keyword`,`response`';
1014 - }
1015 -
1016 -
1017 -
1018 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
1019 - $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) );
1020 -
1021 - $weight = get_option('qc_bot_str_weight')!=''?get_option('qc_bot_str_weight'):'0.4';
1022 -
1023 - if(!empty($results)){
1024 - $max_score = max(array_column($results, 'score'));
1025 - if ($max_score <= 0) {
1026 - $max_score = 1; // Set to 1 to avoid division by zero
1027 - }
1028 - foreach($results as $result){
1029 - if(($result->score/$max_score) >= $weight){
1030 - $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>$result->score);
1031 - }
1032 - }
1033 - }
1034 - }
1035 - $field = "keyword";
1036 - if( empty( $response_result ) ){
1037 -
1038 - $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
1039 -
1040 -
1041 - if(!empty($results)){
1042 - foreach($results as $result){
1043 - $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
1044 - }
1045 - }
1046 - }
1047 - if(!empty($response_result)){
1048 -
1049 - if(count($response_result)>1){
1050 - $status = array('status'=>'success', 'multiple'=>true, 'data'=>$response_result);
1051 - }else{
1052 - $status = array('status'=>'success', 'multiple'=>false, 'data'=>$response_result);
1053 - }
1054 -
1055 - }
1056 - if(empty($result->query)){
1057 - $status = array('status'=>'fail', 'multiple'=>false, 'data'=>$response_result);
1058 - }
1059 - if(empty($status['data']) || (isset($status['status']) && $status['status']==='fail')){
1060 - // Check for space before question mark and try again.
1061 - if(preg_match('/ \?$/', $keyword)){
1062 - $keyword2 = preg_replace('/ \?$/', '?', $keyword);
1063 - // Try again with new keyword.
1064 - // Repeat the main search logic with $keyword2.
1065 - $response_result = array();
1066 - $field = "query";
1067 - $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
1068 - if(!empty($results)){
1069 - foreach($results as $result){
1070 - $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
1071 - }
1072 - if(count($response_result)>1){
1073 - $status = array('status'=>'success', 'multiple'=>true, 'data'=>$response_result);
1074 - }else{
1075 - $status = array('status'=>'success', 'multiple'=>false, 'data'=>$response_result);
1076 - }
1077 - }else{
1078 - $status = array('status'=>'fail', 'multiple'=>false, 'data'=>[]);
1079 - }
1080 - }
1081 - }
1082 - if(empty($status['data']) || (isset($status['status']) && $status['status']==='fail')){
1083 - // Try a partial match if still nothing found.
1084 - if(empty($status['data'])) {
1085 - $keyword_like = '%' . preg_replace('/[\\s\\?]+/', '%', $keyword) . '%';
1086 - $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
1087 - $response_result = array();
1088 - if(!empty($results)){
1089 - foreach($results as $result){
1090 - $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1);
1091 - }
1092 - if(count($response_result)>1){
1093 - $status = array('status'=>'success', 'multiple'=>true, 'data'=>$response_result);
1094 - }else{
1095 - $status = array('status'=>'success', 'multiple'=>false, 'data'=>$response_result);
1096 - }
1097 - } else {
1098 - $status = array('status'=>'fail', 'multiple'=>false, 'data'=>[], 'message'=>'Sorry, I found nothing');
1099 - }
1100 - }
1101 - }
1102 - if(empty($status['data'])){
1103 - $status = array('status'=>'fail', 'multiple'=>false, 'data'=>[], 'message'=>'no result found');
1104 - }
1105 - echo wp_json_encode($status);
1106 -
1107 - die();
1108 -
1109 -}
1110 -
1111 -function qcld_strpro_remove_stopwords($keyword){
1112 -
1113 - if(get_option('qlcd_wp_chatbot_stop_words') && get_option('qlcd_wp_chatbot_stop_words')!=''){
1114 - $commonWords = explode(',', get_option('qlcd_wp_chatbot_stop_words'));
1115 - return preg_replace('/\b('.implode('|',$commonWords).')\b/','',$keyword);
1116 - }else{
1117 - return $keyword;
1118 - }
1119 -
1120 -
1121 -
1122 -}
1 +<?php /** * Product indexing, caching & searching features concept is taken from open source 'Advanced wp Search' Wp plugin by ILLID. */ //include_once( 'includes/class-wpwbot-cache.php' ); include_once( 'includes/class-wpwbot-table.php' ); include_once( 'includes/class-wpwbot-search.php' ); function wpbo_search_site() { $results = new WP_Query( array( 'post_type' => array( 'post', 'page' ), 'post_status' => 'publish', 'nopaging' => true, 'posts_per_page'=> 10, 's' => stripslashes( $_POST['keyword'] ), ) ); $response = array(); $response['status'] = 'fail'; if ( !empty( $results->posts ) ) { $response['status'] = 'success'; $response['html'] = '<div class="wpb-search-result">'; $response['html'] .= '<p>We have found '.count($results->posts).' results for <b>'.$_POST['keyword'].'</b>.</p>'; foreach ( $results->posts as $result ) { $response['html'] .= '<a href="'.$result->guid.'" target="_blank">'.$result->post_title.'</a>'; } $response['html'] .='</div>'; }else{ $texts = unserialize(get_option('qlcd_wp_chatbot_no_result')); $response['html'] = $texts[array_rand($texts)]; } echo json_encode($response); die(); } add_action( 'wp_ajax_wpbo_search_site', 'wpbo_search_site' ); add_action( 'wp_ajax_nopriv_wpbo_search_site', 'wpbo_search_site' ); add_action( 'wp_ajax_wpbo_search_responseby_intent', 'qc_wpbo_search_responseby_intent' ); add_action( 'wp_ajax_nopriv_wpbo_search_responseby_intent', 'qc_wpbo_search_responseby_intent' ); function qc_wpbo_search_responseby_intent(){ global $wpdb; $keyword = sanitize_text_field($_POST['keyword']); $table = $wpdb->prefix.'wpbot_response'; $result = $wpdb->get_row("SELECT `response` FROM `$table` WHERE 1 and `intent` = '".$keyword."'"); $response = array('status'=>'fail'); if(!empty($result)){ $response['status'] = 'success'; $response['html'] = $result->response; } echo json_encode($response); die(); } add_action( 'wp_ajax_wpbo_search_response_catlist', 'wpbo_search_response_catlist' ); add_action( 'wp_ajax_nopriv_wpbo_search_response_catlist', 'wpbo_search_response_catlist' ); function wpbo_search_response_catlist(){ global $wpdb; $table = $wpdb->prefix.'wpbot_response_category'; $status = array('status'=>'fail'); $results = $wpdb->get_results("SELECT * FROM `$table` WHERE 1"); $response_result = array(); if(!empty($results)){ foreach($results as $result){ $response_result[] = array('name'=>$result->name); } } if(!empty($response_result)){ $status = array('status'=>'success', 'data'=>$response_result); } echo json_encode($status); die(); } add_action( 'wp_ajax_wpbo_search_response', 'qc_wpbo_search_response' ); add_action( 'wp_ajax_nopriv_wpbo_search_response', 'qc_wpbo_search_response' ); function qc_wpbo_search_response(){ global $wpdb; $keyword = (sanitize_text_field($_POST['keyword'])); $table = $wpdb->prefix.'wpbot_response'; $response_result = array(); $status = array('status'=>'fail', 'multiple'=>false); $results = $wpdb->get_results("SELECT `query`, `response` FROM `$table` WHERE 1 and `query` = '".$keyword."'"); if(!empty($results)){ foreach($results as $result){ $response_result[] = array('query'=>$result->query, 'response'=>$result->response, 'score'=>1); } } if(empty($response_result)){ $results = $wpdb->get_results("SELECT `query`, `response` FROM `$table` WHERE 1 and `category` = '".$keyword."'"); if(!empty($results)){ foreach($results as $result){ $response_result[] = array('query'=>$result->query, 'response'=>$result->response, 'score'=>1); } if(count($response_result)>1){ $status = array('status'=>'success','category'=> true, 'multiple'=>true, 'data'=>$response_result); }else{ $status = array('status'=>'success', 'category'=> true, 'multiple'=>false, 'data'=>$response_result); } echo json_encode($status); die(); } } if(class_exists('Qcld_str_pro')){ if(get_option('qc_bot_str_remove_stopwords') && get_option('qc_bot_str_remove_stopwords')==1){ $keyword = qc_strpro_remove_stopwords($keyword); } } if(empty($response_result)){ $fields = get_option('qc_bot_str_fields'); if($fields && !empty($fields) && class_exists('Qcld_str_pro')){ $qfields = implode(', ', $fields); }else{ $qfields = '`query`,`keyword`,`response`'; } $results = $wpdb->get_results("SELECT `query`, `response`, MATCH($qfields) AGAINST('".$keyword."' IN NATURAL LANGUAGE MODE) as score FROM $table WHERE MATCH($qfields) AGAINST('".$keyword."' IN NATURAL LANGUAGE MODE) order by score desc limit 15"); $weight = get_option('qc_bot_str_weight')!=''?get_option('qc_bot_str_weight'):'0.4'; //$weight = 0; if(!empty($results)){ foreach($results as $result){ if(intval($result->score) >= intval($weight)){ $response_result[] = array('query'=>$result->query, 'response'=>$result->response, 'score'=>$result->score); } } } } if(!empty($response_result)){ if(count($response_result)>1){ $status = array('status'=>'success', 'multiple'=>true, 'data'=>$response_result); }else{ $status = array('status'=>'success', 'multiple'=>false, 'data'=>$response_result); } } echo json_encode($status); die(); } function qc_strpro_remove_stopwords($keyword){ if(get_option('qlcd_wp_chatbot_stop_words') && get_option('qlcd_wp_chatbot_stop_words')!=''){ $commonWords = explode(',', get_option('qlcd_wp_chatbot_stop_words')); return preg_replace('/\b('.implode('|',$commonWords).')\b/','',$keyword); }else{ return $keyword; } }