| @@ -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 | |