PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.0
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.0
4.4.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 All 139 releases
learnpress / inc / Ajax / AI / OpenAiAjax.php

OpenAiAjax.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.0, at inc/Ajax/AI/OpenAiAjax.php

515 lines 16.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\Ajax\AI;
4
5 use Exception;
6 use LearnPress;
7 use LearnPress\Ajax\AbstractAjax;
8 use LearnPress\Helpers\Config;
9 use LearnPress\Helpers\Template;
10 use LearnPress\Models\QuizPostModel;
11 use LearnPress\Models\UserModel;
12 use LearnPress\Services\CourseService;
13 use LearnPress\Services\OpenAiService;
14 use LearnPress\TemplateHooks\Admin\AI\AdminCreateCourseAITemplate;
15 use LearnPress\TemplateHooks\Admin\AI\AdminEditCourseCurriculumWithAITemplate;
16 use LearnPress\TemplateHooks\Admin\AI\AdminEditWithAITemplate;
17 use LP_Helper;
18 use LP_Request;
19 use LP_REST_Response;
20 use Throwable;
21
22 /**
23 * class OpenAiAjax
24 * Handle request Open AI
25 *
26 * @since 4.3.0
27 * @version 1.0.0
28 */
29 class OpenAiAjax extends AbstractAjax {
30 /**
31 * Generate prompt course with AI
32 */
33 public function openai_generate_prompt_course() {
34 $response = new LP_REST_Response();
35
36 try {
37 // Check permission
38 if ( ! current_user_can( UserModel::ROLE_ADMINISTRATOR )
39 && ! current_user_can( UserModel::ROLE_INSTRUCTOR ) ) {
40 throw new Exception( __( 'You do not have permission to perform this action.', 'learnpress' ) );
41 }
42
43 $data_str = LP_Request::get_param( 'data' );
44 $params = LP_Helper::json_decode( $data_str, true );
45 $prompt = Config::instance()->get( 'prompt-create-course', 'settings/openAi', compact( 'params' ) );
46
47 $response->data = $prompt;
48 $response->status = 'success';
49 $response->message = __( 'Generate prompt successfully!', 'learnpress' );
50 } catch ( Throwable $e ) {
51 $response->message = $e->getMessage();
52 }
53
54 wp_send_json( $response );
55 }
56
57 /**
58 * Generate data course with prompt submitted
59 */
60 public function openai_generate_data_course() {
61 $response = new LP_REST_Response();
62
63 try {
64 // Check permission
65 if ( ! current_user_can( UserModel::ROLE_ADMINISTRATOR )
66 && ! current_user_can( UserModel::ROLE_INSTRUCTOR ) ) {
67 throw new Exception( __( 'You do not have permission to perform this action.', 'learnpress' ) );
68 }
69
70 $data_str = LP_Request::get_param( 'data' );
71 $params = LP_Helper::json_decode( $data_str, true );
72 $prompt = $params['lp-openai-prompt-generated-field'] ?? '';
73 $args = [
74 'prompt' => $prompt,
75 ];
76
77 $result = OpenAiService::instance()->send_request( $args );
78 $lp_structure_data = $result['lp_structure_data'] ?? [];
79 if ( count( $lp_structure_data ) > 0 ) {
80 $result['lp_structure_course'] = $lp_structure_data[0] ?? '';
81 if ( empty( $result['lp_structure_course'] )
82 || ! is_array( $result['lp_structure_course'] ) ) {
83 throw new Exception( __( 'Error: no data structure course generated!', 'learnpress' ) );
84 }
85
86 $result['lp_html_preview'] = AdminCreateCourseAITemplate::html_preview_with_data( $result['lp_structure_course'] );
87 }
88
89 $response->data = $result;
90 $response->status = 'success';
91 $response->message = __( 'Generate course successfully!', 'learnpress' );
92 } catch ( Throwable $e ) {
93 $response->message = $e->getMessage();
94 }
95
96 wp_send_json( $response );
97 }
98
99 /**
100 * Create course with data generated
101 */
102 public function openai_create_course() {
103 $response = new LP_REST_Response();
104
105 try {
106 // Check permission
107 if ( ! current_user_can( UserModel::ROLE_ADMINISTRATOR )
108 && ! current_user_can( UserModel::ROLE_INSTRUCTOR ) ) {
109 throw new Exception( __( 'You do not have permission to perform this action.', 'learnpress' ) );
110 }
111
112 $data_str = LP_Request::get_param( 'data' );
113 $data = LP_Helper::json_decode( $data_str, true );
114 $data_structure_course = $data['lp_structure_course'] ?? [];
115 $is_course_builder = ! empty( $data['is_course_builder'] );
116 if ( empty( $data_structure_course ) ) {
117 throw new Exception( __( 'Invalid data to create course!', 'learnpress' ) );
118 }
119
120 $courseService = CourseService::instance();
121
122 $data_info_main = [
123 'post_title' => $data_structure_course['course_title'] ?? 'AI Generated Course',
124 'post_content' => $data_structure_course['course_description'] ?? '',
125 'post_status' => 'draft',
126 'post_author' => get_current_user_id(),
127 ];
128 $coursePostModel = $courseService->create_info_main( $data_info_main );
129
130 // Create section
131 $data_sections = $data_structure_course['sections'] ?? [];
132 foreach ( $data_sections as $data_section ) {
133 $section_name = $data_section['section_title'] ?? '';
134 $section_description = $data_section['section_description'] ?? '';
135 $lesson_items = $data_section['lessons'] ?? [];
136 $quiz_items = $data_section['quizzes'] ?? [];
137
138 $courseSectionModel = $coursePostModel->add_section(
139 [
140 'section_name' => $section_name,
141 'section_description' => $section_description,
142 ]
143 );
144
145 // Create lesson items for section
146 foreach ( $lesson_items as $lesson_item ) {
147 $lesson_name = $lesson_item['lesson_title'] ?? '';
148 $lesson_description = $lesson_item['lesson_description'] ?? '';
149
150 $courseSectionModel->create_item_and_add(
151 [
152 'item_title' => $lesson_name,
153 'item_type' => LP_LESSON_CPT,
154 'item_content' => $lesson_description,
155 ]
156 );
157 }
158
159 // Create quiz items for section
160 foreach ( $quiz_items as $quiz_item ) {
161 $quiz_name = $quiz_item['quiz_title'] ?? '';
162 $quiz_description = $quiz_item['quiz_description'] ?? '';
163
164 $courseSectionQuizModel = $courseSectionModel->create_item_and_add(
165 [
166 'item_title' => $quiz_name,
167 'item_type' => LP_QUIZ_CPT,
168 'item_content' => $quiz_description,
169 ]
170 );
171 $quizPostModel = QuizPostModel::find( $courseSectionQuizModel->item_id, true );
172
173 // Create questions for quiz
174 $question_items = $quiz_item['questions'] ?? [];
175 foreach ( $question_items as $question_item ) {
176 $question_name = $question_item['question_title'] ?? '';
177 $question_description = $question_item['question_description'] ?? '';
178 $options = $question_item['options'] ?? [];
179 $correct_answer = $question_item['correct_answer'] ?? '';
180
181 $data_answers = [];
182 foreach ( $options as $index => $option ) {
183 $data_answers[] = [
184 'title' => $option,
185 'is_true' => ( $option === $correct_answer ) ? 'yes' : 'no',
186 'order' => $index + 1,
187 ];
188 }
189
190 $quizPostModel->create_question_and_add(
191 [
192 'question_title' => $question_name,
193 'question_content' => $question_description,
194 'question_type' => 'single_choice',
195 'question_options' => $data_answers,
196 ]
197 );
198 }
199 }
200 }
201
202 $course_edit_url = $coursePostModel->get_edit_link();
203 if ( $is_course_builder ) {
204 $course_edit_url = \LearnPress\CourseBuilder\CourseBuilder::get_tab_link(
205 'courses',
206 $coursePostModel->get_id(),
207 'overview'
208 );
209 }
210
211 $response->data->edit_course_url = $course_edit_url;
212 $response->data->button_label = __( 'Redirecting...', 'learnpress' );
213 $response->status = 'success';
214 $response->message = __( 'Create Course Successfully! Redirecting to course detail...', 'learnpress' );
215 } catch ( Throwable $e ) {
216 $response->message = $e->getMessage();
217 }
218
219 wp_send_json( $response );
220 }
221
222 /**
223 * Generate prompt title with AI
224 */
225 public function openai_generate_prompt() {
226 $response = new LP_REST_Response();
227
228 try {
229 // Check permission
230 if ( ! current_user_can( UserModel::ROLE_ADMINISTRATOR )
231 && ! current_user_can( UserModel::ROLE_INSTRUCTOR ) ) {
232 throw new Exception( __( 'You do not have permission to perform this action.', 'learnpress' ) );
233 }
234
235 $data_str = LP_Request::get_param( 'data' );
236 $params = LP_Helper::json_decode( $data_str, true );
237 $lp_prompt_type = $params['lp-prompt-type'] ?? '';
238
239 switch ( $lp_prompt_type ) {
240 case 'course-description':
241 $prompt = Config::instance()->get( 'prompt-create-description-course', 'settings/openAi', compact( 'params' ) );
242 break;
243 case 'course-title':
244 $prompt = Config::instance()->get( 'prompt-create-title-course', 'settings/openAi', compact( 'params' ) );
245 break;
246 case 'course-image':
247 $prompt = Config::instance()->get( 'prompt-create-image-course', 'settings/openAi', compact( 'params' ) );
248 break;
249 case 'course-curriculum':
250 $prompt = Config::instance()->get( 'prompt-curriculum-course', 'settings/openAi', compact( 'params' ) );
251 break;
252 case $lp_prompt_type:
253 $prompt = apply_filters( 'lp-prompt-type', '', $lp_prompt_type, $params );
254 break;
255 default:
256 $prompt = '';
257 break;
258 }
259
260 $response->data = $prompt;
261 $response->status = 'success';
262 $response->message = __( 'Generate prompt successfully!', 'learnpress' );
263 } catch ( Throwable $e ) {
264 $response->message = $e->getMessage();
265 }
266
267 wp_send_json( $response );
268 }
269
270 /**
271 * Generate data course with prompt submitted
272 */
273 public function openai_generate_data() {
274 $response = new LP_REST_Response();
275
276 try {
277 // Check permission
278 if ( ! current_user_can( UserModel::ROLE_ADMINISTRATOR )
279 && ! current_user_can( UserModel::ROLE_INSTRUCTOR ) ) {
280 throw new Exception( __( 'You do not have permission to perform this action.', 'learnpress' ) );
281 }
282
283 $data_str = LP_Request::get_param( 'data' );
284 $params = LP_Helper::json_decode( $data_str, true );
285 $prompt = $params['lp-openai-prompt-generated-field'] ?? '';
286 $args = [
287 'prompt' => $prompt,
288 ];
289
290 $result = OpenAiService::instance()->send_request( $args );
291 $lp_structure_data = $result['lp_structure_data'] ?? [];
292 $result['lp_html_preview'] = '';
293 if ( count( $lp_structure_data ) > 0 ) {
294 $lp_prompt_type = $params['lp-prompt-type'] ?? '';
295 switch ( $lp_prompt_type ) {
296 case 'course-description':
297 case 'course-title':
298 $results = $lp_structure_data[0];
299 if ( isset( $results['results'] ) ) {
300 $results = $results['results'];
301 } else {
302 throw new Exception(
303 __(
304 'Error: No data was generated. The requested data may be large, increase the Max Tokens in settings and try again.',
305 'learnpress'
306 )
307 );
308 }
309
310 foreach ( $results as $index => $data_item ) {
311 $data_item = $data_item['item'] ?? '';
312 $args = [
313 'index' => $index,
314 'value' => $data_item,
315 'target-apply' => $params['target-apply'] ?? '',
316 ];
317 $result['lp_html_preview'] .= AdminEditWithAITemplate::instance()->html_list_results( $args );
318 }
319 break;
320 case 'course-curriculum':
321 $result['lp_structure_course'] = $lp_structure_data[0];
322 $result['lp_html_preview'] = AdminEditCourseCurriculumWithAITemplate::html_preview_with_data(
323 $result['lp_structure_course']
324 );
325 break;
326 case $lp_prompt_type:
327 $result['lp_html_preview'] = apply_filters( 'lp-openai-render-data-generated', '', $lp_prompt_type, $lp_structure_data );
328 break;
329 default:
330 break;
331 }
332 }
333
334 $result['lp_html_preview'] .= sprintf(
335 '<input type="hidden" name="lp-openai-generated-data" value="%s" />',
336 Template::convert_data_to_json( $lp_structure_data )
337 );
338
339 $response->data = $result;
340 $response->status = 'success';
341 $response->message = __( 'Generate course successfully!', 'learnpress' );
342 } catch ( Throwable $e ) {
343 $response->message = $e->getMessage();
344 }
345
346 wp_send_json( $response );
347 }
348
349 /**
350 * Generate image with prompt submitted
351 * Send data to Open AI to generate image
352 *
353 * @since 4.3.0
354 * @version 1.0.0
355 */
356 public function openai_generate_image() {
357 $response = new LP_REST_Response();
358
359 try {
360 // Check permission
361 if ( ! current_user_can( UserModel::ROLE_ADMINISTRATOR )
362 && ! current_user_can( UserModel::ROLE_INSTRUCTOR ) ) {
363 throw new Exception( __( 'You do not have permission to perform this action.', 'learnpress' ) );
364 }
365
366 $data_str = LP_Request::get_param( 'data' );
367 $params = LP_Helper::json_decode( $data_str, true );
368 $prompt = $params['lp-openai-prompt-generated-field'] ?? '';
369 $args = [
370 'prompt' => $prompt,
371 'n' => intval( $params['outputs'] ?? 1 ),
372 'size' => $params['size'] ?? '',
373 ];
374
375 $result = OpenAiService::instance()->send_request_create_image( $args );
376 $html_image = '';
377 $result['lp_html_preview'] = '';
378 $data = $result['data'] ?? [];
379 if ( ! empty( $data ) ) {
380 $result['lp_html_preview'] = '<div class="lp-ai-images-warp">';
381 foreach ( $data as $index => $data_item ) {
382 $image_base_64 = $data_item['b64_json'] ?? '';
383 $image_url = $data_item['url'] ?? '';
384
385 if ( ! empty( $image_url ) ) {
386 $html_image = sprintf(
387 '<img src="%s" alt="AI Generated Image" />',
388 esc_url( $image_url )
389 );
390 } elseif ( ! empty( $image_base_64 ) ) {
391 $html_image = sprintf(
392 '<img src="data:image/png;base64,%s" alt="AI Generated Image" />',
393 esc_attr( $image_base_64 )
394 );
395 }
396
397 if ( empty( $html_image ) ) {
398 continue;
399 }
400
401 $result['lp_html_preview'] .= '<div class="lp-ai-image-item">';
402 $result['lp_html_preview'] .= $html_image;
403 $result['lp_html_preview'] .= sprintf(
404 '<button class="lp-btn-ai-apply-image lp-button" type="button"
405 data-send="%s">%s
406 </button>',
407 Template::convert_data_to_json(
408 [
409 'action' => 'openai_apply_image_feature',
410 'image-url' => ! empty( $image_url ) ? $image_url : '',
411 'image-base64' => ! empty( $image_base_64 ) ? $image_base_64 : '',
412 'id_url' => 'apply-image-feature',
413 ]
414 ),
415 __( 'Apply Image', 'learnpress' )
416 );
417 $result['lp_html_preview'] .= '</div>';
418 }
419 $result['lp_html_preview'] .= '</div>';
420 }
421
422 $response->data = $result;
423 $response->status = 'success';
424 $response->message = __( 'Generate image successfully!', 'learnpress' );
425 } catch ( Throwable $e ) {
426 $response->message = $e->getMessage();
427 }
428
429 wp_send_json( $response );
430 }
431
432 /**
433 * Apply image feature to post
434 * Upload image to media and set as feature image for post
435 *
436 * @since 4.3.0
437 * @version 1.0.0
438 */
439 public function openai_apply_image_feature() {
440 $response = new LP_REST_Response();
441
442 try {
443 set_time_limit( 0 );
444 // Check permission
445 if ( ! current_user_can( UserModel::ROLE_ADMINISTRATOR )
446 && ! current_user_can( UserModel::ROLE_INSTRUCTOR ) ) {
447 throw new Exception( __( 'You do not have permission to perform this action.', 'learnpress' ) );
448 }
449
450 $data_str = $_POST['data'] ?? '';
451 $params = LP_Helper::json_decode( wp_unslash( $data_str ), true );
452 $image_base64 = $params['image-base64'] ?? '';
453 $image_url = $params['image-url'] ?? '';
454
455 $params = LP_Helper::sanitize_params_submitted( $params );
456 $post_id = $params['post-id'] ?? '';
457 $post_title = $params['post-title'] ?? uniqid();
458 $post_slug = sanitize_title( $post_title );
459
460 if ( empty( $post_id ) ) {
461 throw new Exception( __( 'Invalid post ID.', 'learnpress' ) );
462 }
463
464 if ( ! function_exists( 'media_handle_sideload' ) ) {
465 require_once ABSPATH . 'wp-admin/includes/media.php';
466 require_once ABSPATH . 'wp-admin/includes/file.php';
467 require_once ABSPATH . 'wp-admin/includes/image.php';
468 }
469
470 if ( ! empty( $image_url ) ) {
471 $tmp = download_url( $image_url );
472 $fileExt = pathinfo( parse_url( $image_url, PHP_URL_PATH ), PATHINFO_EXTENSION );
473 $filename = sanitize_file_name( $post_slug . '-' . uniqid() . '.' . $fileExt );
474
475 } elseif ( ! empty( $image_base64 ) ) {
476 $decoded_image = base64_decode( $image_base64 );
477 $tmp = wp_tempnam();
478 file_put_contents( $tmp, $decoded_image );
479 $filename = sanitize_file_name( $post_slug . '-' . uniqid() . '.png' );
480 } else {
481 throw new Exception( __( 'No image data provided.', 'learnpress' ) );
482 }
483
484 $file_array = [
485 'name' => $filename,
486 'tmp_name' => $tmp,
487 ];
488 $attachment_id = media_handle_sideload( $file_array, $post_id );
489
490 if ( ! is_wp_error( $attachment_id ) ) {
491 set_post_thumbnail( $post_id, $attachment_id );
492 } else {
493 throw new Exception( $attachment_id->get_error_message() );
494 }
495
496 $args = [
497 'src' => wp_get_attachment_url( $attachment_id ),
498 'post-id' => $post_id,
499 'attachment-id' => $attachment_id,
500 ];
501
502 $response->data->html_image = AdminEditWithAITemplate::instance()->html_feature_image_created( $args );
503 $response->data->attachment_id = $attachment_id;
504 $response->status = 'success';
505 $response->message = __( 'Apply image successfully!', 'learnpress' );
506 } catch ( Throwable $e ) {
507 $response->message = $e->getMessage();
508 }
509
510 set_time_limit( LearnPress::$time_limit_default_of_sever );
511
512 wp_send_json( $response );
513 }
514 }
515