PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.2
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.2
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.2, at inc/Ajax/AI/OpenAiAjax.php

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