PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 3.0.4
MxChat – AI Chatbot & Content Generation for WordPress v3.0.4
3.2.21 3.2.20 3.2.19 3.2.18 3.2.17 3.2.16 3.2.15 3.2.14 3.2.12 3.2.13 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 2.0.3 2.0.4 2.0.5 2.0.6 All 152 releases
← All changes | admin/class-ajax-handler.php +61 -232 3.2.23.0.4 View file →
@@ -40,15 +40,8 @@
40 40 add_action('wp_ajax_mxchat_update_intent_threshold', array($this, 'mxchat_update_intent_threshold'));
41 41
42 42 add_action('wp_ajax_mxchat_save_selected_bot', array($this, 'mxchat_save_selected_bot'));
43 43 add_action('wp_ajax_mxchat_check_api_keys', array($this, 'mxchat_check_api_keys'));
44 -
45 - // Debug & Optimization AJAX
46 - add_action('wp_ajax_mxchat_toggle_debug_mode', array($this, 'mxchat_toggle_debug_mode_callback'));
47 - add_action('wp_ajax_mxchat_get_debug_log', array($this, 'mxchat_get_debug_log_callback'));
48 - add_action('wp_ajax_mxchat_clear_debug_log', array($this, 'mxchat_clear_debug_log_callback'));
49 - add_action('wp_ajax_mxchat_export_settings', array($this, 'mxchat_export_settings_callback'));
50 - add_action('wp_ajax_mxchat_reset_all_settings', array($this, 'mxchat_reset_all_settings_callback'));
51 44 }
52 45
53 46 // ========================================
54 47 // SETTINGS AJAX HANDLERS
@@ -79,17 +72,10 @@
79 72 // Load the full options array
80 73 $options = get_option('mxchat_options', []);
81 74 //error_log('MXChat Save: Current options array: ' . print_r($options, true));
82 75
83 - // Extract field name from mxchat_options[field_name] format if present
84 - // But preserve the full name for special cases like rate_limits that need the full path
85 - $field_name = $name;
86 - if (preg_match('/^mxchat_options\[([^\[\]]+)\]$/', $name, $matches)) {
87 - $field_name = $matches[1];
88 - }
89 -
90 76 // Handle special cases
91 - switch ($field_name) {
77 + switch ($name) {
92 78 case 'model':
93 79 //error_log('MXChat Save: Processing model selection');
94 80 //error_log('MXChat Save: Model value received: ' . $value);
95 81 //error_log('MXChat Save: Value type: ' . gettype($value));
@@ -107,13 +93,14 @@
107 93 'gemini-2.0-flash', 'gemini-2.0-flash-lite', 'gemini-1.5-pro', 'gemini-1.5-flash',
108 94 'grok-4-0709', 'grok-4-1-fast-reasoning', 'grok-4-1-fast-non-reasoning', 'grok-3-beta', 'grok-3-fast-beta', 'grok-3-mini-beta',
109 95 'grok-3-mini-fast-beta', 'grok-2',
110 96 'deepseek-chat',
111 - 'claude-opus-4-6', 'claude-opus-4-5', 'claude-sonnet-4-6',
112 97 'claude-sonnet-4-5-20250929', 'claude-opus-4-1-20250805', 'claude-haiku-4-5-20251001',
113 - 'claude-opus-4-20250514', 'claude-sonnet-4-20250514',
114 - 'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.4-nano', 'gpt-5.3-chat-latest',
115 - 'gpt-5.2', 'gpt-5.1-chat-latest', 'gpt-5.1-2025-11-13', 'gpt-5', 'gpt-5-mini', 'gpt-5-nano',
98 + 'claude-opus-4-20250514', 'claude-sonnet-4-20250514', 'claude-3-7-sonnet-20250219',
99 + 'claude-3-5-sonnet-20241022', 'claude-3-opus-20240229', 'claude-3-sonnet-20240229',
100 + 'claude-3-haiku-20240307',
101 + 'gpt-5.2', 'gpt-5.1-2025-11-13', 'gpt-5', 'gpt-5-mini', 'gpt-5-nano', 'gpt-4.1-2025-04-14',
102 + 'gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo',
116 103 );
117 104
118 105 //error_log('MXChat Save: in_array result: ' . (in_array($value, $allowed_models) ? 'YES' : 'NO'));
119 106
@@ -153,9 +140,9 @@
153 140 case 'additional_popular_questions':
154 141 //error_log('MXChat Save: Processing additional_popular_questions');
155 142 $questions = json_decode($value, true); // No need for stripslashes here
156 143 if (is_array($questions)) {
157 - $options[$field_name] = $questions;
144 + $options[$name] = $questions;
158 145 // Also update old option for backwards compatibility
159 146 update_option('additional_popular_questions', $questions);
160 147 //error_log('MXChat Save: Saved ' . count($questions) . ' additional questions');
161 148 } else {
@@ -164,59 +151,60 @@
164 151 break;
165 152 case 'email_blocker_header_content':
166 153 //error_log('MXChat Save: Processing email_blocker_header_content');
167 154 // Allow HTML content but sanitize it safely
168 - $options[$field_name] = wp_kses_post($value);
155 + $options[$name] = wp_kses_post($value);
169 156 break;
170 157 case 'email_blocker_button_text':
171 158 //error_log('MXChat Save: Processing email_blocker_button_text');
172 - $options[$field_name] = sanitize_text_field($value);
159 + $options[$name] = sanitize_text_field($value);
173 160 break;
174 161 case 'name_field_placeholder':
175 162 //error_log('MXChat Save: Processing name_field_placeholder');
176 - $options[$field_name] = sanitize_text_field($value);
163 + $options[$name] = sanitize_text_field($value);
177 164 break;
178 165 case 'similarity_threshold':
179 166 //error_log('MXChat Save: Processing similarity_threshold');
180 - // Validate and save - enforce min 20, max 85
181 - $threshold = intval($value);
182 - if ($threshold < 20) $threshold = 20;
183 - if ($threshold > 85) $threshold = 85;
184 - $options[$field_name] = $threshold;
167 + // Save to the options array
168 + $options[$name] = $value;
185 169 break;
186 - case 'rag_sources_limit':
187 - //error_log('MXChat Save: Processing rag_sources_limit');
188 - // Validate and save - enforce min 3, max 10, default 6
189 - $rag_limit = intval($value);
190 - if ($rag_limit < 3) $rag_limit = 3;
191 - if ($rag_limit > 10) $rag_limit = 10;
192 - $options[$field_name] = $rag_limit;
170 + case 'user_message_bg_color':
171 + case 'user_message_font_color':
172 + case 'bot_message_bg_color':
173 + case 'bot_message_font_color':
174 + case 'top_bar_bg_color':
175 + case 'send_button_font_color':
176 + case 'chatbot_background_color':
177 + case 'icon_color':
178 + case 'chat_input_font_color':
179 + case 'live_agent_message_bg_color':
180 + case 'live_agent_message_font_color':
181 + case 'mode_indicator_bg_color':
182 + case 'mode_indicator_font_color':
183 + case 'toolbar_icon_color':
184 + case 'quick_questions_toggle_color':
185 + //error_log('MXChat Save: Processing color value: ' . $name);
186 + // Store color values directly
187 + $options[$name] = $value;
193 188 break;
194 - case 'rag_chunks_limit':
195 - // Validate and save - enforce min 8, max 20, default 15
196 - $chunks_limit = intval($value);
197 - if ($chunks_limit < 8) $chunks_limit = 8;
198 - if ($chunks_limit > 20) $chunks_limit = 20;
199 - $options[$field_name] = $chunks_limit;
200 - break;
201 189 case 'live_agent_status':
202 190 //error_log('MXChat Save: Processing live_agent_status');
203 191 // Set the new value
204 - $options[$field_name] = ($value === 'on') ? 'on' : 'off';
192 + $options[$name] = ($value === 'on') ? 'on' : 'off';
205 193 break;
206 194 case 'enable_web_search':
207 195 //error_log('MXChat Save: Processing enable_web_search');
208 - $options[$field_name] = ($value === 'on') ? 'on' : 'off';
196 + $options[$name] = ($value === 'on') ? 'on' : 'off';
209 197 break;
210 198 case 'enable_woocommerce_integration':
211 199 //error_log('MXChat Save: Processing enable_woocommerce_integration');
212 200 // Handle values that used to be 1/0
213 - $options[$field_name] = ($value === 'on' || $value === '1') ? 'on' : 'off';
201 + $options[$name] = ($value === 'on' || $value === '1') ? 'on' : 'off';
214 202 break;
215 203 case 'post_type_visibility_mode':
216 204 // Validate mode value
217 205 $allowed_modes = array('all', 'include', 'exclude');
218 - $options[$field_name] = in_array($value, $allowed_modes) ? $value : 'all';
206 + $options[$name] = in_array($value, $allowed_modes) ? $value : 'all';
219 207 break;
220 208 case 'post_type_visibility_list':
221 209 // Handle JSON array of post types
222 210 $post_types = json_decode($value, true);
@@ -221,18 +209,13 @@
221 209 // Handle JSON array of post types
222 210 $post_types = json_decode($value, true);
223 211 if (is_array($post_types)) {
224 212 // Sanitize each post type slug
225 - $options[$field_name] = array_map('sanitize_key', $post_types);
213 + $options[$name] = array_map('sanitize_key', $post_types);
226 214 } else {
227 - $options[$field_name] = array();
215 + $options[$name] = array();
228 216 }
229 217 break;
230 - case 'script_loading_strategy':
231 - // Validate script loading strategy value
232 - $allowed_strategies = array('default', 'defer', 'delay_1s', 'delay_3s', 'delay_5s', 'on_interaction');
233 - $options[$field_name] = in_array($value, $allowed_strategies) ? $value : 'default';
234 - break;
235 218 default:
236 219 // Handle transcripts options
237 220 if (strpos($name, 'mxchat_transcripts_options') !== false) {
238 221 // Extract field name from mxchat_transcripts_options[field_name]
@@ -266,38 +249,30 @@
266 249
267 250 // Serialize the options array
268 251 $serialized = maybe_serialize($transcripts_options);
269 252
270 - // Check if the option already exists in the database
271 - $existing = $wpdb->get_var("SELECT option_id FROM {$wpdb->options} WHERE option_name = 'mxchat_transcripts_options'");
253 + // Direct database update
254 + $result = $wpdb->update(
255 + $wpdb->options,
256 + array('option_value' => $serialized),
257 + array('option_name' => 'mxchat_transcripts_options'),
258 + array('%s'),
259 + array('%s')
260 + );
272 261
273 - if ($existing) {
274 - // Option exists, do an update
275 - $result = $wpdb->update(
276 - $wpdb->options,
277 - array('option_value' => $serialized),
278 - array('option_name' => 'mxchat_transcripts_options'),
279 - array('%s'),
280 - array('%s')
281 - );
282 - } else {
283 - // Option doesn't exist (new install), do an insert
284 - $result = $wpdb->insert(
285 - $wpdb->options,
286 - array(
287 - 'option_name' => 'mxchat_transcripts_options',
288 - 'option_value' => $serialized,
289 - 'autoload' => 'yes'
290 - ),
291 - array('%s', '%s', '%s')
292 - );
293 - }
294 -
295 262 // Clear all caches after direct DB update
296 263 wp_cache_delete('mxchat_transcripts_options', 'options');
297 264 wp_cache_delete('alloptions', 'options');
298 265 wp_cache_flush();
299 266
267 + // Verify the save worked by reading directly from database
268 + $db_value = $wpdb->get_var("SELECT option_value FROM {$wpdb->options} WHERE option_name = 'mxchat_transcripts_options'");
269 +
270 + // Log for debugging
271 + error_log('MXChat Transcripts Save: field=' . $field_name . ', value=' . $value . ', db_result=' . var_export($result, true));
272 + error_log('MXChat Transcripts Save: saved options=' . print_r($transcripts_options, true));
273 + error_log('MXChat Transcripts Verify: DB direct after save=' . $db_value);
274 +
300 275 wp_send_json_success(['message' => esc_html__('Setting saved', 'mxchat')]);
301 276 return;
302 277 }
303 278 }
@@ -358,10 +333,10 @@
358 333 } else {
359 334 //error_log('MXChat Save: Failed to parse role_rate_limits pattern: ' . $name);
360 335 }
361 336 }
362 - // Handle toggles - check both extracted field_name and original name for toggle detection
363 - else if (strpos($field_name, 'toggle') !== false || in_array($field_name, [
337 + // Handle toggles
338 + else if (strpos($name, 'toggle') !== false || in_array($name, [
364 339 'chat_persistence_toggle',
365 340 'privacy_toggle',
366 341 'complianz_toggle',
367 342 'chat_toolbar_toggle',
@@ -370,16 +345,17 @@
370 345 'enable_streaming_toggle',
371 346 'contextual_awareness_toggle',
372 347 'citation_links_toggle',
373 348 'enable_email_block',
374 - 'enable_name_field'
349 + 'enable_name_field',
350 + 'show_frontend_debugger'
375 351 ])) {
376 - //error_log('MXChat Save: Processing toggle: ' . $field_name);
377 - $options[$field_name] = ($value === 'on') ? 'on' : 'off';
352 + //error_log('MXChat Save: Processing toggle: ' . $name);
353 + $options[$name] = ($value === 'on') ? 'on' : 'off';
378 354 } else {
379 - //error_log('MXChat Save: Processing standard field: ' . $field_name);
380 - // Store all other values directly using the extracted field name
381 - $options[$field_name] = $value;
355 + //error_log('MXChat Save: Processing standard field: ' . $name);
356 + // Store all other values directly
357 + $options[$name] = $value;
382 358 }
383 359 break;
384 360 }
385 361
@@ -387,20 +363,8 @@
387 363 $updated = update_option('mxchat_options', $options);
388 364 //error_log('MXChat Save: Update result: ' . ($updated ? 'success' : 'unchanged') . ' for field: ' . $name);
389 365 //error_log('MXChat Save: Updated options array: ' . print_r($options, true));
390 366
391 - // Log the save action if debug mode is enabled
392 - if ( class_exists( 'MxChat_Admin' ) ) {
393 - MxChat_Admin::mxchat_log_debug(
394 - 'settings_save',
395 - sprintf( 'Field saved: %s', $field_name ),
396 - array(
397 - 'field' => $field_name,
398 - 'updated' => $updated,
399 - )
400 - );
401 - }
402 -
403 367 // Always return success even if WordPress says nothing changed
404 368 // (which happens when the value is the same as before)
405 369 wp_send_json_success(['message' => esc_html__('Setting saved', 'mxchat')]);
406 370 }
@@ -1134,143 +1098,8 @@
1134 1098 'voyage' => !empty($options['voyage_api_key'])
1135 1099 );
1136 1100
1137 1101 wp_send_json_success($api_key_status);
1138 - }
1139 -
1140 - // ========================================
1141 - // DEBUG & OPTIMIZATION AJAX HANDLERS
1142 - // ========================================
1143 -
1144 - /**
1145 - * Toggle debug mode on/off
1146 - */
1147 - public function mxchat_toggle_debug_mode_callback() {
1148 - // Verify nonce
1149 - if ( ! check_ajax_referer( 'mxchat_save_setting_nonce', '_ajax_nonce', false ) ) {
1150 - wp_send_json_error( array( 'message' => esc_html__( 'Security check failed', 'mxchat' ) ) );
1151 - }
1152 -
1153 - // Check permissions
1154 - if ( ! current_user_can( 'manage_options' ) ) {
1155 - wp_send_json_error( array( 'message' => esc_html__( 'Unauthorized', 'mxchat' ) ) );
1156 - }
1157 -
1158 - $enabled = isset( $_POST['enabled'] ) && $_POST['enabled'] === 'on';
1159 -
1160 - $options = get_option( 'mxchat_options', array() );
1161 -
1162 - if ( $enabled ) {
1163 - $options['debug_mode'] = 'on';
1164 - update_option( 'mxchat_options', $options );
1165 - MxChat_Admin::mxchat_log_debug( 'debug_mode', 'Debug mode enabled' );
1166 - } else {
1167 - // Log before disabling
1168 - MxChat_Admin::mxchat_log_debug( 'debug_mode', 'Debug mode disabled' );
1169 - $options['debug_mode'] = 'off';
1170 - update_option( 'mxchat_options', $options );
1171 - }
1172 -
1173 - wp_send_json_success( array(
1174 - 'message' => $enabled ? esc_html__( 'Debug mode enabled', 'mxchat' ) : esc_html__( 'Debug mode disabled', 'mxchat' ),
1175 - 'enabled' => $enabled,
1176 - ) );
1177 - }
1178 -
1179 - /**
1180 - * Get the debug log entries
1181 - */
1182 - public function mxchat_get_debug_log_callback() {
1183 - // Verify nonce
1184 - if ( ! check_ajax_referer( 'mxchat_save_setting_nonce', '_ajax_nonce', false ) ) {
1185 - wp_send_json_error( array( 'message' => esc_html__( 'Security check failed', 'mxchat' ) ) );
1186 - }
1187 -
1188 - // Check permissions
1189 - if ( ! current_user_can( 'manage_options' ) ) {
1190 - wp_send_json_error( array( 'message' => esc_html__( 'Unauthorized', 'mxchat' ) ) );
1191 - }
1192 -
1193 - $log = MxChat_Admin::mxchat_get_debug_log();
1194 -
1195 - wp_send_json_success( array(
1196 - 'log' => $log,
1197 - 'count' => count( $log ),
1198 - ) );
1199 - }
1200 -
1201 - /**
1202 - * Clear the debug log
1203 - */
1204 - public function mxchat_clear_debug_log_callback() {
1205 - // Verify nonce
1206 - if ( ! check_ajax_referer( 'mxchat_save_setting_nonce', '_ajax_nonce', false ) ) {
1207 - wp_send_json_error( array( 'message' => esc_html__( 'Security check failed', 'mxchat' ) ) );
1208 - }
1209 -
1210 - // Check permissions
1211 - if ( ! current_user_can( 'manage_options' ) ) {
1212 - wp_send_json_error( array( 'message' => esc_html__( 'Unauthorized', 'mxchat' ) ) );
1213 - }
1214 -
1215 - MxChat_Admin::mxchat_clear_debug_log();
1216 -
1217 - // Log that the log was cleared (this will be the first entry in the new log)
1218 - MxChat_Admin::mxchat_log_debug( 'debug_log', 'Debug log cleared by user' );
1219 -
1220 - wp_send_json_success( array( 'message' => esc_html__( 'Debug log cleared', 'mxchat' ) ) );
1221 - }
1222 -
1223 - /**
1224 - * Export settings as JSON
1225 - */
1226 - public function mxchat_export_settings_callback() {
1227 - // Verify nonce
1228 - if ( ! check_ajax_referer( 'mxchat_save_setting_nonce', '_ajax_nonce', false ) ) {
1229 - wp_send_json_error( array( 'message' => esc_html__( 'Security check failed', 'mxchat' ) ) );
1230 - }
1231 -
1232 - // Check permissions
1233 - if ( ! current_user_can( 'manage_options' ) ) {
1234 - wp_send_json_error( array( 'message' => esc_html__( 'Unauthorized', 'mxchat' ) ) );
1235 - }
1236 -
1237 - $export = MxChat_Admin::mxchat_export_settings();
1238 -
1239 - // Log the export
1240 - MxChat_Admin::mxchat_log_debug( 'settings_export', 'Settings exported by user' );
1241 -
1242 - wp_send_json_success( array(
1243 - 'settings' => $export,
1244 - 'filename' => 'mxchat-settings-' . gmdate( 'Y-m-d-His' ) . '.json',
1245 - ) );
1246 - }
1247 -
1248 - /**
1249 - * Reset all settings to defaults
1250 - */
1251 - public function mxchat_reset_all_settings_callback() {
1252 - // Verify nonce
1253 - if ( ! check_ajax_referer( 'mxchat_save_setting_nonce', '_ajax_nonce', false ) ) {
1254 - wp_send_json_error( array( 'message' => esc_html__( 'Security check failed', 'mxchat' ) ) );
1255 - }
1256 -
1257 - // Check permissions
1258 - if ( ! current_user_can( 'manage_options' ) ) {
1259 - wp_send_json_error( array( 'message' => esc_html__( 'Unauthorized', 'mxchat' ) ) );
1260 - }
1261 -
1262 - // Require confirmation code
1263 - $confirmation = isset( $_POST['confirmation'] ) ? sanitize_text_field( wp_unslash( $_POST['confirmation'] ) ) : '';
1264 -
1265 - if ( strtoupper( $confirmation ) !== 'RESET' ) {
1266 - wp_send_json_error( array( 'message' => esc_html__( 'Invalid confirmation code. Please type RESET to confirm.', 'mxchat' ) ) );
1267 - }
1268 -
1269 - // Perform the reset
1270 - MxChat_Admin::mxchat_reset_all_settings();
1271 -
1272 - wp_send_json_success( array( 'message' => esc_html__( 'All settings have been reset to defaults. The page will reload.', 'mxchat' ) ) );
1273 1102 }
1274 1103
1275 1104 }
1276 1105