PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7.1
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 / course / class-lp-course-item.php

class-lp-course-item.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.7.1, at inc/course/class-lp-course-item.php

808 lines 18.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class LP_Course_Item.
4 *
5 * @author ThimPress
6 * @package LearnPress/Classes
7 * @version 3.0.0
8 */
9
10 defined( 'ABSPATH' ) || exit();
11
12 if ( ! class_exists( 'LP_Course_Item' ) ) {
13 /**
14 * Class LP_Course_Item.
15 */
16 class LP_Course_Item extends LP_Abstract_Post_Data implements ArrayAccess {
17
18 /**
19 * The icon maybe used somewhere.
20 *
21 * @var string
22 */
23 protected $_icon_class = '';
24
25 /**
26 * The type of item.
27 *
28 * @var string
29 */
30 protected $_item_type = '';
31
32 /**
33 * @var LP_Course
34 */
35 protected $_course = null;
36
37 /**
38 * @var LP_Course_Section
39 */
40 protected $_section = null;
41
42 /**
43 * @var null
44 */
45 protected $_content = null;
46
47 /**
48 * @var bool
49 */
50 protected $_preview = false;
51
52
53 /**
54 * LP_Course_Item constructor.
55 *
56 * @param $item mixed
57 * @param $args array
58 */
59 public function __construct( $item, $args = null ) {
60 parent::__construct( $item, $args );
61
62 $this->add_support( 'comments', get_post_field( 'comment_status', $this->get_id() ) === 'open' );
63 }
64
65 /**
66 * Get type of item.
67 *
68 * @param string $context
69 *
70 * @return string
71 */
72 public function get_item_type( $context = '' ) {
73 $post_type = $this->_item_type;
74
75 if ( $context === 'display' ) {
76 $post_type_object = get_post_type_object( $post_type );
77
78 if ( $post_type_object ) {
79 $post_type = $post_type_object->labels->singular_name;
80 }
81 }
82
83 return $post_type;
84 }
85
86 /**
87 * @return string
88 */
89 public function get_icon_class() {
90 return $this->_icon_class;
91 }
92
93 /**
94 * Check lesson is preview
95 *
96 * @param string $context
97 *
98 * @return bool
99 */
100 public function is_preview( $context = 'display' ): bool {
101 $item_id = $this->get_id();
102
103 $this->_preview = false;
104
105 if ( $item_id && LP_LESSON_CPT === $this->get_post_type() ) {
106 $is_lesson_preview = get_post_meta( $item_id, '_lp_preview', true );
107
108 $this->_preview = 'yes' === $is_lesson_preview;
109 }
110
111 return apply_filters( 'learnpress/course/item-preview', $this->_preview, $this->get_id() );
112 }
113
114 /**
115 * @param string $context
116 *
117 * @return string
118 */
119 public function get_title( $context = '' ) {
120 return apply_filters( 'learn-press/course-item-title', parent::get_title( $context ), $this->get_id() );
121 }
122
123 /**
124 * Get format of Post
125 *
126 * @return bool|false|mixed|string
127 */
128 public function get_format() {
129 $format = get_post_meta( $this->get_id(), 'post_format', true );
130
131 if ( ! $format ) {
132 $format = 'standard';
133 }
134
135 return $format;
136 }
137
138 /**
139 * Return true if item can be shown in course curriculum.
140 *
141 * @return mixed
142 * @deprecated 4.0.0
143 */
144 public function is_visible() {
145 $show = true;
146
147 return apply_filters( 'learn-press/course-item-visible', $show, $this->get_item_type(), $this->get_id() );
148 }
149
150 /**
151 * Get class of item.
152 *
153 * @param string $more
154 * @param int $user_id
155 *
156 * @return array
157 */
158 public function get_class( $more = '', $user_id = 0 ) {
159 $course_id = get_the_ID();
160
161 if ( empty( $GLOBALS['get_class'] ) ) {
162 $GLOBALS['get_class'] = 0;
163 }
164
165 $user_id = $user_id ? $user_id : get_current_user_id();
166 $t = microtime( true );
167 $classes = LP_Object_Cache::get( 'item-' . $user_id . '-' . $this->get_id(), 'learn-press/post-classes' );
168
169 if ( false === $classes ) {
170 $curd = new LP_User_Item_CURD();
171 $all_items = $curd->parse_items_classes( $course_id, $user_id, $more );
172
173 $classes = ! empty( $all_items[ $this->get_id() ] ) ? $all_items[ $this->get_id() ] : $defaults = array(
174 'course-item',
175 'course-item-' . $this->get_item_type(),
176 'course-item-' . $this->get_id(),
177 );
178 }
179
180 $GLOBALS['get_class'] += microtime( true ) - $t;
181
182 return apply_filters(
183 'learn-press/course-item-class-cached',
184 $classes,
185 $this->get_item_type(),
186 $this->get_id(),
187 $course_id
188 );
189 }
190
191 public function get_class_v2( $course_id, $item_id, $can_view_item, $more = array() ) {
192 $course = learn_press_get_course( $course_id );
193
194 if ( ! $course ) {
195 return $more;
196 }
197
198 $defaults = array_merge(
199 array(
200 'course-item',
201 'course-item-' . $this->get_item_type(),
202 'course-item-' . $item_id,
203 ),
204 (array) $more
205 );
206
207 $user = learn_press_get_user( get_current_user_id() );
208
209 if ( ! $user ) {
210 return $defaults;
211 }
212
213 $is_free = $course->is_free();
214 $enrolled = $user->has_enrolled_or_finished( $course_id );
215 $no_required_enroll = $course->is_no_required_enroll();
216
217 $post_format = $this->get_format();
218 if ( 'standard' !== $post_format && $post_format ) {
219 $defaults[] = 'course-item-type-' . $post_format;
220 }
221
222 if ( $no_required_enroll ) {
223 $defaults[] = 'item-free';
224 } elseif ( ! $enrolled ) {
225 $defaults['item-locked'] = 'item-locked';
226
227 if ( $this->is_preview() ) {
228 $defaults['item-preview'] = 'item-preview';
229 $defaults['has-status'] = 'has-status';
230 unset( $defaults['item-locked'] );
231 }
232 } elseif ( ! $can_view_item->flag ) {
233 $defaults[] = 'item-locked';
234 } else {
235 $item_status = $user->get_item_status( $item_id, $course_id );
236 $item_grade = $user->get_item_grade( $item_id, $course_id );
237
238 if ( $item_status ) {
239 $defaults[] = 'has-status';
240 $defaults[] = 'status-' . $item_status;
241 }
242
243 switch ( $item_status ) {
244 case 'started':
245 break;
246 case 'completed':
247 $defaults[] = $item_grade;
248 break;
249 default:
250 if ( $this->is_preview() ) {
251 $defaults['item-preview'] = 'item-preview';
252 $defaults['has-status'] = 'has-status';
253 }
254
255 $item_class = apply_filters(
256 'learn-press/course-item-status-class',
257 $item_status,
258 $item_grade,
259 $this->get_item_type(),
260 $item_id,
261 $course_id
262 );
263
264 if ( $item_class ) {
265 $defaults[] = $item_class;
266 }
267 }
268 }
269
270 $classes = apply_filters(
271 'learn-press/course-item-class',
272 $defaults,
273 $this->get_item_type(),
274 $item_id,
275 $course_id
276 );
277
278 // Filter unwanted values.
279 $classes = is_array( $classes ) ? $classes : explode( ' ', $classes );
280 $classes = array_filter( $classes );
281 $classes = array_unique( $classes );
282
283 return $classes;
284 }
285
286 public function get_status_title() {
287 $course_id = get_the_ID();
288 $status_message = '';
289
290 $user = learn_press_get_current_user();
291 if ( $user->get_item_status( $this->get_id(), $course_id ) === 'completed' ) {
292 $item_grade = $user->get_item_grade( $this->get_id(), $course_id );
293
294 if ( $item_grade === 'failed' ) {
295 $status_message = _x( 'Failed', 'course item status title', 'learnpress' );
296 } elseif ( $item_grade === 'passed' ) {
297 $status_message = _x( 'Passed', 'course item status title', 'learnpress' );
298 } else {
299 $status_message = _x( 'Completed', 'course item status title', 'learnpress' );
300 }
301 } else {
302 $status_message = _x( 'Unread', 'course item status title', 'learnpress' );
303 }
304
305 return apply_filters(
306 'learn-press/course-item-status-title',
307 $status_message,
308 $this->get_id(),
309 $course_id
310 );
311 }
312
313 /**
314 * Get permalink of item inside course.
315 *
316 * @return string
317 */
318 public function get_permalink() {
319 $link = false;
320
321 if ( $this->_course ) {
322 $link = $this->_course->get_item_link( $this->get_id() );
323 }
324
325 return apply_filters( 'learn-press/course-item-link', $link, $this );
326 }
327
328 /**
329 * Set course parent of this item.
330 *
331 * @param LP_Course|LP_Abstract_Course|int $course
332 */
333 public function set_course( $course ) {
334 if ( is_numeric( $course ) ) {
335 $this->_course = learn_press_get_course( $course );
336 } else {
337 $this->_course = $course;
338 }
339 }
340
341 /**
342 * Return course.
343 *
344 * @return LP_Course
345 */
346 public function get_course() {
347 return $this->_course;
348 }
349
350 public function get_course_id() {
351 $course = $this->get_course();
352
353 if ( $course ) {
354 return $course->get_id();
355 }
356
357 return false;
358 }
359
360 /**
361 * @param LP_Course_Section $section
362 */
363 public function set_section( $section ) {
364 $this->_section = $section;
365 }
366
367 /**
368 * @return LP_Course_Section
369 */
370 public function get_section() {
371 return $this->_section;
372 }
373
374 /**
375 * Get instance of an item from post
376 *
377 * @param int $item_id Item id.
378 * @param int $course_id .
379 *
380 * @return LP_Course_Item|false
381 * @Todo: tungnx - review - rewrite - set cache - check where call this function
382 * @editor tungnx
383 * @modify 4.1.3 - change cache
384 * @version 4.0.2
385 * @since 3.x.x
386 */
387 public static function get_item( $item_id = 0, $course_id = 0 ) {
388 /*
389 $lp_course_cache = LP_Course_Cache::instance();
390 $key_cache = sprintf( '%d/item_id/%d', $course_id, $item_id );
391 $item = $lp_course_cache->get_cache( $key_cache );*/
392
393 $item = false;
394
395 if ( false === $item ) {
396 $item_post = get_post( $item_id );
397
398 if ( ! $item_post ) {
399 return false;
400 }
401
402 $item_type = $item_post->post_type;
403
404 if ( learn_press_is_support_course_item_type( $item_type ) ) {
405 $type = str_replace( 'lp_', '', $item_type );
406
407 switch ( $type ) {
408 case 'lesson':
409 $item = LP_Lesson::get_lesson( $item_id );
410 break;
411 case 'quiz':
412 $item = LP_Quiz::get_quiz( $item_id );
413 break;
414 default:
415 $class_name = apply_filters(
416 'learn-press/course-item-object-class',
417 array(),
418 $type,
419 $item_type,
420 $item_id
421 );
422
423 if ( ! empty( $class_name ) && isset( $class_name[ $type ] ) ) {
424 $class = $class_name[ $type ];
425
426 if ( is_string( $class ) && class_exists( $class ) ) {
427 $item = new $class( $item_id );
428 } elseif ( $class instanceof LP_Course_Item ) {
429 $item = $class;
430 }
431 }
432
433 break;
434 }
435
436 // Todo: don't know why when set course here, theme ivy still null course
437 /*if ( $item instanceof LP_Course_Item ) {
438 $item->set_course( $course_id );
439 }*/
440
441 // $lp_course_cache->set_cache( $key_cache, $item );
442 }
443 }
444
445 return apply_filters( 'learn-press/get-course-item', $item, $item_type, $item_id );
446 }
447
448 /**
449 * Get template name of item.
450 *
451 * @return string
452 */
453 public function get_template() {
454 $item_type = $this->get_item_type();
455
456 return apply_filters(
457 'learn-press/section-item-template',
458 'item-' . str_replace( 'lp_', '', $item_type ),
459 $item_type
460 );
461 }
462
463 /**
464 * To array.
465 *
466 * @return array
467 * @since 3.0.0
468 */
469 public function to_array() {
470 $post = get_post( $this->get_id() );
471
472 return apply_filters(
473 'learn-press/item/to_array',
474 array(
475 'id' => $this->get_id(),
476 'type' => $this->get_item_type(),
477 'title' => $post->post_title,
478 'preview' => $this->is_preview(),
479 )
480 );
481 }
482
483 /**
484 * Create nonce for checking actions on an item.
485 *
486 * @param string $action
487 * @param int $course_id
488 * @param int $user_id
489 *
490 * @return string
491 */
492 public function create_nonce( $action = '', $course_id = 0, $user_id = 0 ) {
493 if ( ! $course_id && $this->get_course() ) {
494 $course_id = $this->get_course()->get_id();
495 }
496
497 if ( ! $user_id ) {
498 $user_id = get_current_user_id();
499 }
500
501 $action = $this->get_nonce_action( $action, $course_id, $user_id );
502
503 return wp_create_nonce( $action );
504 }
505
506 /**
507 * Verify nonce for an action on item.
508 *
509 * @param string $nonce
510 * @param string $action
511 * @param int $course_id
512 * @param int $user_id
513 *
514 * @return false|int
515 */
516 public function verify_nonce( $nonce, $action = '', $course_id = 0, $user_id = 0 ) {
517 if ( ! $course_id ) {
518 $course_id = $this->get_course()->get_id();
519 }
520
521 if ( ! $user_id ) {
522 $user_id = get_current_user_id();
523 }
524
525 $action = $this->get_nonce_action( $action, $course_id, $user_id );
526
527 return wp_verify_nonce( $nonce, $action );
528 }
529
530 /**
531 * @param $action
532 * @param $course_id
533 * @param $user_id
534 *
535 * @return string
536 */
537 public function get_nonce_action( $action, $course_id, $user_id ) {
538 return sprintf( '%s-item-%d-%d-%d', $action, $user_id, $course_id, $this->get_id() );
539 }
540
541 /**
542 * @param int $question_id
543 *
544 * @return mixed
545 */
546 public function is_viewing_question( $question_id = 0 ) {
547 global $lp_quiz_question;
548 if ( $question_id ) {
549 $viewing = $lp_quiz_question && $lp_quiz_question->get_id() == $question_id;
550 } else {
551 $viewing = $lp_quiz_question ? $lp_quiz_question->get_id() : false;
552 }
553
554 return apply_filters( 'learn-press/quiz/is-viewing-question', $viewing, $question_id, $this->get_id() );
555 }
556
557 /**
558 * @param int $user_id
559 * @param int $course_id
560 *
561 * @return mixed
562 */
563 public function get_status_classes( $user_id = 0, $course_id = 0 ) {
564 $status_classes = array();
565 $course = learn_press_get_course( $course_id );
566 $user = learn_press_get_user( $user_id, ! $user_id );
567
568 if ( $course ) {
569 if ( $this->is_preview() ) {
570 $status_classes[] = 'item-preview';
571 } elseif ( $course->is_free() && ! $course->is_required_enroll() ) {
572 $status_classes[] = 'item-free';
573 }
574 }
575
576 if ( $user ) {
577 $item_status = $user->get_item_status( $this->get_id(), $course_id );
578 $item_grade = $user->get_item_grade( $this->get_id(), $course_id );
579
580 if ( $item_status ) {
581 $status_classes[] = 'course-item-status';
582 $status_classes[] = 'item-' . $item_status;
583 }
584 switch ( $item_status ) {
585 case 'started':
586 break;
587 case 'completed':
588 $status_classes[] = $item_grade;
589 }
590 }
591
592 return apply_filters(
593 'learn-press/item-status-classes',
594 $status_classes,
595 $this->get_id(),
596 $course_id,
597 $user_id
598 );
599 }
600
601 /**
602 * Get duration of quiz
603 *
604 * @return LP_Duration
605 */
606 public function get_duration() {
607 $duration = $this->get_data( 'duration' );
608
609 if ( false === $duration || '' === $duration ) {
610 $duration = get_post_meta( $this->get_id(), '_lp_duration', true );
611
612 if ( $duration ) {
613 $duration = new LP_Duration( $duration );
614 } else {
615 $duration = new LP_Duration( 0 );
616 }
617
618 $this->_set_data( 'duration', $duration );
619 }
620
621 return apply_filters( 'learn-press/course-item-duration', $duration, $this->get_id() );
622 }
623
624 /**
625 * @param int $course_id
626 * @param int $user_id
627 *
628 * @return bool
629 * @editor tungnx
630 * @modify 4.1.3 - not use - comment
631 * @deprecated
632 */
633 public function is_blocked( $course_id = 0, $user_id = 0 ) {
634 _deprecated_function( __FUNCTION__, '4.1.3' );
635
636 /*
637 if ( ! $user_id ) {
638 $user_id = get_current_user_id();
639 }
640
641 if ( ! $course_id ) {
642 $course_id = get_the_ID();
643 }
644
645 $course_author = learn_press_get_course_user( $course_id );
646
647 if ( $course_author ) {
648 $author_id = $course_author->get_id();
649
650 if ( $author_id == $user_id ) {
651 // return false;
652 }
653 }
654
655 $key = 'course-item-' . $user_id . '-' . $course_id;
656 $blocked_items = LP_Object_Cache::get( $key, 'learn-press/blocked-items' );
657
658 if ( false === $blocked_items ) {
659 $blocked_items = $this->_parse_item_block_status( $course_id, $user_id, $key );
660 }
661
662 $is_blocked = isset( $blocked_items[ $this->get_id() ] ) ? $blocked_items[ $this->get_id() ] : false;
663
664 if ( false === $is_blocked ) {
665 if ( $course_id ) {
666 $course = learn_press_get_course( $course_id );
667 } else {
668 $course = $this->get_course();
669 $course_id = $course ? $course->get_id() : 0;
670 }
671
672 if ( ! $user_id ) {
673 $user_id = get_current_user_id();
674 }
675
676 $user = learn_press_get_user( $user_id );
677
678 if ( ! $course ) {
679 $blocked = 'yes';
680 } elseif ( ! $course->is_required_enroll() || $this->is_preview() ) {
681 $blocked = 'no';
682 } else {
683 if ( $user ) {
684 $blocked = $this->_item_is_blocked( $user, $course, $user->get_course_data( $course_id ) );
685 } else {
686 $blocked = 'yes';
687 }
688 }
689
690 if ( ! is_array( $blocked_items ) ) {
691 $blocked_items = array();
692 }
693 $blocked_items[ $this->get_id() ] = $blocked;
694
695 LP_Object_Cache::set( $key, $blocked_items, 'learn-press/blocked-items' );
696 $is_blocked = $blocked;
697 }
698
699 return apply_filters(
700 'learn-press/course-item/is-blocked',
701 $is_blocked === 'yes' ? true : false,
702 $this->get_id(),
703 $course_id,
704 $user_id
705 );*/
706 }
707
708 /**
709 * @editor tungnx
710 * @modify 4.1.3
711 */
712 /*
713 protected function _parse_item_block_status( $course_id, $user_id, $cache_key ) {
714 $course = learn_press_get_course( $course_id );
715
716 if ( ! $course ) {
717 return false;
718 }
719
720 $user = learn_press_get_user( $user_id );
721 $course_items = $course->get_item_ids();
722 $course_item_data = $user->get_course_data( $course_id );
723
724 if ( ! $course->is_required_enroll() ) {
725 $blocked_items = array_fill_keys( $course_items, 'no' );
726 } elseif ( ! $user || $user->is_guest() ) {
727 $blocked_items = array_fill_keys( $course_items, 'yes' );
728 } else {
729 $blocked = $this->_item_is_blocked( $user, $course, $course_item_data );
730 $blocked_items = array_fill_keys( $course_items, $blocked );
731 }
732 $block_item_types = learn_press_get_block_course_item_types();
733
734 foreach ( $course_items as $course_item ) {
735 $item = $course->get_item( $course_item );
736
737 if ( $item ) {
738 if ( $item->is_preview() ) {
739 $blocked_items[ $course_item ] = 'no';
740 } elseif ( ! $block_item_types || is_array( $block_item_types ) && ! in_array(
741 $item->get_post_type(),
742 $block_item_types
743 ) ) {
744 $blocked_items[ $course_item ] = 'no';
745 }
746 }
747
748 $item_data = $course_item_data->get_item( $course_item );
749 if ( $item_data ) {
750 $access_level = $item_data->get_access_level();
751 if ( $access_level > 0 && $access_level < 50 ) {
752 $blocked_items[ $course_item ] = 'yes';
753 }
754 }
755 }
756
757 $blocked_items = apply_filters(
758 'learn-press/course-item/parse-block-statuses',
759 $blocked_items,
760 $course_id,
761 $user_id
762 );
763
764 LP_Object_Cache::set( $cache_key, $blocked_items, 'learn-press/blocked-items' );
765
766 return $blocked_items;
767 }*/
768
769 /**
770 * @param LP_User $user
771 * @param LP_Course $course
772 * @param LP_User_Item_Course $course_item_data
773 *
774 * @return string
775 * @editor tungnx
776 * @modify 4.1.3
777 */
778 /*
779 protected function _item_is_blocked( $user, $course, $course_item_data ) {
780 if ( in_array( 'administrator', $user->get_roles() ) ) {
781 $blocked = 'no';
782 } elseif ( $user->has_course_status( $course->get_id(), learn_press_course_enrolled_slugs() ) ) {
783 $blocked = 'no';
784
785 if ( $course->is_block_item_content() && $course_item_data->get_finishing_type() !== 'click' ) {
786 $blocked = 'yes';
787 }
788 } else {
789 $blocked = 'yes';
790 }
791
792 return $blocked;
793 }*/
794
795 public function offsetExists( $offset ) {
796 }
797
798 public function offsetGet( $offset ) {
799 }
800
801 public function offsetSet( $offset, $value ) {
802 }
803
804 public function offsetUnset( $offset ) {
805 }
806 }
807 }
808