PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 2.4.2
MxChat – AI Chatbot & Content Generation for WordPress v2.4.2
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
mxchat-basic / mxchat-basic.php

mxchat-basic.php in MxChat – AI Chatbot & Content Generation for WordPress 2.4.2, at mxchat-basic.php

752 lines 27.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: MxChat
4 * Description: AI chatbot for WordPress with OpenAI, Claude, xAI, DeepSeek, live agent, PDF uploads, WooCommerce, and training on website data.
5 * Version: 2.4.2
6 * Author: MxChat
7 * Author URI: https://mxchat.ai
8 * License: GPLv2 or later
9 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
10 * Text Domain: mxchat
11 * Domain Path: /languages
12 */
13
14 if (!defined('ABSPATH')) {
15 exit; // Exit if accessed directly.
16 }
17
18 // Define plugin version constant for asset versioning
19 define('MXCHAT_VERSION', '2.4.2');
20
21 function mxchat_load_textdomain() {
22 load_plugin_textdomain('mxchat', false, dirname(plugin_basename(__FILE__)) . '/languages');
23 }
24 add_action('plugins_loaded', 'mxchat_load_textdomain');
25
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/class-mxchat-meta-box.php',
35 'includes/pdf-parser/alt_autoload.php',
36 'includes/class-mxchat-word-handler.php',
37 'admin/class-ajax-handler.php',
38 'admin/class-pinecone-manager.php',
39 'admin/class-knowledge-manager.php'
40 );
41
42 foreach ($class_files as $file) {
43 $file_path = plugin_dir_path(__FILE__) . $file;
44 if (file_exists($file_path)) {
45 require_once $file_path;
46 } else {
47 //error_log('MxChat: Missing class file - ' . $file);
48 }
49 }
50 }
51
52 /**
53 * Create URL click tracking table
54 */
55 function mxchat_create_url_clicks_table() {
56 global $wpdb;
57
58 $table_name = $wpdb->prefix . 'mxchat_url_clicks';
59
60 $charset_collate = $wpdb->get_charset_collate();
61
62 $sql = "CREATE TABLE $table_name (
63 id mediumint(9) NOT NULL AUTO_INCREMENT,
64 session_id varchar(100) NOT NULL,
65 clicked_url text NOT NULL,
66 message_context text,
67 click_timestamp datetime DEFAULT CURRENT_TIMESTAMP,
68 user_ip varchar(45),
69 user_agent text,
70 PRIMARY KEY (id),
71 KEY session_id (session_id),
72 KEY click_timestamp (click_timestamp)
73 ) $charset_collate;";
74
75 require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
76 dbDelta($sql);
77 }
78
79 /**
80 * FIXED: Robust table creation and column management
81 */
82 function mxchat_create_chat_transcripts_table() {
83 global $wpdb;
84
85 $table_name = $wpdb->prefix . 'mxchat_chat_transcripts';
86 $charset_collate = $wpdb->get_charset_collate();
87
88 // Create table with ALL columns including user_name from the start
89 $sql = "CREATE TABLE $table_name (
90 id MEDIUMINT(9) NOT NULL AUTO_INCREMENT,
91 user_id MEDIUMINT(9) DEFAULT 0,
92 session_id VARCHAR(255) NOT NULL,
93 role VARCHAR(255) NOT NULL,
94 message TEXT NOT NULL,
95 user_email VARCHAR(255) DEFAULT NULL,
96 user_name VARCHAR(100) DEFAULT NULL,
97 user_identifier VARCHAR(255) DEFAULT NULL,
98 originating_page_url TEXT DEFAULT NULL,
99 originating_page_title VARCHAR(500) DEFAULT NULL,
100 timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
101 PRIMARY KEY (id),
102 KEY session_id (session_id),
103 KEY user_email (user_email),
104 KEY timestamp (timestamp)
105 ) $charset_collate;";
106
107 require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
108 $result = dbDelta($sql);
109
110 // Log the result for debugging
111 if (empty($result)) {
112 //error_log("MxChat: dbDelta returned empty result for chat transcripts table");
113 } else {
114 //error_log("MxChat: dbDelta result: " . print_r($result, true));
115 }
116
117 // IMPORTANT: Ensure all columns exist for existing installations
118 mxchat_ensure_all_columns($table_name);
119 }
120
121 /**
122 * Ensure all required columns exist (for upgrades)
123 */
124 function mxchat_ensure_all_columns($table_name) {
125 global $wpdb;
126
127 // First check if table exists
128 $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name;
129 if (!$table_exists) {
130 //error_log("MxChat: Table $table_name does not exist, cannot add columns");
131 return;
132 }
133
134 // Define all required columns and their types
135 $required_columns = [
136 'user_identifier' => 'VARCHAR(255) DEFAULT NULL',
137 'user_email' => 'VARCHAR(255) DEFAULT NULL',
138 'user_name' => 'VARCHAR(100) DEFAULT NULL',
139 'originating_page_url' => 'TEXT DEFAULT NULL',
140 'originating_page_title' => 'VARCHAR(500) DEFAULT NULL'
141 ];
142
143 // Get existing columns
144 $existing_columns = $wpdb->get_results("SHOW COLUMNS FROM $table_name");
145 if (empty($existing_columns)) {
146 //error_log("MxChat: Could not get columns for table $table_name");
147 return;
148 }
149
150 $existing_column_names = array_column($existing_columns, 'Field');
151
152 // Add missing columns
153 foreach ($required_columns as $column_name => $column_definition) {
154 if (!in_array($column_name, $existing_column_names)) {
155 $alter_sql = "ALTER TABLE $table_name ADD COLUMN $column_name $column_definition";
156 $result = $wpdb->query($alter_sql);
157
158 if ($result === false) {
159 //error_log("MxChat: Failed to add column $column_name to $table_name. Error: " . $wpdb->last_error);
160 } else {
161 //error_log("MxChat: Successfully added column $column_name to $table_name");
162 }
163 }
164 }
165 }
166
167 /**
168 * Add role restriction column to knowledge base table
169 */
170 function mxchat_add_role_restriction_column() {
171 global $wpdb;
172 $table_name = $wpdb->prefix . 'mxchat_system_prompt_content';
173
174 // Check if table exists first
175 $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name;
176 if (!$table_exists) {
177 //error_log("MxChat: System prompt content table does not exist, cannot add role_restriction column");
178 return;
179 }
180
181 // Check if column already exists
182 $column_exists = $wpdb->get_results(
183 $wpdb->prepare(
184 "SHOW COLUMNS FROM {$table_name} LIKE %s",
185 'role_restriction'
186 )
187 );
188
189 if (empty($column_exists)) {
190 $alter_sql = "ALTER TABLE {$table_name} ADD COLUMN role_restriction VARCHAR(50) DEFAULT 'public' AFTER source_url";
191 $result = $wpdb->query($alter_sql);
192
193 if ($result === false) {
194 //error_log("MxChat: Failed to add role_restriction column. Error: " . $wpdb->last_error);
195 } else {
196 //error_log("MxChat: Successfully added role_restriction column");
197
198 // Set all existing records to 'public' (everyone can access)
199 $update_result = $wpdb->query(
200 "UPDATE {$table_name}
201 SET role_restriction = 'public'
202 WHERE role_restriction IS NULL OR role_restriction = ''"
203 );
204
205 if ($update_result !== false) {
206 //error_log("MxChat: Updated {$update_result} existing records to public access");
207 }
208 }
209 }
210 }
211
212 /**
213 * NEW: Add enabled_bots column to intents table for multi-bot action filtering
214 */
215 function mxchat_add_enabled_bots_column() {
216 global $wpdb;
217 $table_name = $wpdb->prefix . 'mxchat_intents';
218
219 // Check if table exists first
220 $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name;
221 if (!$table_exists) {
222 //error_log("MxChat: Intents table does not exist, cannot add enabled_bots column");
223 return;
224 }
225
226 // Check if column already exists
227 $column_exists = $wpdb->get_results(
228 $wpdb->prepare(
229 "SHOW COLUMNS FROM {$table_name} LIKE %s",
230 'enabled_bots'
231 )
232 );
233
234 if (empty($column_exists)) {
235 $alter_sql = "ALTER TABLE {$table_name} ADD COLUMN enabled_bots LONGTEXT DEFAULT NULL AFTER enabled";
236 $result = $wpdb->query($alter_sql);
237
238 if ($result === false) {
239 //error_log("MxChat: Failed to add enabled_bots column. Error: " . $wpdb->last_error);
240 } else {
241 //error_log("MxChat: Successfully added enabled_bots column");
242
243 // Set all existing actions to work with 'default' bot for backward compatibility
244 $default_bots = json_encode(['default']);
245 $update_result = $wpdb->query(
246 $wpdb->prepare(
247 "UPDATE {$table_name}
248 SET enabled_bots = %s
249 WHERE enabled_bots IS NULL OR enabled_bots = ''",
250 $default_bots
251 )
252 );
253
254 if ($update_result !== false) {
255 //error_log("MxChat: Updated {$update_result} existing actions to work with default bot");
256 }
257 }
258 }
259 }
260
261 /**
262 * Create Pinecone role restrictions table - UPDATED FOR 2.4.2
263 */
264 function mxchat_create_pinecone_roles_table() {
265 global $wpdb;
266
267 $table_name = $wpdb->prefix . 'mxchat_pinecone_roles';
268 $charset_collate = $wpdb->get_charset_collate();
269
270 $sql = "CREATE TABLE $table_name (
271 id mediumint(9) NOT NULL AUTO_INCREMENT,
272 vector_id varchar(255) NOT NULL,
273 bot_id varchar(50) DEFAULT 'default',
274 source_url text,
275 role_restriction varchar(50) DEFAULT 'public',
276 updated_at timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
277 PRIMARY KEY (id),
278 UNIQUE KEY vector_bot (vector_id, bot_id),
279 KEY role_restriction (role_restriction),
280 KEY bot_id (bot_id)
281 ) $charset_collate;";
282
283 require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
284 dbDelta($sql);
285 }
286
287 /**
288 * Add bot_id column to pinecone_roles table for multi-bot support
289 */
290 function mxchat_add_bot_id_to_pinecone_roles() {
291 global $wpdb;
292 $table_name = $wpdb->prefix . 'mxchat_pinecone_roles';
293
294 // Check if table exists first
295 $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name;
296 if (!$table_exists) {
297 //error_log("MxChat: Pinecone roles table does not exist, creating it");
298 mxchat_create_pinecone_roles_table();
299 return;
300 }
301
302 // Check if bot_id column already exists
303 $column_exists = $wpdb->get_results(
304 $wpdb->prepare(
305 "SHOW COLUMNS FROM {$table_name} LIKE %s",
306 'bot_id'
307 )
308 );
309
310 if (empty($column_exists)) {
311 // Add bot_id column
312 $alter_sql = "ALTER TABLE {$table_name} ADD COLUMN bot_id VARCHAR(50) DEFAULT 'default' AFTER vector_id";
313 $result = $wpdb->query($alter_sql);
314
315 if ($result === false) {
316 //error_log("MxChat: Failed to add bot_id column to pinecone_roles. Error: " . $wpdb->last_error);
317 } else {
318 //error_log("MxChat: Successfully added bot_id column to pinecone_roles");
319
320 // Drop the old unique index if it exists
321 $wpdb->query("ALTER TABLE {$table_name} DROP INDEX IF EXISTS vector_id");
322
323 // Add new composite unique index
324 $wpdb->query("ALTER TABLE {$table_name} ADD UNIQUE KEY vector_bot (vector_id, bot_id)");
325
326 // Add bot_id index for better query performance
327 $wpdb->query("ALTER TABLE {$table_name} ADD KEY bot_id (bot_id)");
328
329 //error_log("MxChat: Updated indexes for pinecone_roles table");
330 }
331 }
332 }
333
334 function mxchat_activate() {
335 global $wpdb;
336 $charset_collate = $wpdb->get_charset_collate();
337
338 //error_log("MxChat: Running activation function");
339
340 // Create chat transcripts table with improved function
341 mxchat_create_chat_transcripts_table();
342
343 // System Prompt Content Table
344 $system_prompt_table = $wpdb->prefix . 'mxchat_system_prompt_content';
345 $sql_system_prompt = "CREATE TABLE $system_prompt_table (
346 id MEDIUMINT(9) NOT NULL AUTO_INCREMENT,
347 url VARCHAR(255) NOT NULL,
348 article_content LONGTEXT NOT NULL,
349 embedding_vector LONGTEXT,
350 source_url VARCHAR(255) DEFAULT NULL,
351 role_restriction VARCHAR(50) DEFAULT 'public',
352 timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
353 PRIMARY KEY (id)
354 ) $charset_collate;";
355
356 // Intents Table - NOW INCLUDES enabled_bots column from the start
357 $intents_table = $wpdb->prefix . 'mxchat_intents';
358 $sql_intents_table = "CREATE TABLE $intents_table (
359 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
360 intent_label VARCHAR(255) NOT NULL,
361 phrases TEXT NOT NULL,
362 embedding_vector LONGTEXT NOT NULL,
363 callback_function VARCHAR(255) NOT NULL,
364 similarity_threshold FLOAT DEFAULT 0.85,
365 enabled TINYINT(1) NOT NULL DEFAULT 1,
366 enabled_bots LONGTEXT DEFAULT NULL,
367 PRIMARY KEY (id)
368 ) $charset_collate;";
369
370 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
371
372 // Create other tables
373 dbDelta($sql_system_prompt);
374 dbDelta($sql_intents_table);
375
376 // Create URL click tracking table
377 mxchat_create_url_clicks_table();
378
379 // Create Pinecone roles table (updated for 2.4.2)
380 mxchat_create_pinecone_roles_table();
381
382 // Ensure additional columns in system prompt table
383 $existing_system_columns = $wpdb->get_results("SHOW COLUMNS FROM $system_prompt_table");
384 if (!empty($existing_system_columns)) {
385 $existing_system_column_names = array_column($existing_system_columns, 'Field');
386
387 if (!in_array('embedding_vector', $existing_system_column_names)) {
388 $wpdb->query("ALTER TABLE $system_prompt_table ADD COLUMN embedding_vector LONGTEXT");
389 }
390 if (!in_array('source_url', $existing_system_column_names)) {
391 $wpdb->query("ALTER TABLE $system_prompt_table ADD COLUMN source_url VARCHAR(255) DEFAULT NULL");
392 }
393 if (!in_array('role_restriction', $existing_system_column_names)) {
394 $wpdb->query("ALTER TABLE $system_prompt_table ADD COLUMN role_restriction VARCHAR(50) DEFAULT 'public' AFTER source_url");
395 }
396 }
397
398 // Set default thresholds for existing intents
399 $wpdb->query("UPDATE {$intents_table} SET similarity_threshold = 0.85 WHERE similarity_threshold IS NULL");
400
401 // Ensure enabled column exists in intents table
402 $existing_intent_columns = $wpdb->get_results("SHOW COLUMNS FROM $intents_table");
403 if (!empty($existing_intent_columns)) {
404 $existing_intent_column_names = array_column($existing_intent_columns, 'Field');
405
406 if (!in_array('enabled', $existing_intent_column_names)) {
407 $wpdb->query("ALTER TABLE $intents_table ADD COLUMN enabled TINYINT(1) NOT NULL DEFAULT 1");
408 }
409
410 // NEW: Ensure enabled_bots column exists for existing installations
411 if (!in_array('enabled_bots', $existing_intent_column_names)) {
412 $wpdb->query("ALTER TABLE $intents_table ADD COLUMN enabled_bots LONGTEXT DEFAULT NULL AFTER enabled");
413
414 // Set existing actions to work with default bot
415 $default_bots = json_encode(['default']);
416 $wpdb->query($wpdb->prepare(
417 "UPDATE {$intents_table} SET enabled_bots = %s WHERE enabled_bots IS NULL",
418 $default_bots
419 ));
420 }
421 }
422
423 // Setup cron jobs
424 mxchat_setup_cron_jobs();
425
426 // Update version
427 update_option('mxchat_plugin_version', MXCHAT_VERSION);
428
429 //error_log("MxChat: Activation function completed");
430 }
431
432 /**
433 * Setup cron jobs on plugin activation
434 */
435 function mxchat_setup_cron_jobs() {
436 // Clear any existing cron jobs first
437 wp_clear_scheduled_hook('mxchat_reset_rate_limits');
438
439 // Check if WordPress cron is disabled
440 if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
441 // Set flag to use fallback system
442 update_option('mxchat_use_fallback_rate_limits', true);
443 update_option('mxchat_next_rate_limit_check', time() + 3600);
444 return;
445 }
446
447 // Schedule the rate limit reset cron job
448 $result = wp_schedule_event(time() + 300, 'hourly', 'mxchat_reset_rate_limits');
449
450 if ($result === false) {
451 // Fallback if scheduling fails
452 update_option('mxchat_use_fallback_rate_limits', true);
453 update_option('mxchat_next_rate_limit_check', time() + 3600);
454 } else {
455 // Clear fallback flags if cron scheduling succeeded
456 delete_option('mxchat_use_fallback_rate_limits');
457 }
458 }
459
460 /**
461 * Clean up on plugin deactivation
462 */
463 function mxchat_deactivate() {
464 // Clear scheduled cron jobs
465 wp_clear_scheduled_hook('mxchat_reset_rate_limits');
466
467 // Clear fallback options
468 delete_option('mxchat_use_fallback_rate_limits');
469 delete_option('mxchat_next_rate_limit_check');
470 delete_option('mxchat_fallback_check_interval');
471 }
472
473 /**
474 * Check if fallback rate limit cleanup is needed
475 */
476 function mxchat_check_fallback_rate_limits() {
477 $use_fallback = get_option('mxchat_use_fallback_rate_limits', false);
478
479 if (!$use_fallback) {
480 return;
481 }
482
483 $next_check = get_option('mxchat_next_rate_limit_check', 0);
484
485 if (time() >= $next_check) {
486 // Only run reset if the MxChat_Integrator class exists
487 if (class_exists('MxChat_Integrator')) {
488 $integrator = new MxChat_Integrator();
489 if (method_exists($integrator, 'mxchat_reset_rate_limits')) {
490 $integrator->mxchat_reset_rate_limits();
491 update_option('mxchat_next_rate_limit_check', time() + 3600);
492 }
493 }
494 }
495 }
496
497 /**
498 * Robust update checking with role restriction migration
499 */
500 function mxchat_check_for_update() {
501 global $wpdb; // CRITICAL: Declare this at the top
502
503 try {
504 $current_version = get_option('mxchat_plugin_version', '0.0.0');
505 $plugin_version = MXCHAT_VERSION;
506
507 // Always run activation to ensure tables exist (safe for existing installations)
508 if ($current_version !== $plugin_version) {
509 //error_log("MxChat: Version change detected: $current_version -> $plugin_version");
510
511 // Run live agent update BEFORE updating the stored version
512 mxchat_handle_live_agent_update();
513
514 // Run role restriction migration for 2.4.1
515 if (version_compare($current_version, '2.4.1', '<')) {
516 mxchat_add_role_restriction_column();
517 }
518
519 // Run enabled_bots column migration and bot_id migration for 2.4.2
520 if (version_compare($current_version, '2.4.2', '<')) {
521 mxchat_add_enabled_bots_column();
522 mxchat_add_bot_id_to_pinecone_roles();
523 }
524
525 // Run activation (this will create/update all tables and columns)
526 mxchat_activate();
527
528 // Run migration functions
529 mxchat_migrate_live_agent_status();
530
531 // Add the cleanup function for version 2.1.8
532 if (version_compare($current_version, '2.1.8', '<')) {
533 $deleted = mxchat_cleanup_orphaned_chat_history();
534 }
535
536 // Update version LAST
537 update_option('mxchat_plugin_version', $plugin_version);
538
539 //error_log("MxChat: Updated from version $current_version to $plugin_version");
540 }
541
542 // CRITICAL: Always ensure tables exist, even if version matches
543 // This handles cases where tables were manually deleted
544 $table_name = $wpdb->prefix . 'mxchat_chat_transcripts';
545 $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name;
546
547 if (!$table_exists) {
548 //error_log("MxChat: Chat transcripts table missing, recreating...");
549 mxchat_activate(); // Run full activation instead of just table creation
550 }
551
552 } catch (Exception $e) {
553 //error_log('MxChat update error: ' . $e->getMessage());
554 // Don't update version if there was an error
555 }
556 }
557
558 /**
559 * Ensure tables exist on every load for fresh installations
560 */
561 function mxchat_ensure_tables_exist() {
562 global $wpdb;
563
564 // Only run for admin users to avoid performance impact
565 if (!current_user_can('administrator')) {
566 return;
567 }
568
569 $table_name = $wpdb->prefix . 'mxchat_chat_transcripts';
570 $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name;
571
572 if (!$table_exists) {
573 //error_log("MxChat: Tables missing on admin load, running activation");
574 mxchat_activate();
575 }
576 }
577
578 /**
579 * Clean up orphaned chat history options from the wp_options table
580 * @return int Number of options deleted
581 */
582 function mxchat_cleanup_orphaned_chat_history() {
583 global $wpdb;
584 $count = 0;
585
586 // Get all option keys that match our pattern
587 $history_options = $wpdb->get_results(
588 "SELECT option_name FROM {$wpdb->options}
589 WHERE option_name LIKE 'mxchat_history_%'"
590 );
591
592 if (!empty($history_options)) {
593 foreach ($history_options as $option) {
594 // Extract the session ID from the option name
595 $session_id = str_replace('mxchat_history_', '', $option->option_name);
596
597 // Check if this session still exists in the custom table
598 $table_name = $wpdb->prefix . 'mxchat_chat_transcripts';
599 $exists = $wpdb->get_var(
600 $wpdb->prepare(
601 "SELECT COUNT(*) FROM {$table_name} WHERE session_id = %s",
602 $session_id
603 )
604 );
605
606 // If session doesn't exist in the main table, delete the option
607 if ($exists == 0) {
608 delete_option($option->option_name);
609 // Also delete related metadata
610 delete_option("mxchat_email_{$session_id}");
611 delete_option("mxchat_name_{$session_id}");
612 delete_option("mxchat_agent_name_{$session_id}");
613 $count++;
614 }
615 }
616 }
617
618 return $count;
619 }
620
621 function mxchat_migrate_live_agent_status() {
622 $options = get_option('mxchat_options', []);
623
624 // Check if live_agent_status exists
625 if (isset($options['live_agent_status'])) {
626 $current_status = $options['live_agent_status'];
627 $needs_update = false;
628
629 // Convert to new format if needed
630 if ($current_status === 'online') {
631 $options['live_agent_status'] = 'on';
632 $needs_update = true;
633 } else if ($current_status === 'offline') {
634 $options['live_agent_status'] = 'off';
635 $needs_update = true;
636 } else if (!in_array($current_status, ['on', 'off'])) {
637 // Default to off for any unexpected values
638 $options['live_agent_status'] = 'off';
639 $needs_update = true;
640 }
641
642 // Only update if needed
643 if ($needs_update) {
644 update_option('mxchat_options', $options);
645 }
646 } else {
647 // If status doesn't exist, set default to off
648 $options['live_agent_status'] = 'off';
649 update_option('mxchat_options', $options);
650 }
651 }
652
653 function mxchat_handle_live_agent_update() {
654 // Get the CURRENT stored version (before it gets updated)
655 $current_version = get_option('mxchat_plugin_version', '0.0.0');
656 $new_version = '2.2.2';
657
658 // Only run this once for the update to 2.2.2
659 $update_handled = get_option('mxchat_live_agent_update_2_2_2_handled', false);
660
661 // Check if we're upgrading TO 2.2.2 and haven't handled this yet
662 if (version_compare($current_version, $new_version, '<') && !$update_handled) {
663 $options = get_option('mxchat_options', array());
664
665 // Check if live agent was previously enabled
666 if (isset($options['live_agent_status']) && $options['live_agent_status'] === 'on') {
667 // Disable live agent
668 $options['live_agent_status'] = 'off';
669 update_option('mxchat_options', $options);
670
671 // Set flag to show the notification banner
672 update_option('mxchat_show_live_agent_disabled_notice', true);
673 }
674
675 // Mark this update as handled
676 update_option('mxchat_live_agent_update_2_2_2_handled', true);
677 }
678 }
679
680 // Initialize plugin safely
681 function mxchat_init() {
682 // Include all class files first
683 mxchat_include_classes();
684
685 // Run update check
686 mxchat_check_for_update();
687
688 // CRITICAL: Ensure tables exist (for fresh installations that don't trigger activation hook)
689 add_action('admin_init', 'mxchat_ensure_tables_exist', 1);
690
691 // Add fallback rate limit check
692 add_action('init', 'mxchat_check_fallback_rate_limits', 5);
693
694 // Initialize classes with error handling
695 try {
696 // Initialize admin classes
697 if (is_admin()) {
698 if (class_exists('MxChat_Knowledge_Manager')) {
699 $mxchat_knowledge_manager = new MxChat_Knowledge_Manager();
700
701 if (class_exists('MxChat_Admin')) {
702 $mxchat_admin = new MxChat_Admin($mxchat_knowledge_manager);
703 }
704 }
705
706 // Initialize meta box class
707 if (class_exists('MxChat_Meta_Box')) {
708 new MxChat_Meta_Box();
709 }
710 }
711
712 // Initialize public classes
713 if (class_exists('MxChat_Public')) {
714 $mxchat_public = new MxChat_Public();
715 }
716
717 if (class_exists('MxChat_Integrator')) {
718 $mxchat_integrator = new MxChat_Integrator();
719 }
720
721 } catch (Exception $e) {
722 //error_log('MxChat initialization error: ' . $e->getMessage());
723
724 // Show admin notice if there's an error
725 if (is_admin()) {
726 add_action('admin_notices', function() use ($e) {
727 echo '<div class="notice notice-error"><p>';
728 echo '<strong>MxChat Error:</strong> Plugin initialization failed. ';
729 echo 'Please check error logs or contact support. Error: ' . esc_html($e->getMessage());
730 echo '</p></div>';
731 });
732 }
733 }
734 }
735
736 // Run initialization on plugins_loaded
737 add_action('plugins_loaded', 'mxchat_init');
738
739 // Register activation hook
740 register_activation_hook(__FILE__, 'mxchat_activate');
741
742 // Add cron schedule
743 add_filter('cron_schedules', function($schedules) {
744 $schedules['one_minute'] = array(
745 'interval' => 60,
746 'display' => 'Every Minute'
747 );
748 return $schedules;
749 });
750
751 // Register deactivation hook
752 register_deactivation_hook(__FILE__, 'mxchat_deactivate');