PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.3.8
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.3.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 8.5.2 All 533 releases
← All changes | includes/class-common-function.php +354 -362 8.5.78.3.8 View file →
@@ -1,362 +1,354 @@
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();
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($table, array(
99 + 'user_id' => $user_id,
100 + 'conversation_id'=> $conversation_id,
101 + 'message' => $message,
102 + 'feedback' => $feedback,
103 + 'meta_info' => $meta_info,
104 + 'created_at' => $date
105 + ));
106 +
107 + if ($inserted !== false) {
108 + wp_send_json_success(array('message' => 'Feedback saved.'));
109 + } else {
110 + wp_send_json_error(array('message' => 'Failed to save feedback.'));
111 + }
112 + }
113 +
114 + /**
115 + * Save report func
116 + *
117 + */
118 +
119 +
120 + public function wpbot_save_report() {
121 + check_ajax_referer('wp_chatbot', 'nonce');
122 + global $wpdb;
123 + $table_report = $wpdb->prefix . 'wpbot_chat_report';
124 +
125 + $email = sanitize_email(wp_unslash($_POST['email']));
126 + $message = sanitize_textarea_field(wp_unslash($_POST['message']));
127 + $report_text = sanitize_textarea_field(wp_unslash($_POST['report_text']));
128 +
129 + $wpdb->insert(
130 + $table_report,
131 + [
132 + 'user_id' => get_current_user_id(), // or match from wpbot_user.
133 + 'message' => $message,
134 + 'meta_info' => maybe_serialize( [ 'email' => $email, 'report_text' => $report_text ] ),
135 + ],
136 + [ '%d', '%s', '%s' ]
137 + );
138 +
139 + // Send report email to admin
140 + $admin_email = get_option( 'admin_email' );
141 + $subject = "New Chat Report";
142 + $body = "Reported Message:\n{$message}\n\nReport Text:\n{$report_text}\n\nUser Email: {$email}";
143 + wp_mail( $admin_email, $subject, $body );
144 +
145 + wp_send_json_success();
146 + }
147 + public function rate_limit_settings_option_callback()
148 + {
149 +
150 + // Check is admin and verify nonce
151 + if (! current_user_can('manage_options')) {
152 + wp_send_json_error('Unauthorized');
153 + wp_die();
154 + }
155 + check_ajax_referer( 'wp_chatbot', 'nonce' );
156 + // Save the rate limiting enabled/disabled setting
157 + if (isset($_POST['is_rate_limiting_enabled'])) {
158 + $is_rate_limiting_enabled = intval( wp_unslash( $_POST['is_rate_limiting_enabled'] ) );
159 + update_option('is_rate_limiting_enabled', $is_rate_limiting_enabled);
160 + }
161 + // Save the rate limits for each role
162 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
163 + if (isset($_POST['rate_limits']) && is_array( $_POST['rate_limits'] )) {
164 + $rate_limits = array_map( 'sanitize_text_field', wp_unslash( $_POST['rate_limits'] ) );
165 + foreach ($rate_limits as $role => $limit) {
166 + $option_name = 'rate_limit_' . sanitize_key( $role );
167 + $limit_value = intval($limit);
168 + update_option($option_name, $limit_value);
169 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
170 + $timeframe_raw = isset( $_POST['rate_limit_timeframes'][ $role ] ) ? sanitize_text_field( wp_unslash( $_POST['rate_limit_timeframes'][ $role ] ) ) : '24';
171 + $timeframe = intval($timeframe_raw) * 3600; // Convert hours to seconds
172 + update_option('rate_limit_timeframe_' . $role, $timeframe);
173 + }
174 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
175 + $guest_timeframe_raw = isset( $_POST['rate_limit_timeframes']['guest'] ) ? sanitize_text_field( wp_unslash( $_POST['rate_limit_timeframes']['guest'] ) ) : '24';
176 + $timeframe = intval($guest_timeframe_raw) * 3600; // Convert hours to seconds
177 + update_option('rate_limit_timeframe_guest', $timeframe);
178 + }
179 + // In your rate_limit_settings_option_callback(), after updating options:
180 + $this->schedule_rate_limit_reset_events();
181 + wp_send_json_success('Settings saved');
182 + wp_die();
183 + }
184 + public function qcld_user_role_rate_cron_schedule($schedules)
185 + {
186 + $roles = wp_roles()->roles;
187 + foreach ($roles as $role => $details) {
188 + $timeframe = intval(get_option('rate_limit_timeframe_' . $role, true));
189 + // Minimum 3600 seconds
190 + $schedules['session_schedules_rate_limit_' . $role] = array(
191 + 'interval' => $timeframe,
192 + 'display' => esc_html( 'session_schedules_rate_limit_' . $role ),
193 + );
194 + // Schedule the cron job for each role if not already scheduled);
195 + }
196 + return $schedules;
197 + }
198 + // wpshedule event to reset the rate limit used counts
199 + public function schedule_rate_limit_reset_events()
200 + {
201 + // Ensure WordPress cron functions are available
202 + if (! function_exists('wp_schedule_event')) {
203 + require_once ABSPATH . 'wp-includes/wp-cron.php';
204 + }
205 + $roles = wp_roles()->roles;
206 + foreach ($roles as $role => $d) {
207 + // Unschedule all existing events for this role
208 + $timestamp = wp_next_scheduled('reset_rate_limit_used_counts', array($role));
209 + while ($timestamp) {
210 + wp_unschedule_event($timestamp, 'reset_rate_limit_used_counts', array($role));
211 + $timestamp = wp_next_scheduled('reset_rate_limit_used_counts', array($role));
212 + }
213 + // Schedule new event with updated interval
214 + wp_schedule_event(time(), 'session_schedules_rate_limit_' . $role, 'reset_rate_limit_used_counts', array($role));
215 + }
216 + }
217 + public function qcld_wpsession_cron_deactivation()
218 + {
219 + $timestamp = wp_next_scheduled('reset_rate_limit_used_counts');
220 + wp_unschedule_event($timestamp, 'reset_rate_limit_used_counts');
221 + }
222 + public function rate_limit_checker()
223 + {
224 + $qlcd_wp_chatbot_ai_rate_limiting_message = qcld_wb_chatbot_func_str_replace(
225 + maybe_unserialize(get_option('qlcd_wp_chatbot_ai_rate_limiting_message', true))
226 + );
227 + if (get_option('is_stream_enabled') == 1) {
228 + $response = array(
229 + 'status' => 'error',
230 + 'message' => esc_html__((is_array($qlcd_wp_chatbot_ai_rate_limiting_message) && !empty($qlcd_wp_chatbot_ai_rate_limiting_message[0]) ? $qlcd_wp_chatbot_ai_rate_limiting_message[0] : 'Rate limit exceeded. Please try again later.'), 'chatbot'),
231 +
232 + );
233 + } else {
234 + $response = array(
235 + 'status' => 'success',
236 + 'message' => esc_html__((is_array($qlcd_wp_chatbot_ai_rate_limiting_message) && !empty($qlcd_wp_chatbot_ai_rate_limiting_message[0]) ? $qlcd_wp_chatbot_ai_rate_limiting_message[0] : 'Rate limit exceeded. Please try again later.'), 'chatbot'),
237 + );
238 + }
239 + if (is_user_logged_in()) {
240 + $user = wp_get_current_user();
241 + if (! empty($user->roles) && is_array($user->roles)) {
242 + $role = $user->roles[0];
243 + $option_name = 'rate_limit_' . $role;
244 + $limit = get_option($option_name);
245 + $rate_limit = get_user_meta(get_current_user_id(), 'qcld_openai_user_rate_limit', true);
246 + if (($limit >= $rate_limit) || $limit == 0) {
247 + return; // allowed
248 + } else {
249 + if (get_option('is_stream_enabled') == 1) {
250 + wp_send_json($response); //Proper JSON with header.
251 + } else {
252 + echo json_encode($response);
253 + wp_die();
254 + }
255 + }
256 + }
257 + } else {
258 + $option_name = 'rate_limit_guest';
259 + $limit = get_option($option_name);
260 +
261 + if (session_status() == PHP_SESSION_NONE) {
262 + session_start();
263 + }
264 +
265 + $guest_rate_limit = isset($_SESSION['guest_rate_limit']) ? intval($_SESSION['guest_rate_limit']) : 0;
266 +
267 + if ($limit >= $guest_rate_limit || $limit == 0) {
268 + return; // allowed
269 + } else {
270 + if (get_option('is_stream_enabled') == 1) {
271 + wp_send_json($response); //Proper JSON with header.
272 + } else {
273 + echo json_encode($response);
274 + // Return role if limit exceeded
275 + wp_die();
276 + }
277 + }
278 + }
279 + }
280 +
281 + public function reset_rate_limit_used_counts($role)
282 + {
283 + if (empty($role)) {
284 + return;
285 + }
286 + // Resetting rate limit used counts for role.
287 + // loop through each role
288 + // for each role get all users with that role
289 + $roles = wp_roles()->roles;
290 + foreach ($roles as $list_roll => $details) {
291 + if ($list_roll != $role) {
292 + continue;
293 + } else {
294 + $option_name = 'rate_limit_' . $role;
295 + $limit = get_option($option_name); // Default to if not set
296 + $users = get_users(array('role' => $role));
297 + foreach ($users as $user) {
298 + update_user_meta($user->ID, 'qcld_openai_user_rate_limit', 0);
299 + }
300 + }
301 + }
302 + }
303 + public function qcld_openai_user_rate_cal($update)
304 + {
305 + if (is_user_logged_in()) {
306 + $rate_limit = get_user_meta(get_current_user_id(), 'qcld_openai_user_rate_limit', true);
307 + if ($update != '') {
308 + $rate_limit = intval($rate_limit) + intval($update);
309 + }
310 + update_user_meta(get_current_user_id(), 'qcld_openai_user_rate_limit', $rate_limit);
311 + return;
312 + } else {
313 + // for guest users we will use session to store the rate limit
314 + // if session is not started then start it
315 + if (session_status() == PHP_SESSION_NONE) {
316 + session_start();
317 + }
318 + // we will use guest_id to identify the guest user
319 + if (! isset($_SESSION['guest_id'])) {
320 + $user_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
321 + $session_id = md5($user_ip . time());
322 + $_SESSION['guest_id'] = $session_id;
323 + $_SESSION['guest_id_time'][$session_id] = time();
324 + get_option('rate_', 10);
325 + // if guest_id_time is set and it is older than 24 hours then unset the guest_id
326 + // we will store the time when the guest_id was created in session
327 + $timeframe = get_option('rate_limit_timeframe_guest', true);
328 + $timeframe = intval($timeframe) * 3600; // convert hours to seconds
329 + if (isset($_SESSION['guest_id_time'][$session_id]) && (time() - $_SESSION['guest_id_time'][$session_id]) > $timeframe) {
330 + unset($_SESSION['guest_id']);
331 + unset($_SESSION['guest_id_time']);
332 + }
333 + // we will store the time when the guest_id was created in session
334 + $_SESSION['guest_id_time'][$session_id] = time();
335 + $_SESSION['guest_rate_limit'] = 0;
336 + }
337 + // update the rate limit
338 + // if update is not empty then add it to the existing rate limit else set it
339 + if ($update != '') {
340 + $guest_rate_limit = isset($_SESSION['guest_rate_limit']) ? intval($_SESSION['guest_rate_limit']) : 0;
341 + // add the update to the existing rate limit
342 + // set the rate limit in session
343 + $_SESSION['guest_rate_limit'] = $guest_rate_limit + $update;
344 + return;
345 + }
346 + }
347 + }
348 +
349 +}
350 +
351 +/**
352 + * Instantiate the class
353 + */
354 +Qcld_WPBot_Common_Functions::instance();