PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 2.3.5
MxChat – AI Chatbot & Content Generation for WordPress v2.3.5
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 +279 -33 2.0.42.3.5 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.4
5 + * Version: 2.3.5
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.5');
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,60 @@
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 +
51 +/**
52 + * NEW: Create URL click tracking table
53 + */
54 +function mxchat_create_url_clicks_table() {
55 + global $wpdb;
56 +
57 + $table_name = $wpdb->prefix . 'mxchat_url_clicks';
58 +
59 + $charset_collate = $wpdb->get_charset_collate();
60 +
61 + $sql = "CREATE TABLE $table_name (
62 + id mediumint(9) NOT NULL AUTO_INCREMENT,
63 + session_id varchar(100) NOT NULL,
64 + clicked_url text NOT NULL,
65 + message_context text,
66 + click_timestamp datetime DEFAULT CURRENT_TIMESTAMP,
67 + user_ip varchar(45),
68 + user_agent text,
69 + PRIMARY KEY (id),
70 + KEY session_id (session_id),
71 + KEY click_timestamp (click_timestamp)
72 + ) $charset_collate;";
73 +
74 + require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
75 + dbDelta($sql);
76 +}
77 +
34 78 function mxchat_activate() {
35 79 global $wpdb;
36 80 $charset_collate = $wpdb->get_charset_collate();
37 81
@@ -78,11 +122,18 @@
78 122 dbDelta($sql_chat_transcripts);
79 123 dbDelta($sql_system_prompt);
80 124 dbDelta($sql_intents_table);
81 125
126 + // NEW: Create URL click tracking table
127 + mxchat_create_url_clicks_table();
128 +
82 129 // Ensure additional columns in `mxchat_chat_transcripts`
83 130 mxchat_add_missing_columns($chat_transcripts_table, 'user_identifier', 'VARCHAR(255)');
84 131 mxchat_add_missing_columns($chat_transcripts_table, 'user_email', 'VARCHAR(255) DEFAULT NULL');
132 +
133 + // NEW: Add originating page tracking columns
134 + mxchat_add_missing_columns($chat_transcripts_table, 'originating_page_url', 'TEXT DEFAULT NULL');
135 + mxchat_add_missing_columns($chat_transcripts_table, 'originating_page_title', 'VARCHAR(500) DEFAULT NULL');
85 136
86 137 // Ensure additional columns in `mxchat_system_prompt_content`
87 138 mxchat_add_missing_columns($system_prompt_table, 'embedding_vector', 'LONGTEXT');
88 139 mxchat_add_missing_columns($system_prompt_table, 'source_url', 'VARCHAR(255) DEFAULT NULL');
@@ -88,14 +139,87 @@
88 139 mxchat_add_missing_columns($system_prompt_table, 'source_url', 'VARCHAR(255) DEFAULT NULL');
89 140
90 141 // Set default thresholds for existing intents
91 142 $wpdb->query("UPDATE {$intents_table} SET similarity_threshold = 0.85 WHERE similarity_threshold IS NULL");
143 + mxchat_add_missing_columns($intents_table, 'enabled', 'TINYINT(1) NOT NULL DEFAULT 1');
92 144
93 - // Update plugin version in the database
94 - update_option('mxchat_plugin_version', '2.0.4');
145 + // SETUP CRON JOB HERE (ONCE ON ACTIVATION)
146 + mxchat_setup_cron_jobs();
147 +
148 + // Use the constant instead of hardcoded version
149 + update_option('mxchat_plugin_version', MXCHAT_VERSION);
95 150 }
96 151
152 +/**
153 + * Setup cron jobs on plugin activation
154 + */
155 +function mxchat_setup_cron_jobs() {
156 + // Clear any existing cron jobs first
157 + wp_clear_scheduled_hook('mxchat_reset_rate_limits');
158 +
159 + // Check if WordPress cron is disabled
160 + if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
161 + // Set flag to use fallback system
162 + update_option('mxchat_use_fallback_rate_limits', true);
163 + update_option('mxchat_next_rate_limit_check', time() + 3600);
164 + //error_log('MxChat: WordPress cron disabled, using fallback system');
165 + return;
166 + }
167 +
168 + // Schedule the rate limit reset cron job
169 + $result = wp_schedule_event(time() + 300, 'hourly', 'mxchat_reset_rate_limits');
170 +
171 + if ($result === false) {
172 + // Fallback if scheduling fails
173 + update_option('mxchat_use_fallback_rate_limits', true);
174 + update_option('mxchat_next_rate_limit_check', time() + 3600);
175 + //error_log('MxChat: Failed to schedule cron on activation, using fallback');
176 + } else {
177 + // Clear fallback flags if cron scheduling succeeded
178 + delete_option('mxchat_use_fallback_rate_limits');
179 + //error_log('MxChat: Successfully scheduled cron on activation');
180 + }
181 +}
97 182
183 +/**
184 + * Clean up on plugin deactivation
185 + */
186 +function mxchat_deactivate() {
187 + // Clear scheduled cron jobs
188 + wp_clear_scheduled_hook('mxchat_reset_rate_limits');
189 +
190 + // Clear fallback options
191 + delete_option('mxchat_use_fallback_rate_limits');
192 + delete_option('mxchat_next_rate_limit_check');
193 + delete_option('mxchat_fallback_check_interval');
194 +
195 + //error_log('MxChat: Cleaned up cron jobs on deactivation');
196 +}
197 +
198 +/**
199 + * Check if fallback rate limit cleanup is needed
200 + */
201 +function mxchat_check_fallback_rate_limits() {
202 + $use_fallback = get_option('mxchat_use_fallback_rate_limits', false);
203 +
204 + if (!$use_fallback) {
205 + return;
206 + }
207 +
208 + $next_check = get_option('mxchat_next_rate_limit_check', 0);
209 +
210 + if (time() >= $next_check) {
211 + // Only run reset if the MxChat_Integrator class exists
212 + if (class_exists('MxChat_Integrator')) {
213 + $integrator = new MxChat_Integrator();
214 + if (method_exists($integrator, 'mxchat_reset_rate_limits')) {
215 + $integrator->mxchat_reset_rate_limits();
216 + update_option('mxchat_next_rate_limit_check', time() + 3600);
217 + }
218 + }
219 + }
220 +}
221 +
98 222 function mxchat_add_missing_columns($table, $column_name, $column_type) {
99 223 global $wpdb;
100 224 $column_exists = $wpdb->get_results($wpdb->prepare("SHOW COLUMNS FROM $table LIKE %s", $column_name));
101 225 if (empty($column_exists)) {
@@ -103,18 +227,76 @@
103 227 }
104 228 }
105 229
106 230 function mxchat_check_for_update() {
107 - $current_version = get_option('mxchat_plugin_version');
108 - $plugin_version = '2.0.4'; // Update with your latest version
231 + try {
232 + $current_version = get_option('mxchat_plugin_version');
233 + $plugin_version = MXCHAT_VERSION;
109 234
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
235 + if ($current_version !== $plugin_version) {
236 + // Run live agent update BEFORE updating the stored version
237 + mxchat_handle_live_agent_update();
238 +
239 + // Run existing update processes
240 + mxchat_activate();
241 + mxchat_migrate_live_agent_status();
242 +
243 + // Add the new cleanup function for version 2.1.8
244 + if (version_compare($current_version, '2.1.8', '<')) {
245 + $deleted = mxchat_cleanup_orphaned_chat_history();
246 + }
247 +
248 + // Update version LAST so the live agent update logic can work
249 + update_option('mxchat_plugin_version', $plugin_version);
250 + }
251 + } catch (Exception $e) {
252 + //error_log('MxChat update error: ' . $e->getMessage());
253 + // Don't update version if there was an error
114 254 }
115 255 }
116 256
257 +/**
258 + * Clean up orphaned chat history options from the wp_options table
259 + * @return int Number of options deleted
260 + */
261 +function mxchat_cleanup_orphaned_chat_history() {
262 + global $wpdb;
263 + $count = 0;
264 +
265 + // Get all option keys that match our pattern
266 + $history_options = $wpdb->get_results(
267 + "SELECT option_name FROM {$wpdb->options}
268 + WHERE option_name LIKE 'mxchat_history_%'"
269 + );
270 +
271 + if (!empty($history_options)) {
272 + foreach ($history_options as $option) {
273 + // Extract the session ID from the option name
274 + $session_id = str_replace('mxchat_history_', '', $option->option_name);
275 +
276 + // Check if this session still exists in the custom table
277 + $table_name = $wpdb->prefix . 'mxchat_chat_transcripts';
278 + $exists = $wpdb->get_var(
279 + $wpdb->prepare(
280 + "SELECT COUNT(*) FROM {$table_name} WHERE session_id = %s",
281 + $session_id
282 + )
283 + );
284 +
285 + // If session doesn't exist in the main table, delete the option
286 + if ($exists == 0) {
287 + delete_option($option->option_name);
288 + // Also delete related metadata
289 + delete_option("mxchat_email_{$session_id}");
290 + delete_option("mxchat_agent_name_{$session_id}");
291 + $count++;
292 + }
293 + }
294 + }
295 +
296 + return $count;
297 +}
298 +
117 299 function mxchat_migrate_live_agent_status() {
118 300 $options = get_option('mxchat_options', []);
119 301
120 302 // Check if live_agent_status exists
@@ -145,16 +327,90 @@
145 327 update_option('mxchat_options', $options);
146 328 }
147 329 }
148 330
331 +function mxchat_handle_live_agent_update() {
332 + // Get the CURRENT stored version (before it gets updated)
333 + $current_version = get_option('mxchat_plugin_version', '0.0.0');
334 + $new_version = '2.2.2';
335 +
336 + // Only run this once for the update to 2.2.2
337 + $update_handled = get_option('mxchat_live_agent_update_2_2_2_handled', false);
338 +
339 + // Check if we're upgrading TO 2.2.2 and haven't handled this yet
340 + if (version_compare($current_version, $new_version, '<') && !$update_handled) {
341 + $options = get_option('mxchat_options', array());
342 +
343 + // Check if live agent was previously enabled
344 + if (isset($options['live_agent_status']) && $options['live_agent_status'] === 'on') {
345 + // Disable live agent
346 + $options['live_agent_status'] = 'off';
347 + update_option('mxchat_options', $options);
348 +
349 + // Set flag to show the notification banner
350 + update_option('mxchat_show_live_agent_disabled_notice', true);
351 + }
352 +
353 + // Mark this update as handled
354 + update_option('mxchat_live_agent_update_2_2_2_handled', true);
355 + }
356 +}
149 357
150 -// Run the update check function on every request
151 -add_action('plugins_loaded', 'mxchat_check_for_update');
358 +// Initialize plugin safely
359 +function mxchat_init() {
360 + // Include all class files first
361 + mxchat_include_classes();
362 +
363 + // Run update check
364 + mxchat_check_for_update();
365 +
366 + // Add fallback rate limit check
367 + add_action('init', 'mxchat_check_fallback_rate_limits', 5);
368 +
369 + // Initialize classes with error handling
370 + try {
371 + // Initialize admin classes
372 + if (is_admin()) {
373 + if (class_exists('MxChat_Knowledge_Manager')) {
374 + $mxchat_knowledge_manager = new MxChat_Knowledge_Manager();
375 +
376 + if (class_exists('MxChat_Admin')) {
377 + $mxchat_admin = new MxChat_Admin($mxchat_knowledge_manager);
378 + }
379 + }
380 + }
381 +
382 + // Initialize public classes
383 + if (class_exists('MxChat_Public')) {
384 + $mxchat_public = new MxChat_Public();
385 + }
386 +
387 + if (class_exists('MxChat_Integrator')) {
388 + $mxchat_integrator = new MxChat_Integrator();
389 + }
390 +
391 + } catch (Exception $e) {
392 + //error_log('MxChat initialization error: ' . $e->getMessage());
393 +
394 + // Show admin notice if there's an error
395 + if (is_admin()) {
396 + add_action('admin_notices', function() use ($e) {
397 + echo '<div class="notice notice-error"><p>';
398 + echo '<strong>MxChat Error:</strong> Plugin initialization failed. ';
399 + echo 'Please check error logs or contact support. Error: ' . esc_html($e->getMessage());
400 + echo '</p></div>';
401 + });
402 + }
403 + }
404 +}
152 405
406 +// Run initialization on plugins_loaded
407 +add_action('plugins_loaded', 'mxchat_init');
408 +
153 409 // Register activation hook
154 410 register_activation_hook(__FILE__, 'mxchat_activate');
155 411
156 -
412 +// Add cron schedule
157 413 add_filter('cron_schedules', function($schedules) {
158 414 $schedules['one_minute'] = array(
159 415 'interval' => 60,
160 416 'display' => 'Every Minute'
@@ -161,16 +417,6 @@
161 417 );
162 418 return $schedules;
163 419 });
164 420
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();
421 +// Register deactivation hook
422 +register_deactivation_hook(__FILE__, 'mxchat_deactivate');