PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.6.93
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.6.93
3.5.7 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.4.9 3.4.8 3.4.7 0.2.1 1.6.91 0.2.2 1.6.92 0.2.3 1.6.93 0.2.4 1.6.94 0.2.5 1.6.95 0.2.6 1.6.96 0.2.7 1.6.97 0.2.8 1.6.98 0.2.9 1.6.99 0.3.0 1.7.0 0.3.1 1.7.1 0.3.2 1.7.2 0.3.3 1.7.3 0.3.4 1.7.4 0.3.5 1.7.5 0.3.6 1.7.6 0.4.0 1.7.7 0.4.1 1.7.8 0.4.2 1.7.9 0.4.3 1.8.0 0.4.4 1.8.1 0.4.5 1.8.2 0.4.6 1.8.3 0.4.7 1.8.4 0.4.8 1.8.5 0.4.9 1.8.6 0.5.0 1.8.7 0.5.1 1.8.8 0.5.2 1.8.9 0.5.3 1.9.0 0.5.4 1.9.1 0.5.5 1.9.2 0.5.6 1.9.3 0.5.7 1.9.4 0.5.8 1.9.5 0.5.9 1.9.6 0.6.0 1.9.7 0.6.1 1.9.8 0.6.2 1.9.81 0.6.3 1.9.82 0.6.4 1.9.83 0.6.5 1.9.84 0.6.6 1.9.85 0.6.7 1.9.86 0.6.8 1.9.87 0.6.9 1.9.88 0.7.0 1.9.89 0.7.1 1.9.90 0.7.2 1.9.91 0.7.3 1.9.92 0.7.4 1.9.93 0.7.5 1.9.94 0.7.6 1.9.95 0.7.7 1.9.96 0.7.8 1.9.97 0.7.9 1.9.98 0.8.0 1.9.99 0.8.1 2.0.0 0.8.2 2.0.1 0.8.3 2.0.2 0.8.4 2.0.3 0.8.5 2.0.4 0.8.6 2.0.5 0.8.7 2.0.6 0.8.8 2.0.7 0.8.9 2.0.8 0.9.0 2.0.9 0.9.2 2.1.0 0.9.3 2.1.1 0.9.4 2.1.2 0.9.5 2.1.3 0.9.6 2.1.4 0.9.7 2.1.5 0.9.8 2.1.6 0.9.81 2.1.7 0.9.82 2.1.8 0.9.83 2.1.9 0.9.84 2.2.0 0.9.85 2.2.1 0.9.86 2.2.2 0.9.87 2.2.3 0.9.88 2.2.4 0.9.89 2.2.5 0.9.9 2.2.51 0.9.91 2.2.52 0.9.92 2.2.53 0.9.93 2.2.54 0.9.94 2.2.56 0.9.95 2.2.57 0.9.96 2.2.6 0.9.97 2.2.60 0.9.98 2.2.61 0.9.99 2.2.62 1.0.0 2.2.63 1.0.01 2.2.70 1.0.1 2.2.80 1.0.2 2.2.81 1.0.3 2.2.90 1.0.4 2.2.91 1.0.5 2.2.92 1.0.6 2.2.93 1.0.7 2.2.94 1.0.8 2.2.95 1.0.9 2.3.0 1.1.0 2.3.1 1.1.1 2.3.2 1.1.2 2.3.3 1.1.3 2.3.4 1.1.4 2.3.5 1.1.5 2.3.6 1.1.6 2.3.7 1.1.7 2.3.8 1.1.8 2.3.9 1.1.9 2.4.0 1.2.0 2.4.1 1.2.1 2.4.2 1.2.2 2.4.3 1.2.21 2.4.4 1.2.3 2.4.5 1.2.30 2.4.6 1.3.0 2.4.7 1.3.1 2.4.8 1.3.2 2.4.9 1.3.3 2.5.0 1.3.31 2.5.1 1.3.32 2.5.2 1.3.33 2.5.3 1.3.34 2.5.4 1.3.35 2.5.5 1.3.36 2.5.6 1.3.37 2.5.7 1.3.38 2.5.8 1.3.39 2.5.9 1.3.40 2.6.0 1.3.41 2.6.1 1.3.42 2.6.2 1.3.43 2.6.3 1.3.44 2.6.5 1.3.45 2.6.6 1.3.46 2.6.7 1.3.47 2.6.8 1.3.48 2.6.9 1.3.49 2.7.0 1.3.50 2.7.1 1.3.51 2.7.2 1.3.52 2.7.3 1.3.53 2.7.4 1.3.54 2.7.5 1.3.56 2.7.6 1.3.57 2.7.7 1.3.58 2.7.8 1.3.59 2.7.9 1.3.60 2.8.0 1.3.61 2.8.1 1.3.62 2.8.2 1.3.63 2.8.3 1.3.64 2.8.4 1.3.65 2.8.5 1.3.66 2.8.6 1.3.67 2.8.7 1.3.68 2.8.8 1.3.69 2.8.9 1.3.70 2.9.0 1.3.71 2.9.1 1.3.72 2.9.2 1.3.73 2.9.3 1.3.74 2.9.4 1.3.75 2.9.5 1.3.76 2.9.6 1.3.77 2.9.7 1.3.78 2.9.8 1.3.79 2.9.9 1.3.80 3.0.0 1.3.81 3.0.1 1.3.82 3.0.2 1.3.83 3.0.3 1.3.84 3.0.4 1.3.85 3.0.5 1.3.86 3.0.6 1.3.87 3.0.7 1.3.88 3.0.8 1.3.89 3.0.9 1.3.90 3.1.0 1.3.91 3.1.1 1.3.92 3.1.2 1.3.93 3.1.3 1.3.94 3.1.4 1.3.95 3.1.5 1.3.96 3.1.6 1.3.97 3.1.7 1.3.98 3.1.8 1.3.99 3.1.9 1.4.0 3.2.0 1.4.1 3.2.1 1.4.2 3.2.2 1.4.3 3.2.3 1.4.4 3.2.4 1.4.5 3.2.5 1.4.6 3.2.6 1.4.7 3.2.7 1.4.8 3.2.8 1.4.9 3.2.9 1.5.0 3.3.0 1.5.1 3.3.1 1.5.2 3.3.2 1.5.3 3.3.3 1.5.4 3.3.4 1.5.5 3.3.5 1.5.6 3.3.6 1.5.7 3.3.7 1.5.8 3.3.8 1.5.9 3.3.9 1.6.0 3.4.0 1.6.1 3.4.1 1.6.2 3.4.2 1.6.3 3.4.3 1.6.5 3.4.4 1.6.51 3.4.5 1.6.52 3.4.6 1.6.53 1.6.54 1.6.55 1.6.56 1.6.57 1.6.58 1.6.59 1.6.60 1.6.61 1.6.62 1.6.63 1.6.64 1.6.65 1.6.66 1.6.67 1.6.68 trunk 1.6.69 0.0.1 1.6.70 0.0.2 1.6.71 0.0.3 1.6.72 0.0.4 1.6.73 0.0.5 1.6.74 0.0.6 1.6.75 0.0.7 1.6.76 0.0.8 1.6.77 0.0.9 1.6.78 0.1.0 1.6.79 0.1.1 1.6.81 0.1.2 1.6.82 0.1.3 1.6.83 0.1.4 1.6.84 0.1.5 1.6.85 0.1.6 1.6.86 0.1.7 1.6.87 0.1.8 1.6.88 0.1.9 1.6.89 0.2.0 1.6.90
ai-engine / classes / modules / chatbot.php
ai-engine / classes / modules Last commit date
assistants.php 3 years ago chatbot.php 3 years ago chatbot_legacy.php 3 years ago discussions.php 3 years ago security.php 3 years ago
chatbot.php
447 lines
1 <?php
2
3 // Params for the chatbot (front and server)
4
5 define( 'MWAI_CHATBOT_FRONT_PARAMS', [ 'aiName', 'userName', 'guestName', 'textSend', 'textClear',
6 'textInputPlaceholder', 'textInputMaxLength', 'textCompliance', 'startSentence', 'localMemory',
7 'themeId', 'window', 'icon', 'iconText', 'iconAlt', 'iconPosition', 'fullscreen', 'copyButton'
8 ] );
9 define( 'MWAI_CHATBOT_SERVER_PARAMS', [ 'id', 'env', 'mode', 'contentAware', 'embeddingsIndex', 'context',
10 'casuallyFineTuned', 'promptEnding', 'completionEnding', 'model', 'temperature', 'maxTokens',
11 'maxResults', 'apiKey', 'service'
12 ] );
13
14 // Params for the discussions (front and server)
15
16 define( 'MWAI_DISCUSSIONS_FRONT_PARAMS', [ 'themeId' ] );
17 define( 'MWAI_DISCUSSIONS_SERVER_PARAMS', [] );
18
19 class Meow_MWAI_Modules_Chatbot {
20 private $core = null;
21 private $namespace = 'mwai-ui/v1';
22 private $siteWideChatId = null;
23
24 public function __construct() {
25 global $mwai_core;
26 $this->core = $mwai_core;
27 add_shortcode( 'mwai_chatbot_v2', array( $this, 'chat_shortcode' ) );
28 add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
29 $this->siteWideChatId = $this->core->get_option( 'botId' );
30 add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts' ) );
31
32 if ( $this->core->get_option( 'shortcode_chat_discussions' ) ) {
33 add_shortcode( 'mwai_discussions', [ $this, 'shortcode_chat_discussions' ] );
34 }
35 }
36
37 public function register_scripts() {
38 wp_register_script( 'mwai_highlight', MWAI_URL . 'vendor/highlightjs/highlight.min.js', [], '11.7', false );
39 $physical_file = trailingslashit( MWAI_PATH ) . 'app/chatbot.js';
40 $cache_buster = file_exists( $physical_file ) ? filemtime( $physical_file ) : MWAI_VERSION;
41 wp_register_script( 'mwai_chatbot', trailingslashit( MWAI_URL ) . 'app/chatbot.js',
42 [ 'wp-element' ], $cache_buster, false );
43 if ( !empty( $this->siteWideChatId ) && $this->siteWideChatId !== 'none' ) {
44 $this->enqueue_scripts();
45 add_action( 'wp_footer', array( $this, 'inject_chat' ) );
46 }
47 }
48
49 public function enqueue_scripts() {
50 wp_enqueue_script( "mwai_chatbot" );
51 if ( $this->core->get_option( 'shortcode_chat_syntax_highlighting' ) ) {
52 wp_enqueue_script( "mwai_highlight" );
53 }
54 }
55
56 public function rest_api_init() {
57 register_rest_route( $this->namespace, '/chats/submit', array(
58 'methods' => 'POST',
59 'callback' => array( $this, 'rest_chat' ),
60 'permission_callback' => '__return_true'
61 ) );
62 }
63
64 public function basics_security_check( $id, $botId, $newMessage ) {
65 if ( empty( $newMessage ) ) {
66 error_log("AI Engine: The query was rejected - message was empty.");
67 return false;
68 }
69 if ( !$botId && !$id ) {
70 error_log("AI Engine: The query was rejected - no botId nor id was specified.");
71 return false;
72 }
73 $length = strlen( $newMessage );
74 if ( $length < 1 || $length > ( 4096 - 512 ) ) {
75 error_log("AI Engine: The query was rejected - message was too short or too long.");
76 return false;
77 }
78 return true;
79 }
80
81 public function rest_chat( $request ) {
82 try {
83 $params = $request->get_json_params();
84 $id = $params['id'] ?? null;
85 $botId = $params['botId'] ?? null;
86 $newMessage = trim( $params['newMessage'] ?? '' );
87 $chatbot = null;
88
89 if ( !$this->basics_security_check( $id, $botId, $newMessage )) {
90 return new WP_REST_Response( [
91 'success' => false,
92 'message' => 'Sorry, your query has been rejected.' ], 403
93 );
94 }
95
96 // Custom Chatbot
97 if ( $id ) {
98 $chatbot = get_transient( 'mwai_custom_chatbot_' . $id );
99 }
100 // Registered Chatbot
101 if ( !$chatbot && $botId ) {
102 $chatbot = $this->core->getChatbot( $botId );
103 }
104
105 if ( !$chatbot ) {
106 error_log("AI Engine: No chatbot was found for this query.");
107 return new WP_REST_Response( [
108 'success' => false,
109 'message' => 'Sorry, your query has been rejected.' ], 403
110 );
111 }
112
113 // Create QueryText
114 $context = null;
115 $mode = $chatbot['mode'] ?? 'chat';
116
117 if ( $mode === 'images' ) {
118 $query = new Meow_MWAI_Query_Image( $newMessage );
119
120 // Handle Params
121 $newParams = [];
122 foreach ( $chatbot as $key => $value ) {
123 $newParams[$key] = $value;
124 }
125 foreach ( $params as $key => $value ) {
126 $newParams[$key] = $value;
127 }
128 $params = apply_filters( 'mwai_chatbot_params', $newParams );
129 $params['env'] = empty( $params['env'] ) ? 'chatbot' : $params['env'];
130 $query->injectParams( $params );
131 }
132 else {
133 $query = new Meow_MWAI_Query_Text( $newMessage, 1024 );
134 //$query->setIsChat( true );
135 $streamCallback = null;
136
137 // Handle Params
138 $newParams = [];
139 foreach ( $chatbot as $key => $value ) {
140 $newParams[$key] = $value;
141 }
142 foreach ( $params as $key => $value ) {
143 $newParams[$key] = $value;
144 }
145 $params = apply_filters( 'mwai_chatbot_params', $newParams );
146 $params['env'] = empty( $params['env'] ) ? 'chatbot' : $params['env'];
147 $query->injectParams( $params );
148
149 // Takeover
150 $takeoverAnswer = apply_filters( 'mwai_chatbot_takeover', null, $query, $params );
151 if ( !empty( $takeoverAnswer ) ) {
152 return new WP_REST_Response( [ 'success' => true, 'reply' => $takeoverAnswer,
153 'html' => $takeoverAnswer, 'usage' => null ], 200 );
154 }
155
156 // Moderation
157 if ( $this->core->get_option( 'shortcode_chat_moderation' ) ) {
158 global $mwai;
159 $isFlagged = $mwai->moderationCheck( $query->prompt );
160 if ( $isFlagged ) {
161 return new WP_REST_Response( [
162 'success' => false,
163 'message' => 'Sorry, your message has been rejected by moderation.' ], 403
164 );
165 }
166 }
167
168 // Awareness & Embeddings
169 // TODO: This is same in Chatbot Legacy and Forms, maybe we should move it to the core?
170 $embeddingsIndex = $params['embeddingsIndex'] ?? null;
171 if ( $query->mode === 'chat' ) {
172 $context = apply_filters( 'mwai_context_search', $context, $query, [ 'embeddingsIndex' => $embeddingsIndex ] );
173 if ( !empty( $context ) ) {
174 if ( isset( $context['content'] ) ) {
175 $content = $this->core->cleanSentences( $context['content'] );
176 $query->injectContext( $content );
177 }
178 else {
179 error_log("AI Engine: A context without content was returned.");
180 }
181 }
182 }
183 }
184
185 // Process Query
186 if ( MWAI_STREAM ) {
187 $streamCallback = function( $reply ) {
188 $raw = _wp_specialchars( $reply, ENT_NOQUOTES, 'UTF-8', true );
189 $this->stream_push( [ 'type' => 'stream', 'data' => $raw ] );
190 };
191 ob_implicit_flush( true );
192 ob_end_flush();
193 header( 'Content-Type: text/event-stream' );
194 header( 'Cache-Control: no-cache' );
195 }
196
197 $reply = $this->core->ai->run( $query, $streamCallback );
198 $rawText = $reply->result;
199 $extra = [];
200 if ( $context ) {
201 $extra = [ 'embeddings' => $context['embeddings'] ];
202 }
203 $html = apply_filters( 'mwai_chatbot_reply', $rawText, $query, $params, $extra );
204 if ( $this->core->get_option( 'shortcode_chat_formatting' ) ) {
205 $html = $this->core->markdown_to_html( $html );
206 }
207 $restRes = [
208 'success' => true,
209 'reply' => $rawText,
210 'images' => $reply->getType() === 'images' ? $reply->results : null,
211 'html' => $html,
212 'usage' => $reply->usage
213 ];
214
215 // Process Reply
216 if ( MWAI_STREAM ) {
217 $this->stream_push( [ 'type' => 'reply', 'data' => $restRes['html'] ] );
218 die();
219 }
220 else {
221 return new WP_REST_Response( $restRes, 200 );
222 }
223
224 }
225 catch ( Exception $e ) {
226 if ( MWAI_STREAM ) {
227 $this->stream_push( [ 'type' => 'error', 'data' => $e->getMessage() ] );
228 }
229 else {
230 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
231 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
232 }
233 }
234 }
235
236 public function stream_push( $data ) {
237 $out = "data: " . json_encode( $data );
238 error_log( $out );
239 echo $out;
240 //echo "data: ok";
241 echo "\n\n";
242 ob_end_flush();
243 flush();
244 }
245
246 public function inject_chat() {
247 $params = $this->core->getChatbot( $this->siteWideChatId );
248 $cleanParams = [];
249 if ( !empty( $params ) ) {
250 $cleanParams['window'] = true;
251 $cleanParams['id'] = $this->siteWideChatId;
252 echo $this->chat_shortcode( $cleanParams );
253 }
254 return null;
255 }
256
257 public function build_front_params( $id, $botId ) {
258 $frontSystem = [
259 'id' => $id,
260 'botId' => $botId,
261 'userData' => $this->core->getUserData(),
262 'sessionId' => $this->core->get_session_id(),
263 'restNonce' => $this->core->get_nonce(),
264 'contextId' => get_the_ID(),
265 'pluginUrl' => MWAI_URL,
266 'restUrl' => untrailingslashit( rest_url() ),
267 'debugMode' => $this->core->get_option( 'debug_mode' ),
268 'typewriter' => $this->core->get_option( 'shortcode_chat_typewriter' ),
269 'speech_recognition' => $this->core->get_option( 'speech_recognition' ),
270 'speech_synthesis' => $this->core->get_option( 'speech_synthesis' ),
271 ];
272 return $frontSystem;
273 }
274
275 public function chat_shortcode( $atts ) {
276 $atts = empty($atts) ? [] : $atts;
277
278 // Properly handle the id, botId, and chatbot
279 // We have the same in discussions.php
280 $chatbot = null;
281 $botId = $atts['chat_id'] ?? null;
282 $id = $atts['id'] ?? null;
283 unset( $atts['chat_id'], $atts['id'] );
284 if ( $botId ) {
285 $chatbot = $this->core->getChatbot( $botId );
286 if ( !$chatbot ) {
287 return "AI Engine: Chatbot not found.";
288 }
289 }
290 if ( $id && !$chatbot ) {
291 $chatbot = $this->core->getChatbot( $id );
292 $botId = $chatbot ? $id : 'default';
293 }
294 $chatbot = $chatbot ?: $this->core->getChatbot( 'default' );
295 $botId = $botId ?: 'default';
296 $isCustom = $botId == 'default' && isset( $atts['id'] );
297
298 // Rename the keys of the atts into camelCase to match the internal params system.
299 $atts = array_map( function( $key, $value ) {
300 $key = str_replace( '_', ' ', $key );
301 $key = ucwords( $key );
302 $key = str_replace( ' ', '', $key );
303 $key = lcfirst( $key );
304 return [ $key => $value ];
305 }, array_keys( $atts ), $atts );
306 $atts = array_merge( ...$atts );
307
308 $frontParams = [];
309 foreach ( MWAI_CHATBOT_FRONT_PARAMS as $param ) {
310 if ( isset( $atts[$param] ) ) {
311 if ( $param === 'localMemory' ) {
312 $frontParams[$param] = $atts[$param] === 'true';
313 }
314 else {
315 $frontParams[$param] = $atts[$param];
316 }
317 }
318 else if ( isset( $chatbot[$param] ) ) {
319 $frontParams[$param] = $chatbot[$param];
320 }
321 }
322
323 // Server Params
324 $serverParams = [];
325 foreach ( MWAI_CHATBOT_SERVER_PARAMS as $param ) {
326 if ( isset( $atts[$param] ) ) {
327 $serverParams[$param] = $atts[$param];
328 }
329 }
330
331 // Front Params
332 $frontSystem = $this->build_front_params( $id, $botId );
333
334 // Clean Params
335 $frontParams = $this->cleanParams( $frontParams );
336 $frontSystem = $this->cleanParams( $frontSystem );
337 $serverParams = $this->cleanParams( $serverParams );
338
339 // Server-side: Keep the System Params
340 if ( count( $serverParams ) > 0 ) {
341 if ( !$isCustom ) {
342 $id = md5( json_encode( $serverParams ) );
343 $botId = null;
344 $frontSystem['id'] = $id;
345 $frontSystem['botId'] = $botId;
346 }
347 set_transient( 'mwai_custom_chatbot_' . $id, $serverParams, 60 * 60 * 24 );
348 }
349
350 // Client-side: Prepare JSON for Front Params and System Params
351 $theme = isset( $frontParams['themeId'] ) ? $this->core->getTheme( $frontParams['themeId'] ) : null;
352 $jsonFrontParams = htmlspecialchars( json_encode( $frontParams ), ENT_QUOTES, 'UTF-8' );
353 $jsonFrontSystem = htmlspecialchars( json_encode( $frontSystem ), ENT_QUOTES, 'UTF-8' );
354 $jsonFrontTheme = htmlspecialchars( json_encode( $theme ), ENT_QUOTES, 'UTF-8' );
355 //$jsonAttributes = htmlspecialchars(json_encode($atts), ENT_QUOTES, 'UTF-8');
356
357 $this->enqueue_scripts();
358 return "<div class='mwai-chatbot-container' data-params='{$jsonFrontParams}' data-system='{$jsonFrontSystem}' data-theme='{$jsonFrontTheme}'></div>";
359 }
360
361 function shortcode_chat_discussions( $atts ) {
362 $atts = empty($atts) ? [] : $atts;
363
364 // Properly handle the id, botId, and chatbot
365 // We have the same in chatbot.php
366 $chatbot = null;
367 $botId = $atts['chat_id'] ?? null;
368 $id = $atts['id'] ?? null;
369 unset( $atts['chat_id'], $atts['id'] );
370 if ( $botId ) {
371 $chatbot = $this->core->getChatbot( $botId );
372 if ( !$chatbot ) {
373 return "AI Engine: Chatbot not found.";
374 }
375 }
376 if ( $id && !$chatbot ) {
377 $chatbot = $this->core->getChatbot( $id );
378 $botId = $chatbot ? $id : 'default';
379 }
380 $chatbot = $chatbot ?: $this->core->getChatbot( 'default' );
381 $botId = $botId ?: 'default';
382 $isCustom = $botId == 'default' && isset( $atts['id'] );
383
384 // Rename the keys of the atts into camelCase to match the internal params system.
385 $atts = array_map( function( $key, $value ) {
386 $key = str_replace( '_', ' ', $key );
387 $key = ucwords( $key );
388 $key = str_replace( ' ', '', $key );
389 $key = lcfirst( $key );
390 return [ $key => $value ];
391 }, array_keys( $atts ), $atts );
392 $atts = array_merge( ...$atts );
393
394 // Front Params
395 $frontParams = [];
396 foreach ( MWAI_DISCUSSIONS_FRONT_PARAMS as $param ) {
397 if ( isset( $atts[$param] ) ) {
398 $frontParams[$param] = $atts[$param];
399 }
400 else if ( isset( $chatbot[$param] ) ) {
401 $frontParams[$param] = $chatbot[$param];
402 }
403 }
404
405 // Server Params
406 $serverParams = [];
407 foreach ( MWAI_DISCUSSIONS_SERVER_PARAMS as $param ) {
408 if ( isset( $atts[$param] ) ) {
409 $serverParams[$param] = $atts[$param];
410 }
411 }
412
413
414 // Front System
415 $frontSystem = $this->build_front_params( $id, $botId );
416
417 // Clean Params
418 $frontParams = $this->cleanParams( $frontParams );
419 $frontSystem = $this->cleanParams( $frontSystem );
420 $serverParams = $this->cleanParams( $serverParams );
421
422 $theme = isset( $frontParams['themeId'] ) ? $this->core->getTheme( $frontParams['themeId'] ) : null;
423 $jsonFrontParams = htmlspecialchars( json_encode( $frontParams ), ENT_QUOTES, 'UTF-8' );
424 $jsonFrontSystem = htmlspecialchars( json_encode( $frontSystem ), ENT_QUOTES, 'UTF-8' );
425 $jsonFrontTheme = htmlspecialchars( json_encode( $theme ), ENT_QUOTES, 'UTF-8' );
426
427 return "<div class='mwai-discussions-container' data-params='{$jsonFrontParams}' data-system='{$jsonFrontSystem}' data-theme='{$jsonFrontTheme}'></div>";
428 }
429
430 function cleanParams( &$params ) {
431 foreach ( $params as $param => $value ) {
432 if ( empty( $value ) || is_array( $value ) ) {
433 continue;
434 }
435 $lowerCaseValue = strtolower( $value );
436 if ( $lowerCaseValue === 'true' || $lowerCaseValue === 'false' || is_bool( $value ) ) {
437 $params[$param] = filter_var( $value, FILTER_VALIDATE_BOOLEAN );
438 }
439 else if ( is_numeric( $value ) ) {
440 $params[$param] = filter_var( $value, FILTER_VALIDATE_FLOAT );
441 }
442 }
443 return $params;
444 }
445
446 }
447