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.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 / Models / UserItems / UserItemModel.php

UserItemModel.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.3.7, at inc/Models/UserItems/UserItemModel.php

598 lines 14.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class UserItemModel
5 * To replace class LP_User_Item
6 *
7 * @package LearnPress/Classes
8 * @version 1.0.3
9 * @since 4.2.5
10 */
11
12 namespace LearnPress\Models\UserItems;
13
14 use Exception;
15 use LearnPress\Filters\UserItemsFilter;
16 use LearnPress\Models\CoursePostModel;
17 use LearnPress\Models\PostModel;
18 use LearnPress\Models\UserItemMeta\UserItemMetaModel;
19 use LearnPress\Models\UserModel;
20 use LP_Datetime;
21 use LP_User_Item_Meta_DB;
22 use LP_User_Item_Meta_Filter;
23 use LP_User_Items_Cache;
24 use LP_User_Items_DB;
25 use LP_User_Items_Filter;
26 use stdClass;
27 use Throwable;
28
29 class UserItemModel {
30 /**
31 * Auto increment, Primary key
32 *
33 * @var int
34 */
35 private $user_item_id = 0;
36 /**
37 * @var string User ID, foreign key
38 */
39 public $user_id = 0;
40 /**
41 * Item id (course, lesson, quiz ...)
42 *
43 * @var string foreign key
44 */
45 public $item_id = 0;
46 /**
47 * @var string Time start item
48 */
49 public $start_time = null;
50 /**
51 * @var string Time finish item
52 */
53 public $end_time = null;
54 /**
55 * Item type (course, lesson, quiz ...)
56 *
57 * @var string Item type
58 */
59 public $item_type = '';
60 /**
61 * Item status (completed, enrolled, finished ...)
62 *
63 * @var string
64 */
65 public $status = '';
66 /**
67 * Item graduation
68 *
69 * @var string (passed, failed, in-progress...)
70 */
71 public $graduation = null;
72 /**
73 * Ref id (Order, course ...)
74 *
75 * @var int Reference id
76 */
77 public $ref_id = 0;
78 /**
79 * Ref type (Order, course ...)
80 *
81 * @var string
82 */
83 public $ref_type = '';
84 /**
85 * Parent id
86 *
87 * @var int
88 */
89 public $parent_id = 0;
90 /**
91 * @var null|PostModel|CoursePostModel
92 */
93 public $item;
94 /**
95 * List UserItemMetaModel
96 * object {meta_key: {meta_id, learnpress_user_item_id, meta_key, meta_value, extra_value}}
97 *
98 * @var {meta_key: UserItemMetaModel}
99 */
100 public $meta_data;
101
102 // Constants
103 const STATUS_COMPLETED = 'completed';
104 const STATUS_FINISHED = 'finished';
105 const STATUS_ENROLLED = 'enrolled';
106 const STATUS_PURCHASED = 'purchased';
107 const STATUS_CANCEL = 'cancel';
108 const GRADUATION_IN_PROGRESS = 'in-progress';
109 const GRADUATION_PASSED = 'passed';
110 const GRADUATION_FAILED = 'failed';
111
112 /**
113 * If data get from database, map to object.
114 * Else create new object to save data to database.
115 *
116 * @param array|object|mixed $data
117 */
118 public function __construct( $data = null ) {
119 if ( $data ) {
120 $this->map_to_object( $data );
121 $this->get_user_model();
122 }
123
124 if ( ! $this->meta_data instanceof stdClass ) {
125 $this->meta_data = new stdClass();
126 }
127 }
128
129 /**
130 * Get start time
131 *
132 * @return string
133 */
134 public function get_start_time(): string {
135 return is_null( $this->start_time ) ? '' : $this->start_time;
136 }
137
138 /**
139 * Get end time
140 *
141 * @return string
142 */
143 public function get_end_time(): string {
144 return is_null( $this->end_time ) ? '' : $this->end_time;
145 }
146
147 /**
148 * Get status
149 *
150 * @return string
151 */
152 public function get_status(): string {
153 return $this->status;
154 }
155
156 /**
157 * Get graduation
158 *
159 * @return string
160 */
161 public function get_graduation(): string {
162 return is_null( $this->graduation ) ? '' : $this->graduation;
163 }
164
165
166 /**
167 * Get user item id
168 *
169 * @return int
170 */
171 public function get_user_item_id(): int {
172 return $this->user_item_id;
173 }
174
175 /**
176 * Set user item id
177 *
178 * @param int $user_item_id
179 */
180 private function set_user_item_id( int $user_item_id ) {
181 $this->user_item_id = $user_item_id;
182 }
183
184 /**
185 * Get user model
186 *
187 * @return false|UserModel
188 * @since 4.2.6
189 * @version 1.0.1
190 */
191 public function get_user_model() {
192 return UserModel::find( $this->user_id, true );
193 }
194
195 /**
196 * Map array, object data to UserItemModel.
197 * Use for data get from database.
198 *
199 * @param array|object|mixed $data
200 *
201 * @return UserItemModel
202 */
203 public function map_to_object( $data ): UserItemModel {
204 foreach ( $data as $key => $value ) {
205 if ( property_exists( $this, $key ) ) {
206 $this->{$key} = $value;
207 }
208 }
209
210 return $this;
211 }
212
213 /**
214 * Get user item from database by user_id, item_id, item_type.
215 * If not exists, return false.
216 * If exists, return UserItemModel.
217 *
218 * @param LP_User_Items_Filter|UserItemsFilter $filter
219 *
220 * @return UserItemModel|false|static
221 * @since 4.2.5
222 * @version 1.0.2
223 */
224 public static function get_user_item_model_from_db( $filter ) {
225 $lp_user_item_db = LP_User_Items_DB::getInstance();
226 $user_item_model = false;
227
228 try {
229 // Set order by user_item_id DESC to get the latest user item.
230 $filter->order = $filter::ORDER_DESC;
231 $filter->order_by = $filter::COL_USER_ITEM_ID;
232 if ( empty( $filter->item_type ) ) {
233 $filter->item_type = ( new static() )->item_type;
234 }
235
236 $lp_user_item_db->get_query_single_row( $filter );
237 $query_single_row = $lp_user_item_db->get_user_items( $filter );
238 $user_item_rs = $lp_user_item_db->wpdb->get_row( $query_single_row );
239 if ( $user_item_rs instanceof stdClass ) {
240 $user_item_model = new static( $user_item_rs );
241 }
242 } catch ( Throwable $e ) {
243 error_log( __METHOD__ . ': ' . $e->getMessage() );
244 }
245
246 return $user_item_model;
247 }
248
249 /**
250 * Find User Item by user_id, item_id, item_type.
251 *
252 * @param int $user_id
253 * @param int $item_id
254 * @param string $item_type
255 * @param int $ref_id
256 * @param string $ref_type
257 * @param bool $check_cache
258 *
259 * @return false|UserItemModel|static
260 * @since 4.2.7.3
261 * @version 1.0.2
262 */
263 public static function find_user_item(
264 int $user_id,
265 int $item_id,
266 string $item_type,
267 int $ref_id = 0,
268 string $ref_type = '',
269 bool $check_cache = false
270 ) {
271 $key_cache = "userItemModel/find/{$user_id}/{$item_id}/{$item_type}";
272 $filter = new LP_User_Items_Filter();
273 $filter->user_id = $user_id;
274 $filter->item_id = $item_id;
275 $filter->item_type = $item_type;
276 if ( ! empty( $ref_id ) ) {
277 $filter->ref_id = $ref_id;
278 $key_cache .= "/{$ref_id}";
279 }
280 if ( ! empty( $ref_type ) ) {
281 $filter->ref_type = $ref_type;
282 $key_cache .= "/{$ref_type}";
283 }
284 $lpUserItemCache = new LP_User_Items_Cache();
285
286 // Check cache
287 if ( $check_cache ) {
288 $userItemModel = $lpUserItemCache->get_cache( $key_cache );
289 if ( $userItemModel instanceof UserItemModel ) {
290 return new static( $userItemModel );
291 }
292 }
293
294 $userItemModel = static::get_user_item_model_from_db( $filter );
295 // Set cache
296 if ( $userItemModel instanceof UserItemModel ) {
297 if ( ! $userItemModel->meta_data instanceof stdClass ) {
298 $userItemModel->meta_data = new stdClass();
299 }
300
301 $lpUserItemCache->set_cache( $key_cache, $userItemModel );
302 }
303
304 return $userItemModel;
305 }
306
307 /**
308 * Get user item metadata from object meta_data or database by user_item_id, meta_key.
309 *
310 * @param string $key
311 *
312 * @return false|UserItemMetaModel
313 * @since 4.2.5
314 * @version 1.0.1
315 */
316 public function get_meta_model_from_key( string $key ) {
317 $filter = new LP_User_Item_Meta_Filter();
318 $filter->meta_key = $key;
319 $filter->learnpress_user_item_id = $this->get_user_item_id();
320
321 return UserItemMetaModel::get_user_item_meta_model_from_db( $filter );
322 }
323
324 /**
325 * Get metadata from key
326 *
327 * @param string $key
328 * @param mixed $default_value
329 * @param bool $get_extra
330 *
331 * @return false|string
332 * @since 4.2.5
333 * @version 1.0.3
334 */
335 public function get_meta_value_from_key( string $key, $default_value = false, bool $get_extra = false ) {
336 if ( $this->meta_data instanceof stdClass && isset( $this->meta_data->{$key} ) ) {
337 return maybe_unserialize( $this->meta_data->{$key} );
338 }
339
340 $user_item_metadata = $this->get_meta_model_from_key( $key );
341 if ( $user_item_metadata instanceof UserItemMetaModel ) {
342 if ( ! $this->meta_data instanceof stdClass ) {
343 $this->meta_data = new stdClass();
344 }
345
346 if ( $get_extra ) {
347 $data = $user_item_metadata->extra_value;
348 } else {
349 $data = $user_item_metadata->meta_value;
350 }
351
352 $this->meta_data->{$key} = maybe_unserialize( $data );
353 } else {
354 $data = $default_value;
355 }
356
357 return $data;
358 }
359
360 /**
361 * Update meta value for key.
362 *
363 * @param string $key
364 * @param mixed $value
365 * @param bool $is_extra
366 *
367 * @return void
368 * @since 4.2.7.4
369 * @version 1.0.0
370 */
371 public function set_meta_value_for_key( string $key, $value, bool $is_extra = false ) {
372 if ( ! $this->meta_data instanceof stdClass ) {
373 $this->meta_data = new stdClass();
374 }
375
376 $this->meta_data->{$key} = $value;
377 $lp_db = LP_User_Items_DB::getInstance();
378 if ( $is_extra ) {
379 if ( is_object( $value ) || is_array( $value ) ) {
380 $value = json_encode( $value );
381 }
382 $lp_db->update_extra_value( $this->get_user_item_id(), $key, $value );
383 } else {
384 learn_press_update_user_item_meta( $this->get_user_item_id(), $key, $value );
385 }
386
387 //$this->clean_caches();
388 }
389
390 /**
391 * Delete meta from key.
392 *
393 * @param string $key
394 *
395 * @return void
396 * @since 4.2.7.4
397 * @version 1.0.0
398 */
399 public function delete_meta( string $key ) {
400 $user_item_metadata = $this->get_meta_model_from_key( $key );
401 if ( $user_item_metadata instanceof UserItemMetaModel ) {
402 $user_item_metadata->delete();
403 $this->meta_data->{$key} = null;
404 $this->clean_caches();
405 }
406 }
407
408 /**
409 * Update data to database.
410 *
411 * If user_item_id is empty, insert new data, else update data.
412 *
413 * @return UserItemModel
414 * @throws Exception
415 * @since 4.2.5
416 * @version 1.0.3
417 */
418 public function save(): UserItemModel {
419 $lp_user_item_db = LP_User_Items_DB::getInstance();
420 $user_item_id_new = 0;
421 $data = get_object_vars( $this );
422
423 if ( ! isset( $data['start_time'] ) ) {
424 $data['start_time'] = gmdate( 'Y-m-d H:i:s', time() );
425 $this->start_time = $data['start_time'];
426 }
427
428 // Check if exists user_item_id.
429 if ( empty( $this->get_user_item_id() ) ) { // Insert data.
430 if ( empty( $data['item_id'] ) ) {
431 throw new Exception( 'Item ID is require.' );
432 }
433 if ( empty( $data['item_type'] ) ) {
434 throw new Exception( 'Item Type is require.' );
435 }
436
437 // Guest can buy course if enable guest checkout.
438 if ( empty( $data['user_id'] ) && LP_COURSE_CPT !== $data['item_type'] ) {
439 throw new Exception( 'User ID is require.' );
440 }
441
442 $user_item_id_new = $lp_user_item_db->insert_data( $data );
443 if ( empty( $user_item_id_new ) ) {
444 throw new Exception( 'Cannot insert data to database.' );
445 }
446 } else { // Update data.
447 $lp_user_item_db->update_data( $data );
448 }
449
450 if ( $user_item_id_new ) {
451 $this->set_user_item_id( $user_item_id_new );
452 }
453
454 // Clear caches.
455 $this->clean_caches();
456
457 return $this;
458 }
459
460 /**
461 * Get total timestamp complete, done item.
462 *
463 * @return int
464 */
465 public function get_total_timestamp_completed(): int {
466 $time_interval = 0;
467
468 if ( empty( $this->get_start_time() ) || empty( $this->get_end_time() ) ) {
469 return $time_interval;
470 }
471
472 $start = new LP_Datetime( $this->get_start_time() );
473 $end = new LP_Datetime( $this->get_end_time() );
474
475 return $end->getTimestamp() - $start->getTimestamp();
476 }
477
478 /**
479 * Get expiration time.
480 *
481 * @return null|LP_Datetime $time
482 * @since 3.3.0
483 * @version 3.3.3
484 */
485 public function get_expiration_time() {
486 $duration = get_post_meta( $this->item_id, '_lp_duration', true );
487
488 if ( ! absint( $duration ) || empty( $this->start_time ) ) {
489 $expire = null;
490 } else {
491 $start = new LP_Datetime( $this->start_time );
492 $start_time = $start->getTimestamp();
493 // Convert duration from string to seconds.
494 if ( ! is_numeric( $duration ) ) {
495 $duration = strtotime( $duration ) - time();
496 }
497
498 $expire_time = $start_time + $duration;
499 $expire = new LP_Datetime( $expire_time );
500 }
501
502 return apply_filters( 'learnPress/user-item/expiration-time', $expire, $duration, $this );
503 }
504
505 /**
506 * Get translate value.
507 *
508 * @param string $value
509 *
510 * @return string
511 * @since 4.2.7.8
512 * @version 1.0.0
513 */
514 public function get_string_i18n( string $value ): string {
515 switch ( $value ) {
516 case self::STATUS_COMPLETED:
517 $value = __( 'Completed', 'learnpress' );
518 break;
519 case self::STATUS_FINISHED:
520 $value = __( 'Finished', 'learnpress' );
521 break;
522 case self::STATUS_ENROLLED:
523 $value = __( 'Enrolled', 'learnpress' );
524 break;
525 case self::STATUS_CANCEL:
526 $value = __( 'Cancel', 'learnpress' );
527 break;
528 case self::GRADUATION_IN_PROGRESS:
529 $value = __( 'In Progress', 'learnpress' );
530 break;
531 case self::GRADUATION_PASSED:
532 $value = __( 'Passed', 'learnpress' );
533 break;
534 case self::GRADUATION_FAILED:
535 $value = __( 'Failed', 'learnpress' );
536 break;
537 }
538
539 return $value;
540 }
541
542 /**
543 * Delete user item.
544 *
545 * @throws Exception
546 * @since 4.2.7.3
547 * @version 1.0.2
548 */
549 public function delete() {
550 // Delete meta data of user item.
551 $lp_user_item_meta_db = LP_User_Item_Meta_DB::getInstance();
552 $filter = new LP_User_Item_Meta_Filter();
553 $filter->where[] = $lp_user_item_meta_db->wpdb->prepare( 'AND learnpress_user_item_id = %d', $this->get_user_item_id() );
554 $filter->collection = $lp_user_item_meta_db->tb_lp_user_itemmeta;
555 $lp_user_item_meta_db->delete_execute( $filter );
556 $this->meta_data = null;
557
558 // Delete user item relationships.
559 $lp_user_item_db = LP_User_Items_DB::getInstance();
560 $filter = new LP_User_Items_Filter();
561 $filter->where[] = $lp_user_item_db->wpdb->prepare( 'AND parent_id = %d', $this->get_user_item_id() );
562 $filter->collection = $lp_user_item_db->tb_lp_user_items;
563 $lp_user_item_db->delete_execute( $filter );
564
565 // Delete user item.
566 $lp_user_item_db = LP_User_Items_DB::getInstance();
567 $filter = new LP_User_Items_Filter();
568 $filter->where[] = $lp_user_item_db->wpdb->prepare( 'AND user_item_id = %d', $this->get_user_item_id() );
569 $filter->collection = $lp_user_item_db->tb_lp_user_items;
570 $lp_user_item_db->delete_execute( $filter );
571
572 $this->clean_caches();
573 }
574
575 /**
576 * Clean caches.
577 *
578 * @return void
579 */
580 public function clean_caches() {
581 // Clear cache user item.
582 $lp_user_items_cache = new LP_User_Items_Cache();
583 $lp_user_items_cache->clean_user_item(
584 [
585 $this->user_id,
586 $this->item_id,
587 $this->item_type,
588 ]
589 );
590
591 $key_cache_user_item = "userItemModel/find/{$this->user_id}/{$this->item_id}/{$this->item_type}";
592 $lp_user_items_cache->clear( $key_cache_user_item );
593
594 $key_cache_user_item_ref = "userItemModel/find/{$this->user_id}/{$this->item_id}/{$this->item_type}/{$this->ref_id}/{$this->ref_type}";
595 $lp_user_items_cache->clear( $key_cache_user_item_ref );
596 }
597 }
598