PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 3.2.23
MxChat – AI Chatbot & Content Generation for WordPress v3.2.23
3.2.25 3.2.24 3.2.23 3.2.22 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 All 156 releases
← All changes | includes/class-mxchat-public.php +2 -82 3.2.25 → 3.2.23 View file →
@@ -11,23 +11,8 @@
11 11 // yields, so an explicit floating placement never doubles up with the
12 12 // Auto-Display instance (plan 95dd1e).
13 13 private static $floating_instance_rendered = false;
14 14
15 - // Bot ids already placed on this page (plan 977cad), floating and inline
16 - // alike. Two copies of one bot share every element id (chat-input-<bot>,
17 - // send-button-<bot>, ...) and chat-script.js looks elements up by id, so
18 - // the second copy's Send reads the FIRST copy's empty box and sends
19 - // nothing. One copy of a bot per page: append_chatbot_to_body() stands
20 - // down for a bot the content already shows, and a second explicit
21 - // placement of the same bot renders an administrator-only note instead.
22 - // Only page renders count: a render in wp-admin, admin-ajax, cron, REST,
23 - // WP-CLI, a feed, or inside wp_head (a plugin building meta tags from the
24 - // content) is not on the page and must not suppress the real one. Note
25 - // that a block theme renders the body BEFORE wp_head (template-canvas
26 - // builds the template first so blocks can enqueue), so "after wp_head"
27 - // is not the test.
28 - private static $rendered_bot_ids = array();
29 -
30 15 public function __construct() {
31 16 // Simply get the options without defining duplicated defaults
32 17 $this->options = get_option('mxchat_options', array());
33 18 add_shortcode('mxchat_chatbot', array($this, 'render_chatbot_shortcode'));
@@ -94,17 +79,8 @@
94 79 // Don't show chatbot if determination is false
95 80 if ($bot_to_show === false) {
96 81 return;
97 82 }
98 -
99 - // The bot is already on this page as an explicit placement (an inline
100 - // shortcode or block in the content). A second, floating copy would share
101 - // its element ids and could be opened but not send; the embedded one wins
102 - // (plan 977cad). A page whose embedded chatbot is a DIFFERENT bot keeps
103 - // both, their ids differ.
104 - if (self::is_bot_on_page($bot_to_show)) {
105 - return;
106 - }
107 83
108 84 // Handle consent for display
109 85 $consent_category = 'marketing';
110 86 $has_consent = true;
@@ -126,56 +102,8 @@
126 102 echo do_shortcode('[mxchat_chatbot floating="yes" has_consent="' . ($has_consent ? 'yes' : 'no') . '"]');
127 103 }
128 104 }
129 105
130 - /**
131 - * Is this render on the page a visitor sees? (plan 977cad) False in
132 - * wp-admin, admin-ajax, cron, REST, WP-CLI, a feed, and inside wp_head.
133 - * Not "after wp_head": block themes render the body content first.
134 - */
135 - private static function is_page_render() {
136 - if (is_admin() || wp_doing_ajax() || wp_doing_cron()
137 - || (defined('REST_REQUEST') && REST_REQUEST)
138 - || (defined('WP_CLI') && WP_CLI)) {
139 - return false;
140 - }
141 - return !doing_action('wp_head') && !is_feed();
142 - }
143 -
144 - private static function record_bot_on_page($bot_id) {
145 - if (!self::is_page_render()) {
146 - return;
147 - }
148 - $bot_id = sanitize_key($bot_id);
149 - if ($bot_id !== '' && !in_array($bot_id, self::$rendered_bot_ids, true)) {
150 - self::$rendered_bot_ids[] = $bot_id;
151 - }
152 - }
153 -
154 - /**
155 - * Has a placement of this bot already rendered in the page body on this
156 - * request? (plan 977cad)
157 - */
158 - public static function is_bot_on_page($bot_id) {
159 - if (!self::is_page_render()) {
160 - return false;
161 - }
162 - return in_array(sanitize_key($bot_id), self::$rendered_bot_ids, true);
163 - }
164 -
165 - /**
166 - * What a second placement of an already-shown bot renders: nothing for
167 - * visitors, one line for a logged-in administrator (plan 977cad).
168 - */
169 - private static function duplicate_placement_notice() {
170 - if (!current_user_can('manage_options')) {
171 - return '';
172 - }
173 - return '<p class="mxchat-placement-notice" data-nosnippet>'
174 - . esc_html__('MxChat: this page already shows this chatbot, so a second copy of the same bot is not displayed. Only administrators see this note.', 'mxchat')
175 - . '</p>';
176 - }
177 -
178 106 private function mxchat_get_user_identifier() {
179 107 return sanitize_text_field($_SERVER['REMOTE_ADDR']);
180 108 }
181 109
@@ -204,18 +132,9 @@
204 132 'bot_id' => '' // Support for multi-bot functionality - empty means auto-detect
205 133 ), $atts);
206 134
207 135 // Determine which bot to use
208 - $bot_id = sanitize_key($this->determine_bot_for_shortcode($attributes['bot_id']));
209 -
210 - // A second placement of a bot already on this page is not rendered
211 - // (plan 977cad, see $rendered_bot_ids): it could be opened but never
212 - // sent. Administrators get a one-line note in its place so the
213 - // duplicate is visible to the person who can remove it.
214 - if (self::is_bot_on_page($bot_id)) {
215 - return self::duplicate_placement_notice();
216 - }
217 - self::record_bot_on_page($bot_id);
136 + $bot_id = $this->determine_bot_for_shortcode($attributes['bot_id']);
218 137
219 138 // A floating shortcode always renders; what it does is suppress the LATER
220 139 // auto-append instance (see append_chatbot_to_body), so a page never gets
221 140 // two floating widgets. This replaced a dead empty branch here that
@@ -227,8 +146,9 @@
227 146 // Non-floating shortcodes (floating="no") should NEVER be blocked by the hide setting
228 147 // This allows embedded chatbots even when floating is hidden
229 148
230 149 $is_floating = $attributes['floating'] === 'yes';
150 + $bot_id = sanitize_key($bot_id); // Sanitize bot ID
231 151
232 152 // Rest of your existing shortcode rendering logic continues unchanged...
233 153 // [All the existing HTML generation code remains the same]
234 154