PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 2.3.4
MxChat – AI Chatbot & Content Generation for WordPress v2.3.4
3.2.21 3.2.20 3.2.19 3.2.18 3.2.17 3.2.16 3.2.15 3.2.14 3.2.12 3.2.13 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 2.0.3 2.0.4 2.0.5 2.0.6 All 152 releases
← All changes | mxchat-basic.php +245 -33 2.0.32.3.4 View file →
@@ -1,9 +1,9 @@
1 1 <?php
2 2 /**
3 3 * Plugin Name: MxChat
4 4 * Description: AI chatbot for WordPress with OpenAI, Claude, xAI, DeepSeek, live agent, PDF uploads, WooCommerce, and training on website data.
5 - * Version: 2.0.3
5 + * Version: 2.3.4
6 6 * Author: MxChat
7 7 * Author URI: https://mxchat.ai
8 8 * License: GPLv2 or later
9 9 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -14,8 +14,10 @@
14 14 if (!defined('ABSPATH')) {
15 15 exit; // Exit if accessed directly.
16 16 }
17 17
18 +// Define plugin version constant for asset versioning
19 +define('MXCHAT_VERSION', '2.3.4');
18 20
19 21 function mxchat_load_textdomain() {
20 22 load_plugin_textdomain('mxchat', false, dirname(plugin_basename(__FILE__)) . '/languages');
21 23 }
@@ -20,18 +22,33 @@
20 22 load_plugin_textdomain('mxchat', false, dirname(plugin_basename(__FILE__)) . '/languages');
21 23 }
22 24 add_action('plugins_loaded', 'mxchat_load_textdomain');
23 25
24 -// Include classes
25 -require_once plugin_dir_path(__FILE__) . 'includes/class-mxchat-integrator.php';
26 -require_once plugin_dir_path(__FILE__) . 'includes/class-mxchat-admin.php';
27 -require_once plugin_dir_path(__FILE__) . 'includes/class-mxchat-public.php';
28 -require_once plugin_dir_path(__FILE__) . 'includes/class-mxchat-utils.php';
29 -require_once plugin_dir_path(__FILE__) . 'includes/class-mxchat-user.php';
30 -require_once plugin_dir_path(__FILE__) . 'includes/class-mxchat-woocommerce.php';
31 -require_once plugin_dir_path(__FILE__) . 'includes/pdf-parser/alt_autoload.php';
32 -require_once plugin_dir_path(__FILE__) . 'includes/class-mxchat-word-handler.php';
26 +// Include classes with error handling
27 +function mxchat_include_classes() {
28 + $class_files = array(
29 + 'includes/class-mxchat-integrator.php',
30 + 'includes/class-mxchat-admin.php',
31 + 'includes/class-mxchat-public.php',
32 + 'includes/class-mxchat-utils.php',
33 + 'includes/class-mxchat-user.php',
34 + 'includes/pdf-parser/alt_autoload.php',
35 + 'includes/class-mxchat-word-handler.php',
36 + 'admin/class-ajax-handler.php',
37 + 'admin/class-pinecone-manager.php',
38 + 'admin/class-knowledge-manager.php'
39 + );
33 40
41 + foreach ($class_files as $file) {
42 + $file_path = plugin_dir_path(__FILE__) . $file;
43 + if (file_exists($file_path)) {
44 + require_once $file_path;
45 + } else {
46 + error_log('MxChat: Missing class file - ' . $file);
47 + }
48 + }
49 +}
50 +
34 51 function mxchat_activate() {
35 52 global $wpdb;
36 53 $charset_collate = $wpdb->get_charset_collate();
37 54
@@ -88,14 +105,87 @@
88 105 mxchat_add_missing_columns($system_prompt_table, 'source_url', 'VARCHAR(255) DEFAULT NULL');
89 106
90 107 // Set default thresholds for existing intents
91 108 $wpdb->query("UPDATE {$intents_table} SET similarity_threshold = 0.85 WHERE similarity_threshold IS NULL");
109 + mxchat_add_missing_columns($intents_table, 'enabled', 'TINYINT(1) NOT NULL DEFAULT 1');
92 110
93 - // Update plugin version in the database
94 - update_option('mxchat_plugin_version', '2.0.3');
111 + // SETUP CRON JOB HERE (ONCE ON ACTIVATION)
112 + mxchat_setup_cron_jobs();
113 +
114 + // Use the constant instead of hardcoded version
115 + update_option('mxchat_plugin_version', MXCHAT_VERSION);
95 116 }
96 117
118 +/**
119 + * Setup cron jobs on plugin activation
120 + */
121 +function mxchat_setup_cron_jobs() {
122 + // Clear any existing cron jobs first
123 + wp_clear_scheduled_hook('mxchat_reset_rate_limits');
124 +
125 + // Check if WordPress cron is disabled
126 + if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
127 + // Set flag to use fallback system
128 + update_option('mxchat_use_fallback_rate_limits', true);
129 + update_option('mxchat_next_rate_limit_check', time() + 3600);
130 + error_log('MxChat: WordPress cron disabled, using fallback system');
131 + return;
132 + }
133 +
134 + // Schedule the rate limit reset cron job
135 + $result = wp_schedule_event(time() + 300, 'hourly', 'mxchat_reset_rate_limits');
136 +
137 + if ($result === false) {
138 + // Fallback if scheduling fails
139 + update_option('mxchat_use_fallback_rate_limits', true);
140 + update_option('mxchat_next_rate_limit_check', time() + 3600);
141 + error_log('MxChat: Failed to schedule cron on activation, using fallback');
142 + } else {
143 + // Clear fallback flags if cron scheduling succeeded
144 + delete_option('mxchat_use_fallback_rate_limits');
145 + error_log('MxChat: Successfully scheduled cron on activation');
146 + }
147 +}
97 148
149 +/**
150 + * Clean up on plugin deactivation
151 + */
152 +function mxchat_deactivate() {
153 + // Clear scheduled cron jobs
154 + wp_clear_scheduled_hook('mxchat_reset_rate_limits');
155 +
156 + // Clear fallback options
157 + delete_option('mxchat_use_fallback_rate_limits');
158 + delete_option('mxchat_next_rate_limit_check');
159 + delete_option('mxchat_fallback_check_interval');
160 +
161 + error_log('MxChat: Cleaned up cron jobs on deactivation');
162 +}
163 +
164 +/**
165 + * Check if fallback rate limit cleanup is needed
166 + */
167 +function mxchat_check_fallback_rate_limits() {
168 + $use_fallback = get_option('mxchat_use_fallback_rate_limits', false);
169 +
170 + if (!$use_fallback) {
171 + return;
172 + }
173 +
174 + $next_check = get_option('mxchat_next_rate_limit_check', 0);
175 +
176 + if (time() >= $next_check) {
177 + // Only run reset if the MxChat_Integrator class exists
178 + if (class_exists('MxChat_Integrator')) {
179 + $integrator = new MxChat_Integrator();
180 + if (method_exists($integrator, 'mxchat_reset_rate_limits')) {
181 + $integrator->mxchat_reset_rate_limits();
182 + update_option('mxchat_next_rate_limit_check', time() + 3600);
183 + }
184 + }
185 + }
186 +}
187 +
98 188 function mxchat_add_missing_columns($table, $column_name, $column_type) {
99 189 global $wpdb;
100 190 $column_exists = $wpdb->get_results($wpdb->prepare("SHOW COLUMNS FROM $table LIKE %s", $column_name));
101 191 if (empty($column_exists)) {
@@ -103,18 +193,76 @@
103 193 }
104 194 }
105 195
106 196 function mxchat_check_for_update() {
107 - $current_version = get_option('mxchat_plugin_version');
108 - $plugin_version = '2.0.3'; // Update with your latest version
197 + try {
198 + $current_version = get_option('mxchat_plugin_version');
199 + $plugin_version = MXCHAT_VERSION;
109 200
110 - if ($current_version !== $plugin_version) {
111 - mxchat_activate(); // Run the activation script to apply schema changes
112 - mxchat_migrate_live_agent_status(); // Add migration for live agent status
113 - update_option('mxchat_plugin_version', $plugin_version); // Update the version
201 + if ($current_version !== $plugin_version) {
202 + // Run live agent update BEFORE updating the stored version
203 + mxchat_handle_live_agent_update();
204 +
205 + // Run existing update processes
206 + mxchat_activate();
207 + mxchat_migrate_live_agent_status();
208 +
209 + // Add the new cleanup function for version 2.1.8
210 + if (version_compare($current_version, '2.1.8', '<')) {
211 + $deleted = mxchat_cleanup_orphaned_chat_history();
212 + }
213 +
214 + // Update version LAST so the live agent update logic can work
215 + update_option('mxchat_plugin_version', $plugin_version);
216 + }
217 + } catch (Exception $e) {
218 + error_log('MxChat update error: ' . $e->getMessage());
219 + // Don't update version if there was an error
114 220 }
115 221 }
116 222
223 +/**
224 + * Clean up orphaned chat history options from the wp_options table
225 + * @return int Number of options deleted
226 + */
227 +function mxchat_cleanup_orphaned_chat_history() {
228 + global $wpdb;
229 + $count = 0;
230 +
231 + // Get all option keys that match our pattern
232 + $history_options = $wpdb->get_results(
233 + "SELECT option_name FROM {$wpdb->options}
234 + WHERE option_name LIKE 'mxchat_history_%'"
235 + );
236 +
237 + if (!empty($history_options)) {
238 + foreach ($history_options as $option) {
239 + // Extract the session ID from the option name
240 + $session_id = str_replace('mxchat_history_', '', $option->option_name);
241 +
242 + // Check if this session still exists in the custom table
243 + $table_name = $wpdb->prefix . 'mxchat_chat_transcripts';
244 + $exists = $wpdb->get_var(
245 + $wpdb->prepare(
246 + "SELECT COUNT(*) FROM {$table_name} WHERE session_id = %s",
247 + $session_id
248 + )
249 + );
250 +
251 + // If session doesn't exist in the main table, delete the option
252 + if ($exists == 0) {
253 + delete_option($option->option_name);
254 + // Also delete related metadata
255 + delete_option("mxchat_email_{$session_id}");
256 + delete_option("mxchat_agent_name_{$session_id}");
257 + $count++;
258 + }
259 + }
260 + }
261 +
262 + return $count;
263 +}
264 +
117 265 function mxchat_migrate_live_agent_status() {
118 266 $options = get_option('mxchat_options', []);
119 267
120 268 // Check if live_agent_status exists
@@ -145,16 +293,90 @@
145 293 update_option('mxchat_options', $options);
146 294 }
147 295 }
148 296
297 +function mxchat_handle_live_agent_update() {
298 + // Get the CURRENT stored version (before it gets updated)
299 + $current_version = get_option('mxchat_plugin_version', '0.0.0');
300 + $new_version = '2.2.2';
301 +
302 + // Only run this once for the update to 2.2.2
303 + $update_handled = get_option('mxchat_live_agent_update_2_2_2_handled', false);
304 +
305 + // Check if we're upgrading TO 2.2.2 and haven't handled this yet
306 + if (version_compare($current_version, $new_version, '<') && !$update_handled) {
307 + $options = get_option('mxchat_options', array());
308 +
309 + // Check if live agent was previously enabled
310 + if (isset($options['live_agent_status']) && $options['live_agent_status'] === 'on') {
311 + // Disable live agent
312 + $options['live_agent_status'] = 'off';
313 + update_option('mxchat_options', $options);
314 +
315 + // Set flag to show the notification banner
316 + update_option('mxchat_show_live_agent_disabled_notice', true);
317 + }
318 +
319 + // Mark this update as handled
320 + update_option('mxchat_live_agent_update_2_2_2_handled', true);
321 + }
322 +}
149 323
150 -// Run the update check function on every request
151 -add_action('plugins_loaded', 'mxchat_check_for_update');
324 +// Initialize plugin safely
325 +function mxchat_init() {
326 + // Include all class files first
327 + mxchat_include_classes();
328 +
329 + // Run update check
330 + mxchat_check_for_update();
331 +
332 + // Add fallback rate limit check
333 + add_action('init', 'mxchat_check_fallback_rate_limits', 5);
334 +
335 + // Initialize classes with error handling
336 + try {
337 + // Initialize admin classes
338 + if (is_admin()) {
339 + if (class_exists('MxChat_Knowledge_Manager')) {
340 + $mxchat_knowledge_manager = new MxChat_Knowledge_Manager();
341 +
342 + if (class_exists('MxChat_Admin')) {
343 + $mxchat_admin = new MxChat_Admin($mxchat_knowledge_manager);
344 + }
345 + }
346 + }
347 +
348 + // Initialize public classes
349 + if (class_exists('MxChat_Public')) {
350 + $mxchat_public = new MxChat_Public();
351 + }
352 +
353 + if (class_exists('MxChat_Integrator')) {
354 + $mxchat_integrator = new MxChat_Integrator();
355 + }
356 +
357 + } catch (Exception $e) {
358 + error_log('MxChat initialization error: ' . $e->getMessage());
359 +
360 + // Show admin notice if there's an error
361 + if (is_admin()) {
362 + add_action('admin_notices', function() use ($e) {
363 + echo '<div class="notice notice-error"><p>';
364 + echo '<strong>MxChat Error:</strong> Plugin initialization failed. ';
365 + echo 'Please check error logs or contact support. Error: ' . esc_html($e->getMessage());
366 + echo '</p></div>';
367 + });
368 + }
369 + }
370 +}
152 371
372 +// Run initialization on plugins_loaded
373 +add_action('plugins_loaded', 'mxchat_init');
374 +
153 375 // Register activation hook
154 376 register_activation_hook(__FILE__, 'mxchat_activate');
155 377
156 -
378 +// Add cron schedule
157 379 add_filter('cron_schedules', function($schedules) {
158 380 $schedules['one_minute'] = array(
159 381 'interval' => 60,
160 382 'display' => 'Every Minute'
@@ -161,16 +383,6 @@
161 383 );
162 384 return $schedules;
163 385 });
164 386
165 -add_action('init', function() {
166 - add_action('mxchat_process_pdf_pages', array('MxChat_Admin', 'process_pdf_pages_cron'), 10, 5);
167 - add_action('mxchat_process_sitemap_urls', array('MxChat_Admin', 'process_sitemap_urls_cron'), 10, 5);
168 -});
169 -
170 -
171 -// Instantiate classes
172 -if (is_admin()) {
173 - $mxchat_admin = new MxChat_Admin();
174 -}
175 -$mxchat_public = new MxChat_Public();
176 -$mxchat_integrator = new MxChat_Integrator();
387 +// Register deactivation hook
388 +register_deactivation_hook(__FILE__, 'mxchat_deactivate');