PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.6.3
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.6.3
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 / core.php
ai-engine / classes Last commit date
modules 3 years ago admin.php 3 years ago ai.php 3 years ago answer.php 3 years ago api.php 3 years ago core.php 3 years ago init.php 3 years ago openai.php 3 years ago query.php 3 years ago queryembed.php 3 years ago queryimage.php 3 years ago querytext.php 3 years ago querytranscribe.php 3 years ago rest.php 3 years ago security.php 3 years ago
core.php
494 lines
1 <?php
2
3 require_once( MWAI_PATH . '/vendor/autoload.php' );
4 require_once( MWAI_PATH . '/constants/init.php' );
5
6 use Rahul900day\Gpt3Encoder\Encoder;
7
8 define( 'MWAI_IMG_WAND', MWAI_URL . '/images/wand.png' );
9 define( 'MWAI_IMG_WAND_HTML', "<img style='height: 22px; margin-bottom: -5px; margin-right: 8px;'
10 src='" . MWAI_IMG_WAND . "' alt='AI Wand' />" );
11 define( 'MWAI_IMG_WAND_HTML_XS', "<img style='height: 16px; margin-bottom: -2px;'
12 src='" . MWAI_IMG_WAND . "' alt='AI Wand' />" );
13 class Meow_MWAI_Core
14 {
15 public $admin = null;
16 public $is_rest = false;
17 public $is_cli = false;
18 public $site_url = null;
19 public $ai = null;
20 private $option_name = 'mwai_options';
21 private $themes_option_name = 'mwai_themes';
22 private $chatbots_option_name = 'mwai_chatbots';
23 public $defaultChatbotParams = MWAI_CHATBOT_PARAMS;
24
25 public function __construct() {
26 $this->site_url = get_site_url();
27 $this->is_rest = MeowCommon_Helpers::is_rest();
28 $this->is_cli = defined( 'WP_CLI' );
29 $this->ai = new Meow_MWAI_AI( $this );
30 add_action( 'plugins_loaded', array( $this, 'init' ) );
31 }
32
33 function init() {
34 global $mwai;
35 $mwai = new Meow_MWAI_API();
36 new Meow_MWAI_Security( $this );
37 if ( $this->is_rest ) {
38 new Meow_MWAI_Rest( $this );
39 }
40 if ( is_admin() ) {
41 new Meow_MWAI_Admin( $this );
42 new Meow_MWAI_Modules_Assistants( $this );
43 }
44 if ( $this->get_option( 'shortcode_chat' ) ) {
45 new Meow_MWAI_Modules_Chatbot();
46 new Meow_MWAI_Modules_Chatbot_Legacy();
47 new Meow_MWAI_Modules_Discussions();
48 }
49
50 // Advanced core
51 if ( class_exists( 'MeowPro_MWAI_Core' ) ) {
52 new MeowPro_MWAI_Core( $this );
53 }
54
55 // Dynamic max tokens
56 if ( $this->get_option( 'dynamic_max_tokens' ) ) {
57 add_filter( 'mwai_estimate_tokens', array( $this, 'dynamic_max_tokens' ), 10, 2 );
58 }
59 }
60
61 #region Roles & Capabilities
62
63 function can_access_settings() {
64 return apply_filters( 'mwai_allow_setup', current_user_can( 'manage_options' ) );
65 }
66
67 function can_access_features() {
68 $editor_or_admin = current_user_can( 'editor' ) || current_user_can( 'administrator' );
69 return apply_filters( 'mwai_allow_usage', $editor_or_admin );
70 }
71
72 #endregion
73
74 #region Text-Related Helpers
75
76 // Clean the text perfectly, resolve shortcodes, etc, etc.
77 function cleanText( $rawText = "" ) {
78 $text = html_entity_decode( $rawText );
79 $text = wp_strip_all_tags( $text );
80 $text = preg_replace( '/[\r\n]+/', "\n", $text );
81 return $text . " ";
82
83 // Before simplification:
84 // $text = strip_tags( $rawText );
85 // $text = strip_shortcodes( $text );
86 // $text = html_entity_decode( $text );
87 // $text = preg_replace( '/[\r\n]+/', "\n", $text );
88 // $sentences = preg_split( '/(?<=[.?!])(?=[a-zA-Z ])/', $text );
89 // foreach ( $sentences as $key => $sentence ) {
90 // $sentences[$key] = trim( $sentence );
91 // }
92 // $text = implode( " ", $sentences );
93 // $text = preg_replace( '/^[\pZ\pC]+|[\pZ\pC]+$/u', '', $text );
94 // return $text . " ";
95 }
96
97 // Make sure there are no duplicate sentences, and keep the length under a maximum length.
98 function cleanSentences( $text, $maxTokens = null ) {
99 //$sentences = preg_split( '/(?<=[.?!])(?=[a-zA-Z ])/', $text );
100 $maxTokens = $maxTokens ? $maxTokens : $this->get_option( 'context_max_tokens', 1024 );
101 $sentences = preg_split('/(?<=[.?!。.!?])+/u', $text);
102 $hashes = array();
103 $uniqueSentences = array();
104 $length = 0;
105 foreach ( $sentences as $sentence ) {
106 $sentence = preg_replace( '/^[\pZ\pC]+|[\pZ\pC]+$/u', '', $sentence );
107 $hash = md5( $sentence );
108 if ( !in_array( $hash, $hashes ) ) {
109 $tokensCount = apply_filters( 'mwai_estimate_tokens', 0, $sentence );
110 if ( $length + $tokensCount > $maxTokens ) {
111 continue;
112 }
113 $hashes[] = $hash;
114 $uniqueSentences[] = $sentence;
115 $length += $tokensCount;
116 }
117 }
118 $freshText = implode( " ", $uniqueSentences );
119 $freshText = preg_replace( '/^[\pZ\pC]+|[\pZ\pC]+$/u', '', $freshText );
120 return $freshText;
121 }
122
123 function getCleanPostContent( $postId ) {
124 $post = get_post( $postId );
125 if ( !$post ) {
126 return false;
127 }
128 $text = $post->post_content;
129 $pattern = '/\[mwai_.*?\]/';
130 $text = preg_replace( $pattern, '', $text );
131 if ( $this->get_option( 'resolve_shortcodes' ) ) {
132 $text = apply_filters( 'the_content', $text );
133 }
134 $text = $this->cleanText( $text );
135 $text = $this->cleanSentences( $text );
136 return $text;
137 }
138
139 function markdown_to_html( $content ) {
140 $Parsedown = new Parsedown();
141 $content = $Parsedown->text( $content );
142 return $content;
143 }
144
145 function get_post_language( $postId ) {
146 $locale = get_locale();
147 $code = strtolower( substr( $locale, 0, 2 ) );
148 $humanLanguage = strtr( $code, MWAI_ALL_LANGUAGES );
149 $lang = apply_filters( 'wpml_post_language_details', null, $postId );
150 if ( !empty( $lang ) ) {
151 $locale = $lang['locale'];
152 $humanLanguage = $lang['display_name'];
153 }
154 return strtolower( "$locale ($humanLanguage)" );
155 }
156 #endregion
157
158 #region Users/Sessions Helpers
159
160 function get_session_id() {
161 if ( isset( $_COOKIE['mwai_session_id'] ) ) {
162 return $_COOKIE['mwai_session_id'];
163 }
164 return "N/A";
165 }
166
167 // Get the UserID from the data, or from the current user
168 function get_user_id( $data = null ) {
169 if ( isset( $data ) && isset( $data['userId'] ) ) {
170 return (int)$data['userId'];
171 }
172 if ( is_user_logged_in() ) {
173 $current_user = wp_get_current_user();
174 if ( $current_user->ID > 0 ) {
175 return $current_user->ID;
176 }
177 }
178 return null;
179 }
180
181 function getUserData() {
182 $user = wp_get_current_user();
183 if ( empty( $user ) || empty( $user->ID ) ) {
184 return null;
185 }
186 $placeholders = array(
187 'FIRST_NAME' => get_user_meta( $user->ID, 'first_name', true ),
188 'LAST_NAME' => get_user_meta( $user->ID, 'last_name', true ),
189 'USER_LOGIN' => isset( $user ) && isset($user->data) && isset( $user->data->user_login ) ?
190 $user->data->user_login : null,
191 'DISPLAY_NAME' => isset( $user ) && isset( $user->data ) && isset( $user->data->display_name ) ?
192 $user->data->display_name : null,
193 'AVATAR_URL' => get_avatar_url( get_current_user_id() ),
194 );
195 return $placeholders;
196 }
197
198 function get_ip_address( $data = null ) {
199 if ( isset( $data ) && isset( $data['ip'] ) ) {
200 $data['ip'] = (string)$data['ip'];
201 }
202 else {
203 if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
204 $data['ip'] = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
205 }
206 else if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) ) {
207 $data['ip'] = sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] );
208 }
209 else if ( isset( $_SERVER['HTTP_X_FORWARDED_ FOR'] ) ) {
210 $data['ip'] = sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] );
211 }
212 }
213 $ip = apply_filters( 'mwai_get_ip_address', $data['ip'] );
214 return $ip;
215 }
216
217 #endregion
218
219 #region Other Helpers
220
221 function isUrl( $url ) {
222 return strpos( $url, 'http' ) === 0 ? true : false;
223 }
224
225 function getPostTypes() {
226 $excluded = array( 'attachment', 'revision', 'nav_menu_item' );
227 $post_types = array();
228 $types = get_post_types( array( 'public' => true ), 'objects' );
229 foreach ( $types as $type ) {
230 if ( in_array( $type->name, $excluded ) ) {
231 continue;
232 }
233 $post_types[] = array(
234 'name' => $type->labels->name,
235 'type' => $type->name,
236 );
237 }
238 return $post_types;
239 }
240
241 function getCleanPost( $post ) {
242 if ( is_object( $post ) ) {
243 $post = (array)$post;
244 }
245 $language = $this->get_post_language( $post['ID'] );
246 $content = apply_filters( 'mwai_pre_post_content', $post['post_content'], $post['ID'] );
247 $content = $this->cleanText( $content );
248 $content = apply_filters( 'mwai_post_content', $content, $post['ID'] );
249 $title = $post['post_title'];
250 $excerpt = $post['post_excerpt'];
251 $url = get_permalink( $post['ID'] );
252 $checksum = wp_hash( $content . $title . $url );
253 return [
254 'postId' => $post['ID'],
255 'title' => $title,
256 'content' => $content,
257 'excerpt' => $excerpt,
258 'url' => $url,
259 'language' => $language,
260 'checksum' => $checksum,
261 ];
262 }
263
264 #endregion
265
266 #region Usage & Costs
267
268 public function dynamic_max_tokens( $tokens, $text ) {
269 // Approximation (fast, no lib)
270 $asciiCount = 0;
271 $nonAsciiCount = 0;
272 for ( $i = 0; $i < mb_strlen( $text ); $i++ ) {
273 $char = mb_substr( $text, $i, 1 );
274 if ( ord( $char ) < 128 ) {
275 $asciiCount++;
276 }
277 else {
278 $nonAsciiCount++;
279 }
280 }
281 $asciiTokens = $asciiCount / 3.5;
282 $nonAsciiTokens = $nonAsciiCount * 2.5;
283 $tokens = $asciiTokens + $nonAsciiTokens;
284
285 // More exact (slower, and lib)
286 if ( PHP_VERSION_ID >= 70400 && function_exists( 'mb_convert_encoding' ) ) {
287 try {
288 $token_array = Encoder::encode( $text );
289 if ( !empty( $token_array ) ) {
290 $tokens = count( $token_array );
291 }
292 }
293 catch ( Exception $e ) {
294 error_log( $e->getMessage() );
295 }
296 }
297
298 $tokens = $tokens;
299 return (int)$tokens;
300 }
301
302 public function record_tokens_usage( $model, $prompt_tokens, $completion_tokens = 0 ) {
303 if ( !is_numeric( $prompt_tokens ) ) {
304 throw new Exception( 'Record usage: prompt_tokens is not a number.' );
305 }
306 if ( !is_numeric( $completion_tokens ) ) {
307 $completion_tokens = 0;
308 }
309 if ( !$model ) {
310 throw new Exception( 'Record usage: model is missing.' );
311 }
312 $usage = $this->get_option( 'openai_usage' );
313 $month = date( 'Y-m' );
314 if ( !isset( $usage[$month] ) ) {
315 $usage[$month] = array();
316 }
317 if ( !isset( $usage[$month][$model] ) ) {
318 $usage[$month][$model] = array(
319 'prompt_tokens' => 0,
320 'completion_tokens' => 0,
321 'total_tokens' => 0
322 );
323 }
324 $usage[$month][$model]['prompt_tokens'] += $prompt_tokens;
325 $usage[$month][$model]['completion_tokens'] += $completion_tokens;
326 $usage[$month][$model]['total_tokens'] += $prompt_tokens + $completion_tokens;
327 $this->update_option( 'openai_usage', $usage );
328 return [
329 'prompt_tokens' => $prompt_tokens,
330 'completion_tokens' => $completion_tokens,
331 'total_tokens' => $prompt_tokens + $completion_tokens
332 ];
333 }
334
335 public function record_images_usage( $model, $resolution, $images ) {
336 if ( !$model || !$resolution || !$images ) {
337 throw new Exception( 'Missing parameters for record_image_usage.' );
338 }
339 $usage = $this->get_option( 'openai_usage' );
340 $month = date( 'Y-m' );
341 if ( !isset( $usage[$month] ) ) {
342 $usage[$month] = array();
343 }
344 if ( !isset( $usage[$month][$model] ) ) {
345 $usage[$month][$model] = array(
346 'resolution' => array(),
347 'images' => 0
348 );
349 }
350 if ( !isset( $usage[$month][$model]['resolution'][$resolution] ) ) {
351 $usage[$month][$model]['resolution'][$resolution] = 0;
352 }
353 $usage[$month][$model]['resolution'][$resolution] += $images;
354 $usage[$month][$model]['images'] += $images;
355 $this->update_option( 'openai_usage', $usage );
356 return [
357 'resolution' => $resolution,
358 'images' => $images
359 ];
360 }
361
362 #endregion
363
364 #region Options
365 function getThemes()
366 {
367 $themes = get_option( $this->themes_option_name, [] );
368 $themes = empty( $themes ) ? [] : $themes;
369
370 $internalThemes = [
371 'chatgpt' => [
372 'type' => 'internal', 'name' => 'ChatGPT', 'themeId' => 'chatgpt',
373 'settings' => [], 'style' => ""
374 ],
375 'messages' => [
376 'type' => 'internal', 'name' => 'Messages', 'themeId' => 'messages',
377 'settings' => [], 'style' => ""
378 ],
379 ];
380 $customThemes = [];
381 foreach ( $themes as $theme ) {
382 if ( isset( $internalThemes[$theme['themeId']] ) ) {
383 $internalThemes[$theme['themeId']] = $theme;
384 continue;
385 }
386 $customThemes[] = $theme;
387 }
388 return array_merge(array_values($internalThemes), $customThemes);
389 }
390
391 function updateThemes( $themes ) {
392 update_option( $this->themes_option_name, $themes );
393 return $themes;
394 }
395
396 function getChatbots() {
397 $chatbots = get_option( $this->chatbots_option_name, [] );
398 if ( empty( $chatbots ) ) {
399 $chatbots = [ array_merge( MWAI_CHATBOT_DEFAULT_PARAMS, ['name' => 'Default', 'chatId' => 'default' ] ) ];
400 }
401 foreach ( $chatbots as &$chatbot ) {
402 foreach ( MWAI_CHATBOT_DEFAULT_PARAMS as $key => $value ) {
403 if ( !isset( $chatbot[$key] ) ) {
404 $chatbot[$key] = $value;
405 }
406 }
407 }
408 return $chatbots;
409 }
410
411 function getChatbot( $chatId ) {
412 $chatbots = $this->getChatbots();
413 foreach ( $chatbots as $chatbot ) {
414 if ( $chatbot['chatId'] === $chatId ) {
415 // Somehow, the default was set to "openai" when creating a new chatbot, but that overrided
416 // the default value in the Settings. It should be always empty here (except if we add this
417 // into the Settings of the chatbot).
418 $chatbot['service'] = null;
419 return $chatbot;
420 }
421 }
422 return null;
423 }
424
425 function getTheme( $themeId ) {
426 $themes = $this->getThemes();
427 foreach ( $themes as $theme ) {
428 if ( $theme['themeId'] === $themeId ) {
429 return $theme;
430 }
431 }
432 return null;
433 }
434
435 function updateChatbots( $chatbots ) {
436 update_option( $this->chatbots_option_name, $chatbots );
437 return $chatbots;
438 }
439
440 function get_all_options() {
441 $options = get_option( $this->option_name, null );
442 foreach ( MWAI_OPTIONS as $key => $value ) {
443 if ( !isset( $options[$key] ) ) {
444 $options[$key] = $value;
445 }
446 if ( $key === 'languages' ) {
447 // TODO: If we decide to make a set of options for languages, we can keep it in the settings
448 $options[$key] = MWAI_LANGUAGES;
449 $options[$key] = apply_filters( 'mwai_languages', $options[$key] );
450 }
451 }
452 $options['shortcode_chat_default_params'] = MWAI_CHATBOT_PARAMS;
453 $options['chatbot_defaults'] = MWAI_CHATBOT_DEFAULT_PARAMS;
454 $options['default_limits'] = MWAI_LIMITS;
455 $options['openai_models'] = MWAI_OPENAI_MODELS;
456 return $options;
457 }
458
459 // Validate and keep the options clean and logical.
460 function sanitize_options() {
461 $options = $this->get_all_options();
462 $needs_update = false;
463
464 // We can sanitize our future options here, let's always remember it.
465 // Now, it is empty...
466
467 if ( $needs_update ) {
468 update_option( $this->option_name, $options, false );
469 }
470 return $options;
471 }
472
473 function update_options( $options ) {
474 if ( !update_option( $this->option_name, $options, false ) ) {
475 return false;
476 }
477 $options = $this->sanitize_options();
478 return $options;
479 }
480
481 function update_option( $option, $value ) {
482 $options = $this->get_all_options();
483 $options[$option] = $value;
484 return $this->update_options( $options );
485 }
486
487 function get_option( $option, $default = null ) {
488 $options = $this->get_all_options();
489 return $options[$option] ?? $default;
490 }
491 #endregion
492 }
493
494 ?>