1) { // Avoid stemming single letters // Remove 's' (e.g., 'inspections' -> 'inspection') if (substr($word, -1) === 's') { $variations[] = substr($word, 0, -1); } else { // Add 's' (e.g., 'inspection' -> 'inspections') $variations[] = $word . 's'; } // Handle 'er' suffix (e.g., 'inspector' -> 'inspect') if (substr($word, -2) === 'er') { $variations[] = substr($word, 0, -2); } // Handle 'ing' suffix (e.g., 'inspecting' -> 'inspect') if (substr($word, -3) === 'ing') { $variations[] = substr($word, 0, -3); } // Add 'er' if the base word is 'inspect' and 'inspector' is not present if (strpos($word, 'inspect') !== false && strpos($word, 'inspector') === false) { $variations[] = str_replace('inspect', 'inspector', $word); } } $all_word_variations[] = array_filter(array_unique($variations)); } return $all_word_variations; } } // Filter function to modify WP_Query search for flexible matching if ( ! function_exists( 'wpbot_flexible_search_filter' ) ) { function wpbot_flexible_search_filter($search, $wp_query) { global $wpdb, $wpbot_search_word_variations; // Only apply if it's the main search query and our variations are set if (empty($wpbot_search_word_variations) || !$wp_query->is_search || !$wp_query->is_main_query()) { return $search; } $search_parts_for_and = []; foreach ($wpbot_search_word_variations as $word_variations) { $search_parts_for_or = []; foreach ($word_variations as $term) { $term = $wpdb->esc_like($term); // Search in both post_title and post_content $search_parts_for_or[] = "(({$wpdb->posts}.post_title LIKE '%{$term}%') OR ({$wpdb->posts}.post_content LIKE '%{$term}%'))"; } if (!empty($search_parts_for_or)) { $search_parts_for_and[] = '(' . implode(' OR ', $search_parts_for_or) . ')'; } } if (!empty($search_parts_for_and)) { // Completely replace the default search clause generated by WP_Query's 's' parameter // This ensures our flexible matching takes precedence. $search = ' AND ' . implode(' AND ', $search_parts_for_and); } return $search; } } function wpbo_search_site() { // Verify nonce for security $nonce = isset($_POST['security']) ? sanitize_text_field(wp_unslash($_POST['security'])) : (isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : ''); if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) && ! wp_verify_nonce( $nonce, 'qcsecretbotnonceval123qc' ) ) { wp_send_json_error( array( 'status' => 'fail', 'message' => 'Security check failed.' ) ); wp_die(); } global $wpdb; // Limit results to 5 items. $limit = 5; $response = array('status' => 'fail', 'html' => ''); // Initialize response array // Get default language for load more button text and other language-specific checks. $default_language = get_locale(); if(get_option('enable_wp_chatbot_post_content') == 1){ $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : ''; $all_word_variations = _wpbot_generate_word_variations($keyword); // Temporarily store the variations for the filter global $wpbot_search_word_variations; $wpbot_search_word_variations = $all_word_variations; // Add the custom search filter add_filter('posts_search', 'wpbot_flexible_search_filter', 10, 2); $enable_post_types = array( 'post', 'page', 'product' ); $total_items = $limit; $query_arg = array( 'post_type' => $enable_post_types, 'post_status' => 'publish', 'posts_per_page'=> $total_items, 's' => stripslashes( $keyword ), // Keep original for WP_Query to initiate search, filter will override 'paged' => 1, 'suppress_filters' => false // Crucial for filters to run ); $resultss = new WP_Query( $query_arg ); $results = $resultss->posts; // Remove the filter after the query to avoid affecting other queries remove_filter('posts_search', 'wpbot_flexible_search_filter', 10); unset($wpbot_search_word_variations); // Clean up global }else{ $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : ''; $all_word_variations = _wpbot_generate_word_variations($keyword); $sql_parts_for_and = []; $sql_params = []; foreach ($all_word_variations as $word_variations) { $sql_parts_for_or = []; foreach ($word_variations as $term) { $sql_parts_for_or[] = "post_title LIKE %s"; $sql_params[] = '%' . $wpdb->esc_like($term) . '%'; } if (!empty($sql_parts_for_or)) { $sql_parts_for_and[] = '(' . implode(' OR ', $sql_parts_for_or) . ')'; } } $where_clause = ''; if (!empty($sql_parts_for_and)) { $where_clause = ' AND ' . implode(' AND ', $sql_parts_for_and); } else { // Fallback to original behavior if no variations generated (e.g., empty keyword) $where_clause = " AND (post_title LIKE %s)"; $sql_params[] = '%' . $wpdb->esc_like($keyword) . '%'; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "posts WHERE post_status = %s " . $where_clause . " ORDER BY ID DESC LIMIT %d", array_merge(['publish'], $sql_params, [$limit]) ) ); } if(!empty( $results )){ $response['status'] = 'success'; $response['html'] = '
'; $total_post = 0; $responses = ''; foreach ( $results as $result ) { $featured_img_url = get_the_post_thumbnail_url( $result->ID, 'full' ); $excerpt = ''; if ( isset( $result->ID ) ) { $post_obj = get_post( $result->ID ); if ( $post_obj ) { if ( has_excerpt( $result->ID ) ) { $excerpt = get_the_excerpt( $result->ID ); } else { $content = $post_obj->post_content; // Remove ALL WPBakery shortcodes (paired + self-closing) $content = preg_replace( '/\[vc_[^\]]*\](.*?)\[\/vc_[^\]]*\]/s', '$1', $content ); // paired $content = preg_replace( '/\[vc_[^\]]*\]/s', '', $content ); // self-closing $content = preg_replace('/\[\/?[\w\-]+[^\]]*\]/', '', $content); // Extra: remove any leftover [] shortcodes (just in case) $content = strip_shortcodes( $content ); // Run through normal WP content filters $content_filtered = apply_filters( 'the_content', $content ); // Strip HTML tags, then trim $excerpt = wp_trim_words( wp_strip_all_tags( $content_filtered ), 20, '...' ); } } } $total_post = $total_post + 1; $responses .='
'; $responses .= ''; $responses .='
'; } $response['html'] .= $responses; $response['html'] .='
'; if($total_post >= $limit ){ // Use $limit for consistency $load_more = maybe_unserialize(get_option('qlcd_wp_chatbot_load_more_search')); $response['html'] .=''; } }else{ // Fuzzy search if initial search yields no results $response['status'] = 'success'; // Use the same word variation logic for fuzzy search $all_word_variations_for_fuzzy = _wpbot_generate_word_variations($keyword); $unique_posts = array(); // Store unique post objects $seen_ids = array(); // Keep track of seen post IDs // Iterate through each word's variations to find matching posts foreach ( $all_word_variations_for_fuzzy as $word_variations ) { foreach ($word_variations as $term) { $term = $wpdb->esc_like( $term ); $term_results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $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 .'%') ); foreach ($term_results as $res) { if (!in_array($res->ID, $seen_ids)) { $unique_posts[] = $res; $seen_ids[] = $res->ID; } } } } $results = $unique_posts; // Now $results contains unique WP_Post objects if( !empty( $results) ){ $response['html'] = '
'; $total_post = 0; $responses = ''; $selected_lan = get_option('qlcd_wp_chatbot_default_language'); foreach ($results as $value) { // $value is a single post object here if(!empty($value->guid)){ $post_id = $value->ID; $current_featured_img_url = get_the_post_thumbnail_url( $post_id, 'full' ); // Corrected URL segment parsing for language check $url_path = wp_parse_url(get_permalink($post_id), PHP_URL_PATH); $url_segments = array_filter(explode('/',$url_path)); // Assuming the language slug is the first non-empty segment of the URL path. $first_segment = !empty($url_segments) ? reset($url_segments) : ''; // If $selected_lan is empty, the language check is effectively skipped. $language_match = empty($selected_lan) || ($first_segment == $selected_lan); if($language_match){ $total_post = $total_post + 1; $responses .='
'; $responses .= ''; $responses .='
'; } } } if($total_post > 2 ){ // This condition is different from the first block ($total_post >= $limit) $load_more = maybe_unserialize(get_option('qlcd_wp_chatbot_load_more_search')); $response['html'] .=''; $response['status'] = 'success'; }else{ $response['status'] = 'fail'; } $response['html'] .= $responses; $response['html'] .='
'; } else { $response['status'] = 'fail'; // No results from fuzzy search either } } echo wp_json_encode($response); wp_die(); } add_action( 'wp_ajax_wpbo_search_site', 'wpbo_search_site' ); add_action( 'wp_ajax_nopriv_wpbo_search_site', 'wpbo_search_site' ); if ( ! function_exists( 'qcld_wpbot_modified_keyword' ) ) { function qcld_wpbot_modified_keyword( $keyword ) { $keyword = rtrim( $keyword, '!' ); $pattern = '/[?\/]/'; $strings = preg_split( $pattern, $keyword ); $strings = array_filter( array_map( 'trim', $strings ) ); $keyword = rtrim( $strings[0], '!' ); return htmlspecialchars_decode( $keyword ); } } add_action( 'wp_ajax_wpbo_search_responseby_intent', 'qcld_wpbo_search_responseby_intent' ); add_action( 'wp_ajax_nopriv_wpbo_search_responseby_intent', 'qcld_wpbo_search_responseby_intent' ); if( !function_exists( 'wpbo_search_site_pagination' )){ function wpbo_search_site_pagination() { global $wpdb; // Verify nonce for security $p_nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : ''; if ( ! wp_verify_nonce( $p_nonce, 'wp_chatbot' ) && ! wp_verify_nonce( $p_nonce, 'qcsecretbotnonceval123qc' ) ) { wp_send_json_error( array( 'message' => 'Security check failed' ) ); wp_die(); } // Sanitize and validate inputs $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : ''; $post_type = isset( $_POST['type'] ) ? sanitize_text_field(wp_unslash($_POST['type'])) : 'post'; $page = isset($_POST['page']) ? absint( wp_unslash($_POST['page']) ) : 0; // Validate post type against allowed types $allowed_post_types = array( 'post', 'page', 'product' ); if ( ! in_array( $post_type, $allowed_post_types, true ) ) { $post_type = 'post'; } $enable_post_types = get_option( 'wppt_post_types' ); $load_more = maybe_unserialize( get_option( 'qlcd_wp_chatbot_load_more' ) ); if ( is_array( $load_more ) && isset( $load_more[ get_locale() ] ) ) { $load_more = $load_more[ get_locale() ]; } if ( is_array( $load_more ) && ! empty( $load_more ) ) { $load_more = $load_more[ array_rand( $load_more ) ]; } $searchlimit = ( get_option( 'wppt_number_of_result' ) == '' ? 5 : absint( get_option( 'wppt_number_of_result' ) ) ); $orderby = ( get_option( 'wppt_result_orderby' ) == '' ? 'none' : get_option( 'wppt_result_orderby' ) ); $order = ( get_option( 'wppt_result_order' ) == '' ? 'ASC' : get_option( 'wppt_result_order' ) ); $thumb = ( get_option( 'wpbot_search_image_size' ) ? get_option( 'wpbot_search_image_size' ) : 'thumbnail' ); // order by setup $new_window = get_option( 'wpbot_search_result_new_window' ); $total_items = absint( get_option( 'wppt_number_of_result' ) ); if ( $total_items < 1 ) { $total_items = 5; } $searchkeyword = qcld_wpbot_modified_keyword( $keyword ); $response = array(); $response['status'] = 'fail'; $response['html'] = ''; // Use prepared statements to prevent SQL injection if ( get_option( 'active_advance_query' ) != '1' ) { // Simple query - search in post_title only $total_results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}posts WHERE post_type = %s AND post_status = 'publish' AND post_title LIKE %s ORDER BY ID DESC", $post_type, '%' . $wpdb->esc_like( $searchkeyword ) . '%' )); } else { // Advanced query - search in both post_title and post_content $total_results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "posts WHERE post_type = %s AND post_status = %s AND (post_title REGEXP %s OR post_content REGEXP %s) ORDER BY ID DESC", $post_type, 'publish', '[[:<:]]' . $searchkeyword . '[[:>:]]', '[[:<:]]' . $searchkeyword . '[[:>:]]' )); } if ( ! empty( $total_results ) ) { // Validate and sanitize orderby parameter $valid_orderby = array( 'title', 'date', 'modified', 'none', 'rand' ); if ( ! in_array( $orderby, $valid_orderby, true ) ) { $orderby = 'none'; } if ( $orderby == 'title' ) { $orderby = 'post_title'; } if ( $orderby == 'date' ) { $orderby = 'post_date'; } if ( $orderby == 'modified' ) { $orderby = 'post_modified'; } // Validate order parameter $order = strtoupper( $order ); if ( ! in_array( $order, array( 'ASC', 'DESC' ), true ) ) { $order = 'ASC'; } // Build query with pagination $offset = absint( $total_items * $page ); if ( get_option( 'active_advance_query' ) != '1' ) { if ( $orderby != 'none' && $orderby != 'rand' ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}posts WHERE post_type = %s AND post_status = 'publish' AND post_title LIKE %s ORDER BY {$orderby} {$order} LIMIT %d, %d", $post_type, '%' . $wpdb->esc_like( $searchkeyword ) . '%', $offset, $total_items ) ); } else { $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}posts WHERE post_type = %s AND post_status = 'publish' AND post_title LIKE %s ORDER BY ID DESC LIMIT %d, %d", $post_type, '%' . $wpdb->esc_like( $searchkeyword ) . '%', $offset, $total_items )); } } else { if ( $orderby != 'none' && $orderby != 'rand' ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "posts WHERE post_type = %s AND post_status = %s AND (post_title REGEXP %s OR post_content REGEXP %s) ORDER BY " . $orderby . " " . $order . " LIMIT %d, %d", $post_type, 'publish', '[[:<:]]' . $searchkeyword . '[[:>:]]', '[[:<:]]' . $searchkeyword . '[[:>:]]', $offset, $total_items ) ); } else { $results = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "posts WHERE post_type = %s AND post_status = %s AND (post_title REGEXP %s OR post_content REGEXP %s) ORDER BY ID DESC LIMIT %d, %d", $post_type, 'publish', '[[:<:]]' . $searchkeyword . '[[:>:]]', '[[:<:]]' . $searchkeyword . '[[:>:]]', $offset, $total_items )); } } } else { if ( class_exists( 'SitePress' ) ) { global $sitepress; $selected_lan = isset( $_POST['language'] ) ? sanitize_text_field(wp_unslash($_POST['language'])) : ''; $selected_lan = explode( '_', $selected_lan ); if ( ! empty( $selected_lan[0] ) ) { $sitepress->switch_lang( $selected_lan[0], true ); } } $query_arg = array( 'post_type' => $post_type, 'post_status' => 'publish', 'posts_per_page' => $total_items, 's' => stripslashes( $keyword ), 'paged' => ( $page + 1 ), 'orderby' => $orderby, ); if ( class_exists( 'SitePress' ) ) { global $sitepress; $selected_lan = isset( $_POST['language'] ) ? sanitize_text_field(wp_unslash($_POST['language'])) : ''; $selected_lan = explode( '_', $selected_lan ); if ( ! empty( $selected_lan[0] ) ) { $sitepress->switch_lang( $selected_lan[0], true ); } } $query_arg['suppress_filters'] = true; if ( $orderby != 'none' && $orderby != 'rand' ) { $query_arg['order'] = $order; } $totalresults = new WP_Query( array( 'post_type' => $post_type, 'post_status' => 'publish', 's' => stripslashes( $keyword ), ) ); $resultss = new WP_Query( $query_arg ); $total_results = $totalresults->posts; $resultss = new WP_Query( $query_arg ); $results = $resultss->posts; } if ( ! empty( $total_results ) ) { $selected_lan = isset( $_POST['language'] ) ? sanitize_text_field(wp_unslash($_POST['language'])) : ''; $urlss = get_option( 'wpbotml_url_urls' ) ? get_option( 'wpbotml_url_urls' ) : ''; $imagesize = ( get_option( 'wpbot_search_image_size' ) != '' ? get_option( 'wpbot_search_image_size' ) : 'thumbnail' ); $response['html'] .= '
'; foreach ( $total_results as $result ) { if ( $result->post_type == 'product' ) { if ( ! class_exists( 'WooCommerce' ) ) { continue; } } $featured_img_url = get_the_post_thumbnail_url( $result->ID, $thumb ); $excerpt = ''; if ( isset( $result->ID ) ) { $post_obj = get_post( $result->ID ); if ( $post_obj ) { if ( has_excerpt( $result->ID ) ) { $excerpt = get_the_excerpt( $result->ID ); } else { $content = $post_obj->post_content; // Remove ALL WPBakery shortcodes (paired + self-closing) $content = preg_replace( '/\[vc_[^\]]*\](.*?)\[\/vc_[^\]]*\]/s', '$1', $content ); // paired $content = preg_replace( '/\[vc_[^\]]*\]/s', '', $content ); // self-closing $content = preg_replace('/\[\/?[\w\-]+[^\]]*\]/', '', $content); // Extra: remove any leftover [] shortcodes (just in case) $content = strip_shortcodes( $content ); // Run through normal WP content filters $content_filtered = apply_filters( 'the_content', $content ); // Strip HTML tags, then trim $excerpt = wp_trim_words( wp_strip_all_tags( $content_filtered ), 20, '...' ); } } } $response['html'] .= '
'; $response['html'] .= ''; $response['html'] .= '
'; } $response['html'] .= '
'; $response['status'] = 'success'; } wp_reset_query(); if ( $response['status'] != 'success' ) { $texts = maybe_unserialize( get_option( 'qlcd_wp_chatbot_no_result' ) ); $selected_lan = isset( $_POST['language'] ) ? sanitize_text_field(wp_unslash($_POST['language'])) : ''; if ( ! empty( $texts ) && is_array( $texts ) && isset( $texts[ $selected_lan ][0] ) ) { $texts = str_replace( "\'", "'", $texts[ $selected_lan ][0] ); $response['html'] = array( $texts ); } else { $response['html'] = array( 'No results found' ); } } wp_send_json( $response ); die(); } } add_action( 'wp_ajax_wpbo_search_site_pagination', 'wpbo_search_site_pagination' ); add_action( 'wp_ajax_nopriv_wpbo_search_site_pagination', 'wpbo_search_site_pagination' ); function qcld_wpbo_search_responseby_intent(){ global $wpdb; $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field(wp_unslash($_POST['keyword'])) : ''; $table = $wpdb->prefix.'wpbot_response'; $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 $response = array('status'=>'fail'); if(!empty($result)){ $response['status'] = 'success'; $response['html'] = $result->response; } echo wp_json_encode($response); die(); } function qcld_wb_chatbot_email_subscription() { global $wpdb; $table = $wpdb->prefix . 'wpbot_subscription'; $name = sanitize_text_field( $_POST['name'] );// phpcs:ignore WordPress.Security.NonceVerification.Missing $email = sanitize_email( $_POST['email'] );// phpcs:ignore WordPress.Security.NonceVerification.Missing $url = esc_url_raw( $_POST['url'] );// phpcs:ignore WordPress.Security.NonceVerification.Missing $user_agent = sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] );// phpcs:ignore WordPress.Security.NonceVerification.Missing if ( isset( $_POST['phone'] ) && $_POST['phone'] != '' ) {// phpcs:ignore WordPress.Security.NonceVerification.Missing $phone = sanitize_text_field( $_POST['phone'] );// phpcs:ignore WordPress.Security.NonceVerification.Missing if ( $email != '' ) { $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 if ( ! empty( $email_exists ) ) { $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $table, array( 'phone' => $phone, ), array( 'email' => $email ), array( '%s', ), array( '%s' ) ); } else { $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $table, array( 'date' => current_time( 'mysql' ), 'name' => $name, 'email' => $email, 'phone' => $phone, 'url' => $url, 'user_agent' => $user_agent, ) ); } } else { $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $table, array( 'date' => current_time( 'mysql' ), 'name' => $name, 'email' => $email, 'phone' => $phone, 'url' => $url, 'user_agent' => $user_agent, ) ); } $response['status'] = 'success'; echo json_encode( $response ); die(); } else { $response = array(); $response['status'] = 'fail'; $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 if ( empty( $email_exists ) ) { $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $table, array( 'date' => current_time( 'mysql' ), 'name' => $name, 'email' => $email, 'url' => $url, 'user_agent' => $user_agent, ) ); $response['status'] = 'success'; $texts = maybe_unserialize( get_option( 'qlcd_wp_email_subscription_success' ) ); if ( is_array( $texts ) && isset( $texts[ get_wpbot_locale() ] ) ) { $texts = $texts[ get_wpbot_locale() ]; } if ( is_array( $texts ) && ! empty( $texts ) ) { $response['msg'] = $texts[ array_rand( $texts ) ]; } elseif ( is_string( $texts ) && ! empty( $texts ) ) { $response['msg'] = $texts; } else { $response['msg'] = 'Thank you for subscribing.'; } } else { $texts = maybe_unserialize( get_option( 'qlcd_wp_email_already_subscribe' ) ); if ( is_array( $texts ) && isset( $texts[ get_wpbot_locale() ] ) ) { $texts = $texts[ get_wpbot_locale() ]; } if ( is_array( $texts ) && ! empty( $texts ) ) { $response['msg'] = $texts[ array_rand( $texts ) ]; } elseif ( is_string( $texts ) && ! empty( $texts ) ) { $response['msg'] = $texts; } else { $response['msg'] = 'You have already subscribed!'; } } do_action( 'qcld_mailing_list_subscription_success', $name, $email ); if ( get_option( 'qc_email_subscription_offer' ) == 1 ) { $response['status'] = 'success'; if ( get_option( 'qlcd_wp_email_subscription_offer_subject' ) ) { $offertextss = maybe_unserialize( get_option( 'qlcd_wp_email_subscription_offer_subject' ) ); if ( is_array( $offertextss ) && isset( $offertextss[ get_wpbot_locale() ] ) ) { $offertextss = $offertextss[ get_wpbot_locale() ]; } if ( is_array( $offertextss ) && ! empty( $offertextss ) ) { $subject = str_replace( '%%username%%', $name, $offertextss[ array_rand( $offertextss ) ] ); } elseif ( is_string( $offertextss ) && ! empty( $offertextss ) ) { $subject = str_replace( '%%username%%', $name, $offertextss ); } else { $subject = 'Email subscription offer'; } } else { $subject = 'Email subscription offer'; } // Extract Domain $url = get_site_url(); $url = parse_url( $url ); $domain = $url['host']; $toEmail = $email; $fromEmail = 'wordpress@' . $domain; $fromname = ( get_option( 'qlcd_wp_chatbot_from_name' ) ? get_option( 'qlcd_wp_chatbot_from_name' ) : 'WordPress' ); if ( get_option( 'qlcd_wp_chatbot_from_email' ) && get_option( 'qlcd_wp_chatbot_from_email' ) != '' ) { $fromEmail = get_option( 'qlcd_wp_chatbot_from_email' ); } $replyto = $fromEmail; if ( get_option( 'qlcd_wp_chatbot_reply_to_email' ) && get_option( 'qlcd_wp_chatbot_reply_to_email' ) != '' ) { $replyto = get_option( 'qlcd_wp_chatbot_reply_to_email' ); } // Starting messaging and status. $offertexts = maybe_unserialize( get_option( 'qlcd_wp_email_subscription_offer' ) ); if ( is_array( $offertexts ) && isset( $offertexts[ get_wpbot_locale() ] ) ) { $offertexts = $offertexts[ get_wpbot_locale() ]; } // build email body. $bodyContent = ''; $bodyContent .= '

