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

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

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