PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, AI Services / 8.5.9
WPBot – AI ChatBot for Live Support, Lead Generation, AI Services v8.5.9
8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 8.5.5 8.5.4 8.5.3 8.5.2 8.5.0 8.4.9 All 531 releases
chatbot / includes / class-common-function.php

class-common-function.php in WPBot – AI ChatBot for Live Support, Lead Generation, AI Services 8.5.9, at includes/class-common-function.php

363 lines 14.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) exit; // Exit if accessed directly
3 /**
4 * Common functions class
5 */
6 class Qcld_WPBot_Common_Functions {
7
8
9 private static $instance = null;
10
11 public static function instance() {
12 if ( is_null( self::$instance ) ) {
13 self::$instance = new self();
14 }
15 return self::$instance;
16 }
17
18 private function __construct() {
19 add_action('wp_ajax_wpbot_save_feedback', array( $this, 'wpbot_save_feedback') );
20 add_action('wp_ajax_nopriv_wpbot_save_feedback', array( $this,'wpbot_save_feedback') );
21 add_action( 'wp_ajax_wpbot_save_report', array( $this, 'wpbot_save_report') );
22 add_action( 'wp_ajax_nopriv_wpbot_save_report', array( $this, 'wpbot_save_report') );
23 add_action('wp_ajax_nopriv_get_relevant_pages', array($this, 'qcld_get_relevant_pages_ajax'));
24 add_action('wp_ajax_rate_limit_settings_option', array($this, 'rate_limit_settings_option_callback'));
25 register_activation_hook(__FILE__, array('qcld_wpopenai_addons', 'schedule_rate_limit_reset_events'));
26 add_filter('cron_schedules', array($this, 'qcld_user_role_rate_cron_schedule'));
27 add_action('rate_limit_checker', array($this, 'rate_limit_checker'));
28 add_action('qcld_openai_user_rate_cal', array($this, 'qcld_openai_user_rate_cal'));
29 add_action('reset_rate_limit_used_counts', [$this, 'reset_rate_limit_used_counts'], 10, 1);
30
31 }
32 /**
33 * Remove stopwords from search query
34 *
35 * @param string $query The search query
36 * @param array $stopwords Array of stopwords to remove
37 * @return string Query with stopwords removed
38 */
39 public static function qcpd_remove_wa_stopwords($query, $stopwords) {
40 return preg_replace('/\b('.implode('|',$stopwords).')\b/','',$query);
41 }
42
43 /**
44 * Get relevant page links based on search query
45 *
46 * @param string $search_query The search query
47 * @return array Array of relevant page links
48 */
49 public static function qcpd_relevant_pagelink($search_query) {
50 $stopwords = explode(',', get_option('qlcd_wp_chatbot_stop_words'));
51
52 $finalQueryWordsWithoutStopWords = self::qcpd_remove_wa_stopwords(strtolower($search_query), $stopwords);
53
54 $cleanWordsWithoutPunctuationMarks = preg_replace('/[\p{P}]/u', '', $finalQueryWordsWithoutStopWords);
55
56 $q = trim($cleanWordsWithoutPunctuationMarks);
57
58 $links = [];
59
60 $post_type_array = get_option('qcld_openai_relevant_post');
61
62 $the_query = new WP_Query(array(
63 'post_status' => 'publish',
64 'posts_per_page' => 5,
65 's' => esc_attr($q),
66 'post_type' => $post_type_array
67 ));
68
69 if($the_query->have_posts()) {
70 while($the_query->have_posts()) {
71 $the_query->the_post();
72
73 $url = esc_url(get_permalink());
74 $link = '<a href=' . $url . ' target="_blank">' . get_the_title() . '</a>';
75 array_push($links, $link);
76 }
77 wp_reset_postdata();
78 }
79
80 $links = array_unique($links);
81 return $links;
82 }
83
84
85 public function wpbot_save_feedback() {
86 check_ajax_referer('wp_chatbot', 'nonce');
87 global $wpdb;
88
89 $table = $wpdb->prefix . 'wpbot_chat_report';
90
91 $user_id = intval(wp_unslash($_POST['user_id']));
92 $conversation_id= intval(wp_unslash($_POST['conversation_id']));
93 $message = sanitize_text_field(wp_unslash($_POST['message']));
94 $feedback = sanitize_text_field(wp_unslash($_POST['feedback'])); // "like" or "dislike"
95 $meta_info = sanitize_textarea_field(wp_unslash($_POST['meta_info']));
96 $date = current_time('mysql');
97
98 $inserted = $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
99 $table, array(
100 'user_id' => $user_id,
101 'conversation_id'=> $conversation_id,
102 'message' => $message,
103 'feedback' => $feedback,
104 'meta_info' => $meta_info,
105 'created_at' => $date
106 ));
107
108 if ($inserted !== false) {
109 wp_send_json_success(array('message' => 'Feedback saved.'));
110 } else {
111 wp_send_json_error(array('message' => 'Failed to save feedback.'));
112 }
113 }
114
115 /**
116 * Save report func
117 *
118 */
119
120
121 public function wpbot_save_report() {
122 check_ajax_referer('wp_chatbot', 'nonce');
123 global $wpdb;
124 $table_report = $wpdb->prefix . 'wpbot_chat_report';
125
126 $email = sanitize_email(wp_unslash($_POST['email']));
127 $message = sanitize_textarea_field(wp_unslash($_POST['message']));
128 $report_text = sanitize_textarea_field(wp_unslash($_POST['report_text']));
129
130 $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
131 $table_report,
132 [
133 'user_id' => get_current_user_id(), // or match from wpbot_user.
134 'message' => $message,
135 'meta_info' => maybe_serialize( [ 'email' => $email, 'report_text' => $report_text ] ),
136 ],
137 [ '%d', '%s', '%s' ]
138 );
139
140 // Send report email to admin
141 $admin_email = get_option( 'admin_email' );
142 $subject = "New Chat Report";
143 $body = "Reported Message:\n{$message}\n\nReport Text:\n{$report_text}\n\nUser Email: {$email}";
144 wp_mail( $admin_email, $subject, $body );
145
146 wp_send_json_success();
147 }
148 public function rate_limit_settings_option_callback()
149 {
150
151 // Check is admin and verify nonce
152 if (! current_user_can('manage_options')) {
153 wp_send_json_error('Unauthorized');
154 wp_die();
155 }
156 check_ajax_referer( 'wp_chatbot', 'nonce' );
157 // Save the rate limiting enabled/disabled setting
158 if (isset($_POST['is_rate_limiting_enabled'])) {
159 $is_rate_limiting_enabled = intval( wp_unslash( $_POST['is_rate_limiting_enabled'] ) );
160 update_option('is_rate_limiting_enabled', $is_rate_limiting_enabled);
161 }
162 // Save the rate limits for each role
163 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
164 if (isset($_POST['rate_limits']) && is_array( $_POST['rate_limits'] )) {
165 $rate_limits = array_map( 'sanitize_text_field', wp_unslash( $_POST['rate_limits'] ) );
166 foreach ($rate_limits as $role => $limit) {
167 $option_name = 'rate_limit_' . sanitize_key( $role );
168 $limit_value = intval($limit);
169 update_option($option_name, $limit_value);
170 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
171 $timeframe_raw = isset( $_POST['rate_limit_timeframes'][ $role ] ) ? sanitize_text_field( wp_unslash( $_POST['rate_limit_timeframes'][ $role ] ) ) : '24';
172 $timeframe = intval($timeframe_raw) * 3600; // Convert hours to seconds
173 update_option('rate_limit_timeframe_' . $role, $timeframe);
174 }
175 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
176 $guest_timeframe_raw = isset( $_POST['rate_limit_timeframes']['guest'] ) ? sanitize_text_field( wp_unslash( $_POST['rate_limit_timeframes']['guest'] ) ) : '24';
177 $timeframe = intval($guest_timeframe_raw) * 3600; // Convert hours to seconds
178 update_option('rate_limit_timeframe_guest', $timeframe);
179 }
180 // In your rate_limit_settings_option_callback(), after updating options:
181 $this->schedule_rate_limit_reset_events();
182 wp_send_json_success('Settings saved');
183 wp_die();
184 }
185 public function qcld_user_role_rate_cron_schedule($schedules)
186 {
187 $roles = wp_roles()->roles;
188 foreach ($roles as $role => $details) {
189 $timeframe = intval(get_option('rate_limit_timeframe_' . $role, true));
190 // Minimum 3600 seconds
191 $schedules['session_schedules_rate_limit_' . $role] = array(
192 'interval' => $timeframe,
193 'display' => esc_html( 'session_schedules_rate_limit_' . $role ),
194 );
195 // Schedule the cron job for each role if not already scheduled);
196 }
197 return $schedules;
198 }
199 // wpshedule event to reset the rate limit used counts
200 public function schedule_rate_limit_reset_events()
201 {
202 // Ensure WordPress cron functions are available
203 if (! function_exists('wp_schedule_event')) {
204 require_once ABSPATH . 'wp-includes/wp-cron.php';
205 }
206 $roles = wp_roles()->roles;
207 foreach ($roles as $role => $d) {
208 // Unschedule all existing events for this role
209 $timestamp = wp_next_scheduled('reset_rate_limit_used_counts', array($role));
210 while ($timestamp) {
211 wp_unschedule_event($timestamp, 'reset_rate_limit_used_counts', array($role));
212 $timestamp = wp_next_scheduled('reset_rate_limit_used_counts', array($role));
213 }
214 // Schedule new event with updated interval
215 wp_schedule_event(time(), 'session_schedules_rate_limit_' . $role, 'reset_rate_limit_used_counts', array($role));
216 }
217 }
218 public function qcld_wpsession_cron_deactivation()
219 {
220 $timestamp = wp_next_scheduled('reset_rate_limit_used_counts');
221 wp_unschedule_event($timestamp, 'reset_rate_limit_used_counts');
222 }
223 public function rate_limit_checker()
224 {
225 $qlcd_wp_chatbot_ai_rate_limiting_message = qcld_wb_chatbot_func_str_replace(
226 maybe_unserialize(get_option('qlcd_wp_chatbot_ai_rate_limiting_message', true))
227 );
228 if (get_option('is_stream_enabled') == 1) {
229 $response = array(
230 'status' => 'error',
231 'message' => esc_html(
232 ( is_array( $qlcd_wp_chatbot_ai_rate_limiting_message ) && ! empty( $qlcd_wp_chatbot_ai_rate_limiting_message[0] ) )
233 ? $qlcd_wp_chatbot_ai_rate_limiting_message[0]
234 : __( 'Rate limit exceeded. Please try again later.', 'chatbot' )
235 ),
236 );
237 } else {
238 $response = array(
239 'status' => 'success',
240 'message' => esc_html(
241 ( is_array( $qlcd_wp_chatbot_ai_rate_limiting_message ) && ! empty( $qlcd_wp_chatbot_ai_rate_limiting_message[0] ) )
242 ? $qlcd_wp_chatbot_ai_rate_limiting_message[0]
243 : __( 'Rate limit exceeded. Please try again later.', 'chatbot' )
244 ),
245 );
246 }
247 if (is_user_logged_in()) {
248 $user = wp_get_current_user();
249 if (! empty($user->roles) && is_array($user->roles)) {
250 $role = $user->roles[0];
251 $option_name = 'rate_limit_' . $role;
252 $limit = get_option($option_name);
253 $rate_limit = get_user_meta(get_current_user_id(), 'qcld_openai_user_rate_limit', true);
254 if (($limit >= $rate_limit) || $limit == 0) {
255 return; // allowed
256 } else {
257 if (get_option('is_stream_enabled') == 1) {
258 wp_send_json($response); //Proper JSON with header.
259 } else {
260 echo json_encode($response);
261 wp_die();
262 }
263 }
264 }
265 } else {
266 $option_name = 'rate_limit_guest';
267 $limit = get_option($option_name);
268
269 if (session_status() == PHP_SESSION_NONE) {
270 session_start();
271 }
272
273 $guest_rate_limit = isset($_SESSION['guest_rate_limit']) ? intval($_SESSION['guest_rate_limit']) : 0;
274
275 if ($limit >= $guest_rate_limit || $limit == 0) {
276 return; // allowed
277 } else {
278 if (get_option('is_stream_enabled') == 1) {
279 wp_send_json($response); //Proper JSON with header.
280 } else {
281 echo json_encode($response);
282 // Return role if limit exceeded
283 wp_die();
284 }
285 }
286 }
287 }
288
289 public function reset_rate_limit_used_counts($role)
290 {
291 if (empty($role)) {
292 return;
293 }
294 // Resetting rate limit used counts for role.
295 // loop through each role
296 // for each role get all users with that role
297 $roles = wp_roles()->roles;
298 foreach ($roles as $list_roll => $details) {
299 if ($list_roll != $role) {
300 continue;
301 } else {
302 $option_name = 'rate_limit_' . $role;
303 $limit = get_option($option_name); // Default to if not set
304 $users = get_users(array('role' => $role));
305 foreach ($users as $user) {
306 update_user_meta($user->ID, 'qcld_openai_user_rate_limit', 0);
307 }
308 }
309 }
310 }
311 public function qcld_openai_user_rate_cal($update)
312 {
313 if (is_user_logged_in()) {
314 $rate_limit = get_user_meta(get_current_user_id(), 'qcld_openai_user_rate_limit', true);
315 if ($update != '') {
316 $rate_limit = intval($rate_limit) + intval($update);
317 }
318 update_user_meta(get_current_user_id(), 'qcld_openai_user_rate_limit', $rate_limit);
319 return;
320 } else {
321 // for guest users we will use session to store the rate limit
322 // if session is not started then start it
323 if (session_status() == PHP_SESSION_NONE) {
324 session_start();
325 }
326 // we will use guest_id to identify the guest user
327 if (! isset($_SESSION['guest_id'])) {
328 $user_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
329 $session_id = md5($user_ip . time());
330 $_SESSION['guest_id'] = $session_id;
331 $_SESSION['guest_id_time'][$session_id] = time();
332 get_option('rate_', 10);
333 // if guest_id_time is set and it is older than 24 hours then unset the guest_id
334 // we will store the time when the guest_id was created in session
335 $timeframe = get_option('rate_limit_timeframe_guest', true);
336 $timeframe = intval($timeframe) * 3600; // convert hours to seconds
337 if (isset($_SESSION['guest_id_time'][$session_id]) && (time() - $_SESSION['guest_id_time'][$session_id]) > $timeframe) {
338 unset($_SESSION['guest_id']);
339 unset($_SESSION['guest_id_time']);
340 }
341 // we will store the time when the guest_id was created in session
342 $_SESSION['guest_id_time'][$session_id] = time();
343 $_SESSION['guest_rate_limit'] = 0;
344 }
345 // update the rate limit
346 // if update is not empty then add it to the existing rate limit else set it
347 if ($update != '') {
348 $guest_rate_limit = isset($_SESSION['guest_rate_limit']) ? intval($_SESSION['guest_rate_limit']) : 0;
349 // add the update to the existing rate limit
350 // set the rate limit in session
351 $_SESSION['guest_rate_limit'] = $guest_rate_limit + $update;
352 return;
353 }
354 }
355 }
356
357 }
358
359 /**
360 * Instantiate the class
361 */
362 Qcld_WPBot_Common_Functions::instance();
363