PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.7.3
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.7.3
3.5.9 3.5.8 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
462 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 if ( $query->mode === 'chat' ) {
176 $context = apply_filters( 'mwai_context_search', $context, $query, [ 'embeddingsIndex' => $embeddingsIndex ] );
177 if ( !empty( $context ) ) {
178 if ( isset( $context['content'] ) ) {
179 $content = $this->core->cleanSentences( $context['content'] );
180 $query->injectContext( $content );
181 }
182 else {
183 error_log("AI Engine: A context without content was returned.");
184 }
185 }
186 }
187 }
188
189 // Process Query
190 if ( $stream ) {
191 $streamCallback = function( $reply ) {
192 //$raw = _wp_specialchars( $reply, ENT_NOQUOTES, 'UTF-8', true );
193 $raw = $reply;
194 $this->stream_push( [ 'type' => 'live', 'data' => $raw ] );
195 if ( ob_get_level() > 0 ) {
196 ob_flush();
197 }
198 flush();
199 };
200 header( 'Cache-Control: no-cache' );
201 header( 'Content-Type: text/event-stream' );
202 header( 'X-Accel-Buffering: no' ); // This is useful to disable buffering in nginx through headers.
203 ob_implicit_flush( true );
204 ob_end_flush();
205 }
206
207 $reply = $this->core->ai->run( $query, $streamCallback );
208 $rawText = $reply->result;
209 $extra = [];
210 if ( $context ) {
211 $extra = [ 'embeddings' => $context['embeddings'] ];
212 }
213
214 $rawText = apply_filters( 'mwai_chatbot_reply', $rawText, $query, $params, $extra );
215 // TODO: There is no need for the shortcode_chat_formatting sice Markdown is handled on the client side.
216 // if ( $this->core->get_option( 'shortcode_chat_formatting' ) ) {
217 // $html = $this->core->markdown_to_html( $rawText );
218 // }
219
220 $restRes = [
221 'success' => true,
222 'reply' => $rawText,
223 'images' => $reply->getType() === 'images' ? $reply->results : null,
224 'usage' => $reply->usage
225 ];
226
227 // Process Reply
228 if ( $stream ) {
229 $this->stream_push( [ 'type' => 'end', 'data' => json_encode( $restRes ) ] );
230 die();
231 }
232 else {
233 return new WP_REST_Response( $restRes, 200 );
234 }
235
236 }
237 catch ( Exception $e ) {
238 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
239 if ( $stream ) {
240 $this->stream_push( [ 'type' => 'error', 'data' => $message ] );
241 }
242 else {
243 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
244 }
245 }
246 }
247
248 public function stream_push( $data ) {
249 $out = "data: " . json_encode( $data );
250 echo $out;
251 echo "\n\n";
252 if (ob_get_level() > 0) {
253 ob_end_flush();
254 }
255 flush();
256 }
257
258 public function inject_chat() {
259 $params = $this->core->getChatbot( $this->siteWideChatId );
260 $cleanParams = [];
261 if ( !empty( $params ) ) {
262 $cleanParams['window'] = true;
263 $cleanParams['id'] = $this->siteWideChatId;
264 echo $this->chat_shortcode( $cleanParams );
265 }
266 return null;
267 }
268
269 public function build_front_params( $id, $botId ) {
270 $frontSystem = [
271 'id' => $id,
272 'botId' => $botId,
273 'userData' => $this->core->getUserData(),
274 'sessionId' => $this->core->get_session_id(),
275 'restNonce' => $this->core->get_nonce(),
276 'contextId' => get_the_ID(),
277 'pluginUrl' => MWAI_URL,
278 'restUrl' => untrailingslashit( rest_url() ),
279 'debugMode' => $this->core->get_option( 'debug_mode' ),
280 'typewriter' => $this->core->get_option( 'shortcode_chat_typewriter' ),
281 'speech_recognition' => $this->core->get_option( 'speech_recognition' ),
282 'speech_synthesis' => $this->core->get_option( 'speech_synthesis' ),
283 'stream' => $this->core->get_option( 'shortcode_chat_stream' ),
284 ];
285 return $frontSystem;
286 }
287
288 public function chat_shortcode( $atts ) {
289 $atts = empty($atts) ? [] : $atts;
290
291 // Properly handle the id, botId, and chatbot
292 // We have the same in discussions.php
293 $chatbot = null;
294 $botId = $atts['chat_id'] ?? null;
295 $id = $atts['id'] ?? null;
296 unset( $atts['chat_id'], $atts['id'] );
297 if ( $botId ) {
298 $chatbot = $this->core->getChatbot( $botId );
299 if ( !$chatbot ) {
300 return "AI Engine: Chatbot not found.";
301 }
302 }
303 if ( $id && !$chatbot ) {
304 $chatbot = $this->core->getChatbot( $id );
305 $botId = $chatbot ? $id : 'default';
306 }
307 $chatbot = $chatbot ?: $this->core->getChatbot( 'default' );
308 $botId = $botId ?: 'default';
309 $isCustom = $botId == 'default' && isset( $atts['id'] );
310
311 $atts = apply_filters( 'mwai_chatbot_params', $atts, $chatbot, $isCustom );
312
313 // Rename the keys of the atts into camelCase to match the internal params system.
314 $atts = array_map( function( $key, $value ) {
315 $key = str_replace( '_', ' ', $key );
316 $key = ucwords( $key );
317 $key = str_replace( ' ', '', $key );
318 $key = lcfirst( $key );
319 return [ $key => $value ];
320 }, array_keys( $atts ), $atts );
321 $atts = array_merge( ...$atts );
322
323 $frontParams = [];
324 foreach ( MWAI_CHATBOT_FRONT_PARAMS as $param ) {
325 if ( isset( $atts[$param] ) ) {
326 if ( $param === 'localMemory' ) {
327 $frontParams[$param] = $atts[$param] === 'true';
328 }
329 else {
330 $frontParams[$param] = $atts[$param];
331 }
332 }
333 else if ( isset( $chatbot[$param] ) ) {
334 $frontParams[$param] = $chatbot[$param];
335 }
336 }
337
338 // Server Params
339 $serverParams = [];
340 foreach ( MWAI_CHATBOT_SERVER_PARAMS as $param ) {
341 if ( isset( $atts[$param] ) ) {
342 $serverParams[$param] = $atts[$param];
343 }
344 }
345
346 // Front Params
347 $frontSystem = $this->build_front_params( $id, $botId );
348
349 // Clean Params
350 $frontParams = $this->cleanParams( $frontParams );
351 $frontSystem = $this->cleanParams( $frontSystem );
352 $serverParams = $this->cleanParams( $serverParams );
353
354 // Server-side: Keep the System Params
355 if ( count( $serverParams ) > 0 ) {
356 if ( !$isCustom ) {
357 $id = md5( json_encode( $serverParams ) );
358 $botId = null;
359 $frontSystem['id'] = $id;
360 $frontSystem['botId'] = $botId;
361 }
362 set_transient( 'mwai_custom_chatbot_' . $id, $serverParams, 60 * 60 * 24 );
363 }
364
365 // Client-side: Prepare JSON for Front Params and System Params
366 $theme = isset( $frontParams['themeId'] ) ? $this->core->getTheme( $frontParams['themeId'] ) : null;
367 $jsonFrontParams = htmlspecialchars( json_encode( $frontParams ), ENT_QUOTES, 'UTF-8' );
368 $jsonFrontSystem = htmlspecialchars( json_encode( $frontSystem ), ENT_QUOTES, 'UTF-8' );
369 $jsonFrontTheme = htmlspecialchars( json_encode( $theme ), ENT_QUOTES, 'UTF-8' );
370 //$jsonAttributes = htmlspecialchars(json_encode($atts), ENT_QUOTES, 'UTF-8');
371
372 $this->enqueue_scripts();
373 return "<div class='mwai-chatbot-container' data-params='{$jsonFrontParams}' data-system='{$jsonFrontSystem}' data-theme='{$jsonFrontTheme}'></div>";
374 }
375
376 function shortcode_chat_discussions( $atts ) {
377 $atts = empty($atts) ? [] : $atts;
378
379 // Properly handle the id, botId, and chatbot
380 // We have the same in chatbot.php
381 $chatbot = null;
382 $botId = $atts['chat_id'] ?? null;
383 $id = $atts['id'] ?? null;
384 unset( $atts['chat_id'], $atts['id'] );
385 if ( $botId ) {
386 $chatbot = $this->core->getChatbot( $botId );
387 if ( !$chatbot ) {
388 return "AI Engine: Chatbot not found.";
389 }
390 }
391 if ( $id && !$chatbot ) {
392 $chatbot = $this->core->getChatbot( $id );
393 $botId = $chatbot ? $id : 'default';
394 }
395 $chatbot = $chatbot ?: $this->core->getChatbot( 'default' );
396 $botId = $botId ?: 'default';
397 $isCustom = $botId == 'default' && isset( $atts['id'] );
398
399 // Rename the keys of the atts into camelCase to match the internal params system.
400 $atts = array_map( function( $key, $value ) {
401 $key = str_replace( '_', ' ', $key );
402 $key = ucwords( $key );
403 $key = str_replace( ' ', '', $key );
404 $key = lcfirst( $key );
405 return [ $key => $value ];
406 }, array_keys( $atts ), $atts );
407 $atts = array_merge( ...$atts );
408
409 // Front Params
410 $frontParams = [];
411 foreach ( MWAI_DISCUSSIONS_FRONT_PARAMS as $param ) {
412 if ( isset( $atts[$param] ) ) {
413 $frontParams[$param] = $atts[$param];
414 }
415 else if ( isset( $chatbot[$param] ) ) {
416 $frontParams[$param] = $chatbot[$param];
417 }
418 }
419
420 // Server Params
421 $serverParams = [];
422 foreach ( MWAI_DISCUSSIONS_SERVER_PARAMS as $param ) {
423 if ( isset( $atts[$param] ) ) {
424 $serverParams[$param] = $atts[$param];
425 }
426 }
427
428
429 // Front System
430 $frontSystem = $this->build_front_params( $id, $botId );
431
432 // Clean Params
433 $frontParams = $this->cleanParams( $frontParams );
434 $frontSystem = $this->cleanParams( $frontSystem );
435 $serverParams = $this->cleanParams( $serverParams );
436
437 $theme = isset( $frontParams['themeId'] ) ? $this->core->getTheme( $frontParams['themeId'] ) : null;
438 $jsonFrontParams = htmlspecialchars( json_encode( $frontParams ), ENT_QUOTES, 'UTF-8' );
439 $jsonFrontSystem = htmlspecialchars( json_encode( $frontSystem ), ENT_QUOTES, 'UTF-8' );
440 $jsonFrontTheme = htmlspecialchars( json_encode( $theme ), ENT_QUOTES, 'UTF-8' );
441
442 return "<div class='mwai-discussions-container' data-params='{$jsonFrontParams}' data-system='{$jsonFrontSystem}' data-theme='{$jsonFrontTheme}'></div>";
443 }
444
445 function cleanParams( &$params ) {
446 foreach ( $params as $param => $value ) {
447 if ( empty( $value ) || is_array( $value ) ) {
448 continue;
449 }
450 $lowerCaseValue = strtolower( $value );
451 if ( $lowerCaseValue === 'true' || $lowerCaseValue === 'false' || is_bool( $value ) ) {
452 $params[$param] = filter_var( $value, FILTER_VALIDATE_BOOLEAN );
453 }
454 else if ( is_numeric( $value ) ) {
455 $params[$param] = filter_var( $value, FILTER_VALIDATE_FLOAT );
456 }
457 }
458 return $params;
459 }
460
461 }
462