PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
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 / TemplateHooks / Admin / AI / AdminEditCourseCurriculumWithAITemplate.php

AdminEditCourseCurriculumWithAITemplate.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.8, at inc/TemplateHooks/Admin/AI/AdminEditCourseCurriculumWithAITemplate.php

474 lines 15.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace LearnPress\TemplateHooks\Admin\AI;
4
5 use LearnPress\Helpers\Config;
6 use LearnPress\Helpers\Singleton;
7 use LearnPress\Helpers\Template;
8 use LearnPress\TemplateHooks\Admin\AdminTemplate;
9 use LP_Debug;
10 use LP_Settings;
11 use Throwable;
12
13 /**
14 * Class AdminEditCourseCurriculumWithAITemplate
15 *
16 * @since 4.2.9
17 * @version 1.1.0
18 */
19 class AdminEditCourseCurriculumWithAITemplate {
20 use Singleton;
21
22 /**
23 * @var array|null
24 */
25 private ?array $config;
26
27 /**
28 * Init hooks.
29 */
30 public function init() {
31 add_action( 'admin_footer', [ $this, 'layout_popup' ] );
32 }
33
34 /**
35 * Layout popup to generate course curriculum with AI
36 */
37 public function layout_popup() {
38 try {
39 if ( ! function_exists( 'get_current_screen' ) ) {
40 return;
41 }
42
43 $screen = get_current_screen();
44 $screens = [
45 LP_COURSE_CPT,
46 ];
47 if ( ! $screen || in_array( $screen, $screens ) ) {
48 return;
49 }
50
51 echo $this->render_for_frontend();
52 } catch ( Throwable $e ) {
53 LP_Debug::error_log( $e );
54 }
55 }
56
57 /**
58 * Render curriculum AI popup template for frontend contexts (e.g. Course Builder).
59 *
60 * @return string
61 * @since 4.3.0
62 */
63 public function render_for_frontend(): string {
64 try {
65 $this->config = Config::instance()->get( 'open-ai-modal', 'settings' );
66
67 $components = [
68 'wrap-script-template' => '<script type="text/template" id="lp-tmpl-edit-course-curriculum-ai">',
69 'wrap' => '<div class="lp-generate-data-ai-wrap">',
70 'btn-close' =>
71 '<button type="button" class="lp-btn-close-ai-popup">
72 <i class="lp-icon-remove"></i>
73 </button>',
74 'h2' => sprintf(
75 '<div class="content-title">%s</div>',
76 esc_html__( 'Generate Course Sections Curriculum', 'learnpress' )
77 ),
78 'header' => $this->html_step_header(),
79 'form' => '<form class="lp-form-generate-data-ai">',
80 'wrap-fields' => '<div class="lp-form-fields">',
81 'step_1' => $this->html_step_1(),
82 'step_2' => $this->html_step_2(),
83 'step_3' => $this->html_step_3(),
84 'step_4' => $this->html_step_4(),
85 'wrap-fields-end' => '</div>',
86 'buttons' => sprintf(
87 '<div class="button-actions" data-step="1" data-step-max="4">
88 <button class="btn btn-secondary lp-btn-step lp-hidden"
89 data-step-show="2,3,4"
90 data-action="prev" type="button">&larr; %s
91 </button>
92 <button class="btn btn-primary lp-btn-step"
93 data-step-show="1"
94 data-action="next" type="button">%s &rarr;
95 </button>
96 <button class="lp-button btn-primary lp-btn-generate-prompt lp-hidden"
97 data-step-show="2"
98 data-send="%s" type="button">%s
99 </button>
100 <button class="lp-button btn-primary lp-btn-call-open-ai lp-hidden"
101 data-step-show="3"
102 data-send="%s" type="button">%s
103 </button>
104 <button class="lp-button btn-primary lp-btn-apply-curriculum lp-hidden"
105 data-step-show="4"
106 data-send="%s" type="button">%s
107 </button>
108 </div>',
109 esc_html__( 'Previous', 'learnpress' ),
110 esc_html__( 'Next', 'learnpress' ),
111 Template::convert_data_to_json(
112 [
113 'action' => 'openai_generate_prompt',
114 'lp-prompt-type' => 'course-curriculum', // define type prompt to generate title.
115 'id_url' => 'generate_prompt_openai',
116 ]
117 ),
118 esc_html__( 'Generate Prompt', 'learnpress' ),
119 Template::convert_data_to_json(
120 [
121 'action' => 'openai_generate_data',
122 'lp-prompt-type' => 'course-curriculum', // define type prompt to generate title.
123 'id_url' => 'submit_to_openai',
124 ]
125 ),
126 esc_html__( 'Generate Sections Course', 'learnpress' ),
127 Template::convert_data_to_json(
128 [
129 'action' => 'openai_create_course_sections',
130 'id_url' => 'openai_create_course_sections',
131 ]
132 ),
133 esc_html__( 'Apply Sections Data To Curriculum', 'learnpress' ),
134 ),
135 'form-end' => '</form>',
136 'wrap-end' => '</div>',
137 'wrap-script-template-end' => '</script>',
138 ];
139
140 return Template::combine_components( $components );
141 } catch ( Throwable $e ) {
142 LP_Debug::error_log( $e );
143 }
144
145 return '';
146 }
147
148 public function html_step_header(): string {
149 $components = [
150 'wrap' => '<div class="step-header">',
151 'step_1' => sprintf(
152 '<div class="step-item active" data-step="1"><span class="step-number">1</span><span class="step-text">%s</span></div>',
153 esc_html__( 'Curriculum Goal', 'learnpress' )
154 ),
155 'step_2' => sprintf(
156 '<div class="step-item" data-step="2"><span class="step-number">2</span><span class="step-text">%s</span></div>',
157 esc_html__( 'AI Settings', 'learnpress' )
158 ),
159 'step_3' => sprintf(
160 '<div class="step-item" data-step="3"><span class="step-number">3</span><span class="step-text">%s</span></div>',
161 esc_html__( 'Prompt', 'learnpress' )
162 ),
163 'step_4' => sprintf(
164 '<div class="step-item" data-step="4"><span class="step-number">4</span><span class="step-text">%s</span></div>',
165 esc_html__( 'Result', 'learnpress' )
166 ),
167 'wrap-end' => '</div>',
168 ];
169
170 return Template::combine_components( $components );
171 }
172
173 public function html_step_1(): string {
174 $options = $this->config;
175
176 $components = [
177 'step' => '<div class="step-content active" data-step="1">',
178 'title' => sprintf(
179 '<div class="step-title">%s</div>',
180 esc_html__( 'Step 1 — Curriculum Goal', 'learnpress' ),
181 ),
182 'description' => sprintf(
183 '<p class="step-description">%s</p>',
184 esc_html__( 'Provide the main goal for the curriculum so the system can generate aligned sections and lessons.', 'learnpress' )
185 ),
186 'post-title' => sprintf(
187 '<div class="form-group">
188 <label>%s</label>
189 <input class="title-refer" type="text" name="post-title" readonly />
190 <p class="lp-ai-warning-refer lp-hidden"><i class="lp-icon-warning"></i>%s</p>
191 <p class="field-description">%s</p>
192 </div>',
193 esc_html__( 'Title refer', 'learnpress' ),
194 esc_html__( 'You can edit the course title to better suit the curriculum generation.', 'learnpress' ),
195 esc_html__( 'The course title is automatically imported from the previous step. It will guide the AI to build a structured curriculum.', 'learnpress' ),
196 ),
197 'post-content' => sprintf(
198 '<div class="form-group">
199 <label>%s</label>
200 <textarea class="description-refer" type="text" name="post-content" readonly></textarea>
201 <p class="lp-ai-warning-refer lp-hidden"><i class="lp-icon-warning"></i>%s</p>
202 <p class="field-description">%s</p>
203 </div>',
204 esc_html__( 'Description refer', 'learnpress' ),
205 esc_html__( 'You can edit the course description to better suit the curriculum generation.', 'learnpress' ),
206 esc_html__( 'The course description is automatically imported from the previous step. It will guide the AI to build a structured curriculum.', 'learnpress' )
207 ),
208 'goal' => sprintf(
209 '<div class="form-group">
210 <label>%s</label>
211 <textarea type="text" name="goal" placeholder="%s"></textarea>
212 </div>',
213 esc_html__( 'Goal', 'learnpress' ),
214 esc_html__( 'Defines the main objective of your curriculum. This helps the AI generate course sections and lessons that align with the intended learning outcomes.', 'learnpress' )
215 ),
216 'form-grid' => '<div class="form-grid">',
217 'sections-number' => sprintf(
218 '<div class="form-group">
219 <label>%s</label>
220 <input type="number" name="section_number" value="2" min="0">
221 </div>',
222 esc_html__( 'Sections number', 'learnpress' )
223 ),
224 /*'sections-title-length' => sprintf(
225 '<div class="form-group">
226 <label>%s</label>
227 <input type="number" name="section_title_length" value="60" min="0">
228 </div>',
229 esc_html__( 'Each section title length', 'learnpress' )
230 ),
231 'sections-des-length' => sprintf(
232 '<div class="form-group">
233 <label>%s</label>
234 <input type="number" name="section_description_length" value="50" min="0">
235 </div>',
236 esc_html__( 'Each section description length', 'learnpress' )
237 ),*/
238 'lesson-number' => sprintf(
239 '<div class="form-group">
240 <label>%s</label>
241 <input type="number" name="lessons_per_section" value="2" min="0">
242 </div>',
243 esc_html__( 'Lessons per Section', 'learnpress' )
244 ),
245 /*'lesson-title-length' => sprintf(
246 '<div class="form-group">
247 <label>%s</label>
248 <input type="number" name="lessons_title_length" value="60" min="0">
249 </div>',
250 esc_html__( 'Each lesson title length', 'learnpress' )
251 ),*/
252 'quizzes' => sprintf(
253 '<div class="form-group">
254 <label>%s</label>
255 <input type="number" name="quizzes_per_section" value="2" min="0">
256 </div>',
257 esc_html__( 'Quizzes per Section', 'learnpress' )
258 ),
259 /*'quiz-title-length' => sprintf(
260 '<div class="form-group">
261 <label>%s</label>
262 <input type="number" name="quiz_title_length" value="60" min="0">
263 </div>',
264 esc_html__( 'Each quiz title length', 'learnpress' )
265 ),*/
266 'form-grid-end' => '</div>',
267 'step_close' => '</div>',
268 ];
269
270 return Template::combine_components( $components );
271 }
272
273 public function html_step_2(): string {
274 $options = $this->config;
275
276 $components = [
277 'step' => '<div class="step-content" data-step="2">',
278 'title' => sprintf(
279 '<div class="step-title">%s</div>',
280 esc_html__( 'Step 2 — AI Settings', 'learnpress' ),
281 ),
282 'description' => sprintf(
283 '<p class="step-description">%s</p>',
284 esc_html__( 'Configure content quality controls for ChatGPT output.', 'learnpress' )
285 ),
286 'form-grid' => '<div class="form-grid">',
287 'audience' => sprintf(
288 '<div class="form-group">
289 <label>%s</label>%s
290 <p class="field-description">%s</p>
291 </div>',
292 esc_html__( 'Target Audience', 'learnpress' ),
293 AdminTemplate::html_tom_select(
294 [
295 'name' => 'target_audience',
296 'class_name' => '',
297 'options' => $options['audience'] ?? [],
298 'default_value' => 'Students',
299 'multiple' => true,
300 ]
301 ),
302 esc_html__( 'Identifies who will take the course so the content matches their background and skill level.', 'learnpress' )
303 ),
304 'tone' => sprintf(
305 '<div class="form-group">
306 <label for="swal-tone">%s</label>%s
307 <p class="field-description">%s</p>
308 </div>',
309 esc_html__( 'Tone', 'learnpress' ),
310 AdminTemplate::html_tom_select(
311 [
312 'name' => 'tone',
313 'options' => $options['tone'] ?? [],
314 'multiple' => true,
315 'default_value' => [ 'Analytical' ],
316 ]
317 ),
318 esc_html__( 'Controls the writing style (e.g., friendly, formal, story-telling) so the content matches your brand and audience.', 'learnpress' )
319 ),
320 'language' => sprintf(
321 '<div class="form-group">
322 <label>%s</label>%s
323 <p class="field-description">%s</p>
324 </div>',
325 esc_html__( 'Language', 'learnpress' ),
326 AdminTemplate::html_tom_select(
327 [
328 'name' => 'language',
329 'options' => $options['language'] ?? [],
330 ]
331 ),
332 esc_html__( 'Sets the output language for all generated course content.', 'learnpress' )
333 ),
334 'form-grid-end' => '</div>',
335 'step_close' => '</div>',
336 ];
337
338 return Template::combine_components( $components );
339 }
340
341 public function html_step_3(): string {
342 $options = $this->config;
343
344 $components = [
345 'step' => '<div class="step-content" data-step="3">',
346 'title' => sprintf(
347 '<div class="step-title">%s</div>',
348 esc_html__( 'Step 3 — Prompt Generated', 'learnpress' ),
349 ),
350 'prompt' => sprintf(
351 '<div class="form-group">
352 <label>%s</label>%s
353 <i>%s</i>
354 </div>',
355 esc_html__( 'Generated Prompt', 'learnpress' ),
356 '<textarea name="lp-openai-prompt-generated-field"></textarea>',
357 __( 'Shows the auto-generated AI prompt, allowing further adjustments before submission.', 'learnpress' )
358 ),
359 'step_close' => '</div>',
360 ];
361
362 return Template::combine_components( $components );
363 }
364
365 public function html_step_4(): string {
366 $options = $this->config;
367
368 $components = [
369 'step' => '<div class="step-content" data-step="4">',
370 'title' => sprintf(
371 '<div class="step-title">%s</div>',
372 esc_html__( 'Step 4 — Result', 'learnpress' ),
373 ),
374 'results' => '<div class="lp-ai-generated-results lp-ai-course-data-preview-wrap"></div>',
375 'step_close' => '</div>',
376 ];
377
378 return Template::combine_components( $components );
379 }
380
381 /**
382 * HTML preview with data received from OpenAI
383 *
384 * @param array $data_received
385 *
386 * @return string
387 */
388 public static function html_preview_with_data( array $data_received ): string {
389 $sections = $data_received['sections'] ?? [];
390
391 $html_section = '';
392 foreach ( $sections as $section ) {
393 $section_title = $section['section_title'] ?? '';
394 $section_des = $section['section_description'] ?? '';
395 $lessons = $section['lessons'] ?? [];
396 $quizzes = $section['quizzes'] ?? [];
397
398 $html_lessons = '';
399 foreach ( $lessons as $lesson ) {
400 $lesson_title = $lesson['lesson_title'] ?? '';
401 $lesson_des = $lesson['lesson_description'] ?? '';
402
403 $arr_lesson_components = [
404 'wrap' => '<li class="course-lesson-item">',
405 'title' => sprintf( '<div class="lesson-title">%s</div>', esc_html( $lesson_title ) ),
406 'des' => sprintf( '<div class="lesson-description">%s</div>', esc_html( $lesson_des ) ),
407 'wrap-end' => '</li>',
408 ];
409
410 $html_lessons .= Template::combine_components( $arr_lesson_components );
411 }
412
413 // Quizzes
414 $html_quizzes = '';
415 foreach ( $quizzes as $quiz ) {
416 $quiz_title = $quiz['quiz_title'] ?? '';
417 $quiz_des = $quiz['quiz_description'] ?? '';
418 $questions = $quiz['questions'] ?? [];
419
420 $html_questions = '';
421 foreach ( $questions as $question ) {
422 $question_title = $question['question_title'] ?? '';
423 $question_des = $question['question_description'] ?? '';
424 $options = $question['options'] ?? [];
425
426 $html_options = '';
427 foreach ( $options as $option ) {
428 $html_options .= sprintf( '<li class="question-option">%s</li>', esc_html( $option ) );
429 }
430
431 $arr_question_components = [
432 'wrap' => '<li class="quiz-question-item">',
433 'title' => sprintf( '<div class="question-title">%s</div>', esc_html( $question_title ) ),
434 'desc' => sprintf( '<div class="question-desc">%s</div>', esc_html( $question_des ) ),
435 'options' => sprintf( '<ul class="course-question-options">%s</ul>', $html_options ),
436 'wrap-end' => '</li>',
437 ];
438
439 $html_questions .= Template::combine_components( $arr_question_components );
440 }
441
442 $arr_quiz_components = [
443 'wrap' => '<div class="course-quiz-item">',
444 'title' => sprintf( '<div class="quiz-title">%s</div>', esc_html( $quiz_title ) ),
445 'des' => sprintf( '<div class="quiz-description">%s</div>', esc_html( $quiz_des ) ),
446 'questions' => sprintf( '<ul class="course-questions">%s</ul>', $html_questions ),
447 'wrap-end' => '</div>',
448 ];
449
450 $html_quizzes .= Template::combine_components( $arr_quiz_components );
451 }
452
453 $arr_section_components = [
454 'wrap' => '<li class="course-section-item">',
455 'title' => sprintf( '<div class="section-title">%s</div>', esc_html( $section_title ) ),
456 'des' => sprintf( '<div class="section-description">%s</div>', esc_html( $section_des ) ),
457 'lessons' => sprintf( '<ul class="course-section-items">%s</ul>', $html_lessons ),
458 'quizzes' => sprintf( '<ul class="course-section-items">%s</ul>', $html_quizzes ),
459 'wrap-end' => '</li>',
460 ];
461
462 $html_section .= Template::combine_components( $arr_section_components );
463 }
464
465 $section = [
466 'wrap' => '<div class="lp-ai-course-data-preview">',
467 'sections' => sprintf( '<ul class="course-sections">%s</ul>', $html_section ),
468 'wrap-end' => '</div>',
469 ];
470
471 return Template::combine_components( $section );
472 }
473 }
474