PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.1
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 / TemplateHooks / Course / AdminEditSettingTemplate.php

AdminEditSettingTemplate.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.1, at inc/TemplateHooks/Course/AdminEditSettingTemplate.php

693 lines 21.4 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\Course;
4
5 use LearnPress\Helpers\Config;
6 use LearnPress\Helpers\Singleton;
7 use LearnPress\Helpers\Template;
8 use LearnPress\Models\CourseModel;
9 use LearnPress\Models\CoursePostModel;
10 use LearnPress\Models\QuizPostModel;
11 use LP_Database;
12 use LP_Meta_Box_Checkbox_Field;
13 use LP_Meta_Box_Course;
14 use LP_Meta_Box_Date_Field;
15 use LP_Meta_Box_Duration_Field;
16 use LP_Meta_Box_Extra_Faq_Field;
17 use LP_Meta_Box_Extra_Field;
18 use LP_Meta_Box_Field;
19 use LP_Meta_Box_Material_Fields;
20 use LP_Meta_Box_Radio_Field;
21 use LP_Meta_Box_Select_Field;
22 use LP_Meta_Box_Text_Field;
23 use LP_Meta_Box_Textarea_Field;
24 use WP_Post;
25 use WP_User;
26
27 /**
28 * Template hooks Admin Edit Course Settings.
29 *
30 * @since 4.3.0
31 * @version 1.0.0
32 */
33 class AdminEditSettingTemplate {
34 use Singleton;
35
36 public function init() {
37 add_action( 'learn-press/admin/course/edit-setting/layout', [ $this, 'render_settings' ] );
38 // add_filter( 'lp/rest/ajax/allow_callback', [ $this, 'allow_callback' ] );
39 }
40
41
42 /**
43 * Render edit course settings html.
44 *
45 * @param int $post_id
46 *
47 * @return string
48 */
49 public static function render_settings( int $post_id = 0 ) {
50 if ( ! $post_id ) {
51 global $post;
52 $post_id = $post->ID;
53 }
54
55 wp_enqueue_style( 'lp-edit-curriculum' );
56 wp_enqueue_script( 'lp-edit-course' );
57
58 echo self::instance()->html_course_settings( $post_id );
59 }
60
61 /**
62 * HTML for course settings metabox.
63 *
64 * @param int $post_id
65 *
66 * @return string
67 */
68 public function html_course_settings( int $post_id ): string {
69 $tabs_data = LP_Meta_Box_Course::instance()->metabox( $post_id );
70 $nav_items = '';
71 $panels = '';
72
73 foreach ( $tabs_data as $key => $tab ) {
74 if ( $key === 'author' && ! is_super_admin() ) {
75 continue;
76 }
77
78 $class_tab = isset( $tab['class'] ) ? implode( ' ', (array) $tab['class'] ) : '';
79 $icon = isset( $tab['icon'] ) ? sprintf( '<i class="%s"></i>', esc_attr( $tab['icon'] ) ) : '';
80
81 $nav_items .= sprintf(
82 '<li class="%s_options %s_tab %s"><a href="#%s">%s<span>%s</span></a></li>',
83 esc_attr( $key ),
84 esc_attr( $key ),
85 esc_attr( $class_tab ),
86 esc_attr( $tab['target'] ),
87 $icon,
88 esc_html( $tab['label'] )
89 );
90
91 if ( isset( $tab['content'] ) ) {
92 ob_start();
93 do_action( 'learnpress/course-settings/before-' . $key );
94
95 foreach ( $tab['content'] as $meta_key => $object ) {
96 if ( is_a( $object, LP_Meta_Box_Field::class ) ) {
97 $object->id = $meta_key;
98 $output = $object->output( $post_id );
99 if ( ! empty( $output ) ) {
100 echo wp_kses_post( $output );
101 }
102 }
103 }
104
105 do_action( 'learnpress/course-settings/after-' . $key );
106 $panel_html = ob_get_clean();
107
108 $panels .= sprintf(
109 '<div id="%s" class="lp-meta-box-course-panels">%s</div>',
110 esc_attr( $tab['target'] ),
111 $panel_html
112 );
113 }
114 }
115
116 $wrapper = [
117 'wrap' => '<div class="lp-meta-box lp-meta-box--course"><div class="lp-meta-box__inner"><div class="lp-meta-box__course-tab">',
118 'ul_tabs' => '<ul class="lp-meta-box__course-tab__tabs">' . $nav_items . '</ul>',
119 'content_div' => '<div class="lp-meta-box__course-tab__content">',
120 'panels' => $panels,
121 'hook_cb' => $this->capture_course_builder_hook_content( $post_id ),
122 'hook_extra' => $this->capture_hook_content( 'lp_course_data_setting_tab_content', $post_id ),
123 'content_end' => '</div>',
124 'inner_end' => '</div></div></div>',
125 ];
126
127 return Template::combine_components( $wrapper );
128 }
129
130 /**
131 * Helper to capture do_action output
132 *
133 * @param string $hook
134 * @param int $post_id
135 * @param bool $allow_course_builder_context
136 *
137 * @return string
138 */
139 private function capture_hook_content( string $hook, int $post_id, bool $allow_course_builder_context = false ): string {
140 if ( ! $allow_course_builder_context && $this->is_course_builder_context() ) {
141 return '';
142 }
143
144 ob_start();
145 $post = get_post( $post_id );
146 do_action( $hook, $post );
147 return ob_get_clean();
148 }
149
150 /**
151 * Render Course Builder-only hook content for course settings.
152 * This keeps admin behavior unchanged while exposing a safe extension point for builder.
153 *
154 * @param int $post_id
155 *
156 * @return string
157 */
158 private function capture_course_builder_hook_content( int $post_id ): string {
159 if ( ! $this->is_course_builder_context() ) {
160 return '';
161 }
162
163 return $this->capture_hook_content(
164 'learn-press/course-builder/edit-course/settings/tab/content',
165 $post_id,
166 true
167 );
168 }
169
170 /**
171 * Check current request is Course Builder page.
172 *
173 * @return bool
174 */
175 private function is_course_builder_context(): bool {
176 if ( ! class_exists( '\\LP_Page_Controller' ) ) {
177 return false;
178 }
179
180 return \LP_Page_Controller::is_page_course_builder();
181 }
182
183 public function tab_general( $post_id ) {
184 $course = CourseModel::find( $post_id, true );
185 $repurchase_option_desc = sprintf(
186 '1. %s',
187 __(
188 'Reset course progress: The course progress and results of student will be removed.',
189 'learnpress'
190 )
191 );
192 $repurchase_option_desc .= '<br/>' . sprintf(
193 '2. %s',
194 __(
195 'Keep course progress: The course progress and results of student will remain.',
196 'learnpress'
197 )
198 );
199 $repurchase_option_desc .= '<br/>' . sprintf(
200 '3. %s',
201 __(
202 'Open popup: The student can decide whether their course progress will be reset with the confirm popup.',
203 'learnpress'
204 )
205 );
206 $max_students_desc = esc_html__(
207 'The maximum number of students that can join a course. Set 0 for unlimited.',
208 'learnpress'
209 );
210 $max_students_desc .= '<br/>' . esc_html__( 'Not apply for case "No enroll requirement".', 'learnpress' );
211
212 $is_enable_allow_course_repurchase = false;
213 if ( $course instanceof CourseModel ) {
214 $is_enable_allow_course_repurchase = $course->get_meta_value_by_key( CoursePostModel::META_KEY_ALLOW_COURSE_REPURCHASE, 'no' ) === 'yes';
215 }
216
217 $fake_students_desc = esc_html__( 'Fake students enrolled for the course.', 'learnpress' );
218 $fake_students_desc .= '<br>' . esc_html__( 'It only to display, not calculate', 'learnpress' );
219
220 return apply_filters(
221 'lp/course/meta-box/fields/general',
222 array(
223 '_lp_duration' => new LP_Meta_Box_Duration_Field(
224 esc_html__( 'Duration', 'learnpress' ),
225 esc_html__( 'Set to 0 for the lifetime access.', 'learnpress' ),
226 '10 week',
227 array(
228 'default_time' => 'week',
229 'custom_attributes' => array(
230 'min' => '0',
231 'step' => '1',
232 ),
233 )
234 ),
235 '_lp_block_expire_duration' => new LP_Meta_Box_Checkbox_Field(
236 esc_html__( 'Block content', 'learnpress' ),
237 esc_html__( 'When the duration expires, the course is blocked.', 'learnpress' ),
238 'no'
239 ),
240 '_lp_block_finished' => new LP_Meta_Box_Checkbox_Field(
241 '',
242 esc_html__( 'Block the course after the student finished this course.', 'learnpress' ),
243 'yes'
244 ),
245 '_lp_allow_course_repurchase' => new LP_Meta_Box_Checkbox_Field(
246 __( 'Allow Repurchase', 'learnpress' ),
247 esc_html__( 'Allow users to repurchase this course after it has been finished or blocked (Do not apply to free courses or Create Order manual).', 'learnpress' ),
248 'no'
249 ),
250 '_lp_course_repurchase_option' => new LP_Meta_Box_Select_Field(
251 esc_html__( 'Repurchase action', 'learnpress' ),
252 $repurchase_option_desc,
253 'reset',
254 array(
255 'options' => array(
256 'reset' => esc_html__( 'Reset course progress', 'learnpress' ),
257 'keep' => esc_html__( 'Keep course progress', 'learnpress' ),
258 'popup' => esc_html__( 'Open popup', 'learnpress' ),
259 ),
260 'dependency' => [
261 'name' => '_lp_allow_course_repurchase',
262 'is_disable' => ! $is_enable_allow_course_repurchase,
263 ],
264 )
265 ),
266 '_lp_level' => new LP_Meta_Box_Select_Field(
267 esc_html__( 'Level', 'learnpress' ),
268 esc_html__( 'Choose a difficulty level.', 'learnpress' ),
269 'all',
270 array(
271 'options' => lp_course_level(),
272 )
273 ),
274 '_lp_students' => new LP_Meta_Box_Text_Field(
275 esc_html__( 'Fake Students Enrolled', 'learnpress' ),
276 $fake_students_desc,
277 0,
278 array(
279 'type_input' => 'number',
280 'custom_attributes' => array(
281 'min' => '0',
282 'step' => '1',
283 ),
284 'style' => 'width: 70px;',
285 )
286 ),
287 '_lp_max_students' => new LP_Meta_Box_Text_Field(
288 esc_html__( 'Max student', 'learnpress' ),
289 $max_students_desc,
290 0,
291 array(
292 'type_input' => 'number',
293 'custom_attributes' => array(
294 'min' => '0',
295 'step' => '1',
296 ),
297 'style' => 'width: 70px;',
298 )
299 ),
300 '_lp_retake_count' => new LP_Meta_Box_Text_Field(
301 esc_html__( 'Re-take Course', 'learnpress' ),
302 esc_html__( 'The number of times a user can learn again from this course. To disable, set to 0.', 'learnpress' ),
303 0,
304 array(
305 'type_input' => 'number',
306 'custom_attributes' => array(
307 'min' => '0',
308 'step' => '1',
309 ),
310 'style' => 'width: 70px;',
311 )
312 ),
313 '_lp_has_finish' => new LP_Meta_Box_Checkbox_Field(
314 esc_html__( 'Finish button', 'learnpress' ),
315 esc_html__( 'Allow showing the finish button when the student has completed all items but has not passed the course assessment yet.', 'learnpress' ),
316 'yes'
317 ),
318 '_lp_featured' => new LP_Meta_Box_Checkbox_Field(
319 esc_html__( 'Featured list', 'learnpress' ),
320 esc_html__( 'Add the course to the Featured List.', 'learnpress' ),
321 'no'
322 ),
323 '_lp_featured_review' => new LP_Meta_Box_Textarea_Field(
324 esc_html__( 'Featured review', 'learnpress' ),
325 esc_html__( 'A good review to promote the course.', 'learnpress' )
326 ),
327 '_lp_external_link_buy_course' => new LP_Meta_Box_Text_Field(
328 esc_html__( 'External link', 'learnpress' ),
329 esc_html__( 'Normally used for offline classes. Ex: link to a contact page. Format: https://google.com', 'learnpress' ),
330 '',
331 array(
332 'desc_tip' => 'You can apply for case: user register form.<br> You accept for user can learn courses by add manual order on backend',
333 )
334 ),
335 ),
336 $post_id
337 );
338 }
339
340 public function tab_offline( $post_id ): array {
341 $course = CourseModel::find( $post_id, true );
342
343 $is_offline_course = false;
344 if ( $course instanceof CourseModel ) {
345 $is_offline_course = $course->is_offline();
346 }
347
348 return apply_filters(
349 'lp/course/meta-box/fields/offline',
350 array(
351 CoursePostModel::META_KEY_OFFLINE_COURSE => new LP_Meta_Box_Checkbox_Field(
352 esc_html__( 'Enable offline course', 'learnpress' ),
353 esc_html__(
354 'When you enable the offline course feature, the system will disable certain online course functions, such as curriculum, finish button, re-take course, block content, repurchase. After checking the checkbox, make sure to click the "Update" button to apply the changes successfully.',
355 'learnpress'
356 ),
357 'no'
358 ),
359 CoursePostModel::META_KEY_OFFLINE_LESSON_COUNT => new LP_Meta_Box_Text_Field(
360 esc_html__( 'Lessons', 'learnpress' ),
361 esc_html__( 'Total lessons of the course.', 'learnpress' ),
362 10,
363 [
364 'type_input' => 'number',
365 'custom_attributes' => array(
366 'min' => '0',
367 'step' => '1',
368 ),
369 'dependency' => [
370 'name' => '_lp_offline_course',
371 'is_disable' => ! $is_offline_course,
372 ],
373 ]
374 ),
375 CoursePostModel::META_KEY_DELIVER => new LP_Meta_Box_Select_Field(
376 esc_html__( 'Delivery Type', 'learnpress' ),
377 esc_html__( 'How your content is conveyed to students.', 'learnpress' ),
378 'private_1_1',
379 [
380 'options' => Config::instance()->get( 'course-deliver-type' ),
381 'dependency' => [
382 'name' => '_lp_offline_course',
383 'is_disable' => ! $is_offline_course,
384 ],
385 ]
386 ),
387 CoursePostModel::META_KEY_ADDRESS => new LP_Meta_Box_Text_Field(
388 esc_html__( 'Address', 'learnpress' ),
389 esc_html__( 'You can enter the physical address of your class or specify the meeting method (e.g., Zoom, Google Meet, etc.).', 'learnpress' ),
390 '',
391 [
392 'dependency' => [
393 'name' => '_lp_offline_course',
394 'is_disable' => ! $is_offline_course,
395 ],
396 ]
397 ),
398 ),
399 $post_id
400 );
401 }
402
403 public function tab_price( $post_id ): array {
404 $key_exists = LP_Database::getInstance()->check_key_postmeta_exists( $post_id, '_lp_regular_price' );
405 $price = get_post_meta( $post_id, '_lp_price', true );
406 $regular_price = $key_exists ? get_post_meta( $post_id, '_lp_regular_price', true ) : $price;
407 $sale_price = get_post_meta( $post_id, '_lp_sale_price', true );
408
409 $is_enable_no_required_enroll = get_post_meta( $post_id, '_lp_no_required_enroll', true ) === 'yes' ? 1 : 0;
410
411 return apply_filters(
412 'lp/course/meta-box/fields/price',
413 array(
414 '_lp_regular_price' => new LP_Meta_Box_Text_Field(
415 esc_html__( 'Regular price', 'learnpress' ),
416 sprintf( __( 'Set a regular price (<strong>%s</strong>). Leave it blank for <strong>Free</strong>.', 'learnpress' ), learn_press_get_currency() ),
417 $regular_price,
418 array(
419 'type_input' => 'text',
420 'custom_attributes' => array(
421 'min' => '0',
422 'step' => '0.01',
423 ),
424 'style' => 'width: 150px;',
425 'class' => 'lp_meta_box_regular_price',
426 'dependency' => [
427 'name' => '_lp_no_required_enroll',
428 'is_disable' => $is_enable_no_required_enroll,
429 ],
430 )
431 ),
432 '_lp_sale_price' => new LP_Meta_Box_Text_Field(
433 esc_html__( 'Sale price', 'learnpress' ),
434 '<a href="#" class="lp_sale_price_schedule">' . esc_html__( 'Schedule', 'learnpress' ) . '</a>',
435 $sale_price,
436 array(
437 'type_input' => 'text',
438 'custom_attributes' => array(
439 'min' => '0',
440 'step' => '0.01',
441 ),
442 'style' => 'width: 150px;',
443 'class' => 'lp_meta_box_sale_price',
444 'dependency' => [
445 'name' => '_lp_no_required_enroll',
446 'is_disable' => $is_enable_no_required_enroll,
447 ],
448 )
449 ),
450 '_lp_sale_start' => new LP_Meta_Box_Date_Field(
451 esc_html__( 'Sale start dates', 'learnpress' ),
452 '',
453 '',
454 array(
455 'wrapper_class' => 'lp_sale_start_dates_fields',
456 'placeholder' => _x( 'From&hellip;', 'placeholder', 'learnpress' ),
457 'dependency' => [
458 'name' => '_lp_no_required_enroll',
459 'is_disable' => $is_enable_no_required_enroll,
460 ],
461 )
462 ),
463 '_lp_sale_end' => new LP_Meta_Box_Date_Field(
464 esc_html__( 'Sale end dates', 'learnpress' ),
465 '',
466 '',
467 array(
468 'wrapper_class' => 'lp_sale_end_dates_fields',
469 'placeholder' => _x( 'To&hellip;', 'placeholder', 'learnpress' ),
470 'cancel' => true,
471 'dependency' => [
472 'name' => '_lp_no_required_enroll',
473 'is_disable' => $is_enable_no_required_enroll,
474 ],
475 )
476 ),
477 '_lp_price_prefix' => new LP_Meta_Box_Text_Field(
478 esc_html__( 'Price prefix', 'learnpress' ),
479 esc_html__( 'Show additional information placed before the price such as: Only, From, Up to...', 'learnpress' ),
480 ''
481 ),
482 '_lp_price_suffix' => new LP_Meta_Box_Text_Field(
483 esc_html__( 'Price Suffix', 'learnpress' ),
484 esc_html__( 'Show additional information placed after the price such as: Included Tax, Per Hour, (Per Week)...', 'learnpress' ),
485 ''
486 ),
487 '_lp_no_required_enroll' => new LP_Meta_Box_Checkbox_Field(
488 esc_html__( 'There is no enrollment requirement', 'learnpress' ),
489 esc_html__( 'Students can see the content of all course items and take the quiz without logging in.', 'learnpress' ),
490 'no'
491 ),
492 ),
493 $post_id
494 );
495 }
496
497 public function tab_author( $thepostid ) {
498 $post = get_post( $thepostid );
499
500 $author_id = $post ? $post->post_author : get_current_user_id();
501
502 $options = array();
503 // Code old only use for addon Frontend Editor v4.0.4
504 // Code old only use for addon Co-Instructor v4.0.2
505 $can_get_options_users = false;
506 if ( class_exists( 'LP_Addon_Frontend_Editor_Preload' )
507 && defined( 'LP_ADDON_FRONTEND_EDITOR_VER' )
508 && version_compare( LP_ADDON_FRONTEND_EDITOR_VER, '4.0.5', '<' ) ) {
509 $can_get_options_users = true;
510 }
511
512 if ( $can_get_options_users ) {
513 $author_roles = array( ADMIN_ROLE, LP_TEACHER_ROLE );
514 $author_roles = apply_filters( 'learn_press_course_author_role_meta_box', $author_roles );
515 $authors = get_users( [ 'role__in' => $author_roles ] );
516
517 /**
518 * @var WP_User $author
519 */
520 foreach ( $authors as $author ) {
521 $options[ $author->ID ] = $author->display_name . ' (#' . $author->ID . ')';
522 }
523 }
524 // Code old only use for addon Frontend Editor v4.0.4
525
526 $data_struct = [
527 'urlApi' => get_rest_url( null, 'lp/v1/admin/tools/search-user' ),
528 'dataSendApi' => [
529 'role_in' => ADMIN_ROLE . ',' . LP_TEACHER_ROLE,
530 ],
531 'dataType' => 'users',
532 'keyGetValue' => [
533 'value' => 'ID',
534 'text' => '{{display_name}}(#{{ID}})',
535 'key_render' => [
536 'display_name' => 'display_name',
537 'user_email' => 'user_email',
538 'ID' => 'ID',
539 ],
540 ],
541 'setting' => [
542 'plugins' => array(),
543 ],
544 ];
545
546 return apply_filters(
547 'lp/course/meta-box/fields/author',
548 array(
549 // Not use key 'post_author' on single edit course, it special key of WP, Gutenberg save will not submit this key.
550 '_post_author' => new LP_Meta_Box_Select_Field(
551 esc_html__( 'Author', 'learnpress' ),
552 '',
553 $author_id,
554 array(
555 'options' => $options,
556 'style' => 'min-width:200px;',
557 'tom_select' => true,
558 'custom_attributes' => [ 'data-struct' => htmlentities2( json_encode( $data_struct ) ) ],
559 )
560 ),
561 )
562 );
563 }
564
565 public function tab_material( $thepostid ) {
566 return apply_filters(
567 'lp/course/meta-box/fields/material',
568 array(
569 '_lp_course_material' => new LP_Meta_Box_Material_Fields(),
570 )
571 );
572 }
573
574 public function tab_assessment( $thepostid ) {
575 $post = get_post( $thepostid );
576
577 $course_result_desc = '';
578 $course_results = get_post_meta( $thepostid, '_lp_course_result', true );
579
580 $course_result_desc .= __( 'The method of evaluating a student\'s performance in a course.', 'learnpress' );
581 $course_result_desc .= sprintf(
582 '<br/><i style="color: red">%s</i>',
583 __( 'Note: changing the evaluation type will affect the assessment results of student learning.', 'learnpress' )
584 );
585
586 if ( $course_results == 'evaluate_final_quiz' && ! get_post_meta( $thepostid, '_lp_final_quiz', true ) ) {
587 $course_result_desc .= __( '<br /><strong>Note! </strong>There is no final quiz in the course. Please add a final quiz.', 'learnpress' );
588 }
589
590 $final_quizz_passing = '';
591
592 $course = learn_press_get_course( $thepostid );
593
594 if ( $course ) {
595 $passing_grade = $url = '';
596
597 $final_quiz = $course->get_final_quiz();
598
599 if ( $final_quiz ) {
600 $passing_grade = get_post_meta( $final_quiz, '_lp_passing_grade', true );
601 if ( '' === (string) $passing_grade ) {
602 $quiz_model = QuizPostModel::find( absint( $final_quiz ), true );
603 if ( $quiz_model ) {
604 $passing_grade = $quiz_model->get_passing_grade();
605 } else {
606 $passing_grade = 80;
607 }
608 }
609
610 $url = get_edit_post_link( $final_quiz ) . '#_lp_passing_grade';
611
612 $final_quizz_passing = '
613 <div class="lp-metabox-evaluate-final_quiz">
614 <div class="lp-metabox-evaluate-final_quiz__message">'
615 . sprintf( esc_html__( 'Passing Grade: %s', 'learpress' ), $passing_grade . '%' ) .
616 ' - '
617 . sprintf( esc_html__( 'Edit: %s', 'learnpress' ), '<a href="' . esc_url_raw( $url ) . '">' . get_the_title( $final_quiz ) . '</a>' ) .
618 '</div>
619 </div>
620 ';
621 }
622 }
623
624 return apply_filters(
625 'lp/course/meta-box/fields/assessment',
626 array(
627 '_lp_course_result' => new LP_Meta_Box_Radio_Field(
628 esc_html__( 'Evaluation', 'learnpress' ),
629 $course_result_desc,
630 'evaluate_lesson',
631 array(
632 'options' => learn_press_course_evaluation_methods( $thepostid, '', $final_quizz_passing ),
633 )
634 ),
635 '_lp_passing_condition' => new LP_Meta_Box_Text_Field(
636 esc_html__( 'Passing Grade(%)', 'learnpress' ),
637 esc_html__( 'The conditions that must be achieved to finish the course.', 'learnpress' ),
638 '80',
639 array(
640 'type_input' => 'number',
641 'custom_attributes' => array(
642 'min' => '0',
643 'step' => '0.01',
644 'max' => '100',
645 ),
646 'style' => 'width: 60px;',
647 )
648 ),
649 )
650 );
651 }
652
653 public function tab_extra( $thepostid ) {
654 return apply_filters(
655 'lp/course/meta-box/fields/extra',
656 array(
657 '_lp_requirements' => new LP_Meta_Box_Extra_Field(
658 esc_html__( 'Requirements', 'learnpress' ),
659 '',
660 array()
661 ),
662 '_lp_target_audiences' => new LP_Meta_Box_Extra_Field(
663 esc_html__( 'Target Audience', 'learnpress' ),
664 '',
665 array()
666 ),
667 '_lp_key_features' => new LP_Meta_Box_Extra_Field(
668 esc_html__( 'Key Features', 'learnpress' ),
669 '',
670 array()
671 ),
672 '_lp_faqs' => new LP_Meta_Box_Extra_Faq_Field(
673 esc_html__( 'FAQs', 'learnpress' ),
674 '',
675 array()
676 ),
677 )
678 );
679 }
680
681 public function data_tabs_sort( $a, $b ) {
682 if ( ! isset( $a['priority'], $b['priority'] ) ) {
683 return - 1;
684 }
685
686 if ( $a['priority'] === $b['priority'] ) {
687 return 0;
688 }
689
690 return $a['priority'] < $b['priority'] ? - 1 : 1;
691 }
692 }
693