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

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