PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7.3.2
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7.3.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 / admin / views / meta-boxes / course / settings.php

settings.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.7.3.2, at inc/admin/views/meta-boxes/course/settings.php

655 lines 21.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class LP_Meta_Box_Course extends LP_Meta_Box {
4 /**
5 * Instance
6 *
7 * @var null|LP_Meta_Box_Course
8 */
9 private static $instance = null;
10
11 public $post_type = LP_COURSE_CPT;
12
13 public function add_meta_box() {
14 add_meta_box( 'course-settings', esc_html__( 'Course Settings', 'learnpress' ), array( $this, 'output' ), $this->post_type, 'normal', 'high' );
15 }
16
17 public function metabox( $post_id ) {
18 $tabs = apply_filters(
19 'lp_course_data_settings_tabs',
20 array(
21 'general' => array(
22 'label' => esc_html__( 'General', 'learnpress' ),
23 'target' => 'general_course_data',
24 'icon' => 'dashicons-admin-tools',
25 'priority' => 10,
26 'content' => $this->general( $post_id ),
27 ),
28 'price' => array(
29 'label' => esc_html__( 'Pricing', 'learnpress' ),
30 'target' => 'price_course_data',
31 'icon' => 'dashicons-cart',
32 'priority' => 20,
33 'content' => $this->lp_price( $post_id ),
34 ),
35 'extra' => array(
36 'label' => esc_html__( 'Extra Information', 'learnpress' ),
37 'target' => 'extra_course_data',
38 'icon' => 'dashicons-excerpt-view',
39 'priority' => 30,
40 'content' => $this->extra( $post_id ),
41 ),
42 'assessment' => array(
43 'label' => esc_html__( 'Assessment', 'learnpress' ),
44 'target' => 'assessment_course_data',
45 'icon' => 'dashicons-awards',
46 'priority' => 40,
47 'content' => $this->assessment( $post_id ),
48 ),
49 'author' => array(
50 'label' => esc_html__( 'Author', 'learnpress' ),
51 'target' => 'author_course_data',
52 'icon' => 'dashicons-businessman',
53 'priority' => 50,
54 'content' => $this->author( $post_id ),
55 ),
56 )
57 );
58
59 $tabs = apply_filters( 'learnpress/course/metabox/tabs', $tabs, $post_id );
60
61 uasort( $tabs, array( __CLASS__, 'data_tabs_sort' ) );
62
63 return $tabs;
64 }
65
66 public function general( $thepostid ) {
67 $repurchase_option_desc = sprintf( '1. %s', __( 'Reset course progress: The course progress and results of student will be removed.' ) );
68 $repurchase_option_desc .= '<br/>' . sprintf( '2. %s', __( 'Keep course progress: The course progress and results of student will remain.' ) );
69 $repurchase_option_desc .= '<br/>' . sprintf( '3. %s', __( 'Open popup: The student can decide whether their course progress will be reset with the confirm popup.' ) );
70
71 return apply_filters(
72 'lp/course/meta-box/fields/general',
73 array(
74 '_lp_duration' => new LP_Meta_Box_Duration_Field(
75 esc_html__( 'Duration', 'learnpress' ),
76 esc_html__( 'Set to 0 for the lifetime access.', 'learnpress' ),
77 '10',
78 array(
79 'default_time' => 'week',
80 'custom_attributes' => array(
81 'min' => '0',
82 'step' => '1',
83 ),
84 )
85 ),
86 '_lp_block_expire_duration' => new LP_Meta_Box_Checkbox_Field(
87 esc_html__( 'Block content', 'learnpress' ),
88 esc_html__( 'When the duration expires, the course is blocked.', 'learnpress' ),
89 'no'
90 ),
91 '_lp_block_finished' => new LP_Meta_Box_Checkbox_Field(
92 '',
93 esc_html__( 'Block the course after the student finished this course.', 'learnpress' ),
94 'yes'
95 ),
96 '_lp_allow_course_repurchase' => new LP_Meta_Box_Checkbox_Field(
97 __( 'Allow Repurchase', 'learnpress' ),
98 esc_html__( 'Allow users to repurchase this course after it has been finished or blocked (Do not apply to free courses).', 'learnpress' ),
99 'no'
100 ),
101 '_lp_course_repurchase_option' => new LP_Meta_Box_Select_Field(
102 esc_html__( 'Repurchase action', 'learnpress' ),
103 $repurchase_option_desc,
104 'reset',
105 array(
106 'options' => array(
107 'reset' => esc_html__( 'Reset course progress', 'learnpress' ),
108 'keep' => esc_html__( 'Keep course progress', 'learnpress' ),
109 'popup' => esc_html__( 'Open popup', 'learnpress' ),
110 ),
111 'show' => array( '_lp_allow_course_repurchase', '=', 'yes' ), // use 'show' or 'hide'
112 )
113 ),
114 '_lp_level' => new LP_Meta_Box_Select_Field(
115 esc_html__( 'Level', 'learnpress' ),
116 esc_html__( 'Choose a difficulty level.', 'learnpress' ),
117 '',
118 array(
119 'options' => lp_course_level(),
120 )
121 ),
122 '_lp_students' => new LP_Meta_Box_Text_Field(
123 esc_html__( 'Fake Students Enrolled', 'learnpress' ),
124 esc_html__( 'How many students have taken this course?', 'learnpress' ),
125 0,
126 array(
127 'type_input' => 'number',
128 'custom_attributes' => array(
129 'min' => '0',
130 'step' => '1',
131 ),
132 'style' => 'width: 70px;',
133 )
134 ),
135 '_lp_max_students' => new LP_Meta_Box_Text_Field(
136 esc_html__( 'Max student', 'learnpress' ),
137 esc_html__( 'The maximum number of students that can join a course. Set 0 for unlimited.', 'learnpress' ),
138 0,
139 array(
140 'type_input' => 'number',
141 'custom_attributes' => array(
142 'min' => '0',
143 'step' => '1',
144 ),
145 'style' => 'width: 70px;',
146 )
147 ),
148 '_lp_retake_count' => new LP_Meta_Box_Text_Field(
149 esc_html__( 'Re-take Course', 'learnpress' ),
150 esc_html__( 'The number of times a user can learn again from this course. To disable, set to 0.', 'learnpress' ),
151 0,
152 array(
153 'type_input' => 'number',
154 'custom_attributes' => array(
155 'min' => '0',
156 'step' => '1',
157 ),
158 'style' => 'width: 70px;',
159 )
160 ),
161 '_lp_has_finish' => new LP_Meta_Box_Checkbox_Field(
162 esc_html__( 'Finish button', 'learnpress' ),
163 esc_html__( 'Allow showing the finish button when the student has completed all items but has not passed the course assessment yet.', 'learnpress' ),
164 'yes'
165 ),
166 '_lp_featured' => new LP_Meta_Box_Checkbox_Field(
167 esc_html__( 'Featured list', 'learnpress' ),
168 esc_html__( 'Add the course to the Featured List.', 'learnpress' ),
169 'no'
170 ),
171 '_lp_featured_review' => new LP_Meta_Box_Textarea_Field(
172 esc_html__( 'Featured review', 'learnpress' ),
173 esc_html__( 'A good review to promote the course.', 'learnpress' )
174 ),
175 '_lp_external_link_buy_course' => new LP_Meta_Box_Text_Field(
176 esc_html__( 'External link', 'learnpress' ),
177 esc_html__( 'Normally used for offline classes. Ex: link to a contact page. Format: https://google.com', 'learnpress' ),
178 '',
179 array(
180 'desc_tip' => 'You can apply for case: user register form.<br> You accept for user can learn courses by add manual order on backend',
181 )
182 ),
183 )
184 );
185 }
186
187 /**
188 * Setting course price
189 *
190 * @param $post_id
191 *
192 * @author tungnx
193 * @since 4.1.5
194 * @version 1.0.0
195 * @return array
196 */
197 public function lp_price( $post_id ): array {
198 $key_exists = LP_Database::getInstance()->check_key_postmeta_exists( $post_id, '_lp_regular_price' );
199 $price = get_post_meta( $post_id, '_lp_price', true );
200 $regular_price = $key_exists ? get_post_meta( $post_id, '_lp_regular_price', true ) : $price;
201 $sale_price = get_post_meta( $post_id, '_lp_sale_price', true );
202
203 return apply_filters(
204 'lp/course/meta-box/fields/price',
205 array(
206 '_lp_regular_price' => new LP_Meta_Box_Text_Field(
207 esc_html__( 'Regular price', 'learnpress' ),
208 sprintf( __( 'Set a regular price (<strong>%s</strong>). Leave it blank for <strong>Free</strong>.', 'learnpress' ), learn_press_get_currency() ),
209 $regular_price,
210 array(
211 'type_input' => 'text',
212 'custom_attributes' => array(
213 'min' => '0',
214 'step' => '0.01',
215 ),
216 'style' => 'width: 70px;',
217 'class' => 'lp_meta_box_regular_price',
218 )
219 ),
220 '_lp_sale_price' => new LP_Meta_Box_Text_Field(
221 esc_html__( 'Sale price', 'learnpress' ),
222 '<a href="#" class="lp_sale_price_schedule">' . esc_html__( 'Schedule', 'learnpress' ) . '</a>',
223 $sale_price,
224 array(
225 'type_input' => 'text',
226 'custom_attributes' => array(
227 'min' => '0',
228 'step' => '0.01',
229 ),
230 'style' => 'width: 70px;',
231 'class' => 'lp_meta_box_sale_price',
232 )
233 ),
234 '_lp_sale_start' => new LP_Meta_Box_Date_Field(
235 esc_html__( 'Sale start dates', 'learnpress' ),
236 '',
237 '',
238 array(
239 'wrapper_class' => 'lp_sale_start_dates_fields',
240 'placeholder' => _x( 'From&hellip;', 'placeholder', 'learnpress' ),
241 )
242 ),
243 '_lp_sale_end' => new LP_Meta_Box_Date_Field(
244 esc_html__( 'Sale end dates', 'learnpress' ),
245 '',
246 '',
247 array(
248 'wrapper_class' => 'lp_sale_end_dates_fields',
249 'placeholder' => _x( 'To&hellip;', 'placeholder', 'learnpress' ),
250 'cancel' => true,
251 )
252 ),
253 '_lp_no_required_enroll' => new LP_Meta_Box_Checkbox_Field(
254 esc_html__( 'There is no enrollment requirement', 'learnpress' ),
255 esc_html__( 'Students can see the content of all course items and take the quiz without logging in.', 'learnpress' ),
256 'no'
257 ),
258 )
259 );
260 }
261
262 public function author( $thepostid ) {
263 $post = get_post( $thepostid );
264
265 $author = $post ? $post->post_author : get_current_user_id();
266
267 $options = array();
268 $role = array( 'administrator', 'lp_teacher' );
269
270 $role = apply_filters( 'learn_press_course_author_role_meta_box', $role );
271
272 foreach ( $role as $_role ) {
273 $users_by_role = get_users( array( 'role' => $_role ) );
274
275 if ( $users_by_role ) {
276 foreach ( $users_by_role as $user ) {
277 $options[ $user->get( 'ID' ) ] = $user->user_login;
278 }
279 }
280 }
281
282 return apply_filters(
283 'lp/course/meta-box/fields/author',
284 array(
285 '_lp_course_author' => new LP_Meta_Box_Select_Field(
286 esc_html__( 'Author', 'learnpress' ),
287 '',
288 $author,
289 array(
290 'options' => $options,
291 'style' => 'min-width:200px;',
292 )
293 ),
294 )
295 );
296 }
297
298 public function assessment( $thepostid ) {
299 $post = get_post( $thepostid );
300
301 $course_result_desc = '';
302 $course_results = get_post_meta( $thepostid, '_lp_course_result', true );
303
304 $course_result_desc .= __( 'The method of evaluating a student\'s performance in a course.', 'learnpress' );
305
306 if ( $course_results == 'evaluate_final_quiz' && ! get_post_meta( $thepostid, '_lp_final_quiz', true ) ) {
307 $course_result_desc .= __( '<br /><strong>Note! </strong>There is no final quiz in the course. Please add a final quiz.', 'learnpress' );
308 }
309
310 $final_quizz_passing = '';
311
312 $course = learn_press_get_course( $thepostid );
313
314 if ( $course ) {
315 $passing_grade = $url = '';
316
317 $final_quiz = $course->get_final_quiz();
318
319 if ( $final_quiz ) {
320 $passing_grade = get_post_meta( $final_quiz, '_lp_passing_grade', true );
321
322 $url = get_edit_post_link( $final_quiz ) . '#_lp_passing_grade';
323
324 $final_quizz_passing = '
325 <div class="lp-metabox-evaluate-final_quiz">
326 <div class="lp-metabox-evaluate-final_quiz__message">'
327 . sprintf( esc_html__( 'Passing Grade: %s', 'learpress' ), $passing_grade . '%' ) .
328 ' - '
329 . sprintf( esc_html__( 'Edit: %s', 'learnpress' ), '<a href="' . esc_url_raw( $url ) . '">' . get_the_title( $final_quiz ) . '</a>' ) .
330 '</div>
331 </div>
332 ';
333 }
334 }
335
336 return apply_filters(
337 'lp/course/meta-box/fields/assessment',
338 array(
339 '_lp_course_result' => new LP_Meta_Box_Radio_Field(
340 esc_html__( 'Evaluation', 'learnpress' ),
341 $course_result_desc,
342 'evaluate_lesson',
343 array(
344 'options' => learn_press_course_evaluation_methods( $thepostid, '', $final_quizz_passing ),
345 )
346 ),
347 '_lp_passing_condition' => new LP_Meta_Box_Text_Field(
348 esc_html__( 'Passing Grade(%)', 'learnpress' ),
349 esc_html__( 'The conditions that must be achieved to finish the course.', 'learnpress' ),
350 '80',
351 array(
352 'type_input' => 'number',
353 'custom_attributes' => array(
354 'min' => '0',
355 'step' => '1',
356 'max' => '100',
357 ),
358 'style' => 'width: 60px;',
359 )
360 ),
361 )
362 );
363 }
364
365 public function extra( $thepostid ) {
366 return apply_filters(
367 'lp/course/meta-box/fields/extra',
368 array(
369 '_lp_requirements' => new LP_Meta_Box_Extra_Field(
370 esc_html__( 'Requirements', 'learnpress' ),
371 '',
372 array()
373 ),
374 '_lp_target_audiences' => new LP_Meta_Box_Extra_Field(
375 esc_html__( 'Target Audience', 'learnpress' ),
376 '',
377 array()
378 ),
379 '_lp_key_features' => new LP_Meta_Box_Extra_Field(
380 esc_html__( 'Key Features', 'learnpress' ),
381 '',
382 array()
383 ),
384 '_lp_faqs' => new LP_Meta_Box_Extra_Faq_Field(
385 esc_html__( 'FAQs', 'learnpress' ),
386 '',
387 array()
388 ),
389 )
390 );
391 }
392
393 public function output( $post ) {
394 parent::output( $post );
395 ?>
396
397 <div class="lp-meta-box lp-meta-box--course">
398 <div class="lp-meta-box__inner">
399 <div class="lp-meta-box__course-tab">
400 <ul class="lp-meta-box__course-tab__tabs">
401 <?php
402 foreach ( $this->metabox( $post->ID ) as $key => $tab ) {
403 if ( $key === 'author' && ! is_super_admin() ) {
404 continue;
405 }
406
407 $class_tab = '';
408
409 if ( isset( $tab['class'] ) ) {
410 $class_tab = implode( ' ', (array) $tab['class'] );
411 }
412 ?>
413 <li class="<?php echo esc_attr( $key ); ?>_options <?php echo esc_attr( $key ); ?>_tab <?php echo esc_attr( $class_tab ); ?>">
414 <a href="#<?php echo esc_attr( $tab['target'] ); ?>">
415 <?php if ( isset( $tab['icon'] ) ) : ?>
416 <i class="<?php echo esc_attr( $tab['icon'] ); ?>"></i>
417 <?php endif; ?>
418 <span><?php echo esc_html( $tab['label'] ); ?></span>
419 </a>
420 </li>
421 <?php } ?>
422 </ul>
423
424 <div class="lp-meta-box__course-tab__content">
425 <?php foreach ( $this->metabox( $post->ID ) as $key => $tab_content ) { ?>
426 <?php
427 if ( $key === 'author' && ! is_super_admin() ) {
428 continue;
429 }
430 ?>
431 <?php if ( isset( $tab_content['content'] ) ) { ?>
432 <div id="<?php echo esc_attr( $tab_content['target'] ); ?>" class="lp-meta-box-course-panels">
433 <?php
434 do_action( 'learnpress/course-settings/before-' . $key );
435
436 foreach ( $tab_content['content'] as $meta_key => $object ) {
437 if ( is_a( $object, 'LP_Meta_Box_Field' ) ) {
438 $object->id = $meta_key;
439 echo wp_kses_post( $object->output( $post->ID ) );
440 }
441 }
442
443 do_action( 'learnpress/course-settings/after-' . $key );
444 ?>
445 </div>
446 <?php
447 }
448 }
449
450 do_action( 'lp_course_data_setting_tab_content', $post );
451 ?>
452 </div>
453 </div>
454 </div>
455 </div>
456
457 <?php
458 }
459
460 public function save( $post_id ) {
461 if ( ! empty( $this->metabox( $post_id ) ) ) {
462 foreach ( $this->metabox( $post_id ) as $key => $tab_content ) {
463 if ( isset( $tab_content['content'] ) ) {
464 foreach ( $tab_content['content'] as $meta_key => $object ) {
465 if ( is_a( $object, 'LP_Meta_Box_Field' ) ) {
466 $object->id = $meta_key;
467 $object->save( $post_id );
468 }
469 }
470 }
471 }
472 }
473
474 $course = learn_press_get_course( $post_id );
475
476 $evalution = isset( $_POST['_lp_course_result'] ) ? LP_Helper::sanitize_params_submitted( $_POST['_lp_course_result'] ) : '';
477 $passing_condition = isset( $_POST['_lp_passing_condition'] ) ? absint( wp_unslash( $_POST['_lp_passing_condition'] ) ) : 0;
478
479 // Update Final Quiz. - Nhamdv
480 if ( $evalution == 'evaluate_final_quiz' ) {
481 $items = $course->get_item_ids();
482
483 if ( $items ) {
484 foreach ( $items as $item ) {
485 if ( learn_press_get_post_type( $item ) === LP_QUIZ_CPT ) {
486 $final_quiz = $item;
487 }
488 }
489 }
490
491 if ( isset( $final_quiz ) ) {
492 update_post_meta( $post_id, '_lp_final_quiz', $final_quiz );
493 } else {
494 delete_post_meta( $post_id, '_lp_final_quiz' );
495 }
496 } else {
497 delete_post_meta( $post_id, '_lp_final_quiz' );
498 }
499
500 $author = isset( $_POST['_lp_course_author'] ) ? wp_unslash( $_POST['_lp_course_author'] ) : '';
501
502 if ( ! empty( $author ) ) {
503 global $wpdb;
504
505 $wpdb->update( $wpdb->posts, array( 'post_author' => $author ), array( 'ID' => $post_id ) );
506 }
507 }
508
509 private static function data_tabs_sort( $a, $b ) {
510 if ( ! isset( $a['priority'], $b['priority'] ) ) {
511 return - 1;
512 }
513
514 if ( $a['priority'] === $b['priority'] ) {
515 return 0;
516 }
517
518 return $a['priority'] < $b['priority'] ? - 1 : 1;
519 }
520
521 /**
522 * In child theme use metabox in v3,
523 * so need use for child theme.
524 * function in child: thim_add_course_meta.
525 *
526 * @return void
527 */
528 public static function eduma_child_metabox_v3( $meta_boxes ) {
529 if ( ! empty( $meta_boxes['fields'] ) ) {
530 foreach ( $meta_boxes['fields'] as $setting ) {
531 $field = wp_parse_args(
532 $setting,
533 array(
534 'id' => '',
535 'name' => '',
536 'desc' => '',
537 'std' => '',
538 )
539 );
540
541 switch ( $field['type'] ) {
542 case 'text':
543 case 'number':
544 lp_meta_box_text_input_field(
545 array(
546 'id' => $field['id'],
547 'label' => isset( $field['label'] ) ? $field['label'] : $field['name'],
548 'description' => isset( $field['description'] ) ? $field['description'] : $field['desc'],
549 'type' => $field['type'],
550 'default' => isset( $field['default'] ) ? $field['default'] : $field['std'],
551 'custom_attributes' => isset( $field['custom_attributes'] ) ? $field['custom_attributes'] : '',
552 )
553 );
554 break;
555
556 case 'textarea':
557 lp_meta_box_textarea_field(
558 array(
559 'id' => $field['id'],
560 'label' => isset( $field['label'] ) ? $field['label'] : $field['name'],
561 'description' => isset( $field['description'] ) ? $field['description'] : $field['desc'],
562 'default' => isset( $field['default'] ) ? $field['default'] : $field['std'],
563 'custom_attributes' => isset( $field['custom_attributes'] ) ? $field['custom_attributes'] : '',
564 )
565 );
566 break;
567
568 case 'checkbox':
569 lp_meta_box_checkbox_field(
570 array(
571 'id' => $field['id'],
572 'label' => isset( $field['label'] ) ? $field['label'] : $field['name'],
573 'description' => isset( $field['description'] ) ? $field['description'] : $field['desc'],
574 'default' => isset( $field['default'] ) ? $field['default'] : $field['std'],
575 )
576 );
577 break;
578
579 case 'duration':
580 lp_meta_box_duration_field(
581 array(
582 'id' => $field['id'],
583 'label' => isset( $field['label'] ) ? $field['label'] : $field['name'],
584 'default_time' => $field['default_time'],
585 'default' => isset( $field['default'] ) ? $field['default'] : $field['std'],
586 'description' => isset( $field['description'] ) ? $field['description'] : $field['desc'],
587 'default' => isset( $field['default'] ) ? $field['default'] : $field['std'],
588 'custom_attributes' => isset( $field['custom_attributes'] ) ? $field['custom_attributes'] : '',
589 )
590 );
591 break;
592
593 case 'select':
594 lp_meta_box_select_field(
595 array(
596 'id' => $field['id'],
597 'label' => isset( $field['label'] ) ? $field['label'] : $field['name'],
598 'default' => isset( $field['default'] ) ? $field['default'] : $field['std'],
599 'description' => isset( $field['description'] ) ? $field['description'] : $field['desc'],
600 'options' => $field['options'],
601 'default' => isset( $field['default'] ) ? $field['default'] : $field['std'],
602 'custom_attributes' => isset( $field['custom_attributes'] ) ? $field['custom_attributes'] : '',
603 )
604 );
605 break;
606
607 case 'select_advanced':
608 lp_meta_box_select_field(
609 array(
610 'id' => $field['id'],
611 'label' => isset( $field['label'] ) ? $field['label'] : $field['name'],
612 'default' => isset( $field['default'] ) ? $field['default'] : $field['std'],
613 'description' => isset( $field['description'] ) ? $field['description'] : $field['desc'],
614 'options' => $field['options'],
615 'multiple' => true,
616 'default' => isset( $field['default'] ) ? $field['default'] : $field['std'],
617 'wrapper_class' => 'lp-select-2',
618 'style' => 'min-width: 200px',
619 'custom_attributes' => isset( $field['custom_attributes'] ) ? $field['custom_attributes'] : '',
620 )
621 );
622 break;
623 }
624 }
625 }
626 }
627
628 public static function save_eduma_child_metabox_v3( $post_id ) {
629 $general = apply_filters( 'learn_press_course_settings_meta_box_args', array( 'fields' => array() ) );
630
631 if ( ! empty( $general['fields'] ) ) {
632 foreach ( $general['fields'] as $field ) {
633 $value = isset( $_POST[ $field['id'] ] ) ? wp_unslash( $_POST[ $field['id'] ] ) : '';
634
635 update_post_meta( $post_id, $field['id'], $value );
636 }
637 }
638 }
639
640 /**
641 * Get instance
642 *
643 * @return LP_Meta_Box_Course
644 */
645 public static function instance(): LP_Meta_Box_Course {
646 if ( ! self::$instance ) {
647 self::$instance = new self();
648 }
649
650 return self::$instance;
651 }
652 }
653
654 LP_Meta_Box_Course::instance();
655