' . esc_html__( 'Offer Details', 'wpchatbot' ) . ':


'; if ( is_array( $offertexts ) && ! empty( $offertexts ) ) { $bodyContent .= '

' . str_replace( '%%username%%', $name, $offertexts[ array_rand( $offertexts ) ] ) . '

'; } elseif ( is_string( $offertexts ) && ! empty( $offertexts ) ) { $bodyContent .= '

' . str_replace( '%%username%%', $name, $offertexts ) . '

'; } else { $bodyContent .= '

'; } $bodyContent .= '

' . esc_html__( 'Mail Generated on', 'wpchatbot' ) . ': ' . current_time( 'F j, Y, g:i a' ) . '

'; $to = $toEmail; $body = $bodyContent; $headers = array(); $headers[] = 'Content-Type: text/html; charset=UTF-8'; $headers[] = 'From: ' . $fromname . ' <' . $fromEmail . '>'; $headers[] = 'Reply-To: ' . $fromname . ' <' . ( $replyto ) . '>'; wp_mail( $to, $subject, $body, $headers ); $response['email'] = 'Send! to ' . $to . ' from ' . $fromEmail; } echo json_encode( $response ); die(); } } add_action( 'wp_ajax_qcld_wb_chatbot_email_subscription', 'qcld_wb_chatbot_email_subscription' ); add_action( 'wp_ajax_nopriv_qcld_wb_chatbot_email_subscription', 'qcld_wb_chatbot_email_subscription' ); add_action( 'admin_post_wpbprint.csv', 'qcld_wpb_export_email_csv' ); if ( ! function_exists( 'qcld_wpbd_array2csv' ) ) { function qcld_wpbd_array2csv( array &$array ) { if ( count( $array ) == 0 ) { return null; } ob_start(); $df = fopen( 'php://output', 'w' ); fputcsv( $df, array( 'Name', 'Email' ), ',', '"', '\\' ); foreach ( $array as $row ) { fputcsv( $df, $row, ',', '"', '\\' ); } fclose( $df ); return ob_get_clean(); } } function qcld_wpb_export_email_csv() { global $wpdb; $table = $wpdb->prefix . 'wpbot_subscription'; if ( ! current_user_can( 'manage_options' ) ) { return; } $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 $childArray = array(); foreach ( $emails as $email ) { $innerArray = array(); $innerArray[0] = $email->name; $innerArray[1] = $email->email; array_push( $childArray, $innerArray ); } qcld_wpbd_download_send_headers( 'wpb_email_lists_' . current_time( 'Y-m-d' ) . '.csv' ); $result = qcld_wpbd_array2csv( $childArray ); print $result; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped die(); } function qcld_wpbd_download_send_headers( $filename ) { // disable caching $now = gmdate( 'D, d M Y H:i:s' ); header( 'Expires: Tue, 03 Jul 2001 06:00:00 GMT' ); header( 'Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate' ); header( "Last-Modified: {$now} GMT" ); // force download header( 'Content-Type: application/force-download' ); // disposition / encoding on response body header( "Content-Disposition: attachment;filename={$filename}" ); header( 'Content-Transfer-Encoding: binary' ); } 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' ); if( !function_exists( '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($wpdb->prepare("SELECT * FROM %i", $table)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $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 wp_json_encode($status); die(); } } add_action( 'wp_ajax_wpbo_search_response', 'qcld_wpbo_search_response' ); add_action( 'wp_ajax_nopriv_wpbo_search_response', 'qcld_wpbo_search_response' ); function qcld_wpbo_search_response(){ global $wpdb; $keyword = isset( $_POST['keyword'] ) ? (sanitize_text_field(wp_unslash($_POST['keyword']))) : ''; $strid = isset( $_POST['strid'] ) ? (sanitize_text_field(wp_unslash($_POST['strid']))) : ''; $table = $wpdb->prefix.'wpbot_response'; $response_result = array(); $status = array('status'=>'fail', 'multiple'=>false); $field = "ID"; if(($strid != '') && empty($response_result)){ $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 if(!empty($results)){ foreach($results as $result){ $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1); } } } $field = "query"; $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 if(!empty($results)){ foreach($results as $result){ $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1); } } $field = "category"; if(empty($response_result)){ $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 if(!empty($results)){ foreach($results as $result){ $response_result[] = array('id'=>$result->id,'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 wp_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 = qcld_strpro_remove_stopwords($keyword); } } if(empty($response_result)){ $fields = get_option('qc_bot_str_fields'); $allowed_fields = array('query', 'keyword', 'response'); $valid_fields = array(); if($fields && !empty($fields) && is_array($fields)){ foreach($fields as $field){ if(in_array($field, $allowed_fields)){ $valid_fields[] = '`' . $field . '`'; } } } if(!empty($valid_fields)){ $qfields = implode(', ', $valid_fields); }else{ $qfields = '`query`,`keyword`,`response`'; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $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) ); $weight = get_option('qc_bot_str_weight')!=''?get_option('qc_bot_str_weight'):'0.4'; if(!empty($results)){ $max_score = max(array_column($results, 'score')); if ($max_score <= 0) { $max_score = 1; // Set to 1 to avoid division by zero } foreach($results as $result){ if(($result->score/$max_score) >= $weight){ $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>$result->score); } } } } $field = "keyword"; if( empty( $response_result ) ){ $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 if(!empty($results)){ foreach($results as $result){ $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1); } } } 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); } } if(empty($result->query)){ $status = array('status'=>'fail', 'multiple'=>false, 'data'=>$response_result); } if(empty($status['data']) || (isset($status['status']) && $status['status']==='fail')){ // Check for space before question mark and try again. if(preg_match('/ \?$/', $keyword)){ $keyword2 = preg_replace('/ \?$/', '?', $keyword); // Try again with new keyword. // Repeat the main search logic with $keyword2. $response_result = array(); $field = "query"; $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 if(!empty($results)){ foreach($results as $result){ $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1); } if(count($response_result)>1){ $status = array('status'=>'success', 'multiple'=>true, 'data'=>$response_result); }else{ $status = array('status'=>'success', 'multiple'=>false, 'data'=>$response_result); } }else{ $status = array('status'=>'fail', 'multiple'=>false, 'data'=>[]); } } } if(empty($status['data']) || (isset($status['status']) && $status['status']==='fail')){ // Try a partial match if still nothing found. if(empty($status['data'])) { $keyword_like = '%' . preg_replace('/[\\s\\?]+/', '%', $keyword) . '%'; $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 $response_result = array(); if(!empty($results)){ foreach($results as $result){ $response_result[] = array('id'=>$result->id,'query'=>$result->query, 'response'=>$result->response, 'score'=>1); } if(count($response_result)>1){ $status = array('status'=>'success', 'multiple'=>true, 'data'=>$response_result); }else{ $status = array('status'=>'success', 'multiple'=>false, 'data'=>$response_result); } } else { $status = array('status'=>'fail', 'multiple'=>false, 'data'=>[], 'message'=>'Sorry, I found nothing'); } } } if(empty($status['data'])){ $status = array('status'=>'fail', 'multiple'=>false, 'data'=>[], 'message'=>'no result found'); } echo wp_json_encode($status); die(); } function qcld_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; } }