PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / trunk
MxChat – AI Chatbot & Content Generation for WordPress vtrunk
3.2.21 3.2.20 3.2.19 3.2.18 3.2.17 3.2.16 3.2.15 3.2.14 3.2.12 3.2.13 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 2.0.3 2.0.4 2.0.5 2.0.6 All 152 releases
mxchat-basic / includes / class-mxchat-meta-box.php

class-mxchat-meta-box.php in MxChat – AI Chatbot & Content Generation for WordPress trunk, at includes/class-mxchat-meta-box.php

356 lines 14.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) {
3 exit; // Exit if accessed directly
4 }
5
6 /**
7 * Enhanced meta box for page-level chatbot visibility and bot selection
8 */
9 class MxChat_Meta_Box {
10
11 public function __construct() {
12 add_action('add_meta_boxes', array($this, 'add_chatbot_meta_box'));
13 add_action('save_post', array($this, 'save_chatbot_meta_box'));
14 add_action('enqueue_block_editor_assets', array($this, 'enqueue_gutenberg_assets'));
15 add_action('init', array($this, 'register_meta_fields'));
16 }
17
18 /**
19 * Add meta box to posts and pages
20 */
21 public function add_chatbot_meta_box() {
22 $post_types = get_post_types(array('public' => true), 'names');
23
24 foreach ($post_types as $post_type) {
25 add_meta_box(
26 'mxchat_visibility',
27 __('MxChat Settings', 'mxchat'),
28 array($this, 'render_meta_box'),
29 $post_type,
30 'side',
31 'default'
32 );
33 }
34 }
35
36 /**
37 * Register meta fields for Gutenberg
38 */
39 public function register_meta_fields() {
40 // Legacy field - kept for backward compatibility
41 register_post_meta('', '_mxchat_hide_chatbot', array(
42 'show_in_rest' => true,
43 'single' => true,
44 'type' => 'string',
45 'default' => '',
46 'auth_callback' => function() {
47 return current_user_can('edit_posts');
48 }
49 ));
50
51 // New visibility field: '' (global), 'show', 'hide'
52 register_post_meta('', '_mxchat_page_visibility', array(
53 'show_in_rest' => true,
54 'single' => true,
55 'type' => 'string',
56 'default' => '',
57 'auth_callback' => function() {
58 return current_user_can('edit_posts');
59 }
60 ));
61
62 register_post_meta('', '_mxchat_selected_bot', array(
63 'show_in_rest' => true,
64 'single' => true,
65 'type' => 'string',
66 'default' => '',
67 'auth_callback' => function() {
68 return current_user_can('edit_posts');
69 }
70 ));
71 }
72
73 /**
74 * Get available bots
75 */
76 private function get_available_bots() {
77 $bots = array();
78
79 // Check if multi-bot addon is active
80 if (class_exists('MxChat_Multi_Bot_Manager')) {
81 $multi_bot_manager = MxChat_Multi_Bot_Core_Manager::get_instance();
82 $available_bots = $multi_bot_manager->get_available_bots();
83
84 // Add the available bots
85 foreach ($available_bots as $bot_id => $bot_name) {
86 $bots[$bot_id] = $bot_name;
87 }
88 } else {
89 // Only default bot available
90 $bots['default'] = __('Default Bot', 'mxchat');
91 }
92
93 return $bots;
94 }
95
96 /**
97 * Check if global auto-show is enabled
98 */
99 private function is_global_autoshow_enabled() {
100 $options = get_option('mxchat_options', array());
101 return isset($options['append_to_body']) && $options['append_to_body'] === 'on';
102 }
103
104 /**
105 * Get the effective visibility value for a post, with backward compatibility
106 */
107 private function get_effective_visibility($post_id) {
108 // Check new field first
109 $visibility = get_post_meta($post_id, '_mxchat_page_visibility', true);
110
111 if (!empty($visibility)) {
112 return $visibility;
113 }
114
115 // Backward compat: check legacy hide checkbox
116 $hide_chatbot = get_post_meta($post_id, '_mxchat_hide_chatbot', true);
117 if ($hide_chatbot === '1') {
118 return 'hide';
119 }
120
121 return ''; // Global default
122 }
123
124 /**
125 * Render meta box with 3-option visibility control
126 */
127 public function render_meta_box($post) {
128 wp_nonce_field('mxchat_meta_box_nonce', 'mxchat_meta_box_nonce');
129
130 $visibility = $this->get_effective_visibility($post->ID);
131 $selected_bot = get_post_meta($post->ID, '_mxchat_selected_bot', true);
132 $available_bots = $this->get_available_bots();
133 $global_autoshow = $this->is_global_autoshow_enabled();
134 $has_multibot = class_exists('MxChat_Multi_Bot_Manager');
135
136 ?>
137 <div style="padding: 10px 0;">
138
139 <!-- Chatbot Visibility -->
140 <div style="margin-bottom: 15px;">
141 <label style="display: block; margin-bottom: 8px; font-weight: 600;">
142 <?php _e('Chatbot Visibility', 'mxchat'); ?>
143 </label>
144
145 <label style="display: flex; align-items: center; margin-bottom: 6px; cursor: pointer;">
146 <input type="radio"
147 name="mxchat_page_visibility"
148 value=""
149 <?php checked($visibility, ''); ?>
150 style="margin-right: 8px;" />
151 <?php _e('Use Global Setting', 'mxchat'); ?>
152 </label>
153
154 <label style="display: flex; align-items: center; margin-bottom: 6px; cursor: pointer;">
155 <input type="radio"
156 name="mxchat_page_visibility"
157 value="show"
158 <?php checked($visibility, 'show'); ?>
159 style="margin-right: 8px;" />
160 <?php _e('Show Chatbot on this page', 'mxchat'); ?>
161 </label>
162
163 <label style="display: flex; align-items: center; cursor: pointer;">
164 <input type="radio"
165 name="mxchat_page_visibility"
166 value="hide"
167 <?php checked($visibility, 'hide'); ?>
168 style="margin-right: 8px;" />
169 <?php _e('Hide Chatbot on this page', 'mxchat'); ?>
170 </label>
171
172 <div style="margin-top: 8px; padding: 8px; background: #f8f9fa; border-left: 3px solid #007cba; font-size: 12px;">
173 <?php if ($global_autoshow) : ?>
174 <p style="margin: 0 0 5px 0; color: #0073aa;">
175 <strong><?php _e('Global Auto-Show: ON', 'mxchat'); ?></strong>
176 </p>
177 <p style="margin: 0; color: #666;">
178 <?php _e('The chatbot appears on all pages by default. Use "Hide" to exclude this page, or "Show" to override post type restrictions.', 'mxchat'); ?>
179 </p>
180 <?php else : ?>
181 <p style="margin: 0 0 5px 0; color: #d63638;">
182 <strong><?php _e('Global Auto-Show: OFF', 'mxchat'); ?></strong>
183 </p>
184 <p style="margin: 0; color: #666;">
185 <?php _e('The chatbot is hidden by default. Select "Show" to display it on this page without needing a shortcode.', 'mxchat'); ?>
186 </p>
187 <?php endif; ?>
188 </div>
189 </div>
190
191 <!-- Bot Selection (only show if multi-bot is available) -->
192 <?php if ($has_multibot && count($available_bots) > 1) : ?>
193 <div style="margin-bottom: 15px;">
194 <label style="display: block; margin-bottom: 5px; font-weight: 600;">
195 <?php _e('Select Bot for this Page:', 'mxchat'); ?>
196 </label>
197 <select name="mxchat_selected_bot" style="width: 100%;">
198 <option value=""><?php _e('Use Default Bot', 'mxchat'); ?></option>
199 <?php foreach ($available_bots as $bot_id => $bot_name) : ?>
200 <option value="<?php echo esc_attr($bot_id); ?>" <?php selected($selected_bot, $bot_id); ?>>
201 <?php echo esc_html($bot_name); ?>
202 </option>
203 <?php endforeach; ?>
204 </select>
205 <p style="font-size: 12px; color: #666; margin-top: 5px; font-style: italic;">
206 <?php _e('Only applies when visibility is set to "Show" or "Use Global Setting" with auto-show enabled.', 'mxchat'); ?>
207 </p>
208 </div>
209 <?php endif; ?>
210
211 <!-- Preview Notice -->
212 <div style="margin-top: 15px; padding: 8px; background: #fff3cd; border-left: 3px solid #ffc107; font-size: 12px;">
213 <p style="margin: 0; color: #856404;">
214 <strong><?php _e('Important:', 'mxchat'); ?></strong>
215 <?php _e('Changes only take effect after saving/updating the page.', 'mxchat'); ?>
216 </p>
217 </div>
218
219 <!-- Shortcode Examples -->
220 <div style="margin-top: 10px; padding: 8px; background: #e7f3ff; border-left: 3px solid #2196f3; font-size: 12px;">
221 <p style="margin: 0 0 5px 0; color: #1565c0;">
222 <strong><?php _e('Shortcode Examples:', 'mxchat'); ?></strong>
223 </p>
224 <p style="margin: 0; color: #666; font-family: monospace;">
225 <?php _e('[mxchat_chatbot floating="yes"] - Floating chatbot', 'mxchat'); ?><br>
226 <?php _e('[mxchat_chatbot floating="no"] - Embedded chatbot', 'mxchat'); ?>
227 </p>
228 </div>
229 </div>
230 <?php
231 }
232
233 /**
234 * Save meta box data
235 */
236 public function save_chatbot_meta_box($post_id) {
237 if (!isset($_POST['mxchat_meta_box_nonce']) ||
238 !wp_verify_nonce($_POST['mxchat_meta_box_nonce'], 'mxchat_meta_box_nonce')) {
239 return;
240 }
241
242 if (!current_user_can('edit_post', $post_id)) {
243 return;
244 }
245
246 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
247 return;
248 }
249
250 // Save new visibility field
251 $visibility = isset($_POST['mxchat_page_visibility']) ? sanitize_text_field($_POST['mxchat_page_visibility']) : '';
252
253 if (in_array($visibility, array('show', 'hide'), true)) {
254 update_post_meta($post_id, '_mxchat_page_visibility', $visibility);
255 } else {
256 delete_post_meta($post_id, '_mxchat_page_visibility');
257 }
258
259 // Sync legacy field for backward compat with any external code
260 if ($visibility === 'hide') {
261 update_post_meta($post_id, '_mxchat_hide_chatbot', '1');
262 } else {
263 delete_post_meta($post_id, '_mxchat_hide_chatbot');
264 }
265
266 // Save selected bot setting
267 if (isset($_POST['mxchat_selected_bot'])) {
268 $selected_bot = sanitize_text_field($_POST['mxchat_selected_bot']);
269 if (!empty($selected_bot)) {
270 update_post_meta($post_id, '_mxchat_selected_bot', $selected_bot);
271 } else {
272 delete_post_meta($post_id, '_mxchat_selected_bot');
273 }
274 }
275 }
276
277 /**
278 * Enqueue Gutenberg assets
279 */
280 public function enqueue_gutenberg_assets() {
281 $available_bots = $this->get_available_bots();
282 $global_autoshow = $this->is_global_autoshow_enabled();
283 $has_multibot = class_exists('MxChat_Multi_Bot_Manager');
284
285 // Enqueue the JavaScript file
286 wp_enqueue_script(
287 'mxchat-meta-box',
288 plugin_dir_url(__FILE__) . '../js/meta-box.js',
289 array('wp-edit-post', 'wp-element', 'wp-components', 'wp-data', 'wp-plugins'),
290 '1.0.0',
291 true
292 );
293
294 // Localize script with data
295 wp_localize_script('mxchat-meta-box', 'mxchatMetaBox', array(
296 'availableBots' => $available_bots,
297 'globalAutoshow' => $global_autoshow,
298 'hasMultibot' => $has_multibot,
299 'strings' => array(
300 'panelTitle' => __('MxChat Settings', 'mxchat'),
301 'visibilityLabel' => __('Chatbot Visibility', 'mxchat'),
302 'useGlobalSetting' => __('Use Global Setting', 'mxchat'),
303 'showChatbot' => __('Show Chatbot on this page', 'mxchat'),
304 'hideChatbot' => __('Hide Chatbot on this page', 'mxchat'),
305 'selectBot' => __('Select Bot for this Page', 'mxchat'),
306 'useDefaultBot' => __('Use Default Bot', 'mxchat'),
307 'globalAutoshowOn' => __('Global Auto-Show is ON. The chatbot appears on all pages by default. Use "Hide" to exclude this page.', 'mxchat'),
308 'globalAutoshowOff' => __('Global Auto-Show is OFF. Select "Show" to display the chatbot on this page without needing a shortcode.', 'mxchat')
309 )
310 ));
311 }
312
313 /**
314 * Helper function to get the bot that should display on current page
315 * Returns: array with 'action' (hide/show/global) and optional 'bot_id'
316 */
317 public static function get_page_bot_setting($post_id = null) {
318 if (!$post_id) {
319 $post_id = get_the_ID();
320 }
321
322 if (!$post_id) {
323 return null;
324 }
325
326 // Check new visibility field first
327 $visibility = get_post_meta($post_id, '_mxchat_page_visibility', true);
328
329 if ($visibility === 'hide') {
330 return array('action' => 'hide');
331 }
332
333 if ($visibility === 'show') {
334 $selected_bot = get_post_meta($post_id, '_mxchat_selected_bot', true);
335 $bot_id = !empty($selected_bot) ? $selected_bot : 'default';
336 return array('action' => 'show', 'bot_id' => $bot_id);
337 }
338
339 // Backward compat: check legacy hide checkbox if no new field set
340 if (empty($visibility)) {
341 $hide_chatbot = get_post_meta($post_id, '_mxchat_hide_chatbot', true);
342 if ($hide_chatbot === '1') {
343 return array('action' => 'hide');
344 }
345 }
346
347 // Check if specific bot is selected (legacy path)
348 $selected_bot = get_post_meta($post_id, '_mxchat_selected_bot', true);
349 if (!empty($selected_bot)) {
350 return array('action' => 'show', 'bot_id' => $selected_bot);
351 }
352
353 // Use global setting
354 return array('action' => 'global');
355 }
356 }