PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7.3.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7.3.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 / user / lp-user-functions.php

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

2,105 lines 53.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Common functions to process actions about user
4 *
5 * @author ThimPress
6 * @package LearnPress/Functions/User
7 * @version 1.0
8 */
9
10 function learn_press_get_user_profile_tabs() {
11 return LP_Profile::instance()->get_tabs();
12 }
13
14 /**
15 * Delete user data by user ID
16 *
17 * @param int $user_id
18 * @param int $course_id
19 */
20 function learn_press_delete_user_data( $user_id, $course_id = 0 ) {
21 global $wpdb;
22 // TODO: Should be deleted user's order and order data???
23
24 $query_args = array( $user_id );
25
26 if ( $course_id ) {
27 $query_args[] = $course_id;
28 }
29
30 $query = $wpdb->prepare(
31 "
32 SELECT user_item_id
33 FROM {$wpdb->prefix}learnpress_user_items
34 WHERE user_id = %d
35 " . ( $course_id ? ' AND item_id = %d' : '' ) . '
36 ',
37 $query_args
38 );
39
40 // delete all courses user has enrolled
41 $query = $wpdb->prepare(
42 "
43 DELETE FROM {$wpdb->prefix}learnpress_user_items
44 WHERE user_id = %d
45 " . ( $course_id ? ' AND item_id = %d' : '' ) . '
46 ',
47 $query_args
48 );
49
50 @$wpdb->query( $query );
51 }
52
53 /**
54 * Get user_item_id field in table learnpress_user_items
55 * with the user_id, item_id. If $course_id is not passed
56 * then item_id is ID of a course. Otherwise, item_id is
57 * ID of an item (like quiz/lesson).
58 *
59 * @param int $user_id
60 * @param int $item_id
61 * @param int $course_id
62 *
63 * @return bool
64 * @editor tungnx
65 * @reason this function only get cache, not handle get user_item_id
66 * @deprecated 4.1.6.9
67 */
68 function learn_press_get_user_item_id( $user_id, $item_id, $course_id = 0 /* added 3.0.0 */ ) {
69 return false;
70 }
71
72 /**
73 * Get current user ID
74 *
75 * @return int
76 */
77 function learn_press_get_current_user_id(): int {
78 $user = learn_press_get_current_user();
79
80 if ( ! $user ) {
81 return 0;
82 }
83
84 return $user->get_id();
85 }
86
87 /**
88 * Get the user by $user_id passed. If $user_id is NULL, get current user.
89 * If current user is not logged in, return a GUEST user
90 *
91 * @param bool $create_temp - Optional. Create temp user if user is not logged in.
92 *
93 * @return bool|LP_User|LP_User_Guest
94 * @editor tungnx
95 * @modify 4.1.4
96 * @version 1.0.1
97 */
98 function learn_press_get_current_user( $create_temp = true ) {
99 $user_id = get_current_user_id();
100
101 if ( $user_id ) {
102 return learn_press_get_user( $user_id );
103 }
104
105 // Return LP_User_Guest
106 return learn_press_get_user( 0 );
107 }
108
109 if ( ! function_exists( 'learn_press_get_user' ) ) {
110 /**
111 * Get user by ID. Return false if the user does not exists.
112 *
113 * @param int $user_id
114 * @param bool $current
115 *
116 * @return LP_User|LP_User_Guest|mixed
117 * Todo: check this function - tungnx
118 */
119 function learn_press_get_user( $user_id, $current = false, $force_new = false ) {
120 $is_guest = false;
121 if ( ! is_null( LearnPress::instance()->session ) && $user_id != LearnPress::instance()->session->guest_user_id ) {
122 if ( $current && ! get_user_by( 'id', $user_id ) ) {
123 $user_id = get_current_user_id();
124 }
125 }
126
127 if ( ! $user_id && isset( LearnPress::instance()->session ) ) {
128 if ( ! LearnPress::instance()->session->guest_user_id ) {
129 LearnPress::instance()->session->set_customer_session_cookie( 1 );
130 LearnPress::instance()->session->guest_user_id = time();
131 }
132
133 $user_id = LearnPress::instance()->session->guest_user_id;
134 $is_guest = true;
135 }
136
137 if ( ! $user_id ) {
138 return false;
139 }
140
141 $user_id = '' . $user_id;
142
143 if ( $force_new || ! array_key_exists( $user_id, LP_Global::$users ) ) {
144 /**
145 * LP Hook.
146 *
147 * Filter the default class name to get LP user.
148 *
149 * @since 3.3.0
150 */
151 $userClass = apply_filters( 'learn-press/user-class', $is_guest ? 'LP_User_Guest' : 'LP_User', $is_guest );
152
153 LP_Global::$users[ $user_id ] = new $userClass( $user_id );
154
155 do_action( 'learn-press/get-user', LP_Global::$users[ $user_id ], $user_id );
156 }
157
158 return LP_Global::$users[ $user_id ];
159 }
160 }
161
162 /**
163 * Add more 2 user roles teacher and student
164 */
165 function learn_press_add_user_roles() {
166
167 $settings = LP_Settings::instance();
168
169 /* translators: user role */
170 _x( 'LP Instructor', 'User role' );
171
172 add_role(
173 LP_TEACHER_ROLE,
174 'LP Instructor',
175 array()
176 );
177
178 $course_cap = LP_COURSE_CPT . 's';
179 $lesson_cap = LP_LESSON_CPT . 's';
180 $order_cap = LP_ORDER_CPT . 's';
181
182 $teacher = get_role( LP_TEACHER_ROLE );
183 if ( $teacher ) {
184 $teacher->add_cap( 'read_private_' . $course_cap );
185 $teacher->add_cap( 'delete_published_' . $course_cap );
186 $teacher->add_cap( 'edit_published_' . $course_cap );
187 $teacher->add_cap( 'edit_' . $course_cap );
188 $teacher->add_cap( 'delete_' . $course_cap );
189 $teacher->add_cap( 'unfiltered_html' );
190
191 $settings->get( 'required_review' );
192
193 if ( $settings->get( 'required_review' ) == 'yes' ) {
194 $teacher->remove_cap( 'publish_' . $course_cap );
195 } else {
196 $teacher->add_cap( 'publish_' . $course_cap );
197 }
198
199 $teacher->add_cap( 'read_private_' . $lesson_cap );
200 $teacher->add_cap( 'delete_published_' . $lesson_cap );
201 $teacher->add_cap( 'edit_published_' . $lesson_cap );
202 $teacher->add_cap( 'edit_' . $lesson_cap );
203 $teacher->add_cap( 'delete_' . $lesson_cap );
204 $teacher->add_cap( 'publish_' . $lesson_cap );
205 $teacher->add_cap( 'upload_files' );
206 $teacher->add_cap( 'read' );
207 $teacher->add_cap( 'edit_posts' );
208 }
209
210 // administrator
211 $admin = get_role( 'administrator' );
212 if ( $admin ) {
213 $admin->add_cap( 'read_private_' . $course_cap );
214 $admin->add_cap( 'delete_' . $course_cap );
215 $admin->add_cap( 'delete_published_' . $course_cap );
216 $admin->add_cap( 'edit_' . $course_cap );
217 $admin->add_cap( 'edit_published_' . $course_cap );
218 $admin->add_cap( 'publish_' . $course_cap );
219 $admin->add_cap( 'delete_private_' . $course_cap );
220 $admin->add_cap( 'edit_private_' . $course_cap );
221 $admin->add_cap( 'delete_others_' . $course_cap );
222 $admin->add_cap( 'edit_others_' . $course_cap );
223
224 $admin->add_cap( 'read_private_' . $lesson_cap );
225 $admin->add_cap( 'delete_' . $lesson_cap );
226 $admin->add_cap( 'delete_published_' . $lesson_cap );
227 $admin->add_cap( 'edit_' . $lesson_cap );
228 $admin->add_cap( 'edit_published_' . $lesson_cap );
229 $admin->add_cap( 'publish_' . $lesson_cap );
230 $admin->add_cap( 'delete_private_' . $lesson_cap );
231 $admin->add_cap( 'edit_private_' . $lesson_cap );
232 $admin->add_cap( 'delete_others_' . $lesson_cap );
233 $admin->add_cap( 'edit_others_' . $lesson_cap );
234
235 $admin->add_cap( 'delete_' . $order_cap );
236 $admin->add_cap( 'delete_published_' . $order_cap );
237 $admin->add_cap( 'edit_' . $order_cap );
238 $admin->add_cap( 'edit_published_' . $order_cap );
239 $admin->add_cap( 'publish_' . $order_cap );
240 $admin->add_cap( 'delete_private_' . $order_cap );
241 $admin->add_cap( 'edit_private_' . $order_cap );
242 $admin->add_cap( 'delete_others_' . $order_cap );
243 $admin->add_cap( 'edit_others_' . $order_cap );
244 }
245 }
246
247 add_action( 'init', 'learn_press_add_user_roles' );
248
249 /**
250 * @param null $user_id
251 * @param array $args
252 *
253 * @return mixed
254 * @deprecated 4.1.7.3
255 */
256 /*function learn_press_get_user_questions( $user_id = null, $args = array() ) {
257 if ( ! $user_id ) {
258 $user_id = get_current_user_id();
259 }
260
261 return learn_press_get_user( $user_id )->get_questions( $args );
262 }*/
263
264 /**
265 * Get the type of current user
266 *
267 * @param null $check_type
268 *
269 * @return bool|string
270 */
271 function learn_press_current_user_is( $check_type = null ) {
272 global $current_user;
273 $user_roles = $current_user->roles;
274 $user_type = '';
275
276 if ( in_array( 'lpr_teacher', $user_roles ) ) {
277 $user_type = 'instructor';
278 } elseif ( in_array( 'lp_teacher', $user_roles ) ) {
279 $user_type = 'instructor';
280 } elseif ( in_array( 'administrator', $user_roles ) ) {
281 $user_type = 'administrator';
282 }
283
284 return $check_type ? $check_type == $user_type : $user_type;
285 }
286
287 function learn_press_user_has_roles( $roles, $user_id = null ) {
288 $has_role = false;
289 if ( ! $user_id ) {
290 $user = wp_get_current_user();
291 } else {
292 $user = get_user_by( 'id', $user_id );
293 }
294 $available_roles = (array) $user->roles;
295 if ( is_array( $roles ) ) {
296 foreach ( $roles as $role ) {
297 if ( in_array( $role, $available_roles ) ) {
298 $has_role = true;
299 break; // only need one of roles is in available
300 }
301 }
302 } else {
303 if ( in_array( $roles, $available_roles ) ) {
304 $has_role = true;
305 }
306 }
307
308 return $has_role;
309 }
310
311 function learn_press_current_user_can_view_profile_section( $section, $user ) {
312 $current_user = wp_get_current_user();
313 $view = true;
314 if ( $user->get_data( 'user_login' ) != $current_user->user_login && $section == LP_Settings::instance()->get(
315 'profile_endpoints.profile-orders',
316 'profile-orders'
317 ) ) {
318 $view = false;
319 }
320
321 return apply_filters( 'learn_press_current_user_can_view_profile_section', $view, $section, $user );
322 }
323
324 /*function learn_press_profile_tab_courses_content( $current, $tab, $user ) {
325 learn_press_get_template(
326 'profile/tabs/courses.php',
327 array(
328 'user' => $user,
329 'current' => $current,
330 'tab' => $tab,
331 )
332 );
333 }*/
334
335 function learn_press_profile_tab_quizzes_content( $current, $tab, $user ) {
336 learn_press_get_template(
337 'profile/tabs/quizzes.php',
338 array(
339 'user' => $user,
340 'current' => $current,
341 'tab' => $tab,
342 )
343 );
344 }
345
346 function learn_press_profile_tab_orders_content( $current, $tab, $user ) {
347 learn_press_get_template(
348 'profile/tabs/orders.php',
349 array(
350 'user' => $user,
351 'current' => $current,
352 'tab' => $tab,
353 )
354 );
355 }
356
357 /**
358 * Get queried user in profile link
359 *
360 * @return false|WP_User
361 * @since 3.0.0
362 */
363 function learn_press_get_profile_user() {
364 return LP_Profile::get_queried_user();
365 }
366
367
368 /**
369 * Add instructor registration button to register page and admin bar
370 */
371 function learn_press_user_become_teacher_registration_form() {
372 if ( LP_Settings::instance()->get( 'instructor_registration' ) != 'yes' ) {
373 return;
374 }
375 ?>
376 <p>
377 <label for="become_teacher">
378 <input type="checkbox" name="become_teacher" id="become_teacher">
379 <?php esc_html_e( 'Want to become an instructor?', 'learnpress' ); ?>
380 </label>
381 </p>
382 <?php
383 }
384
385 add_action( 'register_form', 'learn_press_user_become_teacher_registration_form' );
386
387 /**
388 * Update data into table learnpress_user_items.
389 *
390 * @param array $fields - Fields and values to be updated.
391 * Format: array(
392 * field_name_1 => value 1,
393 * field_name_2 => value 2,
394 * ....
395 * field_name_n => value n
396 * )
397 * @param mixed $where - Optional. Fields with values for conditional update with the same format of $fields.
398 * @param bool $update_cache - Optional. Should be update to cache or not (since 3.0.0).
399 * @param bool $update_extra_fields_as_meta - Optional. Update extra fields as item meta (since 3.1.0).
400 *
401 * @return mixed
402 */
403 function learn_press_update_user_item_field( array $fields = [], $where = false, $update_cache = true, $update_extra_fields_as_meta = false ) {
404 global $wpdb;
405
406 // Table fields format.
407 $table_fields = array(
408 'user_item_id' => '%d',
409 'user_id' => '%d',
410 'item_id' => '%d',
411 'ref_id' => '%d',
412 'start_time' => '%s',
413 'end_time' => '%s',
414 'access_level' => '%d',
415 'graduation' => '%s',
416 'item_type' => '%s',
417 'status' => '%s',
418 'ref_type' => '%s',
419 'parent_id' => '%d',
420 );
421
422 /**
423 * Validate item status
424 */
425 if ( ! empty( $fields['item_id'] ) && ! empty( $fields['status'] ) ) {
426 $item_type = learn_press_get_post_type( $fields['item_id'] );
427
428 if ( LP_COURSE_CPT === $item_type ) {
429 if ( 'completed' === $fields['status'] ) {
430 $fields['status'] = 'finished';
431 }
432 } else {
433 if ( 'finished' === $fields['status'] ) {
434 $fields['status'] = 'completed';
435 }
436 }
437 }
438
439 $data = array();
440 $data_format = array();
441 foreach ( $fields as $field => $value ) {
442 if ( ! empty( $table_fields[ $field ] ) ) {
443 $data[ $field ] = $value;
444
445 // Do not format the date-time field if it's value is NULL
446 if ( in_array( $field, [ 'start_time', 'end_time' ] ) && empty( $value ) ) {
447 $data[ $field ] = null;
448 $data_format[] = '';
449 } else {
450 if ( $value instanceof LP_Datetime ) {
451 $data[ $field ] = $value->toSql();
452 }
453 $data_format[] = $table_fields[ $field ];
454 }
455 }
456 }
457
458 if ( ! empty( $fields['user_item_id'] ) ) {
459 $where = wp_parse_args(
460 $where,
461 array( 'user_item_id' => $fields['user_item_id'] )
462 );
463 }
464
465 // Set where and where format
466 $where_format = array();
467 if ( is_array( $where ) && ! empty( $where ) ) {
468 if ( empty( $where['user_id'] ) ) {
469 $where['user_id'] = ! empty( $fields['user_id'] ) ? $fields['user_id'] : learn_press_get_current_user_id();
470 }
471
472 foreach ( $where as $field => $value ) {
473 if ( isset( $table_fields[ $field ] ) ) {
474 $where_format[] = $table_fields[ $field ];
475 }
476 }
477 }
478
479 if ( ! $data ) {
480 return false;
481 }
482
483 $inserted = false;
484 $updated = false;
485
486 // Update to database.
487 if ( $where ) {
488 $updated = $wpdb->update(
489 $wpdb->learnpress_user_items,
490 $data,
491 $where,
492 $data_format,
493 $where_format
494 );
495 } else {
496 // Insert to database.
497 if ( $wpdb->insert(
498 $wpdb->learnpress_user_items,
499 $data,
500 $data_format
501 ) ) {
502 $inserted = $wpdb->insert_id;
503 }
504 }
505
506 if ( $updated && ! empty( $where['user_item_id'] ) ) {
507 $inserted = $where['user_item_id'];
508 }
509
510 /**
511 * @var object|bool $updated_item
512 */
513 $updated_item = false;
514
515 // Get the item we just have updated or inserted.
516 if ( $inserted ) {
517 $updated_item = learn_press_get_user_item( $inserted );
518 } elseif ( $updated ) {
519 $updated_item = learn_press_get_user_item( $where );
520 }
521
522 /**
523 * If there is some fields does not contain in the main table
524 * then consider update them as metadata.
525 * @comment by tungnx - 4.1.7.3
526 */
527 /*if ( $updated_item && $update_extra_fields_as_meta ) {
528 $extra_fields = array_diff_key( $fields, $table_fields );
529 if ( $extra_fields ) {
530 foreach ( $extra_fields as $meta_key => $meta_value ) {
531 if ( $meta_value == 'user_item_id' ) {
532 continue;
533 }
534
535 if ( $meta_value === false ) {
536 learn_press_delete_user_item_meta( $updated_item->user_item_id, $meta_key );
537 } else {
538
539 if ( empty( $meta_value ) ) {
540 $meta_value = '';
541 }
542 learn_press_update_user_item_meta( $updated_item->user_item_id, $meta_key, $meta_value );
543 }
544 }
545 }
546 }*/
547
548 do_action( 'learn-press/updated-user-item-meta', $updated_item );
549
550 return $updated_item;
551 }
552
553 /**
554 * Get user item row(s) from user items table by multiple WHERE conditional
555 *
556 * @param array|int $where
557 * @param bool $single
558 *
559 * @return array
560 */
561 function learn_press_get_user_item( $where, $single = true ) {
562 global $wpdb;
563
564 // Table fields
565 $table_fields = array(
566 'user_item_id' => '%d',
567 'user_id' => '%d',
568 'item_id' => '%d',
569 'ref_id' => '%d',
570 'start_time' => '%s',
571 'end_time' => '%s',
572 'item_type' => '%s',
573 'status' => '%s',
574 'ref_type' => '%s',
575 'parent_id' => '%d',
576 );
577
578 // If $where is a number consider we are searching the record with unique user_item_id
579 if ( is_numeric( $where ) ) {
580 $where = array( 'user_item_id' => $where );
581 }
582
583 $where_str = array();
584 foreach ( $where as $field => $value ) {
585 if ( ! empty( $table_fields[ $field ] ) ) {
586 $where_str[] = "{$field} = " . $table_fields[ $field ];
587 }
588 }
589 $item = false;
590
591 if ( $where_str ) {
592 $query = $wpdb->prepare(
593 "
594 SELECT *
595 FROM {$wpdb->prefix}learnpress_user_items
596 WHERE " . join( ' AND ', $where_str ) . '
597 ORDER BY user_item_id DESC
598 ',
599 $where
600 );
601 if ( $single || ! empty( $where['user_item_id'] ) ) {
602 $item = $wpdb->get_row( $query );
603 } else {
604 $item = $wpdb->get_results( $query );
605 }
606 }
607
608 return $item;
609 }
610
611 /**
612 * Get user item meta from user_itemmeta table
613 *
614 * @param int $user_item_id .
615 * @param string $meta_key .
616 * @param bool $single .
617 *
618 * @return mixed
619 */
620 function learn_press_get_user_item_meta( $user_item_id = 0, $meta_key = '', $single = true ) {
621 $meta = false;
622 if ( metadata_exists( 'learnpress_user_item', $user_item_id, $meta_key ) ) {
623 $meta = get_metadata( 'learnpress_user_item', $user_item_id, $meta_key, $single );
624 }
625
626 return $meta;
627 }
628
629 /**
630 * Add user item meta into table user_itemmeta
631 *
632 * @param int $user_item_id
633 * @param string $meta_key
634 * @param mixed $meta_value
635 * @param string $prev_value
636 *
637 * @return false|int
638 */
639 function learn_press_add_user_item_meta( $user_item_id, $meta_key, $meta_value, $prev_value = '' ) {
640 return add_metadata( 'learnpress_user_item', $user_item_id, $meta_key, $meta_value, $prev_value );
641 }
642
643 /**
644 * Update user item meta to table user_itemmeta
645 *
646 * @param int $user_item_id
647 * @param string $meta_key
648 * @param mixed $meta_value
649 * @param string $prev_value
650 *
651 * @return bool|int
652 */
653 function learn_press_update_user_item_meta( $user_item_id, $meta_key, $meta_value, $prev_value = '' ) {
654 return update_metadata( 'learnpress_user_item', $user_item_id, $meta_key, $meta_value, $prev_value );
655 }
656
657
658 /**
659 * Update user item meta to table user_itemmeta
660 *
661 * @param int $object_id
662 * @param string $meta_key
663 * @param mixed $meta_value
664 * @param bool $delete_all
665 *
666 * @return bool|int
667 */
668 function learn_press_delete_user_item_meta( $object_id, $meta_key, $meta_value = '', $delete_all = false ) {
669 return delete_metadata( 'learnpress_user_item', $object_id, $meta_key, $meta_value, $delete_all );
670 }
671
672 /**
673 * Get temp users.
674 *
675 * @return array
676 * @deprecated 4.1.6.9
677 */
678 /*function learn_press_get_temp_users() {
679 return false;
680 if ( false === ( $temp_users = LP_Object_Cache::get( 'learn-press/temp-users' ) ) ) {
681 global $wpdb;
682 $query = $wpdb->prepare(
683 "
684 SELECT ID
685 FROM {$wpdb->users} u
686 INNER JOIN {$wpdb->usermeta} um ON u.ID = um.user_id AND um.meta_key = %s AND um.meta_value = %s
687 LEFT JOIN {$wpdb->usermeta} um2 ON u.ID = um2.user_id AND um2.meta_key = %s
688 ",
689 '_lp_temp_user',
690 'yes',
691 '_lp_expiration'
692 );
693
694 $temp_users = $wpdb->get_col( $query );
695
696 LP_Object_Cache::set( 'learn-press/temp-users', $temp_users );
697 }
698
699 return $temp_users;
700 }*/
701
702 /**
703 * Update field created_time after added user item meta
704 *
705 * @use updated_{meta_type}_meta hook
706 *
707 * @param $meta_id
708 * @param $object_id
709 * @param $meta_key
710 * @param $_meta_value
711 * @deprecated 4.1.7.3
712 */
713 /*function _learn_press_update_created_time_user_item_meta( $meta_id, $object_id, $meta_key, $_meta_value ) {
714 global $wpdb;
715 $wpdb->update(
716 $wpdb->learnpress_user_itemmeta,
717 array( 'create_time' => current_time( 'mysql' ) ),
718 array( 'meta_id' => $meta_id ),
719 array( '%s' ),
720 array( '%d' )
721 );
722 }*/
723
724 // add_action( 'added_learnpress_user_item_meta', '_learn_press_update_created_time_user_item_meta', 10, 4 );
725
726 /**
727 * Update field updated_time after updated user item meta
728 *
729 * @use updated_{meta_type}_meta hook
730 *
731 * @param $meta_id
732 * @param $object_id
733 * @param $meta_key
734 * @param $_meta_value
735 * @deprecated
736 */
737 /*function _learn_press_update_updated_time_user_item_meta( $meta_id, $object_id, $meta_key, $_meta_value ) {
738 global $wpdb;
739 $wpdb->update(
740 $wpdb->learnpress_user_itemmeta,
741 array( 'update_time' => current_time( 'mysql' ) ),
742 array( 'meta_id' => $meta_id ),
743 array( '%s' ),
744 array( '%d' )
745 );
746 }*/
747
748 // add_action( 'updated_learnpress_user_item_meta', '_learn_press_update_updated_time_user_item_meta', 10, 4 );
749
750 /**
751 * @param $status
752 * @param int $quiz_id
753 * @param int $user_id
754 * @param int $course_id
755 *
756 * @return bool|mixed
757 * @deprecated 4.1.7.3
758 */
759 /*function learn_press_user_has_quiz_status( $status, $quiz_id = 0, $user_id = 0, $course_id = 0 ) {
760 $user = learn_press_get_user( $user_id );
761
762 return $user->has_quiz_status( $status, $quiz_id, $course_id );
763 }*/
764
765 if ( ! function_exists( 'learn_press_pre_get_avatar_callback' ) ) {
766 /**
767 * Filter the avatar
768 *
769 * @param string $avatar
770 * @param string $id_or_email
771 * @param array $size
772 *
773 * @return string
774 */
775 function learn_press_pre_get_avatar_callback( $avatar, $id_or_email = '', $size = array() ) {
776
777 $profile = LP_Profile::instance();
778
779 if ( ! $profile->is_enable_avatar() ) {
780 return $avatar;
781 }
782
783 if ( ( isset( $size['gravatar'] ) && $size['gravatar'] ) || ( $size['default'] && $size['force_default'] ) ) {
784 return $avatar;
785 }
786
787 $user_id = 0;
788
789 /**
790 * Get the ID of user from $id_or_email
791 */
792 if ( ! is_numeric( $id_or_email ) && is_string( $id_or_email ) ) {
793 $user = get_user_by( 'email', $id_or_email );
794 if ( $user ) {
795 $user_id = $user->ID;
796 }
797 } elseif ( is_numeric( $id_or_email ) ) {
798 $user_id = $id_or_email;
799 } elseif ( is_object( $id_or_email ) && isset( $id_or_email->user_id ) && $id_or_email->user_id ) {
800 $user_id = $id_or_email->user_id;
801 } elseif ( $id_or_email instanceof WP_Comment ) {
802 $user = get_user_by( 'email', $id_or_email->comment_author_email );
803 if ( $user ) {
804 $user_id = $user->ID;
805 }
806 }
807
808 if ( ! $user_id ) {
809 return $avatar;
810 }
811
812 $user = LP_User_Factory::get_user( $user_id );
813
814 $profile_picture_src = $user->get_upload_profile_src();
815 if ( $profile_picture_src ) {
816 $setting_size = learn_press_get_avatar_thumb_size();
817 $img_size = '';
818
819 // Get avatar size
820 if ( ! is_array( $size ) ) {
821 if ( $size === 'thumbnail' ) {
822 $img_size = '';
823 $height = $setting_size['height'];
824 $width = $setting_size['width'];
825 } else {
826 $height = 250;
827 $width = 250;
828 }
829 } else {
830 $img_size = $size['size'];
831 $height = $size['height'];
832 $width = $size['width'];
833 }
834
835 $avatar = '<img alt="' . esc_attr( $user->get_data( 'display_name' ) ) . '" src="' . esc_url_raw( $profile_picture_src ) . '" class="avatar avatar-' . $img_size . ' photo" height="' . $height . '" width="' . $width . '" />';
836 }
837
838 return $avatar;
839 }
840 }
841 add_filter( 'pre_get_avatar', 'learn_press_pre_get_avatar_callback', 1, 5 );
842
843
844 function learn_press_user_profile_picture_upload_dir( $width_user = true ) {
845 static $upload_dir;
846 if ( ! $upload_dir ) {
847 $upload_dir = wp_upload_dir();
848 $subdir = apply_filters( 'learn_press_user_profile_folder', 'learn-press-profile', $width_user );
849 if ( $width_user ) {
850 $subdir .= '/' . get_current_user_id();
851 }
852 $subdir = '/' . $subdir;
853
854 if ( ! empty( $upload_dir['subdir'] ) ) {
855 $u_subdir = str_replace( '\\', '/', $upload_dir['subdir'] );
856 $u_path = str_replace( '\\', '/', $upload_dir['path'] );
857
858 $upload_dir['path'] = str_replace( $u_subdir, $subdir, $u_path );
859 $upload_dir['url'] = str_replace( $u_subdir, $subdir, $upload_dir['url'] );
860 } else {
861 $upload_dir['path'] = $upload_dir['path'] . $subdir;
862 $upload_dir['url'] = $upload_dir['url'] . $subdir;
863 }
864
865 $upload_dir['subdir'] = $subdir;
866
867 // Point path/url to main site if we are in multisite
868 if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
869 foreach ( array( 'path', 'url', 'basedir', 'baseurl' ) as $v ) {
870 $upload_dir[ $v ] = str_replace( '/sites/' . get_current_blog_id(), '', $upload_dir[ $v ] );
871 }
872 }
873 }
874
875 return $upload_dir;
876 }
877
878 add_action( 'learn_press_before_purchase_course_handler', '_learn_press_before_purchase_course_handler', 10, 2 );
879 function _learn_press_before_purchase_course_handler( $course_id, $cart ) {
880 // Redirect to login page if user is not logged in
881 if ( ! is_user_logged_in() ) {
882 $return_url = esc_url_raw( add_query_arg( $_POST, get_the_permalink( $course_id ) ) );
883 $return_url = apply_filters( 'learn_press_purchase_course_login_redirect_return_url', $return_url );
884 $redirect = apply_filters(
885 'learn_press_purchase_course_login_redirect',
886 learn_press_get_login_url( $return_url )
887 );
888 if ( $redirect !== false ) {
889 learn_press_add_message( __( 'Please log in to enroll in this course', 'learnpress' ) );
890
891 if ( learn_press_is_ajax() ) {
892 learn_press_send_json(
893 array(
894 'redirect' => $redirect,
895 'result' => 'success',
896 )
897 );
898 } else {
899 wp_redirect( $redirect );
900 exit();
901 }
902 }
903 } else {
904 $user = learn_press_get_current_user();
905 $redirect = false;
906 if ( $user->has_finished_course( $course_id ) ) {
907 learn_press_add_message( __( 'You have already finished the course', 'learnpress' ) );
908 $redirect = true;
909 } elseif ( $user->has_purchased_course( $course_id ) ) {
910 learn_press_add_message( __( 'You have already enrolled in this course', 'learnpress' ) );
911 $redirect = true;
912 }
913 if ( $redirect ) {
914 wp_redirect( get_the_permalink( $course_id ) );
915 exit();
916 }
917 }
918 }
919
920 function learn_press_user_is( $role, $user_id = 0 ) {
921 if ( ! $user_id ) {
922 $user = learn_press_get_current_user();
923 } else {
924 $user = learn_press_get_user( $user_id );
925 }
926 if ( $role == 'admin' ) {
927 return $user->is_admin();
928 }
929 if ( $role == 'instructor' ) {
930 return $user->is_instructor();
931 }
932
933 return $role;
934 }
935
936 function learn_press_profile_tab_edit_content( $current, $tab, $user ) {
937 learn_press_get_template(
938 'profile/tabs/edit.php',
939 array(
940 'user' => $user,
941 'current' => $current,
942 'tab' => $tab,
943 )
944 );
945 }
946
947 function learn_press_get_profile_endpoints() {
948 $endpoints = (array) LP_Settings::instance()->get( 'profile_endpoints' );
949 $tabs = LP_Profile::instance()->get_tabs();
950 if ( $tabs ) {
951 foreach ( $tabs as $slug => $info ) {
952 if ( empty( $endpoints[ $slug ] ) ) {
953 $endpoints[ $slug ] = $slug;
954 }
955 }
956 }
957
958 return apply_filters( 'learn_press_profile_tab_endpoints', $endpoints );
959 }
960
961
962 function learn_press_update_user_option( $name, $value, $id = 0 ) {
963 if ( ! $id ) {
964 $id = get_current_user_id();
965 }
966 $key = 'learnpress_user_options';
967 $options = get_user_option( $key, $id );
968 $options[ $name ] = $value;
969 update_user_option( $id, $key, $options, true );
970 }
971
972 /**
973 * @param $name
974 * @param int $id
975 *
976 * @return bool
977 */
978 function learn_press_delete_user_option( $name, $id = 0 ) {
979 if ( ! $id ) {
980 $id = get_current_user_id();
981 }
982 $key = 'learnpress_user_options';
983 $options = get_user_option( $key, $id );
984 if ( is_array( $options ) && array_key_exists( $name, $options ) ) {
985 unset( $options[ $name ] );
986 update_user_option( $id, $key, $options, true );
987
988 return true;
989 }
990
991 return false;
992 }
993
994 /**
995 * @param $name
996 * @param int $id
997 *
998 * @return bool
999 */
1000 function learn_press_get_user_option( $name, $id = 0 ) {
1001 if ( ! $id ) {
1002 $id = get_current_user_id();
1003 }
1004 $key = 'learnpress_user_options';
1005 $options = get_user_option( $key, $id );
1006 if ( is_array( $options ) && array_key_exists( $name, $options ) ) {
1007 return $options[ $name ];
1008 }
1009
1010 return false;
1011 }
1012
1013 /**
1014 * Update user basic information.
1015 *
1016 * @param bool $wp_error - Optional. Return WP_Error object in case updating failed.
1017 *
1018 * @return bool|mixed|WP_Error
1019 */
1020 function learn_press_update_user_profile_basic_information( $wp_error = false ) {
1021 $user_id = get_current_user_id();
1022
1023 if ( ! $user_id ) {
1024 return new WP_Error( 2, 'The user is invalid' );
1025 }
1026
1027 $update_data = array(
1028 'ID' => $user_id,
1029 'first_name' => filter_input( INPUT_POST, 'first_name', FILTER_SANITIZE_STRING ),
1030 'last_name' => filter_input( INPUT_POST, 'last_name', FILTER_SANITIZE_STRING ),
1031 'description' => filter_input( INPUT_POST, 'description', FILTER_SANITIZE_STRING ),
1032 'display_name' => filter_input( INPUT_POST, 'account_display_name', FILTER_SANITIZE_STRING ),
1033 'user_email' => filter_input( INPUT_POST, 'account_email', FILTER_SANITIZE_EMAIL ),
1034 );
1035
1036 $update_data = apply_filters( 'learn-press/update-profile-basic-information-data', $update_data );
1037 $update_meta = LP_Helper::sanitize_params_submitted( $_POST['_lp_custom_register'] ?? '' );
1038
1039 $return = LP_Forms_Handler::update_user_data( $update_data, $update_meta );
1040
1041 // Update for social.
1042 $socials = LP_Request::get_array( 'user_profile_social' );
1043 $extra_data = get_user_meta( $user_id, '_lp_extra_info', true );
1044
1045 if ( ! empty( $extra_data ) ) {
1046 $socials = array_merge( $extra_data, $socials );
1047 }
1048
1049 update_user_meta( $user_id, '_lp_extra_info', $socials );
1050
1051 if ( is_wp_error( $return ) ) {
1052 return $wp_error ? $return : false;
1053 }
1054
1055 return $return;
1056 }
1057
1058 /**
1059 * Update new password.
1060 */
1061 function learn_press_update_user_profile_change_password( $wp_error = false ) {
1062 $user_id = get_current_user_id();
1063
1064 if ( ! $user_id ) {
1065 return new WP_Error( 2, 'The user is invalid' );
1066 }
1067
1068 $old_pass = filter_input( INPUT_POST, 'pass0' );
1069 $check_old_pass = false;
1070
1071 if ( $old_pass ) {
1072 $user = wp_get_current_user();
1073 require_once ABSPATH . 'wp-includes/class-phpass.php';
1074 $wp_hasher = new PasswordHash( 8, true );
1075
1076 if ( $wp_hasher->CheckPassword( $old_pass, $user->data->user_pass ) ) {
1077 $check_old_pass = true;
1078 }
1079 }
1080
1081 try {
1082 if ( ! $check_old_pass ) {
1083 throw new Exception( __( 'The old password is incorrect!', 'learnpress' ) );
1084 } else {
1085 $new_pass = filter_input( INPUT_POST, 'pass1' );
1086 $new_pass2 = filter_input( INPUT_POST, 'pass2' );
1087
1088 if ( ! $new_pass || ! $new_pass2 || ( $new_pass != $new_pass2 ) ) {
1089 throw new Exception( __( 'Incorrect confirmation password!', 'learnpress' ) );
1090 } else {
1091 $update_data = array(
1092 'user_pass' => $new_pass,
1093 'ID' => get_current_user_id(),
1094 );
1095 $return = wp_update_user( $update_data );
1096
1097 if ( is_wp_error( $return ) ) {
1098 return $wp_error ? $return : false;
1099 }
1100
1101 return $return;
1102 }
1103 }
1104 } catch ( Exception $ex ) {
1105 return $wp_error ? new WP_Error( 'UPDATE_PROFILE_ERROR', $ex->getMessage() ) : false;
1106 }
1107 }
1108
1109 function learn_press_get_avatar_thumb_size() {
1110 $option = LP_Settings::get_option(
1111 'avatar_dimensions',
1112 array(
1113 'width' => 250,
1114 'height' => 250,
1115 )
1116 );
1117
1118 if ( ! isset( $option['width'] ) || ! isset( $option['height'] ) ) {
1119 $option = array(
1120 'width' => 250,
1121 'height' => 250,
1122 );
1123 }
1124
1125 return $option;
1126 }
1127
1128 function learn_press_get_course_thumbnail_dimensions() {
1129 $option = LP_Settings::get_option(
1130 'course_thumbnail_dimensions',
1131 array(
1132 'width' => 500,
1133 'height' => 300,
1134 )
1135 );
1136
1137 if ( ! isset( $option['width'] ) || ! isset( $option['height'] ) ) {
1138 $option = array(
1139 'width' => 500,
1140 'height' => 300,
1141 );
1142 }
1143
1144 return $option;
1145 }
1146
1147 /**
1148 * Set a fake cookie to
1149 */
1150 function learn_press_set_user_cookie_for_guest() {
1151 if ( ! is_admin() && ! headers_sent() ) {
1152 $guest_key = '_wordpress_lp_guest';
1153
1154 if ( is_user_logged_in() ) {
1155 if ( ! empty( $_COOKIE[ $guest_key ] ) ) {
1156 learn_press_remove_cookie( $guest_key );
1157 }
1158 } else {
1159 if ( empty( $_COOKIE[ $guest_key ] ) ) {
1160 learn_press_setcookie( $guest_key, md5( time() ), time() + 3600 );
1161 }
1162 }
1163 }
1164 }
1165
1166 add_action( 'wp', 'learn_press_set_user_cookie_for_guest' );
1167
1168 function learn_press_get_user_avatar( $user_id = 0, $size = '' ) {
1169 $user = learn_press_get_user( $user_id );
1170
1171 return $user->get_profile_picture( '', $size );
1172 }
1173
1174 /**
1175 * Get profile instance for an user to view.
1176 *
1177 * @param int $for_user
1178 *
1179 * @return LP_Profile|WP_Error
1180 */
1181 function learn_press_get_profile( $for_user = 0 ) {
1182 return LP_Profile::instance( $for_user );
1183 }
1184
1185 /**
1186 * Remove items from learnpress_user_items.
1187 *
1188 * @param int $user_id
1189 * @param int $item_id
1190 * @param int $course_id
1191 * @param bool $include_course - Optional. If TRUE then remove course and it's items
1192 */
1193 function learn_press_remove_user_items( $user_id, $item_id, $course_id, $include_course = false ) {
1194 global $wpdb;
1195
1196 settype( $item_id, 'array' );
1197
1198 $format = array_fill( 0, sizeof( $item_id ), '%d' );
1199 $where = '';
1200
1201 $args = array( $user_id );
1202 $args = array_merge( $args, $item_id );
1203
1204 if ( $course_id ) {
1205 $args[] = $course_id;
1206 $where = 'AND ref_id = %d';
1207 }
1208
1209 if ( $include_course ) {
1210 $where .= ' OR ( item_id = %d AND item_type = %s )';
1211 $args[] = $course_id;
1212 $args[] = LP_COURSE_CPT;
1213 }
1214
1215 $query = $wpdb->prepare(
1216 "
1217 DELETE
1218 FROM {$wpdb->learnpress_user_items}
1219 WHERE user_id = %d
1220 AND ( item_id IN(" . join( ',', $format ) . ")
1221 $where )
1222 ",
1223 $args
1224 );
1225 }
1226
1227 /**
1228 * Get user profile link
1229 *
1230 * @param int $user_id
1231 * @param null $tab
1232 *
1233 * @return mixed|string
1234 */
1235 function learn_press_user_profile_link( $user_id = 0, $tab = null ) {
1236 if ( ! $user_id ) {
1237 $user_id = get_current_user_id();
1238 }
1239 $user = false;
1240 $deleted = in_array( $user_id, LP_User_Factory::$_deleted_users );
1241 if ( ! $deleted ) {
1242 if ( is_numeric( $user_id ) ) {
1243 $user = get_user_by( 'id', $user_id );
1244 } else {
1245 $user = get_user_by( 'login', urldecode( $user_id ) );
1246 }
1247 } else {
1248 return '';
1249 }
1250 if ( ! $deleted && ! $user ) {
1251 LP_User_Factory::$_deleted_users[] = $user_id;
1252 }
1253
1254 $user = learn_press_get_user( $user_id );
1255
1256 if ( ! $user ) {
1257 return '';
1258 }
1259
1260 global $wp_query;
1261 $args = array(
1262 'user' => $user->get_username(),
1263 );
1264
1265 if ( isset( $args['user'] ) ) {
1266 if ( '' === $tab ) {
1267 $tab = learn_press_get_current_profile_tab();
1268 }
1269 if ( $tab ) {
1270 $args['tab'] = $tab;
1271 }
1272
1273 /**
1274 * If no tab is selected in profile and is current user
1275 * then no need the username in profile link.
1276 */
1277 if ( ( $user_id == get_current_user_id() ) && ! isset( $args['tab'] ) ) {
1278 unset( $args['user'] );
1279 }
1280 }
1281
1282 /*$args = array_map(
1283 function ( $string ) {
1284 return preg_replace( '/\s/', '+', $string );
1285 },
1286 $args
1287 );*/
1288 $profile_link = trailingslashit( learn_press_get_page_link( 'profile' ) );
1289 if ( $profile_link ) {
1290 if ( get_option( 'permalink_structure' ) /*&& learn_press_get_page_id( 'profile' )*/ ) {
1291 $url = trailingslashit( $profile_link . join( '/', array_values( $args ) ) );
1292 } else {
1293 $url = esc_url_raw( add_query_arg( $args, $profile_link ) );
1294 }
1295 } else {
1296 $url = get_author_posts_url( $user_id );
1297 }
1298
1299 return apply_filters( 'learn_press_user_profile_link', $url, $user_id, $tab );
1300 }
1301
1302 /**********************************************/
1303 /* Functions are used for hooks */
1304 /**********************************************/
1305
1306 function learn_press_hk_before_start_quiz( $true, $quiz_id, $course_id, $user_id ) {
1307 if ( 'yes' !== get_post_meta( $quiz_id, '_lp_archive_history', true ) ) {
1308 learn_press_remove_user_items( $user_id, $quiz_id, $course_id );
1309 }
1310
1311 return $true;
1312 }
1313
1314 add_filter( 'learn-press/before-start-quiz', 'learn_press_hk_before_start_quiz', 10, 4 );
1315
1316 /*function learn_press_default_user_item_status( $item_id ) {
1317 $status = '';
1318 switch ( learn_press_get_post_type( $item_id ) ) {
1319 case LP_LESSON_CPT:
1320 $status = 'started';
1321 break;
1322 case LP_QUIZ_CPT:
1323 $status = 'viewed';
1324 break;
1325 case LP_COURSE_CPT:
1326 $status = 'enrolled';
1327 }
1328
1329 return apply_filters( 'learn-press/default-user-item-status', $status, $item_id );
1330 }*/
1331
1332 /**
1333 * Get current state of distraction mode
1334 *
1335 * @return mixed
1336 * @since 3.1.0
1337 */
1338 function learn_press_get_user_distraction() {
1339 if ( is_user_logged_in() ) {
1340 return get_user_option( 'distraction_mode', get_current_user_id() );
1341 } else {
1342 return LearnPress::instance()->session->distraction_mode;
1343 }
1344 }
1345
1346 function learn_press_get_user_role( $user_id ) {
1347 if ( $user = learn_press_get_user( $user_id ) ) {
1348 return $user->get_role();
1349 }
1350
1351 return false;
1352 }
1353
1354 /**
1355 * @param array $args
1356 * @param bool $wp_error
1357 *
1358 * @return bool|int|LP_User_Item|mixed|WP_Error
1359 */
1360 function learn_press_create_user_item( $args = array(), $wp_error = false ) {
1361 global $wpdb;
1362
1363 $defaults = array(
1364 'user_id' => get_current_user_id(),
1365 'item_id' => '',
1366 'start_time' => time(),
1367 'end_time' => '',
1368 'graduation' => '',
1369 'item_type' => '',
1370 'status' => '',
1371 'ref_id' => 0,
1372 'ref_type' => '',
1373 'parent_id' => 0,
1374 'create_meta' => array(),
1375 );
1376
1377 $item_data = wp_parse_args( $args, $defaults );
1378
1379 // Validate item_id and post type
1380 if ( empty( $item_data['item_id'] ) ) {
1381 if ( $wp_error ) {
1382 return new WP_Error( 'invalid_item_id', __( 'Invalid item id.', 'learnpress' ) );
1383 }
1384
1385 return 0;
1386 }
1387
1388 $post_type = learn_press_get_post_type( $item_data['item_id'] );
1389 if ( empty( $item_data['item_type'] ) && $post_type ) {
1390 $item_data['item_type'] = $post_type;
1391 }
1392
1393 // Get id and type of ref if they are null
1394 if ( ! empty( $item_data['parent_id'] ) && ( empty( $item_data['ref_id'] ) || ( empty( $item_data['ref_type'] ) ) ) ) {
1395 $parent = $wpdb->get_row(
1396 $wpdb->prepare(
1397 "SELECT * FROM {$wpdb->learnpress_user_items} WHERE %d",
1398 $item_data['parent_id']
1399 )
1400 );
1401
1402 if ( $parent ) {
1403 if ( empty( $item_data['ref_id'] ) ) {
1404 $item_data['ref_id'] = $parent->item_id;
1405 }
1406
1407 if ( empty( $item_data['ref_type'] ) ) {
1408 $item_data['ref_type'] = $parent->item_type;
1409 }
1410 }
1411 }
1412
1413 // Filter
1414 $item_data = apply_filters( 'learn-press/create-user-item-data', $item_data );
1415 if ( ! $item_data ) {
1416 if ( $wp_error ) {
1417 return new WP_Error( 'invalid_item_data', __( 'Invalid item data.', 'learnpress' ) );
1418 }
1419
1420 return 0;
1421 }
1422
1423 do_action( 'learn-press/before-create-user-item', $item_data );
1424
1425 $create_meta = ! empty( $item_data['create_meta'] ) ? $item_data['create_meta'] : false;
1426
1427 if ( $create_meta ) {
1428 unset( $item_data['create_meta'] );
1429 }
1430
1431 $user_item = new LP_User_Item( $item_data );
1432 $result = $user_item->update();
1433 if ( ! $result || is_wp_error( $result ) ) {
1434 if ( $wp_error && is_wp_error( $result ) ) {
1435 return $result;
1436 }
1437
1438 return 0;
1439 }
1440
1441 do_action( 'learn-press/created-user-item', $user_item, $item_data );
1442
1443 $create_meta = apply_filters( 'learn-press/create-user-item-meta', $create_meta, $item_data );
1444 if ( ! $create_meta ) {
1445 return $user_item;
1446 }
1447
1448 do_action( 'learn-press/before-create-user-item-meta', $create_meta );
1449
1450 foreach ( $create_meta as $key => $value ) {
1451 learn_press_update_user_item_meta( $user_item->get_user_item_id(), $key, $value );
1452 }
1453
1454 do_action( 'learn-press/created-user-item-meta', $user_item, $create_meta );
1455
1456 return $user_item;
1457 }
1458
1459 /**
1460 * @param array $args
1461 * @param bool $wp_error - Optional. TRUE will return WP_Error on fail.
1462 *
1463 * @return bool|array|LP_User_Item|WP_Error
1464 */
1465 function learn_press_create_user_item_for_quiz( $args = array(), $wp_error = false ) {
1466 $item_data = wp_parse_args(
1467 $args,
1468 array(
1469 'item_type' => LP_QUIZ_CPT,
1470 'status' => LP_ITEM_STARTED,
1471 'graduation' => LP_COURSE_GRADUATION_IN_PROGRESS,
1472 'user_id' => get_current_user_id(),
1473 )
1474 );
1475
1476 $user_item = learn_press_create_user_item( $item_data, $wp_error );
1477
1478 if ( $user_item && ! is_wp_error( $user_item ) ) {
1479 $user_item = new LP_User_Item_Quiz( $user_item->get_data() );
1480 $user_item->update();
1481 }
1482
1483 return $user_item;
1484 }
1485
1486 /**
1487 * Get list user_item_id for Quiz in table learnpress_user_items
1488 *
1489 * @param int $quiz_id
1490 * @param int $course_id
1491 * @return array || false
1492 */
1493 function learn_press_isset_user_item_for_quiz( $quiz_id, $course_id ) {
1494 global $wpdb;
1495
1496 $query = $wpdb->prepare( "SELECT user_item_id FROM $wpdb->learnpress_user_items WHERE ref_id=%d AND item_id=%d", $course_id, $quiz_id );
1497 $col = $wpdb->get_col( $query );
1498
1499 if ( ! empty( $col ) ) {
1500 return $col;
1501 } else {
1502 return false;
1503 }
1504 }
1505
1506 /**
1507 * Create new user item prepare for user starts a quiz
1508 * Update error retry course not work - Nhamdv.
1509 *
1510 * @param int $quiz_id
1511 * @param int $user_id
1512 * @param int $course_id
1513 * @param bool $wp_error
1514 *
1515 * @return array|bool|LP_User_Item|WP_Error
1516 * @since 4.0.0
1517 */
1518 function learn_press_user_start_quiz( $quiz_id, $user_id = 0, $course_id = 0, $wp_error = false ) {
1519 if ( ! $user_id ) {
1520 $user_id = get_current_user_id();
1521 }
1522
1523 global $wpdb;
1524
1525 $query = $wpdb->prepare(
1526 "
1527 SELECT user_item_id, item_id id, item_type type
1528 FROM {$wpdb->learnpress_user_items}
1529 WHERE user_item_id = (SELECT max(user_item_id)
1530 FROM {$wpdb->learnpress_user_items}
1531 WHERE user_id = %d AND item_id = %d AND status IN ('enrolled', 'in-progress'))
1532 ",
1533 $user_id,
1534 $course_id
1535 );
1536
1537 $parent = $wpdb->get_row( $query );
1538
1539 do_action( 'learn-press/before-user-start-quiz', $quiz_id, $user_id, $course_id );
1540
1541 $user = learn_press_get_user( $user_id );
1542 $course_data = $user->get_course_data( $course_id );
1543 $quiz_data = $course_data->get_item( $quiz_id );
1544
1545 $quiz = LP_Quiz::get_quiz( $quiz_id );
1546 $duration = $quiz->get_duration();
1547 $user_quiz = learn_press_create_user_item_for_quiz(
1548 array(
1549 'user_item_id' => $quiz_data ? $quiz_data->get_user_item_id() : 0,
1550 'item_id' => $quiz->get_id(),
1551 'duration' => $duration ? $duration->get() : 0,
1552 'user_id' => $user_id,
1553 'parent_id' => $parent ? absint( $parent->user_item_id ) : 0,
1554 'ref_type' => $parent ? $parent->type : '',
1555 'ref_id' => $parent ? $parent->id : '',
1556 ),
1557 $wp_error
1558 );
1559
1560 if ( $user_quiz && ! is_wp_error( $user_quiz ) ) {
1561 do_action( 'learn-press/user-started-quiz', $user_quiz, $quiz_id, $user_id, $course_id );
1562 }
1563
1564 // Reset first cache
1565 //$user_quiz->get_status( 'status', true );
1566
1567 return $user_quiz;
1568 }
1569
1570 /**
1571 * Function retake quiz.
1572 *
1573 * @param [type] $quiz_id
1574 * @param integer $user_id
1575 * @param integer $course_id
1576 * @param boolean $wp_error
1577 *
1578 * @return void
1579 */
1580 function learn_press_user_retake_quiz( $quiz_id, $user_id = 0, $course_id = 0, $wp_error = false ) {
1581 if ( ! $user_id ) {
1582 $user_id = get_current_user_id();
1583 }
1584
1585 if ( ! $course_id ) {
1586 return new WP_Error( 'invalid_course_id', esc_html__( 'Invalid Course ID.', 'learnpress' ) );
1587 }
1588
1589 global $wpdb;
1590
1591 $query = $wpdb->prepare(
1592 "
1593 SELECT user_item_id, item_id id, item_type type
1594 FROM {$wpdb->learnpress_user_items}
1595 WHERE user_item_id = (SELECT max(user_item_id)
1596 FROM {$wpdb->learnpress_user_items}
1597 WHERE user_id = %d AND item_id = %d AND status IN ('enrolled', 'in-progress'))
1598 ",
1599 $user_id,
1600 $course_id
1601 );
1602
1603 $parent = $wpdb->get_row( $query );
1604
1605 if ( ! $parent ) {
1606 return new WP_Error( 'invalid_user_item', esc_html__( 'Invalid Quiz', 'learnpress' ) );
1607 }
1608
1609 $data = learn_press_get_user_item(
1610 array(
1611 'item_id' => $quiz_id,
1612 'user_id' => $user_id,
1613 'parent_id' => $parent ? absint( $parent->user_item_id ) : 0,
1614 'ref_type' => $parent ? $parent->type : LP_COURSE_CPT,
1615 'ref_id' => $parent ? $parent->id : '',
1616 )
1617 );
1618
1619 $user_item = new LP_User_Item_Quiz( $data );
1620
1621 $ratake_count = get_post_meta( $quiz_id, '_lp_retake_count', true );
1622
1623 if ( $ratake_count > 0 ) {
1624 $user_item->update_retake_count();
1625 }
1626
1627 // Create new result in table learnpress_user_item_results.
1628 LP_User_Items_Result_DB::instance()->insert( $data->user_item_id );
1629
1630 // Remove user_item_meta.
1631 learn_press_delete_user_item_meta( $data->user_item_id, '_lp_question_checked' );
1632
1633 $user_item->set_status( LP_ITEM_STARTED )
1634 ->set_start_time( time() ) // Error Retake when change timezone - Nhamdv
1635 ->set_end_time()
1636 ->set_graduation( LP_COURSE_GRADUATION_IN_PROGRESS )
1637 ->update();
1638
1639 // Reset first cache
1640 //$user_item->get_status( 'status', true );
1641
1642 // Error Retake when change timezone - Nhamdv
1643 // learn_press_update_user_item_field(
1644 // array(
1645 // 'start_time' => current_time( 'mysql', true ),
1646 // ),
1647 // array(
1648 // 'user_item_id' => $data->user_item_id,
1649 // )
1650 // );
1651
1652 return $user_item;
1653 }
1654
1655
1656 /**
1657 * Prepares list of questions for rest api.
1658 *
1659 * @param int[] $question_ids
1660 * @param array $args
1661 *
1662 * @return array
1663 * @since 3.3.0
1664 */
1665 function learn_press_rest_prepare_user_questions( array $question_ids = array(), array $args = array() ) : array {
1666 if ( is_numeric( $args ) ) {
1667
1668 } else {
1669 $args = wp_parse_args(
1670 $args,
1671 array(
1672 'instant_hint' => true,
1673 'instant_check' => true,
1674 'quiz_status' => '',
1675 'checked_questions' => array(),
1676 'hinted_questions' => array(),
1677 'answered' => array(),
1678 'show_correct_review' => true,
1679 )
1680 );
1681 }
1682
1683 $checkedQuestions = $args['checked_questions'];
1684 $hintedQuestions = $args['hinted_questions'];
1685 $instantHint = $args['instant_hint'];
1686 $instantCheck = $args['instant_check'];
1687 $quizStatus = $args['quiz_status'];
1688 $answered = $args['answered'];
1689 $status = $args['status'] ?? '';
1690 $questions = array();
1691
1692 if ( $question_ids ) {
1693 foreach ( $question_ids as $id ) {
1694 $question = learn_press_get_question( $id );
1695 $hasHint = false;
1696 $hasExplanation = false;
1697 $canCheck = false;
1698 $hinted = false;
1699 $checked = false;
1700 $theHint = $question->get_hint();
1701 $theExplanation = '';
1702
1703 if ( $instantCheck || $status == 'completed' ) {
1704 $theExplanation = $question->get_explanation();
1705 $checked = in_array( $id, $checkedQuestions );
1706 $hasExplanation = ! ! $theExplanation;
1707 }
1708
1709 $mark = $question->get_mark() ? $question->get_mark() : 1;
1710
1711 $questionData = array(
1712 'object' => $question,
1713 'id' => absint( $id ),
1714 'title' => $question->get_title(),
1715 'type' => $question->get_type(),
1716 'point' => $mark,
1717 );
1718
1719 $content = $question->get_content();
1720 if ( $content ) {
1721 $questionData['content'] = $content;
1722 }
1723
1724 if ( $theHint ) {
1725 $questionData['hint'] = $theHint;
1726 }
1727
1728 if ( $status == 'completed' || ( $checked && $theExplanation ) ) {
1729 $questionData['explanation'] = $theExplanation;
1730 }
1731
1732 if ( $hasExplanation ) {
1733 $questionData['has_explanation'] = $hasExplanation;
1734
1735 if ( $checked ) {
1736 $questionData['explanation'] = $theExplanation;
1737 }
1738 }
1739
1740 $with_true_or_false = ( $checked || ( $quizStatus == 'completed' && $args['show_correct_review'] ) );
1741
1742 // if ( $question->is_support( 'answer-options' ) ) {
1743 $questionData['options'] = learn_press_get_question_options_for_js(
1744 $question,
1745 array(
1746 'include_is_true' => $with_true_or_false,
1747 'answer' => $answered[ $id ]['answered'] ?? '',
1748 )
1749 );
1750 // }
1751
1752 $questions[] = $questionData;
1753 }
1754
1755 /**
1756 * Remove answered
1757 */
1758 if ( $quizStatus !== 'completed' ) {
1759 if ( $checkedQuestions && $quizStatus ) {
1760
1761 $omitIds = array_diff( $question_ids, $checkedQuestions );
1762
1763 if ( $omitIds ) {
1764 foreach ( $omitIds as $omitId ) {
1765 if ( ! empty( $answered[ $omitId ] ) ) {
1766 unset( $answered[ $omitId ] );
1767 }
1768 }
1769 }
1770 }
1771 }
1772 }
1773
1774 return apply_filters( 'learn-press/list-questions-data', $questions );
1775 }
1776
1777 /**
1778 * Update extra profile data upon update user.
1779 *
1780 * @param int $user_id
1781 *
1782 * @since 4.0.0
1783 */
1784 function learn_press_update_extra_user_profile_fields( $user_id ) {
1785 if ( ! current_user_can( 'edit_user', $user_id ) ) {
1786 return;
1787 }
1788
1789 if ( isset( $_POST['_lp_extra_info'] ) ) {
1790 update_user_meta( $user_id, '_lp_extra_info', LP_Helper::sanitize_params_submitted( $_POST['_lp_extra_info'] ) );
1791 }
1792 }
1793 add_action( 'personal_options_update', 'learn_press_update_extra_user_profile_fields' );
1794 add_action( 'edit_user_profile_update', 'learn_press_update_extra_user_profile_fields' );
1795
1796 /**
1797 * Get extra profile info data
1798 *
1799 * @param int $user_id
1800 *
1801 * @return array
1802 * @since 4.0.0
1803 */
1804 function learn_press_get_user_extra_profile_info( $user_id = 0 ) {
1805 if ( ! $user_id ) {
1806 $user_id = get_current_user_id();
1807 }
1808
1809 $extra_profile_info = get_the_author_meta( '_lp_extra_info', $user_id );
1810 $extra_fields = learn_press_get_user_extra_profile_fields();
1811
1812 $extra_profile_info = wp_parse_args(
1813 $extra_profile_info,
1814 array_fill_keys( array_keys( $extra_fields ), '' )
1815 );
1816
1817 return apply_filters( 'learn-press/user-extra-profile-info', $extra_profile_info, $user_id );
1818 }
1819
1820 function learn_press_social_profiles() {
1821 return apply_filters(
1822 'learn-press/social-profiles',
1823 array(
1824 'facebook',
1825 'twitter',
1826 'youtube',
1827 'linkedin',
1828 )
1829 );
1830 }
1831
1832 function lp_add_default_fields( $fields ) {
1833 $first_name = LP_Settings::get_option( 'enable_register_first_name', 'no' );
1834
1835 if ( $first_name === 'yes' ) {
1836 ?>
1837 <li class="form-field">
1838 <label for="reg_first_name"><?php esc_html_e( 'First name', 'learnpress' ); ?></label>
1839 <input id="reg_first_name" name="reg_first_name" type="text"
1840 placeholder="<?php esc_attr_e( 'First name', 'learnpress' ); ?>"
1841 value="<?php echo esc_attr( wp_unslash( $_POST['reg_first_name'] ?? '' ) ); ?>">
1842 </li>
1843 <?php
1844 }
1845
1846 $last_name = LP_Settings::instance()->get( 'enable_register_last_name' );
1847
1848 if ( $last_name === 'yes' ) {
1849 ?>
1850 <li class="form-field">
1851 <label for="reg_last_name"><?php esc_html_e( 'Last name', 'learnpress' ); ?></label>
1852 <input id="reg_last_name" name="reg_last_name" type="text"
1853 placeholder="<?php esc_attr_e( 'Last name', 'learnpress' ); ?>"
1854 value="<?php echo esc_attr( wp_unslash( $_POST['reg_last_name'] ?? '' ) ); ?>">
1855 </li>
1856 <?php
1857 }
1858
1859 $display_name = LP_Settings::instance()->get( 'enable_register_display_name' );
1860
1861 if ( $display_name === 'yes' ) {
1862 ?>
1863 <li class="form-field">
1864 <label for="reg_display_name"><?php esc_html_e( 'Display name', 'learnpress' ); ?></label>
1865 <input id="reg_display_name" name="reg_display_name" type="text"
1866 placeholder="<?php esc_attr_e( 'Display name', 'learnpress' ); ?>"
1867 value="<?php echo esc_attr( wp_unslash( $_POST['reg_display_name'] ?? '' ) ); ?>">
1868 </li>
1869 <?php
1870 }
1871 }
1872
1873 add_filter( 'learn-press/after-form-register-fields', 'lp_add_default_fields' );
1874
1875 function lp_custom_register_fields_display() {
1876 ?>
1877 <?php $custom_fields = LP_Settings::instance()->get( 'register_profile_fields' ); ?>
1878
1879 <?php if ( $custom_fields ) : ?>
1880 <?php foreach ( $custom_fields as $custom_field ) : ?>
1881 <?php
1882 $cf_class = '';
1883 if ( $custom_field['required'] == 'yes' ) {
1884 $cf_class = ' required';
1885 ?>
1886 <style>
1887 .required label {
1888 font-weight: bold;
1889 }
1890 .required label:after {
1891 content: ' *';
1892 display:inline;
1893 }
1894 </style>
1895 <?php
1896 }
1897
1898 if ( isset( $custom_field['id'] ) ) {
1899 ?>
1900 <?php $value = $custom_field['id']; ?>
1901
1902 <li class="form-field<?php echo esc_attr( $cf_class ); ?>">
1903 <?php
1904 switch ( $custom_field['type'] ) {
1905 case 'text':
1906 case 'number':
1907 case 'email':
1908 case 'url':
1909 case 'tel':
1910 ?>
1911 <label for="description"><?php echo esc_html( $custom_field['name'] ); ?></label>
1912 <input name="_lp_custom_register_form[<?php echo esc_attr( $value ); ?>]"
1913 type="<?php echo esc_attr( $custom_field['type'] ); ?>" class="regular-text"
1914 value="" />
1915 <?php
1916 break;
1917 case 'textarea':
1918 ?>
1919 <label for="description"><?php echo esc_html( $custom_field['name'] ); ?></label>
1920 <textarea name="_lp_custom_register_form[<?php echo esc_attr( $value ); ?>]"></textarea>
1921 <?php
1922 break;
1923 case 'checkbox':
1924 ?>
1925 <label>
1926 <input name="_lp_custom_register_form[<?php echo esc_attr( $value ); ?>]"
1927 type="<?php echo esc_attr( $custom_field['type'] ); ?>" value="1">
1928 <?php echo esc_html( $custom_field['name'] ); ?>
1929 </label>
1930 <?php
1931 break;
1932 }
1933 ?>
1934 </li>
1935 <?php } ?>
1936 <?php endforeach; ?>
1937 <?php endif; ?>
1938 <?php
1939 }
1940
1941 add_action( 'learn-press/after-form-register-fields', 'lp_custom_register_fields_display' );
1942
1943 /**
1944 * Custom register fields
1945 *
1946 * @param [type] $user_id
1947 *
1948 * @return void
1949 */
1950 function lp_user_custom_register_fields( $user_id, $fields = array() ) {
1951 if ( ! empty( $fields ) ) {
1952 update_user_meta( $user_id, '_lp_custom_register', LP_Helper::sanitize_params_submitted( $fields ) );
1953 } elseif ( isset( $_POST['_lp_custom_register'] ) ) {
1954 update_user_meta( $user_id, '_lp_custom_register', LP_Helper::sanitize_params_submitted( $_POST['_lp_custom_register'] ) );
1955 }
1956 }
1957
1958 add_action( 'personal_options_update', 'lp_user_custom_register_fields' );
1959 add_action( 'edit_user_profile_update', 'lp_user_custom_register_fields' );
1960
1961 function lp_get_user_custom_register_fields( $user_id = 0 ) {
1962 if ( ! $user_id ) {
1963 $user_id = get_current_user_id();
1964 }
1965
1966 $register_fields = get_the_author_meta( '_lp_custom_register', $user_id );
1967 $defaults = lp_get_user_custom_fields();
1968
1969 $extra_profile_info = wp_parse_args( $register_fields, $defaults );
1970
1971 return apply_filters( 'lp/user-custom-register-fields', $register_fields, $user_id );
1972 }
1973
1974 function lp_get_user_custom_fields() {
1975 $custom_fields = LP_Settings::instance()->get( 'register_profile_fields' );
1976
1977 $output = array();
1978
1979 if ( $custom_fields ) {
1980 foreach ( $custom_fields as $field ) {
1981 $output[ $field['id'] ] = '';
1982 }
1983 }
1984
1985 return $output;
1986 }
1987
1988 /**
1989 * Check extra user data is a social profile.
1990 *
1991 * @param $key
1992 *
1993 * @return bool
1994 * @since 4.0.0
1995 */
1996 function learn_press_is_social_profile( $key ) {
1997 $is_socials = learn_press_social_profiles();
1998
1999 return in_array( $key, $is_socials );
2000 }
2001
2002 function learn_press_social_profile_name( $key ) {
2003 $name = '';
2004 switch ( $key ) {
2005 case 'facebook':
2006 $name = esc_html__( 'Facebook Profile', 'learnpress' );
2007 break;
2008 case 'twitter':
2009 $name = esc_html__( 'Twitter Profile', 'learnpress' );
2010 break;
2011 case 'googleplus':
2012 $name = esc_html__( 'Google Profile', 'learnpress' );
2013 break;
2014 case 'youtube':
2015 $name = esc_html__( 'Youtube Channel', 'learnpress' );
2016 break;
2017 case 'linkedin':
2018 $name = esc_html__( 'Linkedin Profile', 'learnpress' );
2019 break;
2020 default:
2021 $name = ucfirst( $key );
2022 }
2023
2024 return apply_filters( 'learn-press/social-profile-name', $name, $key );
2025 }
2026
2027 /**
2028 * Get extra profile fields will be registered in backend profile.
2029 *
2030 * @return array
2031 * @since 4.0.0
2032 */
2033 function learn_press_get_user_extra_profile_fields() {
2034 $socials = learn_press_social_profiles();
2035 $fields = array();
2036
2037 foreach ( $socials as $social ) {
2038 $fields[ $social ] = learn_press_social_profile_name( $social );
2039 }
2040
2041 return apply_filters( 'learn-press/user-extra-profile-fields', $fields );
2042 }
2043
2044 /**
2045 * Show courses user enrolled on backend
2046 *
2047 * @param $user
2048 *
2049 * @return void
2050 */
2051 function learn_press_user_profile_data( $user ) {
2052 if ( ! is_admin() ) {
2053 return;
2054 }
2055
2056 learn_press_admin_view( 'backend-user-profile', array( 'user' => $user ) );
2057 learn_press_admin_view( 'user/courses.php', array( 'user_id' => $user->ID ) );
2058 }
2059 add_action( 'edit_user_profile', 'learn_press_user_profile_data', 1000 );
2060
2061 function learnpress_get_count_by_user( $user_id = '', $post_type = 'lp_course' ) {
2062 if ( empty( $user_id ) ) {
2063 return false;
2064 }
2065
2066 $args = array(
2067 'author' => $user_id,
2068 'posts_per_page' => - 1,
2069 'post_type' => $post_type,
2070 'post_status' => 'any',
2071 );
2072
2073 $posts = get_posts( $args );
2074
2075 $output = array(
2076 'all' => count( $posts ),
2077 'publish' => array(),
2078 'pending' => array(),
2079 );
2080
2081 $pending = $public = array();
2082
2083 if ( ! empty( $posts ) ) {
2084 foreach ( $posts as $post ) {
2085 switch ( $post->post_status ) {
2086 case 'pending':
2087 $pending[] = $post;
2088 break;
2089 case 'publish':
2090 $public[] = $post;
2091 break;
2092 default:
2093 break;
2094 }
2095 }
2096 }
2097
2098 return array(
2099 'all' => count( $posts ),
2100 'publish' => count( $public ),
2101 'pending' => count( $pending ),
2102 );
2103
2104 }
2105