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'] .=''. ( !empty($load_more) && isset($load_more[$default_language]) ? $load_more[$default_language] : 'Load More').' ';
}
}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'] .='
'. ( !empty($load_more) && isset($load_more[$default_language]) ? $load_more[$default_language] : 'Load More').' ';
$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;
}
}