PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.8
4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 4.2.1 All 138 releases
learnpress / inc / Services / OpenAiService.php

OpenAiService.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.3.8, at inc/Services/OpenAiService.php

283 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace LearnPress\Services;
4
5 use Exception;
6 use LearnPress\Helpers\Singleton;
7 use LP_Helper;
8 use LP_Settings;
9
10 /**
11 * Class OpenAiService
12 *
13 * Handles interactions with the OpenAI API for LearnPress.
14 *
15 * @package LearnPress\Services
16 * @since 4.3.0
17 * @version 1.0.0
18 */
19 class OpenAiService {
20 use Singleton;
21
22 public string $baseUrl = 'https://api.openai.com/v1/';
23 public string $urlChartCompletion;
24 public string $urlResponses;
25 public string $urlCompletionLegacy;
26 public string $urlImage;
27
28 public string $secret_key;
29 public string $text_model_type;
30 public string $image_model_type;
31 public float $frequency_penalty;
32 public float $presence_penalty;
33 public float $creativity_level;
34 public int $max_token;
35
36 public function init() {
37 $this->urlChartCompletion = $this->baseUrl . 'chat/completions';
38 $this->urlCompletionLegacy = $this->baseUrl . 'completions';
39 $this->urlResponses = $this->baseUrl . 'responses';
40 $this->urlImage = $this->baseUrl . 'images/generations';
41 $this->get_settings();
42 }
43
44 /**
45 * Check OpenAI integration is enabled
46 */
47 public function is_enable(): bool {
48 return LP_Settings::get_option( 'enable_open_ai', 'no' ) === 'yes';
49 }
50
51 /**
52 * Get secret key
53 *
54 * @return string
55 * @since 4.3.6
56 * @version 1.0.0
57 */
58 public function get_secret_key(): string {
59 return (string) LP_Settings::get_option( 'open_ai_secret_key', '' );
60 }
61
62 public function get_settings() {
63 $this->secret_key = LP_Settings::get_option( 'open_ai_secret_key', '' );
64 $this->text_model_type = LP_Settings::get_option( 'open_ai_text_model_type', 'gpt-4.1' );
65 $this->image_model_type = LP_Settings::get_option( 'open_ai_image_model_type', 'dall-e-3' );
66 $this->frequency_penalty = LP_Settings::get_option( 'open_ai_frequency_penalty_level', 0.0 );
67 $this->presence_penalty = LP_Settings::get_option( 'open_ai_presence_penalty_level', 0.0 );
68 $this->creativity_level = LP_Settings::get_option( 'open_ai_creativity_level', 1.0 );
69 $this->max_token = LP_Settings::get_option( 'open_ai_max_token', 0 );
70 }
71
72 /**
73 * Call OpenAI API
74 *
75 * @throws Exception
76 */
77 public function send_request( array $args ): array {
78 // Handle args before send request
79 $url = '';
80
81 if ( in_array(
82 $this->text_model_type,
83 [ 'chatgpt-4o-latest', 'gpt-4o', 'gpt-4o-mini', 'gpt-3.5-turbo' ]
84 ) ) {
85 $url = $this->urlChartCompletion;
86 $args = $this->handle_params_for_send_chat_completion( $args );
87 } elseif ( $this->text_model_type == 'gpt-3.5-turbo-instruct' ) {
88 $url = $this->urlCompletionLegacy;
89 $args = $this->handle_params_for_send_completion_legacy( $args );
90 } else {
91 $url = $this->urlResponses;
92 $args = $this->handle_params_for_send_responses( $args );
93 }
94
95 $response = wp_remote_post(
96 $url,
97 [
98 'headers' => [
99 'Authorization' => 'Bearer ' . $this->secret_key,
100 'Content-Type' => 'application/json',
101 ],
102 'body' => json_encode( $args ),
103 'timeout' => 3600,
104 ]
105 );
106
107 if ( is_wp_error( $response ) ) {
108 throw new Exception( $response->get_error_message(), 400 );
109 }
110
111 $body = wp_remote_retrieve_body( $response );
112 $data = LP_Helper::json_decode( $body, true );
113 if ( isset( $data['error'] ) ) {
114 throw new Exception( $data['error']['message'] );
115 }
116
117 return $this->detected_data( $data );
118 }
119
120 /**
121 * @throws Exception
122 */
123 public function send_request_create_image( $args ) {
124 $args_default = [
125 'model' => $this->image_model_type,
126 'prompt' => '',
127 ];
128
129 $args = array_merge( $args_default, $args );
130
131 $model_type = LP_Settings::get_option( 'open_ai_image_model_type', 'gpt-image-1' );
132 if ( $model_type === 'gpt-image-1' ) {
133 unset( $args['n'] );
134 }
135
136 if ( $model_type == 'dall-e-3' ) {
137 // only n=1 is supported.
138 $args['n'] = 1;
139 }
140
141 $response = wp_remote_post(
142 $this->urlImage,
143 [
144 'headers' => [
145 'Authorization' => 'Bearer ' . $this->secret_key,
146 'Content-Type' => 'application/json',
147 ],
148 'body' => json_encode( $args ),
149 'timeout' => 3600,
150 ]
151 );
152
153 if ( is_wp_error( $response ) ) {
154 throw new Exception( $response->get_error_message(), 400 );
155 }
156
157 $body = wp_remote_retrieve_body( $response );
158 $data = LP_Helper::json_decode( $body, true );
159 if ( isset( $data['error'] ) ) {
160 throw new Exception( $data['error']['message'] );
161 }
162
163 return $data;
164 }
165
166 /**
167 * Handle params for send chat completion
168 *
169 * @docs https://platform.openai.com/docs/api-reference/chat/create
170 *
171 * @throws Exception
172 */
173 public function handle_params_for_send_chat_completion( $params ): array {
174 $params = [
175 'model' => $this->text_model_type,
176 'frequency_penalty' => $this->frequency_penalty,
177 'presence_penalty' => $this->presence_penalty,
178 'temperature' => $this->creativity_level,
179 'max_completion_tokens' => $this->max_token,
180 'response_format' => [ 'type' => 'json_object' ],
181 'n' => $args['outputs'] ?? 1,
182 'messages' => [
183 [
184 'role' => 'system',
185 'content' => 'You are an AI assistant specialized in education and course design.',
186 ],
187 [
188 'role' => 'user',
189 'content' => $params['prompt'] ?? '',
190 ],
191 ],
192 ];
193
194 if ( $this->max_token === 0 ) {
195 unset( $params['max_completion_tokens'] );
196 }
197
198 return $params;
199 }
200
201 /**
202 * Handle params for send chat completion
203 *
204 * @docs https://platform.openai.com/docs/api-reference/completions/create
205 *
206 * @throws Exception
207 */
208 public function handle_params_for_send_completion_legacy( $params ): array {
209 $params = [
210 'model' => $this->text_model_type,
211 'temperature' => $this->creativity_level,
212 'max_tokens' => $this->max_token,
213 'n' => $args['outputs'] ?? 1,
214 'prompt' => $params['prompt'] ?? '',
215 ];
216
217 if ( $this->max_token === 0 ) {
218 unset( $params['max_tokens'] );
219 }
220
221 return $params;
222 }
223
224 /**
225 * Handle params for send chat completion
226 *
227 * @docs https://platform.openai.com/docs/api-reference/responses/create
228 *
229 * @throws Exception
230 */
231 public function handle_params_for_send_responses( $params ): array {
232 $params = [
233 'model' => $this->text_model_type,
234 //'temperature' => $this->creativity_level,
235 'max_output_tokens' => $this->max_token,
236 'input' => $params['prompt'] ?? '',
237 ];
238
239 if ( $this->max_token === 0 ) {
240 unset( $params['max_output_tokens'] );
241 }
242
243 return $params;
244 }
245
246 /**
247 * Detect data from response
248 *
249 * @throws Exception
250 */
251 public function detected_data( array $data ): array {
252 $data['lp_structure_data'] = [];
253
254 if ( isset( $data['choices'] ) ) {
255 foreach ( $data['choices'] as $choice ) {
256 $text = $choice['message']['content'] ?? $choice['text'] ?? '';
257 $text = str_replace( [ "\\n", "\\r", "\n", "\r", "\t" ], '', $text );
258
259 $data['lp_structure_data'][] = LP_Helper::json_decode( $text, true );
260 }
261 } elseif ( isset( $data['output'] ) ) {
262 foreach ( $data['output'] as $output ) {
263 $content_data = $output['content'] ?? [];
264 if ( empty( $content_data ) ) {
265 continue;
266 }
267
268 foreach ( $output['content'] as $content ) {
269 try {
270 $text = $content['text'] ?? '';
271 $text = str_replace( [ "\\n", "\\r", "\n", "\r", "\t" ], '', $text );
272 $data['lp_structure_data'][] = LP_Helper::json_decode( $text, true );
273 } catch ( Exception $e ) {
274 $data['lp_structure_data'][] = $content['text'] ?? '';
275 }
276 }
277 }
278 }
279
280 return $data;
281 }
282 }
283