PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
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
← All changes | inc/user/lp-user-functions.php +1572 -1728 4.3.94.4.8 View file →
@@ -1,1728 +1,1572 @@
1 -<?php
2 -
3 -use LearnPress\Models\UserItems\UserItemModel;
4 -use LearnPress\Models\UserModel;
5 -
6 -/**
7 - * Common functions to process actions about user
8 - *
9 - * @author ThimPress
10 - * @package LearnPress/Functions/User
11 - * @version 1.0
12 - */
13 -function learn_press_get_user_profile_tabs() {
14 - return LP_Profile::instance()->get_tabs();
15 -}
16 -
17 -/**
18 - * Ensure new users receive a public slug.
19 - *
20 - * @param int $user_id
21 - *
22 - * @return void
23 - */
24 -function learn_press_maybe_generate_user_pretty_slug_on_register( int $user_id ) {
25 - $userModel = UserModel::find( $user_id, true );
26 - if ( ! $userModel ) {
27 - return;
28 - }
29 -
30 - $userModel->generate_pretty_slug();
31 -}
32 -
33 -//add_action( 'user_register', 'learn_press_maybe_generate_user_pretty_slug_on_register' );
34 -
35 -/**
36 - * Delete user data by user ID
37 - *
38 - * @param int $user_id
39 - * @param int $course_id
40 - */
41 -function learn_press_delete_user_data( $user_id, $course_id = 0 ) {
42 - global $wpdb;
43 - // TODO: Should be deleted user's order and order data???
44 -
45 - $query_args = array( $user_id );
46 -
47 - if ( $course_id ) {
48 - $query_args[] = $course_id;
49 - }
50 -
51 - $query = $wpdb->prepare(
52 - "
53 - SELECT user_item_id
54 - FROM {$wpdb->prefix}learnpress_user_items
55 - WHERE user_id = %d
56 - " . ( $course_id ? ' AND item_id = %d' : '' ) . '
57 - ',
58 - $query_args
59 - );
60 -
61 - // delete all courses user has enrolled
62 - $query = $wpdb->prepare(
63 - "
64 - DELETE FROM {$wpdb->prefix}learnpress_user_items
65 - WHERE user_id = %d
66 - " . ( $course_id ? ' AND item_id = %d' : '' ) . '
67 - ',
68 - $query_args
69 - );
70 -
71 - @$wpdb->query( $query );
72 -}
73 -
74 -/**
75 - * Get current user ID
76 - *
77 - * @return int|string LP_User is int, LP_User_Guest is string
78 - */
79 -function learn_press_get_current_user_id() {
80 - $user = learn_press_get_current_user();
81 -
82 - if ( ! $user ) {
83 - return 0;
84 - }
85 -
86 - return $user->get_id();
87 -}
88 -
89 -/**
90 - * Get the user by $user_id passed. If $user_id is NULL, get current user.
91 - * If current user is not logged in, return a GUEST user
92 - *
93 - * @param bool $create_temp - Optional. Create temp user if user is not logged in.
94 - *
95 - * @return LP_User|LP_User_Guest
96 - * @editor tungnx
97 - * @modify 4.1.4
98 - * @version 1.0.1
99 - */
100 -function learn_press_get_current_user( $create_temp = true ) {
101 - $user_id = get_current_user_id();
102 -
103 - if ( $user_id ) {
104 - return learn_press_get_user( $user_id );
105 - }
106 -
107 - // Return LP_User_Guest
108 - return learn_press_get_user( 0 );
109 -}
110 -
111 -if ( ! function_exists( 'learn_press_get_user' ) ) {
112 - /**
113 - * Get user by ID. Return false if the user does not exist.
114 - * If user_id = 0, return a guest user.
115 - *
116 - * @param int $user_id
117 - * @param bool $current
118 - *
119 - * @return LP_User|LP_User_Guest|false
120 - * @since 3.0.0
121 - * @version 4.0.1
122 - */
123 - function learn_press_get_user( $user_id = 0, $current = false, $force_new = false ) {
124 - $userClass = $user_id && get_user_by( 'ID', $user_id ) ? 'LP_User' : ( $user_id == 0 ? 'LP_User_Guest' : false );
125 - if ( false === $userClass ) {
126 - return false;
127 - }
128 -
129 - return new $userClass( $user_id );
130 - }
131 -}
132 -
133 -/**
134 - * Add more 2 user roles teacher and student
135 - */
136 -function learn_press_add_user_roles() {
137 - $course_cap = LP_COURSE_CPT . 's';
138 - $lesson_cap = LP_LESSON_CPT . 's';
139 - $order_cap = LP_ORDER_CPT . 's';
140 -
141 - if ( ! get_role( LP_TEACHER_ROLE ) ) {
142 - add_role( LP_TEACHER_ROLE, 'LP Instructor' );
143 - }
144 -
145 - $teacher = get_role( LP_TEACHER_ROLE );
146 - if ( $teacher ) {
147 - $teacher->add_cap( 'read_private_' . $course_cap );
148 - $teacher->add_cap( 'delete_published_' . $course_cap );
149 - $teacher->add_cap( 'edit_published_' . $course_cap );
150 - $teacher->add_cap( 'edit_' . $course_cap );
151 - $teacher->add_cap( 'delete_' . $course_cap );
152 - // $teacher->add_cap( 'unfiltered_html' );
153 - if ( $teacher->has_cap( 'unfiltered_html' ) ) {
154 - $teacher->remove_cap( 'unfiltered_html' );
155 - }
156 -
157 - if ( LP_Settings::get_option( 'required_review', 'yes' ) == 'yes' ) {
158 - $teacher->remove_cap( 'publish_' . $course_cap );
159 - } else {
160 - $teacher->add_cap( 'publish_' . $course_cap );
161 - }
162 -
163 - $teacher->add_cap( 'read_private_' . $lesson_cap );
164 - $teacher->add_cap( 'delete_published_' . $lesson_cap );
165 - $teacher->add_cap( 'edit_published_' . $lesson_cap );
166 - $teacher->add_cap( 'edit_' . $lesson_cap );
167 - $teacher->add_cap( 'delete_' . $lesson_cap );
168 - $teacher->add_cap( 'publish_' . $lesson_cap );
169 - $teacher->add_cap( 'upload_files' );
170 - $teacher->add_cap( 'read' );
171 - $teacher->add_cap( 'edit_posts' );
172 - }
173 -
174 - // administrator
175 - $admin = get_role( 'administrator' );
176 - if ( $admin ) {
177 - $admin->add_cap( 'lp_mcp_access' );
178 -
179 - $admin->add_cap( 'read_private_' . $course_cap );
180 - $admin->add_cap( 'delete_' . $course_cap );
181 - $admin->add_cap( 'delete_published_' . $course_cap );
182 - $admin->add_cap( 'edit_' . $course_cap );
183 - $admin->add_cap( 'edit_published_' . $course_cap );
184 - $admin->add_cap( 'publish_' . $course_cap );
185 - $admin->add_cap( 'delete_private_' . $course_cap );
186 - $admin->add_cap( 'edit_private_' . $course_cap );
187 - $admin->add_cap( 'delete_others_' . $course_cap );
188 - $admin->add_cap( 'edit_others_' . $course_cap );
189 -
190 - $admin->add_cap( 'read_private_' . $lesson_cap );
191 - $admin->add_cap( 'delete_' . $lesson_cap );
192 - $admin->add_cap( 'delete_published_' . $lesson_cap );
193 - $admin->add_cap( 'edit_' . $lesson_cap );
194 - $admin->add_cap( 'edit_published_' . $lesson_cap );
195 - $admin->add_cap( 'publish_' . $lesson_cap );
196 - $admin->add_cap( 'delete_private_' . $lesson_cap );
197 - $admin->add_cap( 'edit_private_' . $lesson_cap );
198 - $admin->add_cap( 'delete_others_' . $lesson_cap );
199 - $admin->add_cap( 'edit_others_' . $lesson_cap );
200 -
201 - $admin->add_cap( 'delete_' . $order_cap );
202 - $admin->add_cap( 'delete_published_' . $order_cap );
203 - $admin->add_cap( 'edit_' . $order_cap );
204 - $admin->add_cap( 'edit_published_' . $order_cap );
205 - $admin->add_cap( 'publish_' . $order_cap );
206 - $admin->add_cap( 'delete_private_' . $order_cap );
207 - $admin->add_cap( 'edit_private_' . $order_cap );
208 - $admin->add_cap( 'delete_others_' . $order_cap );
209 - $admin->add_cap( 'edit_others_' . $order_cap );
210 - }
211 -}
212 -
213 -/**
214 - * Remove capabilities added for MCP integration.
215 - *
216 - * @return void
217 - */
218 -function learn_press_remove_mcp_capabilities() {
219 -
220 - $admin = get_role( 'administrator' );
221 - if ( $admin ) {
222 - $admin->remove_cap( 'lp_mcp_access' );
223 - }
224 -}
225 -/*
226 -function learn_press_current_user_is( $check_type = null ) {
227 - global $current_user;
228 - $user_roles = $current_user->roles;
229 - $user_type = '';
230 -
231 - if ( in_array( 'lpr_teacher', $user_roles ) ) {
232 - $user_type = 'instructor';
233 - } elseif ( in_array( 'lp_teacher', $user_roles ) ) {
234 - $user_type = 'instructor';
235 - } elseif ( in_array( 'administrator', $user_roles ) ) {
236 - $user_type = 'administrator';
237 - }
238 -
239 - return $check_type ? $check_type == $user_type : $user_type;
240 -}*/
241 -
242 -/*
243 -function learn_press_user_has_roles( $roles, $user_id = null ) {
244 - $has_role = false;
245 - if ( ! $user_id ) {
246 - $user = wp_get_current_user();
247 - } else {
248 - $user = get_user_by( 'id', $user_id );
249 - }
250 - $available_roles = (array) $user->roles;
251 - if ( is_array( $roles ) ) {
252 - foreach ( $roles as $role ) {
253 - if ( in_array( $role, $available_roles ) ) {
254 - $has_role = true;
255 - break; // only need one of roles is in available
256 - }
257 - }
258 - } else {
259 - if ( in_array( $roles, $available_roles ) ) {
260 - $has_role = true;
261 - }
262 - }
263 -
264 - return $has_role;
265 -}*/
266 -
267 -/*
268 -function learn_press_current_user_can_view_profile_section( $section, $user ) {
269 - $current_user = wp_get_current_user();
270 - $view = true;
271 - if ( $user->get_data( 'user_login' ) != $current_user->user_login && $section == LP_Settings::instance()->get(
272 - 'profile_endpoints.orders',
273 - 'profile-orders'
274 - ) ) {
275 - $view = false;
276 - }
277 -
278 - return apply_filters( 'learn_press_current_user_can_view_profile_section', $view, $section, $user );
279 -}*/
280 -
281 -/*
282 -function learn_press_profile_tab_quizzes_content( $current, $tab, $user ) {
283 - learn_press_get_template(
284 - 'profile/tabs/quizzes.php',
285 - array(
286 - 'user' => $user,
287 - 'current' => $current,
288 - 'tab' => $tab,
289 - )
290 - );
291 -}*/
292 -
293 -/*
294 -function learn_press_profile_tab_orders_content( $current, $tab, $user ) {
295 - learn_press_get_template(
296 - 'profile/tabs/orders.php',
297 - array(
298 - 'user' => $user,
299 - 'current' => $current,
300 - 'tab' => $tab,
301 - )
302 - );
303 -}*/
304 -
305 -/**
306 - * Get queried user in profile link
307 - *
308 - * @return false|WP_User
309 - * @since 3.0.0
310 - * @deprecated 4.2.9.1
311 - */
312 -function learn_press_get_profile_user() {
313 - return LP_Profile::instance()->get_user_current();
314 -
315 - return LP_Profile::get_queried_user();
316 -}
317 -
318 -
319 -/**
320 - * Add instructor registration button to register page and admin bar
321 - */
322 -function learn_press_user_become_teacher_registration_form() {
323 - if ( LP_Settings::instance()->get( 'instructor_registration' ) != 'yes' ) {
324 - return;
325 - }
326 - ?>
327 - <p>
328 - <label for="become_teacher">
329 - <input type="checkbox" name="become_teacher" id="become_teacher">
330 - <?php esc_html_e( 'Want to become an instructor?', 'learnpress' ); ?>
331 - </label>
332 - </p>
333 - <?php
334 -}
335 -
336 -add_action( 'register_form', 'learn_press_user_become_teacher_registration_form' );
337 -
338 -/**
339 - * Update data into table learnpress_user_items.
340 - *
341 - * @param array $fields - Fields and values to be updated.
342 - * Format: array(
343 - * field_name_1 => value 1,
344 - * field_name_2 => value 2,
345 - * ....
346 - * field_name_n => value n
347 - * )
348 - * @param mixed $where - Optional. Fields with values for conditional update with the same format of $fields.
349 - * @param bool $update_cache - Optional. Should be update to cache or not (since 3.0.0).
350 - * @param bool $update_extra_fields_as_meta - Optional. Update extra fields as item meta (since 3.1.0).
351 - *
352 - * @return mixed
353 - */
354 -function learn_press_update_user_item_field( array $fields = array(), $where = false, $update_cache = true, $update_extra_fields_as_meta = false ) {
355 - global $wpdb;
356 -
357 - // Table fields format.
358 - $table_fields = array(
359 - 'user_item_id' => '%d',
360 - 'user_id' => '%d',
361 - 'item_id' => '%d',
362 - 'ref_id' => '%d',
363 - 'start_time' => '%s',
364 - 'end_time' => '%s',
365 - 'access_level' => '%d',
366 - 'graduation' => '%s',
367 - 'item_type' => '%s',
368 - 'status' => '%s',
369 - 'ref_type' => '%s',
370 - 'parent_id' => '%d',
371 - );
372 -
373 - /**
374 - * Validate item status
375 - */
376 - if ( ! empty( $fields['item_id'] ) && ! empty( $fields['status'] ) ) {
377 - $item_type = learn_press_get_post_type( $fields['item_id'] );
378 -
379 - if ( LP_COURSE_CPT === $item_type ) {
380 - if ( 'completed' === $fields['status'] ) {
381 - $fields['status'] = 'finished';
382 - }
383 - } elseif ( 'finished' === $fields['status'] ) {
384 - $fields['status'] = 'completed';
385 - }
386 - }
387 -
388 - $data = array();
389 - $data_format = array();
390 - foreach ( $fields as $field => $value ) {
391 - if ( ! empty( $table_fields[ $field ] ) ) {
392 - $data[ $field ] = $value;
393 -
394 - // Do not format the date-time field if it's value is NULL
395 - if ( in_array( $field, array( 'start_time', 'end_time' ) ) && empty( $value ) ) {
396 - $data[ $field ] = null;
397 - $data_format[] = '';
398 - } else {
399 - if ( $value instanceof LP_Datetime ) {
400 - $data[ $field ] = $value->toSql();
401 - }
402 - $data_format[] = $table_fields[ $field ];
403 - }
404 - }
405 - }
406 -
407 - if ( ! empty( $fields['user_item_id'] ) ) {
408 - $where = wp_parse_args(
409 - $where,
410 - array( 'user_item_id' => $fields['user_item_id'] )
411 - );
412 - }
413 -
414 - // Set where and where format
415 - $where_format = array();
416 - if ( is_array( $where ) && ! empty( $where ) ) {
417 - if ( empty( $where['user_id'] ) ) {
418 - $where['user_id'] = ! empty( $fields['user_id'] ) ? $fields['user_id'] : learn_press_get_current_user_id();
419 - }
420 -
421 - foreach ( $where as $field => $value ) {
422 - if ( isset( $table_fields[ $field ] ) ) {
423 - $where_format[] = $table_fields[ $field ];
424 - }
425 - }
426 - }
427 -
428 - if ( ! $data ) {
429 - return false;
430 - }
431 -
432 - $inserted = false;
433 - $updated = false;
434 -
435 - // Update to database.
436 - if ( $where ) {
437 - $updated = $wpdb->update(
438 - $wpdb->learnpress_user_items,
439 - $data,
440 - $where,
441 - $data_format,
442 - $where_format
443 - );
444 - } else {
445 - // Insert to database.
446 - if ( $wpdb->insert(
447 - $wpdb->learnpress_user_items,
448 - $data,
449 - $data_format
450 - ) ) {
451 - $inserted = $wpdb->insert_id;
452 - }
453 - }
454 -
455 - if ( $updated && ! empty( $where['user_item_id'] ) ) {
456 - $inserted = $where['user_item_id'];
457 - }
458 -
459 - /**
460 - * @var object|bool $updated_item
461 - */
462 - $updated_item = false;
463 -
464 - // Get the item we just have updated or inserted.
465 - if ( $inserted ) {
466 - $updated_item = learn_press_get_user_item( $inserted );
467 - } elseif ( $updated ) {
468 - $updated_item = learn_press_get_user_item( $where );
469 - }
470 -
471 - // Clear caches.
472 - if ( $updated_item ) {
473 - // Clear cache total students enrolled.
474 - if ( isset( $updated_item->item_type )
475 - && LP_COURSE_CPT === $updated_item->item_type
476 - && isset( $updated_item->item_id ) ) {
477 - $lp_course_cache = new LP_Course_Cache( true );
478 - $lp_course_cache->clean_total_students_enrolled( $updated_item->item_id );
479 - $lp_course_cache->clean_total_students_enrolled_or_purchased( $updated_item->item_id );
480 - // Clear cache count students many courses.
481 - $lp_courses_cache = new LP_Courses_Cache( true );
482 - $lp_courses_cache->clear_cache_on_group( LP_Courses_Cache::KEYS_COUNT_STUDENT_COURSES );
483 - }
484 - // Clear cache user item.
485 - $lp_user_items_cache = new LP_User_Items_Cache();
486 - $lp_user_items_cache->clean_user_item(
487 - array(
488 - $updated_item->user_id,
489 - $updated_item->item_id,
490 - $updated_item->item_type,
491 - )
492 - );
493 - // Clear cache userItemModel
494 - $userItemModel = UserItemModel::find_user_item(
495 - $updated_item->user_id,
496 - $updated_item->item_id,
497 - $updated_item->item_type,
498 - $updated_item->ref_id,
499 - $updated_item->ref_type,
500 - true
501 - );
502 - $userItemModel->clean_caches();
503 - }
504 -
505 - do_action( 'learn-press/updated-user-item-field', $updated_item );
506 -
507 - /**
508 - * If there is some fields does not contain in the main table
509 - * then consider update them as metadata.
510 - *
511 - * @comment by tungnx - 4.1.7.3
512 - */
513 - /*
514 - if ( $updated_item && $update_extra_fields_as_meta ) {
515 - $extra_fields = array_diff_key( $fields, $table_fields );
516 - if ( $extra_fields ) {
517 - foreach ( $extra_fields as $meta_key => $meta_value ) {
518 - if ( $meta_value == 'user_item_id' ) {
519 - continue;
520 - }
521 -
522 - if ( $meta_value === false ) {
523 - learn_press_delete_user_item_meta( $updated_item->user_item_id, $meta_key );
524 - } else {
525 -
526 - if ( empty( $meta_value ) ) {
527 - $meta_value = '';
528 - }
529 - learn_press_update_user_item_meta( $updated_item->user_item_id, $meta_key, $meta_value );
530 - }
531 - }
532 - }
533 - }*/
534 -
535 - // do_action( 'learn-press/updated-user-item-meta', $updated_item );
536 -
537 - return $updated_item;
538 -}
539 -
540 -/**
541 - * Get user item row(s) from user items table by multiple WHERE conditional
542 - *
543 - * @param array|int $where
544 - * @param bool $single
545 - *
546 - * @return array
547 - */
548 -function learn_press_get_user_item( $where, $single = true ) {
549 - global $wpdb;
550 -
551 - // Table fields
552 - $table_fields = array(
553 - 'user_item_id' => '%d',
554 - 'user_id' => '%d',
555 - 'item_id' => '%d',
556 - 'ref_id' => '%d',
557 - 'start_time' => '%s',
558 - 'end_time' => '%s',
559 - 'item_type' => '%s',
560 - 'status' => '%s',
561 - 'ref_type' => '%s',
562 - 'parent_id' => '%d',
563 - );
564 -
565 - // If $where is a number consider we are searching the record with unique user_item_id
566 - if ( is_numeric( $where ) ) {
567 - $where = array( 'user_item_id' => $where );
568 - }
569 -
570 - $where_str = array();
571 - foreach ( $where as $field => $value ) {
572 - if ( ! empty( $table_fields[ $field ] ) ) {
573 - $where_str[] = "{$field} = " . $table_fields[ $field ];
574 - }
575 - }
576 - $item = false;
577 -
578 - if ( $where_str ) {
579 - $query = $wpdb->prepare(
580 - "
581 - SELECT *
582 - FROM {$wpdb->prefix}learnpress_user_items
583 - WHERE " . join( ' AND ', $where_str ) . '
584 - ORDER BY user_item_id DESC
585 - ',
586 - $where
587 - );
588 - if ( $single || ! empty( $where['user_item_id'] ) ) {
589 - $item = $wpdb->get_row( $query );
590 - } else {
591 - $item = $wpdb->get_results( $query );
592 - }
593 - }
594 -
595 - return $item;
596 -}
597 -
598 -/**
599 - * Get user item meta from user_itemmeta table
600 - *
601 - * @param int $user_item_id .
602 - * @param string $meta_key .
603 - * @param bool $single .
604 - *
605 - * @return mixed
606 - */
607 -function learn_press_get_user_item_meta( $user_item_id = 0, $meta_key = '', $single = true ) {
608 - $meta = false;
609 - if ( metadata_exists( 'learnpress_user_item', $user_item_id, $meta_key ) ) {
610 - $meta = get_metadata( 'learnpress_user_item', $user_item_id, $meta_key, $single );
611 - }
612 -
613 - return $meta;
614 -}
615 -
616 -/**
617 - * Add user item meta into table user_itemmeta
618 - *
619 - * @param int $user_item_id
620 - * @param string $meta_key
621 - * @param mixed $meta_value
622 - * @param string $prev_value
623 - *
624 - * @return false|int
625 - */
626 -function learn_press_add_user_item_meta( $user_item_id, $meta_key, $meta_value, $prev_value = '' ) {
627 - return add_metadata( 'learnpress_user_item', $user_item_id, $meta_key, $meta_value, $prev_value );
628 -}
629 -
630 -/**
631 - * Update user item meta to table user_itemmeta
632 - *
633 - * @param int $user_item_id
634 - * @param string $meta_key
635 - * @param mixed $meta_value
636 - * @param string $prev_value
637 - *
638 - * @return bool|int
639 - */
640 -function learn_press_update_user_item_meta( $user_item_id, $meta_key, $meta_value, $prev_value = '' ) {
641 - return update_metadata( 'learnpress_user_item', $user_item_id, $meta_key, $meta_value, $prev_value );
642 -}
643 -
644 -
645 -/**
646 - * Update user item meta to table user_itemmeta
647 - *
648 - * @param int $object_id
649 - * @param string $meta_key
650 - * @param mixed $meta_value
651 - * @param bool $delete_all
652 - *
653 - * @return bool|int
654 - */
655 -function learn_press_delete_user_item_meta( $object_id, $meta_key, $meta_value = '', $delete_all = false ) {
656 - return delete_metadata( 'learnpress_user_item', $object_id, $meta_key, $meta_value, $delete_all );
657 -}
658 -
659 -if ( ! function_exists( 'learn_press_pre_get_avatar_callback' ) ) {
660 - /**
661 - * Filter the avatar
662 - *
663 - * @param string $avatar
664 - * @param string $id_or_email
665 - * @param array $args
666 - *
667 - * @return string
668 - * @since 1.0.0
669 - * @version 1.0.2
670 - */
671 - function learn_press_pre_get_avatar_callback( $avatar, $id_or_email = '', $args = array() ) {
672 - try {
673 - if ( ( isset( $args['gravatar'] ) && $args['gravatar'] ) || ( $args['default'] && $args['force_default'] ) ) {
674 - return $avatar;
675 - }
676 -
677 - $user_id = 0;
678 -
679 - /**
680 - * Get the ID of user from $id_or_email
681 - */
682 - if ( ! is_numeric( $id_or_email ) && is_string( $id_or_email ) ) {
683 - $user = get_user_by( 'email', $id_or_email );
684 - if ( $user ) {
685 - $user_id = $user->ID;
686 - }
687 - } elseif ( is_numeric( $id_or_email ) ) {
688 - $user_id = $id_or_email;
689 - } elseif ( is_object( $id_or_email ) && isset( $id_or_email->user_id ) && $id_or_email->user_id ) {
690 - $user_id = $id_or_email->user_id;
691 - } elseif ( $id_or_email instanceof WP_Comment ) {
692 - $user = get_user_by( 'email', $id_or_email->comment_author_email );
693 - if ( $user ) {
694 - $user_id = $user->ID;
695 - }
696 - }
697 -
698 - if ( ! $user_id ) {
699 - return $avatar;
700 - }
701 -
702 - $user = UserModel::find( $user_id, true );
703 - if ( ! $user ) {
704 - return $avatar;
705 - }
706 -
707 - $class = array( 'avatar', 'avatar-' . (int) $args['size'], 'photo' );
708 - if ( $args['class'] ) {
709 - if ( is_array( $args['class'] ) ) {
710 - $class = array_merge( $class, $args['class'] );
711 - } else {
712 - $class[] = $args['class'];
713 - }
714 - }
715 -
716 - $avatar_url = $user->get_avatar_url();
717 - $html_img = sprintf(
718 - "<img src='%s' srcset='%s' class='%s' height='%d' width='%d' decoding='async'/>",
719 - esc_url( $avatar_url ),
720 - esc_url( $avatar_url ) . ' 2x',
721 - esc_attr( implode( ' ', $class ) ),
722 - (int) $args['height'],
723 - (int) $args['width']
724 - );
725 -
726 - return $html_img;
727 - } catch ( Throwable $e ) {
728 - error_log( $e->getMessage() );
729 -
730 - return $avatar;
731 - }
732 - }
733 -}
734 -add_filter( 'pre_get_avatar', 'learn_press_pre_get_avatar_callback', 999, 3 );
735 -
736 -
737 -function learn_press_user_profile_picture_upload_dir( $width_user = true ) {
738 - $upload_dir = wp_upload_dir();
739 - $subdir = apply_filters( 'learn_press_user_profile_folder', 'learn-press-profile', $width_user );
740 - if ( $width_user ) {
741 - $subdir .= '/' . get_current_user_id();
742 - }
743 - $subdir = '/' . $subdir;
744 -
745 - if ( ! empty( $upload_dir['subdir'] ) ) {
746 - $u_subdir = str_replace( '\\', '/', $upload_dir['subdir'] );
747 - $u_path = str_replace( '\\', '/', $upload_dir['path'] );
748 -
749 - $upload_dir['path'] = str_replace( $u_subdir, $subdir, $u_path );
750 - $upload_dir['url'] = str_replace( $u_subdir, $subdir, $upload_dir['url'] );
751 - } else {
752 - $upload_dir['path'] = $upload_dir['path'] . $subdir;
753 - $upload_dir['url'] = $upload_dir['url'] . $subdir;
754 - }
755 -
756 - $upload_dir['subdir'] = $subdir;
757 -
758 - // Point path/url to main site if we are in multisite
759 - if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
760 - foreach ( array( 'path', 'url', 'basedir', 'baseurl' ) as $v ) {
761 - $upload_dir[ $v ] = str_replace( '/sites/' . get_current_blog_id(), '', $upload_dir[ $v ] );
762 - }
763 - }
764 -
765 - return $upload_dir;
766 -}
767 -
768 -/*
769 -add_action( 'learn_press_before_purchase_course_handler', '_learn_press_before_purchase_course_handler', 10, 2 );
770 -function _learn_press_before_purchase_course_handler( $course_id, $cart ) {
771 - // Redirect to login page if user is not logged in
772 - if ( ! is_user_logged_in() ) {
773 - $return_url = esc_url_raw( add_query_arg( $_POST, get_the_permalink( $course_id ) ) );
774 - $return_url = apply_filters( 'learn_press_purchase_course_login_redirect_return_url', $return_url );
775 - $redirect = apply_filters(
776 - 'learn_press_purchase_course_login_redirect',
777 - learn_press_get_login_url( $return_url )
778 - );
779 - if ( $redirect !== false ) {
780 - learn_press_add_message( __( 'Please log in to enroll in this course', 'learnpress' ) );
781 -
782 - if ( learn_press_is_ajax() ) {
783 - learn_press_send_json(
784 - array(
785 - 'redirect' => $redirect,
786 - 'result' => 'success',
787 - )
788 - );
789 - } else {
790 - wp_redirect( $redirect );
791 - exit();
792 - }
793 - }
794 - } else {
795 - $user = learn_press_get_current_user();
796 - $redirect = false;
797 - if ( $user->has_finished_course( $course_id ) ) {
798 - learn_press_add_message( __( 'You have already finished the course', 'learnpress' ) );
799 - $redirect = true;
800 - } elseif ( $user->has_purchased_course( $course_id ) ) {
801 - learn_press_add_message( __( 'You have already enrolled in this course', 'learnpress' ) );
802 - $redirect = true;
803 - }
804 - if ( $redirect ) {
805 - wp_redirect( get_the_permalink( $course_id ) );
806 - exit();
807 - }
808 - }
809 -}*/
810 -
811 -/*
812 -function learn_press_user_is( $role, $user_id = 0 ) {
813 - if ( ! $user_id ) {
814 - $user = learn_press_get_current_user();
815 - } else {
816 - $user = learn_press_get_user( $user_id );
817 - }
818 - if ( $role == 'admin' ) {
819 - return $user->is_admin();
820 - }
821 - if ( $role == 'instructor' ) {
822 - return $user->is_instructor();
823 - }
824 -
825 - return $role;
826 -}*/
827 -
828 -/*
829 -function learn_press_profile_tab_edit_content( $current, $tab, $user ) {
830 - learn_press_get_template(
831 - 'profile/tabs/edit.php',
832 - array(
833 - 'user' => $user,
834 - 'current' => $current,
835 - 'tab' => $tab,
836 - )
837 - );
838 -}*/
839 -
840 -/*
841 -function learn_press_update_user_option( $name, $value, $id = 0 ) {
842 - if ( ! $id ) {
843 - $id = get_current_user_id();
844 - }
845 - $key = 'learnpress_user_options';
846 - $options = get_user_option( $key, $id );
847 - $options[ $name ] = $value;
848 - update_user_option( $id, $key, $options, true );
849 -}*/
850 -
851 -/*
852 -function learn_press_delete_user_option( $name, $id = 0 ) {
853 - if ( ! $id ) {
854 - $id = get_current_user_id();
855 - }
856 - $key = 'learnpress_user_options';
857 - $options = get_user_option( $key, $id );
858 - if ( is_array( $options ) && array_key_exists( $name, $options ) ) {
859 - unset( $options[ $name ] );
860 - update_user_option( $id, $key, $options, true );
861 -
862 - return true;
863 - }
864 -
865 - return false;
866 -}*/
867 -
868 -/*
869 -function learn_press_get_user_option( $name, $id = 0 ) {
870 - if ( ! $id ) {
871 - $id = get_current_user_id();
872 - }
873 - $key = 'learnpress_user_options';
874 - $options = get_user_option( $key, $id );
875 - if ( is_array( $options ) && array_key_exists( $name, $options ) ) {
876 - return $options[ $name ];
877 - }
878 -
879 - return false;
880 -}*/
881 -
882 -/**
883 - * Update user basic information.
884 - *
885 - * @param bool $wp_error - Optional. Return WP_Error object in case updating failed.
886 - *
887 - * @return bool|mixed|WP_Error
888 - */
889 -function learn_press_update_user_profile_basic_information( $wp_error = false ) {
890 - $user_id = get_current_user_id();
891 -
892 - if ( ! $user_id ) {
893 - return new WP_Error( 2, 'The user is invalid' );
894 - }
895 -
896 - $update_data = array(
897 - 'ID' => $user_id,
898 - 'first_name' => LP_Request::get_param( 'first_name' ),
899 - 'last_name' => LP_Request::get_param( 'last_name' ),
900 - 'description' => LP_Request::get_param( 'description', '', 'html' ),
901 - 'display_name' => LP_Request::get_param( 'account_display_name' ),
902 - 'user_email' => LP_Request::get_param( 'account_email' ),
903 - );
904 -
905 - $update_data = apply_filters( 'learn-press/update-profile-basic-information-data', $update_data );
906 - $update_meta = LP_Helper::sanitize_params_submitted( $_POST['_lp_custom_register'] ?? '' );
907 -
908 - $return = LP_Forms_Handler::update_user_data( $update_data, $update_meta );
909 -
910 - // Update for social.
911 - $socials = LP_Request::get_param( 'user_profile_social' );
912 - $extra_data = get_user_meta( $user_id, '_lp_extra_info', true );
913 -
914 - if ( ! empty( $extra_data ) ) {
915 - $socials = array_merge( $extra_data, $socials );
916 - }
917 -
918 - update_user_meta( $user_id, '_lp_extra_info', $socials );
919 -
920 - if ( is_wp_error( $return ) ) {
921 - return $wp_error ? $return : false;
922 - }
923 -
924 - return $return;
925 -}
926 -
927 -/**
928 - * Update new password.
929 - *
930 - * @version 1.0.1
931 - */
932 -function learn_press_update_user_profile_change_password() {
933 - try {
934 - $user = wp_get_current_user();
935 - if ( ! $user ) {
936 - throw new Exception( 'error_lp_profile_update_pass', 'The user is invalid' );
937 - }
938 -
939 - $old_pass = LP_Request::get_param( 'pass0', '', 'text', 'post' );
940 - if ( empty( $old_pass ) ) {
941 - throw new Exception( __( 'Enter the old password!', 'learnpress' ) );
942 - }
943 -
944 - $check_old_pass = wp_check_password( $old_pass, $user->data->user_pass, $user->ID );
945 - if ( ! $check_old_pass ) {
946 - throw new Exception( __( 'The old password is incorrect!', 'learnpress' ) );
947 - }
948 -
949 - $new_pass = LP_Request::get_param( 'pass1', '', 'text', 'post' );
950 - $new_pass_confirm = LP_Request::get_param( 'pass2', '', 'text', 'post' );
951 - if ( empty( $new_pass ) || empty( $new_pass_confirm )
952 - || $new_pass != $new_pass_confirm ) {
953 - throw new Exception( __( 'Incorrect confirmation password!', 'learnpress' ) );
954 - }
955 -
956 - // Update user password
957 - // wp_set_password( $new_pass, $user->ID );
958 - $update_data = array(
959 - 'user_pass' => $new_pass,
960 - 'ID' => $user->ID,
961 - );
962 -
963 - $rs = wp_update_user( $update_data );
964 - if ( is_wp_error( $rs ) ) {
965 - throw new Exception( $rs->get_error_message() );
966 - }
967 - } catch ( Exception $ex ) {
968 - return new WP_Error( 'error_lp_profile_update_pass', $ex->getMessage() );
969 - }
970 -
971 - return true;
972 -}
973 -
974 -function learn_press_get_avatar_thumb_size() {
975 - $option = LP_Settings::get_option(
976 - 'avatar_dimensions',
977 - array(
978 - 'width' => 250,
979 - 'height' => 250,
980 - )
981 - );
982 -
983 - if ( ! isset( $option['width'] ) || ! isset( $option['height'] ) ) {
984 - $option = array(
985 - 'width' => 250,
986 - 'height' => 250,
987 - );
988 - }
989 -
990 - // For option get_avatar_url
991 - $option['size'] = $option['width'];
992 -
993 - return $option;
994 -}
995 -
996 -function learn_press_get_course_thumbnail_dimensions() {
997 - $option = LP_Settings::get_option(
998 - 'course_thumbnail_dimensions',
999 - array(
1000 - 'width' => 500,
1001 - 'height' => 300,
1002 - )
1003 - );
1004 -
1005 - if ( ! isset( $option['width'] ) || ! isset( $option['height'] ) ) {
1006 - $option = array(
1007 - 'width' => 500,
1008 - 'height' => 300,
1009 - );
1010 - }
1011 -
1012 - return $option;
1013 -}
1014 -
1015 -/*
1016 -function learn_press_get_user_avatar( $user_id = 0, $size = '' ) {
1017 - $user = learn_press_get_user( $user_id );
1018 -
1019 - return $user->get_profile_picture( '', $size );
1020 -}*/
1021 -
1022 -/**
1023 - * Get profile instance for an user to view.
1024 - *
1025 - * @param int $for_user
1026 - *
1027 - * @return LP_Profile|WP_Error
1028 - */
1029 -function learn_press_get_profile( $for_user = 0 ) {
1030 - return LP_Profile::instance( $for_user );
1031 -}
1032 -
1033 -/*
1034 -function learn_press_remove_user_items( $user_id, $item_id, $course_id, $include_course = false ) {
1035 - global $wpdb;
1036 -
1037 - settype( $item_id, 'array' );
1038 -
1039 - $format = array_fill( 0, sizeof( $item_id ), '%d' );
1040 - $where = '';
1041 -
1042 - $args = array( $user_id );
1043 - $args = array_merge( $args, $item_id );
1044 -
1045 - if ( $course_id ) {
1046 - $args[] = $course_id;
1047 - $where = 'AND ref_id = %d';
1048 - }
1049 -
1050 - if ( $include_course ) {
1051 - $where .= ' OR ( item_id = %d AND item_type = %s )';
1052 - $args[] = $course_id;
1053 - $args[] = LP_COURSE_CPT;
1054 - }
1055 -
1056 - $query = $wpdb->prepare(
1057 - "
1058 - DELETE
1059 - FROM {$wpdb->learnpress_user_items}
1060 - WHERE user_id = %d
1061 - AND ( item_id IN(" . join( ',', $format ) . ")
1062 - $where )
1063 - ",
1064 - $args
1065 - );
1066 -}*/
1067 -
1068 -/**
1069 - * Get user profile link
1070 - *
1071 - * @param int $user_id
1072 - * @param null $tab
1073 - *
1074 - * @return mixed|string
1075 - */
1076 -function learn_press_user_profile_link( $user_id = 0, $tab = '' ) {
1077 - if ( ! $user_id ) {
1078 - $user_id = get_current_user_id();
1079 - }
1080 -
1081 - $user = learn_press_get_user( $user_id );
1082 -
1083 - if ( ! $user ) {
1084 - return '';
1085 - }
1086 -
1087 - global $wp_query;
1088 - $wp_user = get_userdata( $user_id );
1089 - if ( ! $wp_user instanceof WP_User ) {
1090 - return '';
1091 - }
1092 -
1093 - $user_model = new UserModel( $wp_user->data );
1094 - $args = array(
1095 - 'user' => $user_model->get_slug_link(),
1096 - );
1097 -
1098 - if ( $tab ) {
1099 - $args['tab'] = $tab;
1100 - }
1101 -
1102 - /**
1103 - * If no tab is selected in profile and is current user
1104 - * then no need the username in profile link.
1105 - */
1106 - if ( ( $user_id == get_current_user_id() ) && ! isset( $args['tab'] ) ) {
1107 - //unset( $args['user'] );
1108 - }
1109 -
1110 - $profile_link = trailingslashit( learn_press_get_page_link( 'profile' ) );
1111 - if ( $profile_link ) {
1112 - if ( get_option( 'permalink_structure' ) ) {
1113 - $url = trailingslashit( $profile_link . join( '/', array_values( $args ) ) );
1114 - } else {
1115 - $url = esc_url_raw( add_query_arg( $args, $profile_link ) );
1116 - }
1117 - } else {
1118 - $url = get_author_posts_url( $user_id );
1119 - }
1120 -
1121 - return apply_filters( 'learn_press_user_profile_link', $url, $user_id, $tab );
1122 -}
1123 -
1124 -/*
1125 -function learn_press_create_user_item( $args = array(), $wp_error = false ) {
1126 - global $wpdb;
1127 -
1128 - $defaults = array(
1129 - 'user_id' => get_current_user_id(),
1130 - 'item_id' => '',
1131 - 'start_time' => time(),
1132 - 'end_time' => '',
1133 - 'graduation' => '',
1134 - 'item_type' => '',
1135 - 'status' => '',
1136 - 'ref_id' => 0,
1137 - 'ref_type' => '',
1138 - 'parent_id' => 0,
1139 - 'create_meta' => array(),
1140 - );
1141 -
1142 - $item_data = wp_parse_args( $args, $defaults );
1143 -
1144 - // Validate item_id and post type
1145 - if ( empty( $item_data['item_id'] ) ) {
1146 - if ( $wp_error ) {
1147 - return new WP_Error( 'invalid_item_id', __( 'Invalid item id.', 'learnpress' ) );
1148 - }
1149 -
1150 - return 0;
1151 - }
1152 -
1153 - $post_type = learn_press_get_post_type( $item_data['item_id'] );
1154 - if ( empty( $item_data['item_type'] ) && $post_type ) {
1155 - $item_data['item_type'] = $post_type;
1156 - }
1157 -
1158 - // Get id and type of ref if they are null
1159 - if ( ! empty( $item_data['parent_id'] ) && ( empty( $item_data['ref_id'] ) || ( empty( $item_data['ref_type'] ) ) ) ) {
1160 - $parent = $wpdb->get_row(
1161 - $wpdb->prepare(
1162 - "SELECT * FROM {$wpdb->learnpress_user_items} WHERE %d",
1163 - $item_data['parent_id']
1164 - )
1165 - );
1166 -
1167 - if ( $parent ) {
1168 - if ( empty( $item_data['ref_id'] ) ) {
1169 - $item_data['ref_id'] = $parent->item_id;
1170 - }
1171 -
1172 - if ( empty( $item_data['ref_type'] ) ) {
1173 - $item_data['ref_type'] = $parent->item_type;
1174 - }
1175 - }
1176 - }
1177 -
1178 - // Filter
1179 - $item_data = apply_filters( 'learn-press/create-user-item-data', $item_data );
1180 - if ( ! $item_data ) {
1181 - if ( $wp_error ) {
1182 - return new WP_Error( 'invalid_item_data', __( 'Invalid item data.', 'learnpress' ) );
1183 - }
1184 -
1185 - return 0;
1186 - }
1187 -
1188 - do_action( 'learn-press/before-create-user-item', $item_data );
1189 -
1190 - $create_meta = ! empty( $item_data['create_meta'] ) ? $item_data['create_meta'] : false;
1191 -
1192 - if ( $create_meta ) {
1193 - unset( $item_data['create_meta'] );
1194 - }
1195 -
1196 - $user_item = new LP_User_Item( $item_data );
1197 - $result = $user_item->update();
1198 - if ( ! $result || is_wp_error( $result ) ) {
1199 - if ( $wp_error && is_wp_error( $result ) ) {
1200 - return $result;
1201 - }
1202 -
1203 - return 0;
1204 - }
1205 -
1206 - do_action( 'learn-press/created-user-item', $user_item, $item_data );
1207 -
1208 - $create_meta = apply_filters( 'learn-press/create-user-item-meta', $create_meta, $item_data );
1209 - if ( ! $create_meta ) {
1210 - return $user_item;
1211 - }
1212 -
1213 - do_action( 'learn-press/before-create-user-item-meta', $create_meta );
1214 -
1215 - foreach ( $create_meta as $key => $value ) {
1216 - learn_press_update_user_item_meta( $user_item->get_user_item_id(), $key, $value );
1217 - }
1218 -
1219 - do_action( 'learn-press/created-user-item-meta', $user_item, $create_meta );
1220 -
1221 - return $user_item;
1222 -}*/
1223 -
1224 -/*
1225 -function learn_press_isset_user_item_for_quiz( $quiz_id, $course_id ) {
1226 - global $wpdb;
1227 -
1228 - $query = $wpdb->prepare( "SELECT user_item_id FROM $wpdb->learnpress_user_items WHERE ref_id=%d AND item_id=%d", $course_id, $quiz_id );
1229 - $col = $wpdb->get_col( $query );
1230 -
1231 - if ( ! empty( $col ) ) {
1232 - return $col;
1233 - } else {
1234 - return false;
1235 - }
1236 -}*/
1237 -
1238 -/**
1239 - * Prepares list of questions for rest api.
1240 - *
1241 - * @param int[] $question_ids
1242 - * @param array $args
1243 - *
1244 - * @return array
1245 - * @since 3.3.0
1246 - */
1247 -function learn_press_rest_prepare_user_questions( array $question_ids = array(), array $args = array() ): array {
1248 - if ( is_numeric( $args ) ) {
1249 -
1250 - } else {
1251 - $args = wp_parse_args(
1252 - $args,
1253 - array(
1254 - 'instant_hint' => true,
1255 - 'instant_check' => true,
1256 - 'quiz_status' => '',
1257 - 'checked_questions' => array(),
1258 - 'hinted_questions' => array(),
1259 - 'answered' => array(),
1260 - 'show_correct_review' => true,
1261 - )
1262 - );
1263 - }
1264 -
1265 - $checkedQuestions = $args['checked_questions'];
1266 - $hintedQuestions = $args['hinted_questions'];
1267 - $instantHint = $args['instant_hint'];
1268 - $instantCheck = $args['instant_check'];
1269 - $quizStatus = $args['quiz_status'];
1270 - $answered = $args['answered'];
1271 - $status = $args['status'] ?? '';
1272 - $questions = array();
1273 -
1274 - if ( $question_ids ) {
1275 - foreach ( $question_ids as $id ) {
1276 - $question = learn_press_get_question( $id );
1277 - $hasHint = false;
1278 - $hasExplanation = false;
1279 - $canCheck = false;
1280 - $hinted = false;
1281 - $checked = false;
1282 - $theHint = $question->get_hint();
1283 - $theExplanation = '';
1284 -
1285 - if ( $instantCheck || $status == 'completed' ) {
1286 - $theExplanation = $question->get_explanation();
1287 - $checked = in_array( $id, $checkedQuestions );
1288 - $hasExplanation = (bool) $theExplanation;
1289 - }
1290 -
1291 - $mark = $question->get_mark() ? $question->get_mark() : 1;
1292 -
1293 - $questionData = array(
1294 - 'object' => $question,
1295 - 'id' => absint( $id ),
1296 - 'title' => $question->get_title(),
1297 - 'type' => $question->get_type(),
1298 - 'point' => $mark,
1299 - );
1300 -
1301 - $content = $question->get_content();
1302 - if ( $content ) {
1303 - $questionData['content'] = $content;
1304 - }
1305 -
1306 - if ( $theHint ) {
1307 - $questionData['hint'] = $theHint;
1308 - }
1309 -
1310 - if ( $status == 'completed' || ( $checked && $theExplanation ) ) {
1311 - $questionData['explanation'] = $theExplanation;
1312 - }
1313 -
1314 - if ( $hasExplanation ) {
1315 - $questionData['has_explanation'] = $hasExplanation;
1316 -
1317 - if ( $checked ) {
1318 - $questionData['explanation'] = $theExplanation;
1319 - }
1320 - }
1321 -
1322 - $with_true_or_false = ( $checked || ( $quizStatus == 'completed' && $args['show_correct_review'] ) );
1323 -
1324 - // if ( $question->is_support( 'answer-options' ) ) {
1325 - $questionData['options'] = learn_press_get_question_options_for_js(
1326 - $question,
1327 - array(
1328 - 'include_is_true' => $with_true_or_false,
1329 - 'answer' => $answered[ $id ]['answered'] ?? '',
1330 - )
1331 - );
1332 - // }
1333 -
1334 - $questions[] = $questionData;
1335 - }
1336 -
1337 - /**
1338 - * Remove answered
1339 - */
1340 - if ( $quizStatus !== 'completed' ) {
1341 - if ( $checkedQuestions && $quizStatus ) {
1342 -
1343 - $omitIds = array_diff( $question_ids, $checkedQuestions );
1344 -
1345 - if ( $omitIds ) {
1346 - foreach ( $omitIds as $omitId ) {
1347 - if ( ! empty( $answered[ $omitId ] ) ) {
1348 - unset( $answered[ $omitId ] );
1349 - }
1350 - }
1351 - }
1352 - }
1353 - }
1354 - }
1355 -
1356 - return apply_filters( 'learn-press/list-questions-data', $questions );
1357 -}
1358 -
1359 -/**
1360 - * Update extra profile data upon update user.
1361 - *
1362 - * @param int $user_id
1363 - *
1364 - * @since 4.0.0
1365 - */
1366 -function learn_press_update_extra_user_profile_fields( $user_id ) {
1367 - if ( ! current_user_can( 'edit_user', $user_id ) ) {
1368 - return;
1369 - }
1370 -
1371 - if ( array_key_exists( 'lp_user_slug', $_POST ) ) {
1372 - $userModel = UserModel::find( $user_id, true );
1373 - if ( ! $userModel ) {
1374 - return;
1375 - }
1376 -
1377 - $slug_result = $userModel->update_user_nicename( (string) $_POST['lp_user_slug'] );
1378 - if ( is_wp_error( $slug_result ) ) {
1379 - wp_safe_redirect(
1380 - add_query_arg(
1381 - 'lp-message',
1382 - urlencode( $slug_result->get_error_message() ),
1383 - wp_get_referer()
1384 - )
1385 - );
1386 - die();
1387 - }
1388 - }
1389 -
1390 - if ( isset( $_POST['_lp_extra_info'] ) ) {
1391 - $extra_info = LP_Request::get_param( '_lp_extra_info', array(), '', 'post' );
1392 - update_user_meta( $user_id, '_lp_extra_info', $extra_info );
1393 - }
1394 -}
1395 -
1396 -add_action( 'personal_options_update', 'learn_press_update_extra_user_profile_fields' );
1397 -add_action( 'edit_user_profile_update', 'learn_press_update_extra_user_profile_fields' );
1398 -
1399 -/**
1400 - * Get extra profile info data
1401 - *
1402 - * @param int $user_id
1403 - *
1404 - * @return array
1405 - * @since 4.0.1
1406 - */
1407 -function learn_press_get_user_extra_profile_info( $user_id = 0 ) {
1408 - if ( ! $user_id ) {
1409 - $user_id = get_current_user_id();
1410 - }
1411 -
1412 - $extra_profile_info = get_the_author_meta( '_lp_extra_info', $user_id );
1413 - $social_fields = learn_press_social_profiles();
1414 -
1415 - $user_socials = array();
1416 - foreach ( $social_fields as $key => $label ) {
1417 - $key = sanitize_key( $key );
1418 - $user_socials[ $key ] = '';
1419 - if ( is_array( $extra_profile_info ) && isset( $extra_profile_info[ $key ] ) ) {
1420 - $user_socials[ $key ] = esc_url_raw( $extra_profile_info[ $key ] );
1421 - }
1422 - }
1423 -
1424 - return apply_filters( 'learn-press/user-extra-profile-info', $user_socials, $user_id );
1425 -}
1426 -
1427 -/**
1428 - * @return array
1429 - * @since 3.x.x
1430 - * @version 4.0.2
1431 - */
1432 -function learn_press_social_profiles() {
1433 - return apply_filters(
1434 - 'learn-press/social-profiles',
1435 - array(
1436 - 'facebook' => learn_press_social_profile_name( 'facebook' ),
1437 - 'twitter' => learn_press_social_profile_name( 'twitter' ),
1438 - 'youtube' => learn_press_social_profile_name( 'youtube' ),
1439 - 'linkedin' => learn_press_social_profile_name( 'linkedin' ),
1440 - )
1441 - );
1442 -}
1443 -
1444 -function learn_press_social_profile_name( $key ) {
1445 - $name = '';
1446 - switch ( $key ) {
1447 - case 'facebook':
1448 - $name = esc_html__( 'Facebook Profile', 'learnpress' );
1449 - break;
1450 - case 'twitter':
1451 - $name = esc_html__( 'X Profile', 'learnpress' );
1452 - break;
1453 - case 'youtube':
1454 - $name = esc_html__( 'Youtube Channel', 'learnpress' );
1455 - break;
1456 - case 'linkedin':
1457 - $name = esc_html__( 'Linkedin Profile', 'learnpress' );
1458 - break;
1459 - default:
1460 - $name = ucfirst( $key );
1461 - }
1462 -
1463 - return apply_filters( 'learn-press/social-profile-name', $name, $key );
1464 -}
1465 -
1466 -function lp_add_default_fields( $fields ) {
1467 - $first_name = LP_Settings::get_option( 'enable_register_first_name', 'no' );
1468 -
1469 - if ( $first_name === 'yes' ) {
1470 - ?>
1471 - <li class="form-field">
1472 - <label for="reg_first_name"><?php esc_html_e( 'First name', 'learnpress' ); ?></label>
1473 - <input id="reg_first_name" name="reg_first_name" type="text"
1474 - placeholder="<?php esc_attr_e( 'First name', 'learnpress' ); ?>"
1475 - value="<?php echo esc_attr( wp_unslash( $_POST['reg_first_name'] ?? '' ) ); ?>">
1476 - </li>
1477 - <?php
1478 - }
1479 -
1480 - $last_name = LP_Settings::instance()->get( 'enable_register_last_name' );
1481 -
1482 - if ( $last_name === 'yes' ) {
1483 - ?>
1484 - <li class="form-field">
1485 - <label for="reg_last_name"><?php esc_html_e( 'Last name', 'learnpress' ); ?></label>
1486 - <input id="reg_last_name" name="reg_last_name" type="text"
1487 - placeholder="<?php esc_attr_e( 'Last name', 'learnpress' ); ?>"
1488 - value="<?php echo esc_attr( wp_unslash( $_POST['reg_last_name'] ?? '' ) ); ?>">
1489 - </li>
1490 - <?php
1491 - }
1492 -
1493 - $display_name = LP_Settings::instance()->get( 'enable_register_display_name' );
1494 -
1495 - if ( $display_name === 'yes' ) {
1496 - ?>
1497 - <li class="form-field">
1498 - <label for="reg_display_name"><?php esc_html_e( 'Display name', 'learnpress' ); ?></label>
1499 - <input id="reg_display_name" name="reg_display_name" type="text"
1500 - placeholder="<?php esc_attr_e( 'Display name', 'learnpress' ); ?>"
1501 - value="<?php echo esc_attr( wp_unslash( $_POST['reg_display_name'] ?? '' ) ); ?>">
1502 - </li>
1503 - <?php
1504 - }
1505 -}
1506 -
1507 -add_filter( 'learn-press/after-form-register-fields', 'lp_add_default_fields' );
1508 -
1509 -function lp_custom_register_fields_display() {
1510 - ?>
1511 - <?php $custom_fields = LP_Profile::get_register_fields_custom(); ?>
1512 -
1513 - <?php if ( $custom_fields ) : ?>
1514 - <?php foreach ( $custom_fields as $custom_field ) : ?>
1515 - <?php
1516 - $cf_class = '';
1517 - if ( $custom_field['required'] == 'yes' ) {
1518 - $cf_class = ' required';
1519 - ?>
1520 - <style>
1521 - .required label {
1522 - font-weight: bold;
1523 - }
1524 -
1525 - .required label:after {
1526 - content: ' *';
1527 - display: inline;
1528 - }
1529 - </style>
1530 - <?php
1531 - }
1532 -
1533 - if ( isset( $custom_field['id'] ) ) {
1534 - ?>
1535 - <?php $value = $custom_field['id']; ?>
1536 -
1537 - <li class="form-field<?php echo esc_attr( $cf_class ); ?>">
1538 - <?php
1539 - switch ( $custom_field['type'] ) {
1540 - case 'text':
1541 - case 'number':
1542 - case 'email':
1543 - case 'url':
1544 - case 'tel':
1545 - ?>
1546 - <label for="description"><?php echo esc_html( $custom_field['name'] ); ?></label>
1547 - <input name="_lp_custom_register_form[<?php echo esc_attr( $value ); ?>]"
1548 - type="<?php echo esc_attr( $custom_field['type'] ); ?>" class="regular-text"
1549 - value=""/>
1550 - <?php
1551 - break;
1552 - case 'textarea':
1553 - ?>
1554 - <label for="description"><?php echo esc_html( $custom_field['name'] ); ?></label>
1555 - <textarea name="_lp_custom_register_form[<?php echo esc_attr( $value ); ?>]"></textarea>
1556 - <?php
1557 - break;
1558 - case 'checkbox':
1559 - ?>
1560 - <label>
1561 - <input name="_lp_custom_register_form[<?php echo esc_attr( $value ); ?>]"
1562 - type="<?php echo esc_attr( $custom_field['type'] ); ?>" value="1">
1563 - <?php echo esc_html( $custom_field['name'] ); ?>
1564 - </label>
1565 - <?php
1566 - break;
1567 - }
1568 - ?>
1569 - </li>
1570 - <?php } ?>
1571 - <?php endforeach; ?>
1572 - <?php endif; ?>
1573 - <?php
1574 -}
1575 -
1576 -add_action( 'learn-press/after-form-register-fields', 'lp_custom_register_fields_display' );
1577 -
1578 -/**
1579 - * Custom register fields
1580 - *
1581 - * @param [type] $user_id
1582 - *
1583 - * @return void
1584 - */
1585 -function lp_user_custom_register_fields( $user_id, $fields = array() ) {
1586 - if ( ! empty( $fields ) ) {
1587 - update_user_meta( $user_id, '_lp_custom_register', LP_Helper::sanitize_params_submitted( $fields ) );
1588 - } elseif ( isset( $_POST['_lp_custom_register'] ) ) {
1589 - update_user_meta( $user_id, '_lp_custom_register', LP_Helper::sanitize_params_submitted( $_POST['_lp_custom_register'] ) );
1590 - }
1591 -}
1592 -
1593 -add_action( 'personal_options_update', 'lp_user_custom_register_fields' );
1594 -add_action( 'edit_user_profile_update', 'lp_user_custom_register_fields' );
1595 -
1596 -function lp_get_user_custom_register_fields( $user_id = 0 ) {
1597 - if ( ! $user_id ) {
1598 - $user_id = get_current_user_id();
1599 - }
1600 -
1601 - $register_fields = get_the_author_meta( '_lp_custom_register', $user_id );
1602 - $defaults = lp_get_user_custom_fields();
1603 -
1604 - $extra_profile_info = wp_parse_args( $register_fields, $defaults );
1605 -
1606 - return apply_filters( 'lp/user-custom-register-fields', $register_fields, $user_id );
1607 -}
1608 -
1609 -function lp_get_user_custom_fields() {
1610 - $custom_fields = LP_Settings::get_option( 'register_profile_fields', array() );
1611 -
1612 - $output = array();
1613 -
1614 - if ( $custom_fields ) {
1615 - foreach ( $custom_fields as $field ) {
1616 - $output[ $field['id'] ] = '';
1617 - }
1618 - }
1619 -
1620 - return $output;
1621 -}
1622 -
1623 -/**
1624 - * Check extra user data is a social profile.
1625 - *
1626 - * @param $key
1627 - *
1628 - * @return bool
1629 - * @since 4.0.0
1630 - * @deprecated 4.3.2
1631 - */
1632 -function learn_press_is_social_profile( $key ) {
1633 - _deprecated_function( __FUNCTION__, '4.3.2' );
1634 -
1635 - return true;
1636 -
1637 - $is_socials = learn_press_social_profiles();
1638 -
1639 - return in_array( $key, $is_socials );
1640 -}
1641 -
1642 -/**
1643 - * Get extra profile fields will be registered in backend profile.
1644 - *
1645 - * @return array
1646 - * @since 4.0.0
1647 - * @deprecated 4.3.2
1648 - */
1649 -function learn_press_get_user_extra_profile_fields() {
1650 - _deprecated_function( __FUNCTION__, '4.3.2' );
1651 - return array();
1652 -
1653 - $socials = learn_press_social_profiles();
1654 -
1655 - return $socials;
1656 -
1657 - $fields = array();
1658 -
1659 - foreach ( $socials as $social ) {
1660 - $fields[ $social ] = learn_press_social_profile_name( $social );
1661 - }
1662 -
1663 - return apply_filters( 'learn-press/user-extra-profile-fields', $fields );
1664 -}
1665 -
1666 -/**
1667 - * Show courses user enrolled on backend
1668 - *
1669 - * @param $user
1670 - *
1671 - * @return void
1672 - */
1673 -function learn_press_user_profile_data( $user ) {
1674 - if ( ! is_admin() ) {
1675 - return;
1676 - }
1677 -
1678 - learn_press_admin_view( 'backend-user-profile', array( 'user' => $user ) );
1679 - learn_press_admin_view( 'user/courses.php', array( 'user_id' => $user->ID ) );
1680 -}
1681 -
1682 -add_action( 'edit_user_profile', 'learn_press_user_profile_data', 1000 );
1683 -add_action( 'show_user_profile', 'learn_press_user_profile_data', 1000 );
1684 -
1685 -/*
1686 -function learnpress_get_count_by_user( $user_id = '', $post_type = 'lp_course' ) {
1687 - if ( empty( $user_id ) ) {
1688 - return false;
1689 - }
1690 -
1691 - $args = array(
1692 - 'author' => $user_id,
1693 - 'posts_per_page' => - 1,
1694 - 'post_type' => $post_type,
1695 - 'post_status' => 'any',
1696 - );
1697 -
1698 - $posts = get_posts( $args );
1699 -
1700 - $output = array(
1701 - 'all' => count( $posts ),
1702 - 'publish' => array(),
1703 - 'pending' => array(),
1704 - );
1705 -
1706 - $pending = $public = array();
1707 -
1708 - if ( ! empty( $posts ) ) {
1709 - foreach ( $posts as $post ) {
1710 - switch ( $post->post_status ) {
1711 - case 'pending':
1712 - $pending[] = $post;
1713 - break;
1714 - case 'publish':
1715 - $public[] = $post;
1716 - break;
1717 - default:
1718 - break;
1719 - }
1720 - }
1721 - }
1722 -
1723 - return array(
1724 - 'all' => count( $posts ),
1725 - 'publish' => count( $public ),
1726 - 'pending' => count( $pending ),
1727 - );
1728 -}*/
1 +<?php
2 +
3 +use LearnPress\Models\UserItems\UserItemModel;
4 +use LearnPress\Models\UserModel;
5 +use LearnPress\Services\UserService;
6 +
7 +/**
8 + * Common functions to process actions about user
9 + *
10 + * @author ThimPress
11 + * @package LearnPress/Functions/User
12 + * @version 1.0
13 + */
14 +function learn_press_get_user_profile_tabs() {
15 + return LP_Profile::instance()->get_tabs();
16 +}
17 +
18 +/**
19 + * Ensure new users receive a public slug.
20 + *
21 + * @param int $user_id
22 + *
23 + * @return void
24 + */
25 +function learn_press_maybe_generate_user_pretty_slug_on_register( int $user_id ) {
26 + $userModel = UserModel::find( $user_id, true );
27 + if ( ! $userModel ) {
28 + return;
29 + }
30 +
31 + $userModel->generate_pretty_slug();
32 +}
33 +
34 +//add_action( 'user_register', 'learn_press_maybe_generate_user_pretty_slug_on_register' );
35 +
36 +/**
37 + * Delete user data by user ID
38 + *
39 + * @param int $user_id
40 + * @param int $course_id
41 + */
42 +function learn_press_delete_user_data( $user_id, $course_id = 0 ) {
43 + global $wpdb;
44 + // TODO: Should be deleted user's order and order data???
45 +
46 + $query_args = array( $user_id );
47 +
48 + if ( $course_id ) {
49 + $query_args[] = $course_id;
50 + }
51 +
52 + $query = $wpdb->prepare(
53 + "
54 + SELECT user_item_id
55 + FROM {$wpdb->prefix}learnpress_user_items
56 + WHERE user_id = %d
57 + " . ( $course_id ? ' AND item_id = %d' : '' ) . '
58 + ',
59 + $query_args
60 + );
61 +
62 + // delete all courses user has enrolled
63 + $query = $wpdb->prepare(
64 + "
65 + DELETE FROM {$wpdb->prefix}learnpress_user_items
66 + WHERE user_id = %d
67 + " . ( $course_id ? ' AND item_id = %d' : '' ) . '
68 + ',
69 + $query_args
70 + );
71 +
72 + @$wpdb->query( $query );
73 +}
74 +
75 +/**
76 + * Get current user ID
77 + *
78 + * @return int|string LP_User is int, LP_User_Guest is string
79 + */
80 +function learn_press_get_current_user_id() {
81 + $user = learn_press_get_current_user();
82 +
83 + if ( ! $user ) {
84 + return 0;
85 + }
86 +
87 + return $user->get_id();
88 +}
89 +
90 +/**
91 + * Get the user by $user_id passed. If $user_id is NULL, get current user.
92 + * If current user is not logged in, return a GUEST user
93 + *
94 + * @param bool $create_temp - Optional. Create temp user if user is not logged in.
95 + *
96 + * @return LP_User|LP_User_Guest
97 + * @editor tungnx
98 + * @modify 4.1.4
99 + * @version 1.0.1
100 + */
101 +function learn_press_get_current_user( $create_temp = true ) {
102 + $user_id = get_current_user_id();
103 +
104 + if ( $user_id ) {
105 + return learn_press_get_user( $user_id );
106 + }
107 +
108 + // Return LP_User_Guest
109 + return learn_press_get_user( 0 );
110 +}
111 +
112 +if ( ! function_exists( 'learn_press_get_user' ) ) {
113 + /**
114 + * Get user by ID. Return false if the user does not exist.
115 + * If user_id = 0, return a guest user.
116 + *
117 + * @param int $user_id
118 + * @param bool $current
119 + *
120 + * @return LP_User|LP_User_Guest|false
121 + * @since 3.0.0
122 + * @version 4.0.1
123 + */
124 + function learn_press_get_user( $user_id = 0, $current = false, $force_new = false ) {
125 + $userClass = $user_id && get_user_by( 'ID', $user_id ) ? 'LP_User' : ( $user_id == 0 ? 'LP_User_Guest' : false );
126 + if ( false === $userClass ) {
127 + return false;
128 + }
129 +
130 + return new $userClass( $user_id );
131 + }
132 +}
133 +
134 +/**
135 + * Add roles and add capabilities for roles
136 + */
137 +function learn_press_add_user_roles() {
138 + $item_types = [
139 + LP_COURSE_CPT,
140 + LP_LESSON_CPT,
141 + LP_ORDER_CPT,
142 + ];
143 +
144 + foreach ( $item_types as $item_type ) {
145 + UserService::instance()->add_capabilities_for_roles( $item_type );
146 + }
147 +}
148 +
149 +/**
150 + * Get queried user in profile link
151 + *
152 + * @return false|WP_User
153 + * @since 3.0.0
154 + * @deprecated 4.2.9.1
155 + */
156 +function learn_press_get_profile_user() {
157 + return LP_Profile::instance()->get_user_current();
158 +
159 + return LP_Profile::get_queried_user();
160 +}
161 +
162 +
163 +/**
164 + * Add instructor registration button to register page and admin bar
165 + */
166 +function learn_press_user_become_teacher_registration_form() {
167 + if ( LP_Settings::instance()->get( 'instructor_registration' ) != 'yes' ) {
168 + return;
169 + }
170 + ?>
171 + <p>
172 + <label for="become_teacher">
173 + <input type="checkbox" name="become_teacher" id="become_teacher">
174 + <?php esc_html_e( 'Want to become an instructor?', 'learnpress' ); ?>
175 + </label>
176 + </p>
177 + <?php
178 +}
179 +
180 +add_action( 'register_form', 'learn_press_user_become_teacher_registration_form' );
181 +
182 +/**
183 + * Update data into table learnpress_user_items.
184 + *
185 + * @param array $fields - Fields and values to be updated.
186 + * Format: array(
187 + * field_name_1 => value 1,
188 + * field_name_2 => value 2,
189 + * ....
190 + * field_name_n => value n
191 + * )
192 + * @param mixed $where - Optional. Fields with values for conditional update with the same format of $fields.
193 + * @param bool $update_cache - Optional. Should be update to cache or not (since 3.0.0).
194 + * @param bool $update_extra_fields_as_meta - Optional. Update extra fields as item meta (since 3.1.0).
195 + *
196 + * @return mixed
197 + */
198 +function learn_press_update_user_item_field( array $fields = array(), $where = false, $update_cache = true, $update_extra_fields_as_meta = false ) {
199 + global $wpdb;
200 +
201 + // Table fields format.
202 + $table_fields = array(
203 + 'user_item_id' => '%d',
204 + 'user_id' => '%d',
205 + 'item_id' => '%d',
206 + 'ref_id' => '%d',
207 + 'start_time' => '%s',
208 + 'end_time' => '%s',
209 + 'access_level' => '%d',
210 + 'graduation' => '%s',
211 + 'item_type' => '%s',
212 + 'status' => '%s',
213 + 'ref_type' => '%s',
214 + 'parent_id' => '%d',
215 + );
216 +
217 + /**
218 + * Validate item status
219 + */
220 + if ( ! empty( $fields['item_id'] ) && ! empty( $fields['status'] ) ) {
221 + $item_type = learn_press_get_post_type( $fields['item_id'] );
222 +
223 + if ( LP_COURSE_CPT === $item_type ) {
224 + if ( 'completed' === $fields['status'] ) {
225 + $fields['status'] = 'finished';
226 + }
227 + } elseif ( 'finished' === $fields['status'] ) {
228 + $fields['status'] = 'completed';
229 + }
230 + }
231 +
232 + $data = array();
233 + $data_format = array();
234 + foreach ( $fields as $field => $value ) {
235 + if ( ! empty( $table_fields[ $field ] ) ) {
236 + $data[ $field ] = $value;
237 +
238 + // Do not format the date-time field if it's value is NULL
239 + if ( in_array( $field, array( 'start_time', 'end_time' ) ) && empty( $value ) ) {
240 + $data[ $field ] = null;
241 + $data_format[] = '';
242 + } else {
243 + if ( $value instanceof LP_Datetime ) {
244 + $data[ $field ] = $value->toSql();
245 + }
246 + $data_format[] = $table_fields[ $field ];
247 + }
248 + }
249 + }
250 +
251 + if ( ! empty( $fields['user_item_id'] ) ) {
252 + $where = wp_parse_args(
253 + $where,
254 + array( 'user_item_id' => $fields['user_item_id'] )
255 + );
256 + }
257 +
258 + // Set where and where format
259 + $where_format = array();
260 + if ( is_array( $where ) && ! empty( $where ) ) {
261 + if ( empty( $where['user_id'] ) ) {
262 + $where['user_id'] = ! empty( $fields['user_id'] ) ? $fields['user_id'] : learn_press_get_current_user_id();
263 + }
264 +
265 + foreach ( $where as $field => $value ) {
266 + if ( isset( $table_fields[ $field ] ) ) {
267 + $where_format[] = $table_fields[ $field ];
268 + }
269 + }
270 + }
271 +
272 + if ( ! $data ) {
273 + return false;
274 + }
275 +
276 + $inserted = false;
277 + $updated = false;
278 +
279 + // Update to database.
280 + if ( $where ) {
281 + $updated = $wpdb->update(
282 + $wpdb->learnpress_user_items,
283 + $data,
284 + $where,
285 + $data_format,
286 + $where_format
287 + );
288 + } else {
289 + // Insert to database.
290 + if ( $wpdb->insert(
291 + $wpdb->learnpress_user_items,
292 + $data,
293 + $data_format
294 + ) ) {
295 + $inserted = $wpdb->insert_id;
296 + }
297 + }
298 +
299 + if ( $updated && ! empty( $where['user_item_id'] ) ) {
300 + $inserted = $where['user_item_id'];
301 + }
302 +
303 + /**
304 + * @var object|bool $updated_item
305 + */
306 + $updated_item = false;
307 +
308 + // Get the item we just have updated or inserted.
309 + if ( $inserted ) {
310 + $updated_item = learn_press_get_user_item( $inserted );
311 + } elseif ( $updated ) {
312 + $updated_item = learn_press_get_user_item( $where );
313 + }
314 +
315 + // Clear caches.
316 + if ( $updated_item ) {
317 + // Clear cache total students enrolled.
318 + if ( isset( $updated_item->item_type )
319 + && LP_COURSE_CPT === $updated_item->item_type
320 + && isset( $updated_item->item_id ) ) {
321 + $lp_course_cache = new LP_Course_Cache( true );
322 + $lp_course_cache->clean_total_students_enrolled( $updated_item->item_id );
323 + $lp_course_cache->clean_total_students_enrolled_or_purchased( $updated_item->item_id );
324 + // Clear cache count students many courses.
325 + $lp_courses_cache = new LP_Courses_Cache( true );
326 + $lp_courses_cache->clear_cache_on_group( LP_Courses_Cache::KEYS_COUNT_STUDENT_COURSES );
327 + }
328 + // Clear cache user item.
329 + $lp_user_items_cache = new LP_User_Items_Cache();
330 + $lp_user_items_cache->clean_user_item(
331 + array(
332 + $updated_item->user_id,
333 + $updated_item->item_id,
334 + $updated_item->item_type,
335 + )
336 + );
337 + // Clear cache userItemModel
338 + $userItemModel = UserItemModel::find_user_item(
339 + $updated_item->user_id,
340 + $updated_item->item_id,
341 + $updated_item->item_type,
342 + $updated_item->ref_id,
343 + $updated_item->ref_type,
344 + true
345 + );
346 + $userItemModel->clean_caches();
347 + }
348 +
349 + do_action( 'learn-press/updated-user-item-field', $updated_item );
350 +
351 + /**
352 + * If there is some fields does not contain in the main table
353 + * then consider update them as metadata.
354 + *
355 + * @comment by tungnx - 4.1.7.3
356 + */
357 + /*
358 + if ( $updated_item && $update_extra_fields_as_meta ) {
359 + $extra_fields = array_diff_key( $fields, $table_fields );
360 + if ( $extra_fields ) {
361 + foreach ( $extra_fields as $meta_key => $meta_value ) {
362 + if ( $meta_value == 'user_item_id' ) {
363 + continue;
364 + }
365 +
366 + if ( $meta_value === false ) {
367 + learn_press_delete_user_item_meta( $updated_item->user_item_id, $meta_key );
368 + } else {
369 +
370 + if ( empty( $meta_value ) ) {
371 + $meta_value = '';
372 + }
373 + learn_press_update_user_item_meta( $updated_item->user_item_id, $meta_key, $meta_value );
374 + }
375 + }
376 + }
377 + }*/
378 +
379 + // do_action( 'learn-press/updated-user-item-meta', $updated_item );
380 +
381 + return $updated_item;
382 +}
383 +
384 +/**
385 + * Get user item row(s) from user items table by multiple WHERE conditional
386 + *
387 + * @param array|int $where
388 + * @param bool $single
389 + *
390 + * @return array
391 + */
392 +function learn_press_get_user_item( $where, $single = true ) {
393 + global $wpdb;
394 +
395 + // Table fields
396 + $table_fields = array(
397 + 'user_item_id' => '%d',
398 + 'user_id' => '%d',
399 + 'item_id' => '%d',
400 + 'ref_id' => '%d',
401 + 'start_time' => '%s',
402 + 'end_time' => '%s',
403 + 'item_type' => '%s',
404 + 'status' => '%s',
405 + 'ref_type' => '%s',
406 + 'parent_id' => '%d',
407 + );
408 +
409 + // If $where is a number consider we are searching the record with unique user_item_id
410 + if ( is_numeric( $where ) ) {
411 + $where = array( 'user_item_id' => $where );
412 + }
413 +
414 + $where_str = array();
415 + foreach ( $where as $field => $value ) {
416 + if ( ! empty( $table_fields[ $field ] ) ) {
417 + $where_str[] = "{$field} = " . $table_fields[ $field ];
418 + }
419 + }
420 + $item = false;
421 +
422 + if ( $where_str ) {
423 + $query = $wpdb->prepare(
424 + "
425 + SELECT *
426 + FROM {$wpdb->prefix}learnpress_user_items
427 + WHERE " . join( ' AND ', $where_str ) . '
428 + ORDER BY user_item_id DESC
429 + ',
430 + $where
431 + );
432 + if ( $single || ! empty( $where['user_item_id'] ) ) {
433 + $item = $wpdb->get_row( $query );
434 + } else {
435 + $item = $wpdb->get_results( $query );
436 + }
437 + }
438 +
439 + return $item;
440 +}
441 +
442 +/**
443 + * Get user item meta from user_itemmeta table
444 + *
445 + * @param int $user_item_id .
446 + * @param string $meta_key .
447 + * @param bool $single .
448 + *
449 + * @return mixed
450 + */
451 +function learn_press_get_user_item_meta( $user_item_id = 0, $meta_key = '', $single = true ) {
452 + $meta = false;
453 + if ( metadata_exists( 'learnpress_user_item', $user_item_id, $meta_key ) ) {
454 + $meta = get_metadata( 'learnpress_user_item', $user_item_id, $meta_key, $single );
455 + }
456 +
457 + return $meta;
458 +}
459 +
460 +/**
461 + * Add user item meta into table user_itemmeta
462 + *
463 + * @param int $user_item_id
464 + * @param string $meta_key
465 + * @param mixed $meta_value
466 + * @param string $prev_value
467 + *
468 + * @return false|int
469 + */
470 +function learn_press_add_user_item_meta( $user_item_id, $meta_key, $meta_value, $prev_value = '' ) {
471 + return add_metadata( 'learnpress_user_item', $user_item_id, $meta_key, $meta_value, $prev_value );
472 +}
473 +
474 +/**
475 + * Update user item meta to table user_itemmeta
476 + *
477 + * @param int $user_item_id
478 + * @param string $meta_key
479 + * @param mixed $meta_value
480 + * @param string $prev_value
481 + *
482 + * @return bool|int
483 + */
484 +function learn_press_update_user_item_meta( $user_item_id, $meta_key, $meta_value, $prev_value = '' ) {
485 + return update_metadata( 'learnpress_user_item', $user_item_id, $meta_key, $meta_value, $prev_value );
486 +}
487 +
488 +
489 +/**
490 + * Update user item meta to table user_itemmeta
491 + *
492 + * @param int $object_id
493 + * @param string $meta_key
494 + * @param mixed $meta_value
495 + * @param bool $delete_all
496 + *
497 + * @return bool|int
498 + */
499 +function learn_press_delete_user_item_meta( $object_id, $meta_key, $meta_value = '', $delete_all = false ) {
500 + return delete_metadata( 'learnpress_user_item', $object_id, $meta_key, $meta_value, $delete_all );
501 +}
502 +
503 +if ( ! function_exists( 'learn_press_pre_get_avatar_callback' ) ) {
504 + /**
505 + * Filter the avatar
506 + *
507 + * @param string $avatar
508 + * @param string $id_or_email
509 + * @param array $args
510 + *
511 + * @return string
512 + * @since 1.0.0
513 + * @version 1.0.2
514 + */
515 + function learn_press_pre_get_avatar_callback( $avatar, $id_or_email = '', $args = array() ) {
516 + try {
517 + if ( ( isset( $args['gravatar'] ) && $args['gravatar'] ) || ( $args['default'] && $args['force_default'] ) ) {
518 + return $avatar;
519 + }
520 +
521 + $user_id = 0;
522 +
523 + /**
524 + * Get the ID of user from $id_or_email
525 + */
526 + if ( ! is_numeric( $id_or_email ) && is_string( $id_or_email ) ) {
527 + $user = get_user_by( 'email', $id_or_email );
528 + if ( $user ) {
529 + $user_id = $user->ID;
530 + }
531 + } elseif ( is_numeric( $id_or_email ) ) {
532 + $user_id = $id_or_email;
533 + } elseif ( is_object( $id_or_email ) && isset( $id_or_email->user_id ) && $id_or_email->user_id ) {
534 + $user_id = $id_or_email->user_id;
535 + } elseif ( $id_or_email instanceof WP_Comment ) {
536 + $user = get_user_by( 'email', $id_or_email->comment_author_email );
537 + if ( $user ) {
538 + $user_id = $user->ID;
539 + }
540 + }
541 +
542 + if ( ! $user_id ) {
543 + return $avatar;
544 + }
545 +
546 + $user = UserModel::find( $user_id, true );
547 + if ( ! $user ) {
548 + return $avatar;
549 + }
550 +
551 + $class = array( 'avatar', 'avatar-' . (int) $args['size'], 'photo' );
552 + if ( $args['class'] ) {
553 + if ( is_array( $args['class'] ) ) {
554 + $class = array_merge( $class, $args['class'] );
555 + } else {
556 + $class[] = $args['class'];
557 + }
558 + }
559 +
560 + $avatar_url = $user->get_avatar_url();
561 + $html_img = sprintf(
562 + "<img src='%s' srcset='%s' class='%s' height='%d' width='%d' decoding='async'/>",
563 + esc_url( $avatar_url ),
564 + esc_url( $avatar_url ) . ' 2x',
565 + esc_attr( implode( ' ', $class ) ),
566 + (int) $args['height'],
567 + (int) $args['width']
568 + );
569 +
570 + return $html_img;
571 + } catch ( Throwable $e ) {
572 + error_log( $e->getMessage() );
573 +
574 + return $avatar;
575 + }
576 + }
577 +}
578 +add_filter( 'pre_get_avatar', 'learn_press_pre_get_avatar_callback', 999, 3 );
579 +
580 +
581 +function learn_press_user_profile_picture_upload_dir( $width_user = true ) {
582 + $upload_dir = wp_upload_dir();
583 + $subdir = apply_filters( 'learn_press_user_profile_folder', 'learn-press-profile', $width_user );
584 + if ( $width_user ) {
585 + $subdir .= '/' . get_current_user_id();
586 + }
587 + $subdir = '/' . $subdir;
588 +
589 + if ( ! empty( $upload_dir['subdir'] ) ) {
590 + $u_subdir = str_replace( '\\', '/', $upload_dir['subdir'] );
591 + $u_path = str_replace( '\\', '/', $upload_dir['path'] );
592 +
593 + $upload_dir['path'] = str_replace( $u_subdir, $subdir, $u_path );
594 + $upload_dir['url'] = str_replace( $u_subdir, $subdir, $upload_dir['url'] );
595 + } else {
596 + $upload_dir['path'] = $upload_dir['path'] . $subdir;
597 + $upload_dir['url'] = $upload_dir['url'] . $subdir;
598 + }
599 +
600 + $upload_dir['subdir'] = $subdir;
601 +
602 + // Point path/url to main site if we are in multisite
603 + if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
604 + foreach ( array( 'path', 'url', 'basedir', 'baseurl' ) as $v ) {
605 + $upload_dir[ $v ] = str_replace( '/sites/' . get_current_blog_id(), '', $upload_dir[ $v ] );
606 + }
607 + }
608 +
609 + return $upload_dir;
610 +}
611 +
612 +/*
613 +add_action( 'learn_press_before_purchase_course_handler', '_learn_press_before_purchase_course_handler', 10, 2 );
614 +function _learn_press_before_purchase_course_handler( $course_id, $cart ) {
615 + // Redirect to login page if user is not logged in
616 + if ( ! is_user_logged_in() ) {
617 + $return_url = esc_url_raw( add_query_arg( $_POST, get_the_permalink( $course_id ) ) );
618 + $return_url = apply_filters( 'learn_press_purchase_course_login_redirect_return_url', $return_url );
619 + $redirect = apply_filters(
620 + 'learn_press_purchase_course_login_redirect',
621 + learn_press_get_login_url( $return_url )
622 + );
623 + if ( $redirect !== false ) {
624 + learn_press_add_message( __( 'Please log in to enroll in this course', 'learnpress' ) );
625 +
626 + if ( learn_press_is_ajax() ) {
627 + learn_press_send_json(
628 + array(
629 + 'redirect' => $redirect,
630 + 'result' => 'success',
631 + )
632 + );
633 + } else {
634 + wp_redirect( $redirect );
635 + exit();
636 + }
637 + }
638 + } else {
639 + $user = learn_press_get_current_user();
640 + $redirect = false;
641 + if ( $user->has_finished_course( $course_id ) ) {
642 + learn_press_add_message( __( 'You have already finished the course', 'learnpress' ) );
643 + $redirect = true;
644 + } elseif ( $user->has_purchased_course( $course_id ) ) {
645 + learn_press_add_message( __( 'You have already enrolled in this course', 'learnpress' ) );
646 + $redirect = true;
647 + }
648 + if ( $redirect ) {
649 + wp_redirect( get_the_permalink( $course_id ) );
650 + exit();
651 + }
652 + }
653 +}*/
654 +
655 +/*
656 +function learn_press_user_is( $role, $user_id = 0 ) {
657 + if ( ! $user_id ) {
658 + $user = learn_press_get_current_user();
659 + } else {
660 + $user = learn_press_get_user( $user_id );
661 + }
662 + if ( $role == 'admin' ) {
663 + return $user->is_admin();
664 + }
665 + if ( $role == 'instructor' ) {
666 + return $user->is_instructor();
667 + }
668 +
669 + return $role;
670 +}*/
671 +
672 +/*
673 +function learn_press_profile_tab_edit_content( $current, $tab, $user ) {
674 + learn_press_get_template(
675 + 'profile/tabs/edit.php',
676 + array(
677 + 'user' => $user,
678 + 'current' => $current,
679 + 'tab' => $tab,
680 + )
681 + );
682 +}*/
683 +
684 +/*
685 +function learn_press_update_user_option( $name, $value, $id = 0 ) {
686 + if ( ! $id ) {
687 + $id = get_current_user_id();
688 + }
689 + $key = 'learnpress_user_options';
690 + $options = get_user_option( $key, $id );
691 + $options[ $name ] = $value;
692 + update_user_option( $id, $key, $options, true );
693 +}*/
694 +
695 +/*
696 +function learn_press_delete_user_option( $name, $id = 0 ) {
697 + if ( ! $id ) {
698 + $id = get_current_user_id();
699 + }
700 + $key = 'learnpress_user_options';
701 + $options = get_user_option( $key, $id );
702 + if ( is_array( $options ) && array_key_exists( $name, $options ) ) {
703 + unset( $options[ $name ] );
704 + update_user_option( $id, $key, $options, true );
705 +
706 + return true;
707 + }
708 +
709 + return false;
710 +}*/
711 +
712 +/*
713 +function learn_press_get_user_option( $name, $id = 0 ) {
714 + if ( ! $id ) {
715 + $id = get_current_user_id();
716 + }
717 + $key = 'learnpress_user_options';
718 + $options = get_user_option( $key, $id );
719 + if ( is_array( $options ) && array_key_exists( $name, $options ) ) {
720 + return $options[ $name ];
721 + }
722 +
723 + return false;
724 +}*/
725 +
726 +/**
727 + * Update user basic information.
728 + *
729 + * @param bool $wp_error - Optional. Return WP_Error object in case updating failed.
730 + *
731 + * @return bool|mixed|WP_Error
732 + */
733 +function learn_press_update_user_profile_basic_information( $wp_error = false ) {
734 + $user_id = get_current_user_id();
735 +
736 + if ( ! $user_id ) {
737 + return new WP_Error( 2, 'The user is invalid' );
738 + }
739 +
740 + $update_data = array(
741 + 'ID' => $user_id,
742 + 'first_name' => LP_Request::get_param( 'first_name' ),
743 + 'last_name' => LP_Request::get_param( 'last_name' ),
744 + 'description' => LP_Request::get_param( 'description', '', 'html' ),
745 + 'display_name' => LP_Request::get_param( 'account_display_name' ),
746 + 'user_email' => LP_Request::get_param( 'account_email' ),
747 + );
748 +
749 + $update_data = apply_filters( 'learn-press/update-profile-basic-information-data', $update_data );
750 + $update_meta = LP_Helper::sanitize_params_submitted( $_POST['_lp_custom_register'] ?? '' );
751 +
752 + $return = LP_Forms_Handler::update_user_data( $update_data, $update_meta );
753 +
754 + // Update for social.
755 + $socials = LP_Request::get_param( 'user_profile_social' );
756 + $extra_data = get_user_meta( $user_id, '_lp_extra_info', true );
757 +
758 + if ( ! empty( $extra_data ) ) {
759 + $socials = array_merge( $extra_data, $socials );
760 + }
761 +
762 + update_user_meta( $user_id, '_lp_extra_info', $socials );
763 +
764 + if ( is_wp_error( $return ) ) {
765 + return $wp_error ? $return : false;
766 + }
767 +
768 + return $return;
769 +}
770 +
771 +/**
772 + * Update new password.
773 + *
774 + * @version 1.0.1
775 + */
776 +function learn_press_update_user_profile_change_password() {
777 + try {
778 + $user = wp_get_current_user();
779 + if ( ! $user ) {
780 + throw new Exception( __( 'The user is invalid', 'learnpress' ) );
781 + }
782 +
783 + $old_pass = LP_Request::get_param( 'pass0', '', 'text', 'post' );
784 + if ( empty( $old_pass ) ) {
785 + throw new Exception( __( 'Enter the old password!', 'learnpress' ) );
786 + }
787 +
788 + $check_old_pass = wp_check_password( $old_pass, $user->data->user_pass, $user->ID );
789 + if ( ! $check_old_pass ) {
790 + throw new Exception( __( 'The old password is incorrect!', 'learnpress' ) );
791 + }
792 +
793 + $new_pass = LP_Request::get_param( 'pass1', '', 'text', 'post' );
794 + $new_pass_confirm = LP_Request::get_param( 'pass2', '', 'text', 'post' );
795 + if ( empty( $new_pass ) || empty( $new_pass_confirm )
796 + || $new_pass != $new_pass_confirm ) {
797 + throw new Exception( __( 'Incorrect confirmation password!', 'learnpress' ) );
798 + }
799 +
800 + // Update user password
801 + // wp_set_password( $new_pass, $user->ID );
802 + $update_data = array(
803 + 'user_pass' => $new_pass,
804 + 'ID' => $user->ID,
805 + );
806 +
807 + $rs = wp_update_user( $update_data );
808 + if ( is_wp_error( $rs ) ) {
809 + throw new Exception( $rs->get_error_message() );
810 + }
811 + } catch ( Exception $ex ) {
812 + return new WP_Error( 'error_lp_profile_update_pass', $ex->getMessage() );
813 + }
814 +
815 + return true;
816 +}
817 +
818 +function learn_press_get_avatar_thumb_size() {
819 + $option = LP_Settings::get_option(
820 + 'avatar_dimensions',
821 + array(
822 + 'width' => 250,
823 + 'height' => 250,
824 + )
825 + );
826 +
827 + if ( ! isset( $option['width'] ) || ! isset( $option['height'] ) ) {
828 + $option = array(
829 + 'width' => 250,
830 + 'height' => 250,
831 + );
832 + }
833 +
834 + // For option get_avatar_url
835 + $option['size'] = $option['width'];
836 +
837 + return $option;
838 +}
839 +
840 +function learn_press_get_course_thumbnail_dimensions() {
841 + $option = LP_Settings::get_option(
842 + 'course_thumbnail_dimensions',
843 + array(
844 + 'width' => 500,
845 + 'height' => 300,
846 + )
847 + );
848 +
849 + if ( ! isset( $option['width'] ) || ! isset( $option['height'] ) ) {
850 + $option = array(
851 + 'width' => 500,
852 + 'height' => 300,
853 + );
854 + }
855 +
856 + return $option;
857 +}
858 +
859 +/*
860 +function learn_press_get_user_avatar( $user_id = 0, $size = '' ) {
861 + $user = learn_press_get_user( $user_id );
862 +
863 + return $user->get_profile_picture( '', $size );
864 +}*/
865 +
866 +/**
867 + * Get profile instance for an user to view.
868 + *
869 + * @param int $for_user
870 + *
871 + * @return LP_Profile|WP_Error
872 + */
873 +function learn_press_get_profile( $for_user = 0 ) {
874 + return LP_Profile::instance( $for_user );
875 +}
876 +
877 +/*
878 +function learn_press_remove_user_items( $user_id, $item_id, $course_id, $include_course = false ) {
879 + global $wpdb;
880 +
881 + settype( $item_id, 'array' );
882 +
883 + $format = array_fill( 0, sizeof( $item_id ), '%d' );
884 + $where = '';
885 +
886 + $args = array( $user_id );
887 + $args = array_merge( $args, $item_id );
888 +
889 + if ( $course_id ) {
890 + $args[] = $course_id;
891 + $where = 'AND ref_id = %d';
892 + }
893 +
894 + if ( $include_course ) {
895 + $where .= ' OR ( item_id = %d AND item_type = %s )';
896 + $args[] = $course_id;
897 + $args[] = LP_COURSE_CPT;
898 + }
899 +
900 + $query = $wpdb->prepare(
901 + "
902 + DELETE
903 + FROM {$wpdb->learnpress_user_items}
904 + WHERE user_id = %d
905 + AND ( item_id IN(" . join( ',', $format ) . ")
906 + $where )
907 + ",
908 + $args
909 + );
910 +}*/
911 +
912 +/**
913 + * Get user profile link
914 + *
915 + * @param int $user_id
916 + * @param null $tab
917 + *
918 + * @return mixed|string
919 + */
920 +function learn_press_user_profile_link( $user_id = 0, $tab = '' ) {
921 + if ( ! $user_id ) {
922 + $user_id = get_current_user_id();
923 + }
924 +
925 + $user = learn_press_get_user( $user_id );
926 +
927 + if ( ! $user ) {
928 + return '';
929 + }
930 +
931 + global $wp_query;
932 + $wp_user = get_userdata( $user_id );
933 + if ( ! $wp_user instanceof WP_User ) {
934 + return '';
935 + }
936 +
937 + $user_model = new UserModel( $wp_user->data );
938 + $args = array(
939 + 'user' => $user_model->get_slug_link(),
940 + );
941 +
942 + if ( $tab ) {
943 + $args['tab'] = $tab;
944 + }
945 +
946 + /**
947 + * If no tab is selected in profile and is current user
948 + * then no need the username in profile link.
949 + */
950 + if ( ( $user_id == get_current_user_id() ) && ! isset( $args['tab'] ) ) {
951 + //unset( $args['user'] );
952 + }
953 +
954 + $profile_link = trailingslashit( learn_press_get_page_link( 'profile' ) );
955 + if ( $profile_link ) {
956 + if ( get_option( 'permalink_structure' ) ) {
957 + $url = trailingslashit( $profile_link . join( '/', array_values( $args ) ) );
958 + } else {
959 + $url = esc_url_raw( add_query_arg( $args, $profile_link ) );
960 + }
961 + } else {
962 + $url = get_author_posts_url( $user_id );
963 + }
964 +
965 + return apply_filters( 'learn_press_user_profile_link', $url, $user_id, $tab );
966 +}
967 +
968 +/*
969 +function learn_press_create_user_item( $args = array(), $wp_error = false ) {
970 + global $wpdb;
971 +
972 + $defaults = array(
973 + 'user_id' => get_current_user_id(),
974 + 'item_id' => '',
975 + 'start_time' => time(),
976 + 'end_time' => '',
977 + 'graduation' => '',
978 + 'item_type' => '',
979 + 'status' => '',
980 + 'ref_id' => 0,
981 + 'ref_type' => '',
982 + 'parent_id' => 0,
983 + 'create_meta' => array(),
984 + );
985 +
986 + $item_data = wp_parse_args( $args, $defaults );
987 +
988 + // Validate item_id and post type
989 + if ( empty( $item_data['item_id'] ) ) {
990 + if ( $wp_error ) {
991 + return new WP_Error( 'invalid_item_id', __( 'Invalid item id.', 'learnpress' ) );
992 + }
993 +
994 + return 0;
995 + }
996 +
997 + $post_type = learn_press_get_post_type( $item_data['item_id'] );
998 + if ( empty( $item_data['item_type'] ) && $post_type ) {
999 + $item_data['item_type'] = $post_type;
1000 + }
1001 +
1002 + // Get id and type of ref if they are null
1003 + if ( ! empty( $item_data['parent_id'] ) && ( empty( $item_data['ref_id'] ) || ( empty( $item_data['ref_type'] ) ) ) ) {
1004 + $parent = $wpdb->get_row(
1005 + $wpdb->prepare(
1006 + "SELECT * FROM {$wpdb->learnpress_user_items} WHERE %d",
1007 + $item_data['parent_id']
1008 + )
1009 + );
1010 +
1011 + if ( $parent ) {
1012 + if ( empty( $item_data['ref_id'] ) ) {
1013 + $item_data['ref_id'] = $parent->item_id;
1014 + }
1015 +
1016 + if ( empty( $item_data['ref_type'] ) ) {
1017 + $item_data['ref_type'] = $parent->item_type;
1018 + }
1019 + }
1020 + }
1021 +
1022 + // Filter
1023 + $item_data = apply_filters( 'learn-press/create-user-item-data', $item_data );
1024 + if ( ! $item_data ) {
1025 + if ( $wp_error ) {
1026 + return new WP_Error( 'invalid_item_data', __( 'Invalid item data.', 'learnpress' ) );
1027 + }
1028 +
1029 + return 0;
1030 + }
1031 +
1032 + do_action( 'learn-press/before-create-user-item', $item_data );
1033 +
1034 + $create_meta = ! empty( $item_data['create_meta'] ) ? $item_data['create_meta'] : false;
1035 +
1036 + if ( $create_meta ) {
1037 + unset( $item_data['create_meta'] );
1038 + }
1039 +
1040 + $user_item = new LP_User_Item( $item_data );
1041 + $result = $user_item->update();
1042 + if ( ! $result || is_wp_error( $result ) ) {
1043 + if ( $wp_error && is_wp_error( $result ) ) {
1044 + return $result;
1045 + }
1046 +
1047 + return 0;
1048 + }
1049 +
1050 + do_action( 'learn-press/created-user-item', $user_item, $item_data );
1051 +
1052 + $create_meta = apply_filters( 'learn-press/create-user-item-meta', $create_meta, $item_data );
1053 + if ( ! $create_meta ) {
1054 + return $user_item;
1055 + }
1056 +
1057 + do_action( 'learn-press/before-create-user-item-meta', $create_meta );
1058 +
1059 + foreach ( $create_meta as $key => $value ) {
1060 + learn_press_update_user_item_meta( $user_item->get_user_item_id(), $key, $value );
1061 + }
1062 +
1063 + do_action( 'learn-press/created-user-item-meta', $user_item, $create_meta );
1064 +
1065 + return $user_item;
1066 +}*/
1067 +
1068 +/*
1069 +function learn_press_isset_user_item_for_quiz( $quiz_id, $course_id ) {
1070 + global $wpdb;
1071 +
1072 + $query = $wpdb->prepare( "SELECT user_item_id FROM $wpdb->learnpress_user_items WHERE ref_id=%d AND item_id=%d", $course_id, $quiz_id );
1073 + $col = $wpdb->get_col( $query );
1074 +
1075 + if ( ! empty( $col ) ) {
1076 + return $col;
1077 + } else {
1078 + return false;
1079 + }
1080 +}*/
1081 +
1082 +/**
1083 + * Prepares list of questions for rest api.
1084 + *
1085 + * @param int[] $question_ids
1086 + * @param array $args
1087 + *
1088 + * @return array
1089 + * @since 3.3.0
1090 + */
1091 +function learn_press_rest_prepare_user_questions( array $question_ids = array(), array $args = array() ): array {
1092 + if ( is_numeric( $args ) ) {
1093 +
1094 + } else {
1095 + $args = wp_parse_args(
1096 + $args,
1097 + array(
1098 + 'instant_hint' => true,
1099 + 'instant_check' => true,
1100 + 'quiz_status' => '',
1101 + 'checked_questions' => array(),
1102 + 'hinted_questions' => array(),
1103 + 'answered' => array(),
1104 + 'show_correct_review' => true,
1105 + )
1106 + );
1107 + }
1108 +
1109 + $checkedQuestions = $args['checked_questions'];
1110 + $hintedQuestions = $args['hinted_questions'];
1111 + $instantHint = $args['instant_hint'];
1112 + $instantCheck = $args['instant_check'];
1113 + $quizStatus = $args['quiz_status'];
1114 + $answered = $args['answered'];
1115 + $status = $args['status'] ?? '';
1116 + $questions = array();
1117 +
1118 + if ( $question_ids ) {
1119 + foreach ( $question_ids as $id ) {
1120 + $question = learn_press_get_question( $id );
1121 + $hasHint = false;
1122 + $hasExplanation = false;
1123 + $canCheck = false;
1124 + $hinted = false;
1125 + $checked = false;
1126 + $theHint = $question->get_hint();
1127 + $theExplanation = '';
1128 +
1129 + if ( $instantCheck || $status == 'completed' ) {
1130 + $theExplanation = $question->get_explanation();
1131 + $checked = in_array( $id, $checkedQuestions );
1132 + $hasExplanation = (bool) $theExplanation;
1133 + }
1134 +
1135 + $mark = $question->get_mark() ? $question->get_mark() : 1;
1136 +
1137 + $questionData = array(
1138 + 'object' => $question,
1139 + 'id' => absint( $id ),
1140 + 'title' => $question->get_title(),
1141 + 'type' => $question->get_type(),
1142 + 'point' => $mark,
1143 + );
1144 +
1145 + $content = $question->get_content();
1146 + if ( $content ) {
1147 + $questionData['content'] = $content;
1148 + }
1149 +
1150 + if ( $theHint ) {
1151 + $questionData['hint'] = $theHint;
1152 + }
1153 +
1154 + if ( $status == 'completed' || ( $checked && $theExplanation ) ) {
1155 + $questionData['explanation'] = $theExplanation;
1156 + }
1157 +
1158 + if ( $hasExplanation ) {
1159 + $questionData['has_explanation'] = $hasExplanation;
1160 +
1161 + if ( $checked ) {
1162 + $questionData['explanation'] = $theExplanation;
1163 + }
1164 + }
1165 +
1166 + $with_true_or_false = ( $checked || ( $quizStatus == 'completed' && $args['show_correct_review'] ) );
1167 +
1168 + // if ( $question->is_support( 'answer-options' ) ) {
1169 + $questionData['options'] = learn_press_get_question_options_for_js(
1170 + $question,
1171 + array(
1172 + 'include_is_true' => $with_true_or_false,
1173 + 'answer' => $answered[ $id ]['answered'] ?? '',
1174 + )
1175 + );
1176 + // }
1177 +
1178 + $questions[] = $questionData;
1179 + }
1180 +
1181 + /**
1182 + * Remove answered
1183 + */
1184 + if ( $quizStatus !== 'completed' ) {
1185 + if ( $checkedQuestions && $quizStatus ) {
1186 +
1187 + $omitIds = array_diff( $question_ids, $checkedQuestions );
1188 +
1189 + if ( $omitIds ) {
1190 + foreach ( $omitIds as $omitId ) {
1191 + if ( ! empty( $answered[ $omitId ] ) ) {
1192 + unset( $answered[ $omitId ] );
1193 + }
1194 + }
1195 + }
1196 + }
1197 + }
1198 + }
1199 +
1200 + return apply_filters( 'learn-press/list-questions-data', $questions );
1201 +}
1202 +
1203 +/**
1204 + * Update extra profile data upon update user.
1205 + *
1206 + * @param int $user_id
1207 + *
1208 + * @since 4.0.0
1209 + */
1210 +function learn_press_update_extra_user_profile_fields( $user_id ) {
1211 + if ( ! current_user_can( 'edit_user', $user_id ) ) {
1212 + return;
1213 + }
1214 +
1215 + if ( array_key_exists( 'lp_user_slug', $_POST ) ) {
1216 + $userModel = UserModel::find( $user_id, true );
1217 + if ( ! $userModel ) {
1218 + return;
1219 + }
1220 +
1221 + $slug_result = $userModel->update_user_nicename( (string) $_POST['lp_user_slug'] );
1222 + if ( is_wp_error( $slug_result ) ) {
1223 + wp_safe_redirect(
1224 + add_query_arg(
1225 + 'lp-message',
1226 + urlencode( $slug_result->get_error_message() ),
1227 + wp_get_referer()
1228 + )
1229 + );
1230 + die();
1231 + }
1232 + }
1233 +
1234 + if ( isset( $_POST['_lp_extra_info'] ) ) {
1235 + $extra_info = LP_Request::get_param( '_lp_extra_info', array(), '', 'post' );
1236 + update_user_meta( $user_id, '_lp_extra_info', $extra_info );
1237 + }
1238 +}
1239 +
1240 +add_action( 'personal_options_update', 'learn_press_update_extra_user_profile_fields' );
1241 +add_action( 'edit_user_profile_update', 'learn_press_update_extra_user_profile_fields' );
1242 +
1243 +/**
1244 + * Get extra profile info data
1245 + *
1246 + * @param int $user_id
1247 + *
1248 + * @return array
1249 + * @since 4.0.1
1250 + */
1251 +function learn_press_get_user_extra_profile_info( $user_id = 0 ) {
1252 + if ( ! $user_id ) {
1253 + $user_id = get_current_user_id();
1254 + }
1255 +
1256 + $extra_profile_info = get_the_author_meta( '_lp_extra_info', $user_id );
1257 + $social_fields = learn_press_social_profiles();
1258 +
1259 + $user_socials = array();
1260 + foreach ( $social_fields as $key => $label ) {
1261 + $key = sanitize_key( $key );
1262 + $user_socials[ $key ] = '';
1263 + if ( is_array( $extra_profile_info ) && isset( $extra_profile_info[ $key ] ) ) {
1264 + $user_socials[ $key ] = esc_url_raw( $extra_profile_info[ $key ] );
1265 + }
1266 + }
1267 +
1268 + return apply_filters( 'learn-press/user-extra-profile-info', $user_socials, $user_id );
1269 +}
1270 +
1271 +/**
1272 + * @return array
1273 + * @since 3.x.x
1274 + * @version 4.0.2
1275 + */
1276 +function learn_press_social_profiles() {
1277 + return apply_filters(
1278 + 'learn-press/social-profiles',
1279 + array(
1280 + 'facebook' => learn_press_social_profile_name( 'facebook' ),
1281 + 'twitter' => learn_press_social_profile_name( 'twitter' ),
1282 + 'youtube' => learn_press_social_profile_name( 'youtube' ),
1283 + 'linkedin' => learn_press_social_profile_name( 'linkedin' ),
1284 + )
1285 + );
1286 +}
1287 +
1288 +function learn_press_social_profile_name( $key ) {
1289 + $name = '';
1290 + switch ( $key ) {
1291 + case 'facebook':
1292 + $name = esc_html__( 'Facebook Profile', 'learnpress' );
1293 + break;
1294 + case 'twitter':
1295 + $name = esc_html__( 'X Profile', 'learnpress' );
1296 + break;
1297 + case 'youtube':
1298 + $name = esc_html__( 'Youtube Channel', 'learnpress' );
1299 + break;
1300 + case 'linkedin':
1301 + $name = esc_html__( 'Linkedin Profile', 'learnpress' );
1302 + break;
1303 + default:
1304 + $name = ucfirst( $key );
1305 + }
1306 +
1307 + return apply_filters( 'learn-press/social-profile-name', $name, $key );
1308 +}
1309 +
1310 +function lp_add_default_fields( $fields ) {
1311 + $first_name = LP_Settings::get_option( 'enable_register_first_name', 'no' );
1312 +
1313 + if ( $first_name === 'yes' ) {
1314 + ?>
1315 + <li class="form-field">
1316 + <label for="reg_first_name"><?php esc_html_e( 'First name', 'learnpress' ); ?></label>
1317 + <input id="reg_first_name" name="reg_first_name" type="text"
1318 + placeholder="<?php esc_attr_e( 'First name', 'learnpress' ); ?>"
1319 + value="<?php echo esc_attr( wp_unslash( $_POST['reg_first_name'] ?? '' ) ); ?>">
1320 + </li>
1321 + <?php
1322 + }
1323 +
1324 + $last_name = LP_Settings::instance()->get( 'enable_register_last_name' );
1325 +
1326 + if ( $last_name === 'yes' ) {
1327 + ?>
1328 + <li class="form-field">
1329 + <label for="reg_last_name"><?php esc_html_e( 'Last name', 'learnpress' ); ?></label>
1330 + <input id="reg_last_name" name="reg_last_name" type="text"
1331 + placeholder="<?php esc_attr_e( 'Last name', 'learnpress' ); ?>"
1332 + value="<?php echo esc_attr( wp_unslash( $_POST['reg_last_name'] ?? '' ) ); ?>">
1333 + </li>
1334 + <?php
1335 + }
1336 +
1337 + $display_name = LP_Settings::instance()->get( 'enable_register_display_name' );
1338 +
1339 + if ( $display_name === 'yes' ) {
1340 + ?>
1341 + <li class="form-field">
1342 + <label for="reg_display_name"><?php esc_html_e( 'Display name', 'learnpress' ); ?></label>
1343 + <input id="reg_display_name" name="reg_display_name" type="text"
1344 + placeholder="<?php esc_attr_e( 'Display name', 'learnpress' ); ?>"
1345 + value="<?php echo esc_attr( wp_unslash( $_POST['reg_display_name'] ?? '' ) ); ?>">
1346 + </li>
1347 + <?php
1348 + }
1349 +}
1350 +
1351 +add_filter( 'learn-press/after-form-register-fields', 'lp_add_default_fields' );
1352 +
1353 +function lp_custom_register_fields_display() {
1354 + ?>
1355 + <?php $custom_fields = LP_Profile::get_register_fields_custom(); ?>
1356 +
1357 + <?php if ( $custom_fields ) : ?>
1358 + <?php foreach ( $custom_fields as $custom_field ) : ?>
1359 + <?php
1360 + $cf_class = '';
1361 + if ( $custom_field['required'] == 'yes' ) {
1362 + $cf_class = ' required';
1363 + ?>
1364 + <style>
1365 + .required label {
1366 + font-weight: bold;
1367 + }
1368 +
1369 + .required label:after {
1370 + content: ' *';
1371 + display: inline;
1372 + }
1373 + </style>
1374 + <?php
1375 + }
1376 +
1377 + if ( isset( $custom_field['id'] ) ) {
1378 + ?>
1379 + <?php $value = $custom_field['id']; ?>
1380 +
1381 + <li class="form-field<?php echo esc_attr( $cf_class ); ?>">
1382 + <?php
1383 + switch ( $custom_field['type'] ) {
1384 + case 'text':
1385 + case 'number':
1386 + case 'email':
1387 + case 'url':
1388 + case 'tel':
1389 + ?>
1390 + <label for="description"><?php echo esc_html( $custom_field['name'] ); ?></label>
1391 + <input name="_lp_custom_register_form[<?php echo esc_attr( $value ); ?>]"
1392 + type="<?php echo esc_attr( $custom_field['type'] ); ?>" class="regular-text"
1393 + value=""/>
1394 + <?php
1395 + break;
1396 + case 'textarea':
1397 + ?>
1398 + <label for="description"><?php echo esc_html( $custom_field['name'] ); ?></label>
1399 + <textarea name="_lp_custom_register_form[<?php echo esc_attr( $value ); ?>]"></textarea>
1400 + <?php
1401 + break;
1402 + case 'checkbox':
1403 + ?>
1404 + <label>
1405 + <input name="_lp_custom_register_form[<?php echo esc_attr( $value ); ?>]"
1406 + type="<?php echo esc_attr( $custom_field['type'] ); ?>" value="1">
1407 + <?php echo esc_html( $custom_field['name'] ); ?>
1408 + </label>
1409 + <?php
1410 + break;
1411 + }
1412 + ?>
1413 + </li>
1414 + <?php } ?>
1415 + <?php endforeach; ?>
1416 + <?php endif; ?>
1417 + <?php
1418 +}
1419 +
1420 +add_action( 'learn-press/after-form-register-fields', 'lp_custom_register_fields_display' );
1421 +
1422 +/**
1423 + * Custom register fields
1424 + *
1425 + * @param [type] $user_id
1426 + *
1427 + * @return void
1428 + */
1429 +function lp_user_custom_register_fields( $user_id, $fields = array() ) {
1430 + if ( ! empty( $fields ) ) {
1431 + update_user_meta( $user_id, '_lp_custom_register', LP_Helper::sanitize_params_submitted( $fields ) );
1432 + } elseif ( isset( $_POST['_lp_custom_register'] ) ) {
1433 + update_user_meta( $user_id, '_lp_custom_register', LP_Helper::sanitize_params_submitted( $_POST['_lp_custom_register'] ) );
1434 + }
1435 +}
1436 +
1437 +add_action( 'personal_options_update', 'lp_user_custom_register_fields' );
1438 +add_action( 'edit_user_profile_update', 'lp_user_custom_register_fields' );
1439 +
1440 +function lp_get_user_custom_register_fields( $user_id = 0 ) {
1441 + if ( ! $user_id ) {
1442 + $user_id = get_current_user_id();
1443 + }
1444 +
1445 + $register_fields = get_the_author_meta( '_lp_custom_register', $user_id );
1446 + $defaults = lp_get_user_custom_fields();
1447 +
1448 + $extra_profile_info = wp_parse_args( $register_fields, $defaults );
1449 +
1450 + return apply_filters( 'lp/user-custom-register-fields', $register_fields, $user_id );
1451 +}
1452 +
1453 +function lp_get_user_custom_fields() {
1454 + $custom_fields = LP_Settings::get_option( 'register_profile_fields', array() );
1455 +
1456 + $output = array();
1457 +
1458 + if ( $custom_fields ) {
1459 + foreach ( $custom_fields as $field ) {
1460 + $output[ $field['id'] ] = '';
1461 + }
1462 + }
1463 +
1464 + return $output;
1465 +}
1466 +
1467 +/**
1468 + * Check extra user data is a social profile.
1469 + *
1470 + * @param $key
1471 + *
1472 + * @return bool
1473 + * @since 4.0.0
1474 + * @deprecated 4.3.2
1475 + */
1476 +function learn_press_is_social_profile( $key ) {
1477 + _deprecated_function( __FUNCTION__, '4.3.2' );
1478 +
1479 + return true;
1480 +
1481 + $is_socials = learn_press_social_profiles();
1482 +
1483 + return in_array( $key, $is_socials );
1484 +}
1485 +
1486 +/**
1487 + * Get extra profile fields will be registered in backend profile.
1488 + *
1489 + * @return array
1490 + * @since 4.0.0
1491 + * @deprecated 4.3.2
1492 + */
1493 +function learn_press_get_user_extra_profile_fields() {
1494 + _deprecated_function( __FUNCTION__, '4.3.2' );
1495 + return array();
1496 +
1497 + $socials = learn_press_social_profiles();
1498 +
1499 + return $socials;
1500 +
1501 + $fields = array();
1502 +
1503 + foreach ( $socials as $social ) {
1504 + $fields[ $social ] = learn_press_social_profile_name( $social );
1505 + }
1506 +
1507 + return apply_filters( 'learn-press/user-extra-profile-fields', $fields );
1508 +}
1509 +
1510 +/**
1511 + * Show courses user enrolled on backend
1512 + *
1513 + * @param $user
1514 + *
1515 + * @return void
1516 + */
1517 +function learn_press_user_profile_data( $user ) {
1518 + if ( ! is_admin() ) {
1519 + return;
1520 + }
1521 +
1522 + learn_press_admin_view( 'backend-user-profile', array( 'user' => $user ) );
1523 + learn_press_admin_view( 'user/courses.php', array( 'user_id' => $user->ID ) );
1524 +}
1525 +
1526 +add_action( 'edit_user_profile', 'learn_press_user_profile_data', 1000 );
1527 +add_action( 'show_user_profile', 'learn_press_user_profile_data', 1000 );
1528 +
1529 +/*
1530 +function learnpress_get_count_by_user( $user_id = '', $post_type = 'lp_course' ) {
1531 + if ( empty( $user_id ) ) {
1532 + return false;
1533 + }
1534 +
1535 + $args = array(
1536 + 'author' => $user_id,
1537 + 'posts_per_page' => - 1,
1538 + 'post_type' => $post_type,
1539 + 'post_status' => 'any',
1540 + );
1541 +
1542 + $posts = get_posts( $args );
1543 +
1544 + $output = array(
1545 + 'all' => count( $posts ),
1546 + 'publish' => array(),
1547 + 'pending' => array(),
1548 + );
1549 +
1550 + $pending = $public = array();
1551 +
1552 + if ( ! empty( $posts ) ) {
1553 + foreach ( $posts as $post ) {
1554 + switch ( $post->post_status ) {
1555 + case 'pending':
1556 + $pending[] = $post;
1557 + break;
1558 + case 'publish':
1559 + $public[] = $post;
1560 + break;
1561 + default:
1562 + break;
1563 + }
1564 + }
1565 + }
1566 +
1567 + return array(
1568 + 'all' => count( $posts ),
1569 + 'publish' => count( $public ),
1570 + 'pending' => count( $pending ),
1571 + );
1572 +}*/