Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/aimogen-pro/res/StatisticsClass.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 + defined("ABSPATH") or die();
3 + class Aiomatic_Statistics
4 + {
5 + private $wpdb = null;
6 + private $db_check = false;
7 + private $table_logs = null;
8 + private $table_logmeta = null;
9 + private $apiRef = null;
10 +
11 + public function __construct()
12 + {
13 + add_action('ihc_action_after_subscription_activated', array($this, 'reset_usage_after_activation'), 999, 4);
14 + add_action('ihc_action_after_subscription_renew_activated', array($this, 'reset_usage_after_renewal'), 999, 4);
15 +
16 + $aiomatic_Main_Settings = get_option("aiomatic_Main_Settings", false);
17 + global $wpdb;
18 + $this->wpdb = $wpdb;
19 + $this->table_logs = $wpdb->prefix . "aiomatic_logs";
20 + $this->table_logmeta = $wpdb->prefix . "aiomatic_logmeta";
21 + add_shortcode("aiomatic-user-remaining-credits-bar", [
22 + $this,
23 + "shortcode_current",
24 + ]);
25 + add_shortcode("aimogen-user-remaining-credits-bar", [
26 + $this,
27 + "shortcode_current",
28 + ]);
29 + if (
30 + isset($aiomatic_Main_Settings["aiomatic_enabled"]) &&
31 + $aiomatic_Main_Settings["aiomatic_enabled"] === "on"
32 + ) {
33 + if (
34 + isset($aiomatic_Main_Settings["enable_tracking"]) &&
35 + trim($aiomatic_Main_Settings["enable_tracking"]) == "on"
36 + ) {
37 + add_filter("aiomatic_stats_query", [$this, "query"], 10, 1);
38 + add_filter(
39 + "aiomatic_ai_reply",
40 + function ($reply, $query) {
41 + global $aiomatic_stats;
42 + if (empty($aiomatic_stats)) {
43 + return $reply;
44 + }
45 + $aiomatic_stats->addCasually($query, $reply, []);
46 + return $reply;
47 + },
48 + 10,
49 + 2
50 + );
51 + add_filter(
52 + "aiomatic_ai_reply_text",
53 + function ($query, $text) {
54 + global $aiomatic_stats;
55 + if (empty($aiomatic_stats)) {
56 + return $text;
57 + }
58 + $aiomatic_stats->addCasually($query, $text, []);
59 + return $text;
60 + },
61 + 10,
62 + 2
63 + );
64 + aiomatic_get_session_id();
65 + add_filter(
66 + "aiomatic_ai_allowed",
67 + [$this, "check_limits"],
68 + 1,
69 + 2
70 + );
71 + add_filter(
72 + "aiomatic_tts_allowed",
73 + [$this, "check_limits_tts"],
74 + 1,
75 + 2
76 + );
77 + }
78 + }
79 + }
80 + public function reset_usage_after_activation($uid, $lid, $firstTime, $args)
81 + {
82 + $this->deleteUsageEntries('all', false, $uid, null, null);
83 + }
84 + public function reset_usage_after_renewal($uid, $lid, $args)
85 + {
86 + $this->deleteUsageEntries('all', false, $uid, null, null);
87 + }
88 + function check_limits($allowed, $aiomatic_Limit_Settings)
89 + {
90 + global $aiomatic_stats;
91 + if (empty($aiomatic_stats)) {
92 + return $allowed;
93 + }
94 + $userId = null;
95 + if (
96 + isset($aiomatic_Limit_Settings["enable_limits"]) &&
97 + trim($aiomatic_Limit_Settings["enable_limits"]) == "on"
98 + ) {
99 + $userId = $this->getUserId();
100 + $target = $userId ? "users" : "guests";
101 + $skipme = false;
102 + if ($target === "users") {
103 + if (
104 + isset($aiomatic_Limit_Settings["ignored_users"]) &&
105 + $aiomatic_Limit_Settings["ignored_users"] != ""
106 + ) {
107 + $ignoredUsers = $aiomatic_Limit_Settings["ignored_users"];
108 + } else {
109 + $ignoredUsers = "admin";
110 + }
111 + $isAdministrator = current_user_can("manage_options");
112 + if ($isAdministrator && $ignoredUsers == "admin") {
113 + $skipme = true;
114 + }
115 + $isEditor = current_user_can("edit_posts");
116 + if ($isEditor && $ignoredUsers == "editor") {
117 + $skipme = true;
118 + }
119 + }
120 + if ($skipme == false) {
121 + if (
122 + isset($aiomatic_Limit_Settings["ignored_users"]) &&
123 + $aiomatic_Limit_Settings["ignored_users"] != ""
124 + ) {
125 + $ignoredUsers = $aiomatic_Limit_Settings["ignored_users"];
126 + } else {
127 + $ignoredUsers = "admin";
128 + }
129 + if (
130 + isset($aiomatic_Limit_Settings["limit_message_logged"]) &&
131 + $aiomatic_Limit_Settings["limit_message_logged"] != ""
132 + ) {
133 + $limit_message_logged =
134 + $aiomatic_Limit_Settings["limit_message_logged"];
135 + } else {
136 + $limit_message_logged = esc_html__(
137 + "You have reached the usage limit.",
138 + "aiomatic-automatic-ai-content-writer"
139 + );
140 + }
141 + if (
142 + isset(
143 + $aiomatic_Limit_Settings["limit_message_not_logged"]
144 + ) &&
145 + $aiomatic_Limit_Settings["limit_message_not_logged"] != ""
146 + ) {
147 + $limit_message_not_logged =
148 + $aiomatic_Limit_Settings["limit_message_not_logged"];
149 + } else {
150 + $limit_message_not_logged = esc_html__(
151 + "You have reached the usage limit.",
152 + "aiomatic-automatic-ai-content-writer"
153 + );
154 + }
155 + if ($target === "users") {
156 + if (
157 + isset($aiomatic_Limit_Settings["user_credits"]) &&
158 + $aiomatic_Limit_Settings["user_credits"] == "0"
159 + ) {
160 + return $limit_message_logged;
161 + } elseif (
162 + !isset($aiomatic_Limit_Settings["user_credits"]) ||
163 + $aiomatic_Limit_Settings["user_credits"] == ""
164 + ) {
165 + $skipme = true;
166 + }
167 + if (
168 + isset($aiomatic_Limit_Settings["user_time_frame"]) &&
169 + $aiomatic_Limit_Settings["user_time_frame"] != ""
170 + ) {
171 + $timeFrame =
172 + $aiomatic_Limit_Settings["user_time_frame"];
173 + } else {
174 + $timeFrame = "day";
175 + }
176 + if (
177 + isset($aiomatic_Limit_Settings["is_absolute_user"]) &&
178 + $aiomatic_Limit_Settings["is_absolute_user"] == "on"
179 + ) {
180 + $isAbsolute = true;
181 + } else {
182 + $isAbsolute = false;
183 + }
184 + } else {
185 + if (
186 + isset($aiomatic_Limit_Settings["guest_credits"]) &&
187 + $aiomatic_Limit_Settings["guest_credits"] == "0"
188 + ) {
189 + return $limit_message_not_logged;
190 + } elseif (
191 + !isset($aiomatic_Limit_Settings["guest_credits"]) ||
192 + $aiomatic_Limit_Settings["guest_credits"] == ""
193 + ) {
194 + $skipme = true;
195 + }
196 + if (
197 + isset($aiomatic_Limit_Settings["guest_time_frame"]) &&
198 + $aiomatic_Limit_Settings["guest_time_frame"] != ""
199 + ) {
200 + $timeFrame =
201 + $aiomatic_Limit_Settings["guest_time_frame"];
202 + } else {
203 + $timeFrame = "day";
204 + }
205 + if (
206 + isset($aiomatic_Limit_Settings["is_absolute_guest"]) &&
207 + $aiomatic_Limit_Settings["is_absolute_guest"] == "on"
208 + ) {
209 + $isAbsolute = true;
210 + } else {
211 + $isAbsolute = false;
212 + }
213 + }
214 + if ($skipme == false) {
215 + $stats = $this->query($timeFrame, $isAbsolute);
216 + if ($stats["overLimit"]) {
217 + if ($target === "users") {
218 + return $limit_message_logged;
219 + } else {
220 + return $limit_message_not_logged;
221 + }
222 + }
223 + }
224 + }
225 + }
226 +
227 +
228 + $aiomatic_Limit_Rules = get_option("aiomatic_Limit_Rules", false);
229 + if (is_array($aiomatic_Limit_Rules)) {
230 + if (
231 + isset($aiomatic_Limit_Settings["limit_message_rule"]) &&
232 + $aiomatic_Limit_Settings["limit_message_rule"] != ""
233 + ) {
234 + $limit_message_rule =
235 + $aiomatic_Limit_Settings["limit_message_rule"];
236 + } else {
237 + $limit_message_rule = esc_html__(
238 + "You have reached the usage limit.",
239 + "aiomatic-automatic-ai-content-writer"
240 + );
241 + }
242 + $userRoles = aiomatic_my_get_current_user_roles();
243 + $userSubs = aiomatic_my_get_current_user_subscriptions();
244 + if(count($userSubs) > 1)
245 + {
246 + $is_limited = array();
247 + $no_limit_found = false;
248 + foreach($userSubs as $usub)
249 + {
250 + foreach ($aiomatic_Limit_Rules as $cont => $bundle[]) {
251 + $matching = false;
252 + $bundle_values = array_values($bundle);
253 + $myValues = $bundle_values[$cont];
254 + $array_my_values = array_values($myValues);
255 + for ($iji = 0; $iji < count($array_my_values); ++$iji) {
256 + if (is_string($array_my_values[$iji])) {
257 + $array_my_values[$iji] = stripslashes(
258 + $array_my_values[$iji]
259 + );
260 + }
261 + }
262 + $user_credits = $array_my_values[0];
263 + $user_credit_type = $array_my_values[1];
264 + $user_time_frame = $array_my_values[2];
265 + $absolute = $array_my_values[3];
266 + $role = $array_my_values[4];
267 + $active = $array_my_values[5];
268 + $ums_sub = $array_my_values[6];
269 + $message = $array_my_values[7];
270 + $rule_description = $array_my_values[8];
271 + $user_list = $array_my_values[9];
272 + $rest_sub = $array_my_values[10];
273 + $paid_sub = $array_my_values[11];
274 + if ($active !== "1") {
275 + continue;
276 + }
277 + if (
278 + empty($user_time_frame) ||
279 + empty($user_credit_type) ||
280 + empty($user_credits)
281 + ) {
282 + continue;
283 + }
284 + if (
285 + $user_credit_type == 'pdf' || $user_credit_type == 'pdfchar'
286 + ) {
287 + continue;
288 + }
289 + $isAbsolute = false;
290 + if ($absolute == "1") {
291 + $isAbsolute = true;
292 + }
293 + if ($role == "any" || in_array($role, $userRoles)) {
294 + $matching = true;
295 + }
296 + if(!empty($user_list) && !empty($userId))
297 + {
298 + $user_list_arr = explode(',', trim($user_list));
299 + foreach($user_list_arr as $uli)
300 + {
301 + if($userId == $uli)
302 + {
303 + $matching = true;
304 + break;
305 + }
306 + }
307 + }
308 + if ($ums_sub == "any" || $ums_sub == $usub){
309 + $matching = true;
310 + } elseif ($ums_sub == "nosub" && empty($userSubs)) {
311 + $matching = true;
312 + } else {
313 + if ($ums_sub !== "none") {
314 + $matching = false;
315 + }
316 + }
317 + if ($rest_sub == "any" || $rest_sub == $usub){
318 + $matching = true;
319 + } elseif ($rest_sub == "nosub" && empty($userSubs)) {
320 + $matching = true;
321 + } else {
322 + if ($rest_sub !== "none") {
323 + $matching = false;
324 + }
325 + }
326 + if ($paid_sub == "any" || $paid_sub == $usub){
327 + $matching = true;
328 + } elseif ($paid_sub == "nosub" && empty($userSubs)) {
329 + $matching = true;
330 + } else {
331 + if ($paid_sub !== "none") {
332 + $matching = false;
333 + }
334 + }
335 + if ($matching === true) {
336 + $stats = $this->query(
337 + $user_time_frame,
338 + $isAbsolute,
339 + $user_credits,
340 + $user_credit_type
341 + );
342 + if ($stats["overLimit"])
343 + {
344 + if (!empty($message)) {
345 + $is_limited[] = $message;
346 + } else {
347 + $is_limited[] = $limit_message_rule;
348 + }
349 + }
350 + else
351 + {
352 + $no_limit_found = true;
353 + }
354 + }
355 + }
356 + }
357 + if($no_limit_found == false && count($is_limited) > 0)
358 + {
359 + return $is_limited[0];
360 + }
361 + }
362 + else
363 + {
364 + foreach ($aiomatic_Limit_Rules as $cont => $bundle[]) {
365 + $matching = false;
366 + $bundle_values = array_values($bundle);
367 + $myValues = $bundle_values[$cont];
368 + $array_my_values = array_values($myValues);
369 + for ($iji = 0; $iji < count($array_my_values); ++$iji) {
370 + if (is_string($array_my_values[$iji])) {
371 + $array_my_values[$iji] = stripslashes(
372 + $array_my_values[$iji]
373 + );
374 + }
375 + }
376 + $user_credits = $array_my_values[0];
377 + $user_credit_type = $array_my_values[1];
378 + $user_time_frame = $array_my_values[2];
379 + $absolute = $array_my_values[3];
380 + $role = $array_my_values[4];
381 + $active = $array_my_values[5];
382 + $ums_sub = $array_my_values[6];
383 + $message = $array_my_values[7];
384 + $rule_description = $array_my_values[8];
385 + $user_list = $array_my_values[9];
386 + $rest_sub = $array_my_values[10];
387 + $paid_sub = $array_my_values[11];
388 + if ($active !== "1") {
389 + continue;
390 + }
391 + if (
392 + empty($user_time_frame) ||
393 + empty($user_credit_type) ||
394 + empty($user_credits)
395 + ) {
396 + continue;
397 + }
398 + if (
399 + $user_credit_type == 'pdf' || $user_credit_type == 'pdfchar'
400 + ) {
401 + continue;
402 + }
403 + $isAbsolute = false;
404 + if ($absolute == "1") {
405 + $isAbsolute = true;
406 + }
407 + if ($role == "any" || in_array($role, $userRoles)) {
408 + $matching = true;
409 + }
410 + if(!empty($user_list) && !empty($userId))
411 + {
412 + $user_list_arr = explode(',', trim($user_list));
413 + foreach($user_list_arr as $uli)
414 + {
415 + if($userId == $uli)
416 + {
417 + $matching = true;
418 + break;
419 + }
420 + }
421 + }
422 + if ($ums_sub == "any" || in_array($ums_sub, $userSubs)) {
423 + $matching = true;
424 + } elseif ($ums_sub == "nosub" && empty($userSubs)) {
425 + $matching = true;
426 + } else {
427 + if ($ums_sub !== "none") {
428 + $matching = false;
429 + }
430 + }
431 + if ($rest_sub == "any" || in_array($rest_sub, $userSubs)) {
432 + $matching = true;
433 + } elseif ($rest_sub == "nosub" && empty($userSubs)) {
434 + $matching = true;
435 + } else {
436 + if ($rest_sub !== "none") {
437 + $matching = false;
438 + }
439 + }
440 + if ($paid_sub == "any" || in_array($paid_sub, $userSubs)) {
441 + $matching = true;
442 + } elseif ($paid_sub == "nosub" && empty($userSubs)) {
443 + $matching = true;
444 + } else {
445 + if ($paid_sub !== "none") {
446 + $matching = false;
447 + }
448 + }
449 + if ($matching === true) {
450 + $stats = $this->query(
451 + $user_time_frame,
452 + $isAbsolute,
453 + $user_credits,
454 + $user_credit_type
455 + );
456 + if ($stats["overLimit"]) {
457 + if (!empty($message)) {
458 + return $message;
459 + } else {
460 + return $limit_message_rule;
461 + }
462 + }
463 + }
464 + }
465 + }
466 + }
467 + return $allowed;
468 + }
469 +
470 + function check_limits_tts($allowed, $aiomatic_Limit_Settings)
471 + {
472 + global $aiomatic_stats;
473 + if (empty($aiomatic_stats)) {
474 + return $allowed;
475 + }
476 + if (
477 + isset($aiomatic_Limit_Settings["enable_limits_text"]) &&
478 + trim($aiomatic_Limit_Settings["enable_limits_text"]) == "on"
479 + ) {
480 + $userId = $this->getUserId();
481 + $target = $userId ? "users" : "guests";
482 + $skipme = false;
483 + if ($target === "users") {
484 + if (
485 + isset($aiomatic_Limit_Settings["ignored_users_text"]) &&
486 + $aiomatic_Limit_Settings["ignored_users_text"] != ""
487 + ) {
488 + $ignoredUsers = $aiomatic_Limit_Settings["ignored_users_text"];
489 + } else {
490 + $ignoredUsers = "admin";
491 + }
492 + $isAdministrator = current_user_can("manage_options");
493 + if ($isAdministrator && $ignoredUsers == "admin") {
494 + $skipme = true;
495 + }
496 + $isEditor = current_user_can("edit_posts");
497 + if ($isEditor && $ignoredUsers == "editor") {
498 + $skipme = true;
499 + }
500 + }
501 + if ($skipme == false) {
502 + if (
503 + isset($aiomatic_Limit_Settings["ignored_users_text"]) &&
504 + $aiomatic_Limit_Settings["ignored_users_text"] != ""
505 + ) {
506 + $ignoredUsers = $aiomatic_Limit_Settings["ignored_users_text"];
507 + } else {
508 + $ignoredUsers = "admin";
509 + }
510 + $limit_message_logged = esc_html__(
511 + "You have reached the usage limit.",
512 + "aiomatic-automatic-ai-content-writer"
513 + );
514 + $limit_message_not_logged = esc_html__(
515 + "You have reached the usage limit.",
516 + "aiomatic-automatic-ai-content-writer"
517 + );
518 + if ($target === "users") {
519 + if (
520 + isset($aiomatic_Limit_Settings["user_credits_text"]) &&
521 + $aiomatic_Limit_Settings["user_credits_text"] == "0"
522 + ) {
523 + return $limit_message_logged;
524 + } elseif (
525 + !isset($aiomatic_Limit_Settings["user_credits_text"]) ||
526 + $aiomatic_Limit_Settings["user_credits_text"] == ""
527 + ) {
528 + $skipme = true;
529 + }
530 + if (
531 + isset($aiomatic_Limit_Settings["user_time_frame_text"]) &&
532 + $aiomatic_Limit_Settings["user_time_frame_text"] != ""
533 + ) {
534 + $timeFrame =
535 + $aiomatic_Limit_Settings["user_time_frame_text"];
536 + } else {
537 + $timeFrame = "day";
538 + }
539 + if (
540 + isset($aiomatic_Limit_Settings["is_absolute_user_text"]) &&
541 + $aiomatic_Limit_Settings["is_absolute_user_text"] == "on"
542 + ) {
543 + $isAbsolute = true;
544 + } else {
545 + $isAbsolute = false;
546 + }
547 + } else {
548 + if (
549 + isset($aiomatic_Limit_Settings["guest_credits_text"]) &&
550 + $aiomatic_Limit_Settings["guest_credits_text"] == "0"
551 + ) {
552 + return $limit_message_not_logged;
553 + } elseif (
554 + !isset($aiomatic_Limit_Settings["guest_credits_text"]) ||
555 + $aiomatic_Limit_Settings["guest_credits_text"] == ""
556 + ) {
557 + $skipme = true;
558 + }
559 + if (
560 + isset($aiomatic_Limit_Settings["guest_time_frame_text"]) &&
561 + $aiomatic_Limit_Settings["guest_time_frame_text"] != ""
562 + ) {
563 + $timeFrame =
564 + $aiomatic_Limit_Settings["guest_time_frame_text"];
565 + } else {
566 + $timeFrame = "day";
567 + }
568 + if (
569 + isset($aiomatic_Limit_Settings["is_absolute_guest_text"]) &&
570 + $aiomatic_Limit_Settings["is_absolute_guest_text"] == "on"
571 + ) {
572 + $isAbsolute = true;
573 + } else {
574 + $isAbsolute = false;
575 + }
576 + }
577 + if ($skipme == false) {
578 + $stats = $this->query_tts($timeFrame, $isAbsolute);
579 + if ($stats["overLimit"]) {
580 + if ($target === "users") {
581 + return $limit_message_logged;
582 + } else {
583 + return $limit_message_not_logged;
584 + }
585 + }
586 + }
587 + }
588 + }
589 + return $allowed;
590 + }
591 +
592 + public function get_pdf_limits()
593 + {
594 + $pdfpage = array();
595 + $pdfchar = array();
596 + global $aiomatic_stats;
597 + if (empty($aiomatic_stats)) {
598 + return array($pdfpage, $pdfchar);
599 + }
600 + $userId = $this->getUserId();
601 + $aiomatic_Limit_Rules = get_option("aiomatic_Limit_Rules", false);
602 + if (is_array($aiomatic_Limit_Rules))
603 + {
604 + $userRoles = aiomatic_my_get_current_user_roles();
605 + $userSubs = aiomatic_my_get_current_user_subscriptions();
606 +
607 + if(count($userSubs) > 1)
608 + {
609 + foreach($userSubs as $usub)
610 + {
611 + foreach ($aiomatic_Limit_Rules as $cont => $bundle[]) {
612 + $matching = false;
613 + $bundle_values = array_values($bundle);
614 + $myValues = $bundle_values[$cont];
615 + $array_my_values = array_values($myValues);
616 + for ($iji = 0; $iji < count($array_my_values); ++$iji) {
617 + if (is_string($array_my_values[$iji])) {
618 + $array_my_values[$iji] = stripslashes(
619 + $array_my_values[$iji]
620 + );
621 + }
622 + }
623 + $user_credits = $array_my_values[0];
624 + $user_credit_type = $array_my_values[1];
625 + $user_time_frame = $array_my_values[2];
626 + $absolute = $array_my_values[3];
627 + $role = $array_my_values[4];
628 + $active = $array_my_values[5];
629 + $ums_sub = $array_my_values[6];
630 + $message = $array_my_values[7];
631 + $rule_description = $array_my_values[8];
632 + $user_list = $array_my_values[9];
633 + $rest_sub = $array_my_values[10];
634 + $paid_sub = $array_my_values[11];
635 + if ($active !== "1") {
636 + continue;
637 + }
638 + if (
639 + empty($user_time_frame) ||
640 + empty($user_credit_type) ||
641 + empty($user_credits)
642 + ) {
643 + continue;
644 + }
645 + if (
646 + $user_credit_type != 'pdf' && $user_credit_type != 'pdfchar'
647 + ) {
648 + continue;
649 + }
650 + if ($role == "any" || in_array($role, $userRoles)) {
651 + $matching = true;
652 + }
653 + if(!empty($user_list) && !empty($userId))
654 + {
655 + $user_list_arr = explode(',', trim($user_list));
656 + foreach($user_list_arr as $uli)
657 + {
658 + if($userId == $uli)
659 + {
660 + $matching = true;
661 + break;
662 + }
663 + }
664 + }
665 + if ($ums_sub == "any" || $ums_sub == $usub){
666 + $matching = true;
667 + } elseif ($ums_sub == "nosub" && empty($userSubs)) {
668 + $matching = true;
669 + } else {
670 + if ($ums_sub !== "none") {
671 + $matching = false;
672 + }
673 + }
674 + if ($rest_sub == "any" || $rest_sub == $usub){
675 + $matching = true;
676 + } elseif ($rest_sub == "nosub" && empty($userSubs)) {
677 + $matching = true;
678 + } else {
679 + if ($rest_sub !== "none") {
680 + $matching = false;
681 + }
682 + }
683 + if ($paid_sub == "any" || $paid_sub == $usub){
684 + $matching = true;
685 + } elseif ($paid_sub == "nosub" && empty($userSubs)) {
686 + $matching = true;
687 + } else {
688 + if ($paid_sub !== "none") {
689 + $matching = false;
690 + }
691 + }
692 + if ($matching === true) {
693 + if ($user_credit_type == 'pdf')
694 + {
695 + $pdfpage[] = $user_credits;
696 + }
697 + elseif ($user_credit_type == 'pdfchar')
698 + {
699 + $pdfchar[] = $user_credits;
700 + }
701 + }
702 + }
703 + }
704 + }
705 + else
706 + {
707 + foreach ($aiomatic_Limit_Rules as $cont => $bundle[]) {
708 + $matching = false;
709 + $bundle_values = array_values($bundle);
710 + $myValues = $bundle_values[$cont];
711 + $array_my_values = array_values($myValues);
712 + for ($iji = 0; $iji < count($array_my_values); ++$iji) {
713 + if (is_string($array_my_values[$iji])) {
714 + $array_my_values[$iji] = stripslashes(
715 + $array_my_values[$iji]
716 + );
717 + }
718 + }
719 + $user_credits = $array_my_values[0];
720 + $user_credit_type = $array_my_values[1];
721 + $user_time_frame = $array_my_values[2];
722 + $absolute = $array_my_values[3];
723 + $role = $array_my_values[4];
724 + $active = $array_my_values[5];
725 + $ums_sub = $array_my_values[6];
726 + $message = $array_my_values[7];
727 + $rule_description = $array_my_values[8];
728 + $user_list = $array_my_values[9];
729 + $rest_sub = $array_my_values[10];
730 + $paid_sub = $array_my_values[11];
731 + if ($active !== "1") {
732 + continue;
733 + }
734 + if (
735 + empty($user_time_frame) ||
736 + empty($user_credit_type) ||
737 + empty($user_credits)
738 + ) {
739 + continue;
740 + }
741 + if (
742 + $user_credit_type != 'pdf' && $user_credit_type != 'pdfchar'
743 + ) {
744 + continue;
745 + }
746 + if ($role == "any" || in_array($role, $userRoles)) {
747 + $matching = true;
748 + }
749 + if(!empty($user_list) && !empty($userId))
750 + {
751 + $user_list_arr = explode(',', trim($user_list));
752 + foreach($user_list_arr as $uli)
753 + {
754 + if($userId == $uli)
755 + {
756 + $matching = true;
757 + break;
758 + }
759 + }
760 + }
761 + if ($ums_sub == "any" || in_array($ums_sub, $userSubs)) {
762 + $matching = true;
763 + } elseif ($ums_sub == "nosub" && empty($userSubs)) {
764 + $matching = true;
765 + } else {
766 + if ($ums_sub !== "none") {
767 + $matching = false;
768 + }
769 + }
770 + if ($rest_sub == "any" || in_array($rest_sub, $userSubs)) {
771 + $matching = true;
772 + } elseif ($rest_sub == "nosub" && empty($userSubs)) {
773 + $matching = true;
774 + } else {
775 + if ($rest_sub !== "none") {
776 + $matching = false;
777 + }
778 + }
779 + if ($paid_sub == "any" || in_array($paid_sub, $userSubs)) {
780 + $matching = true;
781 + } elseif ($paid_sub == "nosub" && empty($userSubs)) {
782 + $matching = true;
783 + } else {
784 + if ($paid_sub !== "none") {
785 + $matching = false;
786 + }
787 + }
788 + if ($matching === true) {
789 + if ($user_credit_type == 'pdf')
790 + {
791 + $pdfpage[] = $user_credits;
792 + }
793 + elseif ($user_credit_type == 'pdfchar')
794 + {
795 + $pdfchar[] = $user_credits;
796 + }
797 + }
798 + }
799 + }
800 + }
801 + $aiomatic_Limit_Settings = get_option("aiomatic_Limit_Settings", false);
802 + if (
803 + isset($aiomatic_Limit_Settings["enable_limits"]) &&
804 + trim($aiomatic_Limit_Settings["enable_limits"]) == "on"
805 + ) {
806 + $userId = $this->getUserId();
807 + $target = $userId ? "users" : "guests";
808 + $skipme = false;
809 + if ($target === "users") {
810 + if (
811 + isset($aiomatic_Limit_Settings["ignored_users"]) &&
812 + $aiomatic_Limit_Settings["ignored_users"] != ""
813 + ) {
814 + $ignoredUsers = $aiomatic_Limit_Settings["ignored_users"];
815 + } else {
816 + $ignoredUsers = "admin";
817 + }
818 + $isAdministrator = current_user_can("manage_options");
819 + if ($isAdministrator && $ignoredUsers == "admin") {
820 + $skipme = true;
821 + }
822 + $isEditor = current_user_can("edit_posts");
823 + if ($isEditor && $ignoredUsers == "editor") {
824 + $skipme = true;
825 + }
826 + }
827 + if ($skipme == false) {
828 + if ($target === "users") {
829 + if (
830 + isset($aiomatic_Limit_Settings["guest_credit_type"]) &&
831 + trim($aiomatic_Limit_Settings["guest_credit_type"]) == "pdf" &&
832 + isset($aiomatic_Limit_Settings["guest_credits"]) &&
833 + $aiomatic_Limit_Settings["guest_credits"] != ""
834 + ) {
835 + $pdfpage[] = $aiomatic_Limit_Settings["guest_credits"];
836 + }
837 + elseif (
838 + isset($aiomatic_Limit_Settings["guest_credit_type"]) &&
839 + trim($aiomatic_Limit_Settings["guest_credit_type"]) == "pdfchar" &&
840 + isset($aiomatic_Limit_Settings["guest_credits"]) &&
841 + $aiomatic_Limit_Settings["guest_credits"] != ""
842 + ) {
843 + $pdfchar[] = $aiomatic_Limit_Settings["guest_credits"];
844 + }
845 + } else {
846 + if (
847 + isset($aiomatic_Limit_Settings["user_credit_type"]) &&
848 + trim($aiomatic_Limit_Settings["user_credit_type"]) == "pdf" &&
849 + isset($aiomatic_Limit_Settings["user_credits"]) &&
850 + $aiomatic_Limit_Settings["user_credits"] != ""
851 + ) {
852 + $pdfpage[] = $aiomatic_Limit_Settings["user_credits"];
853 + }
854 + elseif (
855 + isset($aiomatic_Limit_Settings["user_credit_type"]) &&
856 + trim($aiomatic_Limit_Settings["user_credit_type"]) == "pdfchar" &&
857 + isset($aiomatic_Limit_Settings["user_credits"]) &&
858 + $aiomatic_Limit_Settings["user_credits"] != ""
859 + ) {
860 + $pdfchar[] = $aiomatic_Limit_Settings["user_credits"];
861 + }
862 + }
863 + }
864 + }
865 + return array($pdfpage, $pdfchar);
866 + }
867 +
868 + public function get_limits($aiomatic_Limit_Settings)
869 + {
870 + $limits = "";
871 + $userId = null;
872 + global $aiomatic_stats;
873 + if (empty($aiomatic_stats)) {
874 + return esc_html__(
875 + "Limits not available",
876 + "aiomatic-automatic-ai-content-writer"
877 + );
878 + }
879 + if (
880 + isset($aiomatic_Limit_Settings["enable_limits"]) &&
881 + trim($aiomatic_Limit_Settings["enable_limits"]) == "on"
882 + ) {
883 + $userId = $this->getUserId();
884 + $target = $userId ? "users" : "guests";
885 + $skipme = false;
886 + if ($target === "users") {
887 + if (
888 + isset($aiomatic_Limit_Settings["ignored_users"]) &&
889 + $aiomatic_Limit_Settings["ignored_users"] != ""
890 + ) {
891 + $ignoredUsers = $aiomatic_Limit_Settings["ignored_users"];
892 + } else {
893 + $ignoredUsers = "admin";
894 + }
895 + $isAdministrator = current_user_can("manage_options");
896 + if ($isAdministrator && $ignoredUsers == "admin") {
897 + $skipme = true;
898 + }
899 + $isEditor = current_user_can("edit_posts");
900 + if ($isEditor && $ignoredUsers == "editor") {
901 + $skipme = true;
902 + }
903 + }
904 + if ($skipme == false) {
905 + if (
906 + isset($aiomatic_Limit_Settings["ignored_users"]) &&
907 + $aiomatic_Limit_Settings["ignored_users"] != ""
908 + ) {
909 + $ignoredUsers = $aiomatic_Limit_Settings["ignored_users"];
910 + } else {
911 + $ignoredUsers = "admin";
912 + }
913 + if ($target === "users") {
914 + if (
915 + isset($aiomatic_Limit_Settings["user_credits"]) &&
916 + $aiomatic_Limit_Settings["user_credits"] == "0"
917 + ) {
918 + } elseif (
919 + !isset($aiomatic_Limit_Settings["user_credits"]) ||
920 + $aiomatic_Limit_Settings["user_credits"] == ""
921 + ) {
922 + $skipme = true;
923 + }
924 + if (
925 + isset($aiomatic_Limit_Settings["user_time_frame"]) &&
926 + $aiomatic_Limit_Settings["user_time_frame"] != ""
927 + ) {
928 + $timeFrame =
929 + $aiomatic_Limit_Settings["user_time_frame"];
930 + } else {
931 + $timeFrame = "day";
932 + }
933 + if (
934 + isset($aiomatic_Limit_Settings["is_absolute_user"]) &&
935 + $aiomatic_Limit_Settings["is_absolute_user"] == "on"
936 + ) {
937 + $isAbsolute = true;
938 + } else {
939 + $isAbsolute = false;
940 + }
941 + } else {
942 + if (
943 + !isset($aiomatic_Limit_Settings["guest_credits"]) ||
944 + $aiomatic_Limit_Settings["guest_credits"] == ""
945 + ) {
946 + $skipme = true;
947 + }
948 + if (
949 + isset($aiomatic_Limit_Settings["guest_time_frame"]) &&
950 + $aiomatic_Limit_Settings["guest_time_frame"] != ""
951 + ) {
952 + $timeFrame =
953 + $aiomatic_Limit_Settings["guest_time_frame"];
954 + } else {
955 + $timeFrame = "day";
956 + }
957 + if (
958 + isset($aiomatic_Limit_Settings["is_absolute_guest"]) &&
959 + $aiomatic_Limit_Settings["is_absolute_guest"] == "on"
960 + ) {
961 + $isAbsolute = true;
962 + } else {
963 + $isAbsolute = false;
964 + }
965 + }
966 + if ($skipme == false) {
967 + $stats = $this->query($timeFrame, $isAbsolute);
968 + if ($stats["queriesLimit"] != "0") {
969 + $limits .=
970 + $stats["queries"] .
971 + esc_html__(" used from a maximum of ", "aiomatic-automatic-ai-content-writer") .
972 + $stats["queriesLimit"] .
973 + " " .
974 + esc_html__(
975 + "queries",
976 + "aiomatic-automatic-ai-content-writer"
977 + ) .
978 + "/" .
979 + $timeFrame .
980 + "<br>";
981 + } elseif ($stats["unitsLimit"] != "0") {
982 + $limits .=
983 + $stats["units"] .
984 + esc_html__(" used from a maximum of ", "aiomatic-automatic-ai-content-writer") .
985 + $stats["unitsLimit"] .
986 + " " .
987 + esc_html__(
988 + "tokens",
989 + "aiomatic-automatic-ai-content-writer"
990 + ) .
991 + "/" .
992 + $timeFrame .
993 + "<br>";
994 + } elseif ($stats["priceLimit"] != "0") {
995 + $limits .=
996 + $stats["price"] .
997 + esc_html__(" used from a maximum of ", "aiomatic-automatic-ai-content-writer") .
998 + $stats["priceLimit"] .
999 + " " .
1000 + esc_html__(
1001 + "USD",
1002 + "aiomatic-automatic-ai-content-writer"
1003 + ) .
1004 + "/" .
1005 + $timeFrame .
1006 + "<br>";
1007 + }
1008 + }
1009 + }
1010 + }
1011 +
1012 + $aiomatic_Limit_Rules = get_option("aiomatic_Limit_Rules", false);
1013 + if (is_array($aiomatic_Limit_Rules)) {
1014 + $userRoles = aiomatic_my_get_current_user_roles();
1015 + $userSubs = aiomatic_my_get_current_user_subscriptions();
1016 + foreach ($aiomatic_Limit_Rules as $cont => $bundle[]) {
1017 + $matching = false;
1018 + $bundle_values = array_values($bundle);
1019 + $myValues = $bundle_values[$cont];
1020 + $array_my_values = array_values($myValues);
1021 + for ($iji = 0; $iji < count($array_my_values); ++$iji) {
1022 + if (is_string($array_my_values[$iji])) {
1023 + $array_my_values[$iji] = stripslashes(
1024 + $array_my_values[$iji]
1025 + );
1026 + }
1027 + }
1028 + $user_credits = $array_my_values[0];
1029 + $user_credit_type = $array_my_values[1];
1030 + $user_time_frame = $array_my_values[2];
1031 + $absolute = $array_my_values[3];
1032 + $role = $array_my_values[4];
1033 + $active = $array_my_values[5];
1034 + $ums_sub = $array_my_values[6];
1035 + $message = $array_my_values[7];
1036 + $rule_description = $array_my_values[8];
1037 + $user_list = $array_my_values[9];
1038 + $rest_sub = $array_my_values[10];
1039 + $paid_sub = $array_my_values[11];
1040 + if ($active !== "1") {
1041 + continue;
1042 + }
1043 + if (
1044 + empty($user_time_frame) ||
1045 + empty($user_credit_type) ||
1046 + empty($user_credits)
1047 + ) {
1048 + continue;
1049 + }
1050 + if (
1051 + $user_credit_type == 'pdf' || $user_credit_type == 'pdfchar'
1052 + ) {
1053 + continue;
1054 + }
1055 + $isAbsolute = false;
1056 + if ($absolute == "1") {
1057 + $isAbsolute = true;
1058 + }
1059 + if ($role == "any" || in_array($role, $userRoles)) {
1060 + $matching = true;
1061 + }
1062 + if(!empty($user_list) && !empty($userId))
1063 + {
1064 + $user_list_arr = explode(',', trim($user_list));
1065 + foreach($user_list_arr as $uli)
1066 + {
1067 + if($userId == $uli)
1068 + {
1069 + $matching = true;
1070 + break;
1071 + }
1072 + }
1073 + }
1074 + if ($ums_sub == "any" || in_array($ums_sub, $userSubs)) {
1075 + $matching = true;
1076 + } elseif ($ums_sub == "nosub" && empty($userSubs)) {
1077 + $matching = true;
1078 + } else {
1079 + if ($ums_sub !== "none") {
1080 + $matching = false;
1081 + }
1082 + }
1083 + if ($rest_sub == "any" || in_array($rest_sub, $userSubs)) {
1084 + $matching = true;
1085 + } elseif ($rest_sub == "nosub" && empty($userSubs)) {
1086 + $matching = true;
1087 + } else {
1088 + if ($rest_sub !== "none") {
1089 + $matching = false;
1090 + }
1091 + }
1092 + if ($paid_sub == "any" || in_array($paid_sub, $userSubs)) {
1093 + $matching = true;
1094 + } elseif ($paid_sub == "nosub" && empty($userSubs)) {
1095 + $matching = true;
1096 + } else {
1097 + if ($paid_sub !== "none") {
1098 + $matching = false;
1099 + }
1100 + }
1101 + if ($matching === true)
1102 + {
1103 + $stats = $this->query(
1104 + $user_time_frame,
1105 + $isAbsolute,
1106 + $user_credits,
1107 + $user_credit_type
1108 + );
1109 + if ($stats["queriesLimit"] != "0") {
1110 + $limits .=
1111 + $stats["queries"] .
1112 + esc_html__(" used from a maximum of ", "aiomatic-automatic-ai-content-writer") .
1113 + $stats["queriesLimit"] .
1114 + " " .
1115 + esc_html__(
1116 + "queries",
1117 + "aiomatic-automatic-ai-content-writer"
1118 + ) .
1119 + "/" .
1120 + $user_time_frame .
1121 + "<br>";
1122 + } elseif ($stats["unitsLimit"] != "0") {
1123 + $limits .=
1124 + $stats["units"] .
1125 + esc_html__(" used from a maximum of ", "aiomatic-automatic-ai-content-writer") .
1126 + $stats["unitsLimit"] .
1127 + " " .
1128 + esc_html__(
1129 + "tokens",
1130 + "aiomatic-automatic-ai-content-writer"
1131 + ) .
1132 + "/" .
1133 + $user_time_frame .
1134 + "<br>";
1135 + } elseif ($stats["priceLimit"] != "0") {
1136 + $limits .=
1137 + $stats["price"] .
1138 + esc_html__(" used from a maximum of ", "aiomatic-automatic-ai-content-writer") .
1139 + $stats["priceLimit"] .
1140 + " " .
1141 + esc_html__(
1142 + "USD",
1143 + "aiomatic-automatic-ai-content-writer"
1144 + ) .
1145 + "/" .
1146 + $user_time_frame .
1147 + "<br>";
1148 + }
1149 + }
1150 + }
1151 + }
1152 + if (empty($limits)) {
1153 + return esc_html__(
1154 + "No limit",
1155 + "aiomatic-automatic-ai-content-writer"
1156 + );
1157 + } else {
1158 + return $limits;
1159 + }
1160 + }
1161 +
1162 + function calculatePrice(
1163 + $model,
1164 + $response_units,
1165 + $prompt_units = 0,
1166 + $option = null
1167 + ) {
1168 + if(empty($model))
1169 + {
1170 + return 0;
1171 + }
1172 + $aiomatic_Main_Settings = get_option('aiomatic_Main_Settings', false);
1173 + // Price as of 1st November 2023: https://openai.com/api/pricing/
1174 + $openai_pricing = [
1175 + // Base models:
1176 + [
1177 + "model" => "text-embedding-ada-002",
1178 + "prompt_price" => 0.0001,
1179 + "completion_price" => 0.0001,
1180 + "type" => "token",
1181 + "unit" => 1 / 1000,
1182 + "options" => [],
1183 + ],
1184 + [
1185 + "model" => "text-embedding-3-large",
1186 + "prompt_price" => 0.00013,
1187 + "completion_price" => 0.00013,
1188 + "type" => "token",
1189 + "unit" => 1 / 1000,
1190 + "options" => [],
1191 + ],
1192 + [
1193 + "model" => "text-embedding-3-small",
1194 + "prompt_price" => 0.00002,
1195 + "completion_price" => 0.00002,
1196 + "type" => "token",
1197 + "unit" => 1 / 1000,
1198 + "options" => [],
1199 + ],
1200 + [
1201 + "model" => "chatgpt",
1202 + "prompt_price" => 0.0010,
1203 + "completion_price" => 0.002,
1204 + "type" => "token",
1205 + "unit" => 1 / 1000,
1206 + "options" => [],
1207 + ],
1208 + [
1209 + "model" => "chatgpt-16k",
1210 + "prompt_price" => 0.003,
1211 + "completion_price" => 0.004,
1212 + "type" => "token",
1213 + "unit" => 1 / 1000,
1214 + "options" => [],
1215 + ],
1216 + [
1217 + "model" => "gpt4",
1218 + "prompt_price" => 0.03,
1219 + "completion_price" => 0.06,
1220 + "type" => "token",
1221 + "unit" => 1 / 1000,
1222 + "options" => [],
1223 + ],
1224 + [
1225 + "model" => "gpt4-turbo",
1226 + "prompt_price" => 0.01,
1227 + "completion_price" => 0.03,
1228 + "type" => "token",
1229 + "unit" => 1 / 1000,
1230 + "options" => [],
1231 + ],
1232 + [
1233 + "model" => "gpt4o",
1234 + "prompt_price" => 0.005,
1235 + "completion_price" => 0.015,
1236 + "type" => "token",
1237 + "unit" => 1 / 1000,
1238 + "options" => [],
1239 + ],
1240 + [
1241 + "model" => "o1",
1242 + "prompt_price" => 0.015,
1243 + "completion_price" => 0.06,
1244 + "type" => "token",
1245 + "unit" => 1 / 1000,
1246 + "options" => [],
1247 + ],
1248 + [
1249 + "model" => "o1-pro",
1250 + "prompt_price" => 0.15,
1251 + "completion_price" => 0.6,
1252 + "type" => "token",
1253 + "unit" => 1 / 1000,
1254 + "options" => [],
1255 + ],
1256 + [
1257 + "model" => "o3-mini",
1258 + "prompt_price" => 0.0011,
1259 + "completion_price" => 0.0044,
1260 + "type" => "token",
1261 + "unit" => 1 / 1000,
1262 + "options" => [],
1263 + ],
1264 + [
1265 + "model" => "o3",
1266 + "prompt_price" => 0.01,
1267 + "completion_price" => 0.04,
1268 + "type" => "token",
1269 + "unit" => 1 / 1000,
1270 + "options" => [],
1271 + ],
1272 + [
1273 + "model" => "o4-mini",
1274 + "prompt_price" => 0.0011,
1275 + "completion_price" => 0.0044,
1276 + "type" => "token",
1277 + "unit" => 1 / 1000,
1278 + "options" => [],
1279 + ],
1280 + [
1281 + "model" => "o3-2025-04-16",
1282 + "prompt_price" => 0.01,
1283 + "completion_price" => 0.04,
1284 + "type" => "token",
1285 + "unit" => 1 / 1000,
1286 + "options" => [],
1287 + ],
1288 + [
1289 + "model" => "o4-mini-2025-04-16",
1290 + "prompt_price" => 0.0011,
1291 + "completion_price" => 0.0044,
1292 + "type" => "token",
1293 + "unit" => 1 / 1000,
1294 + "options" => [],
1295 + ],
1296 + [
1297 + "model" => "o3-pro",
1298 + "prompt_price" => 0.01,
1299 + "completion_price" => 0.04,
1300 + "type" => "token",
1301 + "unit" => 1 / 1000,
1302 + "options" => [],
1303 + ],
1304 + [
1305 + "model" => "o3-pro-2025-06-10",
1306 + "prompt_price" => 0.01,
1307 + "completion_price" => 0.04,
1308 + "type" => "token",
1309 + "unit" => 1 / 1000,
1310 + "options" => [],
1311 + ],
1312 + [
1313 + "model" => "o4-mini",
1314 + "prompt_price" => 0.0011,
1315 + "completion_price" => 0.0044,
1316 + "type" => "token",
1317 + "unit" => 1 / 1000,
1318 + "options" => [],
1319 + ],
1320 + [
1321 + "model" => "gpt4omini",
1322 + "prompt_price" => 0.00015,
1323 + "completion_price" => 0.0006,
1324 + "type" => "token",
1325 + "unit" => 1 / 1000,
1326 + "options" => [],
1327 + ],
1328 + [
1329 + "model" => "gpt41",
1330 + "prompt_price" => 0.002,
1331 + "completion_price" => 0.008,
1332 + "type" => "token",
1333 + "unit" => 1 / 1000,
1334 + "options" => [],
1335 + ],
1336 + [
1337 + "model" => "gpt5",
1338 + "prompt_price" => 0.00125,
1339 + "completion_price" => 0.01,
1340 + "type" => "token",
1341 + "unit" => 1 / 1000,
1342 + "options" => [],
1343 + ],
1344 + [
1345 + "model" => "gpt4-32k",
1346 + "prompt_price" => 0.06,
1347 + "completion_price" => 0.12,
1348 + "type" => "token",
1349 + "unit" => 1 / 1000,
1350 + "options" => [],
1351 + ],
1352 + [
1353 + "model" => "davinci",
1354 + "prompt_price" => 0.002,
1355 + "completion_price" => 0.002,
1356 + "type" => "token",
1357 + "unit" => 1 / 1000,
1358 + "options" => [],
1359 + ],
1360 + [
1361 + "model" => "gpt-instruct",
1362 + "prompt_price" => 0.0015,
1363 + "completion_price" => 0.002,
1364 + "type" => "token",
1365 + "unit" => 1 / 1000,
1366 + "options" => [],
1367 + ],
1368 + [
1369 + "model" => "curie",
1370 + "prompt_price" => 0.002,
1371 + "completion_price" => 0.002,
1372 + "type" => "token",
1373 + "unit" => 1 / 1000,
1374 + "options" => [],
1375 + ],
1376 + [
1377 + "model" => "babbage",
1378 + "prompt_price" => 0.0004,
1379 + "completion_price" => 0.0004,
1380 + "type" => "token",
1381 + "unit" => 1 / 1000,
1382 + "options" => [],
1383 + ],
1384 + [
1385 + "model" => "ada",
1386 + "prompt_price" => 0.0004,
1387 + "completion_price" => 0.0004,
1388 + "type" => "token",
1389 + "unit" => 1 / 1000,
1390 + "options" => [],
1391 + ],
1392 + // Image models:
1393 + [
1394 + "model" => "dalle2",
1395 + "type" => "image",
1396 + "unit" => 1,
1397 + "options" => [
1398 + ["option" => "1024x1024", "price" => 0.02],
1399 + ["option" => "512x512", "price" => 0.018],
1400 + ["option" => "256x256", "price" => 0.016],
1401 + ],
1402 + ],
1403 + [
1404 + "model" => "dalle3",
1405 + "type" => "image",
1406 + "unit" => 1,
1407 + "options" => [
1408 + ["option" => "1024x1024", "price" => 0.04],
1409 + ["option" => "1024x1792", "price" => 0.08],
1410 + ["option" => "1792x1024", "price" => 0.08]
1411 + ],
1412 + ],
1413 + [
1414 + "model" => "dalle3hd",
1415 + "type" => "image",
1416 + "unit" => 1,
1417 + "options" => [
1418 + ["option" => "1024x1024", "price" => 0.08],
1419 + ["option" => "1024x1792", "price" => 0.12],
1420 + ["option" => "1792x1024", "price" => 0.12]
1421 + ],
1422 + ],
1423 + [
1424 + "model" => "gpt-image-1",
1425 + "type" => "image",
1426 + "unit" => 1,
1427 + "options" => [
1428 + ["option" => "1024x1024", "price" => 0.08],
1429 + ["option" => "1024x1792", "price" => 0.12],
1430 + ["option" => "1792x1024", "price" => 0.12],
1431 + ["option" => "1536x1024", "price" => 0.12],
1432 + ["option" => "1024x1536", "price" => 0.12]
1433 + ],
1434 + ],
1435 + [
1436 + "model" => "gpt-image-1.5",
1437 + "type" => "image",
1438 + "unit" => 1,
1439 + "options" => [
1440 + ["option" => "1024x1024", "price" => 0.08],
1441 + ["option" => "1024x1792", "price" => 0.12],
1442 + ["option" => "1792x1024", "price" => 0.12],
1443 + ["option" => "1536x1024", "price" => 0.12],
1444 + ["option" => "1024x1536", "price" => 0.12]
1445 + ],
1446 + ],
1447 + [
1448 + "model" => "chatgpt-image-latest",
1449 + "type" => "image",
1450 + "unit" => 1,
1451 + "options" => [
1452 + ["option" => "1024x1024", "price" => 0.08],
1453 + ["option" => "1024x1792", "price" => 0.12],
1454 + ["option" => "1792x1024", "price" => 0.12],
1455 + ["option" => "1536x1024", "price" => 0.12],
1456 + ["option" => "1024x1536", "price" => 0.12]
1457 + ],
1458 + ],
1459 + [
1460 + "model" => "gpt-image-1-mini",
1461 + "type" => "image",
1462 + "unit" => 1,
1463 + "options" => [
1464 + ["option" => "1024x1024", "price" => 0.02],
1465 + ["option" => "1024x1792", "price" => 0.04],
1466 + ["option" => "1792x1024", "price" => 0.04],
1467 + ["option" => "1536x1024", "price" => 0.04],
1468 + ["option" => "1024x1536", "price" => 0.04]
1469 + ],
1470 + ],
1471 + [
1472 + "model" => "stable-diffusion",
1473 + "type" => "image",
1474 + "unit" => 1,
1475 + "options" => [
1476 + ["option" => "1024x1024", "price" => 0.02],
1477 + ["option" => "512x512", "price" => 0.018],
1478 + ],
1479 + ],
1480 + [
1481 + "model" => "replicate",
1482 + "type" => "image",
1483 + "unit" => 1,
1484 + "options" => [
1485 + ["option" => "1024x1024", "price" => 0.08],
1486 + ["option" => "1024x1792", "price" => 0.12],
1487 + ["option" => "1792x1024", "price" => 0.12],
1488 + ["option" => "512x512", "price" => 0.018],
1489 + ["option" => "256x256", "price" => 0.016],
1490 + ],
1491 + ],
1492 + [
1493 + "model" => "ideogram",
1494 + "type" => "image",
1495 + "unit" => 1,
1496 + "options" => [
1497 + ["option" => "1024x1024", "price" => 0.08],
1498 + ["option" => "1024x1792", "price" => 0.12],
1499 + ["option" => "1792x1024", "price" => 0.12],
1500 + ["option" => "512x512", "price" => 0.018],
1501 + ["option" => "256x256", "price" => 0.016],
1502 + ],
1503 + ],
1504 + // Fine-tuned models:
1505 + [
1506 + "model" => "fn-davinci",
1507 + "prompt_price" => 0.012,
1508 + "completion_price" => 0.012,
1509 + "type" => "token",
1510 + "unit" => 1 / 1000,
1511 + "options" => [],
1512 + ],
1513 + [
1514 + "model" => "fn-curie",
1515 + "prompt_price" => 0.012,
1516 + "completion_price" => 0.012,
1517 + "type" => "token",
1518 + "unit" => 1 / 1000,
1519 + "options" => [],
1520 + ],
1521 + [
1522 + "model" => "fn-babbage",
1523 + "prompt_price" => 0.0016,
1524 + "completion_price" => 0.0016,
1525 + "type" => "token",
1526 + "unit" => 1 / 1000,
1527 + "options" => [],
1528 + ],
1529 + [
1530 + "model" => "fn-ada",
1531 + "prompt_price" => 0.0016,
1532 + "completion_price" => 0.0016,
1533 + "type" => "token",
1534 + "unit" => 1 / 1000,
1535 + "options" => [],
1536 + ],
1537 + [
1538 + "model" => "fn-turbo",
1539 + "prompt_price" => 0.003,
1540 + "completion_price" => 0.006,
1541 + "type" => "token",
1542 + "unit" => 1 / 1000,
1543 + "options" => [],
1544 + ],
1545 + [
1546 + "model" => "fn-gpt4",
1547 + "prompt_price" => 0.09,
1548 + "completion_price" => 0.18,
1549 + "type" => "token",
1550 + "unit" => 1 / 1000,
1551 + "options" => [],
1552 + ],
1553 + [
1554 + "model" => "whisper-1",
1555 + "prompt_price" => 0,
1556 + "completion_price" => 0,
1557 + "type" => "token",
1558 + "unit" => 1 / 1000,
1559 + "options" => [],
1560 + ],
1561 + ];
1562 + //https://www.goapi.ai/midjourney-api
1563 + $midjourney_pricing = [[
1564 + "model" => "fast",
1565 + "type" => "image",
1566 + "unit" => 1,
1567 + "options" => [
1568 + ["option" => "1024x1024", "price" => 0.045],
1569 + ["option" => "512x512", "price" => 0.045],
1570 + ["option" => "256x256", "price" => 0.045],
1571 + ["option" => "1792x1024", "price" => 0.045],
1572 + ["option" => "1024x1792", "price" => 0.045],
1573 + ],
1574 + [
1575 + "model" => "turbo",
1576 + "type" => "image",
1577 + "unit" => 1,
1578 + "options" => [
1579 + ["option" => "1024x1024", "price" => 0.1],
1580 + ["option" => "512x512", "price" => 0.1],
1581 + ["option" => "256x256", "price" => 0.1],
1582 + ["option" => "1792x1024", "price" => 0.1],
1583 + ["option" => "1024x1792", "price" => 0.1],
1584 + ]],
1585 + [
1586 + "model" => "mixed",
1587 + "type" => "image",
1588 + "unit" => 1,
1589 + "options" => [
1590 + ["option" => "1024x1024", "price" => 0.015],
1591 + ["option" => "512x512", "price" => 0.015],
1592 + ["option" => "256x256", "price" => 0.015],
1593 + ["option" => "1792x1024", "price" => 0.015],
1594 + ["option" => "1024x1792", "price" => 0.015],
1595 + ]]
1596 + ]
1597 + ];
1598 + //https://azure.microsoft.com/en-us/pricing/details/cognitive-services/openai-service/
1599 + $azure_pricing = [
1600 + // Base models:
1601 + [
1602 + "model" => "embeddings",
1603 + "prompt_price" => 0.0001,
1604 + "completion_price" => 0.0001,
1605 + "type" => "token",
1606 + "unit" => 1 / 1000,
1607 + "options" => [],
1608 + ],
1609 + [
1610 + "model" => "chatgpt",
1611 + "prompt_price" => 0.0005,
1612 + "completion_price" => 0.0015,
1613 + "type" => "token",
1614 + "unit" => 1 / 1000,
1615 + "options" => [],
1616 + ],
1617 + [
1618 + "model" => "o1",
1619 + "prompt_price" => 0.0005,
1620 + "completion_price" => 0.0015,
1621 + "type" => "token",
1622 + "unit" => 1 / 1000,
1623 + "options" => [],
1624 + ],
1625 + [
1626 + "model" => "gpt4omini",
1627 + "prompt_price" => 0.0005,
1628 + "completion_price" => 0.0015,
1629 + "type" => "token",
1630 + "unit" => 1 / 1000,
1631 + "options" => [],
1632 + ],
1633 + [
1634 + "model" => "gpt4o",
1635 + "prompt_price" => 0.0005,
1636 + "completion_price" => 0.0015,
1637 + "type" => "token",
1638 + "unit" => 1 / 1000,
1639 + "options" => [],
1640 + ],
1641 + [
1642 + "model" => "gpt-instruct",
1643 + "prompt_price" => 0.0015,
1644 + "completion_price" => 0.002,
1645 + "type" => "token",
1646 + "unit" => 1 / 1000,
1647 + "options" => [],
1648 + ],
1649 + [
1650 + "model" => "chatgpt-16k",
1651 + "prompt_price" => 0.003,
1652 + "completion_price" => 0.004,
1653 + "type" => "token",
1654 + "unit" => 1 / 1000,
1655 + "options" => [],
1656 + ],
1657 + [
1658 + "model" => "gpt4",
1659 + "prompt_price" => 0.03,
1660 + "completion_price" => 0.06,
1661 + "type" => "token",
1662 + "unit" => 1 / 1000,
1663 + "options" => [],
1664 + ],
1665 + [
1666 + "model" => "gpt4turbo",
1667 + "prompt_price" => 0.03,
1668 + "completion_price" => 0.06,
1669 + "type" => "token",
1670 + "unit" => 1 / 1000,
1671 + "options" => [],
1672 + ],
1673 + [
1674 + "model" => "gpt4turbovision",
1675 + "prompt_price" => 0.03,
1676 + "completion_price" => 0.06,
1677 + "type" => "token",
1678 + "unit" => 1 / 1000,
1679 + "options" => [],
1680 + ],
1681 + [
1682 + "model" => "gpt4-32k",
1683 + "prompt_price" => 0.06,
1684 + "completion_price" => 0.12,
1685 + "type" => "token",
1686 + "unit" => 1 / 1000,
1687 + "options" => [],
1688 + ],
1689 + [
1690 + "model" => "davinci",
1691 + "prompt_price" => 0.02,
1692 + "completion_price" => 0.02,
1693 + "type" => "token",
1694 + "unit" => 1 / 1000,
1695 + "options" => [],
1696 + ],
1697 + [
1698 + "model" => "curie",
1699 + "prompt_price" => 0.002,
1700 + "completion_price" => 0.002,
1701 + "type" => "token",
1702 + "unit" => 1 / 1000,
1703 + "options" => [],
1704 + ],
1705 + [
1706 + "model" => "babbage",
1707 + "prompt_price" => 0.0005,
1708 + "completion_price" => 0.0005,
1709 + "type" => "token",
1710 + "unit" => 1 / 1000,
1711 + "options" => [],
1712 + ],
1713 + [
1714 + "model" => "ada",
1715 + "prompt_price" => 0.0004,
1716 + "completion_price" => 0.0004,
1717 + "type" => "token",
1718 + "unit" => 1 / 1000,
1719 + "options" => [],
1720 + ],
1721 + // Image models:
1722 + [
1723 + "model" => "dall-e",
1724 + "type" => "image",
1725 + "unit" => 1,
1726 + "options" => [
1727 + ["option" => "1024x1024", "price" => 0.02],
1728 + ["option" => "512x512", "price" => 0.02],
1729 + ["option" => "256x256", "price" => 0.02],
1730 + ],
1731 + ],
1732 + // Image models:
1733 + [
1734 + "model" => "dalle3",
1735 + "type" => "image",
1736 + "unit" => 1,
1737 + "options" => [
1738 + ["option" => "1024x1024", "price" => 0.04],
1739 + ["option" => "1024x1792", "price" => 0.08],
1740 + ["option" => "1792x1024", "price" => 0.08],
1741 + ],
1742 + ],
1743 + [
1744 + "model" => "dalle3hd",
1745 + "type" => "image",
1746 + "unit" => 1,
1747 + "options" => [
1748 + ["option" => "1024x1024", "price" => 0.08],
1749 + ["option" => "1024x1792", "price" => 0.12],
1750 + ["option" => "1792x1024", "price" => 0.12]
1751 + ],
1752 + ],
1753 + [
1754 + "model" => "gpt-image-1",
1755 + "type" => "image",
1756 + "unit" => 1,
1757 + "options" => [
1758 + ["option" => "1024x1024", "price" => 0.08],
1759 + ["option" => "1024x1792", "price" => 0.12],
1760 + ["option" => "1792x1024", "price" => 0.12],
1761 + ["option" => "1536x1024", "price" => 0.12],
1762 + ["option" => "1024x1536", "price" => 0.12]
1763 + ],
1764 + ],
1765 + [
1766 + "model" => "gpt-image-1.5",
1767 + "type" => "image",
1768 + "unit" => 1,
1769 + "options" => [
1770 + ["option" => "1024x1024", "price" => 0.08],
1771 + ["option" => "1024x1792", "price" => 0.12],
1772 + ["option" => "1792x1024", "price" => 0.12],
1773 + ["option" => "1536x1024", "price" => 0.12],
1774 + ["option" => "1024x1536", "price" => 0.12]
1775 + ],
1776 + ],
1777 + [
1778 + "model" => "chatgpt-image-latest",
1779 + "type" => "image",
1780 + "unit" => 1,
1781 + "options" => [
1782 + ["option" => "1024x1024", "price" => 0.08],
1783 + ["option" => "1024x1792", "price" => 0.12],
1784 + ["option" => "1792x1024", "price" => 0.12],
1785 + ["option" => "1536x1024", "price" => 0.12],
1786 + ["option" => "1024x1536", "price" => 0.12]
1787 + ],
1788 + ],
1789 + [
1790 + "model" => "gpt-image-1-mini",
1791 + "type" => "image",
1792 + "unit" => 1,
1793 + "options" => [
1794 + ["option" => "1024x1024", "price" => 0.02],
1795 + ["option" => "1024x1792", "price" => 0.04],
1796 + ["option" => "1792x1024", "price" => 0.04],
1797 + ["option" => "1536x1024", "price" => 0.04],
1798 + ["option" => "1024x1536", "price" => 0.04]
1799 + ],
1800 + ],
1801 + [
1802 + "model" => "stable-diffusion",
1803 + "type" => "image",
1804 + "unit" => 1,
1805 + "options" => [
1806 + ["option" => "1024x1024", "price" => 0.02],
1807 + ["option" => "512x512", "price" => 0.018],
1808 + ],
1809 + ],
1810 + [
1811 + "model" => "replicate",
1812 + "type" => "image",
1813 + "unit" => 1,
1814 + "options" => [
1815 + ["option" => "1024x1024", "price" => 0.08],
1816 + ["option" => "1024x1792", "price" => 0.12],
1817 + ["option" => "1792x1024", "price" => 0.12],
1818 + ["option" => "512x512", "price" => 0.018],
1819 + ["option" => "256x256", "price" => 0.016],
1820 + ],
1821 + ],
1822 + [
1823 + "model" => "ideogram",
1824 + "type" => "image",
1825 + "unit" => 1,
1826 + "options" => [
1827 + ["option" => "1024x1024", "price" => 0.08],
1828 + ["option" => "1024x1792", "price" => 0.12],
1829 + ["option" => "1792x1024", "price" => 0.12],
1830 + ["option" => "512x512", "price" => 0.018],
1831 + ["option" => "256x256", "price" => 0.016],
1832 + ],
1833 + ],
1834 + // Fine-tuned models:
1835 + [
1836 + "model" => "fn-davinci",
1837 + "prompt_price" => 0.02,
1838 + "completion_price" => 0.02,
1839 + "type" => "token",
1840 + "unit" => 1 / 1000,
1841 + "options" => [],
1842 + ],
1843 + [
1844 + "model" => "fn-curie",
1845 + "prompt_price" => 0.002,
1846 + "completion_price" => 0.002,
1847 + "type" => "token",
1848 + "unit" => 1 / 1000,
1849 + "options" => [],
1850 + ],
1851 + [
1852 + "model" => "fn-babbage",
1853 + "prompt_price" => 0.0005,
1854 + "completion_price" => 0.0005,
1855 + "type" => "token",
1856 + "unit" => 1 / 1000,
1857 + "options" => [],
1858 + ],
1859 + [
1860 + "model" => "fn-ada",
1861 + "prompt_price" => 0.0004,
1862 + "completion_price" => 0.0004,
1863 + "type" => "token",
1864 + "unit" => 1 / 1000,
1865 + "options" => [],
1866 + ],
1867 + ];
1868 + //https://www-files.anthropic.com/production/images/model_pricing_nov2023.pdf
1869 + $claude_pricing = [
1870 + // Base models:
1871 + [
1872 + "model" => "claude-3-opus-20240229",
1873 + "prompt_price" => 0.015,
1874 + "completion_price" => 0.075,
1875 + "type" => "token",
1876 + "unit" => 1 / 1000,
1877 + "options" => [],
1878 + ],
1879 + [
1880 + "model" => "claude-3-sonnet-20240229",
1881 + "prompt_price" => 0.003,
1882 + "completion_price" => 0.015,
1883 + "type" => "token",
1884 + "unit" => 1 / 1000,
1885 + "options" => [],
1886 + ],
1887 + [
1888 + "model" => "claude-3-haiku-20240307",
1889 + "prompt_price" => 0.00025,
1890 + "completion_price" => 0.00125,
1891 + "type" => "token",
1892 + "unit" => 1 / 1000,
1893 + "options" => [],
1894 + ],
1895 + [
1896 + "model" => "claude-3-5-sonnet-20240620",
1897 + "prompt_price" => 0.003,
1898 + "completion_price" => 0.015,
1899 + "type" => "token",
1900 + "unit" => 1 / 1000,
1901 + "options" => [],
1902 + ],
1903 + [
1904 + "model" => "claude-3-5-sonnet-20241022",
1905 + "prompt_price" => 0.003,
1906 + "completion_price" => 0.015,
1907 + "type" => "token",
1908 + "unit" => 1 / 1000,
1909 + "options" => [],
1910 + ],
1911 + [
1912 + "model" => "claude-3-5-haiku-20241022",
1913 + "prompt_price" => 0.00025,
1914 + "completion_price" => 0.00125,
1915 + "type" => "token",
1916 + "unit" => 1 / 1000,
1917 + "options" => [],
1918 + ],
1919 + [
1920 + "model" => "claude-3-7-sonnet-20250219",
1921 + "prompt_price" => 0.003,
1922 + "completion_price" => 0.015,
1923 + "type" => "token",
1924 + "unit" => 1 / 1000,
1925 + "options" => [],
1926 + ],
1927 + [
1928 + "model" => "claude-sonnet-4-20250514",
1929 + "prompt_price" => 0.003,
1930 + "completion_price" => 0.015,
1931 + "type" => "token",
1932 + "unit" => 1 / 1000,
1933 + "options" => [],
1934 + ],
1935 + [
1936 + "model" => "claude-opus-4-20250514",
1937 + "prompt_price" => 0.015,
1938 + "completion_price" => 0.075,
1939 + "type" => "token",
1940 + "unit" => 1 / 1000,
1941 + "options" => [],
1942 + ],
1943 + [
1944 + "model" => "claude-opus-4-1-20250805",
1945 + "prompt_price" => 0.015,
1946 + "completion_price" => 0.075,
1947 + "type" => "token",
1948 + "unit" => 1 / 1000,
1949 + "options" => [],
1950 + ],
1951 + [
1952 + "model" => "claude-sonnet-4-5-20250929",
1953 + "prompt_price" => 0.015,
1954 + "completion_price" => 0.075,
1955 + "type" => "token",
1956 + "unit" => 1 / 1000,
1957 + "options" => [],
1958 + ]
1959 + ];
1960 + $google_pricing = [
1961 + // Base models:
1962 + [
1963 + "model" => "gemini-2.0-flash-thinking-exp-01-21",
1964 + "prompt_price" => 0,
1965 + "completion_price" => 0,
1966 + "type" => "token",
1967 + "unit" => 1 / 1000,
1968 + "options" => [],
1969 + ],[
1970 + "model" => "gemini-2.5-pro-exp-03-25",
1971 + "prompt_price" => 0,
1972 + "completion_price" => 0,
1973 + "type" => "token",
1974 + "unit" => 1 / 1000,
1975 + "options" => [],
1976 + ],[
1977 + "model" => "gemini-2.5-pro",
1978 + "prompt_price" => 0,
1979 + "completion_price" => 0,
1980 + "type" => "token",
1981 + "unit" => 1 / 1000,
1982 + "options" => [],
1983 + ],[
1984 + "model" => "gemini-3-pro-preview",
1985 + "prompt_price" => 0,
1986 + "completion_price" => 0,
1987 + "type" => "token",
1988 + "unit" => 1 / 1000,
1989 + "options" => [],
1990 + ],[
1991 + "model" => "gemini-2.5-flash",
1992 + "prompt_price" => 0,
1993 + "completion_price" => 0,
1994 + "type" => "token",
1995 + "unit" => 1 / 1000,
1996 + "options" => [],
1997 + ],[
1998 + "model" => "gemini-2.5-flash-lite",
1999 + "prompt_price" => 0,
2000 + "completion_price" => 0,
2001 + "type" => "token",
2002 + "unit" => 1 / 1000,
2003 + "options" => [],
2004 + ],[
2005 + "model" => "gemini-2.5-flash-preview-05-20",
2006 + "prompt_price" => 0,
2007 + "completion_price" => 0,
2008 + "type" => "token",
2009 + "unit" => 1 / 1000,
2010 + "options" => [],
2011 + ],[
2012 + "model" => "gemini-2.5-pro-preview-06-05",
2013 + "prompt_price" => 0,
2014 + "completion_price" => 0,
2015 + "type" => "token",
2016 + "unit" => 1 / 1000,
2017 + "options" => [],
2018 + ],[
2019 + "model" => "gemini-2.5-flash-lite-preview-06-17",
2020 + "prompt_price" => 0,
2021 + "completion_price" => 0,
2022 + "type" => "token",
2023 + "unit" => 1 / 1000,
2024 + "options" => [],
2025 + ],[
2026 + "model" => "gemini-2.5-flash-preview-04-17",
2027 + "prompt_price" => 0,
2028 + "completion_price" => 0,
2029 + "type" => "token",
2030 + "unit" => 1 / 1000,
2031 + "options" => [],
2032 + ],[
2033 + "model" => "gemma-3-27b-it",
2034 + "prompt_price" => 0,
2035 + "completion_price" => 0,
2036 + "type" => "token",
2037 + "unit" => 1 / 1000,
2038 + "options" => [],
2039 + ],[
2040 + "model" => "gemini-2.0-pro-exp-02-05",
2041 + "prompt_price" => 0,
2042 + "completion_price" => 0,
2043 + "type" => "token",
2044 + "unit" => 1 / 1000,
2045 + "options" => [],
2046 + ],[
2047 + "model" => "gemini-2.0-flash-exp",
2048 + "prompt_price" => 0,
2049 + "completion_price" => 0,
2050 + "type" => "token",
2051 + "unit" => 1 / 1000,
2052 + "options" => [],
2053 + ],[
2054 + "model" => "gemini-2.0-flash",
2055 + "prompt_price" => 0,
2056 + "completion_price" => 0,
2057 + "type" => "token",
2058 + "unit" => 1 / 1000,
2059 + "options" => [],
2060 + ],[
2061 + "model" => "gemini-2.0-flash-lite",
2062 + "prompt_price" => 0,
2063 + "completion_price" => 0,
2064 + "type" => "token",
2065 + "unit" => 1 / 1000,
2066 + "options" => [],
2067 + ],[
2068 + "model" => "chat-bison-001",
2069 + "prompt_price" => 0,
2070 + "completion_price" => 0,
2071 + "type" => "token",
2072 + "unit" => 1 / 1000,
2073 + "options" => [],
2074 + ],
2075 + [
2076 + "model" => "text-bison-001",
2077 + "prompt_price" => 0,
2078 + "completion_price" => 0,
2079 + "type" => "token",
2080 + "unit" => 1 / 1000,
2081 + "options" => [],
2082 + ]
2083 + ];
2084 + //https://docs.perplexity.ai/docs/pricing
2085 + $perplexity_pricing = [
2086 + // Base models:
2087 + [
2088 + "model" => "sonar-pro",
2089 + "prompt_price" => 0.001,
2090 + "completion_price" => 0.001,
2091 + "type" => "token",
2092 + "unit" => 1 / 1000,
2093 + "options" => [],
2094 + ],
2095 + [
2096 + "model" => "sonar-reasoning",
2097 + "prompt_price" => 0.001,
2098 + "completion_price" => 0.001,
2099 + "type" => "token",
2100 + "unit" => 1 / 1000,
2101 + "options" => [],
2102 + ],
2103 + [
2104 + "model" => "sonar-deep-research",
2105 + "prompt_price" => 0.001,
2106 + "completion_price" => 0.001,
2107 + "type" => "token",
2108 + "unit" => 1 / 1000,
2109 + "options" => [],
2110 + ],
2111 + [
2112 + "model" => "sonar-reasoning-pro",
2113 + "prompt_price" => 0.001,
2114 + "completion_price" => 0.001,
2115 + "type" => "token",
2116 + "unit" => 1 / 1000,
2117 + "options" => [],
2118 + ],
2119 + [
2120 + "model" => "sonar",
2121 + "prompt_price" => 0.001,
2122 + "completion_price" => 0.001,
2123 + "type" => "token",
2124 + "unit" => 1 / 1000,
2125 + "options" => [],
2126 + ]
2127 + ];
2128 + if (aiomatic_check_if_midjourney($model))
2129 + {
2130 + foreach ($midjourney_pricing as $price) {
2131 + if ($price["model"] == $model) {
2132 + if ($price["type"] == "image") {
2133 + if (!$option) {
2134 + aiomatic_log_to_file("Image models require an option.");
2135 + return 0;
2136 + } else {
2137 + foreach ($price["options"] as $imageType) {
2138 + if ($imageType["option"] == $option) {
2139 + $response_price =
2140 + $imageType["price"] * $response_units;
2141 + return $response_price;
2142 + }
2143 + }
2144 + }
2145 + } else {
2146 + $response_price =
2147 + $price["completion_price"] *
2148 + $price["unit"] *
2149 + $response_units;
2150 + $prompt_price =
2151 + $price["prompt_price"] * $price["unit"] * $prompt_units;
2152 + return $response_price + $prompt_price;
2153 + }
2154 + }
2155 + }
2156 + }
2157 + elseif (aiomatic_is_claude_model($model))
2158 + {
2159 + foreach ($claude_pricing as $price) {
2160 + if ($price["model"] == $model) {
2161 + if ($price["type"] == "image") {
2162 + if (!$option) {
2163 + aiomatic_log_to_file("Image models require an option.");
2164 + return 0;
2165 + } else {
2166 + foreach ($price["options"] as $imageType) {
2167 + if ($imageType["option"] == $option) {
2168 + $response_price =
2169 + $imageType["price"] * $response_units;
2170 + return $response_price;
2171 + }
2172 + }
2173 + }
2174 + } else {
2175 + $response_price =
2176 + $price["completion_price"] *
2177 + $price["unit"] *
2178 + $response_units;
2179 + $prompt_price =
2180 + $price["prompt_price"] * $price["unit"] * $prompt_units;
2181 + return $response_price + $prompt_price;
2182 + }
2183 + }
2184 + }
2185 + }
2186 + elseif (aiomatic_is_google_model($model))
2187 + {
2188 + foreach ($google_pricing as $price) {
2189 + if ($price["model"] == $model) {
2190 + if ($price["type"] == "image") {
2191 + if (!$option) {
2192 + aiomatic_log_to_file("Image models require an option.");
2193 + return 0;
2194 + } else {
2195 + foreach ($price["options"] as $imageType) {
2196 + if ($imageType["option"] == $option) {
2197 + $response_price =
2198 + $imageType["price"] * $response_units;
2199 + return $response_price;
2200 + }
2201 + }
2202 + }
2203 + } else {
2204 + $response_price =
2205 + $price["completion_price"] *
2206 + $price["unit"] *
2207 + $response_units;
2208 + $prompt_price =
2209 + $price["prompt_price"] * $price["unit"] * $prompt_units;
2210 + return $response_price + $prompt_price;
2211 + }
2212 + }
2213 + }
2214 + }
2215 + elseif (aiomatic_is_huggingface_model($model) || $model == 'huggingface')
2216 + {
2217 + $response_price = 0;
2218 + $prompt_price = 0;
2219 + return $response_price + $prompt_price;
2220 + }
2221 + elseif (aiomatic_is_ollama_model($model) || aiomatic_is_ollama_embeddings_model($model) || $model == 'ollama' || strstr($model, ':ollama') !== false)
2222 + {
2223 + $response_price = 0;
2224 + $prompt_price = 0;
2225 + return $response_price + $prompt_price;
2226 + }
2227 + elseif (aiomatic_is_openrouter_model($model))
2228 + {
2229 + $response_price = 0;
2230 + $prompt_price = 0;
2231 + return $response_price + $prompt_price;
2232 + }
2233 + elseif (aiomatic_is_custom_model($model, $aiomatic_Main_Settings))
2234 + {
2235 + $response_price = 0;
2236 + $prompt_price = 0;
2237 + return $response_price + $prompt_price;
2238 + }
2239 + elseif (aiomatic_is_groq_model($model) || $model == 'groq')
2240 + {
2241 + $response_price = 0;
2242 + $prompt_price = 0;
2243 + return $response_price + $prompt_price;
2244 + }
2245 + elseif (aiomatic_is_nvidia_model($model) || $model == 'nvidia')
2246 + {
2247 + $response_price = 0;
2248 + $prompt_price = 0;
2249 + return $response_price + $prompt_price;
2250 + }
2251 + elseif (aiomatic_is_xai_model($model) || $model == 'xai')
2252 + {
2253 + $response_price = 0;
2254 + $prompt_price = 0;
2255 + return $response_price + $prompt_price;
2256 + }
2257 + elseif (aiomatic_is_perplexity_model($model))
2258 + {
2259 + foreach ($perplexity_pricing as $price) {
2260 + if ($price["model"] == $model) {
2261 + if ($price["type"] == "image") {
2262 + if (!$option) {
2263 + aiomatic_log_to_file("Image models require an option.");
2264 + return 0;
2265 + } else {
2266 + foreach ($price["options"] as $imageType) {
2267 + if ($imageType["option"] == $option) {
2268 + $response_price =
2269 + $imageType["price"] * $response_units;
2270 + return $response_price;
2271 + }
2272 + }
2273 + }
2274 + } else {
2275 + $response_price =
2276 + $price["completion_price"] *
2277 + $price["unit"] *
2278 + $response_units;
2279 + $prompt_price =
2280 + $price["prompt_price"] * $price["unit"] * $prompt_units;
2281 + return $response_price + $prompt_price;
2282 + }
2283 + }
2284 + }
2285 + }
2286 + elseif (aiomatic_check_if_azure($aiomatic_Main_Settings))
2287 + {
2288 + foreach ($azure_pricing as $price) {
2289 + if ($price["model"] == $model) {
2290 + if ($price["type"] == "image") {
2291 + if (!$option) {
2292 + aiomatic_log_to_file("Image models require an option.");
2293 + return 0;
2294 + } else {
2295 + foreach ($price["options"] as $imageType) {
2296 + if ($imageType["option"] == $option) {
2297 + $response_price =
2298 + $imageType["price"] * $response_units;
2299 + return $response_price;
2300 + }
2301 + }
2302 + }
2303 + } else {
2304 + $response_price =
2305 + $price["completion_price"] *
2306 + $price["unit"] *
2307 + $response_units;
2308 + $prompt_price =
2309 + $price["prompt_price"] * $price["unit"] * $prompt_units;
2310 + return $response_price + $prompt_price;
2311 + }
2312 + }
2313 + }
2314 + }
2315 + elseif(aiomatic_is_ollama_embeddings_model($model))
2316 + {
2317 + return 0;
2318 + }
2319 + elseif($model == 'stable-diffusion')
2320 + {
2321 + return 0;
2322 + }
2323 + elseif($model == 'google-image')
2324 + {
2325 + return 0;
2326 + }
2327 + else
2328 + {
2329 + foreach ($openai_pricing as $price) {
2330 + if ($price["model"] == $model) {
2331 + if ($price["type"] == "image") {
2332 + if (!$option) {
2333 + aiomatic_log_to_file("Image models require an option.");
2334 + return 0;
2335 + } else {
2336 + foreach ($price["options"] as $imageType) {
2337 + if ($imageType["option"] == $option) {
2338 + $response_price =
2339 + $imageType["price"] * $response_units;
2340 + return $response_price;
2341 + }
2342 + }
2343 + }
2344 + } else {
2345 + $response_price =
2346 + $price["completion_price"] *
2347 + $price["unit"] *
2348 + $response_units;
2349 + $prompt_price =
2350 + $price["prompt_price"] * $price["unit"] * $prompt_units;
2351 + return $response_price + $prompt_price;
2352 + }
2353 + }
2354 + }
2355 + }
2356 + aiomatic_log_to_file("Invalid model (" . $model . ").");
2357 + return 0;
2358 + }
2359 + function getVisionPrice($model)
2360 + {
2361 + return 0;
2362 + }
2363 + function getVideoPrice($model, $resolution, $seconds)
2364 + {
2365 + if(!in_array($model, AIMOGEN_MODELS_VIDEO))
2366 + {
2367 + return 0;
2368 + }
2369 + $possible_sizes = AIMOGEN_MODELS_VIDEO_PARAMS[$model]['durations'];
2370 + if(!in_array($seconds, $possible_sizes))
2371 + {
2372 + return 0;
2373 + }
2374 + $resolutions = AIMOGEN_MODELS_VIDEO_PARAMS[$model]['resolutions'];
2375 + if(!array_key_exists($resolution, $resolutions))
2376 + {
2377 + return 0;
2378 + }
2379 + $price_per_second = $resolutions[$resolution]['price'];
2380 + return (float)$price_per_second * (float)$seconds;
2381 + }
2382 + function getPrice($query, $answer)
2383 + {
2384 + $prompt_units = 0;
2385 + $response_units = 0;
2386 + $model = $query->model;
2387 + $modelBase = null;
2388 + $option = "";
2389 + if ($query->mode == "text") {
2390 + if (aiomatic_is_ollama_model($model) || aiomatic_is_ollama_embeddings_model($model))
2391 + {
2392 + $modelBase = 'ollama';
2393 + }
2394 + elseif (aiomatic_is_chatgpt_41_model($model))
2395 + {
2396 + $modelBase = 'gpt41';
2397 + }
2398 + elseif (aiomatic_is_chatgpt_5_model($model))
2399 + {
2400 + $modelBase = 'gpt5';
2401 + }
2402 + elseif (preg_match("/^([a-zA-Z]{0,32}):/", $model, $matches))
2403 + {
2404 + if($matches[1] != 'ft')
2405 + {
2406 + $modelBase = "fn-" . $matches[1];
2407 + }
2408 + else
2409 + {
2410 + if(aiomatic_starts_with($model, 'ft:davinci-002'))
2411 + {
2412 + $modelBase = "fn-davinci";
2413 + }
2414 + elseif(aiomatic_starts_with($model, 'ft:babbage-002'))
2415 + {
2416 + $modelBase = "fn-babbage";
2417 + }
2418 + elseif(aiomatic_starts_with($model, 'ft:gpt-3.5-turbo'))
2419 + {
2420 + $modelBase = "fn-turbo";
2421 + }
2422 + elseif(aiomatic_starts_with($model, 'ft:gpt-4'))
2423 + {
2424 + $modelBase = "fn-gpt4";
2425 + }
2426 + else
2427 + {
2428 + aiomatic_log_to_file("Cannot find the base model for trained model $model.");
2429 + return null;
2430 + }
2431 + }
2432 + } elseif (
2433 + preg_match("/^(?:text|code)-(\w+)-\d+/", $model, $matches)
2434 + ) {
2435 + $modelBase = $matches[1];
2436 + } elseif (aiomatic_is_chatgpt_model($model)) {
2437 + if (stristr($model, "turbo") !== false) {
2438 + if (stristr($model, "turbo-16k") !== false)
2439 + {
2440 + $modelBase = "chatgpt-16k";
2441 + }
2442 + else
2443 + {
2444 + $modelBase = "chatgpt";
2445 + }
2446 + } else {
2447 + if (stristr($model, "32k") !== false) {
2448 + $modelBase = "gpt4-32k";
2449 + } else {
2450 + $modelBase = "gpt4";
2451 + }
2452 + }
2453 + }
2454 + elseif (aiomatic_is_claude_model($model))
2455 + {
2456 + $modelBase = $model;
2457 + }
2458 + elseif (aiomatic_is_chatgpt_turbo_model($model))
2459 + {
2460 + $modelBase = 'gpt4-turbo';
2461 + }
2462 + elseif (aiomatic_is_chatgpt_o_mini_model($model))
2463 + {
2464 + $modelBase = 'gpt4omini';
2465 + }
2466 + elseif (aiomatic_is_chatgpt_o_model($model))
2467 + {
2468 + $modelBase = 'gpt4o';
2469 + }
2470 + elseif(aiomatic_is_o1_pro_model($model))
2471 + {
2472 + $modelBase = 'o1-pro';
2473 + }
2474 + elseif(aiomatic_is_o3_mini_model($model))
2475 + {
2476 + $modelBase = 'o3-mini';
2477 + }
2478 + elseif(aiomatic_is_o4_mini_model($model))
2479 + {
2480 + $modelBase = 'o4-mini';
2481 + }
2482 + elseif(aiomatic_is_o3_model($model))
2483 + {
2484 + $modelBase = 'o3';
2485 + }
2486 + elseif(aiomatic_is_o1_model($model))
2487 + {
2488 + $modelBase = 'o1';
2489 + }
2490 + elseif (aiomatic_is_perplexity_model($model))
2491 + {
2492 + $modelBase = $model;
2493 + }
2494 + elseif (aiomatic_is_groq_model($model))
2495 + {
2496 + $modelBase = 'groq';
2497 + }
2498 + elseif (aiomatic_is_nvidia_model($model))
2499 + {
2500 + $modelBase = 'nvidia';
2501 + }
2502 + elseif (aiomatic_is_xai_model($model))
2503 + {
2504 + $modelBase = 'xai';
2505 + }
2506 + elseif (aiomatic_is_huggingface_model($model))
2507 + {
2508 + $modelBase = 'huggingface';
2509 + }
2510 + else
2511 + {
2512 + $modelBase = 'gpt-instruct';
2513 + }
2514 + if (empty($modelBase)) {
2515 + aiomatic_log_to_file("Cannot find the base model for $model.");
2516 + return null;
2517 + }
2518 + if (isset($query->prompt) && is_string($query->prompt)) {
2519 + $prompt_units = count(aiomatic_encode($query->prompt));
2520 + }
2521 + if (is_string($answer)) {
2522 + $response_units = count(aiomatic_encode($answer));
2523 + } else {
2524 + if (isset($answer->usage->total_tokens)) {
2525 + $response_units = $answer->usage->total_tokens;
2526 + } else {
2527 + if (isset($answer['content'][0]['text']['value'])) {
2528 + $response_units = count(
2529 + aiomatic_encode($answer['content'][0]['text']['value'])
2530 + );
2531 + }
2532 + else
2533 + {
2534 + aiomatic_log_to_file(
2535 + "Error, textual answer does not have total_tokens: " .
2536 + print_r($answer, true)
2537 + );
2538 + return false;
2539 + }
2540 + }
2541 + }
2542 + } elseif ($query->mode == "image") {
2543 + $modelBase = $query->model;
2544 + $response_units = 1;
2545 + if (isset($query->image_size)) {
2546 + $option = $query->image_size;
2547 + }
2548 + } elseif ($query->mode == "stable") {
2549 + $modelBase = "stable-diffusion";
2550 + $response_units = 1;
2551 + if (isset($query->image_size)) {
2552 + $option = $query->image_size;
2553 + }
2554 + } elseif ($query->mode == "replicate") {
2555 + $modelBase = "replicate";
2556 + $response_units = 1;
2557 + if (isset($query->image_size)) {
2558 + $option = $query->image_size;
2559 + }
2560 + } elseif ($query->mode == "ideogram") {
2561 + $modelBase = "ideogram";
2562 + $response_units = 1;
2563 + if (isset($query->image_size)) {
2564 + $option = $query->image_size;
2565 + }
2566 + } elseif (in_array($query->model, AIMOGEN_GOOGLE_IMAGE_MODELS)) {
2567 + $modelBase = "google-image";
2568 + $response_units = 1;
2569 + if (isset($query->image_size)) {
2570 + $option = $query->image_size;
2571 + }
2572 + } elseif ($query->mode == "edit") {
2573 + if (preg_match("/^([a-zA-Z]{0,32}):/", $model, $matches)) {
2574 + if($matches[1] != 'ft')
2575 + {
2576 + $modelBase = "fn-" . $matches[1];
2577 + }
2578 + else
2579 + {
2580 + if(aiomatic_starts_with($model, 'ft:davinci-002'))
2581 + {
2582 + $modelBase = "fn-davinci";
2583 + }
2584 + elseif(aiomatic_starts_with($model, 'ft:babbage-002'))
2585 + {
2586 + $modelBase = "fn-babbage";
2587 + }
2588 + elseif(aiomatic_starts_with($model, 'ft:gpt-3.5-turbo'))
2589 + {
2590 + $modelBase = "fn-turbo";
2591 + }
2592 + elseif(aiomatic_starts_with($model, 'ft:gpt-4'))
2593 + {
2594 + $modelBase = "fn-gpt4";
2595 + }
2596 + else
2597 + {
2598 + aiomatic_log_to_file("Cannot find the base model for trained model $model.");
2599 + return null;
2600 + }
2601 + }
2602 + } elseif (
2603 + preg_match("/^(?:text|code)-(\w+)-edit-\d+/", $model, $matches)
2604 + ) {
2605 + $modelBase = $matches[1];
2606 + }
2607 + if (empty($modelBase)) {
2608 + aiomatic_log_to_file("Cannot find the base model for $model.");
2609 + return null;
2610 + }
2611 + if (isset($query->prompt) && is_string($query->prompt)) {
2612 + $prompt_units = count(aiomatic_encode($query->prompt));
2613 + }
2614 + if (is_string($answer)) {
2615 + $response_units = count(aiomatic_encode($answer));
2616 + } else {
2617 + if (isset($answer->usage->total_tokens)) {
2618 + $response_units = $answer->usage->total_tokens;
2619 + } else {
2620 + if (isset($answer['content'][0]['text']['value'])) {
2621 + $response_units = count(
2622 + aiomatic_encode($answer['content'][0]['text']['value'])
2623 + );
2624 + }
2625 + else
2626 + {
2627 + aiomatic_log_to_file(
2628 + "Error, textual answer does not have total_tokens: " .
2629 + print_r($answer, true)
2630 + );
2631 + return false;
2632 + }
2633 + }
2634 + }
2635 + } elseif ($query->mode == "embeddings") {
2636 + $modelBase = $query->model;
2637 + if(aiomatic_is_ollama_embeddings_model($modelBase))
2638 + {
2639 + $response_units = 1;
2640 + }
2641 + else
2642 + {
2643 + $response_units = 1;
2644 + if (isset($query->prompt) && is_string($query->prompt)) {
2645 + $prompt_units = count(aiomatic_encode($query->prompt));
2646 + }
2647 + if (is_string($answer)) {
2648 + $response_units = count(aiomatic_encode($answer));
2649 + } else {
2650 + if (isset($answer["usage"]["total_tokens"])) {
2651 + $response_units = $answer["usage"]["total_tokens"];
2652 + } elseif (isset($answer->usage->total_tokens)) {
2653 + $response_units = $answer->usage->total_tokens;
2654 + } elseif (isset($answer[0]->usage->total_tokens)) {
2655 + $response_units = $answer[0]->usage->total_tokens;
2656 + } else {
2657 + aiomatic_log_to_file(
2658 + "Error, embedding answer does not have total_tokens: " .
2659 + print_r($answer, true)
2660 + );
2661 + return false;
2662 + }
2663 + }
2664 + }
2665 + } else {
2666 + aiomatic_log_to_file("Unknown query: " . print_r($query, true));
2667 + }
2668 + return $this->calculatePrice(
2669 + $modelBase,
2670 + $response_units,
2671 + $prompt_units,
2672 + $option
2673 + );
2674 + }
2675 + public function getDetails($query, $answer, $overrides = [])
2676 + {
2677 + $type = null;
2678 + $units = 0;
2679 + if ($query->mode == "text" || $query->mode == "edit") {
2680 + $type = "tokens";
2681 + if (is_string($answer)) {
2682 + $units =
2683 + count(aiomatic_encode($answer)) +
2684 + count(aiomatic_encode($query->prompt));
2685 + } else {
2686 + if (aiomatic_is_aiomaticapi_key($query->apiKey)) {
2687 + if (isset($answer->content)) {
2688 + $response_units = count(
2689 + aiomatic_encode($answer->content)
2690 + );
2691 + $prompt_units = count(aiomatic_encode($query->prompt));
2692 + $units = $prompt_units + $response_units;
2693 + } else {
2694 + aiomatic_log_to_file(
2695 + "Error, AiomaticAPI text answer does not have defined layout: " .
2696 + print_r($answer, true)
2697 + );
2698 + return false;
2699 + }
2700 + } else {
2701 + if (isset($answer->usage->total_tokens)) {
2702 + $units = $answer->usage->total_tokens;
2703 + } else {
2704 + if (isset($answer['content'][0]['text']['value']))
2705 + {
2706 + $response_units = count(
2707 + aiomatic_encode($answer['content'][0]['text']['value'])
2708 + );
2709 + $prompt_units = count(aiomatic_encode($query->prompt));
2710 + $units = $prompt_units + $response_units;
2711 + }
2712 + else
2713 + {
2714 + aiomatic_log_to_file(
2715 + "Error, text answer does not have total_tokens: " .
2716 + print_r($answer, true)
2717 + );
2718 + return false;
2719 + }
2720 + }
2721 + }
2722 + }
2723 + } elseif ($query->mode == "image") {
2724 + $type = "images";
2725 + $units = 1;
2726 + } elseif ($query->mode == "video") {
2727 + $type = "videos";
2728 + $units = 1;
2729 + } elseif ($query->mode == "stable") {
2730 + $type = "images";
2731 + $units = 1;
2732 + } elseif ($query->mode == "replicate") {
2733 + $type = "images";
2734 + $units = 1;
2735 + } elseif ($query->mode == "ideogram") {
2736 + $type = "images";
2737 + $units = 1;
2738 + } elseif ($query->mode == "google-image") {
2739 + $type = "images";
2740 + $units = 1;
2741 + } elseif ($query->mode == "text-to-speech") {
2742 + $type = "characters";
2743 + $units = aiomatic_strlen($answer);
2744 + } elseif ($query->mode == "speech-to-text") {
2745 + $type = "characters";
2746 + $units = aiomatic_strlen($answer);
2747 + } elseif ($query->mode == "embeddings") {
2748 + $type = "tokens";
2749 + if (isset($answer["usage"]["total_tokens"])) {
2750 + $units = $answer["usage"]["total_tokens"];
2751 + } else {
2752 + $units = count(aiomatic_encode($query->prompt));
2753 + }
2754 + }
2755 + $stats = [
2756 + "env" => $query->env,
2757 + "session" => $query->session,
2758 + "mode" => $query->mode,
2759 + "model" => $query->model,
2760 + "assistant_id" => $query->assistant_id,
2761 + "apiRef" => $query->apiKey,
2762 + "units" => $units,
2763 + "type" => $type,
2764 + ];
2765 + $stats = array_merge($stats, $overrides);
2766 + if (empty($stats["price"])) {
2767 + if ($query->mode == "speech-to-text")
2768 + {
2769 + $stats["price"] = 0;
2770 + }
2771 + else
2772 + {
2773 + if ($query->mode == "text-to-speech")
2774 + {
2775 + if($query->model == 'elevenlabs')
2776 + {
2777 + $stats["price"] = 0;
2778 + }
2779 + elseif($query->model == 'google')
2780 + {
2781 + $stats["price"] = 0.000004 * $units;
2782 + }
2783 + elseif($query->model == 'd-id')
2784 + {
2785 + $stats["price"] = 0;
2786 + }
2787 + elseif($query->model == 'openai-tts-1')
2788 + {
2789 + $stats["price"] = 0.000015 * $units;
2790 + }
2791 + elseif($query->model == 'openai-tts-1-hd')
2792 + {
2793 + $stats["price"] = 0.00003 * $units;
2794 + }
2795 + else
2796 + {
2797 + $stats["price"] = 0;
2798 + }
2799 + }
2800 + else
2801 + {
2802 + if (aiomatic_is_aiomaticapi_key($query->apiKey))
2803 + {
2804 + $stats["price"] = 0;
2805 + }
2806 + elseif($stats['type'] == 'videos')
2807 + {
2808 + $stats["price"] = 0;
2809 + }
2810 + else
2811 + {
2812 + $stats["price"] = $this->getPrice($query, $answer);
2813 + }
2814 + }
2815 + }
2816 + }
2817 + return $stats;
2818 + }
2819 + function addCasually($query, $answer, $overrides)
2820 + {
2821 + $type = null;
2822 + $units = 0;
2823 + if ($query->mode == "text" || $query->mode == "edit") {
2824 + $type = "tokens";
2825 + if (is_string($answer)) {
2826 + $units =
2827 + count(aiomatic_encode($answer)) +
2828 + count(aiomatic_encode($query->prompt));
2829 + } else {
2830 + if (aiomatic_is_aiomaticapi_key($query->apiKey)) {
2831 + if (isset($answer->content)) {
2832 + $response_units = count(
2833 + aiomatic_encode($answer->content)
2834 + );
2835 + $prompt_units = count(aiomatic_encode($query->prompt));
2836 + $units = $prompt_units + $response_units;
2837 + } else {
2838 + aiomatic_log_to_file(
2839 + "Error, AiomaticAPI text answer does not have defined layout: " .
2840 + print_r($answer, true)
2841 + );
2842 + return false;
2843 + }
2844 + } else {
2845 + if (isset($answer->usage->total_tokens)) {
2846 + $units = $answer->usage->total_tokens;
2847 + } else {
2848 + if (isset($answer['content'][0]['text']['value']))
2849 + {
2850 + $response_units = count(
2851 + aiomatic_encode($answer['content'][0]['text']['value'])
2852 + );
2853 + $prompt_units = count(aiomatic_encode($query->prompt));
2854 + $units = $prompt_units + $response_units;
2855 + }
2856 + else
2857 + {
2858 + aiomatic_log_to_file(
2859 + "Error, text answer does not have total_tokens: " .
2860 + print_r($answer, true)
2861 + );
2862 + return false;
2863 + }
2864 + }
2865 + }
2866 + }
2867 + } elseif ($query->mode == "image") {
2868 + $type = "images";
2869 + $units = 1;
2870 + } elseif ($query->mode == "video") {
2871 + $type = "videos";
2872 + $units = 1;
2873 + } elseif ($query->mode == "stable") {
2874 + $type = "images";
2875 + $units = 1;
2876 + } elseif ($query->mode == "replicate") {
2877 + $type = "images";
2878 + $units = 1;
2879 + } elseif ($query->mode == "ideogram") {
2880 + $type = "images";
2881 + $units = 1;
2882 + } elseif ($query->mode == "google-images") {
2883 + $type = "images";
2884 + $units = 1;
2885 + } elseif ($query->mode == "text-to-speech") {
2886 + $type = "characters";
2887 + $units = aiomatic_strlen($answer);
2888 + } elseif ($query->mode == "speech-to-text") {
2889 + $type = "characters";
2890 + $units = aiomatic_strlen($answer);
2891 + } elseif ($query->mode == "embeddings") {
2892 + $type = "tokens";
2893 + if (isset($answer["usage"]["total_tokens"])) {
2894 + $units = $answer["usage"]["total_tokens"];
2895 + } else {
2896 + $units = count(aiomatic_encode($query->prompt));
2897 + }
2898 + }
2899 + $stats = [
2900 + "env" => $query->env,
2901 + "session" => $query->session,
2902 + "mode" => $query->mode,
2903 + "model" => $query->model,
2904 + "assistant_id" => $query->assistant_id,
2905 + "apiRef" => $query->apiKey,
2906 + "units" => $units,
2907 + "type" => $type,
2908 + ];
2909 + $stats = array_merge($stats, $overrides);
2910 + if (empty($stats["price"])) {
2911 + if ($query->mode == "speech-to-text")
2912 + {
2913 + $stats["price"] = 0;
2914 + }
2915 + else
2916 + {
2917 + if ($query->mode == "text-to-speech")
2918 + {
2919 + if($query->model == 'elevenlabs')
2920 + {
2921 + $stats["price"] = 0;
2922 + }
2923 + elseif($query->model == 'google')
2924 + {
2925 + $stats["price"] = 0.000004 * $units;
2926 + }
2927 + elseif($query->model == 'd-id')
2928 + {
2929 + $stats["price"] = 0;
2930 + }
2931 + elseif($query->model == 'openai-tts-1')
2932 + {
2933 + $stats["price"] = 0.000015 * $units;
2934 + }
2935 + elseif($query->model == 'openai-tts-1-hd')
2936 + {
2937 + $stats["price"] = 0.00003 * $units;
2938 + }
2939 + else
2940 + {
2941 + $stats["price"] = 0;
2942 + }
2943 + }
2944 + else
2945 + {
2946 + if (aiomatic_is_aiomaticapi_key($query->apiKey))
2947 + {
2948 + $stats["price"] = 0;
2949 + }
2950 + elseif($stats['type'] == 'videos')
2951 + {
2952 + $stats["price"] = 0;
2953 + }
2954 + else
2955 + {
2956 + $stats["price"] = $this->getPrice($query, $answer);
2957 + }
2958 + }
2959 + }
2960 + }
2961 + return $this->add($stats);
2962 + }
2963 + function getUserId($data = null)
2964 + {
2965 + if (isset($data) && isset($data["userId"])) {
2966 + return (int) $data["userId"];
2967 + }
2968 + if (is_user_logged_in()) {
2969 + $current_user = wp_get_current_user();
2970 + if ($current_user->ID > 0) {
2971 + return $current_user->ID;
2972 + }
2973 + }
2974 + return null;
2975 + }
2976 +
2977 + function buildTagsForDb($tags)
2978 + {
2979 + if (is_array($tags)) {
2980 + $tags = implode("|", $tags);
2981 + }
2982 + if (!empty($tags)) {
2983 + $tags .= "|";
2984 + } else {
2985 + $tags = null;
2986 + }
2987 + return $tags;
2988 + }
2989 +
2990 + function getUserIpAddress($data = null)
2991 + {
2992 + if (isset($data) && isset($data["ip"])) {
2993 + $data["ip"] = (string) $data["ip"];
2994 + } else {
2995 + if (isset($_SERVER["REMOTE_ADDR"])) {
2996 + $data["ip"] = $_SERVER["REMOTE_ADDR"];
2997 + } elseif (isset($_SERVER["HTTP_CLIENT_IP"])) {
2998 + $data["ip"] = $_SERVER["HTTP_CLIENT_IP"];
2999 + } elseif (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
3000 + $data["ip"] = $_SERVER["HTTP_X_FORWARDED_FOR"];
3001 + }
3002 + }
3003 + return $data["ip"];
3004 + }
3005 +
3006 + function query(
3007 + $timeFrame = null,
3008 + $isAbsolute = null,
3009 + $credits = null,
3010 + $credit_type = null,
3011 + $userId = null,
3012 + $ipAddress = null,
3013 + $apiRef = null
3014 + ) {
3015 + if ($apiRef === null) {
3016 + $apiRef = $this->apiRef;
3017 + }
3018 + $target = "guests";
3019 + if ($userId === null && $ipAddress === null) {
3020 + $userId = $this->getUserId();
3021 + if ($userId) {
3022 + $target = "users";
3023 + } else {
3024 + $ipAddress = $this->getUserIpAddress();
3025 + if ($ipAddress === null) {
3026 + aiomatic_log_to_file(
3027 + "There should be an userId or an ipAddress."
3028 + );
3029 + return null;
3030 + }
3031 + }
3032 + }
3033 + $aiomatic_Limit_Settings = get_option("aiomatic_Limit_Settings", false);
3034 + if ($target == "guests") {
3035 + if ($credits === null) {
3036 + if (
3037 + isset($aiomatic_Limit_Settings["guest_credits"]) &&
3038 + $aiomatic_Limit_Settings["guest_credits"] != ""
3039 + ) {
3040 + $hasLimits = true;
3041 + } else {
3042 + $hasLimits = false;
3043 + }
3044 + } else {
3045 + $hasLimits = true;
3046 + }
3047 + if ($timeFrame === null) {
3048 + if (
3049 + isset($aiomatic_Limit_Settings["guest_time_frame"]) &&
3050 + $aiomatic_Limit_Settings["guest_time_frame"] != ""
3051 + ) {
3052 + $timeFrame = $aiomatic_Limit_Settings["guest_time_frame"];
3053 + } else {
3054 + $timeFrame = "day";
3055 + }
3056 + }
3057 + if ($isAbsolute === null) {
3058 + if (
3059 + isset($aiomatic_Limit_Settings["is_absolute_guest"]) &&
3060 + $aiomatic_Limit_Settings["is_absolute_guest"] == "on"
3061 + ) {
3062 + $isAbsolute = true;
3063 + } else {
3064 + $isAbsolute = false;
3065 + }
3066 + }
3067 + if ($credits === null) {
3068 + if (
3069 + isset($aiomatic_Limit_Settings["guest_credits"]) &&
3070 + $aiomatic_Limit_Settings["guest_credits"] != ""
3071 + ) {
3072 + $credits = $aiomatic_Limit_Settings["guest_credits"];
3073 + } else {
3074 + $credits = "";
3075 + }
3076 + }
3077 + if ($credit_type === null) {
3078 + if (
3079 + isset($aiomatic_Limit_Settings["guest_credit_type"]) &&
3080 + $aiomatic_Limit_Settings["guest_credit_type"] != ""
3081 + ) {
3082 + $credit_type =
3083 + $aiomatic_Limit_Settings["guest_credit_type"];
3084 + } else {
3085 + $credit_type = "queries";
3086 + }
3087 + }
3088 + } else {
3089 + if ($credits === null) {
3090 + if (
3091 + isset($aiomatic_Limit_Settings["user_credits"]) &&
3092 + $aiomatic_Limit_Settings["user_credits"] != ""
3093 + ) {
3094 + $hasLimits = true;
3095 + } else {
3096 + $hasLimits = false;
3097 + }
3098 + } else {
3099 + $hasLimits = true;
3100 + }
3101 + if ($timeFrame === null) {
3102 + if (
3103 + isset($aiomatic_Limit_Settings["user_time_frame"]) &&
3104 + $aiomatic_Limit_Settings["user_time_frame"] != ""
3105 + ) {
3106 + $timeFrame = $aiomatic_Limit_Settings["user_time_frame"];
3107 + } else {
3108 + $timeFrame = "day";
3109 + }
3110 + }
3111 + if ($isAbsolute === null) {
3112 + if (
3113 + isset($aiomatic_Limit_Settings["is_absolute_user"]) &&
3114 + $aiomatic_Limit_Settings["is_absolute_user"] == "on"
3115 + ) {
3116 + $isAbsolute = true;
3117 + } else {
3118 + $isAbsolute = false;
3119 + }
3120 + }
3121 + if ($credits === null) {
3122 + if (
3123 + isset($aiomatic_Limit_Settings["user_credits"]) &&
3124 + $aiomatic_Limit_Settings["user_credits"] != ""
3125 + ) {
3126 + $credits = $aiomatic_Limit_Settings["user_credits"];
3127 + } else {
3128 + $credits = "";
3129 + }
3130 + }
3131 + if ($credit_type === null) {
3132 + if (
3133 + isset($aiomatic_Limit_Settings["user_credit_type"]) &&
3134 + $aiomatic_Limit_Settings["user_credit_type"] != ""
3135 + ) {
3136 + $credit_type = $aiomatic_Limit_Settings["user_credit_type"];
3137 + } else {
3138 + $credit_type = "queries";
3139 + }
3140 + }
3141 + }
3142 + if (
3143 + $timeFrame !== "day" &&
3144 + $timeFrame !== "week" &&
3145 + $timeFrame !== "month" &&
3146 + $timeFrame !== "year"
3147 + ) {
3148 + aiomatic_log_to_file(
3149 + "TimeFrame should be day, week, month, or year."
3150 + );
3151 + return null;
3152 + }
3153 + if (
3154 + $credit_type == 'pdf' || $credit_type == 'pdfchar'
3155 + ) {
3156 + return null;
3157 + }
3158 +
3159 + $this->check_db();
3160 + $prefix = esc_sql($this->wpdb->prefix);
3161 + $sql = "SELECT COUNT(*) AS queries, SUM(units) AS units, SUM(price) AS price FROM {$prefix}aiomatic_logs WHERE ";
3162 +
3163 + if ($target === "users") {
3164 + $sql .= "userId = " . esc_sql($userId) . "";
3165 + } else {
3166 + $sql .= "ip = '" . esc_sql($ipAddress) . "'";
3167 + }
3168 +
3169 + if ($apiRef) {
3170 + $sql .= " AND apiRef = '" . esc_sql($apiRef) . "'";
3171 + }
3172 +
3173 + if ($timeFrame === "day") {
3174 + if ($isAbsolute) {
3175 + $sql .= " AND DAY(time) = DAY(CURRENT_DATE())";
3176 + } else {
3177 + $sql .= " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)";
3178 + }
3179 + } elseif ($timeFrame === "week") {
3180 + if ($isAbsolute) {
3181 + $sql .= " AND WEEK(time) = WEEK(CURRENT_DATE())";
3182 + } else {
3183 + $sql .=
3184 + " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 WEEK)";
3185 + }
3186 + } elseif ($timeFrame === "month") {
3187 + if ($isAbsolute) {
3188 + $sql .= " AND MONTH(time) = MONTH(CURRENT_DATE())";
3189 + } else {
3190 + $sql .=
3191 + " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH)";
3192 + }
3193 + } elseif ($timeFrame === "year") {
3194 + if ($isAbsolute) {
3195 + $sql .= " AND YEAR(time) = YEAR(CURRENT_DATE())";
3196 + } else {
3197 + $sql .=
3198 + " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 YEAR)";
3199 + }
3200 + }
3201 +
3202 + $results = $this->wpdb->get_results($sql);
3203 + if (count($results) === 0) {
3204 + return null;
3205 + }
3206 + $result = $results[0];
3207 + $stats = [];
3208 + $stats["userId"] = $userId;
3209 + $stats["ipAddress"] = $ipAddress;
3210 + $stats["queries"] = intVal($result->queries);
3211 + $stats["units"] = intVal($result->units);
3212 + $stats["price"] = round(floatVal($result->price), 2);
3213 +
3214 + $stats["queriesLimit"] = intVal(
3215 + $hasLimits && $credit_type === "queries" ? $credits : 0
3216 + );
3217 + $stats["unitsLimit"] = intVal(
3218 + $hasLimits && $credit_type === "units" ? $credits : 0
3219 + );
3220 + $stats["priceLimit"] = floatVal(
3221 + $hasLimits && $credit_type === "price" ? $credits : 0
3222 + );
3223 +
3224 + $credits = apply_filters("aiomatic_stats_credits", $credits, $userId);
3225 + $stats["overLimit"] = false;
3226 + if ($hasLimits) {
3227 + if ($credit_type === "queries") {
3228 + $stats["overLimit"] = $stats["queries"] >= $credits;
3229 + $stats["usagePercentage"] =
3230 + $stats["queriesLimit"] > 0
3231 + ? round(
3232 + ($stats["queries"] / $stats["queriesLimit"]) * 100,
3233 + 2
3234 + )
3235 + : 0;
3236 + } elseif ($credit_type === "units") {
3237 + $stats["overLimit"] = $stats["units"] >= $credits;
3238 + $stats["usagePercentage"] =
3239 + $stats["unitsLimit"] > 0
3240 + ? round(
3241 + ($stats["units"] / $stats["unitsLimit"]) * 100,
3242 + 2
3243 + )
3244 + : 0;
3245 + } elseif ($credit_type === "price") {
3246 + $stats["overLimit"] = $stats["price"] >= $credits;
3247 + $stats["usagePercentage"] =
3248 + $stats["priceLimit"] > 0
3249 + ? round(
3250 + ($stats["price"] / $stats["priceLimit"]) * 100,
3251 + 2
3252 + )
3253 + : 0;
3254 + }
3255 + }
3256 + return $stats;
3257 + }
3258 +
3259 + function query_tts(
3260 + $timeFrame = null,
3261 + $isAbsolute = null,
3262 + $credits = null,
3263 + $credit_type = null,
3264 + $userId = null,
3265 + $ipAddress = null,
3266 + $apiRef = null
3267 + ) {
3268 + if ($apiRef === null) {
3269 + $apiRef = $this->apiRef;
3270 + }
3271 + $target = "guests";
3272 + if ($userId === null && $ipAddress === null) {
3273 + $userId = $this->getUserId();
3274 + if ($userId) {
3275 + $target = "users";
3276 + } else {
3277 + $ipAddress = $this->getUserIpAddress();
3278 + if ($ipAddress === null) {
3279 + aiomatic_log_to_file(
3280 + "There should be an userId or an ipAddress."
3281 + );
3282 + return null;
3283 + }
3284 + }
3285 + }
3286 + $aiomatic_Limit_Settings = get_option("aiomatic_Limit_Settings", false);
3287 + if ($target == "guests") {
3288 + if ($credits === null) {
3289 + if (
3290 + isset($aiomatic_Limit_Settings["guest_credits_text"]) &&
3291 + $aiomatic_Limit_Settings["guest_credits_text"] != ""
3292 + ) {
3293 + $hasLimits = true;
3294 + } else {
3295 + $hasLimits = false;
3296 + }
3297 + } else {
3298 + $hasLimits = true;
3299 + }
3300 + if ($timeFrame === null) {
3301 + if (
3302 + isset($aiomatic_Limit_Settings["guest_time_frame_text"]) &&
3303 + $aiomatic_Limit_Settings["guest_time_frame_text"] != ""
3304 + ) {
3305 + $timeFrame = $aiomatic_Limit_Settings["guest_time_frame_text"];
3306 + } else {
3307 + $timeFrame = "day";
3308 + }
3309 + }
3310 + if ($isAbsolute === null) {
3311 + if (
3312 + isset($aiomatic_Limit_Settings["is_absolute_guest_text"]) &&
3313 + $aiomatic_Limit_Settings["is_absolute_guest_text"] == "on"
3314 + ) {
3315 + $isAbsolute = true;
3316 + } else {
3317 + $isAbsolute = false;
3318 + }
3319 + }
3320 + if ($credits === null) {
3321 + if (
3322 + isset($aiomatic_Limit_Settings["guest_credits_text"]) &&
3323 + $aiomatic_Limit_Settings["guest_credits_text"] != ""
3324 + ) {
3325 + $credits = $aiomatic_Limit_Settings["guest_credits_text"];
3326 + } else {
3327 + $credits = "";
3328 + }
3329 + }
3330 + if ($credit_type === null) {
3331 + if (
3332 + isset($aiomatic_Limit_Settings["guest_credit_type_text"]) &&
3333 + $aiomatic_Limit_Settings["guest_credit_type_text"] != ""
3334 + ) {
3335 + $credit_type =
3336 + $aiomatic_Limit_Settings["guest_credit_type_text"];
3337 + } else {
3338 + $credit_type = "characters";
3339 + }
3340 + }
3341 + } else {
3342 + if ($credits === null) {
3343 + if (
3344 + isset($aiomatic_Limit_Settings["user_credits_text"]) &&
3345 + $aiomatic_Limit_Settings["user_credits_text"] != ""
3346 + ) {
3347 + $hasLimits = true;
3348 + } else {
3349 + $hasLimits = false;
3350 + }
3351 + } else {
3352 + $hasLimits = true;
3353 + }
3354 + if ($timeFrame === null) {
3355 + if (
3356 + isset($aiomatic_Limit_Settings["user_time_frame_text"]) &&
3357 + $aiomatic_Limit_Settings["user_time_frame_text"] != ""
3358 + ) {
3359 + $timeFrame = $aiomatic_Limit_Settings["user_time_frame_text"];
3360 + } else {
3361 + $timeFrame = "day";
3362 + }
3363 + }
3364 + if ($isAbsolute === null) {
3365 + if (
3366 + isset($aiomatic_Limit_Settings["is_absolute_user_text"]) &&
3367 + $aiomatic_Limit_Settings["is_absolute_user_text"] == "on"
3368 + ) {
3369 + $isAbsolute = true;
3370 + } else {
3371 + $isAbsolute = false;
3372 + }
3373 + }
3374 + if ($credits === null) {
3375 + if (
3376 + isset($aiomatic_Limit_Settings["user_credits_text"]) &&
3377 + $aiomatic_Limit_Settings["user_credits_text"] != ""
3378 + ) {
3379 + $credits = $aiomatic_Limit_Settings["user_credits_text"];
3380 + } else {
3381 + $credits = "";
3382 + }
3383 + }
3384 + if ($credit_type === null) {
3385 + if (
3386 + isset($aiomatic_Limit_Settings["user_credit_type_text"]) &&
3387 + $aiomatic_Limit_Settings["user_credit_type_text"] != ""
3388 + ) {
3389 + $credit_type = $aiomatic_Limit_Settings["user_credit_type_text"];
3390 + } else {
3391 + $credit_type = "characters";
3392 + }
3393 + }
3394 + }
3395 + if (
3396 + $timeFrame !== "day" &&
3397 + $timeFrame !== "week" &&
3398 + $timeFrame !== "month" &&
3399 + $timeFrame !== "year"
3400 + ) {
3401 + aiomatic_log_to_file(
3402 + "TimeFrame should be day, week, month, or year."
3403 + );
3404 + return null;
3405 + }
3406 +
3407 + $this->check_db();
3408 + $prefix = esc_sql($this->wpdb->prefix);
3409 + $sql = "SELECT COUNT(*) AS queries, SUM(units) AS units, SUM(price) AS price FROM {$prefix}aiomatic_logs WHERE ";
3410 +
3411 + if ($target === "users") {
3412 + $sql .= "userId = " . esc_sql($userId) . "";
3413 + } else {
3414 + $sql .= "ip = '" . esc_sql($ipAddress) . "'";
3415 + }
3416 +
3417 + if ($apiRef) {
3418 + $sql .= " AND apiRef = '" . esc_sql($apiRef) . "'";
3419 + }
3420 + $sql .= " AND mode = 'text-to-speech'";
3421 + if ($timeFrame === "day") {
3422 + if ($isAbsolute) {
3423 + $sql .= " AND DAY(time) = DAY(CURRENT_DATE())";
3424 + } else {
3425 + $sql .= " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)";
3426 + }
3427 + } elseif ($timeFrame === "week") {
3428 + if ($isAbsolute) {
3429 + $sql .= " AND WEEK(time) = WEEK(CURRENT_DATE())";
3430 + } else {
3431 + $sql .=
3432 + " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 WEEK)";
3433 + }
3434 + } elseif ($timeFrame === "month") {
3435 + if ($isAbsolute) {
3436 + $sql .= " AND MONTH(time) = MONTH(CURRENT_DATE())";
3437 + } else {
3438 + $sql .=
3439 + " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH)";
3440 + }
3441 + } elseif ($timeFrame === "year") {
3442 + if ($isAbsolute) {
3443 + $sql .= " AND YEAR(time) = YEAR(CURRENT_DATE())";
3444 + } else {
3445 + $sql .=
3446 + " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 YEAR)";
3447 + }
3448 + }
3449 +
3450 + $results = $this->wpdb->get_results($sql);
3451 + if (count($results) === 0) {
3452 + return null;
3453 + }
3454 + $result = $results[0];
3455 + $stats = [];
3456 + $stats["userId"] = $userId;
3457 + $stats["ipAddress"] = $ipAddress;
3458 + $stats["queries"] = intVal($result->queries);
3459 + $stats["units"] = intVal($result->units);
3460 + $stats["price"] = round(floatVal($result->price), 2);
3461 +
3462 + $stats["queriesLimit"] = intVal(
3463 + $hasLimits && $credit_type === "queries" ? $credits : 0
3464 + );
3465 + $stats["unitsLimit"] = intVal(
3466 + $hasLimits && $credit_type === "characters" ? $credits : 0
3467 + );
3468 + $stats["priceLimit"] = floatVal(
3469 + $hasLimits && $credit_type === "price" ? $credits : 0
3470 + );
3471 +
3472 + $credits = apply_filters("aiomatic_stats_credits", $credits, $userId);
3473 + $stats["overLimit"] = false;
3474 + if ($hasLimits) {
3475 + if ($credit_type === "queries") {
3476 + $stats["overLimit"] = $stats["queries"] >= $credits;
3477 + $stats["usagePercentage"] =
3478 + $stats["queriesLimit"] > 0
3479 + ? round(
3480 + ($stats["queries"] / $stats["queriesLimit"]) * 100,
3481 + 2
3482 + )
3483 + : 0;
3484 + } elseif ($credit_type === "characters") {
3485 + $stats["overLimit"] = $stats["units"] >= $credits;
3486 + $stats["usagePercentage"] =
3487 + $stats["unitsLimit"] > 0
3488 + ? round(
3489 + ($stats["units"] / $stats["unitsLimit"]) * 100,
3490 + 2
3491 + )
3492 + : 0;
3493 + } elseif ($credit_type === "price") {
3494 + $stats["overLimit"] = $stats["price"] >= $credits;
3495 + $stats["usagePercentage"] =
3496 + $stats["priceLimit"] > 0
3497 + ? round(
3498 + ($stats["price"] / $stats["priceLimit"]) * 100,
3499 + 2
3500 + )
3501 + : 0;
3502 + }
3503 + }
3504 + return $stats;
3505 + }
3506 +
3507 + public function deleteUsageEntries(
3508 + $timeFrame = null,
3509 + $isAbsolute = null,
3510 + $userId = null,
3511 + $ipAddress = null,
3512 + $apiRef = null
3513 + ) {
3514 + if ($apiRef === null) {
3515 + $apiRef = $this->apiRef;
3516 + }
3517 + $target = "guests";
3518 + if ($userId) {
3519 + $target = "users";
3520 + }
3521 + if ($userId === null && $ipAddress === null) {
3522 + $userId = $this->getUserId();
3523 + if ($userId) {
3524 + $target = "users";
3525 + } else {
3526 + $ipAddress = $this->getUserIpAddress();
3527 + if ($ipAddress === null) {
3528 + aiomatic_log_to_file(
3529 + "There should be an userId or an ipAddress."
3530 + );
3531 + return null;
3532 + }
3533 + }
3534 + }
3535 + if (
3536 + $timeFrame !== "day" &&
3537 + $timeFrame !== "week" &&
3538 + $timeFrame !== "month" &&
3539 + $timeFrame !== "year" &&
3540 + $timeFrame !== "all"
3541 + ) {
3542 + aiomatic_log_to_file(
3543 + "TimeFrame should be day, week, month, year or all."
3544 + );
3545 + return null;
3546 + }
3547 + $this->check_db();
3548 + $prefix = esc_sql($this->wpdb->prefix);
3549 + $sql = "DELETE FROM {$prefix}aiomatic_logs WHERE ";
3550 + if ($target === "users") {
3551 + $sql .= "userId = " . esc_sql($userId) . "";
3552 + } else {
3553 + $sql .= "ip = '" . esc_sql($ipAddress) . "'";
3554 + }
3555 + if ($apiRef) {
3556 + $sql .= " AND apiRef = '" . esc_sql($apiRef) . "'";
3557 + }
3558 + if ($timeFrame === "day") {
3559 + if ($isAbsolute) {
3560 + $sql .= " AND DAY(time) = DAY(CURRENT_DATE())";
3561 + } else {
3562 + $sql .= " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)";
3563 + }
3564 + } elseif ($timeFrame === "week") {
3565 + if ($isAbsolute) {
3566 + $sql .= " AND WEEK(time) = WEEK(CURRENT_DATE())";
3567 + } else {
3568 + $sql .=
3569 + " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 WEEK)";
3570 + }
3571 + } elseif ($timeFrame === "month") {
3572 + if ($isAbsolute) {
3573 + $sql .= " AND MONTH(time) = MONTH(CURRENT_DATE())";
3574 + } else {
3575 + $sql .=
3576 + " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH)";
3577 + }
3578 + } elseif ($timeFrame === "year") {
3579 + if ($isAbsolute) {
3580 + $sql .= " AND YEAR(time) = YEAR(CURRENT_DATE())";
3581 + } else {
3582 + $sql .=
3583 + " AND time >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 YEAR)";
3584 + }
3585 + }
3586 + $result = $this->wpdb->query($sql);
3587 + if ($result === false) {
3588 + aiomatic_log_to_file("Error deleting usage entries.");
3589 + return false;
3590 + }
3591 + return true;
3592 + }
3593 +
3594 + function shortcode_current($atts)
3595 + {
3596 + $aiomatic_Limit_Settings = get_option('aiomatic_Limit_Settings', false);
3597 + if (
3598 + isset($aiomatic_Limit_Settings["enable_limits"]) &&
3599 + trim($aiomatic_Limit_Settings["enable_limits"]) == "on"
3600 + )
3601 + {
3602 + $display = isset($atts["display"]) ? $atts["display"] : "usage";
3603 + $stats = $this->query();
3604 + if ($display === "usage") {
3605 + $name = md5(get_bloginfo());
3606 + wp_register_style(
3607 + $name . "-stats-style",
3608 + plugins_url("../styles/stats-chatgpt.css", __FILE__),
3609 + false,
3610 + AIMOGEN_MAJOR_VERSION
3611 + );
3612 + wp_enqueue_style($name . "-stats-style");
3613 + $percent = isset($stats["usagePercentage"])
3614 + ? $stats["usagePercentage"]
3615 + : 0;
3616 + $cssPercent = $percent > 100 ? 100 : $percent;
3617 + $output =
3618 + '<div class="aiomatic-statistics aiomatic-statistics-usage">';
3619 + $output .= '<div class="aiomatic-statistics-bar-container">';
3620 + $output .=
3621 + '<div class="aiomatic-statistics-bar" style="width: ' .
3622 + $cssPercent .
3623 + '%;"></div>';
3624 + $output .= "</div>";
3625 + $output .=
3626 + '<div class="aiomatic-statistics-bar-text">' .
3627 + $percent .
3628 + "%</div>";
3629 + $output .= "</div>";
3630 + return $output;
3631 + } elseif ($display === "details") {
3632 + if ($stats === null) {
3633 + return "No stats available.";
3634 + }
3635 + $output =
3636 + '<div class="aiomatic-statistics aiomatic-statistics-debug">';
3637 + if (!empty($stats["ipAddress"])) {
3638 + $output .= "IP Address: " . $stats["ipAddress"] . "<br>";
3639 + }
3640 + $output .=
3641 + "Queries: " . $stats["queries"] .
3642 + (!empty($stats["queriesLimit"])
3643 + ? " / " . $stats["queriesLimit"]
3644 + : "") .
3645 + "<br>";
3646 + $output .=
3647 + "Tokens (Units): " . $stats["units"] .
3648 + (!empty($stats["unitsLimit"])
3649 + ? " / " . $stats["unitsLimit"]
3650 + : "") .
3651 + "<br>";
3652 + $output .=
3653 + "Dollars (Price): " . $stats["price"] .
3654 + (!empty($stats["priceLimit"])
3655 + ? " / " . $stats["priceLimit"]
3656 + : "") .
3657 + "<br>";
3658 + if (isset($stats["usagePercentage"])) {
3659 + $output .= "Usage: " . $stats["usagePercentage"] . "%" . "<br>";
3660 + $output .=
3661 + "Status: " . ($stats["overLimit"] ? "OVER LIMIT" : "OK");
3662 + }
3663 + $output .= "</div>";
3664 + return $output;
3665 + }
3666 + }
3667 + }
3668 +
3669 + function validate_data($data)
3670 + {
3671 + // env: Could be "textwriter", "chatbot", "imagesbot", or anything else
3672 + $data["time"] = date("Y-m-d H:i:s");
3673 + $data["userId"] = $this->getUserId($data);
3674 + $data["session"] = isset($data["session"])
3675 + ? (string) $data["session"]
3676 + : null;
3677 + $data["ip"] = $this->getUserIpAddress($data);
3678 + $data["model"] = isset($data["model"]) ? (string) $data["model"] : null;
3679 + $data["assistant_id"] = isset($data["assistant_id"]) ? (string) $data["assistant_id"] : null;
3680 + $data["mode"] = isset($data["mode"]) ? (string) $data["mode"] : null;
3681 + $data["units"] = isset($data["units"]) ? intval($data["units"]) : 0;
3682 + $data["type"] = isset($data["type"]) ? (string) $data["type"] : null;
3683 + $data["price"] = isset($data["price"]) ? floatval($data["price"]) : 0;
3684 + $data["env"] = isset($data["env"]) ? (string) $data["env"] : null;
3685 + $data["apiRef"] = isset($data["apiRef"])
3686 + ? (string) $data["apiRef"]
3687 + : null;
3688 + $data["tags"] = $this->buildTagsForDb(
3689 + isset($data["tags"]) ? $data["tags"] : null
3690 + );
3691 + return $data;
3692 + }
3693 +
3694 + function calculateRealtimeCost($usage, $model = 'gpt-4o')
3695 + {
3696 + if(stristr($model, 'gpt-4o-mini') !== false)
3697 + {
3698 + $model = 'gpt-4o-mini';
3699 + }
3700 + elseif(stristr($model, 'gpt-4o') !== false)
3701 + {
3702 + $model = 'gpt-4o';
3703 + }
3704 + $realtime_pricing = [
3705 + 'gpt-4o' => [
3706 + 'text_input' => 5.00,
3707 + 'text_cached_input' => 2.50,
3708 + 'text_output' => 20.00,
3709 +
3710 + 'audio_input' => 40.00,
3711 + 'audio_cached_input' => 2.50,
3712 + 'audio_output' => 80.00,
3713 + ],
3714 + 'gpt-4o-mini' => [
3715 + 'text_input' => 0.60,
3716 + 'text_cached_input' => 0.30,
3717 + 'text_output' => 2.40,
3718 +
3719 + 'audio_input' => 10.00,
3720 + 'audio_cached_input' => 0.30,
3721 + 'audio_output' => 20.00,
3722 + ],
3723 + ];
3724 + if (!isset($pricing[$model])) {
3725 + $model = 'gpt-4o';
3726 + }
3727 + $textInput = $usage['input_token_details']['text_tokens'] ?? 0;
3728 + $audioInput = $usage['input_token_details']['audio_tokens'] ?? 0;
3729 + $cachedTextInput = $usage['input_token_details']['cached_tokens_details']['text_tokens'] ?? 0;
3730 + $cachedAudioInput = $usage['input_token_details']['cached_tokens_details']['audio_tokens'] ?? 0;
3731 + $textOutput = $usage['output_token_details']['text_tokens'] ?? 0;
3732 + $audioOutput = $usage['output_token_details']['audio_tokens'] ?? 0;
3733 +
3734 + $nonCachedTextInputTokens = max($textInput - $cachedTextInput, 0);
3735 + $nonCachedAudioInputTokens = max($audioInput - $cachedAudioInput, 0);
3736 +
3737 + $textInputCost = ($nonCachedTextInputTokens / 1_000_000) * $realtime_pricing[$model]['text_input'];
3738 + $textCachedInputCost = ($cachedTextInput / 1_000_000) * $realtime_pricing[$model]['text_cached_input'];
3739 +
3740 + $audioInputCost = ($nonCachedAudioInputTokens / 1_000_000) * $realtime_pricing[$model]['audio_input'];
3741 + $audioCachedInputCost = ($cachedAudioInput / 1_000_000) * $realtime_pricing[$model]['audio_cached_input'];
3742 +
3743 + $textOutputCost = ($textOutput / 1_000_000) * $realtime_pricing[$model]['text_output'];
3744 + $audioOutputCost = ($audioOutput / 1_000_000) * $realtime_pricing[$model]['audio_output'];
3745 +
3746 + $totalCost = $textInputCost
3747 + + $textCachedInputCost
3748 + + $audioInputCost
3749 + + $audioCachedInputCost
3750 + + $textOutputCost
3751 + + $audioOutputCost;
3752 +
3753 + return $totalCost;
3754 + }
3755 +
3756 + function add($data)
3757 + {
3758 + $this->check_db();
3759 + $data = $this->validate_data($data);
3760 + $dbrez = $this->wpdb->insert($this->table_logs, $data);
3761 + if ($dbrez === false) {
3762 + aiomatic_log_to_file(
3763 + "Failed to save statistics data: " . $this->wpdb->last_error
3764 + );
3765 + }
3766 + }
3767 +
3768 + function check_db()
3769 + {
3770 + if ($this->db_check) {
3771 + return true;
3772 + }
3773 + $this->db_check = !(
3774 + strtolower(
3775 + $this->wpdb->get_var("SHOW TABLES LIKE '$this->table_logs'")
3776 + ) != strtolower($this->table_logs)
3777 + );
3778 + if (!$this->db_check) {
3779 + $this->create_db();
3780 + $this->db_check = !(
3781 + strtolower(
3782 + $this->wpdb->get_var("SHOW TABLES LIKE '$this->table_logs'")
3783 + ) != strtolower($this->table_logs)
3784 + );
3785 + }
3786 + if (!$this->wpdb->get_var("SHOW COLUMNS FROM `{$this->table_logs}` LIKE 'assistant_id'")) {
3787 + $this->wpdb->query("ALTER TABLE `{$this->table_logs}` ADD `assistant_id` VARCHAR(256) NULL");
3788 + }
3789 + $this->db_check =
3790 + $this->db_check &&
3791 + $this->wpdb->get_var(
3792 + "SHOW COLUMNS FROM $this->table_logs LIKE 'apiRef'"
3793 + );
3794 + if (!$this->db_check) {
3795 + $this->wpdb->query(
3796 + "ALTER TABLE $this->table_logs ADD COLUMN apiRef VARCHAR(256) NULL"
3797 + );
3798 + $this->wpdb->query(
3799 + "UPDATE $this->table_logs SET apiRef = '$this->apiRef'"
3800 + );
3801 + $this->db_check = true;
3802 + }
3803 + $apiRefLength = $this->wpdb->get_var(
3804 + "SELECT CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS
3805 + WHERE TABLE_NAME = '{$this->table_logs}'
3806 + AND COLUMN_NAME = 'apiRef'"
3807 + );
3808 + if ($apiRefLength == 128) {
3809 + $this->wpdb->query("ALTER TABLE `{$this->table_logs}` MODIFY COLUMN `apiRef` VARCHAR(256) NULL");
3810 + }
3811 + return $this->db_check;
3812 + }
3813 +
3814 + function create_db()
3815 + {
3816 + $charset_collate = $this->wpdb->get_charset_collate();
3817 + $current_time = date('Y-m-d H:i:s', time());
3818 + $sqlLogs = "CREATE TABLE $this->table_logs (
3819 + id BIGINT(20) NOT NULL AUTO_INCREMENT,
3820 + userId BIGINT(20) NULL,
3821 + ip VARCHAR(64) NULL,
3822 + session VARCHAR(64) NULL,
3823 + model VARCHAR(256) NULL,
3824 + assistant_id VARCHAR(256) NULL,
3825 + mode VARCHAR(128) NULL,
3826 + units INT(11) NOT NULL DEFAULT 0,
3827 + type VARCHAR(64) NULL,
3828 + price FLOAT NOT NULL DEFAULT 0,
3829 + env VARCHAR(64) NULL,
3830 + tags VARCHAR(128) NULL,
3831 + apiRef VARCHAR(256) NULL,
3832 + time DATETIME NOT NULL DEFAULT '" . $current_time . "',
3833 + PRIMARY KEY (id)
3834 + ) $charset_collate;";
3835 +
3836 + $sqlLogMeta = "CREATE TABLE $this->table_logmeta (
3837 + meta_id BIGINT(20) NOT NULL AUTO_INCREMENT,
3838 + log_id BIGINT(20) NOT NULL,
3839 + meta_key varchar(255) NULL,
3840 + meta_value longtext NULL,
3841 + PRIMARY KEY (meta_id)
3842 + ) $charset_collate;";
3843 +
3844 + require_once ABSPATH . "wp-admin/includes/upgrade.php";
3845 + dbDelta($sqlLogs);
3846 + dbDelta($sqlLogMeta);
3847 + }
3848 +
3849 + function remove_db()
3850 + {
3851 + $sql = "DROP TABLE IF EXISTS $this->table_logs, $this->table_logmeta;";
3852 + $this->wpdb->query($sql);
3853 + }
3854 + function clear_db()
3855 + {
3856 + $sql = "TRUNCATE TABLE $this->table_logs;";
3857 + $this->wpdb->query($sql);
3858 + $sql = "TRUNCATE TABLE $this->table_logmeta;";
3859 + $this->wpdb->query($sql);
3860 + }
3861 + public function logs_query(
3862 + $logs = [],
3863 + $offset = 0,
3864 + $limit = null,
3865 + $filters = null,
3866 + $sort = null
3867 + ) {
3868 + $offset = !empty($offset) ? intval($offset) : 0;
3869 + $limit = !empty($limit) ? intval($limit) : 100;
3870 + $filters = !empty($filters) ? $filters : [];
3871 + $sort = !empty($sort) ? $sort : ["accessor" => "time", "by" => "desc"];
3872 + $query = "SELECT * FROM $this->table_logs";
3873 + $where = [];
3874 + if (isset($filters["apiRef"])) {
3875 + $where[] = "apiRef = '" . esc_sql($filters["apiRef"]) . "'";
3876 + }
3877 + if (isset($filters["userId"])) {
3878 + $where[] = "userId = '" . intval($filters["userId"]) . "'";
3879 + }
3880 + if (isset($filters["ip"])) {
3881 + $where[] = "ip = '" . esc_sql($filters["ip"]) . "'";
3882 + }
3883 + if (isset($filters["session"])) {
3884 + $where[] = "session = '" . esc_sql($filters["session"]) . "'";
3885 + }
3886 + if (isset($filters["model"])) {
3887 + $where[] = "model = '" . esc_sql($filters["model"]) . "'";
3888 + }
3889 + if (isset($filters["assistant_id"])) {
3890 + $where[] = "assistant_id = '" . esc_sql($filters["assistant_id"]) . "'";
3891 + }
3892 + if (isset($filters["mode"])) {
3893 + $where[] = "mode = '" . esc_sql($filters["mode"]) . "'";
3894 + }
3895 + if (isset($filters["type"])) {
3896 + $where[] = "type = '" . esc_sql($filters["type"]) . "'";
3897 + }
3898 + if (isset($filters["env"])) {
3899 + $where[] = "env = '" . esc_sql($filters["env"]) . "'";
3900 + }
3901 + if (isset($filters["tags"])) {
3902 + $where[] = "tags LIKE '%" . esc_sql($filters["tags"]) . "%'";
3903 + }
3904 + if (isset($filters["from"])) {
3905 + $where[] = "time >= '" . esc_sql($filters["from"]) . "'";
3906 + }
3907 + if (isset($filters["to"])) {
3908 + $where[] = "time <= '" . esc_sql($filters["to"]) . "'";
3909 + }
3910 + if (count($where) > 0) {
3911 + $query .= " WHERE " . implode(" AND ", $where);
3912 + }
3913 +
3914 + $logs["total"] = $this->wpdb->get_var(
3915 + "SELECT COUNT(*) FROM ($query) AS t"
3916 + );
3917 +
3918 + if(isset($sort["accessor"]) && isset($sort["by"]))
3919 + {
3920 + $query .=
3921 + " ORDER BY " .
3922 + esc_sql($sort["accessor"]) .
3923 + " " .
3924 + esc_sql($sort["by"]);
3925 + }
3926 + else
3927 + {
3928 + $query .=
3929 + " ORDER BY time desc";
3930 + }
3931 + if ($limit > 0) {
3932 + $query .= " LIMIT $offset, $limit";
3933 + }
3934 + $logs["rows"] = $this->wpdb->get_results($query, ARRAY_A);
3935 + return $logs;
3936 + }
3937 + }
3938 + ?>
3939 +