| @@ -45,8 +45,9 @@ | ||
| 45 | 45 | add_action('post_updated', array($this, 'handle_post_update'), 10, 3); |
| 46 | 46 | add_action('wp_ajax_mxchat_save_setting', array($this, 'mxchat_save_setting_callback')); |
| 47 | 47 | add_action('wp_trash_post', array($this, 'mxchat_handle_post_delete')); |
| 48 | 48 | add_action('before_delete_post', array($this, 'mxchat_handle_post_delete')); |
| 49 | + add_action('wp_ajax_mxchat_export_transcripts', array($this, 'export_chat_transcripts')); | |
| 49 | 50 | add_action('wp_ajax_mxchat_save_prompts_setting', array($this, 'mxchat_save_prompts_setting_callback')); |
| 50 | 51 | if (isset($this->options['enable_woocommerce_integration']) && |
| 51 | 52 | ($this->options['enable_woocommerce_integration'] === '1' || |
| 52 | 53 | $this->options['enable_woocommerce_integration'] === 'on')) { |
| @@ -70,8 +71,10 @@ | ||
| 70 | 71 | 'api_key' => '', |
| 71 | 72 | 'xai_api_key' => '', |
| 72 | 73 | 'claude_api_key' => '', |
| 73 | 74 | 'deepseek_api_key' => '', |
| 75 | + 'voyage_api_key' => '', | |
| 76 | + 'embedding_model' => 'text-embedding-ada-002', | |
| 74 | 77 | 'system_prompt_instructions' => esc_html__('[EXAMPLE INSTRUCTIONS] You are an AI Chatbot assistant for this website. The primary subject you should focus on is [insert proper subject here]. Your main goal is to assist visitors with questions related to this specific topic. Here are some key things to keep in mind: |
| 75 | 78 | - Your name is [Chatbot Name]. |
| 76 | 79 | - Stay focused on topics related to [insert proper subject here]. If a visitor asks about an unrelated topic, politely redirect the conversation to how you can assist them with this subject. |
| 77 | 80 | - Do not make up links to pages. Only use specific links you see in your knowledgebase from [insert your domain]. Do not make assumptions or make up URLs. |
| @@ -114,8 +117,10 @@ | ||
| 114 | 117 | 'pdf_intent_trigger_text' => esc_html__("Please provide the URL to the PDF you'd like to discuss.", 'mxchat'), |
| 115 | 118 | 'pdf_intent_success_text' => esc_html__("I've processed the PDF. What questions do you have about it?", 'mxchat'), |
| 116 | 119 | 'pdf_intent_error_text' => esc_html__("Sorry, I couldn't process the PDF. Please ensure it's a valid file.", 'mxchat'), |
| 117 | 120 | 'pdf_max_pages' => 69, |
| 121 | + 'show_pdf_upload_button' => 'on', | |
| 122 | + 'show_word_upload_button' => 'on', | |
| 118 | 123 | |
| 119 | 124 | // Live Agent Integration |
| 120 | 125 | 'live_agent_webhook_url' => '', |
| 121 | 126 | 'live_agent_secret_key' => '', |
| @@ -173,26 +178,24 @@ | ||
| 173 | 178 | 'mxchat-prompts', |
| 174 | 179 | array($this, 'mxchat_create_prompts_page') |
| 175 | 180 | ); |
| 176 | 181 | |
| 177 | - // Submenu page for Chat Transcripts | |
| 178 | 182 | add_submenu_page( |
| 179 | - 'mxchat-max', // Corrected parent slug to match the main menu | |
| 183 | + 'mxchat-max', | |
| 180 | 184 | esc_html__('Chat Transcripts', 'mxchat'), |
| 181 | 185 | esc_html__('Transcripts', 'mxchat'), |
| 182 | 186 | 'manage_options', |
| 183 | 187 | 'mxchat-transcripts', |
| 184 | - array($this, 'mxchat_create_transcripts_page') // Prefixed function name with mxchat_ | |
| 188 | + array($this, 'mxchat_create_transcripts_page') | |
| 185 | 189 | ); |
| 186 | 190 | |
| 187 | - // Submenu page for Intents | |
| 188 | 191 | add_submenu_page( |
| 189 | - 'mxchat-max', // Parent slug | |
| 190 | - esc_html__('MxChat Intents', 'mxchat'), // Page title | |
| 191 | - esc_html__('Intents', 'mxchat'), // Menu title | |
| 192 | - 'manage_options', // Capability | |
| 193 | - 'mxchat-intents', // Menu slug | |
| 194 | - array($this, 'mxchat_intents_page_html') // Callback function | |
| 192 | + 'mxchat-max', | |
| 193 | + esc_html__('MxChat Intents', 'mxchat'), | |
| 194 | + esc_html__('Intents', 'mxchat'), | |
| 195 | + 'manage_options', | |
| 196 | + 'mxchat-intents', | |
| 197 | + array($this, 'mxchat_intents_page_html') | |
| 195 | 198 | ); |
| 196 | 199 | |
| 197 | 200 | add_submenu_page( |
| 198 | 201 | 'mxchat-max', |
| @@ -288,9 +291,11 @@ | ||
| 288 | 291 | if (strpos($name, 'toggle') !== false || in_array($name, [ |
| 289 | 292 | 'chat_persistence_toggle', |
| 290 | 293 | 'privacy_toggle', |
| 291 | 294 | 'complianz_toggle', |
| 292 | - 'chat_toolbar_toggle' // Removed live_agent_status from here | |
| 295 | + 'chat_toolbar_toggle', | |
| 296 | + 'show_pdf_upload_button', | |
| 297 | + 'show_word_upload_button' | |
| 293 | 298 | ])) { |
| 294 | 299 | $options[$name] = ($value === 'on') ? 'on' : 'off'; |
| 295 | 300 | } else { |
| 296 | 301 | // Store all other values directly |
| @@ -312,9 +317,8 @@ | ||
| 312 | 317 | } else { |
| 313 | 318 | wp_send_json_error(['message' => esc_html__('Update failed or no changes', 'mxchat')]); |
| 314 | 319 | } |
| 315 | 320 | } |
| 316 | - | |
| 317 | 321 | /** |
| 318 | 322 | * Handles AJAX auto-save for prompts and auto-sync settings. |
| 319 | 323 | */ |
| 320 | 324 | public function mxchat_save_prompts_setting_callback() { |
| @@ -410,9 +414,9 @@ | ||
| 410 | 414 | <?php endif; ?> |
| 411 | 415 | |
| 412 | 416 | <div class="mxchat-agents-banner"> |
| 413 | 417 | <p> |
| 414 | - <strong><?php echo esc_html__('The MxChat Add-Ons Platform', 'mxchat'); ?></strong><?php echo esc_html__(' is here! Pro users get unlimited access to our growing collection of powerful add-ons. ', 'mxchat'); ?><a href="<?php echo admin_url('admin.php?page=mxchat-addons'); ?>"><?php echo esc_html__('Explore all add-ons', 'mxchat'); ?></a><?php echo esc_html__(' including Forms Builder, Theme Customizer, Content Moderation, and more – all included with your lifetime Pro license!', 'mxchat'); ?> | |
| 418 | + <strong><?php echo esc_html__('The MxChat Add-Ons Platform', 'mxchat'); ?></strong><?php echo esc_html__(' is here! Pro users get unlimited access to our growing collection of powerful add-ons. ', 'mxchat'); ?><a href="<?php echo admin_url('admin.php?page=mxchat-addons'); ?>"><?php echo esc_html__('Explore all add-ons', 'mxchat'); ?></a><?php echo esc_html__(' including Forms Builder, Theme Customizer, WooCommerce, Perplexity, and more – all included with your lifetime Pro license!', 'mxchat'); ?> | |
| 415 | 419 | </p> |
| 416 | 420 | </div> |
| 417 | 421 | |
| 418 | 422 | <h2 class="mxchat-nav-tab-wrapper"> |
| @@ -417,9 +421,9 @@ | ||
| 417 | 421 | |
| 418 | 422 | <h2 class="mxchat-nav-tab-wrapper"> |
| 419 | 423 | <a href="#chatbot" class="mxchat-nav-tab mxchat-nav-tab-active" data-tab="chatbot"><?php echo esc_html__('Chatbot', 'mxchat'); ?></a> |
| 420 | 424 | <a href="#embed" class="mxchat-nav-tab" data-tab="embed"><?php echo esc_html__('Integrations', 'mxchat'); ?></a> |
| 421 | - <a href="#general" class="mxchat-nav-tab" data-tab="general"><?php echo esc_html__('FAQ', 'mxchat'); ?></a> | |
| 425 | + <a href="#general" class="mxchat-nav-tab" data-tab="general"><?php echo esc_html__('YouTube Tutorials', 'mxchat'); ?></a> | |
| 422 | 426 | </h2> |
| 423 | 427 | |
| 424 | 428 | <div id="chatbot" class="mxchat-tab-content active"> |
| 425 | 429 | <div class="mxchat-autosave-section"> |
| @@ -428,15 +432,8 @@ | ||
| 428 | 432 | </div> |
| 429 | 433 | |
| 430 | 434 | <div id="embed" class="mxchat-tab-content"> |
| 431 | 435 | <div class="mxchat-autosave-section"> |
| 432 | - <div class="mxchat-settings-section"> | |
| 433 | - <h2><?php echo esc_html__('WooCommerce Settings', 'mxchat'); ?></h2> | |
| 434 | - <table class="form-table"> | |
| 435 | - <?php do_settings_fields('mxchat-embed', 'mxchat_woocommerce_section'); ?> | |
| 436 | - </table> | |
| 437 | - </div> | |
| 438 | - <div class="section-divider"></div> | |
| 439 | 436 | |
| 440 | 437 | <div class="mxchat-settings-section"> |
| 441 | 438 | <h2><?php echo esc_html__('Loops Settings', 'mxchat'); ?></h2> |
| 442 | 439 | <table class="form-table"> |
| @@ -477,109 +474,131 @@ | ||
| 477 | 474 | |
| 478 | 475 | |
| 479 | 476 | <div id="general" class="mxchat-tab-content"> |
| 480 | 477 | <?php do_settings_sections('mxchat-general'); ?> |
| 481 | - <p> | |
| 482 | - <?php echo esc_html__('If you’re having trouble with setup or getting the responses you need, we encourage you to review our', 'mxchat'); ?> | |
| 483 | - <a href="https://mxchat.ai/documentation/" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('documentation', 'mxchat'); ?></a> <?php echo esc_html__('or', 'mxchat'); ?> | |
| 484 | - <a href="https://wordpress.org/support/plugin/mxchat-basic/" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('create a support ticket', 'mxchat'); ?></a>. | |
| 485 | - </p> | |
| 486 | - <p> | |
| 487 | - <?php echo esc_html__('If you like our plugin, please consider', 'mxchat'); ?> <a href="https://wordpress.org/plugins/mxchat-basic/#reviews" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('leaving us a review', 'mxchat'); ?></a>. | |
| 488 | - </p> | |
| 478 | +<div class="video-tutorials-section"> | |
| 489 | 479 | |
| 490 | - <div class="faq-item"> | |
| 491 | - <h3><?php echo esc_html__('How does the Claude API integration work?', 'mxchat'); ?></h3> | |
| 492 | - <p> | |
| 493 | - <?php echo esc_html__('The Claude API, provided by Anthropic, allows for intelligent, context-aware chatbot responses in MxChat. To use it, you will need both an OpenAI API key and a Claude API key. This is necessary because the system utilizes OpenAI for vector embedding in the Retrieval-Augmented Generation (RAG) process, as Claude does not currently offer an embedding API.', 'mxchat'); ?> | |
| 494 | - </p> | |
| 495 | - <p> | |
| 496 | - <?php echo esc_html__('When using the Claude API, your custom content is sent to Claude for generating responses, while the embeddings are processed through OpenAI. This ensures your chatbot provides accurate and engaging responses while maintaining knowledge relevant to your website.', 'mxchat'); ?> | |
| 497 | - </p> | |
| 498 | - <p> | |
| 499 | - <?php echo esc_html__('You can obtain your Claude API key by signing up on the', 'mxchat'); ?> <a href="https://www.anthropic.com/api" target="_blank" rel="noopener"><?php echo esc_html__('Anthropic API page', 'mxchat'); ?></a>. | |
| 500 | - </p> | |
| 480 | + <div class="tutorial-grid"> | |
| 481 | + <div class="tutorial-item"> | |
| 482 | + <h3><?php echo esc_html__('MxChat Forms Tutorial', 'mxchat'); ?></h3> | |
| 483 | + <div class="video-description"> | |
| 484 | + <p><?php echo esc_html__('Learn how to create and manage smart forms that automatically trigger during chat conversations.', 'mxchat'); ?></p> | |
| 485 | + <a href="https://www.youtube.com/watch?v=3MrWy5dRalA" target="_blank" rel="noopener" class="video-link"> | |
| 486 | + <span class="video-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19c-2.3 0-6.4-.2-8.1-.6-.7-.2-1.2-.7-1.4-1.4-.3-1.1-.5-3.4-.5-5s.2-3.9.5-5c.2-.7.7-1.2 1.4-1.4C5.6 5.2 9.7 5 12 5s6.4.2 8.1.6c.7.2 1.2.7 1.4 1.4.3 1.1.5 3.4.5 5s-.2 3.9-.5 5c-.2.7-.7 1.2-1.4 1.4-1.7.4-5.8.6-8.1.6z"></path><polygon points="10 15 15 12 10 9 10 15"></polygon></svg></span> | |
| 487 | + <?php echo esc_html__('Watch MxChat Forms Tutorial', 'mxchat'); ?> | |
| 488 | + </a> | |
| 501 | 489 | </div> |
| 490 | + </div> | |
| 502 | 491 | |
| 503 | - <div class="faq-item"> | |
| 504 | - <h3><?php echo esc_html__('How does the X.AI API integration work?', 'mxchat'); ?></h3> | |
| 505 | - <p> | |
| 506 | - <?php echo esc_html__('The X.AI API, released on 10.21.24, is currently in beta. To use it, you will need both an OpenAI API key and an X.AI API key. This is because OpenAI handles vector embeddings in the Retrieval-Augmented Generation (RAG) process, as X.AI does not yet provide an embedding API.', 'mxchat'); ?> | |
| 507 | - </p> | |
| 508 | - <p> | |
| 509 | - <?php echo esc_html__('Custom content is sent to the X.AI API for generating responses, while OpenAI processes the embeddings. This allows the chatbot to provide advanced responses while maintaining context from your website. You can get your X.AI API key from the', 'mxchat'); ?> <a href="https://docs.x.ai/docs" target="_blank" rel="noopener"><?php echo esc_html__('X.AI API documentation', 'mxchat'); ?></a>. | |
| 510 | - </p> | |
| 492 | + <div class="tutorial-item"> | |
| 493 | + <h3><?php echo esc_html__('Intent Tester Guide', 'mxchat'); ?></h3> | |
| 494 | + <div class="video-description"> | |
| 495 | + <p><?php echo esc_html__('Discover how to use the Intent Tester to fine-tune your chatbot\'s responses and ensure it accurately understands user queries.', 'mxchat'); ?></p> | |
| 496 | + <a href="https://www.youtube.com/watch?v=uTr14tn59Hc" target="_blank" rel="noopener" class="video-link"> | |
| 497 | + <span class="video-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19c-2.3 0-6.4-.2-8.1-.6-.7-.2-1.2-.7-1.4-1.4-.3-1.1-.5-3.4-.5-5s.2-3.9.5-5c.2-.7.7-1.2 1.4-1.4C5.6 5.2 9.7 5 12 5s6.4.2 8.1.6c.7.2 1.2.7 1.4 1.4.3 1.1.5 3.4.5 5s-.2 3.9-.5 5c-.2.7-.7 1.2-1.4 1.4-1.7.4-5.8.6-8.1.6z"></path><polygon points="10 15 15 12 10 9 10 15"></polygon></svg></span> | |
| 498 | + <?php echo esc_html__('Watch Intent Tester Tutorial', 'mxchat'); ?> | |
| 499 | + </a> | |
| 511 | 500 | </div> |
| 501 | + </div> | |
| 512 | 502 | |
| 513 | - <div class="faq-item"> | |
| 514 | - <h3><?php echo esc_html__('Do I need an OpenAI API key to use the chatbot?', 'mxchat'); ?></h3> | |
| 515 | - <p> | |
| 516 | - <?php echo esc_html__('Yes, you will need an OpenAI API key to power the chatbot. You can obtain an API key by signing up on the', 'mxchat'); ?> <a href="https://platform.openai.com/signup" target="_blank" rel="noopener"><?php echo esc_html__('OpenAI platform', 'mxchat'); ?></a>. <?php echo esc_html__('After signing up, you must add credits to your account—typically, $5 in credits is sufficient to get started.', 'mxchat'); ?> | |
| 517 | - </p> | |
| 518 | - <p> | |
| 519 | - <?php echo esc_html__('Once you have your API key, simply enter it in the chatbot\'s settings to enable functionality. The chatbot relies on OpenAI’s models for generating responses, so having sufficient credits in your OpenAI account is essential for smooth operation.', 'mxchat'); ?> | |
| 520 | - </p> | |
| 503 | + <div class="tutorial-item"> | |
| 504 | + <h3><?php echo esc_html__('WooCommerce Integration', 'mxchat'); ?></h3> | |
| 505 | + <div class="video-description"> | |
| 506 | + <p><?php echo esc_html__('See how to integrate MxChat with your WooCommerce store to provide product recommendations and shopping assistance to your customers.', 'mxchat'); ?></p> | |
| 507 | + <a href="https://www.youtube.com/watch?v=WsqAppHRGdA" target="_blank" rel="noopener" class="video-link"> | |
| 508 | + <span class="video-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19c-2.3 0-6.4-.2-8.1-.6-.7-.2-1.2-.7-1.4-1.4-.3-1.1-.5-3.4-.5-5s.2-3.9.5-5c.2-.7.7-1.2 1.4-1.4C5.6 5.2 9.7 5 12 5s6.4.2 8.1.6c.7.2 1.2.7 1.4 1.4.3 1.1.5 3.4.5 5s-.2 3.9-.5 5c-.2.7-.7 1.2-1.4 1.4-1.7.4-5.8.6-8.1.6z"></path><polygon points="10 15 15 12 10 9 10 15"></polygon></svg></span> | |
| 509 | + <?php echo esc_html__('Watch WooCommerce Integration Tutorial', 'mxchat'); ?> | |
| 510 | + </a> | |
| 521 | 511 | </div> |
| 512 | + </div> | |
| 522 | 513 | |
| 523 | - <div class="faq-item"> | |
| 524 | - <h3><?php echo esc_html__('How do I add the chatbot to my site?', 'mxchat'); ?></h3> | |
| 525 | - <p> | |
| 526 | - <?php echo esc_html__('You can add the chatbot using the shortcode', 'mxchat'); ?> <code>[mxchat_chatbot floating="yes"]</code> <?php echo esc_html__('or', 'mxchat'); ?> <code>[mxchat_chatbot floating="no"]</code>. <?php echo esc_html__('For initial testing and styling, it\'s best to use the shortcode on a draft or non-public page. Once you’re ready to go live, enable the “Append Chat Widget to Body” option in the settings for site-wide integration (recommended) or add shortcode to the footer.', 'mxchat'); ?> | |
| 527 | - </p> | |
| 514 | + <div class="tutorial-item"> | |
| 515 | + <h3><?php echo esc_html__('Knowledge Base Setup', 'mxchat'); ?></h3> | |
| 516 | + <div class="video-description"> | |
| 517 | + <p><?php echo esc_html__('Learn how to set up your knowledge base using PDFs, sitemaps, and manual entries to enhance your chatbot\'s responses with site-specific information.', 'mxchat'); ?></p> | |
| 518 | + <p><small><?php echo esc_html__('Note: This tutorial uses an older UI, but the process remains the same.', 'mxchat'); ?></small></p> | |
| 519 | + <a href="https://www.youtube.com/watch?v=8Ztjs66-VTo" target="_blank" rel="noopener" class="video-link"> | |
| 520 | + <span class="video-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19c-2.3 0-6.4-.2-8.1-.6-.7-.2-1.2-.7-1.4-1.4-.3-1.1-.5-3.4-.5-5s.2-3.9.5-5c.2-.7.7-1.2 1.4-1.4C5.6 5.2 9.7 5 12 5s6.4.2 8.1.6c.7.2 1.2.7 1.4 1.4.3 1.1.5 3.4.5 5s-.2 3.9-.5 5c-.2.7-.7 1.2-1.4 1.4-1.7.4-5.8.6-8.1.6z"></path><polygon points="10 15 15 12 10 9 10 15"></polygon></svg></span> | |
| 521 | + <?php echo esc_html__('Watch Knowledge Base Setup Tutorial', 'mxchat'); ?> | |
| 522 | + </a> | |
| 528 | 523 | </div> |
| 524 | + </div> | |
| 529 | 525 | |
| 530 | - <div class="faq-item"> | |
| 531 | - <h3><?php echo esc_html__('How does the chatbot use my content to generate responses?', 'mxchat'); ?></h3> | |
| 532 | - <p> | |
| 533 | - <?php echo esc_html__('The chatbot uses AI and vector embeddings to connect users with relevant information. When you submit content, it converts it into a mathematical format. When a user asks a question, the bot matches it to your stored content and generates a response based on relevance. For example, submitting "Our phone number is 910-123-4567" allows the bot to retrieve this information when asked about contact details. To ensure related information is provided together, submit it in one entry.', 'mxchat'); ?> | |
| 534 | - </p> | |
| 526 | + <div class="tutorial-item"> | |
| 527 | + <h3><?php echo esc_html__('Toolbar Chat with Documents', 'mxchat'); ?></h3> | |
| 528 | + <div class="video-description"> | |
| 529 | + <p><?php echo esc_html__('See how to use the MxChat toolbar to chat with PDF and Word documents for enhanced document analysis and information retrieval.', 'mxchat'); ?></p> | |
| 530 | + <a href="https://www.youtube.com/watch?v=j_c45WWCTG0" target="_blank" rel="noopener" class="video-link"> | |
| 531 | + <span class="video-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19c-2.3 0-6.4-.2-8.1-.6-.7-.2-1.2-.7-1.4-1.4-.3-1.1-.5-3.4-.5-5s.2-3.9.5-5c.2-.7.7-1.2 1.4-1.4C5.6 5.2 9.7 5 12 5s6.4.2 8.1.6c.7.2 1.2.7 1.4 1.4.3 1.1.5 3.4.5 5s-.2 3.9-.5 5c-.2.7-.7 1.2-1.4 1.4-1.7.4-5.8.6-8.1.6z"></path><polygon points="10 15 15 12 10 9 10 15"></polygon></svg></span> | |
| 532 | + <?php echo esc_html__('Watch Document Chat Tutorial', 'mxchat'); ?> | |
| 533 | + </a> | |
| 535 | 534 | </div> |
| 536 | - | |
| 537 | - <div class="faq-item"> | |
| 538 | - <h3><?php echo esc_html__('Why does the chatbot sometimes make up links or information?', 'mxchat'); ?></h3> | |
| 539 | - <p> | |
| 540 | - <?php echo esc_html__('Occasionally, the chatbot may generate inaccurate links or information, known as "hallucinations." To minimize this, you can add system instructions to guide its behavior. For example, include an instruction like: "Only provide links you directly have access to or retrieve from the knowledge base. Do not make up links or information that you do not have direct access to." This helps the bot stay aligned with your content.', 'mxchat'); ?> | |
| 541 | - </p> | |
| 535 | + </div> | |
| 536 | + | |
| 537 | + <div class="tutorial-item"> | |
| 538 | + <h3><?php echo esc_html__('Perplexity Integration', 'mxchat'); ?></h3> | |
| 539 | + <div class="video-description"> | |
| 540 | + <p><?php echo esc_html__('Learn how to integrate Perplexity with your chatbot for real-time web search capabilities. This tutorial covers intent recognition, the toolbar toggle button, and how to enable your chatbot to search the web and provide up-to-date information to your visitors.', 'mxchat'); ?></p> | |
| 541 | + <a href="https://youtu.be/wpKkbt24-bo" target="_blank" rel="noopener" class="video-link"> | |
| 542 | + <span class="video-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19c-2.3 0-6.4-.2-8.1-.6-.7-.2-1.2-.7-1.4-1.4-.3-1.1-.5-3.4-.5-5s.2-3.9.5-5c.2-.7.7-1.2 1.4-1.4C5.6 5.2 9.7 5 12 5s6.4.2 8.1.6c.7.2 1.2.7 1.4 1.4.3 1.1.5 3.4.5 5s-.2 3.9-.5 5c-.2.7-.7 1.2-1.4 1.4-1.7.4-5.8.6-8.1.6z"></path><polygon points="10 15 15 12 10 9 10 15"></polygon></svg></span> | |
| 543 | + <?php echo esc_html__('Watch Perplexity Integration Tutorial', 'mxchat'); ?> | |
| 544 | + </a> | |
| 542 | 545 | </div> |
| 546 | + </div> | |
| 543 | 547 | |
| 544 | - <div class="faq-item"> | |
| 545 | - <h3><?php echo esc_html__('How do intents work in MxChat?', 'mxchat'); ?></h3> | |
| 546 | - <p> | |
| 547 | - <?php echo esc_html__('Intents allow MxChat to recognize user requests and trigger specific actions, such as capturing emails or displaying product information. This helps provide a more interactive and responsive experience. For a detailed explanation of each intent, please refer to our', 'mxchat'); ?> <a href="https://mxchat.ai/documentation/#intents" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('Intents Documentation', 'mxchat'); ?></a>. | |
| 548 | - </p> | |
| 548 | + <div class="tutorial-item"> | |
| 549 | + <h3><?php echo esc_html__('Brave Search Intent', 'mxchat'); ?></h3> | |
| 550 | + <div class="video-description"> | |
| 551 | + <p><?php echo esc_html__('Learn how to leverage Brave Search intent capabilities to improve your chatbot\'s understanding of user queries and provide more accurate responses.', 'mxchat'); ?></p> | |
| 552 | + <a href="https://www.youtube.com/watch?v=7vDL5H7vToc" target="_blank" rel="noopener" class="video-link"> | |
| 553 | + <span class="video-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19c-2.3 0-6.4-.2-8.1-.6-.7-.2-1.2-.7-1.4-1.4-.3-1.1-.5-3.4-.5-5s.2-3.9.5-5c.2-.7.7-1.2 1.4-1.4C5.6 5.2 9.7 5 12 5s6.4.2 8.1.6c.7.2 1.2.7 1.4 1.4.3 1.1.5 3.4.5 5s-.2 3.9-.5 5c-.2.7-.7 1.2-1.4 1.4-1.7.4-5.8.6-8.1.6z"></path><polygon points="10 15 15 12 10 9 10 15"></polygon></svg></span> | |
| 554 | + <?php echo esc_html__('Watch Brave Search Intent Tutorial', 'mxchat'); ?> | |
| 555 | + </a> | |
| 549 | 556 | </div> |
| 557 | + </div> | |
| 550 | 558 | |
| 551 | - <div class="faq-item"> | |
| 552 | - <h3><?php echo esc_html__('How does the Complianz integration work?', 'mxchat'); ?></h3> | |
| 553 | - <p> | |
| 554 | - <?php echo esc_html__('The Pro version offers direct integration with the Complianz GDPR plugin, making it easy to stay compliant with GDPR. If Complianz is enabled on your website, users must accept consent before the chatbot widget appears. The chatbot will only display once the user has accepted, ensuring compliance with data privacy regulations.', 'mxchat'); ?> | |
| 555 | - </p> | |
| 559 | + <div class="tutorial-item"> | |
| 560 | + <h3><?php echo esc_html__('Loops Email Capture', 'mxchat'); ?></h3> | |
| 561 | + <div class="video-description"> | |
| 562 | + <p><?php echo esc_html__('Discover how to set up email capture with MxChat using Loops to grow your mailing list while providing value through your chatbot.', 'mxchat'); ?></p> | |
| 563 | + <p><small><?php echo esc_html__('Note: This tutorial uses an older UI, but the process remains the same.', 'mxchat'); ?></small></p> | |
| 564 | + <a href="https://www.youtube.com/watch?v=CNgm5TYDyTc" target="_blank" rel="noopener" class="video-link"> | |
| 565 | + <span class="video-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19c-2.3 0-6.4-.2-8.1-.6-.7-.2-1.2-.7-1.4-1.4-.3-1.1-.5-3.4-.5-5s.2-3.9.5-5c.2-.7.7-1.2 1.4-1.4C5.6 5.2 9.7 5 12 5s6.4.2 8.1.6c.7.2 1.2.7 1.4 1.4.3 1.1.5 3.4.5 5s-.2 3.9-.5 5c-.2.7-.7 1.2-1.4 1.4-1.7.4-5.8.6-8.1.6z"></path><polygon points="10 15 15 12 10 9 10 15"></polygon></svg></span> | |
| 566 | + <?php echo esc_html__('Watch Loops Email Capture Tutorial', 'mxchat'); ?> | |
| 567 | + </a> | |
| 556 | 568 | </div> |
| 569 | + </div> | |
| 557 | 570 | |
| 558 | - <div class="faq-item"> | |
| 559 | - <h3><?php echo esc_html__('How does the WooCommerce integration work?', 'mxchat'); ?></h3> | |
| 560 | - <p> | |
| 561 | - <?php echo esc_html__('With WooCommerce integration, the chatbot automatically embeds new products and updates existing ones. For already-published products, you can click update or submit the product sitemap. The “Order History Access” setting allows the bot to access users\' order history (requires login) and assist with order inquiries. To enable the “Add to Cart” feature, add this system instruction: “After discussing a product, ask if the user wants to add it to their cart. The user must say \'Add to cart\' exactly.” Currently, this feature supports English only, with more languages coming soon.', 'mxchat'); ?> | |
| 562 | - </p> | |
| 571 | + <div class="tutorial-item"> | |
| 572 | + <h3><?php echo esc_html__('MxChat AI Agent Testing Service', 'mxchat'); ?></h3> | |
| 573 | + <div class="video-description"> | |
| 574 | + <p><?php echo esc_html__('Learn how to use the MxChat AI Agent Testing Service to evaluate and improve your chatbot\'s performance and accuracy.', 'mxchat'); ?></p> | |
| 575 | + <p><small><?php echo esc_html__('Note: This tutorial uses an older UI, but the process remains the same.', 'mxchat'); ?></small></p> | |
| 576 | + <a href="https://www.youtube.com/watch?v=A0jowbpyX54" target="_blank" rel="noopener" class="video-link"> | |
| 577 | + <span class="video-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19c-2.3 0-6.4-.2-8.1-.6-.7-.2-1.2-.7-1.4-1.4-.3-1.1-.5-3.4-.5-5s.2-3.9.5-5c.2-.7.7-1.2 1.4-1.4C5.6 5.2 9.7 5 12 5s6.4.2 8.1.6c.7.2 1.2.7 1.4 1.4.3 1.1.5 3.4.5 5s-.2 3.9-.5 5c-.2.7-.7 1.2-1.4 1.4-1.7.4-5.8.6-8.1.6z"></path><polygon points="10 15 15 12 10 9 10 15"></polygon></svg></span> | |
| 578 | + <?php echo esc_html__('Watch AI Agent Testing Tutorial', 'mxchat'); ?> | |
| 579 | + </a> | |
| 563 | 580 | </div> |
| 581 | + </div> | |
| 582 | + </div> | |
| 564 | 583 | |
| 565 | - <div class="faq-item"> | |
| 566 | - <h3><?php echo esc_html__('Why isn\'t my chatbot responding as expected?', 'mxchat'); ?></h3> | |
| 584 | + <div class="support-section"> | |
| 585 | + <h3><?php echo esc_html__('Need Help?', 'mxchat'); ?></h3> | |
| 586 | + <div class="support-content"> | |
| 567 | 587 | <p> |
| 568 | - <?php echo esc_html__('AI chatbots can sometimes behave in unexpected ways, especially if you\'re new to configuring AI for specific tasks. We\'re committed to helping you get the most out of your chatbot experience. While we’re working on comprehensive guides and video tutorials, our team is here to assist you directly. If your chatbot isn\'t delivering the responses you need, please don’t hesitate to', 'mxchat'); ?> <a href="https://mxchat.ai/contact/" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('contact us', 'mxchat'); ?></a> <?php echo esc_html__('for personalized support.', 'mxchat'); ?> | |
| 588 | + <?php echo esc_html__('If you\'re having trouble with setup or getting the responses you need, we encourage you to review our', 'mxchat'); ?> | |
| 589 | + <a href="https://mxchat.ai/documentation/" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('documentation', 'mxchat'); ?></a> <?php echo esc_html__('or', 'mxchat'); ?> | |
| 590 | + <a href="https://wordpress.org/support/plugin/mxchat-basic/" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('create a support ticket', 'mxchat'); ?></a>. | |
| 569 | 591 | </p> |
| 570 | 592 | <p> |
| 571 | - <?php echo esc_html__('We’re dedicated to your success and ready to guide you in aligning the AI\'s behavior to meet your goals.', 'mxchat'); ?> | |
| 593 | + <?php echo esc_html__('If you like our plugin, please consider', 'mxchat'); ?> <a href="https://wordpress.org/plugins/mxchat-basic/#reviews" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('leaving us a review', 'mxchat'); ?></a>. | |
| 572 | 594 | </p> |
| 573 | 595 | </div> |
| 596 | + </div> | |
| 597 | + | |
| 598 | + | |
| 599 | + </div> | |
| 574 | 600 | |
| 575 | - <div class="faq-item"> | |
| 576 | - <h3><?php echo esc_html__('What is Loops, and how do I get an API key?', 'mxchat'); ?></h3> | |
| 577 | - <p> | |
| 578 | - <?php echo esc_html__('Loops is a powerful SaaS email service that helps you automate and enhance your email marketing campaigns, making it easy to reach and engage with your audience. To integrate Loops with MxChat, you’ll need an API key from Loops. You can obtain this key by logging into your Loops account and navigating to the API settings. Visit the', 'mxchat'); ?> <a href="https://loops.so" target="_blank" rel="noopener noreferrer"><?php echo esc_html__('Loops website', 'mxchat'); ?></a> <?php echo esc_html__('to get started or to sign up for an account.', 'mxchat'); ?> | |
| 579 | - </p> | |
| 580 | - </div> | |
| 581 | - | |
| 582 | 601 | </div> |
| 583 | 602 | </div> |
| 584 | 603 | <?php |
| 585 | 604 | } |
| @@ -584,73 +603,348 @@ | ||
| 584 | 603 | <?php |
| 585 | 604 | } |
| 586 | 605 | |
| 587 | 606 | |
| 588 | - | |
| 589 | 607 | public function mxchat_create_transcripts_page() { |
| 590 | 608 | global $wpdb; |
| 591 | 609 | $table_name = $wpdb->prefix . 'mxchat_chat_transcripts'; |
| 592 | - | |
| 610 | + | |
| 593 | 611 | // Get basic stats |
| 594 | 612 | $total_chats = $wpdb->get_var("SELECT COUNT(DISTINCT session_id) FROM $table_name"); |
| 595 | 613 | $total_messages = $wpdb->get_var("SELECT COUNT(*) FROM $table_name"); |
| 596 | - $total_users = $wpdb->get_var("SELECT COUNT(DISTINCT user_email) FROM $table_name WHERE user_email != ''"); | |
| 614 | + | |
| 615 | + // Count unique users with detailed breakdown | |
| 616 | + $total_users = $wpdb->get_var(" | |
| 617 | + SELECT COUNT(DISTINCT | |
| 618 | + CASE | |
| 619 | + WHEN user_email != '' AND user_email IS NOT NULL THEN user_email | |
| 620 | + WHEN user_id != 0 THEN CONCAT('user_', user_id) | |
| 621 | + WHEN user_identifier NOT LIKE 'Tech-Savvy User' | |
| 622 | + AND user_identifier NOT LIKE 'Detail-Oriented User' | |
| 623 | + AND user_identifier NOT LIKE 'Language Learner' | |
| 624 | + AND user_identifier NOT LIKE 'Casual Browser' | |
| 625 | + AND user_identifier NOT LIKE 'Policy Enforcer' | |
| 626 | + AND user_identifier NOT LIKE 'Researcher' | |
| 627 | + AND user_identifier NOT LIKE 'Loyalty Member' | |
| 628 | + AND user_identifier NOT LIKE 'Gift Buyer' | |
| 629 | + AND user_identifier NOT LIKE 'Parent or Caregiver' | |
| 630 | + THEN user_identifier | |
| 631 | + ELSE session_id | |
| 632 | + END | |
| 633 | + ) | |
| 634 | + FROM $table_name | |
| 635 | + WHERE role != 'assistant' | |
| 636 | + "); | |
| 637 | + | |
| 638 | + // Get user type breakdown | |
| 639 | + $registered_users = $wpdb->get_var(" | |
| 640 | + SELECT COUNT(DISTINCT user_email) | |
| 641 | + FROM $table_name | |
| 642 | + WHERE user_email != '' AND user_email IS NOT NULL | |
| 643 | + "); | |
| 644 | + | |
| 645 | + $guest_users = $wpdb->get_var(" | |
| 646 | + SELECT COUNT(DISTINCT user_identifier) | |
| 647 | + FROM $table_name | |
| 648 | + WHERE (user_email = '' OR user_email IS NULL) | |
| 649 | + AND role != 'assistant' | |
| 650 | + AND user_identifier NOT LIKE 'Tech-Savvy User' | |
| 651 | + AND user_identifier NOT LIKE 'Detail-Oriented User' | |
| 652 | + AND user_identifier NOT LIKE 'Language Learner' | |
| 653 | + AND user_identifier NOT LIKE 'Casual Browser' | |
| 654 | + AND user_identifier NOT LIKE 'Policy Enforcer' | |
| 655 | + AND user_identifier NOT LIKE 'Researcher' | |
| 656 | + AND user_identifier NOT LIKE 'Loyalty Member' | |
| 657 | + AND user_identifier NOT LIKE 'Gift Buyer' | |
| 658 | + AND user_identifier NOT LIKE 'Parent or Caregiver' | |
| 659 | + "); | |
| 660 | + | |
| 661 | + // Get agent test messages count | |
| 662 | + $agent_tests = $wpdb->get_var(" | |
| 663 | + SELECT COUNT(DISTINCT session_id) | |
| 664 | + FROM $table_name | |
| 665 | + WHERE user_identifier IN ( | |
| 666 | + 'Tech-Savvy User', | |
| 667 | + 'Detail-Oriented User', | |
| 668 | + 'Language Learner', | |
| 669 | + 'Casual Browser', | |
| 670 | + 'Policy Enforcer', | |
| 671 | + 'Researcher', | |
| 672 | + 'Loyalty Member', | |
| 673 | + 'Gift Buyer', | |
| 674 | + 'Parent or Caregiver' | |
| 675 | + ) | |
| 676 | + "); | |
| 597 | 677 | ?> |
| 598 | - <div class="wrap mxchat-admin"> | |
| 599 | - <!-- Stats Cards --> | |
| 600 | - <div class="mxchat-stats-grid"> | |
| 601 | - <div class="mxchat-stat-card"> | |
| 602 | - <div class="stat-icon">💬</div> | |
| 603 | - <div class="stat-content"> | |
| 604 | - <span class="stat-value"><?php echo esc_html($total_chats); ?></span> | |
| 605 | - <span class="stat-label"><?php esc_html_e('Total Chats', 'mxchat'); ?></span> | |
| 678 | + <div class="wrap mxchat-transcripts-wrapper"> | |
| 679 | + <!-- Hero Section --> | |
| 680 | + <div class="mxchat-transcripts-hero"> | |
| 681 | + <h1 class="mxchat-main-title"> | |
| 682 | + Chat <span class="mxchat-gradient-text">Transcripts</span> | |
| 683 | + </h1> | |
| 684 | + <p class="mxchat-hero-subtitle"> | |
| 685 | + <?php esc_html_e('Review and manage your chatbot conversations with detailed message history.', 'mxchat'); ?> | |
| 686 | + </p> | |
| 687 | + </div> | |
| 688 | + <div class="mxchat-content"> | |
| 689 | + <!-- Stats Cards --> | |
| 690 | + <div class="mxchat-stats-grid"> | |
| 691 | + <div class="mxchat-stat-card"> | |
| 692 | + <div class="stat-icon">💬</div> | |
| 693 | + <div class="stat-content"> | |
| 694 | + <span class="stat-value"><?php echo esc_html($total_chats); ?></span> | |
| 695 | + <span class="stat-label"><?php esc_html_e('Total Chats', 'mxchat'); ?></span> | |
| 696 | + </div> | |
| 606 | 697 | </div> |
| 607 | - </div> | |
| 608 | - <div class="mxchat-stat-card"> | |
| 609 | - <div class="stat-icon">📝</div> | |
| 610 | - <div class="stat-content"> | |
| 611 | - <span class="stat-value"><?php echo esc_html($total_messages); ?></span> | |
| 612 | - <span class="stat-label"><?php esc_html_e('Total Messages', 'mxchat'); ?></span> | |
| 698 | + <div class="mxchat-stat-card"> | |
| 699 | + <div class="stat-icon">📝</div> | |
| 700 | + <div class="stat-content"> | |
| 701 | + <span class="stat-value"><?php echo esc_html($total_messages); ?></span> | |
| 702 | + <span class="stat-label"><?php esc_html_e('Total Messages', 'mxchat'); ?></span> | |
| 703 | + </div> | |
| 613 | 704 | </div> |
| 705 | + <div class="mxchat-stat-card"> | |
| 706 | + <div class="stat-icon">👥</div> | |
| 707 | + <div class="stat-content"> | |
| 708 | + <span class="stat-value"><?php echo esc_html($total_users); ?></span> | |
| 709 | + <span class="stat-label"><?php esc_html_e('Unique Users', 'mxchat'); ?></span> | |
| 710 | + <span class="stat-sublabel"> | |
| 711 | + <?php | |
| 712 | + echo sprintf( | |
| 713 | + esc_html__('%d registered, %d guests, %d agent tests', 'mxchat'), | |
| 714 | + $registered_users, | |
| 715 | + $guest_users, | |
| 716 | + $agent_tests | |
| 717 | + ); | |
| 718 | + ?> | |
| 719 | + </span> | |
| 720 | + </div> | |
| 721 | + </div> | |
| 614 | 722 | </div> |
| 615 | - <div class="mxchat-stat-card"> | |
| 616 | - <div class="stat-icon">👥</div> | |
| 617 | - <div class="stat-content"> | |
| 618 | - <span class="stat-value"><?php echo esc_html($total_users); ?></span> | |
| 619 | - <span class="stat-label"><?php esc_html_e('Unique Users', 'mxchat'); ?></span> | |
| 723 | + <!-- Search and Filter Controls --> | |
| 724 | + <div class="mxchat-controls-wrapper"> | |
| 725 | + <div class="mxchat-search-box"> | |
| 726 | + <input type="text" id="mxchat-search-transcripts" | |
| 727 | + placeholder="<?php esc_attr_e('Search transcripts...', 'mxchat'); ?>" | |
| 728 | + class="regular-text"> | |
| 620 | 729 | </div> |
| 730 | + <form id="mxchat-delete-form" method="post"> | |
| 731 | + <?php wp_nonce_field('mxchat_delete_chat_history', 'mxchat_delete_chat_nonce'); ?> | |
| 732 | + <div class="mxchat-controls"> | |
| 733 | + <button type="button" id="mxchat-export-transcripts" class="mxchat-action-button"> | |
| 734 | + <span class="dashicons dashicons-download"></span> | |
| 735 | + <?php esc_html_e('Export All Chats', 'mxchat'); ?> | |
| 736 | + </button> | |
| 737 | + <button type="button" id="mxchat-select-all-transcripts" class="mxchat-select-button"> | |
| 738 | + <span class="dashicons dashicons-yes-alt"></span> | |
| 739 | + <span class="button-text"><?php esc_html_e('Select All', 'mxchat'); ?></span> | |
| 740 | + </button> | |
| 741 | + <button type="submit" class="button delete-chats-button"> | |
| 742 | + <span class="dashicons dashicons-trash"></span> | |
| 743 | + <?php esc_html_e('Delete Selected', 'mxchat'); ?> | |
| 744 | + </button> | |
| 745 | + </div> | |
| 746 | + </form> | |
| 621 | 747 | </div> |
| 748 | + <!-- Transcripts Container --> | |
| 749 | + <div id="mxchat-transcripts"></div> | |
| 622 | 750 | </div> |
| 751 | + </div> | |
| 752 | + <?php | |
| 753 | +} | |
| 623 | 754 | |
| 624 | - <!-- Search and Filter Controls --> | |
| 625 | - <div class="mxchat-controls-wrapper"> | |
| 626 | - <div class="mxchat-search-box"> | |
| 627 | - <input type="text" id="mxchat-search-transcripts" | |
| 628 | - placeholder="<?php esc_attr_e('Search transcripts...', 'mxchat'); ?>" | |
| 629 | - class="regular-text"> | |
| 630 | - </div> | |
| 755 | +public function export_chat_transcripts() { | |
| 756 | + if (!current_user_can('manage_options')) { | |
| 757 | + wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'mxchat')); | |
| 758 | + } | |
| 631 | 759 | |
| 632 | - <form id="mxchat-delete-form" method="post"> | |
| 633 | - <?php wp_nonce_field('mxchat_delete_chat_history', 'mxchat_delete_chat_nonce'); ?> | |
| 634 | - <div class="mxchat-controls"> | |
| 635 | - <button type="button" id="mxchat-select-all-transcripts" class="mxchat-select-button"> | |
| 636 | - <span class="dashicons dashicons-yes-alt"></span> | |
| 637 | - <span class="button-text"><?php esc_html_e('Select All', 'mxchat'); ?></span> | |
| 638 | - </button> | |
| 639 | - <button type="submit" class="button delete-chats-button"> | |
| 640 | - <span class="dashicons dashicons-trash"></span> | |
| 641 | - <?php esc_html_e('Delete Selected', 'mxchat'); ?> | |
| 642 | - </button> | |
| 643 | - </div> | |
| 644 | - </form> | |
| 645 | - </div> | |
| 760 | + check_ajax_referer('mxchat_export_transcripts', 'security'); | |
| 646 | 761 | |
| 647 | - <!-- Transcripts Container --> | |
| 648 | - <div id="mxchat-transcripts"></div> | |
| 649 | - </div> | |
| 650 | - <?php | |
| 762 | + global $wpdb; | |
| 763 | + $table_name = $wpdb->prefix . 'mxchat_chat_transcripts'; | |
| 764 | + | |
| 765 | + // Get all transcripts ordered by session and timestamp | |
| 766 | + $results = $wpdb->get_results( | |
| 767 | + "SELECT session_id, user_email, user_identifier, role, message, timestamp | |
| 768 | + FROM {$table_name} | |
| 769 | + ORDER BY session_id, timestamp ASC" | |
| 770 | + ); | |
| 771 | + | |
| 772 | + if (empty($results)) { | |
| 773 | + wp_send_json_error(array('message' => 'No transcripts found.')); | |
| 774 | + wp_die(); | |
| 775 | + } | |
| 776 | + | |
| 777 | + // Set headers for CSV download | |
| 778 | + header('Content-Type: text/csv'); | |
| 779 | + header('Content-Disposition: attachment; filename="chat-transcripts-' . date('Y-m-d') . '.csv"'); | |
| 780 | + header('Pragma: no-cache'); | |
| 781 | + header('Expires: 0'); | |
| 782 | + | |
| 783 | + // Create output stream | |
| 784 | + $output = fopen('php://output', 'w'); | |
| 785 | + | |
| 786 | + // Add UTF-8 BOM for proper Excel encoding | |
| 787 | + fputs($output, "\xEF\xBB\xBF"); | |
| 788 | + | |
| 789 | + // Add CSV headers | |
| 790 | + fputcsv($output, array( | |
| 791 | + 'Session ID', | |
| 792 | + 'Email', | |
| 793 | + 'User Identifier', | |
| 794 | + 'Role', | |
| 795 | + 'Message', | |
| 796 | + 'Timestamp' | |
| 797 | + )); | |
| 798 | + | |
| 799 | + // Add data rows | |
| 800 | + foreach ($results as $row) { | |
| 801 | + fputcsv($output, array( | |
| 802 | + $row->session_id, | |
| 803 | + $row->user_email, | |
| 804 | + $row->user_identifier, | |
| 805 | + $row->role, | |
| 806 | + $row->message, | |
| 807 | + $row->timestamp | |
| 808 | + )); | |
| 809 | + } | |
| 810 | + | |
| 811 | + fclose($output); | |
| 812 | + wp_die(); | |
| 651 | 813 | } |
| 652 | 814 | |
| 815 | +public function mxchat_fetch_chat_history() { | |
| 816 | + global $wpdb; | |
| 817 | + $table_name = $wpdb->prefix . 'mxchat_chat_transcripts'; | |
| 818 | + | |
| 819 | + if (!current_user_can('manage_options')) { | |
| 820 | + wp_die(esc_html__('You do not have sufficient permissions to view this page.', 'mxchat')); | |
| 821 | + } | |
| 822 | + | |
| 823 | + // First get unique session IDs ordered by most recent message in each session | |
| 824 | + $session_ids = $wpdb->get_col( | |
| 825 | + $wpdb->prepare( | |
| 826 | + "SELECT DISTINCT session_id | |
| 827 | + FROM {$table_name} | |
| 828 | + GROUP BY session_id | |
| 829 | + ORDER BY MAX(timestamp) DESC" | |
| 830 | + ) | |
| 831 | + ); | |
| 832 | + | |
| 833 | + if (empty($session_ids)) { | |
| 834 | + wp_die(esc_html__('No chat history available.', 'mxchat')); | |
| 835 | + } | |
| 836 | + | |
| 837 | + ob_start(); | |
| 838 | + echo '<div class="mxchat-transcript">'; | |
| 839 | + | |
| 840 | + // Iterate through sessions from newest to oldest | |
| 841 | + foreach ($session_ids as $session_id) { | |
| 842 | + // Get the email associated with this session (if available) | |
| 843 | + $email = $wpdb->get_var( | |
| 844 | + $wpdb->prepare( | |
| 845 | + "SELECT user_email | |
| 846 | + FROM {$table_name} | |
| 847 | + WHERE session_id = %s AND user_email != '' | |
| 848 | + ORDER BY timestamp ASC | |
| 849 | + LIMIT 1", | |
| 850 | + $session_id | |
| 851 | + ) | |
| 852 | + ); | |
| 853 | + | |
| 854 | + // Debug: Check email retrieval | |
| 855 | + if (empty($email)) { | |
| 856 | + //error_log("No email found for session {$session_id}"); | |
| 857 | + } else { | |
| 858 | + //error_log("Email for session {$session_id}: " . $email); | |
| 859 | + } | |
| 860 | + | |
| 861 | + // Get messages for this session ordered by timestamp | |
| 862 | + $messages = $wpdb->get_results( | |
| 863 | + $wpdb->prepare( | |
| 864 | + "SELECT * FROM {$table_name} | |
| 865 | + WHERE session_id = %s | |
| 866 | + ORDER BY timestamp ASC", | |
| 867 | + $session_id | |
| 868 | + ) | |
| 869 | + ); | |
| 870 | + | |
| 871 | + // Start session block | |
| 872 | + echo '<div class="mxchat-session">'; | |
| 873 | + echo '<div class="mxchat-session-header">'; | |
| 874 | + // Wrap checkbox and session ID in one block | |
| 875 | + echo '<div class="mxchat-session-id">'; | |
| 876 | + echo '<input type="checkbox" name="delete_session_ids[]" value="' . esc_attr($session_id) . '"> '; | |
| 877 | + echo '<strong>' . esc_html__('Session ID:', 'mxchat') . '</strong> ' . esc_html($session_id); | |
| 878 | + echo '</div>'; | |
| 879 | + | |
| 880 | + // Place email directly below the session ID block | |
| 881 | + if (!empty($email)) { | |
| 882 | + echo '<div class="mxchat-session-email">'; | |
| 883 | + echo '<strong>' . esc_html__('Email:', 'mxchat') . '</strong> ' . esc_html($email); | |
| 884 | + echo '</div>'; | |
| 885 | + } | |
| 886 | + echo '</div>'; | |
| 887 | + | |
| 888 | + echo '<div class="mxchat-messages">'; | |
| 889 | + | |
| 890 | + // Display messages for this session | |
| 891 | + foreach ($messages as $transcript) { | |
| 892 | + $formatted_timestamp = date_i18n('F j, Y g:i a', strtotime($transcript->timestamp)); | |
| 893 | + | |
| 894 | + // Determine message styling | |
| 895 | + switch ($transcript->role) { | |
| 896 | + case 'assistant': | |
| 897 | + case 'bot': | |
| 898 | + $message_class = 'bot-message'; | |
| 899 | + $display_role = esc_html__('Chatbot', 'mxchat'); | |
| 900 | + break; | |
| 901 | + case 'user': | |
| 902 | + $message_class = 'user-message'; | |
| 903 | + $display_role = !empty($transcript->user_identifier) | |
| 904 | + ? sanitize_text_field($transcript->user_identifier) | |
| 905 | + : esc_html__('User', 'mxchat'); | |
| 906 | + break; | |
| 907 | + case 'agent': | |
| 908 | + $message_class = 'agent-message'; | |
| 909 | + $display_role = esc_html__('Agent', 'mxchat'); | |
| 910 | + break; | |
| 911 | + default: | |
| 912 | + $message_class = 'unknown-message'; | |
| 913 | + $display_role = esc_html__('Unknown', 'mxchat'); | |
| 914 | + } | |
| 915 | + | |
| 916 | + // Process message content | |
| 917 | + $message_content = wp_kses( | |
| 918 | + stripslashes($transcript->message), | |
| 919 | + [ | |
| 920 | + 'b' => [], 'strong' => [], 'i' => [], 'em' => [], 'u' => [], | |
| 921 | + 'br' => [], 'p' => [], 'ul' => [], 'ol' => [], 'li' => [], | |
| 922 | + 'a' => ['href' => [], 'title' => []] | |
| 923 | + ] | |
| 924 | + ); | |
| 925 | + $message_content = nl2br($message_content); | |
| 926 | + | |
| 927 | + // Render message | |
| 928 | + echo '<div class="mxchat-message ' . esc_attr($message_class) . '">'; | |
| 929 | + echo '<div class="mxchat-message-header">' . esc_html($display_role) . '</div>'; | |
| 930 | + echo '<div class="mxchat-message-content">' . $message_content . '</div>'; | |
| 931 | + echo '<div class="mxchat-timestamp">' . esc_html($formatted_timestamp) . '</div>'; | |
| 932 | + echo '</div>'; | |
| 933 | + } | |
| 934 | + | |
| 935 | + // Close session block | |
| 936 | + echo '</div></div>'; | |
| 937 | + } | |
| 938 | + | |
| 939 | + echo '</div>'; | |
| 940 | + $output = ob_get_clean(); | |
| 941 | + echo $output; | |
| 942 | + wp_die(); | |
| 943 | +} | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 653 | 947 | public function mxchat_create_prompts_page() { |
| 654 | 948 | global $wpdb; |
| 655 | 949 | $table_name = $wpdb->prefix . 'mxchat_system_prompt_content'; |
| 656 | 950 | |
| @@ -781,10 +1075,9 @@ | ||
| 781 | 1075 | <!-- Import Methods --> |
| 782 | 1076 | <div class="mxchat-import-methods"> |
| 783 | 1077 | <div class="mxchat-method-card"> |
| 784 | 1078 | <h4><?php esc_html_e('Sitemap Import', 'mxchat'); ?></h4> |
| 785 | - <p><?php esc_html_e('Import all content from your sitemap automatically.', 'mxchat'); ?></p> | |
| 786 | - </div> | |
| 1079 | + <p><span class="red-warning">IMPORTANT:</span> <?php esc_html_e('Use a content-specific sub-sitemap, not the sitemap index.', 'mxchat'); ?></p> </div> | |
| 787 | 1080 | <div class="mxchat-method-card"> |
| 788 | 1081 | <h4><?php esc_html_e('PDF Import', 'mxchat'); ?></h4> |
| 789 | 1082 | <p><?php esc_html_e('Import knowledge directly from PDF documents.', 'mxchat'); ?></p> |
| 790 | 1083 | </div> |
| @@ -1091,30 +1384,127 @@ | ||
| 1091 | 1384 | |
| 1092 | 1385 | wp_safe_redirect(add_query_arg(array('page' => 'mxchat-prompts', 'deleted' => 'true'), admin_url('admin.php'))); |
| 1093 | 1386 | exit; |
| 1094 | 1387 | } |
| 1095 | -public function mxchat_generate_embedding($text) { | |
| 1096 | - $options = get_option('mxchat_options'); | |
| 1097 | - $api_key = $options['api_key'] ?? esc_html__('default_api_key', 'mxchat'); | |
| 1098 | 1388 | |
| 1099 | - $response = wp_remote_post('https://api.openai.com/v1/embeddings', array( | |
| 1100 | - 'body' => wp_json_encode(array( | |
| 1101 | - 'model' => esc_html__('text-embedding-ada-002', 'mxchat'), | |
| 1102 | - 'input' => $text | |
| 1103 | - )), | |
| 1104 | - 'headers' => array( | |
| 1105 | - 'Authorization' => 'Bearer ' . $api_key, | |
| 1106 | - 'Content-Type' => esc_html__('application/json', 'mxchat') | |
| 1107 | - ), | |
| 1108 | - )); | |
| 1109 | 1389 | |
| 1110 | - if (is_wp_error($response)) { | |
| 1111 | - return null; | |
| 1390 | +public function mxchat_generate_embedding($text) { | |
| 1391 | + //error_log('[MXCHAT-EMBED] Starting embedding generation. Text length: ' . strlen($text) . ' bytes'); | |
| 1392 | + //error_log('[MXCHAT-EMBED] Text preview: ' . substr($text, 0, 100) . '...'); | |
| 1393 | + | |
| 1394 | + $options = get_option('mxchat_options'); | |
| 1395 | + $selected_model = $options['embedding_model'] ?? 'text-embedding-ada-002'; | |
| 1396 | + //error_log('[MXCHAT-EMBED] Selected embedding model: ' . $selected_model); | |
| 1397 | + | |
| 1398 | + // Determine provider and endpoint | |
| 1399 | + if (strpos($selected_model, 'voyage') === 0) { | |
| 1400 | + $api_key = $options['voyage_api_key'] ?? ''; | |
| 1401 | + $endpoint = 'https://api.voyageai.com/v1/embeddings'; | |
| 1402 | + //error_log('[MXCHAT-EMBED] Using Voyage AI API'); | |
| 1403 | + } else { | |
| 1404 | + $api_key = $options['api_key'] ?? ''; | |
| 1405 | + $endpoint = 'https://api.openai.com/v1/embeddings'; | |
| 1406 | + //error_log('[MXCHAT-EMBED] Using OpenAI API'); | |
| 1407 | + } | |
| 1408 | + | |
| 1409 | + //error_log('[MXCHAT-EMBED] Using endpoint: ' . $endpoint); | |
| 1410 | + | |
| 1411 | + if (empty($api_key)) { | |
| 1412 | + //error_log('[MXCHAT-EMBED] Error: API key not configured'); | |
| 1413 | + return null; | |
| 1414 | + } | |
| 1415 | + | |
| 1416 | + // Check if text is too long (for OpenAI, roughly estimate tokens as words/0.75) | |
| 1417 | + $estimated_tokens = ceil(str_word_count($text) / 0.75); | |
| 1418 | + //error_log('[MXCHAT-EMBED] Estimated token count: ~' . $estimated_tokens); | |
| 1419 | + | |
| 1420 | + if ($estimated_tokens > 8000 && strpos($selected_model, 'voyage') === false) { | |
| 1421 | + //error_log('[MXCHAT-EMBED] Warning: Text may exceed OpenAI token limits (8K for most models)'); | |
| 1422 | + // Consider truncating text here | |
| 1423 | + } | |
| 1424 | + | |
| 1425 | + // Prepare request body | |
| 1426 | + $request_body = array( | |
| 1427 | + 'model' => $selected_model, | |
| 1428 | + 'input' => $text | |
| 1429 | + ); | |
| 1430 | + | |
| 1431 | + // Add output_dimension for voyage-3-large model | |
| 1432 | + if ($selected_model === 'voyage-3-large') { | |
| 1433 | + $request_body['output_dimension'] = 2048; | |
| 1434 | + } | |
| 1435 | + | |
| 1436 | + //error_log('[MXCHAT-EMBED] Request prepared with model: ' . $selected_model); | |
| 1437 | + | |
| 1438 | + // Make API request | |
| 1439 | + //error_log('[MXCHAT-EMBED] Sending API request to: ' . $endpoint); | |
| 1440 | + $response = wp_remote_post($endpoint, array( | |
| 1441 | + 'body' => wp_json_encode($request_body), | |
| 1442 | + 'headers' => array( | |
| 1443 | + 'Authorization' => 'Bearer ' . $api_key, | |
| 1444 | + 'Content-Type' => 'application/json' | |
| 1445 | + ), | |
| 1446 | + 'timeout' => 60 // Increased timeout for large inputs | |
| 1447 | + )); | |
| 1448 | + | |
| 1449 | + // Handle wp_remote_post errors | |
| 1450 | + if (is_wp_error($response)) { | |
| 1451 | + //error_log('[MXCHAT-EMBED] WP Remote Post Error: ' . $response->get_error_message()); | |
| 1452 | + return null; | |
| 1453 | + } | |
| 1454 | + | |
| 1455 | + // Get and check HTTP response code | |
| 1456 | + $http_code = wp_remote_retrieve_response_code($response); | |
| 1457 | + //error_log('[MXCHAT-EMBED] API Response Code: ' . $http_code); | |
| 1458 | + | |
| 1459 | + if ($http_code !== 200) { | |
| 1460 | + $error_body = wp_remote_retrieve_body($response); | |
| 1461 | + //error_log('[MXCHAT-EMBED] API Error Response Body: ' . $error_body); | |
| 1462 | + | |
| 1463 | + // Try to parse error for more details | |
| 1464 | + $error_json = json_decode($error_body, true); | |
| 1465 | + if (json_last_error() === JSON_ERROR_NONE && isset($error_json['error'])) { | |
| 1466 | + //error_log('[MXCHAT-EMBED] API Error Type: ' . ($error_json['error']['type'] ?? 'unknown')); | |
| 1467 | + //error_log('[MXCHAT-EMBED] API Error Message: ' . ($error_json['error']['message'] ?? 'No message')); | |
| 1112 | 1468 | } |
| 1113 | - | |
| 1114 | - $response_data = json_decode(wp_remote_retrieve_body($response), true); | |
| 1115 | - return $response_data['data'][0]['embedding'] ?? null; | |
| 1469 | + | |
| 1470 | + return null; | |
| 1116 | 1471 | } |
| 1472 | + | |
| 1473 | + // Parse response body | |
| 1474 | + $response_body = wp_remote_retrieve_body($response); | |
| 1475 | + //error_log('[MXCHAT-EMBED] Received response length: ' . strlen($response_body) . ' bytes'); | |
| 1476 | + | |
| 1477 | + $response_data = json_decode($response_body, true); | |
| 1478 | + | |
| 1479 | + if (json_last_error() !== JSON_ERROR_NONE) { | |
| 1480 | + //error_log('[MXCHAT-EMBED] JSON Parse Error: ' . json_last_error_msg()); | |
| 1481 | + //error_log('[MXCHAT-EMBED] Response preview: ' . substr($response_body, 0, 200)); | |
| 1482 | + return null; | |
| 1483 | + } | |
| 1484 | + | |
| 1485 | + // Both APIs use the same structure, so we can extract the embedding the same way | |
| 1486 | + if (isset($response_data['data'][0]['embedding'])) { | |
| 1487 | + $embedding_dimensions = count($response_data['data'][0]['embedding']); | |
| 1488 | + //error_log('[MXCHAT-EMBED] Successfully extracted embedding with ' . $embedding_dimensions . ' dimensions'); | |
| 1489 | + | |
| 1490 | + // Check if embedding dimensions are as expected | |
| 1491 | + if (($selected_model === 'text-embedding-ada-002' && $embedding_dimensions !== 1536) || | |
| 1492 | + ($selected_model === 'voyage-3-large' && $embedding_dimensions !== 2048)) { | |
| 1493 | + } | |
| 1494 | + | |
| 1495 | + return $response_data['data'][0]['embedding']; | |
| 1496 | + } else { | |
| 1497 | + //error_log('[MXCHAT-EMBED] Error: No embedding found in response'); | |
| 1498 | + //error_log('[MXCHAT-EMBED] Response structure: ' . wp_json_encode(array_keys($response_data))); | |
| 1499 | + | |
| 1500 | + if (isset($response_data['error'])) { | |
| 1501 | + //error_log('[MXCHAT-EMBED] API Error in response: ' . wp_json_encode($response_data['error'])); | |
| 1502 | + } | |
| 1503 | + | |
| 1504 | + return null; | |
| 1505 | + } | |
| 1506 | +} | |
| 1117 | 1507 | public function mxchat_delete_chat_history() { |
| 1118 | 1508 | if (!current_user_can('manage_options')) { |
| 1119 | 1509 | echo wp_json_encode(['error' => esc_html__('You do not have sufficient permissions.', 'mxchat')]); |
| 1120 | 1510 | wp_die(); |
| @@ -1339,8 +1729,10 @@ | ||
| 1339 | 1729 | 'success' => true, |
| 1340 | 1730 | 'message' => 'Successfully stored in Pinecone' |
| 1341 | 1731 | ); |
| 1342 | 1732 | } |
| 1733 | + | |
| 1734 | + | |
| 1343 | 1735 | // Helper method for WordPress DB storage |
| 1344 | 1736 | private function store_in_wordpress_db($content, $url, $embedding_vector) { |
| 1345 | 1737 | global $wpdb; |
| 1346 | 1738 | $table_name = $wpdb->prefix . 'mxchat_system_prompt_content'; |
| @@ -1716,19 +2108,26 @@ | ||
| 1716 | 2108 | 'status' => sanitize_text_field($status['status']), |
| 1717 | 2109 | 'last_update' => human_time_diff(absint($status['last_update']), time()) . ' ' . esc_html__('ago', 'mxchat') |
| 1718 | 2110 | ); |
| 1719 | 2111 | } |
| 2112 | + | |
| 1720 | 2113 | public function mxchat_handle_sitemap_submission() { |
| 2114 | + // Start logging the submission process | |
| 2115 | + //error_log('[MXCHAT-URL] ===== Starting URL submission process ====='); | |
| 2116 | + | |
| 1721 | 2117 | // Check if the form was submitted and verify permissions |
| 1722 | 2118 | if (!isset($_POST['submit_sitemap']) || !current_user_can('manage_options')) { |
| 2119 | + //error_log('[MXCHAT-URL] Error: Unauthorized access or form not submitted properly'); | |
| 1723 | 2120 | wp_die(esc_html__('Unauthorized access', 'mxchat')); |
| 1724 | 2121 | } |
| 1725 | 2122 | |
| 1726 | 2123 | // Verify nonce |
| 2124 | + //error_log('[MXCHAT-URL] Verifying nonce'); | |
| 1727 | 2125 | check_admin_referer('mxchat_submit_sitemap_action', 'mxchat_submit_sitemap_nonce'); |
| 1728 | 2126 | |
| 1729 | 2127 | // Validate URL |
| 1730 | 2128 | if (!isset($_POST['sitemap_url']) || empty($_POST['sitemap_url'])) { |
| 2129 | + //error_log('[MXCHAT-URL] Error: Empty or missing URL'); | |
| 1731 | 2130 | set_transient('mxchat_admin_notice_error', |
| 1732 | 2131 | esc_html__('Please provide a valid URL.', 'mxchat'), |
| 1733 | 2132 | 30 |
| 1734 | 2133 | ); |
| @@ -1736,12 +2135,16 @@ | ||
| 1736 | 2135 | exit; |
| 1737 | 2136 | } |
| 1738 | 2137 | |
| 1739 | 2138 | $submitted_url = esc_url_raw($_POST['sitemap_url']); |
| 2139 | + //error_log('[MXCHAT-URL] Processing URL: ' . $submitted_url); | |
| 2140 | + | |
| 2141 | + //error_log('[MXCHAT-URL] Fetching URL content'); | |
| 1740 | 2142 | $response = wp_remote_get($submitted_url, array('timeout' => 30)); |
| 1741 | 2143 | |
| 1742 | 2144 | if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) { |
| 1743 | - $error_message = is_wp_error($response) ? $response->get_error_message() : __('Failed to fetch URL', 'mxchat'); | |
| 2145 | + $error_message = is_wp_error($response) ? $response->get_error_message() : 'HTTP Status: ' . wp_remote_retrieve_response_code($response); | |
| 2146 | + //error_log('[MXCHAT-URL] Error fetching URL: ' . $error_message); | |
| 1744 | 2147 | set_transient('mxchat_admin_notice_error', |
| 1745 | 2148 | sprintf( |
| 1746 | 2149 | esc_html__('Failed to fetch the URL: %s', 'mxchat'), |
| 1747 | 2150 | esc_html($error_message) |
| @@ -1752,11 +2155,13 @@ | ||
| 1752 | 2155 | exit; |
| 1753 | 2156 | } |
| 1754 | 2157 | |
| 1755 | 2158 | $content_type = wp_remote_retrieve_header($response, 'content-type'); |
| 2159 | + //error_log('[MXCHAT-URL] Content type: ' . $content_type); | |
| 1756 | 2160 | $body_content = wp_remote_retrieve_body($response); |
| 1757 | 2161 | |
| 1758 | 2162 | if (empty($body_content)) { |
| 2163 | + //error_log('[MXCHAT-URL] Error: Empty response body'); | |
| 1759 | 2164 | set_transient('mxchat_admin_notice_error', |
| 1760 | 2165 | esc_html__('Empty response received from URL.', 'mxchat'), |
| 1761 | 2166 | 30 |
| 1762 | 2167 | ); |
| @@ -1762,12 +2167,15 @@ | ||
| 1762 | 2167 | ); |
| 1763 | 2168 | wp_safe_redirect(esc_url(admin_url('admin.php?page=mxchat-prompts'))); |
| 1764 | 2169 | exit; |
| 1765 | 2170 | } |
| 2171 | + //error_log('[MXCHAT-URL] Retrieved body content length: ' . strlen($body_content) . ' bytes'); | |
| 1766 | 2172 | |
| 1767 | 2173 | // Handle PDF URL |
| 1768 | 2174 | if ($this->is_pdf_url($submitted_url, $response)) { |
| 2175 | + //error_log('[MXCHAT-URL] Detected PDF URL, handling PDF for knowledge base'); | |
| 1769 | 2176 | $result = $this->handle_pdf_for_knowledge_base($submitted_url, $response); |
| 2177 | + //error_log('[MXCHAT-URL] PDF handling result: ' . $result); | |
| 1770 | 2178 | |
| 1771 | 2179 | if ($result === 'scheduled') { |
| 1772 | 2180 | set_transient( |
| 1773 | 2181 | 'mxchat_last_pdf_url', |
| @@ -1790,8 +2198,9 @@ | ||
| 1790 | 2198 | } |
| 1791 | 2199 | |
| 1792 | 2200 | // Handle Sitemap XML |
| 1793 | 2201 | if (strpos($content_type, 'xml') !== false || strpos($body_content, '<urlset') !== false) { |
| 2202 | + //error_log('[MXCHAT-URL] Detected XML content, processing as sitemap'); | |
| 1794 | 2203 | libxml_use_internal_errors(true); |
| 1795 | 2204 | $xml = simplexml_load_string($body_content); |
| 1796 | 2205 | $xml_errors = libxml_get_errors(); |
| 1797 | 2206 | libxml_clear_errors(); |
| @@ -1796,8 +2205,15 @@ | ||
| 1796 | 2205 | $xml_errors = libxml_get_errors(); |
| 1797 | 2206 | libxml_clear_errors(); |
| 1798 | 2207 | |
| 1799 | 2208 | if ($xml === false || !empty($xml_errors)) { |
| 2209 | + //error_log('[MXCHAT-URL] Error: Invalid XML format'); | |
| 2210 | + if (!empty($xml_errors)) { | |
| 2211 | + foreach ($xml_errors as $error) { | |
| 2212 | + //error_log('[MXCHAT-URL] XML Error: ' . $error->message); | |
| 2213 | + } | |
| 2214 | + } | |
| 2215 | + | |
| 1800 | 2216 | set_transient('mxchat_admin_notice_error', |
| 1801 | 2217 | esc_html__('Invalid sitemap XML. Please provide a valid sitemap.', 'mxchat'), |
| 1802 | 2218 | 30 |
| 1803 | 2219 | ); |
| @@ -1804,9 +2220,11 @@ | ||
| 1804 | 2220 | wp_safe_redirect(esc_url(admin_url('admin.php?page=mxchat-prompts'))); |
| 1805 | 2221 | exit; |
| 1806 | 2222 | } |
| 1807 | 2223 | |
| 2224 | + //error_log('[MXCHAT-URL] Valid XML found, handling sitemap for knowledge base'); | |
| 1808 | 2225 | $result = $this->handle_sitemap_for_knowledge_base($xml, $submitted_url); |
| 2226 | + //error_log('[MXCHAT-URL] Sitemap handling result: ' . $result); | |
| 1809 | 2227 | |
| 1810 | 2228 | if ($result === 'scheduled') { |
| 1811 | 2229 | set_transient( |
| 1812 | 2230 | 'mxchat_last_sitemap_url', |
| @@ -1828,12 +2246,17 @@ | ||
| 1828 | 2246 | exit; |
| 1829 | 2247 | } |
| 1830 | 2248 | |
| 1831 | 2249 | // Handle Regular URL |
| 2250 | + //error_log('[MXCHAT-URL] Processing as regular webpage'); | |
| 1832 | 2251 | $page_content = $this->mxchat_extract_main_content($body_content); |
| 2252 | + //error_log('[MXCHAT-URL] Extracted content length: ' . strlen($page_content) . ' bytes'); | |
| 2253 | + | |
| 1833 | 2254 | $sanitized_content = $this->mxchat_sanitize_content_for_api($page_content); |
| 2255 | + //error_log('[MXCHAT-URL] Sanitized content length: ' . strlen($sanitized_content) . ' bytes'); | |
| 1834 | 2256 | |
| 1835 | 2257 | if (empty($sanitized_content)) { |
| 2258 | + //error_log('[MXCHAT-URL] Error: No valid content after sanitization'); | |
| 1836 | 2259 | set_transient('mxchat_admin_notice_error', |
| 1837 | 2260 | esc_html__('No valid content found on the provided URL.', 'mxchat'), |
| 1838 | 2261 | 30 |
| 1839 | 2262 | ); |
| @@ -1840,20 +2263,33 @@ | ||
| 1840 | 2263 | wp_safe_redirect(esc_url(admin_url('admin.php?page=mxchat-prompts'))); |
| 1841 | 2264 | exit; |
| 1842 | 2265 | } |
| 1843 | 2266 | |
| 2267 | + //error_log('[MXCHAT-URL] Generating embedding for content'); | |
| 1844 | 2268 | $embedding_vector = $this->mxchat_generate_embedding($sanitized_content); |
| 2269 | + | |
| 1845 | 2270 | if (is_array($embedding_vector)) { |
| 1846 | - MxChat_Utils::submit_content_to_db( | |
| 2271 | + //error_log('[MXCHAT-URL] Successfully generated embedding with ' . count($embedding_vector) . ' dimensions'); | |
| 2272 | + | |
| 2273 | + //error_log('[MXCHAT-URL] Submitting content to database'); | |
| 2274 | + $db_result = MxChat_Utils::submit_content_to_db( | |
| 1847 | 2275 | $sanitized_content, |
| 1848 | 2276 | $submitted_url, |
| 1849 | 2277 | $this->options['api_key'] |
| 1850 | 2278 | ); |
| 2279 | + | |
| 2280 | + if ($db_result) { | |
| 2281 | + //error_log('[MXCHAT-URL] Successfully stored content in database'); | |
| 2282 | + } else { | |
| 2283 | + //error_log('[MXCHAT-URL] Error: Failed to store content in database'); | |
| 2284 | + } | |
| 2285 | + | |
| 1851 | 2286 | set_transient('mxchat_admin_notice_success', |
| 1852 | 2287 | esc_html__('URL content successfully submitted!', 'mxchat'), |
| 1853 | 2288 | 30 |
| 1854 | 2289 | ); |
| 1855 | 2290 | } else { |
| 2291 | + //error_log('[MXCHAT-URL] Error: Failed to generate embedding. Result: ' . (is_string($embedding_vector) ? $embedding_vector : gettype($embedding_vector))); | |
| 1856 | 2292 | set_transient('mxchat_admin_notice_error', |
| 1857 | 2293 | esc_html__('Failed to generate embedding for the URL content. Please check your API key and try again.', 'mxchat'), |
| 1858 | 2294 | 30 |
| 1859 | 2295 | ); |
| @@ -1858,11 +2294,14 @@ | ||
| 1858 | 2294 | 30 |
| 1859 | 2295 | ); |
| 1860 | 2296 | } |
| 1861 | 2297 | |
| 2298 | + //error_log('[MXCHAT-URL] ===== Completed URL submission process ====='); | |
| 1862 | 2299 | wp_safe_redirect(esc_url(admin_url('admin.php?page=mxchat-prompts'))); |
| 1863 | 2300 | exit; |
| 1864 | 2301 | } |
| 2302 | + | |
| 2303 | + | |
| 1865 | 2304 | private function handle_sitemap_for_knowledge_base($xml, $sitemap_url) { |
| 1866 | 2305 | if (!current_user_can('manage_options')) { |
| 1867 | 2306 | //error_log(esc_html__('Unauthorized sitemap processing attempt', 'mxchat')); |
| 1868 | 2307 | return false; |
| @@ -1975,9 +2414,9 @@ | ||
| 1975 | 2414 | |
| 1976 | 2415 | $batch_stats['processed']++; |
| 1977 | 2416 | } else { |
| 1978 | 2417 | $batch_stats['failed']++; |
| 1979 | - $batch_stats['last_error'] = 'Failed to generate embedding. Please check OpenAI API key.'; | |
| 2418 | + $batch_stats['last_error'] = 'Failed to generate embedding. Please check embedding API key.'; | |
| 1980 | 2419 | } |
| 1981 | 2420 | } |
| 1982 | 2421 | |
| 1983 | 2422 | $status['processed_urls'] = absint($i + 1); |
| @@ -2206,8 +2645,9 @@ | ||
| 2206 | 2645 | $wpdb->delete($table_name, array('source_url' => $source_url), array('%s')); |
| 2207 | 2646 | } |
| 2208 | 2647 | } |
| 2209 | 2648 | |
| 2649 | + | |
| 2210 | 2650 | /** |
| 2211 | 2651 | * Delete vectors from Pinecone by source URL |
| 2212 | 2652 | * |
| 2213 | 2653 | * @param array $urls Array of source URLs to delete |
| @@ -2296,139 +2736,11 @@ | ||
| 2296 | 2736 | ); |
| 2297 | 2737 | } |
| 2298 | 2738 | |
| 2299 | 2739 | |
| 2300 | -public function mxchat_fetch_chat_history() { | |
| 2301 | - global $wpdb; | |
| 2302 | - $table_name = $wpdb->prefix . 'mxchat_chat_transcripts'; | |
| 2303 | 2740 | |
| 2304 | - if (!current_user_can('manage_options')) { | |
| 2305 | - wp_die(esc_html__('You do not have sufficient permissions to view this page.', 'mxchat')); | |
| 2306 | - } | |
| 2307 | 2741 | |
| 2308 | - // First get unique session IDs ordered by most recent message in each session | |
| 2309 | - $session_ids = $wpdb->get_col( | |
| 2310 | - $wpdb->prepare( | |
| 2311 | - "SELECT DISTINCT session_id | |
| 2312 | - FROM {$table_name} | |
| 2313 | - GROUP BY session_id | |
| 2314 | - ORDER BY MAX(timestamp) DESC" | |
| 2315 | - ) | |
| 2316 | - ); | |
| 2317 | 2742 | |
| 2318 | - if (empty($session_ids)) { | |
| 2319 | - wp_die(esc_html__('No chat history available.', 'mxchat')); | |
| 2320 | - } | |
| 2321 | - | |
| 2322 | - ob_start(); | |
| 2323 | - echo '<div class="mxchat-transcript">'; | |
| 2324 | - | |
| 2325 | - // Iterate through sessions from newest to oldest | |
| 2326 | - foreach ($session_ids as $session_id) { | |
| 2327 | - // Get the email associated with this session (if available) | |
| 2328 | - $email = $wpdb->get_var( | |
| 2329 | - $wpdb->prepare( | |
| 2330 | - "SELECT user_email | |
| 2331 | - FROM {$table_name} | |
| 2332 | - WHERE session_id = %s AND user_email != '' | |
| 2333 | - ORDER BY timestamp ASC | |
| 2334 | - LIMIT 1", | |
| 2335 | - $session_id | |
| 2336 | - ) | |
| 2337 | - ); | |
| 2338 | - | |
| 2339 | - // Debug: Check email retrieval | |
| 2340 | - if (empty($email)) { | |
| 2341 | - //error_log("No email found for session {$session_id}"); | |
| 2342 | - } else { | |
| 2343 | - //error_log("Email for session {$session_id}: " . $email); | |
| 2344 | - } | |
| 2345 | - | |
| 2346 | - // Get messages for this session ordered by timestamp | |
| 2347 | - $messages = $wpdb->get_results( | |
| 2348 | - $wpdb->prepare( | |
| 2349 | - "SELECT * FROM {$table_name} | |
| 2350 | - WHERE session_id = %s | |
| 2351 | - ORDER BY timestamp ASC", | |
| 2352 | - $session_id | |
| 2353 | - ) | |
| 2354 | - ); | |
| 2355 | - | |
| 2356 | - // Start session block | |
| 2357 | - echo '<div class="mxchat-session">'; | |
| 2358 | - echo '<div class="mxchat-session-header">'; | |
| 2359 | - // Wrap checkbox and session ID in one block | |
| 2360 | - echo '<div class="mxchat-session-id">'; | |
| 2361 | - echo '<input type="checkbox" name="delete_session_ids[]" value="' . esc_attr($session_id) . '"> '; | |
| 2362 | - echo '<strong>' . esc_html__('Session ID:', 'mxchat') . '</strong> ' . esc_html($session_id); | |
| 2363 | - echo '</div>'; | |
| 2364 | - | |
| 2365 | - // Place email directly below the session ID block | |
| 2366 | - if (!empty($email)) { | |
| 2367 | - echo '<div class="mxchat-session-email">'; | |
| 2368 | - echo '<strong>' . esc_html__('Email:', 'mxchat') . '</strong> ' . esc_html($email); | |
| 2369 | - echo '</div>'; | |
| 2370 | - } | |
| 2371 | - echo '</div>'; | |
| 2372 | - | |
| 2373 | - echo '<div class="mxchat-messages">'; | |
| 2374 | - | |
| 2375 | - // Display messages for this session | |
| 2376 | - foreach ($messages as $transcript) { | |
| 2377 | - $formatted_timestamp = date_i18n('F j, Y g:i a', strtotime($transcript->timestamp)); | |
| 2378 | - | |
| 2379 | - // Determine message styling | |
| 2380 | - switch ($transcript->role) { | |
| 2381 | - case 'assistant': | |
| 2382 | - case 'bot': | |
| 2383 | - $message_class = 'bot-message'; | |
| 2384 | - $display_role = esc_html__('Chatbot', 'mxchat'); | |
| 2385 | - break; | |
| 2386 | - case 'user': | |
| 2387 | - $message_class = 'user-message'; | |
| 2388 | - $display_role = !empty($transcript->user_identifier) | |
| 2389 | - ? sanitize_text_field($transcript->user_identifier) | |
| 2390 | - : esc_html__('User', 'mxchat'); | |
| 2391 | - break; | |
| 2392 | - case 'agent': | |
| 2393 | - $message_class = 'agent-message'; | |
| 2394 | - $display_role = esc_html__('Agent', 'mxchat'); | |
| 2395 | - break; | |
| 2396 | - default: | |
| 2397 | - $message_class = 'unknown-message'; | |
| 2398 | - $display_role = esc_html__('Unknown', 'mxchat'); | |
| 2399 | - } | |
| 2400 | - | |
| 2401 | - // Process message content | |
| 2402 | - $message_content = wp_kses( | |
| 2403 | - stripslashes($transcript->message), | |
| 2404 | - [ | |
| 2405 | - 'b' => [], 'strong' => [], 'i' => [], 'em' => [], 'u' => [], | |
| 2406 | - 'br' => [], 'p' => [], 'ul' => [], 'ol' => [], 'li' => [], | |
| 2407 | - 'a' => ['href' => [], 'title' => []] | |
| 2408 | - ] | |
| 2409 | - ); | |
| 2410 | - $message_content = nl2br($message_content); | |
| 2411 | - | |
| 2412 | - // Render message | |
| 2413 | - echo '<div class="mxchat-message ' . esc_attr($message_class) . '">'; | |
| 2414 | - echo '<div class="mxchat-message-header">' . esc_html($display_role) . '</div>'; | |
| 2415 | - echo '<div class="mxchat-message-content">' . $message_content . '</div>'; | |
| 2416 | - echo '<div class="mxchat-timestamp">' . esc_html($formatted_timestamp) . '</div>'; | |
| 2417 | - echo '</div>'; | |
| 2418 | - } | |
| 2419 | - | |
| 2420 | - // Close session block | |
| 2421 | - echo '</div></div>'; | |
| 2422 | - } | |
| 2423 | - | |
| 2424 | - echo '</div>'; | |
| 2425 | - $output = ob_get_clean(); | |
| 2426 | - echo $output; | |
| 2427 | - wp_die(); | |
| 2428 | -} | |
| 2429 | - | |
| 2430 | - | |
| 2431 | 2743 | public function mxchat_create_activation_page() { |
| 2432 | 2744 | $license_status = get_option('mxchat_license_status', 'inactive'); |
| 2433 | 2745 | $license_error = get_option('mxchat_license_error', ''); |
| 2434 | 2746 | ?> |
| @@ -3037,22 +3349,12 @@ | ||
| 3037 | 3349 | |
| 3038 | 3350 | private function mxchat_get_available_callbacks($grouped = false) { |
| 3039 | 3351 | $callbacks = [ |
| 3040 | 3352 | 'mxchat_handle_email_capture' => [ |
| 3041 | - 'label' => __('Email Capture', 'mxchat'), | |
| 3353 | + 'label' => __('Loops Email Capture', 'mxchat'), | |
| 3042 | 3354 | 'pro_only' => false, |
| 3043 | 3355 | 'group' => __('Customer Engagement', 'mxchat'), |
| 3044 | 3356 | ], |
| 3045 | - 'mxchat_handle_product_inquiry' => [ | |
| 3046 | - 'label' => __('Show Product Card', 'mxchat'), | |
| 3047 | - 'pro_only' => true, | |
| 3048 | - 'group' => __('WooCommerce Features', 'mxchat'), | |
| 3049 | - ], | |
| 3050 | - 'mxchat_handle_order_history' => [ | |
| 3051 | - 'label' => __('Order History', 'mxchat'), | |
| 3052 | - 'pro_only' => true, | |
| 3053 | - 'group' => __('WooCommerce Features', 'mxchat'), | |
| 3054 | - ], | |
| 3055 | 3357 | 'mxchat_generate_image' => [ |
| 3056 | 3358 | 'label' => __('Generate Image', 'mxchat'), |
| 3057 | 3359 | 'pro_only' => true, |
| 3058 | 3360 | 'group' => __('Other Features', 'mxchat'), |
| @@ -3066,28 +3368,13 @@ | ||
| 3066 | 3368 | 'label' => __('Brave Image Search', 'mxchat'), |
| 3067 | 3369 | 'pro_only' => false, |
| 3068 | 3370 | 'group' => __('Search Features', 'mxchat'), |
| 3069 | 3371 | ], |
| 3070 | - 'mxchat_handle_add_to_cart_intent' => [ | |
| 3071 | - 'label' => __('Add to Cart', 'mxchat'), | |
| 3072 | - 'pro_only' => true, | |
| 3073 | - 'group' => __('WooCommerce Features', 'mxchat'), | |
| 3074 | - ], | |
| 3075 | - 'mxchat_handle_checkout_intent' => [ | |
| 3076 | - 'label' => __('Proceed to Checkout', 'mxchat'), | |
| 3077 | - 'pro_only' => true, | |
| 3078 | - 'group' => __('WooCommerce Features', 'mxchat'), | |
| 3079 | - ], | |
| 3080 | 3372 | 'mxchat_handle_pdf_discussion' => [ |
| 3081 | 3373 | 'label' => __('Chat with PDF', 'mxchat'), |
| 3082 | 3374 | 'pro_only' => true, |
| 3083 | 3375 | 'group' => __('Other Features', 'mxchat'), |
| 3084 | 3376 | ], |
| 3085 | - 'mxchat_handle_product_recommendations' => [ | |
| 3086 | - 'label' => __('Product Recommendations', 'mxchat'), | |
| 3087 | - 'pro_only' => true, | |
| 3088 | - 'group' => __('WooCommerce Features', 'mxchat'), | |
| 3089 | - ], | |
| 3090 | 3377 | 'mxchat_live_agent_handover' => [ |
| 3091 | 3378 | 'label' => __('Live Agent', 'mxchat'), |
| 3092 | 3379 | 'pro_only' => true, |
| 3093 | 3380 | 'group' => __('Customer Engagement', 'mxchat'), |
| @@ -3098,8 +3385,11 @@ | ||
| 3098 | 3385 | 'group' => __('Customer Engagement', 'mxchat'), |
| 3099 | 3386 | ], |
| 3100 | 3387 | ]; |
| 3101 | 3388 | |
| 3389 | + // Allow other plugins to add their callbacks | |
| 3390 | + $callbacks = apply_filters('mxchat_available_callbacks', $callbacks); | |
| 3391 | + | |
| 3102 | 3392 | // Return grouped structure if requested |
| 3103 | 3393 | if ($grouped) { |
| 3104 | 3394 | $grouped_callbacks = []; |
| 3105 | 3395 | foreach ($callbacks as $key => $data) { |
| @@ -3110,14 +3400,12 @@ | ||
| 3110 | 3400 | ]; |
| 3111 | 3401 | } |
| 3112 | 3402 | return $grouped_callbacks; |
| 3113 | 3403 | } |
| 3114 | - | |
| 3115 | 3404 | return $callbacks; |
| 3116 | 3405 | } |
| 3117 | 3406 | |
| 3118 | 3407 | |
| 3119 | - | |
| 3120 | 3408 | private function mxchat_average_vectors($vectors) { |
| 3121 | 3409 | $vector_length = count($vectors[0]); |
| 3122 | 3410 | $sum_vector = array_fill(0, $vector_length, 0); |
| 3123 | 3411 | |
| @@ -3234,10 +3522,36 @@ | ||
| 3234 | 3522 | array($this, 'deepseek_api_key_callback'), |
| 3235 | 3523 | 'mxchat-chatbot', |
| 3236 | 3524 | 'mxchat_chatbot_section' |
| 3237 | 3525 | ); |
| 3526 | + | |
| 3527 | + add_settings_field( | |
| 3528 | + 'voyage_api_key', | |
| 3529 | + esc_html__('Voyage AI API Key', 'mxchat'), | |
| 3530 | + array($this, 'voyage_api_key_callback'), | |
| 3531 | + 'mxchat-chatbot', | |
| 3532 | + 'mxchat_chatbot_section' | |
| 3533 | + ); | |
| 3534 | + | |
| 3238 | 3535 | |
| 3239 | 3536 | add_settings_field( |
| 3537 | + 'model', | |
| 3538 | + esc_html__('Chat Model', 'mxchat'), | |
| 3539 | + array($this, 'mxchat_model_callback'), | |
| 3540 | + 'mxchat-chatbot', | |
| 3541 | + 'mxchat_chatbot_section' | |
| 3542 | + ); | |
| 3543 | + | |
| 3544 | + // Add the settings field | |
| 3545 | + add_settings_field( | |
| 3546 | + 'embedding_model', | |
| 3547 | + esc_html__('Embedding Model', 'mxchat'), | |
| 3548 | + array($this, 'embedding_model_callback'), | |
| 3549 | + 'mxchat-chatbot', | |
| 3550 | + 'mxchat_chatbot_section' | |
| 3551 | + ); | |
| 3552 | + | |
| 3553 | + add_settings_field( | |
| 3240 | 3554 | 'system_prompt_instructions', |
| 3241 | 3555 | esc_html__('AI Instructions (Behavior)', 'mxchat'), |
| 3242 | 3556 | array($this, 'system_prompt_instructions_callback'), |
| 3243 | 3557 | 'mxchat-chatbot', |
| @@ -3243,15 +3557,8 @@ | ||
| 3243 | 3557 | 'mxchat-chatbot', |
| 3244 | 3558 | 'mxchat_chatbot_section' |
| 3245 | 3559 | ); |
| 3246 | 3560 | |
| 3247 | - add_settings_field( | |
| 3248 | - 'model', | |
| 3249 | - esc_html__('Model', 'mxchat'), | |
| 3250 | - array($this, 'mxchat_model_callback'), | |
| 3251 | - 'mxchat-chatbot', | |
| 3252 | - 'mxchat_chatbot_section' | |
| 3253 | - ); | |
| 3254 | 3561 | |
| 3255 | 3562 | add_settings_field( |
| 3256 | 3563 | 'top_bar_title', |
| 3257 | 3564 | esc_html__('Top Bar Title', 'mxchat'), |
| @@ -3365,9 +3672,9 @@ | ||
| 3365 | 3672 | ); |
| 3366 | 3673 | |
| 3367 | 3674 | add_settings_field( |
| 3368 | 3675 | 'popular_question_1', |
| 3369 | - esc_html__('Popular Question 1', 'mxchat'), | |
| 3676 | + esc_html__('Quick Question 1', 'mxchat'), | |
| 3370 | 3677 | array($this, 'mxchat_popular_question_1_callback'), |
| 3371 | 3678 | 'mxchat-chatbot', |
| 3372 | 3679 | 'mxchat_chatbot_section' |
| 3373 | 3680 | ); |
| @@ -3373,9 +3680,9 @@ | ||
| 3373 | 3680 | ); |
| 3374 | 3681 | |
| 3375 | 3682 | add_settings_field( |
| 3376 | 3683 | 'popular_question_2', |
| 3377 | - esc_html__('Popular Question 2', 'mxchat'), | |
| 3684 | + esc_html__('Quick Question 2', 'mxchat'), | |
| 3378 | 3685 | array($this, 'mxchat_popular_question_2_callback'), |
| 3379 | 3686 | 'mxchat-chatbot', |
| 3380 | 3687 | 'mxchat_chatbot_section' |
| 3381 | 3688 | ); |
| @@ -3381,9 +3688,9 @@ | ||
| 3381 | 3688 | ); |
| 3382 | 3689 | |
| 3383 | 3690 | add_settings_field( |
| 3384 | 3691 | 'popular_question_3', |
| 3385 | - esc_html__('Popular Question 3', 'mxchat'), | |
| 3692 | + esc_html__('Quick Question 3', 'mxchat'), | |
| 3386 | 3693 | array($this, 'mxchat_popular_question_3_callback'), |
| 3387 | 3694 | 'mxchat-chatbot', |
| 3388 | 3695 | 'mxchat_chatbot_section' |
| 3389 | 3696 | ); |
| @@ -3389,21 +3696,14 @@ | ||
| 3389 | 3696 | ); |
| 3390 | 3697 | |
| 3391 | 3698 | add_settings_field( |
| 3392 | 3699 | 'additional_popular_questions', |
| 3393 | - esc_html__('Additional Popular Questions', 'mxchat'), | |
| 3700 | + esc_html__('Additional Quick Questions', 'mxchat'), | |
| 3394 | 3701 | array($this, 'mxchat_additional_popular_questions_callback'), |
| 3395 | 3702 | 'mxchat-chatbot', |
| 3396 | 3703 | 'mxchat_chatbot_section' |
| 3397 | 3704 | ); |
| 3398 | 3705 | |
| 3399 | - // WooCommerce Settings Section | |
| 3400 | - add_settings_section( | |
| 3401 | - 'mxchat_woocommerce_section', | |
| 3402 | - esc_html__('WooCommerce Settings', 'mxchat'), | |
| 3403 | - null, | |
| 3404 | - 'mxchat-embed' | |
| 3405 | - ); | |
| 3406 | 3706 | |
| 3407 | 3707 | // Loops Settings Section |
| 3408 | 3708 | add_settings_section( |
| 3409 | 3709 | 'mxchat_loops_section', |
| @@ -3411,33 +3711,8 @@ | ||
| 3411 | 3711 | null, |
| 3412 | 3712 | 'mxchat-embed' |
| 3413 | 3713 | ); |
| 3414 | 3714 | |
| 3415 | - // WooCommerce Settings Fields | |
| 3416 | - add_settings_field( | |
| 3417 | - 'enable_woocommerce_integration', | |
| 3418 | - esc_html__('Automatically Embed Products', 'mxchat'), | |
| 3419 | - array($this, 'mxchat_enable_woocommerce_integration_callback'), | |
| 3420 | - 'mxchat-embed', | |
| 3421 | - 'mxchat_woocommerce_section' | |
| 3422 | - ); | |
| 3423 | - | |
| 3424 | - add_settings_field( | |
| 3425 | - 'woocommerce_consumer_key', | |
| 3426 | - esc_html__('WooCommerce Consumer Key', 'mxchat'), | |
| 3427 | - array($this, 'mxchat_woocommerce_consumer_key_callback'), | |
| 3428 | - 'mxchat-embed', | |
| 3429 | - 'mxchat_woocommerce_section' | |
| 3430 | - ); | |
| 3431 | - | |
| 3432 | - add_settings_field( | |
| 3433 | - 'woocommerce_consumer_secret', | |
| 3434 | - esc_html__('WooCommerce Consumer Secret', 'mxchat'), | |
| 3435 | - array($this, 'mxchat_woocommerce_consumer_secret_callback'), | |
| 3436 | - 'mxchat-embed', | |
| 3437 | - 'mxchat_woocommerce_section' | |
| 3438 | - ); | |
| 3439 | - | |
| 3440 | 3715 | // Loops Settings Fields |
| 3441 | 3716 | add_settings_field( |
| 3442 | 3717 | 'loops_api_key', |
| 3443 | 3718 | esc_html__('Loops API Key', 'mxchat'), |
| @@ -3540,8 +3815,26 @@ | ||
| 3540 | 3815 | array($this, 'mxchat_chat_toolbar_toggle_callback'), |
| 3541 | 3816 | 'mxchat-embed', |
| 3542 | 3817 | 'mxchat_pdf_intent_section' |
| 3543 | 3818 | ); |
| 3819 | + | |
| 3820 | + // PDF Upload Button Toggle | |
| 3821 | + add_settings_field( | |
| 3822 | + 'show_pdf_upload_button', | |
| 3823 | + __('Show PDF Upload Button', 'mxchat'), | |
| 3824 | + array($this, 'mxchat_show_pdf_upload_button_callback'), | |
| 3825 | + 'mxchat-embed', | |
| 3826 | + 'mxchat_pdf_intent_section' | |
| 3827 | + ); | |
| 3828 | + | |
| 3829 | + // Word Upload Button Toggle | |
| 3830 | + add_settings_field( | |
| 3831 | + 'show_word_upload_button', | |
| 3832 | + __('Show Word Upload Button', 'mxchat'), | |
| 3833 | + array($this, 'mxchat_show_word_upload_button_callback'), | |
| 3834 | + 'mxchat-embed', | |
| 3835 | + 'mxchat_pdf_intent_section' | |
| 3836 | + ); | |
| 3544 | 3837 | |
| 3545 | 3838 | add_settings_field( |
| 3546 | 3839 | 'pdf_intent_trigger_text', |
| 3547 | 3840 | __('Intent Trigger Text', 'mxchat'), |
| @@ -3638,9 +3931,9 @@ | ||
| 3638 | 3931 | |
| 3639 | 3932 | // General Settings Section |
| 3640 | 3933 | add_settings_section( |
| 3641 | 3934 | 'mxchat_general_section', |
| 3642 | - esc_html__('Frequently Asked Questions (FAQ)', 'mxchat'), | |
| 3935 | + esc_html__('YouTube Tutorials', 'mxchat'), | |
| 3643 | 3936 | null, |
| 3644 | 3937 | 'mxchat-general' |
| 3645 | 3938 | ); |
| 3646 | 3939 | } |
| @@ -3883,52 +4176,8 @@ | ||
| 3883 | 4176 | echo '</div>'; |
| 3884 | 4177 | } |
| 3885 | 4178 | |
| 3886 | 4179 | |
| 3887 | -public function mxchat_enable_woocommerce_integration_callback() { | |
| 3888 | - // Load from mxchat_options array | |
| 3889 | - $options = get_option('mxchat_options', []); | |
| 3890 | - | |
| 3891 | - // Get WooCommerce integration status with backwards compatibility | |
| 3892 | - $woo_integration = isset($options['enable_woocommerce_integration']) | |
| 3893 | - ? $options['enable_woocommerce_integration'] | |
| 3894 | - : ''; | |
| 3895 | - | |
| 3896 | - // Support both old ('1') and new ('on') values | |
| 3897 | - $checked = ($woo_integration === 'on' || $woo_integration === '1') ? 'checked' : ''; | |
| 3898 | - | |
| 3899 | - // Check if the feature is activated (paid feature) | |
| 3900 | - $disabled = $this->is_activated ? '' : 'disabled'; | |
| 3901 | - $class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; | |
| 3902 | - | |
| 3903 | - echo '<div class="' . esc_attr($class) . '">'; | |
| 3904 | - | |
| 3905 | - echo '<label class="toggle-switch">'; | |
| 3906 | - echo sprintf( | |
| 3907 | - '<input type="checkbox" id="enable_woocommerce_integration" name="enable_woocommerce_integration" value="on" %s %s />', | |
| 3908 | - esc_attr($checked), | |
| 3909 | - esc_attr($disabled) | |
| 3910 | - ); | |
| 3911 | - echo '<span class="slider"></span>'; | |
| 3912 | - echo '</label>'; | |
| 3913 | - | |
| 3914 | - echo '<p class="description">' . esc_html__('Automatically syncs new product additions, updates, and removals to the knowledge base. For existing products, submit your product sitemap in the Knowledge Base section to add them initially.', 'mxchat') . '</p>'; | |
| 3915 | - | |
| 3916 | - // Pro feature overlay for non-activated users | |
| 3917 | - if (!$this->is_activated) { | |
| 3918 | - echo '<div class="pro-feature-overlay">'; | |
| 3919 | - echo '<a href="https://mxchat.ai/" target="_blank">'; | |
| 3920 | - echo '<img src="' . esc_url(plugin_dir_url(__FILE__) . '../images/pro-only-dark.png') . '" alt="' . esc_attr__('Pro Only', 'mxchat') . '" />'; | |
| 3921 | - echo '</a>'; | |
| 3922 | - echo '</div>'; | |
| 3923 | - } | |
| 3924 | - | |
| 3925 | - echo '</div>'; | |
| 3926 | -} | |
| 3927 | - | |
| 3928 | - | |
| 3929 | - | |
| 3930 | - | |
| 3931 | 4180 | private function mxchat_add_option_field($id, $title, $callback = '') { |
| 3932 | 4181 | add_settings_field( |
| 3933 | 4182 | $id, |
| 3934 | 4183 | __($title, 'mxchat'), |
| @@ -3945,9 +4194,8 @@ | ||
| 3945 | 4194 | |
| 3946 | 4195 | // Notice we changed the name to "api_key" (no array notation). |
| 3947 | 4196 | echo '<input type="password" id="api_key" name="api_key" value="' . $apiKey . '" class="regular-text" />'; |
| 3948 | 4197 | echo '<button type="button" id="toggleApiKeyVisibility">' . esc_html__('Show', 'mxchat') . '</button>'; |
| 3949 | - echo '<p class="description">' . esc_html__('The OpenAI API key is required even when using other models as it is used for vector embedding functionality. You must add credits to your OpenAI billing account before use.', 'mxchat') . '</p>'; | |
| 3950 | 4198 | } |
| 3951 | 4199 | public function xai_api_key_callback() { |
| 3952 | 4200 | // Check if the feature is activated (paid feature) |
| 3953 | 4201 | $disabled = $this->is_activated ? '' : 'disabled'; // Disable input if not activated |
| @@ -4007,79 +4255,11 @@ | ||
| 4007 | 4255 | echo '<button type="button" id="toggleDeepSeekApiKeyVisibility">' . esc_html__('Show', 'mxchat') . '</button>'; |
| 4008 | 4256 | } |
| 4009 | 4257 | |
| 4010 | 4258 | |
| 4011 | -public function mxchat_woocommerce_consumer_key_callback() { | |
| 4012 | - // Load the entire 'mxchat_options' array | |
| 4013 | - $all_options = get_option('mxchat_options', []); | |
| 4014 | 4259 | |
| 4015 | - // Retrieve the WooCommerce consumer key or set a default | |
| 4016 | - $consumer_key = isset($all_options['woocommerce_consumer_key']) ? $all_options['woocommerce_consumer_key'] : ''; | |
| 4017 | 4260 | |
| 4018 | - // Check if the feature is activated (paid feature) | |
| 4019 | - $disabled = $this->is_activated ? '' : 'disabled'; | |
| 4020 | - $class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; | |
| 4021 | 4261 | |
| 4022 | - echo '<div class="' . esc_attr($class) . '">'; | |
| 4023 | - | |
| 4024 | - // Render the input field | |
| 4025 | - printf( | |
| 4026 | - '<input type="text" id="woocommerce_consumer_key" name="woocommerce_consumer_key" value="%s" class="regular-text" %s />', | |
| 4027 | - esc_attr($consumer_key), | |
| 4028 | - esc_attr($disabled) | |
| 4029 | - ); | |
| 4030 | - | |
| 4031 | - // Description for the input field | |
| 4032 | - echo '<p class="description">' . esc_html__('Enter your WooCommerce consumer key for integration.', 'mxchat') . '</p>'; | |
| 4033 | - | |
| 4034 | - // Pro feature overlay for non-activated users | |
| 4035 | - if (!$this->is_activated) { | |
| 4036 | - echo '<div class="pro-feature-overlay">'; | |
| 4037 | - echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="' . esc_attr__('Pro Only', 'mxchat') . '" /></a>'; | |
| 4038 | - echo '</div>'; | |
| 4039 | - } | |
| 4040 | - | |
| 4041 | - echo '</div>'; | |
| 4042 | -} | |
| 4043 | - | |
| 4044 | -public function mxchat_woocommerce_consumer_secret_callback() { | |
| 4045 | - // Get value with fallback | |
| 4046 | - $consumer_secret = isset($this->options['woocommerce_consumer_secret']) | |
| 4047 | - ? esc_attr($this->options['woocommerce_consumer_secret']) | |
| 4048 | - : ''; | |
| 4049 | - | |
| 4050 | - // Check if the feature is activated (paid feature) | |
| 4051 | - $disabled = $this->is_activated ? '' : 'disabled'; | |
| 4052 | - $class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; | |
| 4053 | - | |
| 4054 | - echo '<div class="' . esc_attr($class) . '">'; | |
| 4055 | - | |
| 4056 | - // Output the password input | |
| 4057 | - echo sprintf( | |
| 4058 | - '<input type="password" | |
| 4059 | - id="woocommerce_consumer_secret" | |
| 4060 | - name="woocommerce_consumer_secret" | |
| 4061 | - value="%s" | |
| 4062 | - class="regular-text" | |
| 4063 | - %s />', | |
| 4064 | - $consumer_secret, | |
| 4065 | - esc_attr($disabled) | |
| 4066 | - ); | |
| 4067 | - | |
| 4068 | - // Add show/hide button | |
| 4069 | - echo '<button type="button" id="toggleWooCommerceSecretVisibility">' . esc_html__('Show', 'mxchat') . '</button>'; | |
| 4070 | - | |
| 4071 | - // Pro feature overlay | |
| 4072 | - if (!$this->is_activated) { | |
| 4073 | - echo '<div class="pro-feature-overlay">'; | |
| 4074 | - echo '<a href="https://mxchat.ai/" target="_blank">'; | |
| 4075 | - echo '<img src="' . esc_url(plugin_dir_url(__FILE__) . '../images/pro-only-dark.png') . '" alt="' . esc_attr__('Pro Only', 'mxchat') . '" />'; | |
| 4076 | - echo '</a>'; | |
| 4077 | - echo '</div>'; | |
| 4078 | - } | |
| 4079 | - | |
| 4080 | - echo '</div>'; | |
| 4081 | -} | |
| 4082 | 4262 | public function mxchat_loops_api_key_callback() { |
| 4083 | 4263 | // Support both old and new format |
| 4084 | 4264 | $loops_api_key = isset($this->options['loops_api_key']) ? esc_attr($this->options['loops_api_key']) : ''; |
| 4085 | 4265 | |
| @@ -4089,9 +4269,9 @@ | ||
| 4089 | 4269 | $loops_api_key |
| 4090 | 4270 | ); |
| 4091 | 4271 | echo '<button type="button" id="toggleLoopsApiKeyVisibility">' . esc_html__('Show', 'mxchat') . '</button>'; |
| 4092 | 4272 | echo '</div>'; |
| 4093 | - echo '<p class="description">' . esc_html__('Enter your Loops API Key here. (See FAQ for details)', 'mxchat') . '</p>'; | |
| 4273 | + echo '<p class="description">' . esc_html__('Enter your Loops API Key here. Once entered, refreshed page to load list (See FAQ for details)', 'mxchat') . '</p>'; | |
| 4094 | 4274 | } |
| 4095 | 4275 | |
| 4096 | 4276 | public function mxchat_loops_mailing_list_callback() { |
| 4097 | 4277 | // Add error handling and type checking |
| @@ -4200,9 +4380,10 @@ | ||
| 4200 | 4380 | esc_html__('DeepSeek Models', 'mxchat') => array( |
| 4201 | 4381 | 'deepseek-chat' => esc_html__('DeepSeek-V3', 'mxchat'), |
| 4202 | 4382 | ), |
| 4203 | 4383 | esc_html__('Claude Models', 'mxchat') => array( |
| 4204 | - 'claude-3-5-sonnet-20241022' => esc_html__('Claude 3.5 Sonnet (Most Intelligent)', 'mxchat'), | |
| 4384 | + 'claude-3-7-sonnet-20250219' => esc_html__('Claude 3.7 Sonnet (Most Intelligent)', 'mxchat'), | |
| 4385 | + 'claude-3-5-sonnet-20241022' => esc_html__('Claude 3.5 Sonnet (Intelligent)', 'mxchat'), | |
| 4205 | 4386 | 'claude-3-opus-20240229' => esc_html__('Claude 3 Opus (Highly Complex Tasks)', 'mxchat'), |
| 4206 | 4387 | 'claude-3-sonnet-20240229' => esc_html__('Claude 3 Sonnet (Balanced)', 'mxchat'), |
| 4207 | 4388 | 'claude-3-haiku-20240307' => esc_html__('Claude 3 Haiku (Fastest)', 'mxchat') |
| 4208 | 4389 | ), |
| @@ -4240,13 +4421,46 @@ | ||
| 4240 | 4421 | // Close the select dropdown |
| 4241 | 4422 | echo '</select>'; |
| 4242 | 4423 | |
| 4243 | 4424 | // Add a description below the dropdown |
| 4244 | - echo '<p class="description">' . esc_html__('Select the AI model to use for your chatbot. Pro-only models are marked accordingly.', 'mxchat') . '</p>'; | |
| 4425 | + echo '<p class="description">' . esc_html__('Select the AI model your chatbot will use for chatting. Pro-only models are marked accordingly.', 'mxchat') . '</p>'; | |
| 4245 | 4426 | } |
| 4246 | 4427 | |
| 4428 | +public function voyage_api_key_callback() { | |
| 4429 | + $apiKey = isset($this->options['voyage_api_key']) ? esc_attr($this->options['voyage_api_key']) : ''; | |
| 4430 | + echo '<input type="password" id="voyage_api_key" name="voyage_api_key" value="' . $apiKey . '" class="regular-text" />'; | |
| 4431 | + echo '<button type="button" id="toggleVoyageAPIKeyVisibility">' . esc_html__('Show', 'mxchat') . '</button>'; | |
| 4432 | +} | |
| 4247 | 4433 | |
| 4434 | +// Callback function for embedding model selection | |
| 4435 | +public function embedding_model_callback() { | |
| 4436 | + $models = array( | |
| 4437 | + esc_html__('OpenAI Embeddings', 'mxchat') => array( | |
| 4438 | + 'text-embedding-3-small' => esc_html__('TE3 Small (1536, Efficient)', 'mxchat'), | |
| 4439 | + 'text-embedding-ada-002' => esc_html__('Ada 2 (1536, Original)', 'mxchat'), | |
| 4440 | + 'text-embedding-3-large' => esc_html__('TE3 Large (3072, Powerful)', 'mxchat'), | |
| 4441 | + ), | |
| 4442 | + esc_html__('Voyage AI Embeddings', 'mxchat') => array( | |
| 4443 | + 'voyage-3-large' => esc_html__('Voyage-3 Large (2048, Most Capable)', 'mxchat'), | |
| 4444 | + ) | |
| 4445 | + ); | |
| 4248 | 4446 | |
| 4447 | + $selected_model = isset($this->options['embedding_model']) ? esc_attr($this->options['embedding_model']) : 'text-embedding-ada-002'; | |
| 4448 | + | |
| 4449 | + echo '<select id="embedding_model" name="embedding_model">'; | |
| 4450 | + foreach ($models as $group_label => $group_models) { | |
| 4451 | + echo '<optgroup label="' . esc_attr($group_label) . '">'; | |
| 4452 | + foreach ($group_models as $model_value => $model_label) { | |
| 4453 | + echo '<option value="' . esc_attr($model_value) . '" ' . selected($selected_model, $model_value, false) . '>' . esc_html($model_label) . '</option>'; | |
| 4454 | + } | |
| 4455 | + echo '</optgroup>'; | |
| 4456 | + } | |
| 4457 | + echo '</select>'; | |
| 4458 | +echo '<p class="description"><span class="red-warning">IMPORTANT:</span> Select the model for vector embeddings. Changing models is not recommended; if you do, you must delete all existing knowledge & intent data and reconfigure them.</p>'; | |
| 4459 | + | |
| 4460 | +} | |
| 4461 | + | |
| 4462 | + | |
| 4249 | 4463 | public function mxchat_top_bar_title_callback() { |
| 4250 | 4464 | // Retrieve the current value of the top bar title from saved options |
| 4251 | 4465 | $top_bar_title = isset($this->options['top_bar_title']) ? esc_attr($this->options['top_bar_title']) : ''; |
| 4252 | 4466 | |
| @@ -4909,13 +5123,13 @@ | ||
| 4909 | 5123 | // Render the input field |
| 4910 | 5124 | printf( |
| 4911 | 5125 | '<input type="text" id="popular_question_1" name="popular_question_1" value="%s" placeholder="%s" class="regular-text" />', |
| 4912 | 5126 | esc_attr($popular_question_1), |
| 4913 | - esc_attr__('Enter Popular Question 1', 'mxchat') | |
| 5127 | + esc_attr__('Enter Quick Question 1', 'mxchat') | |
| 4914 | 5128 | ); |
| 4915 | 5129 | |
| 4916 | 5130 | // Add a description for the field |
| 4917 | - echo '<p class="description">' . esc_html__('This will be the first popular question in the chatbot.', 'mxchat') . '</p>'; | |
| 5131 | + echo '<p class="description">' . esc_html__('This will be the first Quick Question in the chatbot, displayed above the input field.', 'mxchat') . '</p>'; | |
| 4918 | 5132 | } |
| 4919 | 5133 | |
| 4920 | 5134 | |
| 4921 | 5135 | public function mxchat_popular_question_2_callback() { |
| @@ -4928,13 +5142,13 @@ | ||
| 4928 | 5142 | // Render the input field |
| 4929 | 5143 | printf( |
| 4930 | 5144 | '<input type="text" id="popular_question_2" name="popular_question_2" value="%s" placeholder="%s" class="regular-text" />', |
| 4931 | 5145 | esc_attr($popular_question_2), |
| 4932 | - esc_attr__('Enter Popular Question 2', 'mxchat') | |
| 5146 | + esc_attr__('Enter Quick Question 2', 'mxchat') | |
| 4933 | 5147 | ); |
| 4934 | 5148 | |
| 4935 | 5149 | // Add a description for the field |
| 4936 | - echo '<p class="description">' . esc_html__('This will be the second popular question in the chatbot.', 'mxchat') . '</p>'; | |
| 5150 | + echo '<p class="description">' . esc_html__('This will be the second Quick Question in the chatbot.', 'mxchat') . '</p>'; | |
| 4937 | 5151 | } |
| 4938 | 5152 | |
| 4939 | 5153 | |
| 4940 | 5154 | public function mxchat_popular_question_3_callback() { |
| @@ -4947,13 +5161,13 @@ | ||
| 4947 | 5161 | // Render the input field |
| 4948 | 5162 | printf( |
| 4949 | 5163 | '<input type="text" id="popular_question_3" name="popular_question_3" value="%s" placeholder="%s" class="regular-text" />', |
| 4950 | 5164 | esc_attr($popular_question_3), |
| 4951 | - esc_attr(__('Enter Popular Question 3', 'mxchat')) | |
| 5165 | + esc_attr(__('Enter Quick Question 3', 'mxchat')) | |
| 4952 | 5166 | ); |
| 4953 | 5167 | |
| 4954 | 5168 | // Add a description for the field |
| 4955 | - echo '<p class="description">' . esc_html__('This will be the third popular question in the chatbot.', 'mxchat') . '</p>'; | |
| 5169 | + echo '<p class="description">' . esc_html__('This will be the third Quick Question in the chatbot.', 'mxchat') . '</p>'; | |
| 4956 | 5170 | } |
| 4957 | 5171 | |
| 4958 | 5172 | public function mxchat_additional_popular_questions_callback() { |
| 4959 | 5173 | $options = get_option('mxchat_options', []); |
| @@ -4974,9 +5188,9 @@ | ||
| 4974 | 5188 | <button type="button" class="button mxchat-remove-question" |
| 4975 | 5189 | aria-label="%s">%s</button> |
| 4976 | 5190 | </div>', |
| 4977 | 5191 | esc_attr($question), |
| 4978 | - esc_attr(sprintf(__('Enter Additional Popular Question %d', 'mxchat'), $index + 4)), | |
| 5192 | + esc_attr(sprintf(__('Enter Additional Quick Question %d', 'mxchat'), $index + 4)), | |
| 4979 | 5193 | $index, |
| 4980 | 5194 | esc_attr(__('Remove question', 'mxchat')), |
| 4981 | 5195 | esc_html__('Remove', 'mxchat') |
| 4982 | 5196 | ); |
| @@ -4991,9 +5205,9 @@ | ||
| 4991 | 5205 | data-question-index="0" /> |
| 4992 | 5206 | <button type="button" class="button mxchat-remove-question" |
| 4993 | 5207 | aria-label="%s">%s</button> |
| 4994 | 5208 | </div>', |
| 4995 | - esc_attr(__('Enter Additional Popular Question 4', 'mxchat')), | |
| 5209 | + esc_attr(__('Enter Additional Quick Question 4', 'mxchat')), | |
| 4996 | 5210 | esc_attr(__('Remove question', 'mxchat')), |
| 4997 | 5211 | esc_html__('Remove', 'mxchat') |
| 4998 | 5212 | ); |
| 4999 | 5213 | } |
| @@ -5002,9 +5216,9 @@ | ||
| 5002 | 5216 | '<button type="button" class="button mxchat-add-question" aria-label="%s">%s</button>', |
| 5003 | 5217 | esc_attr(__('Add question', 'mxchat')), |
| 5004 | 5218 | esc_html__('Add Question', 'mxchat') |
| 5005 | 5219 | ); |
| 5006 | - echo '<p class="description">' . esc_html__('Add as many popular questions as you need.', 'mxchat') . '</p>'; | |
| 5220 | + echo '<p class="description">' . esc_html__('Add as many Quick Questions as you need.', 'mxchat') . '</p>'; | |
| 5007 | 5221 | echo '</div>'; |
| 5008 | 5222 | } |
| 5009 | 5223 | |
| 5010 | 5224 | public function mxchat_brave_api_key_callback() { |
| @@ -5136,9 +5350,78 @@ | ||
| 5136 | 5350 | echo '</div>'; |
| 5137 | 5351 | echo '<p class="description">' . esc_html__('Enable to display the chat toolbar, adding two icons below the chatbot input field for uploading PDF and Word documents (default is hidden).', 'mxchat') . '</p>'; |
| 5138 | 5352 | } |
| 5139 | 5353 | |
| 5354 | +/** | |
| 5355 | + * Callback for PDF upload button toggle setting | |
| 5356 | + */ | |
| 5357 | +public function mxchat_show_pdf_upload_button_callback() { | |
| 5358 | + // Get toggle value with fallback | |
| 5359 | + $show_pdf_button = isset($this->options['show_pdf_upload_button']) ? $this->options['show_pdf_upload_button'] : 'on'; | |
| 5360 | + $checked = ($show_pdf_button === 'on') ? 'checked' : ''; | |
| 5361 | + // Check if the plugin is activated (paid feature) | |
| 5362 | + $disabled = $this->is_activated ? '' : 'disabled'; | |
| 5363 | + $class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; | |
| 5364 | + | |
| 5365 | + echo '<div class="' . esc_attr($class) . '">'; | |
| 5366 | + // Output the toggle switch | |
| 5367 | + echo '<label class="toggle-switch">'; | |
| 5368 | + echo sprintf( | |
| 5369 | + '<input type="checkbox" id="show_pdf_upload_button" name="show_pdf_upload_button" value="on" %s %s />', | |
| 5370 | + esc_attr($checked), | |
| 5371 | + esc_attr($disabled) | |
| 5372 | + ); | |
| 5373 | + echo '<span class="slider"></span>'; | |
| 5374 | + echo '</label>'; | |
| 5375 | + | |
| 5376 | + // Pro feature overlay if needed | |
| 5377 | + if (!$this->is_activated) { | |
| 5378 | + echo '<div class="pro-feature-overlay">'; | |
| 5379 | + echo '<a href="https://mxchat.ai/" target="_blank">'; | |
| 5380 | + echo '<img src="' . esc_url(plugin_dir_url(__FILE__) . '../images/pro-only-dark.png') . '" alt="' . esc_attr__('Pro Only', 'mxchat') . '" />'; | |
| 5381 | + echo '</a>'; | |
| 5382 | + echo '</div>'; | |
| 5383 | + } | |
| 5384 | + | |
| 5385 | + echo '</div>'; | |
| 5386 | + echo '<p class="description">' . esc_html__('Enable to show the PDF upload button in the chatbot toolbar. Disable to hide it.', 'mxchat') . '</p>'; | |
| 5387 | +} | |
| 5140 | 5388 | |
| 5389 | +/** | |
| 5390 | + * Callback for Word upload button toggle setting | |
| 5391 | + */ | |
| 5392 | +public function mxchat_show_word_upload_button_callback() { | |
| 5393 | + // Get toggle value with fallback | |
| 5394 | + $show_word_button = isset($this->options['show_word_upload_button']) ? $this->options['show_word_upload_button'] : 'on'; | |
| 5395 | + $checked = ($show_word_button === 'on') ? 'checked' : ''; | |
| 5396 | + // Check if the plugin is activated (paid feature) | |
| 5397 | + $disabled = $this->is_activated ? '' : 'disabled'; | |
| 5398 | + $class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; | |
| 5399 | + | |
| 5400 | + echo '<div class="' . esc_attr($class) . '">'; | |
| 5401 | + // Output the toggle switch | |
| 5402 | + echo '<label class="toggle-switch">'; | |
| 5403 | + echo sprintf( | |
| 5404 | + '<input type="checkbox" id="show_word_upload_button" name="show_word_upload_button" value="on" %s %s />', | |
| 5405 | + esc_attr($checked), | |
| 5406 | + esc_attr($disabled) | |
| 5407 | + ); | |
| 5408 | + echo '<span class="slider"></span>'; | |
| 5409 | + echo '</label>'; | |
| 5410 | + | |
| 5411 | + // Pro feature overlay if needed | |
| 5412 | + if (!$this->is_activated) { | |
| 5413 | + echo '<div class="pro-feature-overlay">'; | |
| 5414 | + echo '<a href="https://mxchat.ai/" target="_blank">'; | |
| 5415 | + echo '<img src="' . esc_url(plugin_dir_url(__FILE__) . '../images/pro-only-dark.png') . '" alt="' . esc_attr__('Pro Only', 'mxchat') . '" />'; | |
| 5416 | + echo '</a>'; | |
| 5417 | + echo '</div>'; | |
| 5418 | + } | |
| 5419 | + | |
| 5420 | + echo '</div>'; | |
| 5421 | + echo '<p class="description">' . esc_html__('Enable to show the Word document upload button in the chatbot toolbar. Disable to hide it.', 'mxchat') . '</p>'; | |
| 5422 | +} | |
| 5423 | + | |
| 5141 | 5424 | public function mxchat_pdf_intent_trigger_text_callback() { |
| 5142 | 5425 | $disabled = $this->is_activated ? '' : 'disabled'; |
| 5143 | 5426 | $class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; |
| 5144 | 5427 | $default_text = __("Please provide the URL to the PDF you'd like to discuss.", 'mxchat'); |
| @@ -5374,9 +5657,9 @@ | ||
| 5374 | 5657 | echo sprintf( |
| 5375 | 5658 | '<input type="range" |
| 5376 | 5659 | id="similarity_threshold" |
| 5377 | 5660 | name="similarity_threshold" |
| 5378 | - min="70" | |
| 5661 | + min="20" | |
| 5379 | 5662 | max="85" |
| 5380 | 5663 | step="1" |
| 5381 | 5664 | value="%s" |
| 5382 | 5665 | class="range-slider" />', |
| @@ -5388,9 +5671,9 @@ | ||
| 5388 | 5671 | ); |
| 5389 | 5672 | echo '</div>'; |
| 5390 | 5673 | |
| 5391 | 5674 | echo '<p class="description">'; |
| 5392 | - echo esc_html__('Set the similarity threshold (recommended: 75) to balance accuracy; too high might limit your bot\'s ability to find relevant knowledge.', 'mxchat'); | |
| 5675 | + echo esc_html__('Set the similarity threshold (recommended: 75) to balance accuracy; too high might limit your bot\'s ability to find relevant knowledge. If your bot is not matching content, move to lowest setting to test.', 'mxchat'); | |
| 5393 | 5676 | echo '</p>'; |
| 5394 | 5677 | } |
| 5395 | 5678 | |
| 5396 | 5679 | |
| @@ -5440,9 +5723,9 @@ | ||
| 5440 | 5723 | public function mxchat_enqueue_admin_assets() { |
| 5441 | 5724 | wp_enqueue_style('wp-color-picker'); |
| 5442 | 5725 | |
| 5443 | 5726 | // Get the plugin version or file modification time for cache busting |
| 5444 | - $plugin_version = '2.0.3'; // Replace this with your plugin's version | |
| 5727 | + $plugin_version = '2.0.7'; // Replace this with your plugin's version | |
| 5445 | 5728 | |
| 5446 | 5729 | // File paths |
| 5447 | 5730 | $color_picker_js_path = plugin_dir_path(__FILE__) . '../js/my-color-picker.js'; |
| 5448 | 5731 | $embedding_check_js_path = plugin_dir_path(__FILE__) . '../js/embedding-check.js'; |
| @@ -5448,10 +5731,12 @@ | ||
| 5448 | 5731 | $embedding_check_js_path = plugin_dir_path(__FILE__) . '../js/embedding-check.js'; |
| 5449 | 5732 | $admin_css_path = plugin_dir_path(__FILE__) . '../css/admin-style.css'; |
| 5450 | 5733 | $knowledge_css_path = plugin_dir_path(__FILE__) . '../css/knowledge-style.css'; |
| 5451 | 5734 | $intent_css_path = plugin_dir_path(__FILE__) . '../css/intent-style.css'; |
| 5735 | + $transcripts_css_path = plugin_dir_path(__FILE__) . '../css/chat-transcripts.css'; | |
| 5452 | 5736 | $transcripts_js_path = plugin_dir_path(__FILE__) . '../js/mxchat_transcripts.js'; |
| 5453 | 5737 | |
| 5738 | + | |
| 5454 | 5739 | // Check if files exist and get modification times |
| 5455 | 5740 | $color_picker_version = file_exists($color_picker_js_path) ? filemtime($color_picker_js_path) : $plugin_version; |
| 5456 | 5741 | $embedding_check_version = file_exists($embedding_check_js_path) ? filemtime($embedding_check_js_path) : $plugin_version; |
| 5457 | 5742 | $admin_css_version = file_exists($admin_css_path) ? filemtime($admin_css_path) : $plugin_version; |
| @@ -5456,10 +5741,12 @@ | ||
| 5456 | 5741 | $embedding_check_version = file_exists($embedding_check_js_path) ? filemtime($embedding_check_js_path) : $plugin_version; |
| 5457 | 5742 | $admin_css_version = file_exists($admin_css_path) ? filemtime($admin_css_path) : $plugin_version; |
| 5458 | 5743 | $knowledge_css_version = file_exists($knowledge_css_path) ? filemtime($knowledge_css_path) : $plugin_version; |
| 5459 | 5744 | $intent_css_version = file_exists($intent_css_path) ? filemtime($intent_css_path) : $plugin_version; |
| 5745 | + $transcripts_css_version = file_exists($transcripts_css_path) ? filemtime($transcripts_css_path) : $plugin_version; | |
| 5460 | 5746 | $transcripts_js_version = file_exists($transcripts_js_path) ? filemtime($transcripts_js_path) : $plugin_version; |
| 5461 | 5747 | |
| 5748 | + | |
| 5462 | 5749 | // Enqueue scripts and styles with corrected paths |
| 5463 | 5750 | wp_enqueue_script( |
| 5464 | 5751 | 'mxchat-color-picker', |
| 5465 | 5752 | plugin_dir_url(__FILE__) . '../js/my-color-picker.js', |
| @@ -5476,16 +5763,8 @@ | ||
| 5476 | 5763 | true |
| 5477 | 5764 | ); |
| 5478 | 5765 | |
| 5479 | 5766 | wp_enqueue_script( |
| 5480 | - 'mxchat-transcripts-js', | |
| 5481 | - plugin_dir_url(__FILE__) . '../js/mxchat_transcripts.js', | |
| 5482 | - array('jquery'), | |
| 5483 | - $transcripts_js_version, | |
| 5484 | - true | |
| 5485 | - ); | |
| 5486 | - | |
| 5487 | - wp_enqueue_script( | |
| 5488 | 5767 | 'mxchat-admin-js', |
| 5489 | 5768 | plugin_dir_url(__FILE__) . '../js/mxchat-admin.js', |
| 5490 | 5769 | array('jquery'), |
| 5491 | 5770 | $plugin_version, |
| @@ -5496,8 +5775,9 @@ | ||
| 5496 | 5775 | 'ajax_url' => admin_url('admin-ajax.php'), |
| 5497 | 5776 | 'license_nonce' => wp_create_nonce('mxchat_activate_license_nonce'), |
| 5498 | 5777 | 'inline_edit_nonce' => wp_create_nonce('mxchat_save_inline_nonce'), |
| 5499 | 5778 | 'setting_nonce' => wp_create_nonce('mxchat_save_setting_nonce'), |
| 5779 | + 'export_nonce' => wp_create_nonce('mxchat_export_transcripts'), | |
| 5500 | 5780 | )); |
| 5501 | 5781 | |
| 5502 | 5782 | // Enqueue the admin CSS |
| 5503 | 5783 | wp_enqueue_style( |
| @@ -5505,9 +5785,26 @@ | ||
| 5505 | 5785 | plugin_dir_url(__FILE__) . '../css/admin-style.css', |
| 5506 | 5786 | array(), |
| 5507 | 5787 | $admin_css_version |
| 5508 | 5788 | ); |
| 5509 | - | |
| 5789 | + | |
| 5790 | + if (isset($_GET['page']) && $_GET['page'] === 'mxchat-transcripts') { | |
| 5791 | + wp_enqueue_style( | |
| 5792 | + 'mxchat-chat-transcripts-css', | |
| 5793 | + plugin_dir_url(__FILE__) . '../css/chat-transcripts.css', | |
| 5794 | + array(), | |
| 5795 | + $transcripts_css_version | |
| 5796 | + ); | |
| 5797 | + | |
| 5798 | + wp_enqueue_script( | |
| 5799 | + 'mxchat-transcripts-js', | |
| 5800 | + plugin_dir_url(__FILE__) . '../js/mxchat_transcripts.js', | |
| 5801 | + array('jquery'), | |
| 5802 | + $transcripts_js_version, | |
| 5803 | + true | |
| 5804 | + ); | |
| 5805 | + } | |
| 5806 | + | |
| 5510 | 5807 | wp_enqueue_style( |
| 5511 | 5808 | 'mxchat-knowledge-css', |
| 5512 | 5809 | plugin_dir_url(__FILE__) . '../css/knowledge-style.css', |
| 5513 | 5810 | array(), |
| @@ -5557,8 +5854,10 @@ | ||
| 5557 | 5854 | 'live_agent_bot_token' => $this->options['live_agent_bot_token'] ?? '', |
| 5558 | 5855 | 'live_agent_message_bg_color' => $this->options['live_agent_message_bg_color'] ?? '#ffffff', |
| 5559 | 5856 | 'live_agent_message_font_color' => $this->options['live_agent_message_font_color'] ?? '#333333', |
| 5560 | 5857 | 'chat_toolbar_toggle' => $this->options['chat_toolbar_toggle'] ?? 'off', |
| 5858 | + 'show_pdf_upload_button' => $this->options['show_pdf_upload_button'] ?? 'on', // Add this line | |
| 5859 | + 'show_word_upload_button' => $this->options['show_word_upload_button'] ?? 'on', // Add this line | |
| 5561 | 5860 | 'mode_indicator_bg_color' => $this->options['mode_indicator_bg_color'] ?? '#767676', |
| 5562 | 5861 | 'mode_indicator_font_color' => $this->options['mode_indicator_font_color'] ?? '#ffffff', |
| 5563 | 5862 | 'toolbar_icon_color' => $this->options['toolbar_icon_color'] ?? '#212121', |
| 5564 | 5863 | )); |
| @@ -5573,9 +5872,9 @@ | ||
| 5573 | 5872 | } |
| 5574 | 5873 | |
| 5575 | 5874 | if (isset($input['similarity_threshold'])) { |
| 5576 | 5875 | $new_input['similarity_threshold'] = absint($input['similarity_threshold']); // Ensure it's an integer |
| 5577 | - $new_input['similarity_threshold'] = min(max($new_input['similarity_threshold'], 70), 85); // Enforce range | |
| 5876 | + $new_input['similarity_threshold'] = min(max($new_input['similarity_threshold'], 20), 85); // Enforce range | |
| 5578 | 5877 | } |
| 5579 | 5878 | |
| 5580 | 5879 | if (isset($input['xai_api_key'])) { |
| 5581 | 5880 | $new_input['xai_api_key'] = sanitize_text_field($input['xai_api_key']); |
| @@ -5679,8 +5978,25 @@ | ||
| 5679 | 5978 | |
| 5680 | 5979 | if (isset($input['pre_chat_message'])) { |
| 5681 | 5980 | $new_input['pre_chat_message'] = sanitize_textarea_field($input['pre_chat_message']); |
| 5682 | 5981 | } |
| 5982 | + | |
| 5983 | + if (isset($input['voyage_api_key'])) { | |
| 5984 | + $new_input['voyage_api_key'] = sanitize_text_field($input['voyage_api_key']); | |
| 5985 | + } | |
| 5986 | + | |
| 5987 | + // Add to your sanitize function | |
| 5988 | + if (isset($input['embedding_model'])) { | |
| 5989 | + $allowed_models = array( | |
| 5990 | + 'text-embedding-ada-002', | |
| 5991 | + 'text-embedding-3-small', | |
| 5992 | + 'text-embedding-3-large', | |
| 5993 | + 'voyage-3-large' | |
| 5994 | + ); | |
| 5995 | + if (in_array($input['embedding_model'], $allowed_models)) { | |
| 5996 | + $new_input['embedding_model'] = sanitize_text_field($input['embedding_model']); | |
| 5997 | + } | |
| 5998 | + } | |
| 5683 | 5999 | |
| 5684 | 6000 | if (isset($input['model'])) { |
| 5685 | 6001 | $allowed_models = array( |
| 5686 | 6002 | 'grok-beta', |
| @@ -5685,8 +6001,9 @@ | ||
| 5685 | 6001 | $allowed_models = array( |
| 5686 | 6002 | 'grok-beta', |
| 5687 | 6003 | 'grok-2', |
| 5688 | 6004 | 'deepseek-chat', |
| 6005 | + 'claude-3-7-sonnet-20250219', | |
| 5689 | 6006 | 'claude-3-5-sonnet-20241022', |
| 5690 | 6007 | 'claude-3-opus-20240229', |
| 5691 | 6008 | 'claude-3-sonnet-20240229', |
| 5692 | 6009 | 'claude-3-haiku-20240307', |
| @@ -5854,8 +6171,22 @@ | ||
| 5854 | 6171 | } |
| 5855 | 6172 | |
| 5856 | 6173 | if (isset($input['chat_toolbar_toggle'])) { |
| 5857 | 6174 | $new_input['chat_toolbar_toggle'] = $input['chat_toolbar_toggle'] === 'on' ? 'on' : 'off'; |
| 6175 | + } | |
| 6176 | + | |
| 6177 | + // Sanitize PDF upload button toggle | |
| 6178 | + if (isset($input['show_pdf_upload_button'])) { | |
| 6179 | + $new_input['show_pdf_upload_button'] = $input['show_pdf_upload_button'] === 'on' ? 'on' : 'off'; | |
| 6180 | + } else { | |
| 6181 | + $new_input['show_pdf_upload_button'] = 'off'; // If checkbox is unchecked | |
| 6182 | + } | |
| 6183 | + | |
| 6184 | + // Sanitize Word upload button toggle | |
| 6185 | + if (isset($input['show_word_upload_button'])) { | |
| 6186 | + $new_input['show_word_upload_button'] = $input['show_word_upload_button'] === 'on' ? 'on' : 'off'; | |
| 6187 | + } else { | |
| 6188 | + $new_input['show_word_upload_button'] = 'off'; // If checkbox is unchecked | |
| 5858 | 6189 | } |
| 5859 | 6190 | |
| 5860 | 6191 | if (isset($input['pdf_intent_trigger_text'])) { |
| 5861 | 6192 | $new_input['pdf_intent_trigger_text'] = sanitize_text_field($input['pdf_intent_trigger_text']); |