PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.5.6
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.5.6
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
491 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 $placeholders = array(
184 'FIRST_NAME' => get_user_meta( $user->ID, 'first_name', true ),
185 'LAST_NAME' => get_user_meta( $user->ID, 'last_name', true ),
186 'USER_LOGIN' => isset( $user ) && isset($user->data) && isset( $user->data->user_login ) ?
187 $user->data->user_login : null,
188 'DISPLAY_NAME' => isset( $user ) && isset( $user->data ) && isset( $user->data->display_name ) ?
189 $user->data->display_name : null,
190 'AVATAR_URL' => get_avatar_url( get_current_user_id() ),
191 );
192 return $placeholders;
193 }
194
195 function get_ip_address( $data = null ) {
196 if ( isset( $data ) && isset( $data['ip'] ) ) {
197 $data['ip'] = (string)$data['ip'];
198 }
199 else {
200 if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
201 $data['ip'] = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
202 }
203 else if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) ) {
204 $data['ip'] = sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] );
205 }
206 else if ( isset( $_SERVER['HTTP_X_FORWARDED_ FOR'] ) ) {
207 $data['ip'] = sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] );
208 }
209 }
210 $ip = apply_filters( 'mwai_get_ip_address', $data['ip'] );
211 return $ip;
212 }
213
214 #endregion
215
216 #region Other Helpers
217
218 function isUrl( $url ) {
219 return strpos( $url, 'http' ) === 0 ? true : false;
220 }
221
222 function getPostTypes() {
223 $excluded = array( 'attachment', 'revision', 'nav_menu_item' );
224 $post_types = array();
225 $types = get_post_types( array( 'public' => true ), 'objects' );
226 foreach ( $types as $type ) {
227 if ( in_array( $type->name, $excluded ) ) {
228 continue;
229 }
230 $post_types[] = array(
231 'name' => $type->labels->name,
232 'type' => $type->name,
233 );
234 }
235 return $post_types;
236 }
237
238 function getCleanPost( $post ) {
239 if ( is_object( $post ) ) {
240 $post = (array)$post;
241 }
242 $language = $this->get_post_language( $post['ID'] );
243 $content = apply_filters( 'mwai_pre_post_content', $post['post_content'], $post['ID'] );
244 $content = $this->cleanText( $content );
245 $content = apply_filters( 'mwai_post_content', $content, $post['ID'] );
246 $title = $post['post_title'];
247 $excerpt = $post['post_excerpt'];
248 $url = get_permalink( $post['ID'] );
249 $checksum = wp_hash( $content . $title . $url );
250 return [
251 'postId' => $post['ID'],
252 'title' => $title,
253 'content' => $content,
254 'excerpt' => $excerpt,
255 'url' => $url,
256 'language' => $language,
257 'checksum' => $checksum,
258 ];
259 }
260
261 #endregion
262
263 #region Usage & Costs
264
265 public function dynamic_max_tokens( $tokens, $text ) {
266 // Approximation (fast, no lib)
267 $asciiCount = 0;
268 $nonAsciiCount = 0;
269 for ( $i = 0; $i < mb_strlen( $text ); $i++ ) {
270 $char = mb_substr( $text, $i, 1 );
271 if ( ord( $char ) < 128 ) {
272 $asciiCount++;
273 }
274 else {
275 $nonAsciiCount++;
276 }
277 }
278 $asciiTokens = $asciiCount / 3.5;
279 $nonAsciiTokens = $nonAsciiCount * 2.5;
280 $tokens = $asciiTokens + $nonAsciiTokens;
281
282 // More exact (slower, and lib)
283 if ( PHP_VERSION_ID >= 70400 && function_exists( 'mb_convert_encoding' ) ) {
284 try {
285 $token_array = Encoder::encode( $text );
286 if ( !empty( $token_array ) ) {
287 $tokens = count( $token_array );
288 }
289 }
290 catch ( Exception $e ) {
291 error_log( $e->getMessage() );
292 }
293 }
294
295 $tokens = $tokens;
296 return (int)$tokens;
297 }
298
299 public function record_tokens_usage( $model, $prompt_tokens, $completion_tokens = 0 ) {
300 if ( !is_numeric( $prompt_tokens ) ) {
301 throw new Exception( 'Record usage: prompt_tokens is not a number.' );
302 }
303 if ( !is_numeric( $completion_tokens ) ) {
304 $completion_tokens = 0;
305 }
306 if ( !$model ) {
307 throw new Exception( 'Record usage: model is missing.' );
308 }
309 $usage = $this->get_option( 'openai_usage' );
310 $month = date( 'Y-m' );
311 if ( !isset( $usage[$month] ) ) {
312 $usage[$month] = array();
313 }
314 if ( !isset( $usage[$month][$model] ) ) {
315 $usage[$month][$model] = array(
316 'prompt_tokens' => 0,
317 'completion_tokens' => 0,
318 'total_tokens' => 0
319 );
320 }
321 $usage[$month][$model]['prompt_tokens'] += $prompt_tokens;
322 $usage[$month][$model]['completion_tokens'] += $completion_tokens;
323 $usage[$month][$model]['total_tokens'] += $prompt_tokens + $completion_tokens;
324 $this->update_option( 'openai_usage', $usage );
325 return [
326 'prompt_tokens' => $prompt_tokens,
327 'completion_tokens' => $completion_tokens,
328 'total_tokens' => $prompt_tokens + $completion_tokens
329 ];
330 }
331
332 public function record_images_usage( $model, $resolution, $images ) {
333 if ( !$model || !$resolution || !$images ) {
334 throw new Exception( 'Missing parameters for record_image_usage.' );
335 }
336 $usage = $this->get_option( 'openai_usage' );
337 $month = date( 'Y-m' );
338 if ( !isset( $usage[$month] ) ) {
339 $usage[$month] = array();
340 }
341 if ( !isset( $usage[$month][$model] ) ) {
342 $usage[$month][$model] = array(
343 'resolution' => array(),
344 'images' => 0
345 );
346 }
347 if ( !isset( $usage[$month][$model]['resolution'][$resolution] ) ) {
348 $usage[$month][$model]['resolution'][$resolution] = 0;
349 }
350 $usage[$month][$model]['resolution'][$resolution] += $images;
351 $usage[$month][$model]['images'] += $images;
352 $this->update_option( 'openai_usage', $usage );
353 return [
354 'resolution' => $resolution,
355 'images' => $images
356 ];
357 }
358
359 #endregion
360
361 #region Options
362 function getThemes()
363 {
364 $themes = get_option( $this->themes_option_name, [] );
365 $themes = empty( $themes ) ? [] : $themes;
366
367 $internalThemes = [
368 'chatgpt' => [
369 'type' => 'internal', 'name' => 'ChatGPT', 'themeId' => 'chatgpt',
370 'settings' => [], 'style' => ""
371 ],
372 'messages' => [
373 'type' => 'internal', 'name' => 'Messages', 'themeId' => 'messages',
374 'settings' => [], 'style' => ""
375 ],
376 ];
377 $customThemes = [];
378 foreach ( $themes as $theme ) {
379 if ( isset( $internalThemes[$theme['themeId']] ) ) {
380 $internalThemes[$theme['themeId']] = $theme;
381 continue;
382 }
383 $customThemes[] = $theme;
384 }
385 return array_merge(array_values($internalThemes), $customThemes);
386 }
387
388 function updateThemes( $themes ) {
389 update_option( $this->themes_option_name, $themes );
390 return $themes;
391 }
392
393 function getChatbots() {
394 $chatbots = get_option( $this->chatbots_option_name, [] );
395 if ( empty( $chatbots ) ) {
396 $chatbots = [ array_merge( MWAI_CHATBOT_DEFAULT_PARAMS, ['name' => 'Default', 'chatId' => 'default' ] ) ];
397 }
398 foreach ( $chatbots as $chatbot ) {
399 foreach ( MWAI_CHATBOT_DEFAULT_PARAMS as $key => $value ) {
400 if ( !isset( $chatbot[$key] ) ) {
401 $chatbot[$key] = $value;
402 }
403 }
404 }
405 return $chatbots;
406 }
407
408 function getChatbot( $chatId ) {
409 $chatbots = $this->getChatbots();
410 foreach ( $chatbots as $chatbot ) {
411 if ( $chatbot['chatId'] === $chatId ) {
412 // Somehow, the default was set to "openai" when creating a new chatbot, but that overrided
413 // the default value in the Settings. It should be always empty here (except if we add this
414 // into the Settings of the chatbot).
415 $chatbot['service'] = null;
416 return $chatbot;
417 }
418 }
419 return null;
420 }
421
422 function getTheme( $themeId ) {
423 $themes = $this->getThemes();
424 foreach ( $themes as $theme ) {
425 if ( $theme['themeId'] === $themeId ) {
426 return $theme;
427 }
428 }
429 return null;
430 }
431
432 function updateChatbots( $chatbots ) {
433 update_option( $this->chatbots_option_name, $chatbots );
434 return $chatbots;
435 }
436
437 function get_all_options() {
438 $options = get_option( $this->option_name, null );
439 foreach ( MWAI_OPTIONS as $key => $value ) {
440 if ( !isset( $options[$key] ) ) {
441 $options[$key] = $value;
442 }
443 if ( $key === 'languages' ) {
444 // TODO: If we decide to make a set of options for languages, we can keep it in the settings
445 $options[$key] = MWAI_LANGUAGES;
446 $options[$key] = apply_filters( 'mwai_languages', $options[$key] );
447 }
448 }
449 $options['shortcode_chat_default_params'] = MWAI_CHATBOT_PARAMS;
450 $options['chatbot_defaults'] = MWAI_CHATBOT_DEFAULT_PARAMS;
451 $options['default_limits'] = MWAI_LIMITS;
452 $options['openai_models'] = MWAI_OPENAI_MODELS;
453 return $options;
454 }
455
456 // Validate and keep the options clean and logical.
457 function sanitize_options() {
458 $options = $this->get_all_options();
459 $needs_update = false;
460
461 // We can sanitize our future options here, let's always remember it.
462 // Now, it is empty...
463
464 if ( $needs_update ) {
465 update_option( $this->option_name, $options, false );
466 }
467 return $options;
468 }
469
470 function update_options( $options ) {
471 if ( !update_option( $this->option_name, $options, false ) ) {
472 return false;
473 }
474 $options = $this->sanitize_options();
475 return $options;
476 }
477
478 function update_option( $option, $value ) {
479 $options = $this->get_all_options();
480 $options[$option] = $value;
481 return $this->update_options( $options );
482 }
483
484 function get_option( $option, $default = null ) {
485 $options = $this->get_all_options();
486 return $options[$option] ?? $default;
487 }
488 #endregion
489 }
490
491 ?>