PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7.2
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7.2
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / inc / jwt / rest-api / version1 / class-lp-rest-users-v1-controller.php

class-lp-rest-users-v1-controller.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.7.2, at inc/jwt/rest-api/version1/class-lp-rest-users-v1-controller.php

1,540 lines 44.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST API for the user.
4 *
5 * @package LearnPress/JWT/RESTAPI
6 * @author Nhamdv <daonham95@gmail.com>
7 */
8 class LP_Jwt_Users_V1_Controller extends LP_REST_Jwt_Controller {
9 protected $namespace = 'learnpress/v1';
10
11 protected $rest_base = 'users';
12
13 protected $hierarchical = true;
14
15 protected $meta;
16
17 public function __construct() {
18 $this->meta = new WP_REST_User_Meta_Fields();
19 }
20
21 public function register_routes() {
22 register_rest_route(
23 $this->namespace,
24 '/' . $this->rest_base,
25 array(
26 array(
27 'methods' => WP_REST_Server::READABLE,
28 'callback' => array( $this, 'get_items' ),
29 'permission_callback' => array( $this, 'get_items_permissions_check' ),
30 'args' => $this->get_collection_params(),
31 ),
32 'schema' => array( $this, 'get_public_item_schema' ),
33 )
34 );
35
36 register_rest_route(
37 $this->namespace,
38 '/' . $this->rest_base . '/(?P<id>[\d]+)',
39 array(
40 'args' => array(
41 'id' => array(
42 'description' => esc_html__( 'Unique identifier for the resource.', 'learnpress' ),
43 'type' => 'integer',
44 ),
45 ),
46 array(
47 'methods' => WP_REST_Server::READABLE,
48 'callback' => array( $this, 'get_item' ),
49 'permission_callback' => array( $this, 'get_item_permissions_check' ),
50 'args' => array(
51 'context' => $this->get_context_param(
52 array(
53 'default' => 'view',
54 )
55 ),
56 ),
57 ),
58 array(
59 'methods' => WP_REST_Server::EDITABLE,
60 'callback' => array( $this, 'update_item' ),
61 'permission_callback' => array( $this, 'update_item_permissions_check' ),
62 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
63 ),
64 'schema' => array( $this, 'get_public_item_schema' ),
65 )
66 );
67
68 register_rest_route(
69 $this->namespace,
70 '/' . $this->rest_base . '/reset-password',
71 array(
72 'methods' => WP_REST_Server::EDITABLE,
73 'callback' => array( $this, 'reset_password' ),
74 'permission_callback' => '__return_true',
75 'args' => array(
76 'user_login' => array(
77 'description' => esc_html__( 'User or Email login.', 'learnpress' ),
78 'type' => 'string',
79 'required' => true,
80 ),
81 ),
82 )
83 );
84
85 register_rest_route(
86 $this->namespace,
87 '/' . $this->rest_base . '/change-password',
88 array(
89 'methods' => WP_REST_Server::EDITABLE,
90 'callback' => array( $this, 'change_password' ),
91 'permission_callback' => array( $this, 'update_item_password_permissions' ),
92 'args' => array(
93 'old_password' => array(
94 'description' => esc_html__( 'Old Password', 'learnpress' ),
95 'type' => 'string',
96 'required' => true,
97 ),
98 'new_password' => array(
99 'description' => esc_html__( 'New Password', 'learnpress' ),
100 'type' => 'string',
101 'required' => true,
102 ),
103 ),
104 )
105 );
106
107 register_rest_route(
108 $this->namespace,
109 '/' . $this->rest_base . '/delete',
110 array(
111 'methods' => WP_REST_Server::EDITABLE,
112 'callback' => array( $this, 'delete_account' ),
113 'permission_callback' => array( $this, 'update_item_password_permissions' ),
114 'args' => array(
115 'id' => array(
116 'description' => esc_html__( 'User ID', 'learnpress' ),
117 'type' => 'integer',
118 'required' => true,
119 ),
120 'password' => array(
121 'description' => esc_html__( 'Password', 'learnpress' ),
122 'type' => 'string',
123 'required' => true,
124 ),
125 ),
126 )
127 );
128 }
129
130 public function get_items_permissions_check( $request ) {
131 if ( ! empty( $request['roles'] ) && ! ( in_array( 'lp_teacher', $request['roles'] ) || in_array( 'subscriber', $request['roles'] ) ) && ! current_user_can( 'list_users' ) ) {
132 return new WP_Error(
133 'rest_user_cannot_view',
134 __( 'Sorry, you are not allowed to filter users by role.' ),
135 array( 'status' => rest_authorization_required_code() )
136 );
137 }
138
139 return true;
140 }
141
142 public function get_item_permissions_check( $request ) {
143 $user = $this->get_user( $request['id'] );
144
145 if ( is_wp_error( $user ) ) {
146 return $user;
147 }
148
149 $types = get_post_types( array( 'show_in_rest' => true ), 'names' );
150
151 if ( get_current_user_id() === $user->ID ) {
152 return true;
153 }
154
155 if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
156 return new WP_Error(
157 'rest_user_cannot_view',
158 __( 'Sorry, you are not allowed to list users.' ),
159 array( 'status' => rest_authorization_required_code() )
160 );
161 } elseif ( ! count_user_posts( $user->ID, $types ) && ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) ) {
162 return new WP_Error(
163 'rest_user_cannot_view',
164 __( 'Sorry, you are not allowed to list users.' ),
165 array( 'status' => rest_authorization_required_code() )
166 );
167 }
168
169 return true;
170 }
171
172 /**
173 * Checks if a given request has access to update a user.
174 *
175 * @since 4.7.0
176 *
177 * @param WP_REST_Request $request Full details about the request.
178 * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
179 */
180 public function update_item_permissions_check( $request ) {
181 $user = $this->get_user( $request['id'] );
182 if ( is_wp_error( $user ) ) {
183 return $user;
184 }
185
186 if ( ! empty( $request['roles'] ) ) {
187 if ( ! current_user_can( 'promote_user', $user->ID ) ) {
188 return new WP_Error(
189 'rest_cannot_edit_roles',
190 __( 'Sorry, you are not allowed to edit roles of this user.' ),
191 array( 'status' => rest_authorization_required_code() )
192 );
193 }
194
195 $request_params = array_keys( $request->get_params() );
196 sort( $request_params );
197 // If only 'id' and 'roles' are specified (we are only trying to
198 // edit roles), then only the 'promote_user' cap is required.
199 if ( array( 'id', 'roles' ) === $request_params ) {
200 return true;
201 }
202 }
203
204 if ( ! current_user_can( 'edit_user', $user->ID ) ) {
205 return new WP_Error(
206 'rest_cannot_edit',
207 __( 'Sorry, you are not allowed to edit this user.' ),
208 array( 'status' => rest_authorization_required_code() )
209 );
210 }
211
212 return true;
213 }
214
215 public function update_item_password_permissions( $request ) {
216 $user = wp_get_current_user();
217
218 if ( ! $user ) {
219 return new WP_Error(
220 'rest_cannot_update',
221 __( 'Sorry, you are not allowed to update this user.' ),
222 array( 'status' => rest_authorization_required_code() )
223 );
224 }
225
226 if ( ! current_user_can( 'edit_user', $user->ID ) ) {
227 return new WP_Error(
228 'rest_cannot_edit',
229 __( 'Sorry, you are not allowed to edit this user.' ),
230 array( 'status' => rest_authorization_required_code() )
231 );
232 }
233
234 return true;
235 }
236
237 /**
238 * Determines if the current user is allowed to make the desired roles change.
239 *
240 * @since 4.7.0
241 *
242 * @param int $user_id User ID.
243 * @param array $roles New user roles.
244 * @return true|WP_Error True if the current user is allowed to make the role change,
245 * otherwise a WP_Error object.
246 */
247 protected function check_role_update( $user_id, $roles ) {
248 global $wp_roles;
249
250 foreach ( $roles as $role ) {
251
252 if ( ! isset( $wp_roles->role_objects[ $role ] ) ) {
253 return new WP_Error(
254 'rest_user_invalid_role',
255 /* translators: %s: Role key. */
256 sprintf( __( 'The role %s does not exist.' ), $role ),
257 array( 'status' => 400 )
258 );
259 }
260
261 $potential_role = $wp_roles->role_objects[ $role ];
262
263 /*
264 * Don't let anyone with 'edit_users' (admins) edit their own role to something without it.
265 * Multisite super admins can freely edit their blog roles -- they possess all caps.
266 */
267 if ( ! ( is_multisite()
268 && current_user_can( 'manage_sites' ) )
269 && get_current_user_id() === $user_id
270 && ! $potential_role->has_cap( 'edit_users' )
271 ) {
272 return new WP_Error(
273 'rest_user_invalid_role',
274 __( 'Sorry, you are not allowed to give users that role.' ),
275 array( 'status' => rest_authorization_required_code() )
276 );
277 }
278
279 // Include user admin functions to get access to get_editable_roles().
280 require_once ABSPATH . 'wp-admin/includes/user.php';
281
282 // The new role must be editable by the logged-in user.
283 $editable_roles = get_editable_roles();
284
285 if ( empty( $editable_roles[ $role ] ) ) {
286 return new WP_Error(
287 'rest_user_invalid_role',
288 __( 'Sorry, you are not allowed to give users that role.' ),
289 array( 'status' => 403 )
290 );
291 }
292 }
293
294 return true;
295 }
296
297 public function reset_password( $request ) {
298 $user_login = $request['user_login'];
299 $reset = LP_Forms_Handler::retrieve_password( $user_login );
300
301 if ( is_wp_error( $reset ) ) {
302 return $reset;
303 } else {
304 return rest_ensure_response(
305 array(
306 'code' => 'success',
307 'message' => esc_html__( 'A link to reset your password has been emailed to you.', 'learnpress' ),
308 )
309 );
310 }
311 }
312
313 public function delete_account( $request ) {
314 $user_id = $request['id'];
315 $password = $request['password'];
316
317 $user = wp_get_current_user();
318
319 if ( ! $user || $user_id !== $user->ID ) {
320 return new WP_Error(
321 'rest_user_invalid_id',
322 __( 'Invalid user ID.', 'learnpress' ),
323 array( 'status' => 400 )
324 );
325 }
326
327 if ( ! wp_check_password( $password, $user->data->user_pass, $user->ID ) ) {
328 return new WP_Error(
329 'rest_user_invalid_password',
330 __( 'Invalid password.', 'learnpress' ),
331 array( 'status' => 400 )
332 );
333 }
334
335 if ( ! function_exists( 'wp_delete_user' ) ) {
336 require_once ABSPATH . 'wp-admin/includes/user.php';
337 }
338
339 $delete = wp_delete_user( $user_id );
340
341 if ( is_wp_error( $delete ) ) {
342 return $delete;
343 } else {
344 return rest_ensure_response(
345 array(
346 'code' => 'success',
347 'message' => esc_html__( 'Your account has been deleted.', 'learnpress' ),
348 )
349 );
350 }
351 }
352
353 public function change_password( $request ) {
354 $old_password = $request['old_password'];
355 $new_password = $request['new_password'];
356
357 $user = wp_get_current_user();
358
359 if ( ! $user || ! $user->ID || ( empty( $old_password ) || empty( $new_password ) ) ) {
360 return new WP_Error(
361 'rest_user_cannot_change_password',
362 __( 'Sorry, you are not allowed to change password.' ),
363 array( 'status' => rest_authorization_required_code() )
364 );
365 }
366
367 if ( ! wp_check_password( $old_password, $user->user_pass, $user->ID ) ) {
368 return new WP_Error(
369 'rest_user_incorrect_password',
370 __( 'Your current password is incorrect.' ),
371 array( 'status' => 403 )
372 );
373 }
374
375 if ( apply_filters( 'learnpress_rest_api_user_change_password', true, $user ) ) {
376 wp_set_password( $new_password, $user->ID );
377 } else {
378 return new WP_Error(
379 'rest_user_cannot_change_password',
380 __( 'Sorry, you are not allowed to change password.' ),
381 array( 'status' => rest_authorization_required_code() )
382 );
383 }
384
385 return rest_ensure_response(
386 array(
387 'code' => 'success',
388 'message' => esc_html__( 'Your password has been updated, Please login again to continue!', 'learnpress' ),
389 )
390 );
391 }
392
393 protected function get_user( $id ) {
394 $error = new WP_Error(
395 'rest_user_invalid_id',
396 __( 'Invalid user ID.' ),
397 array( 'status' => 404 )
398 );
399
400 if ( (int) $id <= 0 ) {
401 return $error;
402 }
403
404 $user = get_userdata( (int) $id );
405 if ( empty( $user ) || ! $user->exists() ) {
406 return $error;
407 }
408
409 if ( is_multisite() && ! is_user_member_of_blog( $user->ID ) ) {
410 return $error;
411 }
412
413 return $user;
414 }
415
416 /**
417 * Updates a single user.
418 *
419 * @param WP_REST_Request $request Full details about the request.
420 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
421 */
422 public function update_item( $request ) {
423 $user = $this->get_user( $request['id'] );
424 if ( is_wp_error( $user ) ) {
425 return $user;
426 }
427
428 $id = $user->ID;
429
430 if ( ! $user ) {
431 return new WP_Error(
432 'rest_user_invalid_id',
433 __( 'Invalid user ID.' ),
434 array( 'status' => 404 )
435 );
436 }
437
438 $owner_id = email_exists( $request['email'] );
439
440 if ( $owner_id && $owner_id !== $id ) {
441 return new WP_Error(
442 'rest_user_invalid_email',
443 __( 'Invalid email address.' ),
444 array( 'status' => 400 )
445 );
446 }
447
448 if ( ! empty( $request['username'] ) && $request['username'] !== $user->user_login ) {
449 return new WP_Error(
450 'rest_user_invalid_argument',
451 __( "Username isn't editable." ),
452 array( 'status' => 400 )
453 );
454 }
455
456 if ( ! empty( $request['slug'] ) && $request['slug'] !== $user->user_nicename && get_user_by( 'slug', $request['slug'] ) ) {
457 return new WP_Error(
458 'rest_user_invalid_slug',
459 __( 'Invalid slug.' ),
460 array( 'status' => 400 )
461 );
462 }
463
464 if ( ! empty( $request['roles'] ) ) {
465 $check_permission = $this->check_role_update( $id, $request['roles'] );
466
467 if ( is_wp_error( $check_permission ) ) {
468 return $check_permission;
469 }
470 }
471
472 $user = $this->prepare_item_for_database( $request );
473
474 // Ensure we're operating on the same user we already checked.
475 $user->ID = $id;
476
477 $user_id = wp_update_user( wp_slash( (array) $user ) );
478
479 if ( is_wp_error( $user_id ) ) {
480 return $user_id;
481 }
482
483 $files = $request->get_file_params();
484
485 if ( ! empty( $files['lp_avatar_file'] ) ) {
486 $file = $files['lp_avatar_file'];
487
488 if ( ! empty( $file['name'] ) ) {
489 list($width, $height) = getimagesize( $file['tmp_name'] );
490
491 $upload_size = learn_press_get_avatar_thumb_size();
492
493 if ( $width != $upload_size['width'] || $height != $upload_size['height'] ) {
494 return new WP_Error(
495 'rest_user_invalid_avatar_dimensions',
496 sprintf( __( 'Invalid avatar dimensions. Please upload a new avatar width size %1$1sx%2$2s' ), $upload_size['width'], $upload_size['height'] ),
497 array( 'status' => 400 )
498 );
499 }
500
501 $data = LP_WP_Filesystem::instance()->file_get_contents( $file['tmp_name'] );
502 $base64 = base64_encode( $data );
503
504 $controller = new LP_REST_Profile_Controller();
505
506 $request->set_param( 'file', $base64 );
507
508 $uploaded_avatar = $controller->upload_avatar( $request );
509 }
510 }
511
512 if ( ! empty( $request['avatar_url'] ) ) {
513 $controller = new LP_REST_Profile_Controller();
514
515 $request->set_param( 'file', $request['avatar_url'] );
516
517 $uploaded_avatar = $controller->upload_avatar( $request );
518 }
519
520 $user = get_user_by( 'id', $user_id );
521
522 do_action( 'lp_rest_insert_user', $user, $request, false );
523
524 if ( ! empty( $request['roles'] ) ) {
525 array_map( array( $user, 'add_role' ), $request['roles'] );
526 }
527
528 $schema = $this->get_item_schema();
529
530 if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) {
531 $meta_update = $this->meta->update_value( $request['meta'], $user_id );
532
533 if ( is_wp_error( $meta_update ) ) {
534 return $meta_update;
535 }
536 }
537
538 $user = get_user_by( 'id', $user_id );
539 $fields_update = $this->update_additional_fields_for_object( $user, $request );
540
541 if ( is_wp_error( $fields_update ) ) {
542 return $fields_update;
543 }
544
545 $request->set_param( 'context', 'edit' );
546
547 do_action( 'lp_rest_after_insert_user', $user, $request, false );
548
549 $response = $this->prepare_item_for_response( $user, $request );
550 $response = rest_ensure_response( $response );
551
552 return $response;
553 }
554
555 /**
556 * Prepares a single user for creation or update.
557 *
558 * @param WP_REST_Request $request Request object.
559 * @return object User object.
560 */
561 protected function prepare_item_for_database( $request ) {
562 $prepared_user = new stdClass();
563
564 $schema = $this->get_item_schema();
565
566 // Required arguments.
567 if ( isset( $request['email'] ) && ! empty( $schema['properties']['email'] ) ) {
568 $prepared_user->user_email = $request['email'];
569 }
570
571 if ( isset( $request['username'] ) && ! empty( $schema['properties']['username'] ) ) {
572 $prepared_user->user_login = $request['username'];
573 }
574
575 if ( isset( $request['password'] ) && ! empty( $schema['properties']['password'] ) ) {
576 $prepared_user->user_pass = $request['password'];
577 }
578
579 // Optional arguments.
580 if ( isset( $request['id'] ) ) {
581 $prepared_user->ID = absint( $request['id'] );
582 }
583
584 if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) {
585 $prepared_user->display_name = $request['name'];
586 }
587
588 if ( isset( $request['first_name'] ) && ! empty( $schema['properties']['first_name'] ) ) {
589 $prepared_user->first_name = $request['first_name'];
590 }
591
592 if ( isset( $request['last_name'] ) && ! empty( $schema['properties']['last_name'] ) ) {
593 $prepared_user->last_name = $request['last_name'];
594 }
595
596 if ( isset( $request['nickname'] ) && ! empty( $schema['properties']['nickname'] ) ) {
597 $prepared_user->nickname = $request['nickname'];
598 }
599
600 if ( isset( $request['slug'] ) && ! empty( $schema['properties']['slug'] ) ) {
601 $prepared_user->user_nicename = $request['slug'];
602 }
603
604 if ( isset( $request['description'] ) && ! empty( $schema['properties']['description'] ) ) {
605 $prepared_user->description = $request['description'];
606 }
607
608 if ( isset( $request['url'] ) && ! empty( $schema['properties']['url'] ) ) {
609 $prepared_user->user_url = $request['url'];
610 }
611
612 if ( isset( $request['locale'] ) && ! empty( $schema['properties']['locale'] ) ) {
613 $prepared_user->locale = $request['locale'];
614 }
615
616 // Setting roles will be handled outside of this function.
617 if ( isset( $request['roles'] ) ) {
618 $prepared_user->role = false;
619 }
620
621 /**
622 * Filters user data before insertion via the REST API.
623 *
624 * @param object $prepared_user User object.
625 * @param WP_REST_Request $request Request object.
626 */
627 return apply_filters( 'lp_rest_pre_insert_user', $prepared_user, $request );
628 }
629
630 public function get_overview_tab_contents( $user ) {
631 $output = array();
632 $statistic = LP_Profile::instance( $user->get_id )->get_statistic_info();
633
634 $output['statistic'] = array_map( 'absint', $statistic );
635
636 $featured_query = new LP_Course_Query(
637 array(
638 'paginate' => false,
639 'featured' => 'yes',
640 'return' => 'ids',
641 'author' => $user->ID,
642 )
643 );
644
645 $output['featured'] = $featured_query->get_courses();
646
647 $latest_query = new LP_Course_Query(
648 array(
649 'paginate' => false,
650 'return' => 'ids',
651 'author' => $user->get_id(),
652 'limit' => '-1',
653 )
654 );
655
656 $output['latest'] = $latest_query->get_courses();
657
658 return $output;
659 }
660
661 public function get_course_tab_contents( $request ) {
662 $output = array(
663 'enrolled' => array(),
664 'created' => array(),
665 );
666
667 $profile = learn_press_get_profile( $request['id'] );
668 $user = learn_press_get_user( $request['id'] );
669 $filters_enrolled = array(
670 'all' => 'all',
671 'finished' => 'finished',
672 'passed' => 'passed',
673 'failed' => 'failed',
674 'in-progress' => 'in-progress',
675 );
676
677 if ( method_exists( $profile, 'query_courses' ) ) {
678 foreach ( $filters_enrolled as $key => $filter ) {
679 $query_enrolled = $profile->query_courses(
680 'purchased',
681 array(
682 'status' => $filter,
683 'limit' => $request['per_page'] ?? '100',
684 'paged' => $request['paged'] ?? 1,
685 )
686 );
687
688 if ( empty( $query_enrolled['items'] ) ) {
689 continue;
690 }
691
692 $enrolled_ids = array();
693 foreach ( $query_enrolled['items'] as $enrolled_item ) {
694 $course_data = $user->get_course_data( $enrolled_item );
695
696 if ( $course_data ) {
697 $post = get_post( $enrolled_item );
698
699 $enrolled_ids[] = array(
700 'id' => $enrolled_item ?? '',
701 'title' => $post->post_title,
702 'graduation' => ! empty( $course_data->get_graduation() ) ? $course_data->get_graduation() : '',
703 'status' => ! empty( $course_data->get_status() ) ? $course_data->get_status() : '',
704 'start_time' => lp_jwt_prepare_date_response( $course_data->get_start_time() ? $course_data->get_start_time()->toSql( false ) : '' ),
705 'end_time' => lp_jwt_prepare_date_response( $course_data->get_end_time() ? $course_data->get_end_time()->toSql( false ) : '' ),
706 'expiration' => lp_jwt_prepare_date_response( $course_data->get_expiration_time() ? $course_data->get_expiration_time()->toSql( false ) : '' ),
707 'results' => $course_data->calculate_course_results(),
708 );
709 }
710 }
711
712 $output['enrolled'][ $key ] = $enrolled_ids;
713 }
714 }
715
716 $filters_created = array(
717 'all' => '',
718 'publish' => 'publish',
719 'pending' => 'pending',
720 );
721
722 if ( method_exists( $profile, 'query_courses' ) ) {
723 foreach ( $filters_created as $created_key => $filter ) {
724 $query_created = $profile->query_courses(
725 'own',
726 array(
727 'status' => $filter,
728 'limit' => $request['per_page'] ?? '100',
729 'paged' => $request['paged'] ?? 1,
730 )
731 );
732
733 $created_ids = array();
734 if ( ! empty( $query_created['items'] ) ) {
735 foreach ( $query_created['items'] as $created_item ) {
736 $created_ids[] = $created_item;
737 }
738 }
739
740 $output['created'][ $created_key ] = array_map( 'absint', $created_ids );
741 }
742 }
743
744 return $output;
745 }
746
747 /**
748 * Get Profile Quiz Tab content
749 *
750 * @param [type] $request
751 * @return void
752 *
753 * @author Nhamdv <daonham@gmail.com>
754 */
755 public function get_quiz_tab_contents( $request ) {
756 $output = array();
757
758 $user_profile = learn_press_get_user( $request['id'] );
759 $filters = array(
760 'all' => '',
761 'finished' => 'completed',
762 'passed' => 'passed',
763 'failed' => 'failed',
764 'in-progress' => 'in-progress',
765 );
766
767 if ( method_exists( $user_profile, 'get_user_quizzes' ) ) {
768 foreach ( $filters as $key => $quiz_filter ) {
769 $filter = new LP_User_Items_Filter();
770 $filter->user_id = $request['id'];
771 $filter->limit = 100;
772 $filter->status = $quiz_filter === 'complete' ? 'complete' : '';
773 $filter->graduation = $quiz_filter !== 'complete' ? $quiz_filter : '';
774 $query = $user_profile->get_user_quizzes( $filter );
775
776 $ids = array();
777 if ( ! empty( $query['items'] ) ) {
778 foreach ( $query['items'] as $item ) {
779 $ids[] = array(
780 'id' => $item->get_id(),
781 'result' => $item->get_percent_result() ?? '',
782 'graduation' => $item->get_graduation() ?? '',
783 'start_time' => $item->get_start_time() ? lp_jwt_prepare_date_response( $item->get_start_time()->toSql( false ) ) : '',
784 'end_time' => $item->get_end_time() ? lp_jwt_prepare_date_response( $item->get_end_time()->toSql( false ) ) : '',
785 'data' => $filter !== 'in-progress' ? $item->calculate_quiz_result() : array(),
786 'attempt' => $filter !== 'in-progress' ? $item->get_attempts() : array(),
787 );
788 }
789 }
790
791 $output[ $key ] = $ids;
792 }
793 }
794
795 return $output;
796 }
797
798 /**
799 * Get order by user id
800 *
801 * @param array $request [id: user ID]
802 * @return array
803 *
804 * @author Nhamdv <daonham95@gmail.com>
805 */
806 public function get_order_content_tab( $request ) {
807 $output = array();
808
809 $profile = learn_press_get_profile( $request['id'] );
810
811 if ( method_exists( $profile, 'query_orders' ) ) {
812 $query_orders = $profile->query_orders( array( 'fields' => 'ids' ) );
813
814 if ( ! empty( $query_orders['items'] ) ) {
815 foreach ( $query_orders['items'] as $order_id ) {
816 $order = learn_press_get_order( $order_id );
817
818 $output[ $order_id ] = array(
819 'order_key' => $order->get_order_number() ?? '',
820 'total' => $order->get_total(),
821 'currency' => $order->get_currency(),
822 'status' => $order->get_status(),
823 'date' => lp_jwt_prepare_date_response( $order->get_order_date() ),
824 );
825 }
826 }
827 }
828
829 return $output;
830 }
831
832 /**
833 * Retrieves a single user.
834 *
835 * @since 4.7.0
836 *
837 * @param WP_REST_Request $request Full details about the request.
838 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
839 */
840 public function get_item( $request ) {
841 $user = $this->get_user( $request['id'] );
842
843 if ( is_wp_error( $user ) ) {
844 return $user;
845 }
846
847 $user = $this->prepare_item_for_response( $user, $request );
848 $response = rest_ensure_response( $user );
849
850 return $response;
851 }
852
853 /**
854 * Retrieves all users.
855 *
856 * @since 4.7.0
857 *
858 * @param WP_REST_Request $request Full details about the request.
859 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
860 */
861 public function get_items( $request ) {
862
863 // Retrieve the list of registered collection query parameters.
864 $registered = $this->get_collection_params();
865
866 /*
867 * This array defines mappings between public API query parameters whose
868 * values are accepted as-passed, and their internal WP_Query parameter
869 * name equivalents (some are the same). Only values which are also
870 * present in $registered will be set.
871 */
872 $parameter_mappings = array(
873 'exclude' => 'exclude',
874 'include' => 'include',
875 'order' => 'order',
876 'per_page' => 'number',
877 'search' => 'search',
878 'roles' => 'role__in',
879 'slug' => 'nicename__in',
880 );
881
882 $prepared_args = array();
883
884 /*
885 * For each known parameter which is both registered and present in the request,
886 * set the parameter's value on the query $prepared_args.
887 */
888 foreach ( $parameter_mappings as $api_param => $wp_param ) {
889 if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) {
890 $prepared_args[ $wp_param ] = $request[ $api_param ];
891 }
892 }
893
894 if ( isset( $registered['offset'] ) && ! empty( $request['offset'] ) ) {
895 $prepared_args['offset'] = $request['offset'];
896 } else {
897 $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number'];
898 }
899
900 if ( isset( $registered['orderby'] ) ) {
901 $orderby_possibles = array(
902 'id' => 'ID',
903 'include' => 'include',
904 'name' => 'display_name',
905 'registered_date' => 'registered',
906 'slug' => 'user_nicename',
907 'include_slugs' => 'nicename__in',
908 'email' => 'user_email',
909 'url' => 'user_url',
910 );
911 $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ];
912 }
913
914 if ( isset( $registered['who'] ) && ! empty( $request['who'] ) && 'authors' === $request['who'] ) {
915 $prepared_args['who'] = 'authors';
916 }
917
918 if ( ! empty( $prepared_args['search'] ) ) {
919 $prepared_args['search'] = '*' . $prepared_args['search'] . '*';
920 }
921 /**
922 * Filters WP_User_Query arguments when querying users via the REST API.
923 *
924 * @link https://developer.wordpress.org/reference/classes/wp_user_query/
925 *
926 * @since 4.7.0
927 *
928 * @param array $prepared_args Array of arguments for WP_User_Query.
929 * @param WP_REST_Request $request The REST API request.
930 */
931 $prepared_args = apply_filters( 'rest_user_query', $prepared_args, $request );
932
933 $query = new WP_User_Query( $prepared_args );
934
935 $users = array();
936
937 foreach ( $query->results as $user ) {
938 $data = $this->prepare_item_for_response( $user, $request );
939 $users[] = $this->prepare_response_for_collection( $data );
940 }
941
942 $response = rest_ensure_response( $users );
943
944 // Store pagination values for headers then unset for count query.
945 $per_page = (int) $prepared_args['number'];
946 $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
947
948 $prepared_args['fields'] = 'ID';
949
950 $total_users = $query->get_total();
951
952 if ( $total_users < 1 ) {
953 // Out-of-bounds, run the query again without LIMIT for total count.
954 unset( $prepared_args['number'], $prepared_args['offset'] );
955 $count_query = new WP_User_Query( $prepared_args );
956 $total_users = $count_query->get_total();
957 }
958
959 $response->header( 'X-WP-Total', (int) $total_users );
960
961 $max_pages = ceil( $total_users / $per_page );
962
963 $response->header( 'X-WP-TotalPages', (int) $max_pages );
964
965 $base = add_query_arg( urlencode_deep( $request->get_query_params() ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) );
966 if ( $page > 1 ) {
967 $prev_page = $page - 1;
968
969 if ( $prev_page > $max_pages ) {
970 $prev_page = $max_pages;
971 }
972
973 $prev_link = add_query_arg( 'page', $prev_page, $base );
974 $response->link_header( 'prev', $prev_link );
975 }
976 if ( $max_pages > $page ) {
977 $next_page = $page + 1;
978 $next_link = add_query_arg( 'page', $next_page, $base );
979
980 $response->link_header( 'next', $next_link );
981 }
982
983 return $response;
984 }
985
986 /**
987 * Prepares a single user output for response.
988 *
989 * @since 4.7.0
990 *
991 * @param WP_User $user User object.
992 * @param WP_REST_Request $request Request object.
993 * @return WP_REST_Response Response object.
994 */
995 public function prepare_item_for_response( $user, $request ) {
996 $context = ! empty( $request['context'] ) ? $request['context'] : 'embed';
997 $data = $this->get_users_data( $user, $context, $request );
998
999 $data = $this->add_additional_fields_to_object( $data, $request );
1000 $data = $this->filter_response_by_context( $data, $context );
1001
1002 // Wrap the data in a response object.
1003 $response = rest_ensure_response( $data );
1004
1005 $response->add_links( $this->prepare_links( $user ) );
1006
1007 return apply_filters( 'lp_rest_prepare_user', $response, $user, $request );
1008 }
1009
1010 public function get_users_data( $user, $context = 'view' ) {
1011 $request = func_num_args() >= 2 ? func_get_arg( 2 ) : new WP_REST_Request( '', '', array( 'context' => $context ) );
1012 $fields = $this->get_fields_for_response( $request );
1013 $data = array();
1014
1015 foreach ( $fields as $field ) {
1016 switch ( $field ) {
1017 case 'id':
1018 $data['id'] = $user->ID;
1019 break;
1020 case 'username':
1021 $data['username'] = $user->user_login;
1022 break;
1023 case 'name':
1024 $data['name'] = $user->display_name;
1025 break;
1026 case 'first_name':
1027 $data['first_name'] = $user->first_name;
1028 break;
1029 case 'last_name':
1030 $data['last_name'] = $user->last_name;
1031 break;
1032 case 'email':
1033 $data['email'] = $user->user_email;
1034 break;
1035 case 'url':
1036 $data['url'] = $user->user_url;
1037 break;
1038 case 'description':
1039 $data['description'] = $user->description;
1040 break;
1041 case 'link':
1042 $data['link'] = get_author_posts_url( $user->ID, $user->user_nicename );
1043 break;
1044 case 'locale':
1045 $data['locale'] = get_user_locale( $user );
1046 break;
1047 case 'nickname':
1048 $data['nickname'] = $user->nickname;
1049 break;
1050 case 'slug':
1051 $data['slug'] = $user->user_nicename;
1052 break;
1053 case 'roles':
1054 $data['roles'] = array_values( $user->roles );
1055 break;
1056 case 'registered_date':
1057 $data['registered_date'] = gmdate( 'c', strtotime( $user->user_registered ) );
1058 break;
1059 case 'capabilities':
1060 $data['capabilities'] = (object) $user->allcaps;
1061 break;
1062 case 'extra_capabilities':
1063 $data['extra_capabilities'] = (object) $user->caps;
1064 break;
1065 case 'avatar_url':
1066 $data['avatar_url'] = $this->get_profile_avatar( $user->ID );
1067 break;
1068 case 'avatar_size':
1069 $data['avatar_size']['width'] = learn_press_get_avatar_thumb_size()['width'];
1070 $data['avatar_size']['height'] = learn_press_get_avatar_thumb_size()['height'];
1071 break;
1072 case 'instructor_data':
1073 // $data['instructor_data'] = $this->get_instructor_data( $user->ID );
1074 $data['instructor_data'] = LP_Profile::instance( $user->ID )->get_statistic_info();
1075 break;
1076 case 'meta':
1077 $data['meta'] = $this->meta->get_value( $user->ID, $request );
1078 break;
1079 case 'tabs':
1080 $data['tabs'] = $this->get_lp_data_tabs( $user, $request );
1081 break;
1082 case 'custom_register':
1083 $data['custom_register'] = $this->custom_register( $user );
1084 break;
1085 case 'social':
1086 $data['social'] = $this->get_social_data( $user->ID );
1087 break;
1088 }
1089 }
1090
1091 return $data;
1092 }
1093
1094 public function get_social_data( $user_id ) {
1095 return learn_press_get_user_extra_profile_info( $user_id );
1096 }
1097
1098 public function get_profile_avatar( $user_id ) {
1099 $user = learn_press_get_user( $user_id );
1100
1101 $avatar = $user->get_upload_profile_src();
1102
1103 return ! empty( $avatar ) ? $avatar : '';
1104 }
1105
1106 /**
1107 * @editor tungnx
1108 * @deprecated 4.1.6
1109 */
1110 /*
1111 public function get_instructor_data( $user_id ) {
1112 $profile = learn_press_get_profile( $user_id );
1113
1114 $output = array();
1115
1116 if ( is_wp_error( $profile ) ) {
1117 return $output;
1118 }
1119
1120 $query = $profile->query_courses( 'purchased' );
1121 $counts = $query['counts'];
1122
1123 $output = array(
1124 'enrolled_courses' => isset( $counts['all'] ) ? absint( $counts['all'] ) : 0,
1125 'completed_courses' => isset( $counts['finished'] ) ? absint( $counts['finished'] ) : 0,
1126 'courses' => absint( count_user_posts( $user_id, LP_COURSE_CPT ) ),
1127 'students' => absint( learn_press_count_instructor_users( $user_id ) ),
1128 );
1129
1130 return $output;
1131 }*/
1132
1133 public function get_lp_data_tabs( $user, $request ) {
1134 $output = array();
1135
1136 if ( get_current_user_id() === $user->ID || current_user_can( 'list_users' ) ) {
1137 if ( function_exists( 'learn_press_get_user_profile_tabs' ) ) {
1138 $tabs = learn_press_get_user_profile_tabs();
1139
1140 $content = array(
1141 'overview' => $this->get_overview_tab_contents( $user ),
1142 'courses' => $this->get_course_tab_contents( $request ),
1143 'quizzes' => $this->get_quiz_tab_contents( $request ),
1144 'orders' => $this->get_order_content_tab( $request ),
1145 );
1146
1147 foreach ( $tabs->get() as $key => $tab ) {
1148 $output[ $key ] = array(
1149 'title' => $tab['title'] ?? '',
1150 'slug' => $tab['slug'] ?? '',
1151 'priority' => $tab['priority'] ?? '',
1152 'icon' => $tab['icon'] ?? '',
1153 'content' => $content[ $key ] ?? '',
1154 );
1155
1156 if ( ! empty( $tab['sections'] ) ) {
1157 foreach ( $tab['sections'] as $section_key => $section ) {
1158 $output[ $key ]['section'][ $section_key ] = array(
1159 'title' => $section['title'] ?? '',
1160 'slug' => $section['slug'] ?? '',
1161 'priority' => $section['priority'] ?? '',
1162 );
1163 }
1164 }
1165 }
1166 }
1167 }
1168
1169 return $output;
1170 }
1171
1172 /**
1173 * Display register cutom form in LearnPress Setting
1174 *
1175 * @param object $user
1176 * @return array
1177 */
1178 public function custom_register( $user ) {
1179 $output = array();
1180
1181 if ( function_exists( 'lp_get_user_custom_register_fields' ) ) {
1182 $custom_fields = LP_Settings::instance()->get( 'register_profile_fields' );
1183 $custom_profile = lp_get_user_custom_register_fields( $user->ID );
1184
1185 if ( $custom_fields ) {
1186 foreach ( $custom_fields as $field ) {
1187 $value = $field['id'];
1188 $output[ $value ] = array(
1189 'title' => $field['name'] ?? '',
1190 'type' => $field['type'] ?? '',
1191 'required' => $field['required'] ?? 'no',
1192 'value' => $custom_profile[ $value ] ?? '',
1193 );
1194 }
1195 }
1196 }
1197
1198 return $output;
1199 }
1200
1201 /**
1202 * Prepares links for the user request.
1203 *
1204 * @since 4.7.0
1205 *
1206 * @param WP_User $user User object.
1207 * @return array Links for the given user.
1208 */
1209 protected function prepare_links( $user ) {
1210 $links = array(
1211 'self' => array(
1212 'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user->ID ) ),
1213 ),
1214 'collection' => array(
1215 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
1216 ),
1217 );
1218
1219 return $links;
1220 }
1221
1222 public function check_username( $value, $request, $param ) {
1223 $username = (string) $value;
1224
1225 if ( ! validate_username( $username ) ) {
1226 return new WP_Error(
1227 'rest_user_invalid_username',
1228 __( 'This username is invalid because it uses illegal characters. Please enter a valid username.' ),
1229 array( 'status' => 400 )
1230 );
1231 }
1232
1233 /** This filter is documented in wp-includes/user.php */
1234 $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
1235
1236 if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ), true ) ) {
1237 return new WP_Error(
1238 'rest_user_invalid_username',
1239 __( 'Sorry, that username is not allowed.' ),
1240 array( 'status' => 400 )
1241 );
1242 }
1243
1244 return $username;
1245 }
1246
1247 /**
1248 * Check a user password for the REST API.
1249 *
1250 * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
1251 *
1252 * @since 4.7.0
1253 *
1254 * @param string $value The password submitted in the request.
1255 * @param WP_REST_Request $request Full details about the request.
1256 * @param string $param The parameter name.
1257 * @return string|WP_Error The sanitized password, if valid, otherwise an error.
1258 */
1259 public function check_user_password( $value, $request, $param ) {
1260 $password = (string) $value;
1261
1262 if ( empty( $password ) ) {
1263 return new WP_Error(
1264 'rest_user_invalid_password',
1265 __( 'Passwords cannot be empty.' ),
1266 array( 'status' => 400 )
1267 );
1268 }
1269
1270 if ( false !== strpos( $password, '\\' ) ) {
1271 return new WP_Error(
1272 'rest_user_invalid_password',
1273 sprintf(
1274 /* translators: %s: The '\' character. */
1275 __( 'Passwords cannot contain the "%s" character.' ),
1276 '\\'
1277 ),
1278 array( 'status' => 400 )
1279 );
1280 }
1281
1282 return $password;
1283 }
1284
1285 public function get_item_schema() {
1286 $schema = array(
1287 '$schema' => 'http://json-schema.org/draft-04/schema#',
1288 'title' => 'user',
1289 'type' => 'object',
1290 'properties' => array(
1291 'id' => array(
1292 'description' => __( 'Unique identifier for the user.' ),
1293 'type' => 'integer',
1294 'context' => array( 'embed', 'view', 'edit' ),
1295 'readonly' => true,
1296 ),
1297 'username' => array(
1298 'description' => __( 'Login name for the user.' ),
1299 'type' => 'string',
1300 'context' => array( 'view', 'edit' ),
1301 'required' => true,
1302 'arg_options' => array(
1303 'sanitize_callback' => array( $this, 'check_username' ),
1304 ),
1305 ),
1306 'name' => array(
1307 'description' => __( 'Display name for the user.' ),
1308 'type' => 'string',
1309 'context' => array( 'embed', 'view', 'edit' ),
1310 'arg_options' => array(
1311 'sanitize_callback' => 'sanitize_text_field',
1312 ),
1313 ),
1314 'first_name' => array(
1315 'description' => __( 'First name for the user.' ),
1316 'type' => 'string',
1317 'context' => array( 'view', 'edit' ),
1318 'arg_options' => array(
1319 'sanitize_callback' => 'sanitize_text_field',
1320 ),
1321 ),
1322 'last_name' => array(
1323 'description' => __( 'Last name for the user.' ),
1324 'type' => 'string',
1325 'context' => array( 'view', 'edit' ),
1326 'arg_options' => array(
1327 'sanitize_callback' => 'sanitize_text_field',
1328 ),
1329 ),
1330 'email' => array(
1331 'description' => __( 'The email address for the user.' ),
1332 'type' => 'string',
1333 'format' => 'email',
1334 'context' => array( 'view', 'edit' ),
1335 'required' => true,
1336 ),
1337 'url' => array(
1338 'description' => __( 'URL of the user.' ),
1339 'type' => 'string',
1340 'format' => 'uri',
1341 'context' => array( 'embed', 'view', 'edit' ),
1342 ),
1343 'description' => array(
1344 'description' => __( 'Description of the user.' ),
1345 'type' => 'string',
1346 'context' => array( 'embed', 'view', 'edit' ),
1347 ),
1348 'link' => array(
1349 'description' => __( 'Author URL of the user.' ),
1350 'type' => 'string',
1351 'format' => 'uri',
1352 'context' => array( 'embed', 'view', 'edit' ),
1353 'readonly' => true,
1354 ),
1355 'locale' => array(
1356 'description' => __( 'Locale for the user.' ),
1357 'type' => 'string',
1358 'enum' => array_merge( array( '', 'en_US' ), get_available_languages() ),
1359 'context' => array( 'edit' ),
1360 ),
1361 'nickname' => array(
1362 'description' => __( 'The nickname for the user.' ),
1363 'type' => 'string',
1364 'context' => array( 'view', 'edit' ),
1365 'arg_options' => array(
1366 'sanitize_callback' => 'sanitize_text_field',
1367 ),
1368 ),
1369 'slug' => array(
1370 'description' => __( 'An alphanumeric identifier for the user.' ),
1371 'type' => 'string',
1372 'context' => array( 'embed', 'view', 'edit' ),
1373 'arg_options' => array(
1374 'sanitize_callback' => array( $this, 'sanitize_slug' ),
1375 ),
1376 ),
1377 'registered_date' => array(
1378 'description' => __( 'Registration date for the user.' ),
1379 'type' => 'string',
1380 'format' => 'date-time',
1381 'context' => array( 'edit' ),
1382 'readonly' => true,
1383 ),
1384 'roles' => array(
1385 'description' => __( 'Roles assigned to the user.' ),
1386 'type' => 'array',
1387 'items' => array(
1388 'type' => 'string',
1389 ),
1390 'context' => array( 'edit' ),
1391 ),
1392 'password' => array(
1393 'description' => __( 'Password for the user (never included).' ),
1394 'type' => 'string',
1395 'context' => array(), // Password is never displayed.
1396 'required' => true,
1397 'arg_options' => array(
1398 'sanitize_callback' => array( $this, 'check_user_password' ),
1399 ),
1400 ),
1401 'capabilities' => array(
1402 'description' => __( 'All capabilities assigned to the user.' ),
1403 'type' => 'object',
1404 'context' => array( 'edit' ),
1405 'readonly' => true,
1406 ),
1407 'extra_capabilities' => array(
1408 'description' => __( 'Any extra capabilities assigned to the user.' ),
1409 'type' => 'object',
1410 'context' => array( 'edit' ),
1411 'readonly' => true,
1412 ),
1413 'tabs' => array(
1414 'description' => __( 'Get all items in user like course, lesson, quiz...' ),
1415 'type' => 'array',
1416 'context' => array( 'view' ),
1417 ),
1418 'avatar_url' => array(
1419 'description' => __( 'URL avatar' ),
1420 'type' => 'string',
1421 'context' => array( 'view', 'edit' ),
1422 ),
1423 'avatar_size' => array(
1424 'description' => __( 'URL avatar size' ),
1425 'type' => 'array',
1426 'context' => array( 'view' ),
1427 ),
1428 'instructor_data' => array(
1429 'description' => __( 'Instructor data' ),
1430 'type' => 'array',
1431 'context' => array( 'view' ),
1432 ),
1433 'custom_register' => array(
1434 'description' => __( 'Get custom register fields.' ),
1435 'type' => 'object',
1436 'context' => array( 'view' ),
1437 ),
1438 'social' => array(
1439 'description' => __( 'Get social fields.' ),
1440 'type' => 'object',
1441 'context' => array( 'view' ),
1442 ),
1443 ),
1444 );
1445
1446 $schema['properties']['meta'] = $this->meta->get_field_schema();
1447
1448 return $this->add_additional_fields_schema( $schema );
1449 }
1450
1451 public function get_collection_params() {
1452 $query_params = parent::get_collection_params();
1453
1454 $query_params['context']['default'] = 'view';
1455
1456 $query_params['exclude'] = array(
1457 'description' => __( 'Ensure result set excludes specific IDs.' ),
1458 'type' => 'array',
1459 'items' => array(
1460 'type' => 'integer',
1461 ),
1462 'default' => array(),
1463 );
1464
1465 $query_params['include'] = array(
1466 'description' => __( 'Limit result set to specific IDs.' ),
1467 'type' => 'array',
1468 'items' => array(
1469 'type' => 'integer',
1470 ),
1471 'default' => array(),
1472 );
1473
1474 $query_params['offset'] = array(
1475 'description' => __( 'Offset the result set by a specific number of items.' ),
1476 'type' => 'integer',
1477 );
1478
1479 $query_params['order'] = array(
1480 'default' => 'asc',
1481 'description' => __( 'Order sort attribute ascending or descending.' ),
1482 'enum' => array( 'asc', 'desc' ),
1483 'type' => 'string',
1484 );
1485
1486 $query_params['orderby'] = array(
1487 'default' => 'name',
1488 'description' => __( 'Sort collection by object attribute.' ),
1489 'enum' => array(
1490 'id',
1491 'include',
1492 'name',
1493 'registered_date',
1494 'slug',
1495 'include_slugs',
1496 'email',
1497 'url',
1498 ),
1499 'type' => 'string',
1500 );
1501
1502 $query_params['slug'] = array(
1503 'description' => __( 'Limit result set to users with one or more specific slugs.' ),
1504 'type' => 'array',
1505 'items' => array(
1506 'type' => 'string',
1507 ),
1508 );
1509
1510 $query_params['roles'] = array(
1511 'description' => __( 'Limit result set to users matching at least one specific role provided. Accepts csv list or single role.' ),
1512 'type' => 'array',
1513 'items' => array(
1514 'type' => 'string',
1515 ),
1516 );
1517
1518 $query_params['who'] = array(
1519 'description' => __( 'Limit result set to users who are considered authors.' ),
1520 'type' => 'string',
1521 'enum' => array(
1522 'authors',
1523 ),
1524 );
1525
1526 /**
1527 * Filters REST API collection parameters for the users controller.
1528 *
1529 * This filter registers the collection parameter, but does not map the
1530 * collection parameter to an internal WP_User_Query parameter. Use the
1531 * `rest_user_query` filter to set WP_User_Query arguments.
1532 *
1533 * @since 4.7.0
1534 *
1535 * @param array $query_params JSON Schema-formatted collection parameters.
1536 */
1537 return apply_filters( 'rest_user_collection_params', $query_params );
1538 }
1539 }
1540