PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.7
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 / AdminEditWithAITemplate.php

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

972 lines 32.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\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 AdminEditWithAITemplate
15 *
16 * @since 4.2.9
17 * @version 1.1.0
18 */
19 class AdminEditWithAITemplate {
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 public function layout_popup() {
35 try {
36 if ( ! function_exists( 'get_current_screen' ) ) {
37 return;
38 }
39
40 $screen = get_current_screen();
41 $screens = [
42 LP_COURSE_CPT,
43 ];
44 if ( ! $screen || in_array( $screen, $screens ) ) {
45 return;
46 }
47
48 $this->config = Config::instance()->get( 'open-ai-modal', 'settings' );
49 echo $this->html_edit_title_via_ai();
50 echo $this->html_edit_description_via_ai();
51 echo $this->html_edit_image_via_ai();
52 echo $this->html_edit_curriculum_via_ai();
53 } catch ( Throwable $e ) {
54 LP_Debug::error_log( $e );
55 }
56 }
57
58 /**
59 * Render AI templates for frontend contexts (e.g. Course Builder).
60 *
61 * @param array $template_types Supported: title, description, image, curriculum.
62 *
63 * @return string
64 * @since 4.3.0
65 */
66 public function render_for_frontend( array $template_types = [ 'title', 'description' ] ): string {
67 try {
68 $this->config = Config::instance()->get( 'open-ai-modal', 'settings' );
69
70 $template_map = [
71 'title' => 'html_edit_title_via_ai',
72 'description' => 'html_edit_description_via_ai',
73 'image' => 'html_edit_image_via_ai',
74 'curriculum' => 'html_edit_curriculum_via_ai',
75 ];
76
77 $output = '';
78 foreach ( $template_types as $template_type ) {
79 $method = $template_map[ $template_type ] ?? '';
80 if ( ! $method || ! method_exists( $this, $method ) ) {
81 continue;
82 }
83
84 $output .= $this->{$method}();
85 }
86
87 return $output;
88 } catch ( Throwable $e ) {
89 LP_Debug::error_log( $e );
90 }
91
92 return '';
93 }
94
95 /**
96 * HTML generate title with AI.
97 *
98 * @return string
99 */
100 public function html_edit_title_via_ai(): string {
101 $components = [
102 'wrap-script-template' => '<script type="text/template" id="lp-tmpl-edit-title-ai">',
103 'wrap' => '<div class="lp-generate-data-ai-wrap">',
104 'btn-close' =>
105 '<button type="button" class="lp-btn-close-ai-popup">
106 <i class="lp-icon-remove"></i>
107 </button>',
108 'h2' => sprintf(
109 '<div class="content-title">%s</div>',
110 esc_html__( 'Generate Course Title', 'learnpress' )
111 ),
112 'header' => $this->html_title_step_header(),
113 'form' => '<form class="lp-form-generate-data-ai">',
114 'wrap-fields' => '<div class="lp-form-fields">',
115 'step_1' => $this->html_title_step_1(),
116 'step_2' => $this->html_title_step_2(),
117 'step_3' => $this->html_title_step_3(),
118 'step_4' => $this->html_title_step_4(),
119 'wrap-fields-end' => '</div>',
120 'buttons' => sprintf(
121 '<div class="button-actions" data-step="1" data-step-max="4">
122 <button class="btn btn-secondary lp-btn-step lp-hidden"
123 data-step-show="2,3,4"
124 data-action="prev" type="button">&larr; %s
125 </button>
126 <button class="btn btn-primary lp-btn-step"
127 data-step-show="1"
128 data-action="next" type="button">%s &rarr;
129 </button>
130 <button class="lp-button btn-primary lp-btn-generate-prompt lp-hidden"
131 data-step-show="2"
132 data-send="%s" type="button">%s
133 </button>
134 <button class="lp-button btn-primary lp-btn-call-open-ai lp-hidden"
135 data-step-show="3"
136 data-send="%s" type="button">%s
137 </button>
138 </div>',
139 esc_html__( 'Previous', 'learnpress' ),
140 esc_html__( 'Next', 'learnpress' ),
141 Template::convert_data_to_json(
142 [
143 'action' => 'openai_generate_prompt',
144 'lp-prompt-type' => 'course-title', // define type prompt to generate title.
145 'id_url' => 'generate_prompt_openai',
146 ]
147 ),
148 esc_html__( 'Generate Prompt', 'learnpress' ),
149 Template::convert_data_to_json(
150 [
151 'action' => 'openai_generate_data',
152 'lp-prompt-type' => 'course-title', // define type prompt to generate title.
153 'target-apply' => 'set-wp-title', // Click apply to apply title to this field.
154 'id_url' => 'submit_to_openai',
155 ]
156 ),
157 esc_html__( 'Generate Title Course', 'learnpress' ),
158 ),
159 'form-end' => '</form>',
160 'wrap-end' => '</div>',
161 'wrap-script-template-end' => '</script>',
162 ];
163
164 return Template::combine_components( $components );
165 }
166
167 public function html_title_step_header(): string {
168 $components = [
169 'wrap' => '<div class="step-header">',
170 'step_1' => sprintf(
171 '<div class="step-item active" data-step="1"><span class="step-number">1</span><span class="step-text">%s</span></div>',
172 esc_html__( 'Course Goal', 'learnpress' )
173 ),
174 'step_2' => sprintf(
175 '<div class="step-item" data-step="2"><span class="step-number">2</span><span class="step-text">%s</span></div>',
176 esc_html__( 'AI Settings', 'learnpress' )
177 ),
178 'step_3' => sprintf(
179 '<div class="step-item" data-step="3"><span class="step-number">3</span><span class="step-text">%s</span></div>',
180 esc_html__( 'Prompt', 'learnpress' )
181 ),
182 'step_4' => sprintf(
183 '<div class="step-item" data-step="4"><span class="step-number">4</span><span class="step-text">%s</span></div>',
184 esc_html__( 'Result', 'learnpress' )
185 ),
186 'wrap-end' => '</div>',
187 ];
188
189 return Template::combine_components( $components );
190 }
191
192 public function html_title_step_1(): string {
193 $options = $this->config;
194
195 $components = [
196 'step' => '<div class="step-content active" data-step="1">',
197 'title' => sprintf(
198 '<div class="step-title">%s</div>',
199 esc_html__( 'Step 1 — Configure Course Title', 'learnpress' ),
200 ),
201 'description' => sprintf(
202 '<p class="step-description">%s</p>',
203 esc_html__( 'Provide the basic information to generate your course title.', 'learnpress' )
204 ),
205 'describe-topic' => sprintf(
206 '<div class="form-group">
207 <label>%s</label>
208 <textarea type="text" name="topic" placeholder="%s"></textarea>
209 </div>',
210 esc_html__( 'Describe what your course is about', 'learnpress' ),
211 esc_html__( 'Provide a short explanation of the subject or skills your course covers. This helps AI understand the overall direction of your title.', 'learnpress' )
212 ),
213 'describe-goals' => sprintf(
214 '<div class="form-group">
215 <label>%s</label>
216 <textarea type="text" name="goals" placeholder="%s"></textarea>
217 </div>',
218 esc_html__( 'Describe the main goals of your course', 'learnpress' ),
219 esc_html__( 'Summarize what learners will achieve. AI uses this to make the title more accurate and meaningful.', 'learnpress' )
220 ),
221 'length' => sprintf(
222 '<div class="form-group">
223 <label>%s</label>
224 <input type="text" name="length" value="60" />
225 <p class="field-description">%s</p>
226 </div>',
227 esc_html__( 'Title Length (characters)', 'learnpress' ),
228 esc_html__( 'Set the maximum number of characters for the generated course title. Ideal for SEO and platform display constraints.', 'learnpress' )
229 ),
230 'step_close' => '</div>',
231 ];
232
233 return Template::combine_components( $components );
234 }
235
236 public function html_title_step_2(): string {
237 $options = $this->config;
238
239 $components = [
240 'step' => '<div class="step-content" data-step="2">',
241 'title' => sprintf(
242 '<div class="step-title">%s</div>',
243 esc_html__( 'Step 2 — AI Settings', 'learnpress' ),
244 ),
245 'description' => sprintf(
246 '<p class="step-description">%s</p>',
247 esc_html__( 'Configure content quality controls for ChatGPT output.', 'learnpress' )
248 ),
249 'form-grid' => '<div class="form-grid">',
250 'audience' => sprintf(
251 '<div class="form-group">
252 <label>%s</label>%s
253 <p class="field-description">%s</p>
254 </div>',
255 esc_html__( 'Target Audience', 'learnpress' ),
256 AdminTemplate::html_tom_select(
257 [
258 'name' => 'target_audience',
259 'class_name' => '',
260 'options' => $options['audience'] ?? [],
261 'default_value' => 'Students',
262 'multiple' => true,
263 ]
264 ),
265 esc_html__( 'Identifies who will take the course so the content matches their background and skill level.', 'learnpress' ),
266 ),
267 'tone' => sprintf(
268 '<div class="form-group">
269 <label for="swal-tone">%s</label>%s
270 <p class="field-description">%s</p>
271 </div>',
272 esc_html__( 'Tone', 'learnpress' ),
273 AdminTemplate::html_tom_select(
274 [
275 'name' => 'tone',
276 'options' => $options['tone'] ?? [],
277 'multiple' => true,
278 'default_value' => [ 'Analytical' ],
279 ]
280 ),
281 esc_html__( 'Controls the writing style (e.g., friendly, formal, story-telling) so the content matches your brand and audience.', 'learnpress' )
282 ),
283 'language' => sprintf(
284 '<div class="form-group">
285 <label>%s</label>%s
286 <p class="field-description">%s</p>
287 </div>',
288 esc_html__( 'Language', 'learnpress' ),
289 AdminTemplate::html_tom_select(
290 [
291 'name' => 'language',
292 'options' => $options['language'] ?? [],
293 ]
294 ),
295 esc_html__( 'Sets the output language for all generated course content.', 'learnpress' )
296 ),
297 'outputs' => sprintf(
298 '<div class="form-group">
299 <label>%s</label>%s
300 <p class="field-description">%s</p>
301 </div>',
302 esc_html__( 'Outputs', 'learnpress' ),
303 '<input name="outputs" value="2" />',
304 esc_html__( 'Select how many title options the system will generate for you.', 'learnpress' )
305 ),
306 'form-grid-end' => '</div>',
307 'step_close' => '</div>',
308 ];
309
310 return Template::combine_components( $components );
311 }
312
313 public function html_title_step_3(): string {
314 $options = $this->config;
315
316 $components = [
317 'step' => '<div class="step-content" data-step="3">',
318 'title' => sprintf(
319 '<div class="step-title">%s</div>',
320 esc_html__( 'Step 3 — Prompt Generated', 'learnpress' ),
321 ),
322 'prompt' => sprintf(
323 '<div class="form-group">
324 <label>%s</label>%s
325 <i>%s</i>
326 </div>',
327 esc_html__( 'Generated Prompt', 'learnpress' ),
328 '<textarea name="lp-openai-prompt-generated-field"></textarea>',
329 __( 'Shows the auto-generated AI prompt, allowing further adjustments before submission.', 'learnpress' )
330 ),
331 'step_close' => '</div>',
332 ];
333
334 return Template::combine_components( $components );
335 }
336
337 public function html_title_step_4(): string {
338 $options = $this->config;
339
340 $components = [
341 'step' => '<div class="step-content" data-step="4">',
342 'title' => sprintf(
343 '<div class="step-title">%s</div>',
344 esc_html__( 'Step 4 — Result', 'learnpress' ),
345 ),
346 'results' => '<div class="lp-ai-generated-results"></div>',
347 'step_close' => '</div>',
348 ];
349
350 return Template::combine_components( $components );
351 }
352
353 /**
354 * HTML list results openAI returned.
355 *
356 * @param array $args
357 *
358 * @return string
359 */
360 public function html_list_results( array $args ): string {
361 $index = $args['index'] ?? 0;
362 $value = $args['value'] ?? '';
363 // Target is element html to apply value.
364 $target = $args['target-apply'] ?? '';
365
366 $section = [
367 'wrap' => '<div class="lp-ai-generated-result-item form-group">',
368 'label' => sprintf(
369 '<label>%s</label>',
370 sprintf( __( 'Result %d', 'learnpress' ), $index + 1 )
371 ),
372 'textarea' => sprintf(
373 '<textarea class="lp-ai-string-result" cols="3">%s</textarea>',
374 esc_attr( $value )
375 ),
376 'copy_button' => sprintf(
377 '<button class="button lp-btn-copy" data-copy="%s" type="button">%s</button>',
378 esc_attr( $value ),
379 __( 'Copy', 'learnpress' )
380 ),
381 'apply_button' => sprintf(
382 '<button class="button lp-btn-apply button-primary"
383 data-apply="%s" type="button" data-target="%s">%s
384 </button>',
385 esc_attr( $value ),
386 esc_attr( $target ),
387 __( 'Apply', 'learnpress' )
388 ),
389 'wrap_end' => '</div>',
390 ];
391
392 return Template::combine_components( $section );
393 }
394
395 /***************** Description *****************/
396 /**
397 * HTML generate title with AI.
398 *
399 * @return string
400 */
401 public function html_edit_description_via_ai(): string {
402 $components = [
403 'wrap-script-template' => '<script type="text/template" id="lp-tmpl-edit-description-ai">',
404 'wrap' => '<div class="lp-generate-data-ai-wrap">',
405 'btn-close' =>
406 '<button type="button" class="lp-btn-close-ai-popup">
407 <i class="lp-icon-remove"></i>
408 </button>',
409 'h2' => sprintf(
410 '<div class="content-title">%s</div>',
411 esc_html__( 'Generate Course Description', 'learnpress' )
412 ),
413 'header' => $this->html_description_step_header(),
414 'form' => '<form class="lp-form-generate-data-ai">',
415 'wrap-fields' => '<div class="lp-form-fields">',
416 'step_1' => $this->html_description_step_1(),
417 'step_2' => $this->html_description_step_2(),
418 'step_3' => $this->html_description_step_3(),
419 'step_4' => $this->html_description_step_4(),
420 'wrap-fields-end' => '</div>',
421 'buttons' => sprintf(
422 '<div class="button-actions" data-step="1" data-step-max="4">
423 <button class="btn btn-secondary lp-btn-step lp-hidden"
424 data-step-show="2,3,4"
425 data-action="prev" type="button">&larr; %s
426 </button>
427 <button class="btn btn-primary lp-btn-step"
428 data-step-show="1"
429 data-action="next" type="button">%s &rarr;
430 </button>
431 <button class="lp-button btn-primary lp-btn-generate-prompt lp-hidden"
432 data-step-show="2"
433 data-send="%s" type="button">%s
434 </button>
435 <button class="lp-button btn-primary lp-btn-call-open-ai lp-hidden"
436 data-step-show="3"
437 data-send="%s" type="button">%s
438 </button>
439 </div>',
440 esc_html__( 'Previous', 'learnpress' ),
441 esc_html__( 'Next', 'learnpress' ),
442 Template::convert_data_to_json(
443 [
444 'action' => 'openai_generate_prompt',
445 'lp-prompt-type' => 'course-description',
446 'id_url' => 'generate_prompt_openai',
447 ]
448 ),
449 esc_html__( 'Generate Prompt', 'learnpress' ),
450 Template::convert_data_to_json(
451 [
452 'action' => 'openai_generate_data',
453 'lp-prompt-type' => 'course-description',
454 'target-apply' => 'set-wp-editor-content', // Click apply to apply title to this field.
455 'id_url' => 'submit_to_openai',
456 ]
457 ),
458 esc_html__( 'Generate Description Course', 'learnpress' ),
459 ),
460 'form-end' => '</form>',
461 'wrap-end' => '</div>',
462 'wrap-script-template-end' => '</script>',
463 ];
464
465 return Template::combine_components( $components );
466 }
467
468 public function html_description_step_header(): string {
469 $components = [
470 'wrap' => '<div class="step-header">',
471 'step_1' => sprintf(
472 '<div class="step-item active" data-step="1"><span class="step-number">1</span><span class="step-text">%s</span></div>',
473 esc_html__( 'Course Goal', 'learnpress' )
474 ),
475 'step_2' => sprintf(
476 '<div class="step-item" data-step="2"><span class="step-number">2</span><span class="step-text">%s</span></div>',
477 esc_html__( 'AI Settings', 'learnpress' )
478 ),
479 'step_3' => sprintf(
480 '<div class="step-item" data-step="3"><span class="step-number">3</span><span class="step-text">%s</span></div>',
481 esc_html__( 'Prompt', 'learnpress' )
482 ),
483 'step_4' => sprintf(
484 '<div class="step-item" data-step="4"><span class="step-number">4</span><span class="step-text">%s</span></div>',
485 esc_html__( 'Result', 'learnpress' )
486 ),
487 'wrap-end' => '</div>',
488 ];
489
490 return Template::combine_components( $components );
491 }
492
493 public function html_description_step_1(): string {
494 $options = $this->config;
495
496 $components = [
497 'step' => '<div class="step-content active" data-step="1">',
498 'title' => sprintf(
499 '<div class="step-title">%s</div>',
500 esc_html__( 'Step 1 — Configure Course Description', 'learnpress' ),
501 ),
502 'description' => sprintf(
503 '<p class="step-description">%s</p>',
504 esc_html__( 'Provide the information needed to generate your course description.', 'learnpress' )
505 ),
506 'refer-title' => sprintf(
507 '<div class="form-group">
508 <label>%s</label>
509 <input class="title-refer" type="text" name="post-title" readonly />
510 <p class="lp-ai-warning-refer lp-hidden"><i class="lp-icon-warning"></i>%s</p>
511 <p class="field-description">%s</p>
512 </div>',
513 esc_html__( 'Title refer', 'learnpress' ),
514 esc_html__( 'The title refer to generate a relevant course description. Please enter title first', 'learnpress' ),
515 esc_html__( 'The course title is automatically imported from the previous step. It will guide the AI to build a structured curriculum.', 'learnpress' )
516 ),
517 'describe-topic' => sprintf(
518 '<div class="form-group">
519 <label>%s</label>
520 <textarea type="text" name="topic" placeholder="%s"></textarea>
521 </div>',
522 esc_html__( 'Describe what makes this course stand out?', 'learnpress' ),
523 esc_html__( 'Provide the main strengths or unique selling points to help the system build a compelling course description.', 'learnpress' )
524 ),
525 'length' => sprintf(
526 '<div class="form-group">
527 <label>%s</label>
528 <input type="text" name="length" value="1000" />
529 <p class="field-description">%s</p>
530 </div>',
531 esc_html__( 'Description Length (words)', 'learnpress' ),
532 esc_html__( 'Set the maximum number of characters for the generated description.', 'learnpress' )
533 ),
534 'step_close' => '</div>',
535 ];
536
537 return Template::combine_components( $components );
538 }
539
540 public function html_description_step_2(): string {
541 $options = $this->config;
542
543 $components = [
544 'step' => '<div class="step-content" data-step="2">',
545 'title' => sprintf(
546 '<div class="step-title">%s</div>',
547 esc_html__( 'Step 2 — AI Settings', 'learnpress' ),
548 ),
549 'description' => sprintf(
550 '<p class="step-description">%s</p>',
551 esc_html__( 'Configure content quality controls for ChatGPT output.', 'learnpress' )
552 ),
553 'form-grid' => '<div class="form-grid">',
554 'audience' => sprintf(
555 '<div class="form-group">
556 <label>%s</label>%s
557 <p class="field-description">%s</p>
558 </div>',
559 esc_html__( 'Target Audience', 'learnpress' ),
560 AdminTemplate::html_tom_select(
561 [
562 'name' => 'target_audience',
563 'class_name' => '',
564 'options' => $options['audience'] ?? [],
565 'default_value' => 'Students',
566 'multiple' => true,
567 ]
568 ),
569 esc_html__( 'Identifies who will take the course so the content matches their background and skill level.', 'learnpress' ),
570 ),
571 'tone' => sprintf(
572 '<div class="form-group">
573 <label for="swal-tone">%s</label>%s
574 <p class="field-description">%s</p>
575 </div>',
576 esc_html__( 'Tone', 'learnpress' ),
577 AdminTemplate::html_tom_select(
578 [
579 'name' => 'tone',
580 'options' => $options['tone'] ?? [],
581 'multiple' => true,
582 'default_value' => [ 'Analytical' ],
583 ]
584 ),
585 esc_html__( 'Controls the writing style (e.g., friendly, formal, story-telling) so the content matches your brand and audience.', 'learnpress' )
586 ),
587 'language' => sprintf(
588 '<div class="form-group">
589 <label>%s</label>%s
590 <p class="field-description">%s</p>
591 </div>',
592 esc_html__( 'Language', 'learnpress' ),
593 AdminTemplate::html_tom_select(
594 [
595 'name' => 'language',
596 'options' => $options['language'] ?? [],
597 ]
598 ),
599 esc_html__( 'Sets the output language for all generated course content.', 'learnpress' )
600 ),
601 'outputs' => sprintf(
602 '<div class="form-group">
603 <label>%s</label>%s
604 </div>',
605 esc_html__( 'Outputs', 'learnpress' ),
606 '<input name="outputs" value="2" />'
607 ),
608 'form-grid-end' => '</div>',
609 'step_close' => '</div>',
610 ];
611
612 return Template::combine_components( $components );
613 }
614
615 public function html_description_step_3(): string {
616 $options = $this->config;
617
618 $components = [
619 'step' => '<div class="step-content" data-step="3">',
620 'title' => sprintf(
621 '<div class="step-title">%s</div>',
622 esc_html__( 'Step 3 — Prompt Generated', 'learnpress' ),
623 ),
624 'prompt' => sprintf(
625 '<div class="form-group">
626 <label>%s</label>%s
627 <i>%s</i>
628 </div>',
629 esc_html__( 'Generated Prompt', 'learnpress' ),
630 '<textarea name="lp-openai-prompt-generated-field"></textarea>',
631 __( 'Shows the auto-generated AI prompt, allowing further adjustments before submission.', 'learnpress' )
632 ),
633 'step_close' => '</div>',
634 ];
635
636 return Template::combine_components( $components );
637 }
638
639 public function html_description_step_4(): string {
640 $options = $this->config;
641
642 $components = [
643 'step' => '<div class="step-content" data-step="4">',
644 'title' => sprintf(
645 '<div class="step-title">%s</div>',
646 esc_html__( 'Step 4 — Result', 'learnpress' ),
647 ),
648 'results' => '<div class="lp-ai-generated-results"></div>',
649 'step_close' => '</div>',
650 ];
651
652 return Template::combine_components( $components );
653 }
654
655 /***************** Image *****************/
656 public function html_edit_image_via_ai(): string {
657 $components = [
658 'wrap-script-template' => '<script type="text/template" id="lp-tmpl-edit-image-ai">',
659 'wrap' => '<div class="lp-generate-data-ai-wrap">',
660 'btn-close' =>
661 '<button type="button" class="lp-btn-close-ai-popup">
662 <i class="lp-icon-remove"></i>
663 </button>',
664 'h2' => sprintf(
665 '<div class="content-title">%s</div>',
666 esc_html__( 'Generate Course Image', 'learnpress' )
667 ),
668 'header' => $this->html_image_step_header(), // You can add header if needed.
669 'form' => '<form class="lp-form-generate-data-ai">',
670 'wrap-fields' => '<div class="lp-form-fields">',
671 'step-1' => $this->html_image_step_1(),
672 'step-2' => $this->html_image_step_2(),
673 'step-3' => $this->html_image_step_3(),
674 'wrap-fields-end' => '</div>',
675 'buttons' => sprintf(
676 '<div class="button-actions" data-step="1" data-step-max="3">
677 <button class="btn btn-secondary lp-btn-step lp-hidden"
678 data-step-show="2,3"
679 data-action="prev" type="button">&larr; %s
680 </button>
681 <button class="btn btn-primary lp-btn-step lp-hidden"
682 data-step-show="0"
683 data-action="next" type="button">%s &rarr;
684 </button>
685 <button class="lp-button btn-primary lp-btn-generate-prompt"
686 data-step-show="1"
687 data-send="%s" type="button">%s
688 </button>
689 <button class="lp-button btn-primary lp-btn-call-open-ai lp-hidden"
690 data-step-show="2"
691 data-send="%s" type="button">%s
692 </button>
693 </div>',
694 esc_html__( 'Previous', 'learnpress' ),
695 esc_html__( 'Next', 'learnpress' ),
696 Template::convert_data_to_json(
697 [
698 'action' => 'openai_generate_prompt',
699 'lp-prompt-type' => 'course-image',
700 'id_url' => 'generate_prompt_openai',
701 ]
702 ),
703 esc_html__( 'Generate Prompt', 'learnpress' ),
704 Template::convert_data_to_json(
705 [
706 'action' => 'openai_generate_image',
707 'lp-prompt-type' => 'course-image',
708 'target-apply' => 'set-wp-editor-content', // Click apply to apply title to this field.
709 'id_url' => 'submit_to_openai',
710 ]
711 ),
712 esc_html__( 'Generate Image Course', 'learnpress' ),
713 ),
714 'post-id' => sprintf(
715 '<input type="hidden" name="post-id" value="%d" />',
716 get_the_ID()
717 ),
718 'form-end' => '</form>',
719 'wrap-end' => '</div>',
720 'wrap-script-template-end' => '</script>',
721 ];
722
723 return Template::combine_components( $components );
724 }
725
726 public function html_image_step_header(): string {
727 $components = [
728 'wrap' => '<div class="step-header">',
729 'step_1' => sprintf(
730 '<div class="step-item active" data-step="1"><span class="step-number">1</span><span class="step-text">%s</span></div>',
731 esc_html__( 'Course Image config', 'learnpress' )
732 ),
733 'step_2' => sprintf(
734 '<div class="step-item" data-step="2"><span class="step-number">2</span><span class="step-text">%s</span></div>',
735 esc_html__( 'Prompt', 'learnpress' )
736 ),
737 'step_3' => sprintf(
738 '<div class="step-item" data-step="3"><span class="step-number">3</span><span class="step-text">%s</span></div>',
739 esc_html__( 'Result', 'learnpress' )
740 ),
741 'wrap-end' => '</div>',
742 ];
743
744 return Template::combine_components( $components );
745 }
746
747 public function html_image_step_1(): string {
748 $model_type = LP_Settings::instance()->get( 'open_ai_image_model_type' );
749 $options = $this->config;
750 $size_opts = $options[ "image-size-$model_type" ] ?? [];
751 $quality_opts = $options[ "image-quality-$model_type" ] ?? $options['image-quality'] ?? [];
752
753 $components = [
754 'step' => '<div class="step-content active" data-step="1">',
755 'title' => sprintf(
756 '<div class="step-title">%s</div>',
757 esc_html__( 'Step 1 — Config Image', 'learnpress' ),
758 ),
759 'description' => sprintf(
760 '<p class="step-description">%s</p>',
761 esc_html__( 'Config your image you want, data will refer course title, course description to generate image.', 'learnpress' )
762 ),
763 'from-title' => sprintf(
764 '<div class="form-group">
765 <label>%s</label>
766 <input class="title-refer" type="text" name="post-title" readonly />
767 <p class="lp-ai-warning-refer lp-hidden"><i class="lp-icon-warning"></i>%s</p>
768 <p class="field-description">%s</p>
769 </div>',
770 esc_html__( 'Title Refer', 'learnpress' ),
771 esc_html__( 'The title refer to generate a relevant course image. Please enter title first', 'learnpress' ),
772 esc_html__( 'The current course title that will be used as reference during image generation.', 'learnpress' )
773 ),
774 'goal' => sprintf(
775 '<div class="form-group">
776 <label>%s</label>
777 <textarea type="text" name="goal" placeholder="%s"></textarea>
778 </div>',
779 esc_html__( 'Goal', 'learnpress' ),
780 esc_html__( 'A brief description of the image you want to generate.', 'learnpress' )
781 ),
782 'form-grid' => '<div class="form-grid">',
783 'style' => sprintf(
784 '<div class="form-group">
785 <label>%s</label>
786 %s
787 <p class="field-description">%s</p>
788 </div>',
789 esc_html__( 'Style', 'learnpress' ),
790 AdminTemplate::html_tom_select(
791 [
792 'name' => 'style',
793 'options' => $options['image-style'] ?? [],
794 'default_value' => 'Realistic',
795 ]
796 ),
797 esc_html__( 'Select the visual style such as modern, minimalist, illustration, 3D, etc.', 'learnpress' )
798 ),
799 /*'write-requirement' => sprintf(
800 '<div class="form-group">
801 <label>%s</label>
802 <input type="text" name="topic" placeholder="%s" />
803 <p class="field-description">%s</p>
804 </div>',
805 esc_html__( 'Images or icons should be include', 'learnpress' ),
806 esc_html__( 'e.g., books, laptop, graduation cap', 'learnpress' ),
807 esc_html__( 'List the specific elements or icons that should appear in the generated image.', 'learnpress' )
808 ),*/
809 'size' => sprintf(
810 '<div class="form-group">
811 <label>%s</label>
812 %s
813 <p class="field-description">%s</p>
814 </div>',
815 esc_html__( 'Size', 'learnpress' ),
816 AdminTemplate::html_tom_select(
817 [
818 'name' => 'size',
819 'options' => $size_opts,
820 ]
821 ),
822 esc_html__( 'Set the output.', 'learnpress' )
823 ),
824 'quality' => sprintf(
825 '<div class="form-group">
826 <label>%s</label>
827 %s
828 <p class="field-description">%s</p>
829 </div>',
830 esc_html__( 'Quality', 'learnpress' ),
831 AdminTemplate::html_tom_select(
832 [
833 'name' => 'quality',
834 'options' => $quality_opts,
835 ]
836 ),
837 esc_html__( 'Select the desired image quality such as standard, high, or premium.', 'learnpress' )
838 ),
839 'outputs' => sprintf(
840 '<div class="form-group">
841 <label>%s</label>
842 <input name="outputs" value="2" type="number" />
843 <p class="field-description">%s</p>
844 </div>',
845 esc_html__( 'Outputs', 'learnpress' ),
846 esc_html__( 'Number of images you want the system to generate (model dall-e-3 only 1 supported).', 'learnpress' )
847 ),
848 'form-grid-end' => '</div>',
849 'step_close' => '</div>',
850 ];
851
852 return Template::combine_components( $components );
853 }
854
855 public function html_image_step_2(): string {
856 $options = $this->config;
857
858 $components = [
859 'step' => '<div class="step-content" data-step="2">',
860 'title' => sprintf(
861 '<div class="step-title">%s</div>',
862 esc_html__( 'Step 2 — Prompt Generated', 'learnpress' ),
863 ),
864 'prompt' => sprintf(
865 '<div class="form-group">
866 <label>%s</label>%s
867 <i>%s</i>
868 </div>',
869 esc_html__( 'Generated Prompt', 'learnpress' ),
870 '<textarea name="lp-openai-prompt-generated-field"></textarea>',
871 __( 'Shows the auto-generated AI prompt, allowing further adjustments before submission.', 'learnpress' )
872 ),
873 'step_close' => '</div>',
874 ];
875
876 return Template::combine_components( $components );
877 }
878
879 public function html_image_step_3(): string {
880 $options = $this->config;
881
882 $components = [
883 'step' => '<div class="step-content" data-step="3">',
884 'title' => sprintf(
885 '<div class="step-title">%s</div>',
886 esc_html__( 'Step 3 — Result', 'learnpress' ),
887 ),
888 'description' => sprintf(
889 '<p class="step-description">%s</p>',
890 esc_html__( 'Note: when applying an image, the process can be very slow (about 1 minute or more), depends on the image size. Please wait until it finishes.', 'learnpress' )
891 ),
892 'results' => '<div class="lp-ai-generated-results"></div>',
893 'step_close' => '</div>',
894 ];
895
896 return Template::combine_components( $components );
897 }
898
899 public function html_feature_image_created( $args ): string {
900 $src = $args['src'] ?? '';
901 $post_id = $args['post-id'] ?? '';
902 $attachment_id = $args['attachment-id'] ?? '';
903
904 $section = [
905 'wrap' => '<div class="inside">',
906 'preview' => sprintf(
907 '<p class="hide-if-no-js">
908 <a href="%s" id="set-post-thumbnail" aria-describedby="set-post-thumbnail-desc" class="thickbox">
909 <img width="266" height="266" src="%s" alt="" />
910 </a>
911 </p>',
912 admin_url( "media-upload.php?post_id=$post_id&amp;type=image&amp;TB_iframe=1" ),
913 $src
914 ),
915 'desc' => '<p class="hide-if-no-js howto" id="set-post-thumbnail-desc">Click the image to edit or update</p>',
916 'remove' => sprintf(
917 '<p class="hide-if-no-js"><a href="#" id="remove-post-thumbnail">%s</a></p>',
918 __( 'Remove featured image' )
919 ),
920 'input' => sprintf(
921 '<input type="hidden" id="_thumbnail_id" name="_thumbnail_id" value="%d" />',
922 $attachment_id
923 ),
924 'wrap_end' => '</div>',
925 ];
926
927 return Template::combine_components( $section );
928 }
929
930 /***************** Curriculum *****************/
931 public function html_edit_curriculum_via_ai(): string {
932 $components = [
933 'wrap-script-template' => '<script type="text/template" id="lp-tmpl-edit-curriculum-ai">',
934 'wrap' => '<div class="lp-generate-data-ai-wrap">',
935 'h2' => sprintf(
936 '<div class="content-title">%s</div>',
937 esc_html__( 'Generate Course Curriculum', 'learnpress' )
938 ),
939 'header' => '', // You can add header if needed.
940 'form' => '<form class="lp-form-generate-data-ai">',
941 'wrap-fields' => '<div class="lp-form-fields">',
942 // Add steps for curriculum generation here.
943 'wrap-fields-end' => '</div>',
944 'buttons' => sprintf(
945 '<div class="button-actions" data-step="1" data-step-max="1">
946 <button class="lp-button btn-primary lp-btn-call-open-ai lp-hidden"
947 data-send="%s" type="button">%s
948 </button>
949 </div>',
950 Template::convert_data_to_json(
951 [
952 'action' => 'openai_generate_data',
953 'lp-prompt-type' => 'course-curriculum',
954 'target-apply' => 'set-course-curriculum', // Click apply to apply curriculum to this field.
955 'id_url' => 'submit_to_openai',
956 ]
957 ),
958 esc_html__( 'Generate Course Curriculum', 'learnpress' ),
959 ),
960 'post-id' => sprintf(
961 '<input type="hidden" name="post-id" value="%d" />',
962 get_the_ID()
963 ),
964 'form-end' => '</form>',
965 'wrap-end' => '</div>',
966 'wrap-script-template-end' => '</script>',
967 ];
968
969 return Template::combine_components( $components );
970 }
971 }
972