PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.8.7
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.8.7
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
466 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', 'textNewChat' ] );
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 $stream = $params['stream'] ?? false;
87 $newMessage = trim( $params['newMessage'] ?? '' );
88 $chatbot = null;
89
90 if ( !$this->basics_security_check( $id, $botId, $newMessage )) {
91 return new WP_REST_Response( [
92 'success' => false,
93 'message' => 'Sorry, your query has been rejected.' ], 403
94 );
95 }
96
97 // Custom Chatbot
98 if ( $id ) {
99 $chatbot = get_transient( 'mwai_custom_chatbot_' . $id );
100 }
101 // Registered Chatbot
102 if ( !$chatbot && $botId ) {
103 $chatbot = $this->core->getChatbot( $botId );
104 }
105
106 if ( !$chatbot ) {
107 error_log("AI Engine: No chatbot was found for this query.");
108 return new WP_REST_Response( [
109 'success' => false,
110 'message' => 'Sorry, your query has been rejected.' ], 403
111 );
112 }
113
114 // Create QueryText
115 $context = null;
116 $mode = $chatbot['mode'] ?? 'chat';
117
118 if ( $mode === 'images' ) {
119 $query = new Meow_MWAI_Query_Image( $newMessage );
120
121 // Handle Params
122 $newParams = [];
123 foreach ( $chatbot as $key => $value ) {
124 $newParams[$key] = $value;
125 }
126 foreach ( $params as $key => $value ) {
127 $newParams[$key] = $value;
128 }
129 $params = apply_filters( 'mwai_chatbot_params', $newParams );
130 $params['env'] = empty( $params['env'] ) ? 'chatbot' : $params['env'];
131 $query->injectParams( $params );
132 }
133 else {
134 $query = new Meow_MWAI_Query_Text( $newMessage, 1024 );
135 //$query->setIsChat( true );
136 $streamCallback = null;
137
138 // Handle Params
139 $newParams = [];
140 foreach ( $chatbot as $key => $value ) {
141 $newParams[$key] = $value;
142 }
143 foreach ( $params as $key => $value ) {
144 $newParams[$key] = $value;
145 }
146 $params = apply_filters( 'mwai_chatbot_params', $newParams );
147 $params['env'] = empty( $params['env'] ) ? 'chatbot' : $params['env'];
148 $query->injectParams( $params );
149
150 // Takeover
151 $takeoverAnswer = apply_filters( 'mwai_chatbot_takeover', null, $query, $params );
152 if ( !empty( $takeoverAnswer ) ) {
153 return new WP_REST_Response( [
154 'success' => true,
155 'reply' => $takeoverAnswer,
156 'usage' => null
157 ], 200 );
158 }
159
160 // Moderation
161 if ( $this->core->get_option( 'shortcode_chat_moderation' ) ) {
162 global $mwai;
163 $isFlagged = $mwai->moderationCheck( $query->prompt );
164 if ( $isFlagged ) {
165 return new WP_REST_Response( [
166 'success' => false,
167 'message' => 'Sorry, your message has been rejected by moderation.' ], 403
168 );
169 }
170 }
171
172 // Awareness & Embeddings
173 // TODO: This is same in Chatbot Legacy and Forms, maybe we should move it to the core?
174 $embeddingsIndex = $params['embeddingsIndex'] ?? null;
175 $embeddingsNamespace = $params['embeddingsNamespace'] ?? null;
176 if ( $query->mode === 'chat' ) {
177 $context = apply_filters( 'mwai_context_search', $context, $query, [
178 'embeddingsIndex' => $embeddingsIndex,
179 'embeddingsNamespace' => $embeddingsNamespace
180 ] );
181 if ( !empty( $context ) ) {
182 if ( isset( $context['content'] ) ) {
183 $content = $this->core->cleanSentences( $context['content'] );
184 $query->injectContext( $content );
185 }
186 else {
187 error_log( "AI Engine: A context without content was returned." );
188 }
189 }
190 }
191 }
192
193 // Process Query
194 if ( $stream ) {
195 $streamCallback = function( $reply ) {
196 //$raw = _wp_specialchars( $reply, ENT_NOQUOTES, 'UTF-8', true );
197 $raw = $reply;
198 $this->stream_push( [ 'type' => 'live', 'data' => $raw ] );
199 if ( ob_get_level() > 0 ) {
200 ob_flush();
201 }
202 flush();
203 };
204 header( 'Cache-Control: no-cache' );
205 header( 'Content-Type: text/event-stream' );
206 header( 'X-Accel-Buffering: no' ); // This is useful to disable buffering in nginx through headers.
207 ob_implicit_flush( true );
208 ob_end_flush();
209 }
210
211 $reply = $this->core->ai->run( $query, $streamCallback );
212 $rawText = $reply->result;
213 $extra = [];
214 if ( $context ) {
215 $extra = [ 'embeddings' => $context['embeddings'] ];
216 }
217
218 $rawText = apply_filters( 'mwai_chatbot_reply', $rawText, $query, $params, $extra );
219 // TODO: There is no need for the shortcode_chat_formatting sice Markdown is handled on the client side.
220 // if ( $this->core->get_option( 'shortcode_chat_formatting' ) ) {
221 // $html = $this->core->markdown_to_html( $rawText );
222 // }
223
224 $restRes = [
225 'success' => true,
226 'reply' => $rawText,
227 'images' => $reply->getType() === 'images' ? $reply->results : null,
228 'usage' => $reply->usage
229 ];
230
231 // Process Reply
232 if ( $stream ) {
233 $this->stream_push( [ 'type' => 'end', 'data' => json_encode( $restRes ) ] );
234 die();
235 }
236 else {
237 return new WP_REST_Response( $restRes, 200 );
238 }
239
240 }
241 catch ( Exception $e ) {
242 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
243 if ( $stream ) {
244 $this->stream_push( [ 'type' => 'error', 'data' => $message ] );
245 }
246 else {
247 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
248 }
249 }
250 }
251
252 public function stream_push( $data ) {
253 $out = "data: " . json_encode( $data );
254 echo $out;
255 echo "\n\n";
256 if (ob_get_level() > 0) {
257 ob_end_flush();
258 }
259 flush();
260 }
261
262 public function inject_chat() {
263 $params = $this->core->getChatbot( $this->siteWideChatId );
264 $cleanParams = [];
265 if ( !empty( $params ) ) {
266 $cleanParams['window'] = true;
267 $cleanParams['id'] = $this->siteWideChatId;
268 echo $this->chat_shortcode( $cleanParams );
269 }
270 return null;
271 }
272
273 public function build_front_params( $id, $botId ) {
274 $frontSystem = [
275 'id' => $id,
276 'botId' => $botId,
277 'userData' => $this->core->getUserData(),
278 'sessionId' => $this->core->get_session_id(),
279 'restNonce' => $this->core->get_nonce(),
280 'contextId' => get_the_ID(),
281 'pluginUrl' => MWAI_URL,
282 'restUrl' => untrailingslashit( rest_url() ),
283 'debugMode' => $this->core->get_option( 'debug_mode' ),
284 'typewriter' => $this->core->get_option( 'shortcode_chat_typewriter' ),
285 'speech_recognition' => $this->core->get_option( 'speech_recognition' ),
286 'speech_synthesis' => $this->core->get_option( 'speech_synthesis' ),
287 'stream' => $this->core->get_option( 'shortcode_chat_stream' ),
288 ];
289 return $frontSystem;
290 }
291
292 public function chat_shortcode( $atts ) {
293 $atts = empty($atts) ? [] : $atts;
294
295 // Properly handle the id, botId, and chatbot
296 // We have the same in discussions.php
297 $chatbot = null;
298 $botId = $atts['chat_id'] ?? null;
299 $id = $atts['id'] ?? null;
300 unset( $atts['chat_id'], $atts['id'] );
301 if ( $botId ) {
302 $chatbot = $this->core->getChatbot( $botId );
303 if ( !$chatbot ) {
304 return "AI Engine: Chatbot not found.";
305 }
306 }
307 if ( $id && !$chatbot ) {
308 $chatbot = $this->core->getChatbot( $id );
309 $botId = $chatbot ? $id : 'default';
310 }
311 $chatbot = $chatbot ?: $this->core->getChatbot( 'default' );
312 $botId = $botId ?: 'default';
313 $isCustom = $botId == 'default' && isset( $atts['id'] );
314
315 $atts = apply_filters( 'mwai_chatbot_params', $atts, $chatbot, $isCustom );
316
317 // Rename the keys of the atts into camelCase to match the internal params system.
318 $atts = array_map( function( $key, $value ) {
319 $key = str_replace( '_', ' ', $key );
320 $key = ucwords( $key );
321 $key = str_replace( ' ', '', $key );
322 $key = lcfirst( $key );
323 return [ $key => $value ];
324 }, array_keys( $atts ), $atts );
325 $atts = array_merge( ...$atts );
326
327 $frontParams = [];
328 foreach ( MWAI_CHATBOT_FRONT_PARAMS as $param ) {
329 if ( isset( $atts[$param] ) ) {
330 if ( $param === 'localMemory' ) {
331 $frontParams[$param] = $atts[$param] === 'true';
332 }
333 else {
334 $frontParams[$param] = $atts[$param];
335 }
336 }
337 else if ( isset( $chatbot[$param] ) ) {
338 $frontParams[$param] = $chatbot[$param];
339 }
340 }
341
342 // Server Params
343 $serverParams = [];
344 foreach ( MWAI_CHATBOT_SERVER_PARAMS as $param ) {
345 if ( isset( $atts[$param] ) ) {
346 $serverParams[$param] = $atts[$param];
347 }
348 }
349
350 // Front Params
351 $frontSystem = $this->build_front_params( $id, $botId );
352
353 // Clean Params
354 $frontParams = $this->cleanParams( $frontParams );
355 $frontSystem = $this->cleanParams( $frontSystem );
356 $serverParams = $this->cleanParams( $serverParams );
357
358 // Server-side: Keep the System Params
359 if ( count( $serverParams ) > 0 ) {
360 if ( !$isCustom ) {
361 $id = md5( json_encode( $serverParams ) );
362 $botId = null;
363 $frontSystem['id'] = $id;
364 $frontSystem['botId'] = $botId;
365 }
366 set_transient( 'mwai_custom_chatbot_' . $id, $serverParams, 60 * 60 * 24 );
367 }
368
369 // Client-side: Prepare JSON for Front Params and System Params
370 $theme = isset( $frontParams['themeId'] ) ? $this->core->getTheme( $frontParams['themeId'] ) : null;
371 $jsonFrontParams = htmlspecialchars( json_encode( $frontParams ), ENT_QUOTES, 'UTF-8' );
372 $jsonFrontSystem = htmlspecialchars( json_encode( $frontSystem ), ENT_QUOTES, 'UTF-8' );
373 $jsonFrontTheme = htmlspecialchars( json_encode( $theme ), ENT_QUOTES, 'UTF-8' );
374 //$jsonAttributes = htmlspecialchars(json_encode($atts), ENT_QUOTES, 'UTF-8');
375
376 $this->enqueue_scripts();
377 return "<div class='mwai-chatbot-container' data-params='{$jsonFrontParams}' data-system='{$jsonFrontSystem}' data-theme='{$jsonFrontTheme}'></div>";
378 }
379
380 function shortcode_chat_discussions( $atts ) {
381 $atts = empty($atts) ? [] : $atts;
382
383 // Properly handle the id, botId, and chatbot
384 // We have the same in chatbot.php
385 $chatbot = null;
386 $botId = $atts['chat_id'] ?? null;
387 $id = $atts['id'] ?? null;
388 unset( $atts['chat_id'], $atts['id'] );
389 if ( $botId ) {
390 $chatbot = $this->core->getChatbot( $botId );
391 if ( !$chatbot ) {
392 return "AI Engine: Chatbot not found.";
393 }
394 }
395 if ( $id && !$chatbot ) {
396 $chatbot = $this->core->getChatbot( $id );
397 $botId = $chatbot ? $id : 'default';
398 }
399 $chatbot = $chatbot ?: $this->core->getChatbot( 'default' );
400 $botId = $botId ?: 'default';
401 $isCustom = $botId == 'default' && isset( $atts['id'] );
402
403 // Rename the keys of the atts into camelCase to match the internal params system.
404 $atts = array_map( function( $key, $value ) {
405 $key = str_replace( '_', ' ', $key );
406 $key = ucwords( $key );
407 $key = str_replace( ' ', '', $key );
408 $key = lcfirst( $key );
409 return [ $key => $value ];
410 }, array_keys( $atts ), $atts );
411 $atts = array_merge( ...$atts );
412
413 // Front Params
414 $frontParams = [];
415 foreach ( MWAI_DISCUSSIONS_FRONT_PARAMS as $param ) {
416 if ( isset( $atts[$param] ) ) {
417 $frontParams[$param] = $atts[$param];
418 }
419 else if ( isset( $chatbot[$param] ) ) {
420 $frontParams[$param] = $chatbot[$param];
421 }
422 }
423
424 // Server Params
425 $serverParams = [];
426 foreach ( MWAI_DISCUSSIONS_SERVER_PARAMS as $param ) {
427 if ( isset( $atts[$param] ) ) {
428 $serverParams[$param] = $atts[$param];
429 }
430 }
431
432
433 // Front System
434 $frontSystem = $this->build_front_params( $id, $botId );
435
436 // Clean Params
437 $frontParams = $this->cleanParams( $frontParams );
438 $frontSystem = $this->cleanParams( $frontSystem );
439 $serverParams = $this->cleanParams( $serverParams );
440
441 $theme = isset( $frontParams['themeId'] ) ? $this->core->getTheme( $frontParams['themeId'] ) : null;
442 $jsonFrontParams = htmlspecialchars( json_encode( $frontParams ), ENT_QUOTES, 'UTF-8' );
443 $jsonFrontSystem = htmlspecialchars( json_encode( $frontSystem ), ENT_QUOTES, 'UTF-8' );
444 $jsonFrontTheme = htmlspecialchars( json_encode( $theme ), ENT_QUOTES, 'UTF-8' );
445
446 return "<div class='mwai-discussions-container' data-params='{$jsonFrontParams}' data-system='{$jsonFrontSystem}' data-theme='{$jsonFrontTheme}'></div>";
447 }
448
449 function cleanParams( &$params ) {
450 foreach ( $params as $param => $value ) {
451 if ( empty( $value ) || is_array( $value ) ) {
452 continue;
453 }
454 $lowerCaseValue = strtolower( $value );
455 if ( $lowerCaseValue === 'true' || $lowerCaseValue === 'false' || is_bool( $value ) ) {
456 $params[$param] = filter_var( $value, FILTER_VALIDATE_BOOLEAN );
457 }
458 else if ( is_numeric( $value ) ) {
459 $params[$param] = filter_var( $value, FILTER_VALIDATE_FLOAT );
460 }
461 }
462 return $params;
463 }
464
465 }
466