| 1 |
<?php |
| 2 |
if (!defined('ABSPATH')) { |
| 3 |
exit; // Exit if accessed directly |
| 4 |
} |
| 5 |
|
| 6 |
class MxChat_Admin { |
| 7 |
private $options; |
| 8 |
private $chat_count; |
| 9 |
private $is_activated; |
| 10 |
|
| 11 |
public function __construct() { |
| 12 |
$this->options = get_option('mxchat_options'); |
| 13 |
$this->chat_count = get_option('mxchat_chat_count', 0); |
| 14 |
$this->is_activated = $this->is_license_active(); |
| 15 |
|
| 16 |
// Initialize default options if they are not set |
| 17 |
if (!$this->options) { |
| 18 |
$this->initialize_default_options(); |
| 19 |
} |
| 20 |
|
| 21 |
// Add admin menu and initialize settings |
| 22 |
add_action('admin_menu', array($this, 'mxchat_add_plugin_page')); |
| 23 |
add_action('admin_init', array($this, 'mxchat_page_init')); |
| 24 |
add_action('admin_enqueue_scripts', array($this, 'mxchat_enqueue_admin_assets')); |
| 25 |
add_action('wp_ajax_mxchat_delete_chat_history', array($this, 'mxchat_delete_chat_history')); |
| 26 |
add_action('admin_post_mxchat_submit_content', array($this, 'mxchat_handle_content_submission')); |
| 27 |
add_action('admin_post_mxchat_delete_prompt', array($this, 'mxchat_handle_delete_prompt')); |
| 28 |
add_action('wp_ajax_mxchat_fetch_chat_history', array($this, 'mxchat_fetch_chat_history')); |
| 29 |
add_action('wp_ajax_nopriv_mxchat_fetch_chat_history', array($this, 'mxchat_fetch_chat_history')); |
| 30 |
add_action('admin_post_mxchat_submit_sitemap', array($this, 'mxchat_handle_sitemap_submission')); |
| 31 |
add_action('wp_footer', array($this, 'mxchat_append_chatbot_to_body')); |
| 32 |
add_action('admin_head-mxchat-prompts', array($this, 'mxchat_enqueue_admin_assets')); |
| 33 |
add_action('admin_head-toplevel_page_mxchat-max', array($this, 'mxchat_enqueue_admin_assets')); |
| 34 |
add_action('wp_ajax_mxchat_activate_license', array($this, 'mxchat_handle_activate_license')); |
| 35 |
add_action('admin_notices', array($this, 'mxchat_display_admin_notice')); |
| 36 |
|
| 37 |
} |
| 38 |
|
| 39 |
// Method to check if the license is active |
| 40 |
private function is_license_active() { |
| 41 |
$license_status = get_option('mxchat_license_status', 'inactive'); |
| 42 |
return $license_status === 'active'; |
| 43 |
} |
| 44 |
|
| 45 |
// Initialize default options |
| 46 |
private function initialize_default_options() { |
| 47 |
$default_options = array( |
| 48 |
'api_key' => '', |
| 49 |
'system_prompt_instructions' => '[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: |
| 50 |
- Your name is [Chatbot Name]. Always introduce yourself as this name when appropriate. |
| 51 |
- 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. If there is an exception topic (e.g., "parking") that you should assist with, you may do so if instructed. |
| 52 |
- When appropriate, highlight the benefits of [insert proper subject here]. Offer to guide visitors to relevant pages or provide them with more information. |
| 53 |
- If a visitor asks for a purchase link or further information, provide them with this link: [Insert Purchase Link Here]. Always ensure that the link is relevant and directly related to the website\'s offerings. |
| 54 |
- Keep your responses short, concise, and to the point. Provide clear and direct answers suitable for a chatbot interaction. |
| 55 |
- If you reference specific content, provide a hyperlink to the relevant page using hypertext. Avoid including links that do not directly relate to the content or answer the visitor\'s query. |
| 56 |
- Provide answers based on the knowledge available to you. If you do not have an answer to a specific question, let the visitor know that you don’t have the information and suggest where they might find it or offer to help with something else.', |
| 57 |
'model' => 'gpt-3.5-turbo', |
| 58 |
'rate_limit' => '100', |
| 59 |
'rate_limit_message' => 'Rate limit exceeded. Please try again later.', |
| 60 |
'top_bar_title' => 'MxChat', |
| 61 |
'intro_message' => 'Hello! How can I assist you today?', |
| 62 |
'append_to_body' => 'on', |
| 63 |
'close_button_color' => '#fff', |
| 64 |
'chatbot_bg_color' => '#fff', |
| 65 |
'user_message_bg_color' => '#fff', |
| 66 |
'user_message_font_color' => '#212121', |
| 67 |
'bot_message_bg_color' => '#212121', |
| 68 |
'bot_message_font_color' => '#fff', |
| 69 |
'top_bar_bg_color' => '#212121', |
| 70 |
'send_button_font_color' => '#212121', |
| 71 |
'chat_input_font_color' => '#212121', |
| 72 |
'chatbot_background_color' => '#212121', |
| 73 |
'icon_color' => '#fff', |
| 74 |
'enable_woocommerce_integration' => '0', |
| 75 |
); |
| 76 |
|
| 77 |
|
| 78 |
// Merge existing options with defaults |
| 79 |
$existing_options = get_option('mxchat_options', array()); |
| 80 |
$merged_options = wp_parse_args($existing_options, $default_options); |
| 81 |
|
| 82 |
// Update the options if they have changed |
| 83 |
if ($existing_options !== $merged_options) { |
| 84 |
update_option('mxchat_options', $merged_options); |
| 85 |
} |
| 86 |
|
| 87 |
// Update the $this->options property |
| 88 |
$this->options = $merged_options; |
| 89 |
} |
| 90 |
|
| 91 |
public function mxchat_add_plugin_page() { |
| 92 |
// Main menu page |
| 93 |
add_menu_page( |
| 94 |
'MxChat Settings', |
| 95 |
'MxChat', |
| 96 |
'manage_options', |
| 97 |
'mxchat-max', |
| 98 |
array($this, 'mxchat_create_admin_page'), |
| 99 |
'dashicons-testimonial', |
| 100 |
6 |
| 101 |
); |
| 102 |
|
| 103 |
// Submenu page for Knowledge |
| 104 |
add_submenu_page( |
| 105 |
'mxchat-max', |
| 106 |
'Prompts', |
| 107 |
'Knowledge', |
| 108 |
'manage_options', |
| 109 |
'mxchat-prompts', |
| 110 |
array($this, 'mxchat_create_prompts_page') |
| 111 |
); |
| 112 |
|
| 113 |
// Submenu page for Chat Transcripts |
| 114 |
add_submenu_page( |
| 115 |
'mxchat-max', // Corrected parent slug to match the main menu |
| 116 |
'Chat Transcripts', |
| 117 |
'Transcripts', |
| 118 |
'manage_options', |
| 119 |
'mxchat-transcripts', |
| 120 |
array($this, 'mxchat_create_transcripts_page') // Prefixed function name with mxchat_ |
| 121 |
); |
| 122 |
|
| 123 |
// Submenu page for Activation Key |
| 124 |
add_submenu_page( |
| 125 |
'mxchat-max', |
| 126 |
'Pro Upgrade', |
| 127 |
'Pro Upgrade', |
| 128 |
'manage_options', |
| 129 |
'mxchat-activation', |
| 130 |
array($this, 'mxchat_create_activation_page') |
| 131 |
); |
| 132 |
} |
| 133 |
|
| 134 |
|
| 135 |
public function mxchat_handle_content_submission() { |
| 136 |
// Check if the form was submitted and the user has sufficient permissions |
| 137 |
if (!isset($_POST['submit_content']) || !current_user_can('manage_options')) { |
| 138 |
return; |
| 139 |
} |
| 140 |
|
| 141 |
// Verify the nonce field for security |
| 142 |
$nonce = isset($_POST['mxchat_submit_content_nonce']) ? sanitize_text_field(wp_unslash($_POST['mxchat_submit_content_nonce'])) : ''; |
| 143 |
if (!wp_verify_nonce($nonce, 'mxchat_submit_content_action')) { |
| 144 |
wp_die('Nonce verification failed.'); |
| 145 |
} |
| 146 |
|
| 147 |
// Sanitize the content input |
| 148 |
$article_content = sanitize_textarea_field($_POST['article_content']); |
| 149 |
|
| 150 |
// Generate the embedding vector for the content |
| 151 |
$embedding_vector = $this->mxchat_generate_embedding($article_content); |
| 152 |
|
| 153 |
global $wpdb; |
| 154 |
$table_name = $wpdb->prefix . 'mxchat_system_prompt_content'; |
| 155 |
|
| 156 |
// Check if the 'source_url' column exists in the table and add it if it doesn't |
| 157 |
if ($wpdb->get_var($wpdb->prepare("SHOW COLUMNS FROM {$table_name} LIKE %s", 'source_url')) != 'source_url') { |
| 158 |
// Use wpdb::query and a prepared statement to avoid SQL injection |
| 159 |
$wpdb->query($wpdb->prepare("ALTER TABLE {$table_name} ADD source_url VARCHAR(255) DEFAULT ''")); |
| 160 |
} |
| 161 |
|
| 162 |
if (is_array($embedding_vector)) { |
| 163 |
// Serialize the embedding vector before storing it |
| 164 |
$embedding_vector_serialized = serialize($embedding_vector); |
| 165 |
|
| 166 |
// Insert the content and embedding vector into the database, using a prepared statement |
| 167 |
$inserted = $wpdb->insert( |
| 168 |
$table_name, |
| 169 |
array( |
| 170 |
'article_content' => $article_content, |
| 171 |
'embedding_vector' => $embedding_vector_serialized, |
| 172 |
'source_url' => '', // Empty string as a placeholder for now, or pass a valid URL if applicable |
| 173 |
), |
| 174 |
array( |
| 175 |
'%s', // Format for article_content (string) |
| 176 |
'%s', // Format for embedding_vector (serialized string) |
| 177 |
'%s', // Format for source_url (string) |
| 178 |
) |
| 179 |
); |
| 180 |
|
| 181 |
if ($inserted === false) { |
| 182 |
error_log('Error inserting content: ' . $wpdb->last_error); |
| 183 |
set_transient('mxchat_admin_notice', 'Error inserting content into the database. Please try again.', 30); |
| 184 |
} else { |
| 185 |
set_transient('mxchat_admin_notice', 'Content successfully submitted!', 30); |
| 186 |
} |
| 187 |
} else { |
| 188 |
error_log('Embedding generation failed for article content: ' . $article_content); |
| 189 |
set_transient('mxchat_admin_notice', 'Embedding generation failed. Please ensure your API key is correct and try again.', 30); |
| 190 |
} |
| 191 |
|
| 192 |
// Redirect after setting the transient |
| 193 |
wp_safe_redirect(esc_url(admin_url('admin.php?page=mxchat-prompts'))); |
| 194 |
exit; |
| 195 |
} |
| 196 |
|
| 197 |
public function mxchat_display_admin_notice() { |
| 198 |
// Get the message from the transient |
| 199 |
$message = get_transient('mxchat_admin_notice'); |
| 200 |
|
| 201 |
if ($message) { |
| 202 |
echo '<div class="notice notice-error is-dismissible">'; |
| 203 |
echo '<p>' . esc_html($message) . '</p>'; |
| 204 |
echo '</div>'; |
| 205 |
|
| 206 |
// Delete the transient after displaying the message |
| 207 |
delete_transient('mxchat_admin_notice'); |
| 208 |
} |
| 209 |
} |
| 210 |
|
| 211 |
|
| 212 |
public function mxchat_handle_delete_prompt() { |
| 213 |
// Sanitize and validate nonce using wp_unslash and sanitize_text_field |
| 214 |
$nonce = isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : ''; |
| 215 |
if (empty($nonce) || !wp_verify_nonce($nonce, 'mxchat_delete_prompt_nonce')) { |
| 216 |
wp_die('Nonce verification failed.'); |
| 217 |
} |
| 218 |
|
| 219 |
// Check user permissions |
| 220 |
if (!current_user_can('manage_options')) { |
| 221 |
wp_die('You do not have sufficient permissions to delete prompts.'); |
| 222 |
} |
| 223 |
|
| 224 |
// Sanitize and validate the 'id' parameter |
| 225 |
$id = isset($_GET['id']) ? intval($_GET['id']) : 0; |
| 226 |
if ($id <= 0) { |
| 227 |
wp_die('Invalid prompt ID.'); |
| 228 |
} |
| 229 |
|
| 230 |
global $wpdb; |
| 231 |
$table_name = $wpdb->prefix . 'mxchat_system_prompt_content'; |
| 232 |
|
| 233 |
// Clear relevant cache before deletion |
| 234 |
$cache_key = 'prompt_' . $id; |
| 235 |
wp_cache_delete($cache_key, 'mxchat_prompts'); |
| 236 |
|
| 237 |
// Delete the record using a prepared statement |
| 238 |
$deleted = $wpdb->delete($table_name, array('id' => $id), array('%d')); |
| 239 |
|
| 240 |
if ($deleted !== false) { |
| 241 |
// Optionally, clear a general cache if you have one |
| 242 |
wp_cache_delete('all_prompts', 'mxchat_prompts'); |
| 243 |
} |
| 244 |
|
| 245 |
// Redirect to the prompts page with a success message |
| 246 |
$redirect_url = add_query_arg(array( |
| 247 |
'page' => 'mxchat-prompts', |
| 248 |
'deleted' => 'true' |
| 249 |
), admin_url('admin.php')); |
| 250 |
|
| 251 |
wp_safe_redirect($redirect_url); |
| 252 |
exit; |
| 253 |
} |
| 254 |
|
| 255 |
|
| 256 |
public function mxchat_create_admin_page() { |
| 257 |
?> |
| 258 |
<div class="wrap mxchat-admin"> |
| 259 |
<?php if (!$this->is_activated): ?> |
| 260 |
<div class="mxchat-pro-banner"> |
| 261 |
<p> |
| 262 |
Want even more features such as a fully customizable theme, WooCommerce integration, dedicated support, and much more? |
| 263 |
<a href="https://mxchat.ai/" target="_blank">Upgrade to MxChat Pro today and get a special launch lifetime license for only $49.97!</a> |
| 264 |
</p> |
| 265 |
</div> |
| 266 |
<?php endif; ?> |
| 267 |
<h2 class="admin-title">Mx<span class="admin-emphasis">Chat</span></h2> |
| 268 |
<h2 class="nav-tab-wrapper"> |
| 269 |
<a href="#chatbot" class="nav-tab nav-tab-active" data-tab="chatbot">Chatbot</a> |
| 270 |
<a href="#embed" class="nav-tab" data-tab="embed">Embed</a> |
| 271 |
<a href="#theme" class="nav-tab" data-tab="theme">Theme</a> |
| 272 |
<a href="#general" class="nav-tab" data-tab="general">General</a> |
| 273 |
</h2> |
| 274 |
<form method="post" action="options.php"> |
| 275 |
<?php settings_fields('mxchat_option_group'); ?> |
| 276 |
<div id="chatbot" class="tab-content active"> |
| 277 |
<?php do_settings_sections('mxchat-chatbot'); ?> |
| 278 |
</div> |
| 279 |
<div id="embed" class="tab-content"> |
| 280 |
<?php do_settings_sections('mxchat-embed'); ?> |
| 281 |
</div> |
| 282 |
<div id="theme" class="tab-content"> |
| 283 |
<?php do_settings_sections('mxchat-theme'); ?> |
| 284 |
</div> |
| 285 |
<div id="general" class="tab-content"> |
| 286 |
<?php do_settings_sections('mxchat-general'); ?> |
| 287 |
<div class="mxchat-general-notes"> |
| 288 |
<h3>Important Notes</h3> |
| 289 |
<p> |
| 290 |
You can add the chatbot to your site using the <code>[mxchat_chatbot floating="yes"]</code> or <code>[mxchat_chatbot floating="no"]</code> shortcode. Additionally, you can automatically append the chatbot to your site’s body element from the settings page. |
| 291 |
</p> |
| 292 |
<p> |
| 293 |
Please note that you must have an OpenAI API key to use the chatbot. You can obtain an API key from the <a href="https://platform.openai.com/signup" target="_blank">OpenAI website</a>. It's easy to sign up, and you'll need to add credits to your account before using the chatbot. Generally, as little as $5 in credits is sufficient to get started. |
| 294 |
</p> |
| 295 |
</div> |
| 296 |
</div> |
| 297 |
<?php submit_button(); ?> |
| 298 |
</form> |
| 299 |
</div> |
| 300 |
<?php |
| 301 |
} |
| 302 |
|
| 303 |
|
| 304 |
public function mxchat_create_transcripts_page() { |
| 305 |
?> |
| 306 |
<div class="wrap mxchat-admin"> |
| 307 |
<h2><?php esc_html_e('Chat Transcripts', 'mxchat'); ?></h2> |
| 308 |
<form id="mxchat-delete-form" method="post"> |
| 309 |
<?php wp_nonce_field('mxchat_delete_chat_history', 'mxchat_delete_chat_nonce'); ?> |
| 310 |
<div class="mxchat-controls"> |
| 311 |
<label for="mxchat-select-all-transcripts" class="mxchat-select-all-label"> |
| 312 |
<input type="checkbox" id="mxchat-select-all-transcripts" /> <?php esc_html_e('Select All', 'mxchat'); ?> |
| 313 |
</label> |
| 314 |
<input type="submit" value="<?php esc_attr_e('Delete Selected', 'mxchat'); ?>" class="button button-primary delete-chats-button" /> |
| 315 |
</div> |
| 316 |
<div id="mxchat-transcripts"> |
| 317 |
<!-- Transcripts will be loaded here --> |
| 318 |
</div> |
| 319 |
</form> |
| 320 |
</div> |
| 321 |
<?php |
| 322 |
} |
| 323 |
|
| 324 |
|
| 325 |
|
| 326 |
|
| 327 |
public function mxchat_create_prompts_page() { |
| 328 |
global $wpdb; |
| 329 |
$table_name = $wpdb->prefix . 'mxchat_system_prompt_content'; |
| 330 |
|
| 331 |
// Verify the nonce before processing the request |
| 332 |
$nonce = isset($_GET['_wpnonce']) ? sanitize_text_field($_GET['_wpnonce']) : ''; |
| 333 |
|
| 334 |
if (!empty($nonce) && wp_verify_nonce($nonce, 'mxchat_prompts_search_nonce')) { |
| 335 |
// Sanitize input data |
| 336 |
$search_query = isset($_GET['search']) ? sanitize_text_field($_GET['search']) : ''; |
| 337 |
$current_page = isset($_GET['paged']) ? absint($_GET['paged']) : 1; |
| 338 |
} else { |
| 339 |
$search_query = ''; |
| 340 |
$current_page = 1; |
| 341 |
} |
| 342 |
|
| 343 |
$per_page = 10; |
| 344 |
|
| 345 |
// Create cache keys |
| 346 |
$cache_key_total = 'total_prompts_' . md5($search_query); |
| 347 |
$cache_key_prompts = 'prompts_' . md5($search_query . '_' . $current_page); |
| 348 |
|
| 349 |
// Retrieve total number of prompts from cache or database |
| 350 |
$total_prompts = wp_cache_get($cache_key_total, 'mxchat_prompts'); |
| 351 |
if ($total_prompts === false) { |
| 352 |
if (!empty($search_query)) { |
| 353 |
$total_prompts = $wpdb->get_var( |
| 354 |
$wpdb->prepare( |
| 355 |
"SELECT COUNT(*) FROM {$table_name} WHERE article_content LIKE %s", |
| 356 |
'%' . $wpdb->esc_like($search_query) . '%' |
| 357 |
) |
| 358 |
); |
| 359 |
} else { |
| 360 |
$total_prompts = $wpdb->get_var("SELECT COUNT(*) FROM {$table_name}"); |
| 361 |
} |
| 362 |
wp_cache_set($cache_key_total, $total_prompts, 'mxchat_prompts', 3600); // Cache for 1 hour |
| 363 |
} |
| 364 |
|
| 365 |
$total_pages = ceil($total_prompts / $per_page); |
| 366 |
$offset = ($current_page - 1) * $per_page; |
| 367 |
|
| 368 |
// Retrieve prompts from cache or database |
| 369 |
$prompts = wp_cache_get($cache_key_prompts, 'mxchat_prompts'); |
| 370 |
if ($prompts === false) { |
| 371 |
if (!empty($search_query)) { |
| 372 |
$prompts = $wpdb->get_results( |
| 373 |
$wpdb->prepare( |
| 374 |
"SELECT * FROM {$table_name} WHERE article_content LIKE %s ORDER BY timestamp DESC LIMIT %d OFFSET %d", |
| 375 |
'%' . $wpdb->esc_like($search_query) . '%', |
| 376 |
$per_page, |
| 377 |
$offset |
| 378 |
) |
| 379 |
); |
| 380 |
} else { |
| 381 |
$prompts = $wpdb->get_results( |
| 382 |
$wpdb->prepare( |
| 383 |
"SELECT * FROM {$table_name} ORDER BY timestamp DESC LIMIT %d OFFSET %d", |
| 384 |
$per_page, |
| 385 |
$offset |
| 386 |
) |
| 387 |
); |
| 388 |
} |
| 389 |
wp_cache_set($cache_key_prompts, $prompts, 'mxchat_prompts', 3600); // Cache for 1 hour |
| 390 |
} |
| 391 |
|
| 392 |
?> |
| 393 |
|
| 394 |
<div class="wrap mxchat-admin"> |
| 395 |
<div class="mxchat-grid-container"> |
| 396 |
|
| 397 |
<!-- Submit Content --> |
| 398 |
<div class="mxchat-grid-item full-width"> |
| 399 |
<h2>Submit Content</h2> |
| 400 |
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php?action=mxchat_submit_content')); ?>"> |
| 401 |
<?php wp_nonce_field('mxchat_submit_content_action', 'mxchat_submit_content_nonce'); ?> |
| 402 |
<div class="mxchat-form-group"> |
| 403 |
<label for="article_content">Article Content:</label> |
| 404 |
<textarea name="article_content" id="article_content" required></textarea> |
| 405 |
<input type="submit" name="submit_content" value="Submit Content" class="button button-primary submit-content-button" /> |
| 406 |
</div> |
| 407 |
</form> |
| 408 |
</div> |
| 409 |
|
| 410 |
<!-- Submit Sitemap --> |
| 411 |
<div class="mxchat-grid-item"> |
| 412 |
<h2>Submit Sitemap</h2> |
| 413 |
<form id="mxchat-sitemap-form" method="post" class="mxchat-sitemap-form" action="<?php echo esc_url(admin_url('admin-post.php?action=mxchat_submit_sitemap')); ?>"> |
| 414 |
<?php wp_nonce_field('mxchat_submit_sitemap_action', 'mxchat_submit_sitemap_nonce'); ?> |
| 415 |
<div class="mxchat-search-group"> |
| 416 |
<input type="url" name="sitemap_url" id="sitemap_url" placeholder="Sitemap URL" required /> |
| 417 |
<input type="submit" name="submit_sitemap" value="Submit Sitemap" class="button button-primary" /> |
| 418 |
</div> |
| 419 |
</form> |
| 420 |
<div id="mxchat-sitemap-loading" class="mxchat-spinner" style="display: none;"></div> |
| 421 |
<div id="mxchat-loading-text" style="display: none; margin-top: 10px; color: #333;">Loading sitemap content into database, please wait...</div> |
| 422 |
</div> |
| 423 |
|
| 424 |
<!-- Search Knowledge --> |
| 425 |
<div class="mxchat-grid-item"> |
| 426 |
<h2>Search Knowledge</h2> |
| 427 |
<form method="get" id="knowledge-search"> |
| 428 |
<?php wp_nonce_field('mxchat_prompts_search_nonce'); ?> |
| 429 |
<input type="hidden" name="page" value="mxchat-prompts" /> |
| 430 |
<div class="mxchat-search-group"> |
| 431 |
<input type="text" name="search" placeholder="Search Knowledge" value="<?php echo esc_attr($search_query); ?>" /> |
| 432 |
<input type="submit" value="Search" class="button button-primary" /> |
| 433 |
</div> |
| 434 |
</form> |
| 435 |
</div> |
| 436 |
</div> |
| 437 |
|
| 438 |
<!-- Table below the forms --> |
| 439 |
<div class="tablenav"> |
| 440 |
<div class="tablenav-pages"> |
| 441 |
<span class="displaying-num"><?php echo esc_html($total_prompts); ?> items</span> |
| 442 |
<?php |
| 443 |
$page_links = paginate_links(array( |
| 444 |
'base' => add_query_arg('paged', '%#%', admin_url('admin.php?page=mxchat-prompts')), |
| 445 |
'format' => '', |
| 446 |
'prev_text' => __('« Previous'), |
| 447 |
'next_text' => __('Next »'), |
| 448 |
'total' => $total_pages, |
| 449 |
'current' => $current_page, |
| 450 |
'add_args' => array( |
| 451 |
'search' => $search_query, |
| 452 |
'_wpnonce' => wp_create_nonce('mxchat_prompts_search_nonce') |
| 453 |
), |
| 454 |
)); |
| 455 |
|
| 456 |
if ($page_links) { |
| 457 |
echo '<div class="tablenav-pages">' . wp_kses_post($page_links) . '</div>'; |
| 458 |
} |
| 459 |
?> |
| 460 |
</div> |
| 461 |
</div> |
| 462 |
<table class="wp-list-table widefat fixed striped"> |
| 463 |
<thead> |
| 464 |
<tr> |
| 465 |
<th>ID</th> |
| 466 |
<th>Article Content</th> |
| 467 |
<th>URL</th> |
| 468 |
<th>Actions</th> |
| 469 |
</tr> |
| 470 |
</thead> |
| 471 |
<tbody> |
| 472 |
<?php |
| 473 |
if ($prompts) { |
| 474 |
foreach ($prompts as $prompt) { |
| 475 |
?> |
| 476 |
<tr> |
| 477 |
<td><?php echo esc_html($prompt->id); ?></td> |
| 478 |
<td class="mxchat_article_content_dashboard"><?php echo wp_kses_post(wpautop(esc_textarea($prompt->article_content))); ?></td> |
| 479 |
<td class="mxchat_article_url_dashboard"> |
| 480 |
<?php if (!empty($prompt->source_url)): ?> |
| 481 |
<a href="<?php echo esc_url($prompt->source_url); ?>" target="_blank"><?php echo esc_html($prompt->source_url); ?></a> |
| 482 |
<?php else: ?> |
| 483 |
N/A |
| 484 |
<?php endif; ?> |
| 485 |
</td> |
| 486 |
<td> |
| 487 |
<a href="<?php echo esc_url(admin_url('admin-post.php?action=mxchat_delete_prompt&id=' . esc_attr($prompt->id) . '&_wpnonce=' . wp_create_nonce('mxchat_delete_prompt_nonce'))); ?>">Delete</a> |
| 488 |
</td> |
| 489 |
</tr> |
| 490 |
<?php |
| 491 |
} |
| 492 |
} else { |
| 493 |
?> |
| 494 |
<tr> |
| 495 |
<td colspan="4">No prompts found.</td> |
| 496 |
</tr> |
| 497 |
<?php |
| 498 |
} |
| 499 |
?> |
| 500 |
</tbody> |
| 501 |
</table> |
| 502 |
</div> |
| 503 |
|
| 504 |
<?php |
| 505 |
} |
| 506 |
|
| 507 |
public function mxchat_generate_embedding($text) { |
| 508 |
$options = get_option('mxchat_options'); |
| 509 |
$api_key = $options['api_key'] ?? 'default_api_key'; |
| 510 |
|
| 511 |
$response = wp_remote_post('https://api.openai.com/v1/embeddings', array( |
| 512 |
'body' => wp_json_encode(array( |
| 513 |
'model' => 'text-embedding-ada-002', |
| 514 |
'input' => $text |
| 515 |
)), |
| 516 |
'headers' => array( |
| 517 |
'Authorization' => 'Bearer ' . $api_key, |
| 518 |
'Content-Type' => 'application/json' |
| 519 |
), |
| 520 |
)); |
| 521 |
|
| 522 |
if (is_wp_error($response)) { |
| 523 |
return null; |
| 524 |
} |
| 525 |
|
| 526 |
$response_data = json_decode(wp_remote_retrieve_body($response), true); |
| 527 |
return $response_data['data'][0]['embedding'] ?? null; |
| 528 |
} |
| 529 |
|
| 530 |
public function mxchat_delete_chat_history() { |
| 531 |
if (!current_user_can('manage_options')) { |
| 532 |
echo wp_json_encode(['error' => 'You do not have sufficient permissions.']); |
| 533 |
wp_die(); |
| 534 |
} |
| 535 |
|
| 536 |
check_ajax_referer('mxchat_delete_chat_history', 'security'); |
| 537 |
|
| 538 |
global $wpdb; |
| 539 |
$table_name = $wpdb->prefix . 'mxchat_chat_transcripts'; |
| 540 |
|
| 541 |
if (isset($_POST['delete_session_ids']) && is_array($_POST['delete_session_ids'])) { |
| 542 |
foreach ($_POST['delete_session_ids'] as $session_id) { |
| 543 |
$session_id_sanitized = sanitize_text_field($session_id); |
| 544 |
|
| 545 |
// Clear relevant cache before deletion |
| 546 |
$cache_key = 'chat_session_' . $session_id_sanitized; |
| 547 |
wp_cache_delete($cache_key, 'mxchat_chat_sessions'); |
| 548 |
|
| 549 |
// Perform the deletion |
| 550 |
$wpdb->delete($table_name, ['session_id' => $session_id_sanitized]); |
| 551 |
} |
| 552 |
|
| 553 |
// Optionally, clear a general cache if you have one |
| 554 |
wp_cache_delete('all_chat_sessions', 'mxchat_chat_sessions'); |
| 555 |
|
| 556 |
echo wp_json_encode(['success' => 'Selected chat sessions have been deleted.']); |
| 557 |
} else { |
| 558 |
echo wp_json_encode(['error' => 'No chat sessions selected for deletion.']); |
| 559 |
} |
| 560 |
|
| 561 |
wp_die(); |
| 562 |
} |
| 563 |
|
| 564 |
|
| 565 |
|
| 566 |
public function mxchat_fetch_chat_history() { |
| 567 |
global $wpdb; |
| 568 |
$table_name = $wpdb->prefix . 'mxchat_chat_transcripts'; |
| 569 |
|
| 570 |
// Check if the current user has sufficient permissions |
| 571 |
if (!current_user_can('manage_options')) { |
| 572 |
echo esc_html__('You do not have sufficient permissions to view this page.', 'mxchat'); |
| 573 |
wp_die(); |
| 574 |
} |
| 575 |
|
| 576 |
// Fetch chat transcripts from the database, ordered by timestamp |
| 577 |
$chat_transcripts = $wpdb->get_results( |
| 578 |
$wpdb->prepare("SELECT * FROM {$table_name} ORDER BY timestamp ASC") |
| 579 |
); |
| 580 |
|
| 581 |
// If no transcripts are available, display a message |
| 582 |
if (empty($chat_transcripts)) { |
| 583 |
echo esc_html__('No chat history available.', 'mxchat'); |
| 584 |
wp_die(); |
| 585 |
} |
| 586 |
|
| 587 |
ob_start(); |
| 588 |
$current_session_id = ''; |
| 589 |
|
| 590 |
foreach ($chat_transcripts as $transcript) { |
| 591 |
// Start a new session block if session ID changes |
| 592 |
if ($current_session_id !== $transcript->session_id) { |
| 593 |
if ($current_session_id !== '') { |
| 594 |
echo '</div>'; // Close the previous session block |
| 595 |
} |
| 596 |
$current_session_id = sanitize_text_field($transcript->session_id); |
| 597 |
echo '<div class="chat-session">'; |
| 598 |
echo '<h4><input type="checkbox" name="delete_session_ids[]" value="' . esc_attr($transcript->session_id) . '"> ' . esc_html__('Session ID:', 'mxchat') . ' ' . esc_html($current_session_id) . '</h4>'; |
| 599 |
} |
| 600 |
|
| 601 |
// Format the timestamp for display |
| 602 |
$formatted_timestamp = date_i18n('F j, Y g:i a', strtotime($transcript->timestamp)); |
| 603 |
|
| 604 |
// Determine the role to display (user identifier or email for users, bot for the AI) |
| 605 |
$role = $transcript->role; |
| 606 |
if ($role === 'user') { |
| 607 |
$role = !empty($transcript->user_email) ? sanitize_email($transcript->user_email) : sanitize_text_field($transcript->user_identifier); |
| 608 |
} |
| 609 |
|
| 610 |
// Output the chat message |
| 611 |
echo '<div class="chat-message">'; |
| 612 |
echo '<strong>' . esc_html($role) . ' (' . esc_html($formatted_timestamp) . '):</strong> '; |
| 613 |
echo wp_kses_post($transcript->message); |
| 614 |
echo '</div>'; |
| 615 |
} |
| 616 |
|
| 617 |
// Close the final session block |
| 618 |
echo '</div>'; |
| 619 |
|
| 620 |
$output = ob_get_clean(); |
| 621 |
|
| 622 |
echo $output; |
| 623 |
wp_die(); |
| 624 |
} |
| 625 |
|
| 626 |
|
| 627 |
public function mxchat_create_activation_page() { |
| 628 |
$license_status = get_option('mxchat_license_status', 'inactive'); |
| 629 |
$license_error = get_option('mxchat_license_error', ''); |
| 630 |
|
| 631 |
?> |
| 632 |
<div class="wrap mxchat-admin"> |
| 633 |
<h2>MxChat Pro: Activation</h2> |
| 634 |
<?php if ($license_status === 'inactive' && !empty($license_error)): ?> |
| 635 |
<div class="error notice"> |
| 636 |
<p><?php echo esc_html($license_error); ?></p> |
| 637 |
</div> |
| 638 |
<?php endif; ?> |
| 639 |
<form id="mxchat-activation-form"> |
| 640 |
<table class="form-table"> |
| 641 |
<tr valign="top"> |
| 642 |
<th scope="row">Email Address</th> |
| 643 |
<td> |
| 644 |
<input type="email" id="mxchat_pro_email" name="mxchat_pro_email" value="<?php echo esc_attr(get_option('mxchat_pro_email')); ?>" class="regular-text" /> |
| 645 |
</td> |
| 646 |
</tr> |
| 647 |
<tr valign="top"> |
| 648 |
<th scope="row">Activation Key</th> |
| 649 |
<td> |
| 650 |
<input type="text" id="mxchat_activation_key" name="mxchat_activation_key" value="<?php echo esc_attr(get_option('mxchat_activation_key')); ?>" class="regular-text" /> |
| 651 |
</td> |
| 652 |
</tr> |
| 653 |
</table> |
| 654 |
<?php if ($license_status !== 'active'): ?> |
| 655 |
<?php submit_button('Activate License', 'primary', 'activate_license'); ?> |
| 656 |
<?php else: ?> |
| 657 |
<h3>MxChat Pro</h3> |
| 658 |
<?php endif; ?> |
| 659 |
</form> |
| 660 |
<h3>License Status: <span id="mxchat-license-status"><?php echo $license_status === 'active' ? 'Active' : 'Inactive'; ?></span></h3> |
| 661 |
</div> |
| 662 |
<?php |
| 663 |
} |
| 664 |
|
| 665 |
|
| 666 |
|
| 667 |
public function mxchat_page_init() { |
| 668 |
// Register settings |
| 669 |
register_setting( |
| 670 |
'mxchat_option_group', |
| 671 |
'mxchat_options', |
| 672 |
array($this, 'mxchat_sanitize') |
| 673 |
); |
| 674 |
|
| 675 |
// Chatbot Settings Section |
| 676 |
add_settings_section( |
| 677 |
'mxchat_chatbot_section', |
| 678 |
'Chatbot Settings', |
| 679 |
null, |
| 680 |
'mxchat-chatbot' |
| 681 |
); |
| 682 |
|
| 683 |
// Registering fields for the Chatbot Settings section |
| 684 |
add_settings_field( |
| 685 |
'api_key', |
| 686 |
'API Key', |
| 687 |
array($this, 'api_key_callback'), |
| 688 |
'mxchat-chatbot', |
| 689 |
'mxchat_chatbot_section' |
| 690 |
); |
| 691 |
|
| 692 |
add_settings_field( |
| 693 |
'system_prompt_instructions', |
| 694 |
'AI Instructions', |
| 695 |
array($this, 'system_prompt_instructions_callback'), |
| 696 |
'mxchat-chatbot', |
| 697 |
'mxchat_chatbot_section' |
| 698 |
); |
| 699 |
|
| 700 |
add_settings_field( |
| 701 |
'model', |
| 702 |
'Model', |
| 703 |
array($this, 'mxchat_model_callback'), |
| 704 |
'mxchat-chatbot', |
| 705 |
'mxchat_chatbot_section' |
| 706 |
); |
| 707 |
|
| 708 |
add_settings_field( |
| 709 |
'top_bar_title', |
| 710 |
'Top Bar Title', |
| 711 |
array($this, 'mxchat_top_bar_title_callback'), |
| 712 |
'mxchat-chatbot', |
| 713 |
'mxchat_chatbot_section' |
| 714 |
); |
| 715 |
|
| 716 |
add_settings_field( |
| 717 |
'intro_message', |
| 718 |
'Introductory Message', |
| 719 |
array($this, 'mxchat_intro_message_callback'), |
| 720 |
'mxchat-chatbot', |
| 721 |
'mxchat_chatbot_section' |
| 722 |
); |
| 723 |
|
| 724 |
add_settings_field( |
| 725 |
'rate_limit', |
| 726 |
'Rate Limit', |
| 727 |
array($this, 'mxchat_rate_limit_callback'), |
| 728 |
'mxchat-chatbot', |
| 729 |
'mxchat_chatbot_section' |
| 730 |
); |
| 731 |
|
| 732 |
add_settings_field( |
| 733 |
'rate_limit_message', |
| 734 |
'Rate Limit Message', |
| 735 |
array($this, 'mxchat_rate_limit_message_callback'), |
| 736 |
'mxchat-chatbot', |
| 737 |
'mxchat_chatbot_section' |
| 738 |
); |
| 739 |
|
| 740 |
add_settings_field( |
| 741 |
'pre_chat_message', |
| 742 |
'Pre-Chat Message', |
| 743 |
array($this, 'mxchat_pre_chat_message_callback'), |
| 744 |
'mxchat-chatbot', |
| 745 |
'mxchat_chatbot_section' |
| 746 |
); |
| 747 |
|
| 748 |
add_settings_field( |
| 749 |
'append_to_body', |
| 750 |
'Append Chat Widget to Body', |
| 751 |
array($this, 'mxchat_append_to_body_callback'), |
| 752 |
'mxchat-chatbot', |
| 753 |
'mxchat_chatbot_section' |
| 754 |
); |
| 755 |
|
| 756 |
// Embed Settings Section |
| 757 |
add_settings_section( |
| 758 |
'mxchat_embed_section', |
| 759 |
'Embed Settings', |
| 760 |
null, |
| 761 |
'mxchat-embed' |
| 762 |
); |
| 763 |
|
| 764 |
add_settings_field( |
| 765 |
'enable_woocommerce_integration', |
| 766 |
'Enable WooCommerce Integration', |
| 767 |
array($this, 'mxchat_enable_woocommerce_integration_callback'), |
| 768 |
'mxchat-embed', |
| 769 |
'mxchat_embed_section' |
| 770 |
); |
| 771 |
|
| 772 |
add_settings_field( |
| 773 |
'woocommerce_consumer_key', |
| 774 |
'WooCommerce Consumer Key', |
| 775 |
array($this, 'mxchat_woocommerce_consumer_key_callback'), |
| 776 |
'mxchat-embed', |
| 777 |
'mxchat_embed_section' |
| 778 |
); |
| 779 |
|
| 780 |
add_settings_field( |
| 781 |
'woocommerce_consumer_secret', |
| 782 |
'WooCommerce Consumer Secret', |
| 783 |
array($this, 'mxchat_woocommerce_consumer_secret_callback'), |
| 784 |
'mxchat-embed', |
| 785 |
'mxchat_embed_section' |
| 786 |
); |
| 787 |
|
| 788 |
// Theme Settings Section |
| 789 |
add_settings_section( |
| 790 |
'mxchat_theme_section', |
| 791 |
'Theme Settings', |
| 792 |
null, |
| 793 |
'mxchat-theme' |
| 794 |
); |
| 795 |
|
| 796 |
add_settings_field( |
| 797 |
'close_button_color', |
| 798 |
'Close Button & Title Color', |
| 799 |
array($this, 'mxchat_close_button_color_callback'), |
| 800 |
'mxchat-theme', |
| 801 |
'mxchat_theme_section' |
| 802 |
); |
| 803 |
|
| 804 |
add_settings_field( |
| 805 |
'chatbot_bg_color', |
| 806 |
'Chatbot Background Color', |
| 807 |
array($this, 'mxchat_chatbot_bg_color_callback'), |
| 808 |
'mxchat-theme', |
| 809 |
'mxchat_theme_section' |
| 810 |
); |
| 811 |
|
| 812 |
add_settings_field( |
| 813 |
'user_message_bg_color', |
| 814 |
'User Message Background Color', |
| 815 |
array($this, 'mxchat_user_message_bg_color_callback'), |
| 816 |
'mxchat-theme', |
| 817 |
'mxchat_theme_section' |
| 818 |
); |
| 819 |
|
| 820 |
add_settings_field( |
| 821 |
'user_message_font_color', |
| 822 |
'User Message Font Color', |
| 823 |
array($this, 'mxchat_user_message_font_color_callback'), |
| 824 |
'mxchat-theme', |
| 825 |
'mxchat_theme_section' |
| 826 |
); |
| 827 |
|
| 828 |
add_settings_field( |
| 829 |
'bot_message_bg_color', |
| 830 |
'Bot Message Background Color', |
| 831 |
array($this, 'mxchat_bot_message_bg_color_callback'), |
| 832 |
'mxchat-theme', |
| 833 |
'mxchat_theme_section' |
| 834 |
); |
| 835 |
|
| 836 |
add_settings_field( |
| 837 |
'bot_message_font_color', |
| 838 |
'Bot Message Font Color', |
| 839 |
array($this, 'mxchat_bot_message_font_color_callback'), |
| 840 |
'mxchat-theme', |
| 841 |
'mxchat_theme_section' |
| 842 |
); |
| 843 |
|
| 844 |
add_settings_field( |
| 845 |
'top_bar_bg_color', |
| 846 |
'Top Bar Background Color', |
| 847 |
array($this, 'mxchat_top_bar_bg_color_callback'), |
| 848 |
'mxchat-theme', |
| 849 |
'mxchat_theme_section' |
| 850 |
); |
| 851 |
|
| 852 |
add_settings_field( |
| 853 |
'send_button_font_color', |
| 854 |
'Send Button Color', |
| 855 |
array($this, 'mxchat_send_button_font_color_callback'), |
| 856 |
'mxchat-theme', |
| 857 |
'mxchat_theme_section' |
| 858 |
); |
| 859 |
|
| 860 |
add_settings_field( |
| 861 |
'chat_input_font_color', |
| 862 |
'Chat Input Font Color', |
| 863 |
array($this, 'mxchat_chat_input_font_color_callback'), |
| 864 |
'mxchat-theme', |
| 865 |
'mxchat_theme_section' |
| 866 |
); |
| 867 |
|
| 868 |
add_settings_field( |
| 869 |
'chatbot_background_color', |
| 870 |
'Floating Widget Background Color', |
| 871 |
array($this, 'mxchat_chatbot_background_color_callback'), |
| 872 |
'mxchat-theme', |
| 873 |
'mxchat_theme_section' |
| 874 |
); |
| 875 |
|
| 876 |
add_settings_field( |
| 877 |
'icon_color', |
| 878 |
'Chatbot Icon Color', |
| 879 |
array($this, 'mxchat_icon_color_callback'), |
| 880 |
'mxchat-theme', |
| 881 |
'mxchat_theme_section' |
| 882 |
); |
| 883 |
|
| 884 |
// General Settings Section |
| 885 |
add_settings_section( |
| 886 |
'mxchat_general_section', |
| 887 |
'General Information', |
| 888 |
null, |
| 889 |
'mxchat-general' |
| 890 |
); |
| 891 |
|
| 892 |
|
| 893 |
} |
| 894 |
|
| 895 |
|
| 896 |
|
| 897 |
|
| 898 |
public function mxchat_handle_activate_license() { |
| 899 |
check_ajax_referer('mxchat_activate_license_nonce', 'security'); |
| 900 |
|
| 901 |
$license_key = isset($_POST['key']) ? sanitize_text_field($_POST['key']) : ''; |
| 902 |
$customer_email = isset($_POST['email']) ? sanitize_email($_POST['email']) : ''; |
| 903 |
|
| 904 |
if (empty($license_key) || empty($customer_email)) { |
| 905 |
wp_send_json_error('Email or License Key is missing'); |
| 906 |
} |
| 907 |
|
| 908 |
$product_id = 'MxChatPRO'; |
| 909 |
|
| 910 |
$response = wp_remote_get("http://mxchat.ai/?wc-api=software-api&request=activation&email={$customer_email}&license_key={$license_key}&product_id={$product_id}"); |
| 911 |
|
| 912 |
if (is_wp_error($response)) { |
| 913 |
wp_send_json_error('Activation failed due to a server error'); |
| 914 |
} |
| 915 |
|
| 916 |
$body = wp_remote_retrieve_body($response); |
| 917 |
$data = json_decode($body); |
| 918 |
|
| 919 |
if ($data && isset($data->activated) && $data->activated) { |
| 920 |
update_option('mxchat_license_status', 'active'); |
| 921 |
wp_send_json_success(); |
| 922 |
} else { |
| 923 |
$error_message = isset($data->error) ? $data->error : 'Activation failed'; |
| 924 |
update_option('mxchat_license_status', 'inactive'); |
| 925 |
update_option('mxchat_license_error', $error_message); |
| 926 |
wp_send_json_error($error_message); |
| 927 |
} |
| 928 |
} |
| 929 |
|
| 930 |
|
| 931 |
public function mxchat_rate_limit_callback() { |
| 932 |
$rate_limits = array('5', '10', '15', '20', '100'); |
| 933 |
$selected_rate_limit = isset($this->options['rate_limit']) ? $this->options['rate_limit'] : '100'; |
| 934 |
|
| 935 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 936 |
$class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; |
| 937 |
|
| 938 |
echo '<div class="' . esc_attr($class) . '">'; |
| 939 |
echo '<select id="rate_limit" name="mxchat_options[rate_limit]" ' . $disabled . '>'; |
| 940 |
foreach ($rate_limits as $limit) { |
| 941 |
echo '<option value="' . esc_attr($limit) . '" ' . selected($selected_rate_limit, $limit, false) . '>' . esc_html($limit) . '</option>'; |
| 942 |
} |
| 943 |
echo '</select>'; |
| 944 |
|
| 945 |
if (!$this->is_activated) { |
| 946 |
echo '<div class="pro-feature-overlay">'; |
| 947 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 948 |
echo '</div>'; |
| 949 |
} |
| 950 |
|
| 951 |
echo '</div>'; |
| 952 |
} |
| 953 |
|
| 954 |
public function mxchat_rate_limit_message_callback() { |
| 955 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 956 |
$class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; |
| 957 |
|
| 958 |
echo '<div class="' . esc_attr($class) . '">'; |
| 959 |
printf( |
| 960 |
'<textarea id="rate_limit_message" name="mxchat_options[rate_limit_message]" rows="3" cols="50" %s>%s</textarea>', |
| 961 |
esc_attr($disabled), |
| 962 |
isset($this->options['rate_limit_message']) ? esc_textarea($this->options['rate_limit_message']) : 'Rate limit exceeded. Please try again later.' |
| 963 |
); |
| 964 |
|
| 965 |
if (!$this->is_activated) { |
| 966 |
echo '<div class="pro-feature-overlay">'; |
| 967 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 968 |
echo '</div>'; |
| 969 |
} |
| 970 |
|
| 971 |
echo '</div>'; |
| 972 |
} |
| 973 |
|
| 974 |
|
| 975 |
public function mxchat_enable_woocommerce_integration_callback() { |
| 976 |
$checked = isset($this->options['enable_woocommerce_integration']) && $this->options['enable_woocommerce_integration'] === '1' ? 'checked' : ''; |
| 977 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 978 |
$class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; |
| 979 |
|
| 980 |
echo '<div class="' . esc_attr($class) . '">'; |
| 981 |
echo '<label class="toggle-switch">'; |
| 982 |
echo '<input type="checkbox" id="enable_woocommerce_integration" name="mxchat_options[enable_woocommerce_integration]" value="1" ' . $checked . ' ' . $disabled . '>'; |
| 983 |
echo '<span class="slider"></span>'; |
| 984 |
echo '</label>'; |
| 985 |
|
| 986 |
if (!$this->is_activated) { |
| 987 |
echo '<div class="pro-feature-overlay">'; |
| 988 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 989 |
echo '</div>'; |
| 990 |
} |
| 991 |
|
| 992 |
echo '</div>'; |
| 993 |
} |
| 994 |
|
| 995 |
|
| 996 |
private function mxchat_add_option_field($id, $title, $callback = '') { |
| 997 |
add_settings_field( |
| 998 |
$id, |
| 999 |
$title, |
| 1000 |
$callback ? array($this, $callback) : array($this, $id . '_callback'), |
| 1001 |
'mxchat-max', |
| 1002 |
'mxchat_setting_section_id', |
| 1003 |
$id === 'model' ? ['label_for' => 'model'] : [] |
| 1004 |
); |
| 1005 |
} |
| 1006 |
|
| 1007 |
// Callback for API Key input |
| 1008 |
public function api_key_callback() { |
| 1009 |
printf( |
| 1010 |
'<input type="text" id="api_key" name="mxchat_options[api_key]" value="%s" class="regular-text" />', |
| 1011 |
isset($this->options['api_key']) ? esc_attr($this->options['api_key']) : '' |
| 1012 |
); |
| 1013 |
} |
| 1014 |
|
| 1015 |
|
| 1016 |
|
| 1017 |
public function mxchat_woocommerce_consumer_key_callback() { |
| 1018 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1019 |
$class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; |
| 1020 |
|
| 1021 |
echo '<div class="' . esc_attr($class) . '">'; |
| 1022 |
printf( |
| 1023 |
'<input type="text" id="woocommerce_consumer_key" name="mxchat_options[woocommerce_consumer_key]" value="%s" class="regular-text" %s />', |
| 1024 |
isset($this->options['woocommerce_consumer_key']) ? esc_attr($this->options['woocommerce_consumer_key']) : '', |
| 1025 |
$disabled |
| 1026 |
); |
| 1027 |
|
| 1028 |
if (!$this->is_activated) { |
| 1029 |
echo '<div class="pro-feature-overlay">'; |
| 1030 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1031 |
echo '</div>'; |
| 1032 |
} |
| 1033 |
|
| 1034 |
echo '</div>'; |
| 1035 |
} |
| 1036 |
|
| 1037 |
public function mxchat_woocommerce_consumer_secret_callback() { |
| 1038 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1039 |
$class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; |
| 1040 |
|
| 1041 |
echo '<div class="' . esc_attr($class) . '">'; |
| 1042 |
printf( |
| 1043 |
'<input type="text" id="woocommerce_consumer_secret" name="mxchat_options[woocommerce_consumer_secret]" value="%s" class="regular-text" %s />', |
| 1044 |
isset($this->options['woocommerce_consumer_secret']) ? esc_attr($this->options['woocommerce_consumer_secret']) : '', |
| 1045 |
$disabled |
| 1046 |
); |
| 1047 |
|
| 1048 |
if (!$this->is_activated) { |
| 1049 |
echo '<div class="pro-feature-overlay">'; |
| 1050 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1051 |
echo '</div>'; |
| 1052 |
} |
| 1053 |
|
| 1054 |
echo '</div>'; |
| 1055 |
} |
| 1056 |
|
| 1057 |
|
| 1058 |
public function mxchat_pre_chat_message_callback() { |
| 1059 |
printf( |
| 1060 |
'<textarea id="pre_chat_message" name="mxchat_options[pre_chat_message]" rows="5" cols="50">%s</textarea>', |
| 1061 |
isset($this->options['pre_chat_message']) ? esc_textarea($this->options['pre_chat_message']) : '' |
| 1062 |
); |
| 1063 |
} |
| 1064 |
|
| 1065 |
// Callback for AI Instructions textarea |
| 1066 |
public function system_prompt_instructions_callback() { |
| 1067 |
printf( |
| 1068 |
'<textarea id="system_prompt_instructions" name="mxchat_options[system_prompt_instructions]" rows="5" cols="50">%s</textarea>', |
| 1069 |
isset($this->options['system_prompt_instructions']) ? esc_textarea($this->options['system_prompt_instructions']) : '' |
| 1070 |
); |
| 1071 |
} |
| 1072 |
|
| 1073 |
public function mxchat_model_callback() { |
| 1074 |
$models = array( |
| 1075 |
'gpt-4o' => 'gpt-4o', |
| 1076 |
'gpt-4o-mini' => 'gpt-4o-mini', |
| 1077 |
'gpt-4-turbo' => 'gpt-4-turbo', |
| 1078 |
'gpt-4' => 'gpt-4', |
| 1079 |
'gpt-3.5-turbo' => 'gpt-3.5-turbo', |
| 1080 |
); |
| 1081 |
|
| 1082 |
$selected_model = isset($this->options['model']) ? $this->options['model'] : 'gpt-3.5-turbo'; |
| 1083 |
|
| 1084 |
echo '<select id="model" name="mxchat_options[model]">'; |
| 1085 |
foreach ($models as $model_value => $model_label) { |
| 1086 |
echo '<option value="' . esc_attr($model_value) . '" ' . selected($selected_model, $model_value, false) . '>' . esc_html($model_label) . '</option>'; |
| 1087 |
} |
| 1088 |
echo '</select>'; |
| 1089 |
} |
| 1090 |
|
| 1091 |
public function mxchat_top_bar_title_callback() { |
| 1092 |
printf( |
| 1093 |
'<input type="text" id="top_bar_title" name="mxchat_options[top_bar_title]" value="%s" />', |
| 1094 |
isset($this->options['top_bar_title']) ? esc_attr($this->options['top_bar_title']) : '' |
| 1095 |
); |
| 1096 |
} |
| 1097 |
|
| 1098 |
public function mxchat_intro_message_callback() { |
| 1099 |
printf( |
| 1100 |
'<textarea id="intro_message" name="mxchat_options[intro_message]" rows="5" cols="50">%s</textarea>', |
| 1101 |
isset($this->options['intro_message']) ? esc_textarea($this->options['intro_message']) : 'Hello! How can I assist you today?' |
| 1102 |
); |
| 1103 |
} |
| 1104 |
|
| 1105 |
|
| 1106 |
|
| 1107 |
|
| 1108 |
|
| 1109 |
public function mxchat_close_button_color_callback() { |
| 1110 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1111 |
|
| 1112 |
echo '<div class="pro-feature-wrapper">'; |
| 1113 |
printf( |
| 1114 |
'<input type="text" id="close_button_color" name="mxchat_options[close_button_color]" value="%s" class="my-color-field" data-default-color="#4a4a4a" %s />', |
| 1115 |
isset($this->options['close_button_color']) ? esc_attr($this->options['close_button_color']) : '', |
| 1116 |
esc_attr($disabled) |
| 1117 |
); |
| 1118 |
|
| 1119 |
if (!$this->is_activated) { |
| 1120 |
echo '<div class="pro-feature-overlay">'; |
| 1121 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1122 |
echo '</div>'; |
| 1123 |
} |
| 1124 |
|
| 1125 |
echo '</div>'; |
| 1126 |
} |
| 1127 |
|
| 1128 |
public function mxchat_chatbot_bg_color_callback() { |
| 1129 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1130 |
|
| 1131 |
echo '<div class="pro-feature-wrapper">'; |
| 1132 |
printf( |
| 1133 |
'<input type="text" id="chatbot_bg_color" name="mxchat_options[chatbot_bg_color]" value="%s" class="my-color-field" data-default-color="#f9f9f9" %s />', |
| 1134 |
isset($this->options['chatbot_bg_color']) ? esc_attr($this->options['chatbot_bg_color']) : '', |
| 1135 |
esc_attr($disabled) |
| 1136 |
); |
| 1137 |
|
| 1138 |
if (!$this->is_activated) { |
| 1139 |
echo '<div class="pro-feature-overlay">'; |
| 1140 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1141 |
echo '</div>'; |
| 1142 |
} |
| 1143 |
|
| 1144 |
echo '</div>'; |
| 1145 |
} |
| 1146 |
|
| 1147 |
public function mxchat_user_message_bg_color_callback() { |
| 1148 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1149 |
|
| 1150 |
echo '<div class="pro-feature-wrapper">'; |
| 1151 |
printf( |
| 1152 |
'<input type="text" id="user_message_bg_color" name="mxchat_options[user_message_bg_color]" value="%s" class="my-color-field" data-default-color="#0078d7" %s />', |
| 1153 |
isset($this->options['user_message_bg_color']) ? esc_attr($this->options['user_message_bg_color']) : '', |
| 1154 |
esc_attr($disabled) |
| 1155 |
); |
| 1156 |
|
| 1157 |
if (!$this->is_activated) { |
| 1158 |
echo '<div class="pro-feature-overlay">'; |
| 1159 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1160 |
echo '</div>'; |
| 1161 |
} |
| 1162 |
|
| 1163 |
echo '</div>'; |
| 1164 |
} |
| 1165 |
|
| 1166 |
public function mxchat_user_message_font_color_callback() { |
| 1167 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1168 |
|
| 1169 |
echo '<div class="pro-feature-wrapper">'; |
| 1170 |
printf( |
| 1171 |
'<input type="text" id="user_message_font_color" name="mxchat_options[user_message_font_color]" value="%s" class="my-color-field" data-default-color="#ffffff" %s />', |
| 1172 |
isset($this->options['user_message_font_color']) ? esc_attr($this->options['user_message_font_color']) : '', |
| 1173 |
esc_attr($disabled) |
| 1174 |
); |
| 1175 |
|
| 1176 |
if (!$this->is_activated) { |
| 1177 |
echo '<div class="pro-feature-overlay">'; |
| 1178 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1179 |
echo '</div>'; |
| 1180 |
} |
| 1181 |
|
| 1182 |
echo '</div>'; |
| 1183 |
} |
| 1184 |
|
| 1185 |
public function mxchat_bot_message_bg_color_callback() { |
| 1186 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1187 |
|
| 1188 |
echo '<div class="pro-feature-wrapper">'; |
| 1189 |
printf( |
| 1190 |
'<input type="text" id="bot_message_bg_color" name="mxchat_options[bot_message_bg_color]" value="%s" class="my-color-field" data-default-color="#e1e1e1" %s />', |
| 1191 |
isset($this->options['bot_message_bg_color']) ? esc_attr($this->options['bot_message_bg_color']) : '', |
| 1192 |
esc_attr($disabled) |
| 1193 |
); |
| 1194 |
|
| 1195 |
if (!$this->is_activated) { |
| 1196 |
echo '<div class="pro-feature-overlay">'; |
| 1197 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1198 |
echo '</div>'; |
| 1199 |
} |
| 1200 |
|
| 1201 |
echo '</div>'; |
| 1202 |
} |
| 1203 |
|
| 1204 |
public function mxchat_bot_message_font_color_callback() { |
| 1205 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1206 |
|
| 1207 |
echo '<div class="pro-feature-wrapper">'; |
| 1208 |
printf( |
| 1209 |
'<input type="text" id="bot_message_font_color" name="mxchat_options[bot_message_font_color]" value="%s" class="my-color-field" data-default-color="#333333" %s />', |
| 1210 |
isset($this->options['bot_message_font_color']) ? esc_attr($this->options['bot_message_font_color']) : '', |
| 1211 |
esc_attr($disabled) |
| 1212 |
); |
| 1213 |
|
| 1214 |
if (!$this->is_activated) { |
| 1215 |
echo '<div class="pro-feature-overlay">'; |
| 1216 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1217 |
echo '</div>'; |
| 1218 |
} |
| 1219 |
|
| 1220 |
echo '</div>'; |
| 1221 |
} |
| 1222 |
|
| 1223 |
public function mxchat_top_bar_bg_color_callback() { |
| 1224 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1225 |
|
| 1226 |
echo '<div class="pro-feature-wrapper">'; |
| 1227 |
printf( |
| 1228 |
'<input type="text" id="top_bar_bg_color" name="mxchat_options[top_bar_bg_color]" value="%s" class="my-color-field" data-default-color="#00b294" %s />', |
| 1229 |
isset($this->options['top_bar_bg_color']) ? esc_attr($this->options['top_bar_bg_color']) : '', |
| 1230 |
esc_attr($disabled) |
| 1231 |
); |
| 1232 |
|
| 1233 |
if (!$this->is_activated) { |
| 1234 |
echo '<div class="pro-feature-overlay">'; |
| 1235 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1236 |
echo '</div>'; |
| 1237 |
} |
| 1238 |
|
| 1239 |
echo '</div>'; |
| 1240 |
} |
| 1241 |
|
| 1242 |
public function mxchat_send_button_font_color_callback() { |
| 1243 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1244 |
|
| 1245 |
echo '<div class="pro-feature-wrapper">'; |
| 1246 |
printf( |
| 1247 |
'<input type="text" id="send_button_font_color" name="mxchat_options[send_button_font_color]" value="%s" class="my-color-field" data-default-color="#ffffff" %s />', |
| 1248 |
isset($this->options['send_button_font_color']) ? esc_attr($this->options['send_button_font_color']) : '', |
| 1249 |
esc_attr($disabled) |
| 1250 |
); |
| 1251 |
|
| 1252 |
if (!$this->is_activated) { |
| 1253 |
echo '<div class="pro-feature-overlay">'; |
| 1254 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1255 |
echo '</div>'; |
| 1256 |
} |
| 1257 |
|
| 1258 |
echo '</div>'; |
| 1259 |
} |
| 1260 |
|
| 1261 |
public function mxchat_chatbot_background_color_callback() { |
| 1262 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1263 |
|
| 1264 |
echo '<div class="pro-feature-wrapper">'; |
| 1265 |
printf( |
| 1266 |
'<input type="text" id="chatbot_background_color" name="mxchat_options[chatbot_background_color]" value="%s" class="my-color-field" data-default-color="#000000" %s />', |
| 1267 |
isset($this->options['chatbot_background_color']) ? esc_attr($this->options['chatbot_background_color']) : '', |
| 1268 |
esc_attr($disabled) |
| 1269 |
); |
| 1270 |
|
| 1271 |
if (!$this->is_activated) { |
| 1272 |
echo '<div class="pro-feature-overlay">'; |
| 1273 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1274 |
echo '</div>'; |
| 1275 |
} |
| 1276 |
|
| 1277 |
echo '</div>'; |
| 1278 |
} |
| 1279 |
|
| 1280 |
public function mxchat_icon_color_callback() { |
| 1281 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1282 |
|
| 1283 |
echo '<div class="pro-feature-wrapper">'; |
| 1284 |
printf( |
| 1285 |
'<input type="text" id="icon_color" name="mxchat_options[icon_color]" value="%s" class="my-color-field" data-default-color="#ffffff" %s />', |
| 1286 |
isset($this->options['icon_color']) ? esc_attr($this->options['icon_color']) : '', |
| 1287 |
esc_attr($disabled) |
| 1288 |
); |
| 1289 |
|
| 1290 |
if (!$this->is_activated) { |
| 1291 |
echo '<div class="pro-feature-overlay">'; |
| 1292 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1293 |
echo '</div>'; |
| 1294 |
} |
| 1295 |
|
| 1296 |
echo '</div>'; |
| 1297 |
} |
| 1298 |
|
| 1299 |
public function mxchat_chat_input_font_color_callback() { |
| 1300 |
$disabled = $this->is_activated ? '' : 'disabled'; |
| 1301 |
|
| 1302 |
echo '<div class="pro-feature-wrapper">'; |
| 1303 |
printf( |
| 1304 |
'<input type="text" id="chat_input_font_color" name="mxchat_options[chat_input_font_color]" value="%s" class="my-color-field" data-default-color="#555555" %s />', |
| 1305 |
isset($this->options['chat_input_font_color']) ? esc_attr($this->options['chat_input_font_color']) : '', |
| 1306 |
esc_attr($disabled) |
| 1307 |
); |
| 1308 |
|
| 1309 |
if (!$this->is_activated) { |
| 1310 |
echo '<div class="pro-feature-overlay">'; |
| 1311 |
echo '<a href="https://mxchat.ai/" target="_blank"><img src="' . plugin_dir_url(__FILE__) . '../images/pro-only-dark.png" alt="Pro Only" /></a>'; |
| 1312 |
echo '</div>'; |
| 1313 |
} |
| 1314 |
|
| 1315 |
echo '</div>'; |
| 1316 |
} |
| 1317 |
|
| 1318 |
|
| 1319 |
public function mxchat_append_to_body_callback() { |
| 1320 |
$append_to_body_checked = isset($this->options['append_to_body']) && $this->options['append_to_body'] === 'on' ? 'checked' : ''; |
| 1321 |
echo '<label class="toggle-switch-label" for="append_to_body">Append Chat Widget to Body:</label>'; |
| 1322 |
echo '<label class="toggle-switch">'; |
| 1323 |
printf( |
| 1324 |
'<input type="checkbox" id="append_to_body" name="mxchat_options[append_to_body]" %s />', |
| 1325 |
esc_attr($append_to_body_checked) |
| 1326 |
); |
| 1327 |
echo '<span class="slider"></span>'; |
| 1328 |
echo '</label>'; |
| 1329 |
echo '<p class="description">Enable to append the chat widget directly to the body element or use shortcode: [mxchat_chatbot floating="yes"]</p>'; |
| 1330 |
} |
| 1331 |
|
| 1332 |
|
| 1333 |
|
| 1334 |
|
| 1335 |
|
| 1336 |
public function mxchat_enqueue_admin_assets() { |
| 1337 |
wp_enqueue_style('wp-color-picker'); |
| 1338 |
|
| 1339 |
// Get the plugin version or file modification time for cache busting |
| 1340 |
$plugin_version = '1.0.8'; // Replace this with your plugin's version |
| 1341 |
|
| 1342 |
// File paths |
| 1343 |
$color_picker_js_path = plugin_dir_path(__FILE__) . '../js/my-color-picker.js'; |
| 1344 |
$embedding_check_js_path = plugin_dir_path(__FILE__) . '../js/embedding-check.js'; |
| 1345 |
$admin_css_path = plugin_dir_path(__FILE__) . '../css/admin-style.css'; |
| 1346 |
$transcripts_js_path = plugin_dir_path(__FILE__) . '../js/mxchat_transcripts.js'; |
| 1347 |
|
| 1348 |
// Check if files exist and get modification times |
| 1349 |
$color_picker_version = file_exists($color_picker_js_path) ? filemtime($color_picker_js_path) : $plugin_version; |
| 1350 |
$embedding_check_version = file_exists($embedding_check_js_path) ? filemtime($embedding_check_js_path) : $plugin_version; |
| 1351 |
$admin_css_version = file_exists($admin_css_path) ? filemtime($admin_css_path) : $plugin_version; |
| 1352 |
$transcripts_js_version = file_exists($transcripts_js_path) ? filemtime($transcripts_js_path) : $plugin_version; |
| 1353 |
|
| 1354 |
// Enqueue scripts and styles with corrected paths |
| 1355 |
wp_enqueue_script( |
| 1356 |
'mxchat-color-picker', |
| 1357 |
plugin_dir_url(__FILE__) . '../js/my-color-picker.js', |
| 1358 |
array('wp-color-picker'), |
| 1359 |
$color_picker_version, |
| 1360 |
true |
| 1361 |
); |
| 1362 |
|
| 1363 |
wp_enqueue_script( |
| 1364 |
'mxchat-embedding-check', |
| 1365 |
plugin_dir_url(__FILE__) . '../js/embedding-check.js', |
| 1366 |
array(), |
| 1367 |
$embedding_check_version, |
| 1368 |
true |
| 1369 |
); |
| 1370 |
|
| 1371 |
wp_enqueue_script( |
| 1372 |
'mxchat-transcripts-js', |
| 1373 |
plugin_dir_url(__FILE__) . '../js/mxchat_transcripts.js', |
| 1374 |
array('jquery'), |
| 1375 |
$transcripts_js_version, |
| 1376 |
true |
| 1377 |
); |
| 1378 |
|
| 1379 |
wp_enqueue_script( |
| 1380 |
'mxchat-admin-js', |
| 1381 |
plugin_dir_url(__FILE__) . '../js/mxchat-admin.js', |
| 1382 |
array('jquery'), |
| 1383 |
$plugin_version, |
| 1384 |
true |
| 1385 |
); |
| 1386 |
|
| 1387 |
wp_localize_script('mxchat-admin-js', 'mxchatAdmin', array( |
| 1388 |
'ajax_url' => admin_url('admin-ajax.php'), |
| 1389 |
'nonce' => wp_create_nonce('mxchat_activate_license_nonce'), |
| 1390 |
)); |
| 1391 |
|
| 1392 |
wp_enqueue_style( |
| 1393 |
'mxchat-admin-css', |
| 1394 |
plugin_dir_url(__FILE__) . '../css/admin-style.css', |
| 1395 |
array(), |
| 1396 |
$admin_css_version |
| 1397 |
); |
| 1398 |
|
| 1399 |
// Use wp_json_encode for localizing script |
| 1400 |
wp_localize_script('mxchat-color-picker', 'mxchatStyleSettings', array( |
| 1401 |
'ajax_url' => admin_url('admin-ajax.php'), |
| 1402 |
'user_message_bg_color' => $this->options['user_message_bg_color'] ?? '#fff', |
| 1403 |
'user_message_font_color' => $this->options['user_message_font_color'] ?? '#212121', |
| 1404 |
'bot_message_bg_color' => $this->options['bot_message_bg_color'] ?? '#212121', |
| 1405 |
'bot_message_font_color' => $this->options['bot_message_font_color'] ?? '#fff', |
| 1406 |
'top_bar_bg_color' => $this->options['top_bar_bg_color'] ?? '#212121', |
| 1407 |
'send_button_font_color' => $this->options['send_button_font_color'] ?? '#212121', |
| 1408 |
'close_button_color' => $this->options['close_button_color'] ?? '#fff', |
| 1409 |
'chatbot_background_color' => $this->options['chatbot_background_color'] ?? '#212121', |
| 1410 |
'icon_color' => $this->options['icon_color'] ?? '#fff', |
| 1411 |
'chat_input_font_color' => $this->options['chat_input_font_color'] ?? '#212121' |
| 1412 |
)); |
| 1413 |
} |
| 1414 |
|
| 1415 |
public function mxchat_sanitize($input) { |
| 1416 |
$new_input = array(); |
| 1417 |
|
| 1418 |
if (isset($input['api_key'])) { |
| 1419 |
$new_input['api_key'] = sanitize_text_field($input['api_key']); |
| 1420 |
} |
| 1421 |
|
| 1422 |
if (isset($input['enable_woocommerce_integration'])) { |
| 1423 |
$new_input['enable_woocommerce_integration'] = isset($input['enable_woocommerce_integration']) && $input['enable_woocommerce_integration'] === '1' ? '1' : '0'; |
| 1424 |
|
| 1425 |
} |
| 1426 |
|
| 1427 |
if (isset($input['system_prompt_instructions'])) { |
| 1428 |
$new_input['system_prompt_instructions'] = sanitize_textarea_field($input['system_prompt_instructions']); |
| 1429 |
} |
| 1430 |
|
| 1431 |
if (isset($input['mxchat_pro_email'])) { |
| 1432 |
$new_input['mxchat_pro_email'] = sanitize_email($input['mxchat_pro_email']); |
| 1433 |
} |
| 1434 |
|
| 1435 |
if (isset($input['mxchat_activation_key'])) { |
| 1436 |
$new_input['mxchat_activation_key'] = sanitize_text_field($input['mxchat_activation_key']); |
| 1437 |
} |
| 1438 |
|
| 1439 |
if (isset($input['append_to_body'])) { |
| 1440 |
$new_input['append_to_body'] = $input['append_to_body'] === 'on' ? 'on' : 'off'; |
| 1441 |
} |
| 1442 |
|
| 1443 |
if (isset($input['top_bar_title'])) { |
| 1444 |
$new_input['top_bar_title'] = sanitize_text_field($input['top_bar_title']); |
| 1445 |
} |
| 1446 |
|
| 1447 |
if (isset($input['intro_message'])) { |
| 1448 |
$new_input['intro_message'] = sanitize_text_field($input['intro_message']); |
| 1449 |
} |
| 1450 |
|
| 1451 |
if (isset($input['rate_limit_message'])) { |
| 1452 |
$new_input['rate_limit_message'] = sanitize_text_field($input['rate_limit_message']); |
| 1453 |
} |
| 1454 |
|
| 1455 |
|
| 1456 |
if (isset($input['pre_chat_message'])) { |
| 1457 |
$new_input['pre_chat_message'] = sanitize_textarea_field($input['pre_chat_message']); |
| 1458 |
} |
| 1459 |
|
| 1460 |
if (isset($input['model'])) { |
| 1461 |
$allowed_models = array( |
| 1462 |
'gpt-4o', |
| 1463 |
'gpt-4o-mini', |
| 1464 |
'gpt-4-turbo', |
| 1465 |
'gpt-4', |
| 1466 |
'gpt-3.5-turbo', |
| 1467 |
); |
| 1468 |
if (in_array($input['model'], $allowed_models)) { |
| 1469 |
$new_input['model'] = sanitize_text_field($input['model']); |
| 1470 |
} |
| 1471 |
} |
| 1472 |
|
| 1473 |
// Sanitize new pro features |
| 1474 |
if (isset($input['close_button_color'])) { |
| 1475 |
$new_input['close_button_color'] = sanitize_hex_color($input['close_button_color']); |
| 1476 |
} |
| 1477 |
|
| 1478 |
if (isset($input['chatbot_bg_color'])) { |
| 1479 |
$new_input['chatbot_bg_color'] = sanitize_hex_color($input['chatbot_bg_color']); |
| 1480 |
} |
| 1481 |
|
| 1482 |
if (isset($input['woocommerce_consumer_key'])) { |
| 1483 |
$new_input['woocommerce_consumer_key'] = sanitize_text_field($input['woocommerce_consumer_key']); |
| 1484 |
} |
| 1485 |
|
| 1486 |
if (isset($input['woocommerce_consumer_secret'])) { |
| 1487 |
$new_input['woocommerce_consumer_secret'] = sanitize_text_field($input['woocommerce_consumer_secret']); |
| 1488 |
} |
| 1489 |
|
| 1490 |
if (isset($input['user_message_bg_color'])) { |
| 1491 |
$new_input['user_message_bg_color'] = sanitize_hex_color($input['user_message_bg_color']); |
| 1492 |
} |
| 1493 |
|
| 1494 |
if (isset($input['user_message_font_color'])) { |
| 1495 |
$new_input['user_message_font_color'] = sanitize_hex_color($input['user_message_font_color']); |
| 1496 |
} |
| 1497 |
|
| 1498 |
if (isset($input['bot_message_bg_color'])) { |
| 1499 |
$new_input['bot_message_bg_color'] = sanitize_hex_color($input['bot_message_bg_color']); |
| 1500 |
} |
| 1501 |
|
| 1502 |
if (isset($input['bot_message_font_color'])) { |
| 1503 |
$new_input['bot_message_font_color'] = sanitize_hex_color($input['bot_message_font_color']); |
| 1504 |
} |
| 1505 |
|
| 1506 |
if (isset($input['top_bar_bg_color'])) { |
| 1507 |
$new_input['top_bar_bg_color'] = sanitize_hex_color($input['top_bar_bg_color']); |
| 1508 |
} |
| 1509 |
|
| 1510 |
if (isset($input['send_button_font_color'])) { |
| 1511 |
$new_input['send_button_font_color'] = sanitize_hex_color($input['send_button_font_color']); |
| 1512 |
} |
| 1513 |
|
| 1514 |
if (isset($input['chatbot_background_color'])) { |
| 1515 |
$new_input['chatbot_background_color'] = sanitize_hex_color($input['chatbot_background_color']); |
| 1516 |
} |
| 1517 |
|
| 1518 |
if (isset($input['icon_color'])) { |
| 1519 |
$new_input['icon_color'] = sanitize_hex_color($input['icon_color']); |
| 1520 |
} |
| 1521 |
|
| 1522 |
if (isset($input['chat_input_font_color'])) { |
| 1523 |
$new_input['chat_input_font_color'] = sanitize_hex_color($input['chat_input_font_color']); |
| 1524 |
} |
| 1525 |
|
| 1526 |
return $new_input; |
| 1527 |
} |
| 1528 |
|
| 1529 |
|
| 1530 |
// Method to append the chatbot to the body |
| 1531 |
public function mxchat_append_chatbot_to_body() { |
| 1532 |
$options = get_option('mxchat_options'); |
| 1533 |
if (isset($options['append_to_body']) && $options['append_to_body'] === 'on') { |
| 1534 |
echo do_shortcode('[mxchat_chatbot floating="yes"]'); |
| 1535 |
} |
| 1536 |
} |
| 1537 |
|
| 1538 |
|
| 1539 |
|
| 1540 |
private function mxchat_extract_main_content($html) { |
| 1541 |
$dom = new DOMDocument; |
| 1542 |
libxml_use_internal_errors(true); // Suppress HTML parsing errors |
| 1543 |
@$dom->loadHTML($html); |
| 1544 |
libxml_clear_errors(); |
| 1545 |
|
| 1546 |
$xpath = new DOMXPath($dom); |
| 1547 |
|
| 1548 |
// Simplified selectors focusing on common content areas |
| 1549 |
$selectors = [ |
| 1550 |
'//article', |
| 1551 |
'//*[@id="content"]', |
| 1552 |
'//*[@class="entry-content"]', |
| 1553 |
'//main', |
| 1554 |
]; |
| 1555 |
|
| 1556 |
foreach ($selectors as $selector) { |
| 1557 |
$nodes = $xpath->query($selector); |
| 1558 |
if ($nodes->length > 0) { |
| 1559 |
$content = ''; |
| 1560 |
foreach ($nodes as $node) { |
| 1561 |
$content .= $dom->saveHTML($node); |
| 1562 |
} |
| 1563 |
return $content; |
| 1564 |
} |
| 1565 |
} |
| 1566 |
|
| 1567 |
// Fallback: Return the entire body content if no specific selector matches |
| 1568 |
$body = $dom->getElementsByTagName('body'); |
| 1569 |
return $body->length > 0 ? $dom->saveHTML($body->item(0)) : $html; |
| 1570 |
} |
| 1571 |
|
| 1572 |
public function mxchat_handle_sitemap_submission() { |
| 1573 |
if (!isset($_POST['submit_sitemap']) || !current_user_can('manage_options')) { |
| 1574 |
return; |
| 1575 |
} |
| 1576 |
|
| 1577 |
check_admin_referer('mxchat_submit_sitemap_action', 'mxchat_submit_sitemap_nonce'); |
| 1578 |
|
| 1579 |
$sitemap_url = esc_url_raw($_POST['sitemap_url']); |
| 1580 |
|
| 1581 |
$response = wp_remote_get($sitemap_url); |
| 1582 |
if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) { |
| 1583 |
set_transient('mxchat_admin_notice', 'Failed to fetch the sitemap. Please check the URL and try again.', 30); |
| 1584 |
wp_safe_redirect(esc_url(admin_url('admin.php?page=mxchat-prompts'))); |
| 1585 |
exit; |
| 1586 |
} |
| 1587 |
|
| 1588 |
$sitemap_content = wp_remote_retrieve_body($response); |
| 1589 |
|
| 1590 |
$xml = simplexml_load_string($sitemap_content); |
| 1591 |
if ($xml === false) { |
| 1592 |
set_transient('mxchat_admin_notice', 'Invalid sitemap XML. Please provide a valid sitemap.', 30); |
| 1593 |
wp_safe_redirect(esc_url(admin_url('admin.php?page=mxchat-prompts'))); |
| 1594 |
exit; |
| 1595 |
} |
| 1596 |
|
| 1597 |
$embedding_success = true; // Flag to track if all embeddings are successful |
| 1598 |
|
| 1599 |
foreach ($xml->url as $url_element) { |
| 1600 |
$page_url = (string)$url_element->loc; |
| 1601 |
|
| 1602 |
$page_response = wp_remote_get($page_url); |
| 1603 |
if (is_wp_error($page_response) || wp_remote_retrieve_response_code($page_response) !== 200) { |
| 1604 |
continue; |
| 1605 |
} |
| 1606 |
|
| 1607 |
$page_html = wp_remote_retrieve_body($page_response); |
| 1608 |
$page_content = $this->mxchat_extract_main_content($page_html); |
| 1609 |
$sanitized_content = $this->mxchat_sanitize_content_for_api($page_content); |
| 1610 |
|
| 1611 |
if (!empty($sanitized_content)) { |
| 1612 |
$embedding_vector = $this->mxchat_generate_embedding($sanitized_content); |
| 1613 |
if (is_array($embedding_vector)) { |
| 1614 |
MxChat_Utils::submit_content_to_db($sanitized_content, $page_url, $this->options['api_key']); |
| 1615 |
} else { |
| 1616 |
$embedding_success = false; // Set flag to false if any embedding fails |
| 1617 |
} |
| 1618 |
} |
| 1619 |
} |
| 1620 |
|
| 1621 |
if ($embedding_success) { |
| 1622 |
set_transient('mxchat_admin_notice', 'Sitemap content successfully submitted!', 30); |
| 1623 |
} else { |
| 1624 |
set_transient('mxchat_admin_notice', 'Some content failed to embed. Please check your API key and try again.', 30); |
| 1625 |
} |
| 1626 |
|
| 1627 |
wp_safe_redirect(esc_url(admin_url('admin.php?page=mxchat-prompts'))); |
| 1628 |
exit; |
| 1629 |
} |
| 1630 |
|
| 1631 |
|
| 1632 |
|
| 1633 |
private function mxchat_sanitize_content_for_api($content) { |
| 1634 |
// Remove script, style tags, and HTML comments |
| 1635 |
$content = preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', '', $content); |
| 1636 |
$content = preg_replace('/<style\b[^>]*>(.*?)<\/style>/is', '', $content); |
| 1637 |
$content = preg_replace('/<!--(.|\s)*?-->/', '', $content); |
| 1638 |
|
| 1639 |
// Remove all HTML tags and decode HTML entities |
| 1640 |
$content = wp_strip_all_tags($content); |
| 1641 |
$content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5); |
| 1642 |
|
| 1643 |
// Trim and normalize whitespace |
| 1644 |
$content = trim(preg_replace('/\s+/', ' ', $content)); |
| 1645 |
|
| 1646 |
return $content; |
| 1647 |
} |
| 1648 |
|
| 1649 |
|
| 1650 |
} |
| 1651 |
?> |
| 1652 |
|