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

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

1,156 lines 24.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class LP_User_Item
5 *
6 * @since 3.0.0
7 */
8 class LP_User_Item extends LP_Abstract_Object_Data implements ArrayAccess {
9 /**
10 * Auto increment
11 *
12 * @var int
13 */
14 public $_user_item_id = 0;
15 /**
16 * User id
17 *
18 * @var string
19 */
20 public $_user_id = 0;
21 /**
22 * Item id (course, lesson, quiz ...)
23 *
24 * @var string
25 */
26 public $_item_id = 0;
27 /**
28 * @var string
29 */
30 public $_start_time = '';
31 /**
32 * @var string
33 */
34 public $_end_time = '';
35 /**
36 * Item type (course, lesson, quiz ...)
37 *
38 * @var string
39 */
40 public $_item_type = '';
41 /**
42 * Status
43 *
44 * @var string
45 */
46 public $_status = '';
47 /**
48 * Graduation
49 *
50 * @var string
51 */
52 public $_graduation = '';
53 /**
54 * Ref id (Order, course ...)
55 *
56 * @var string
57 */
58 public $_ref_id = '';
59 /**
60 * Ref type (Order, course ...)
61 *
62 * @var string
63 */
64 public $_ref_type = '';
65 /**
66 * Parent id
67 *
68 * @var string
69 */
70 public $_parent_id = '';
71
72
73 /**
74 * @var string
75 */
76 protected $_data_key = '';
77
78 /**
79 * LP_User_Item constructor.
80 *
81 * @param array $item . A record fetched from table _learnpress_user_items
82 */
83 public function __construct( $item ) {
84 if ( is_numeric( $item ) ) {
85 $item = array( 'item_id' => $item );
86 } else {
87 $item = (array) $item;
88 }
89
90 // $this->_data = self::get_empty_item();
91
92 parent::__construct( $item );
93 $this->set_default_data( $item );
94
95 }
96
97 /**
98 * Set data from passed args
99 *
100 * @param array $item
101 */
102 protected function set_default_data( $item ) {
103 $this->_changes = array();
104 $item_id = 0;
105
106 if ( ! empty( $item['user_item_id'] ) ) {
107 $this->set_data( 'user_item_id', absint( $item['user_item_id'] ) );
108 }
109
110 if ( ! empty( $item['item_id'] ) ) {
111 $item['item_id'] = absint( $item['item_id'] );
112
113 $this->set_id( $item['item_id'] );
114 $this->set_data( 'item_id', $item['item_id'] );
115 $this->set_data( 'item_type', learn_press_get_post_type( $item['item_id'] ) );
116 $item_id = $item['item_id'];
117 }
118
119 if ( ! empty( $item['start_time'] ) ) {
120 $this->set_start_time( $item['start_time'] );
121 } else {
122 $this->set_start_time( current_time( 'mysql', 1 ) );
123 }
124
125 if ( ! empty( $item['end_time'] ) ) {
126 $this->set_end_time( $item['end_time'] );
127 } else {
128 $this->set_end_time( null );
129 }
130
131 if ( ! empty( $item['user_id'] ) ) {
132 $item['user_id'] = absint( $item['user_id'] );
133
134 $this->set_user_id( $item['user_id'] );
135 } else {
136 $this->set_user_id( get_current_user_id() );
137 }
138
139 if ( ! empty( $item['status'] ) ) {
140 $this->set_status( $item['status'] );
141 } else {
142 $this->set_status( '' );
143 }
144
145 if ( ! empty( $item['ref_id'] ) ) {
146 $item['ref_id'] = absint( $item['ref_id'] );
147
148 $this->set_ref_id( $item['ref_id'] );
149 if ( empty( $item['ref_type'] ) ) {
150 $this->set_data( 'ref_type', learn_press_get_post_type( $item['ref_id'] ) );
151 }
152 }
153
154 if ( ! empty( $item['ref_type'] ) ) {
155 $this->set_data( 'ref_type', $item['ref_type'] );
156 }
157
158 if ( ! empty( $item['parent_id'] ) ) {
159 $item['parent_id'] = absint( $item['parent_id'] );
160
161 $this->set_parent_id( $item['parent_id'] );
162 }
163
164 if ( ! empty( $item['access_level'] ) ) {
165 $this->set_data( 'access_level', $item['access_level'] );
166 }
167
168 if ( ! empty( $item['graduation'] ) ) {
169 $this->set_data( 'graduation', $item['graduation'] );
170 }
171
172 $new_data = $this->get_mysql_data();
173 ksort( $new_data );
174 $this->_data_key = md5( serialize( $new_data ) );
175 }
176
177 public function set_user_id( $user_id ) {
178 $this->set_data( 'user_id', $user_id );
179 }
180
181 public function get_user_id() {
182 return $this->get_data( 'user_id' );
183 }
184
185 public function set_ref_id( $ref_id ) {
186 $this->set_data( 'ref_id', $ref_id );
187 $this->set_data( 'ref_type', learn_press_get_post_type( $ref_id ) );
188 }
189
190 public function get_parent_id() {
191 return absint( $this->get_data( 'parent_id' ) );
192 }
193
194 public function set_parent_id( $parent_id ) {
195 $this->set_data( 'parent_id', $parent_id );
196 }
197
198 /**
199 * Get access level to a course.
200 *
201 * @return int
202 * @since 3.x.x
203 */
204 public function get_access_level() {
205 return absint( $this->get_data( 'access_level' ) );
206 }
207
208 /**
209 * Get type of item. Consider is post-type.
210 *
211 * @return array|mixed
212 */
213 public function get_type() {
214 return $this->get_data( 'item_type' );
215 }
216
217 /**
218 * Set start-time.
219 *
220 * @param mixed $time .
221 *
222 * @return $this
223 */
224 public function set_start_time( $time ) {
225 $this->_set_data_date( 'start_time', $time );
226
227 return $this;
228 }
229
230 public function get_time( $field, $format = '', $human_diff_time = false ) {
231 if ( ! $format ) {
232 $format = get_option( 'date_format' );
233 }
234
235 $m_time = call_user_func( array( $this, 'get_' . $field ) );
236 $time = mysql2date( 'G', call_user_func( array( $this, 'get_' . $field . '_gmt' ) ) );
237 $time_diff = time() - $time;
238
239 if ( $human_diff_time && $time_diff > 0 && $time_diff < DAY_IN_SECONDS ) {
240 $h_time = sprintf( __( '%s ago', 'learnpress' ), human_time_diff( $time ) );
241 } else {
242 $h_time = mysql2date( $format, $m_time );
243 }
244
245 return $h_time;
246 }
247
248 /**
249 * Get start-time.
250 *
251 * @param string $format
252 * @param bool $local
253 *
254 * @return string|LP_Datetime
255 */
256 public function get_start_time( $format = '', $local = false ) {
257 $date = $this->get_data( 'start_time' );
258
259 return $this->format_time( $date, $format, $local );
260 }
261
262 /**
263 * @param $time
264 *
265 * @deprecated 4.0.0
266 */
267 public function set_start_time_gmt( $time ) {
268 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
269 }
270
271 /**
272 * @param string $format
273 *
274 * @return array|bool|LP_Datetime|mixed|string
275 * @deprecated
276 */
277 public function get_start_time_gmt( $format = '' ) {
278 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
279
280 // $date = $this->get_data_date( 'start_time_gmt' );
281 // if ( $format ) {
282 // return $date->is_null() ? false : ( $format = 'i18n' ? learn_press_date_i18n( $date->getTimestamp() ) : $date->format( $format ) );
283 // }
284 //
285 // return $date;
286 }
287
288 /**
289 * Set end-time for item.
290 *
291 * @param mixed $time
292 *
293 * @return $this
294 */
295 public function set_end_time( $time ) {
296 if ( $time && '0000-00-00 00:00:00' !== $time ) {
297 $this->_set_data_date( 'end_time', $time );
298 } else {
299 $this->_set_data( 'end_time', '' );
300 }
301
302 return $this;
303 }
304
305 /**
306 * Get end-time.
307 *
308 * @param string $format
309 *
310 * @return string|LP_Datetime
311 */
312 public function get_end_time( $format = '' ) {
313 $date = $this->get_data( 'end_time' );
314
315 return $this->format_time( $date, $format );
316 }
317
318 public function get_start_time_local() {
319
320 }
321
322 /**
323 * @param string|int|LP_Datetime $date
324 * @param string $format
325 * @param bool $local
326 *
327 * @return bool|float|int|LP_Datetime|string
328 */
329 public function format_time( $date, $format = '', $local = false ) {
330 if ( ! $date ) {
331 return false;
332 }
333
334 if ( ! $date instanceof LP_Datetime ) {
335 $date = new LP_Datetime( $date );
336 }
337
338 return $format ? $date->format( $format, $local ) : $date;
339 }
340
341 /**
342 * Get end-time.
343 *
344 * @param mixed $time
345 *
346 * @deprecated 4.0.0
347 */
348 public function set_end_time_gmt( $time ) {
349 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
350 }
351
352 /**
353 * Get end-time.
354 *
355 * @param string $format
356 *
357 * @return string|LP_Datetime
358 * @deprecated
359 */
360 public function get_end_time_gmt( $format = '' ) {
361 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
362 }
363
364 /**
365 * Get expiration time.
366 *
367 * @param string $format
368 *
369 * @return string|LP_Datetime $time
370 * @since 3.3.0
371 */
372 public function get_expiration_time( $format = '' ) {
373 $duration = get_post_meta( $this->get_item_id(), '_lp_duration', true );
374 $start_time = $this->get_start_time( '', false );
375
376 if ( ! absint( $duration ) || ! $start_time ) {
377 return null;
378 }
379
380 $date = new LP_Datetime( $start_time->getPeriod( $duration, true ) );
381
382 return $this->format_time( $date, $format );
383 }
384
385 /**
386 * Set item-status.
387 *
388 * @param string $status .
389 *
390 * @return $this
391 */
392 public function set_status( string $status ): LP_User_Item {
393 $this->_set_data( 'status', $status );
394
395 return $this;
396 }
397
398 /**
399 * Get item status.
400 *
401 * @param string $field
402 * @param bool $force_cache Reset first cache
403 *
404 * @version 1.0.1
405 * @return string
406 * @editor tungnx
407 * @modify 4.1.3
408 */
409 public function get_status( string $field = 'status', bool $force_cache = false ): string {
410 /*if ( ! is_null( $this->get_data( $field, null ) && ! $force_cache ) ) {
411 return $this->get_data( $field );
412 }*/
413
414 $got_status = '';
415
416 try {
417 // User is Guest
418 if ( (int) $this->get_user_id() === 0 ) {
419 return $got_status;
420 }
421
422 $lp_user_item = LP_User_Items_DB::getInstance();
423 $filter = new LP_User_Items_Filter();
424
425 $filter->user_id = $this->get_user_id();
426 $filter->item_id = $this->get_item_id();
427 $filter->ref_id = $this->get_data( 'ref_id' );
428 $filter->parent_id = $this->get_parent_id();
429
430 $user_item = $lp_user_item->get_user_course_item( $filter, $force_cache );
431
432 if ( ! empty( $user_item ) && isset( $user_item->$field ) ) {
433 $got_status = $user_item->$field;
434 }
435
436 $this->set_data( $field, $got_status );
437 } catch ( Throwable $e ) {
438 LP_Debug::error_log( __FUNCTION__ . ':' . $e->getMessage() );
439 }
440
441 return $got_status;
442 }
443
444 public function is_exists() {
445 return ! ! $this->get_user_item_id();
446 }
447
448 /**
449 * @editor tungnx
450 * @reason comment - not use
451 */
452 /*
453 public function is_available() {
454 if ( null === $this->_is_available ) {
455 $user = $this->get_user();
456 $order = $user->get_course_order( $this->get_item_id() );
457 $this->_is_available = $order && ( $order->get_status() === 'completed' ) && $this->is_exists();
458 }
459
460 return $this->_is_available;
461 }*/
462
463 /**
464 * @param string $return
465 *
466 * @return LP_User|int
467 */
468 public function get_user( $return = '' ) {
469 return $this->get_data( 'user_id', 0 );
470 }
471
472 public function get_course( $return = '' ) {
473 $cid = $this->get_data( 'ref_id' );
474 if ( $return == '' ) {
475 return $cid ? learn_press_get_course( $cid ) : false;
476 }
477
478 return $cid;
479 }
480
481 /**
482 * @return int
483 */
484 public function get_user_item_id() {
485 return intval( $this->get_data( 'user_item_id' ) );
486 }
487
488 /**
489 * Change the primary key user_item_id of user-items.
490 * Only use zero value to force creating new item.
491 *
492 * @param int $user_item_id
493 */
494 public function set_user_item_id( $user_item_id ) {
495 $this->_set_data( 'user_item_id', absint( $user_item_id ) );
496 }
497
498 public function get_item_id() {
499 return $this->get_data( 'item_id' );
500 }
501
502 public function get_parent() {
503 $user = learn_press_get_user( $this->get_user_id() );
504 $ref_id = $this->get_data( 'ref_id' );
505
506 if ( get_post_type( $ref_id ) === LP_COURSE_CPT ) {
507 return $user->get_course_data( $ref_id );
508 }
509
510 return false;
511 }
512
513 public function get_result( $prop = 'result' ) {
514 $result = array(
515 'result' => $this->is_completed() ? 100 : 0,
516 'grade' => $this->is_completed() ? 'passed' : 'failed',
517 );
518
519 return $prop && array_key_exists( $prop, $result ) ? $result[ $prop ] : $result;
520 }
521
522 public function read_meta() {
523 global $wpdb;
524 $query = $wpdb->prepare(
525 "
526 SELECT *
527 FROM {$wpdb->learnpress_user_itemmeta}
528 WHERE learnpress_user_item_id = %d
529 ",
530 $this->get_user_item_id()
531 );
532
533 $results = $wpdb->get_results( $query );
534 if ( $results ) {
535 foreach ( $results as $result ) {
536 $result->meta_value = LP_Helper::maybe_unserialize( $result->meta_value );
537 $this->_meta_data[] = $result;
538 }
539 }
540
541 }
542
543 /**
544 * Get structure of an user item.
545 *
546 * @return array
547 * @since 3.1.0
548 */
549 public static function get_empty_item() {
550 return array(
551 'user_item_id' => 0,
552 'user_id' => 0,
553 'item_id' => 0,
554 'start_time' => '',
555 'end_time' => '',
556 'item_type' => '',
557 'status' => '',
558 'graduation' => '',
559 'access_level' => 50,
560 'ref_id' => '',
561 'ref_type' => '',
562 'parent_id' => 0,
563 );
564 }
565
566 /**
567 * Get user-item meta data.
568 * Check if meta data does not exist then return FALSE.
569 *
570 * @updated 3.1.0
571 *
572 * @param string $key
573 * @param bool $single
574 *
575 * @return bool|mixed
576 */
577 public function get_meta( $key, $single = true ) {
578 if ( ! metadata_exists( 'learnpress_user_item', $this->get_user_item_id(), $key ) ) {
579 return false;
580 }
581
582 return learn_press_get_user_item_meta( $this->get_user_item_id(), $key, $single );
583 }
584
585 /**
586 * Update meta data
587 *
588 * @updated 3.1.0
589 *
590 * @param string $key
591 * @param string $value
592 * @param string $prev_value
593 *
594 * @editor tungnx add bk method
595 */
596 public function update_meta_bk( $key = '', $value = '', $prev_value = '' ) {
597 if ( func_num_args() === 0 ) {
598 if ( $this->_meta_data ) {
599 foreach ( $this->_meta_data as $meta_data ) {
600 if ( $meta_data->meta_value ) {
601 learn_press_update_user_item_meta(
602 $this->get_user_item_id(),
603 $meta_data->meta_key,
604 $meta_data->meta_value
605 );
606 } else {
607 learn_press_delete_user_item_meta( $this->get_user_item_id(), $meta_data->meta_key );
608 }
609 }
610 }
611 } else {
612 if ( is_array( $key ) ) {
613 foreach ( $key as $k => $v ) {
614 if ( $v === false ) {
615 learn_press_delete_user_item_meta( $this->get_user_item_id(), $k );
616 } else {
617 learn_press_update_user_item_meta( $this->get_user_item_id(), $k, $v );
618 }
619 }
620 } else {
621 if ( $value === false ) {
622 learn_press_delete_user_item_meta( $this->get_user_item_id(), $key );
623 } else {
624 learn_press_update_user_item_meta( $this->get_user_item_id(), $key, $value, $prev_value );
625 }
626 }
627 }
628 }
629
630 /**
631 * Update meta data
632 *
633 * @param string $key .
634 * @param string $value .
635 * @param string $prev_value .
636 *
637 * @return int|bool
638 * @editor tungnx
639 */
640 public function update_meta( $key = '', $value = '', $prev_value = '' ) {
641 $result = false;
642
643 if ( is_array( $key ) ) {
644 $result = $this->update_meta_multiple_keys( $key );
645 } else {
646 if ( false === $value ) {
647 $result = learn_press_delete_user_item_meta( $this->get_user_item_id(), $key );
648 } else {
649 $result = learn_press_update_user_item_meta( $this->get_user_item_id(), $key, $value, $prev_value );
650 }
651 }
652
653 return $result;
654 }
655
656 /**
657 * Update metadata with array keys values
658 *
659 * @param array $meta_datas .
660 *
661 * @return bool|int
662 */
663 public function update_meta_multiple_keys( $meta_datas = array() ) {
664 $result = false;
665
666 foreach ( $meta_datas as $k => $v ) {
667 if ( false === $v ) {
668 $result = learn_press_delete_user_item_meta( $this->get_user_item_id(), $k );
669 } else {
670 $result = learn_press_update_user_item_meta( $this->get_user_item_id(), $k, $v );
671 }
672 }
673
674 return $result;
675 }
676
677 public function get_mysql_data() {
678 /**
679 * @var LP_Datetime $v
680 */
681 $columns = array();
682
683 foreach ( $this->get_data() as $k => $v ) {
684 switch ( $k ) {
685 case 'start_time':
686 case 'end_time':
687 $v = is_a( $v, 'LP_Datetime' ) ? $v->toSql( false ) : $v;
688 break;
689 }
690 $columns[ $k ] = $v;
691 }
692
693 return $columns;
694 }
695
696 /**
697 * @param $data
698 *
699 * @return LP_User_Item|bool
700 */
701 public static function get_item_object( $data ) {
702 $item_id = 0;
703
704 if ( is_array( $data ) && isset( $data['item_id'] ) ) {
705 $item_id = $data['item_id'];
706 } elseif ( is_object( $data ) && isset( $data->item_id ) ) {
707 $item_id = $data->item_id;
708 } elseif ( is_numeric( $data ) ) {
709 $item_id = absint( $data );
710 } elseif ( $data instanceof LP_User_Item ) {
711 $item_id = $data->get_id();
712 }
713
714 $item = false;
715 $item_type = learn_press_get_post_type( $item_id );
716
717 switch ( $item_type ) {
718 case LP_LESSON_CPT:
719 $item = new LP_User_Item( $data );
720 break;
721 case LP_QUIZ_CPT:
722 $item = new LP_User_Item_Quiz( $data );
723 break;
724 default:
725 break;
726 }
727
728 return apply_filters( 'learn-press/user-item-object', $item, $data, $item_type );
729 }
730
731 /**
732 * Set graduation
733 *
734 * @param string $graduation .
735 *
736 * @return $this
737 */
738 public function set_graduation( string $graduation ): LP_User_Item {
739 $this->_set_data( 'graduation', $graduation );
740
741 return $this;
742 }
743
744 /**
745 * Get graduation
746 *
747 * @return string|null
748 */
749 public function get_graduation() {
750 return $this->get_data( 'graduation', '' );
751 }
752
753 /**
754 * Update data from memory to database.
755 *
756 * @updated 3.1.0
757 *
758 * @return bool|mixed
759 * @throws Exception
760 */
761 public function update( $force = false, $wp_error = false ) {
762
763 $data = $this->get_mysql_data();
764
765 /**
766 * @since 3.3.0
767 * Allow filter to modify data
768 */
769 $data = apply_filters( 'learn-press/update-user-item-data', $data, $this->get_user_item_id() );
770 $where = array();
771
772 if ( $this->get_user_item_id() ) {
773 $where = array( 'user_item_id' => $this->get_user_item_id() );
774 }
775
776 $return = learn_press_update_user_item_field( $data, $where );
777
778 // Clear cache first status
779 $this->get_status( 'status', true );
780
781 if ( $return ) {
782 foreach ( (array) $return as $k => $v ) {
783 $this->_set_data( $k, $v );
784 }
785 $this->_changes = array();
786 }
787
788 /*$data_course = $this->get_parent();
789 if ( $data_course ) {
790 $data_course->calculate_course_results();
791 }*/
792
793 return $return;
794 }
795
796 /**
797 * @editor tungnx
798 * @reason commnet - not use
799 * @modify 4.1.2
800 */
801 /*
802 public function is_course_item() {
803 return learn_press_is_support_course_item_type( $this->get_data( 'item_type' ) );
804 }*/
805
806 public function get_status_label( $status = '' ) {
807 $statuses = array(
808 LP_COURSE_ENROLLED => esc_html__( 'Enrolled', 'learnpress' ),
809 LP_COURSE_PURCHASED => esc_html__( 'Purchased', 'learnpress' ),
810 LP_ITEM_COMPLETED => esc_html__( 'Completed', 'learnpress' ),
811 LP_ITEM_STARTED => esc_html__( 'Started', 'learnpress' ),
812 LP_COURSE_FINISHED => esc_html__( 'Finished', 'learnpress' ),
813 );
814
815 if ( ! $status ) {
816 $status = $this->get_status();
817 }
818
819 return ! empty( $statuses[ $status ] ) ? $statuses[ $status ] : esc_html__( 'Not Enrolled', 'learnpress' );
820 }
821
822 /**
823 * Get time from user started to ended.
824 *
825 * @param string $context
826 *
827 * @return bool|float|int
828 */
829 public function get_time_interval( $context = '' ) {
830 $start = $this->get_start_time();
831 $end = $this->get_end_time();
832
833 if ( ! $start instanceof LP_Datetime || ! $end instanceof LP_Datetime ) {
834 return false;
835 }
836
837 if ( $start->is_null() || $end->is_null() ) {
838 return false;
839 }
840 $interval = $end->getTimestamp() - $start->getTimestamp();
841
842 return $interval;
843 }
844
845 public function get_history() {
846 return LP_Object_Cache::get(
847 sprintf(
848 'course-item-%s-%s-%s',
849 $this->get_user_id(),
850 $this->get_course( 'id' ),
851 $this->get_id()
852 ),
853 'learn-press/user-course-items'
854 );
855 }
856
857 /**
858 * @editor tungnx
859 * @modify 4.1.2
860 * @reason comment - not use
861 */
862 /*
863 public function count_history() {
864 if ( $items = $this->get_history() ) {
865 return sizeof( $items );
866 }
867
868 return 0;
869 }*/
870
871 /**
872 * @editor tungnx
873 * @modify 4.1.2
874 * @reason comment - not use
875 */
876 /*
877 public function remove_user_items_history( $keep = 10 ) {
878 learn_press_remove_user_items_history(
879 $this->get_item_id(),
880 $this->get_course( 'id' ),
881 $this->get_user_id(),
882 $keep
883 );
884 }*/
885
886 /**
887 * Return number of seconds has exceeded from the expiration time to now.
888 * If less than or equals to 0 that means the time is exceeded.
889 * Otherwise, the time is not exceeded.
890 *
891 * @return float|int
892 * @since 3.3.0
893 */
894 public function get_exceeded() {
895 $time = new LP_Datetime();
896 $current = $time->getTimestamp( false );
897 $exceeded = $this->get_expiration_time();
898
899 return false !== $exceeded ? $exceeded->getTimestamp() - $current : false;
900 }
901
902 /**
903 * Check if user was finished before the expiration time is exceeded.
904 * If the expiration-time is NULL that mean the course is not set duration.
905 *
906 * @return bool|float|int
907 * @since 3.3.0
908 * Todo: check remove function
909 */
910 public function is_exceeded() {
911 $expiration = $this->get_expiration_time();
912 $end = $this->get_end_time();
913
914 if ( ! $expiration ) {
915 return false;
916 }
917
918 // If course is not finished then consider end time is current time
919 if ( ! $end || 0 >= $end->getTimestamp() ) {
920 $end = new LP_Datetime();
921 $end = $end->getTimestamp( false );
922 } else {
923 $end = $end->getTimestamp();
924 }
925
926 return $expiration->getTimestamp() - $end;
927 }
928
929 /**
930 * Get time remaining for user item.
931 *
932 * @param string $return - Optional. What kind of data to return.
933 *
934 * @return LP_Duration
935 * @since 3.3.0
936 */
937 public function get_time_remaining( $return = 'object' ) {
938 $is_exceeded = $this->is_exceeded();
939 $time = false;
940
941 if ( false !== $is_exceeded ) {
942 $time = 0 < $is_exceeded ? absint( $is_exceeded ) : 0;
943 }
944
945 // return apply_filters( 'learn-press/quiz/time-remaining', $remaining, $this->get_item_id(), $this->get_course_id() );
946 return apply_filters(
947 'learn-press/user-item-time-remaining',
948 $return === 'object' ? new LP_Duration( $time ) : $time,
949 $this->get_item_id(),
950 $this->get_parent_id(),
951 $this->get_user_id()
952 );
953 }
954
955 /**
956 * Return true of item is completed/finished
957 *
958 * @param string $status
959 *
960 * @return bool
961 */
962 public function is_completed( $status = 'completed' ) {
963 return $this->get_status() === $status;
964 }
965
966 /**
967 * Complete item
968 *
969 * @editor tungnx
970 * @modify 4.1.4.1 - should review to improve
971 * @version 4.0.1
972 */
973 public function complete( $status = 'completed' ) {
974 global $wpdb;
975
976 // $end_time = new LP_Datetime();
977 // $null_time = null;
978
979 try {
980 // if ( ! $this->get_end_time() ) {
981 $this->set_end_time( current_time( 'mysql', 1 ) );
982 // }
983
984 $this->set_status( $status );
985 $this->update();
986
987 /*
988 $query = $wpdb->prepare(
989 "SELECT user_item_id
990 FROM {$wpdb->prefix}learnpress_user_items
991 WHERE user_id = %d
992 AND item_id = %d
993 AND status = %s
994 GROUP BY user_item_id DESC
995 LIMIT 1
996 ",
997 $this->get_user_id(),
998 $this->get_item_id(),
999 $status
1000 );
1001
1002 return $wpdb->get_var( $query );*/
1003 } catch ( Throwable $e ) {
1004 error_log( __FUNCTION__ . ':' . $e->getMessage() );
1005 return false;
1006 }
1007
1008 return true;
1009 }
1010
1011 /**
1012 * @editor tungnx
1013 * @modify 4.1.2
1014 * @reason comment - not use
1015 */
1016 /*
1017 public function delete_meta_data( $include = '', $exclude = '' ) {
1018 global $wpdb;
1019
1020 $where = '';
1021 if ( $include ) {
1022 settype( $include, 'array' );
1023 $format = array_fill( 0, sizeof( $include ), '%s' );
1024 $where .= $wpdb->prepare( ' AND meta_key IN(' . join( ',', $format ) . ')', $include );
1025 }
1026
1027 if ( $exclude ) {
1028 settype( $exclude, 'array' );
1029 $format = array_fill( 0, sizeof( $exclude ), '%s' );
1030 $where .= $wpdb->prepare( ' AND meta_key IN(' . join( ',', $format ) . ')', $exclude );
1031 }
1032
1033 $query = $wpdb->prepare(
1034 "
1035 DELETE FROM {$wpdb->learnpress_user_itemmeta}
1036 WHERE learnpress_user_item_id = %d
1037 {$where}
1038 ",
1039 $this->get_user_item_id()
1040 );
1041
1042 $wpdb->query( $query );
1043
1044 $this->_meta_data = array();
1045 update_meta_cache( 'learnpress_user_item', $this->get_user_item_id() );
1046 }*/
1047
1048 /**
1049 * Get post type of item.
1050 *
1051 * @return string
1052 */
1053 public function get_post_type() {
1054 return learn_press_get_post_type( $this->get_item_id() );
1055 }
1056
1057 /**
1058 * @return bool
1059 */
1060 public function is_passed() {
1061 return 'passed' === $this->get_graduation();
1062 }
1063
1064 public function get_percent_result( $decimal = 1 ) {
1065 return apply_filters(
1066 'learn-press/user/item-percent-result',
1067 sprintf(
1068 '%s%%',
1069 round( $this->get_result( 'result' ), $decimal ),
1070 $this->get_user_id(),
1071 $this->get_item_id()
1072 )
1073 );
1074 }
1075
1076 /**
1077 * Calculate expiration time from the start time and duration.
1078 *
1079 * @param int|string|LP_Datetime $duration
1080 *
1081 * @return LP_Datetime
1082 * @since 3.3.0
1083 */
1084 public function set_duration( $duration ) {
1085 if ( $duration instanceof LP_Datetime ) {
1086 $period = $duration->toSql();
1087 } else {
1088 $period = $duration;
1089 }
1090
1091 return $this->get_expiration_time();
1092 }
1093
1094 public function is_change() {
1095
1096 $new_data = $this->get_mysql_data();
1097 ksort( $new_data );
1098
1099 return $this->_data_key !== md5( serialize( $new_data ) );
1100 }
1101
1102 protected function _set_data_date( $key, $value, $extra = false ) {
1103 if ( $value instanceof LP_Datetime ) {
1104 $value = $value->getTimestamp();
1105 } else {
1106 $value = is_numeric( $value ) ? $value : strtotime( $value );
1107 }
1108 $offset = (int) ( get_option( 'gmt_offset', 0 ) * HOUR_IN_SECONDS );
1109
1110 parent::_set_data_date( $key, $value + $offset, $extra );
1111 }
1112
1113 /**
1114 * @param $name
1115 * @param $arguments
1116 *
1117 * @return mixed
1118 */
1119 public function __call( $name, $arguments ) {
1120 if ( ! method_exists( $this, $name ) ) {
1121 $course = $this->get_course();
1122
1123 if ( $course ) {
1124 $item = $course->get_item( $this->get_item_id() );
1125
1126 if ( is_callable( array( $item, $name ) ) ) {
1127 return call_user_func_array( array( $item, $name ), $arguments );
1128 }
1129 }
1130 }
1131
1132 return false;
1133 }
1134
1135 public function offsetSet( $offset, $value ) {
1136 // TODO: Implement offsetSet() method.
1137 }
1138
1139 public function offsetGet( $offset ) {
1140 if ( is_callable( array( $this, 'get_' . $offset ) ) ) {
1141 return call_user_func( array( $this, 'get_' . $offset ) );
1142 }
1143
1144 return false;
1145 }
1146
1147 public function offsetUnset( $offset ) {
1148 // TODO: Implement offsetUnset() method.
1149 }
1150
1151 public function offsetExists( $offset ) {
1152 // TODO: Implement offsetExists() method.
1153 }
1154 }
1155
1156