135 * @param array $args Arguments passed to WP_User_Query to retrieve items for the current |
135 * @param array $args Arguments passed to WP_User_Query to retrieve items for the current |
136 * users list table. |
136 * users list table. |
137 */ |
137 */ |
138 $args = apply_filters( 'users_list_table_query_args', $args ); |
138 $args = apply_filters( 'users_list_table_query_args', $args ); |
139 |
139 |
140 // Query the user IDs for this page |
140 // Query the user IDs for this page. |
141 $wp_user_search = new WP_User_Query( $args ); |
141 $wp_user_search = new WP_User_Query( $args ); |
142 |
142 |
143 $this->items = $wp_user_search->get_results(); |
143 $this->items = $wp_user_search->get_results(); |
144 |
144 |
145 $this->set_pagination_args( |
145 $this->set_pagination_args( |
164 * with this table. |
164 * with this table. |
165 * |
165 * |
166 * Provides a list of roles and user count for that role for easy |
166 * Provides a list of roles and user count for that role for easy |
167 * Filtersing of the user table. |
167 * Filtersing of the user table. |
168 * |
168 * |
169 * @since 3.1.0 |
169 * @since 3.1.0 |
170 * |
170 * |
171 * @global string $role |
171 * @global string $role |
172 * |
172 * |
173 * @return array An array of HTML links, one for each view. |
173 * @return string[] An array of HTML links keyed by their view. |
174 */ |
174 */ |
175 protected function get_views() { |
175 protected function get_views() { |
176 global $role; |
176 global $role; |
177 |
177 |
178 $wp_roles = wp_roles(); |
178 $wp_roles = wp_roles(); |
192 unset( $users_of_blog ); |
192 unset( $users_of_blog ); |
193 |
193 |
194 $current_link_attributes = empty( $role ) ? ' class="current" aria-current="page"' : ''; |
194 $current_link_attributes = empty( $role ) ? ' class="current" aria-current="page"' : ''; |
195 |
195 |
196 $role_links = array(); |
196 $role_links = array(); |
197 $role_links['all'] = "<a href='$url'$current_link_attributes>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_users, 'users' ), number_format_i18n( $total_users ) ) . '</a>'; |
197 $role_links['all'] = sprintf( |
|
198 '<a href="%s"%s>%s</a>', |
|
199 $url, |
|
200 $current_link_attributes, |
|
201 sprintf( |
|
202 /* translators: %s: Number of users. */ |
|
203 _nx( |
|
204 'All <span class="count">(%s)</span>', |
|
205 'All <span class="count">(%s)</span>', |
|
206 $total_users, |
|
207 'users' |
|
208 ), |
|
209 number_format_i18n( $total_users ) |
|
210 ) |
|
211 ); |
|
212 |
198 foreach ( $wp_roles->get_names() as $this_role => $name ) { |
213 foreach ( $wp_roles->get_names() as $this_role => $name ) { |
199 if ( ! isset( $avail_roles[ $this_role ] ) ) { |
214 if ( ! isset( $avail_roles[ $this_role ] ) ) { |
200 continue; |
215 continue; |
201 } |
216 } |
202 |
217 |
205 if ( $this_role === $role ) { |
220 if ( $this_role === $role ) { |
206 $current_link_attributes = ' class="current" aria-current="page"'; |
221 $current_link_attributes = ' class="current" aria-current="page"'; |
207 } |
222 } |
208 |
223 |
209 $name = translate_user_role( $name ); |
224 $name = translate_user_role( $name ); |
210 /* translators: User role name with count */ |
225 $name = sprintf( |
211 $name = sprintf( __( '%1$s <span class="count">(%2$s)</span>' ), $name, number_format_i18n( $avail_roles[ $this_role ] ) ); |
226 /* translators: 1: User role name, 2: Number of users. */ |
|
227 __( '%1$s <span class="count">(%2$s)</span>' ), |
|
228 $name, |
|
229 number_format_i18n( $avail_roles[ $this_role ] ) |
|
230 ); |
|
231 |
212 $role_links[ $this_role ] = "<a href='" . esc_url( add_query_arg( 'role', $this_role, $url ) ) . "'$current_link_attributes>$name</a>"; |
232 $role_links[ $this_role ] = "<a href='" . esc_url( add_query_arg( 'role', $this_role, $url ) ) . "'$current_link_attributes>$name</a>"; |
213 } |
233 } |
214 |
234 |
215 if ( ! empty( $avail_roles['none'] ) ) { |
235 if ( ! empty( $avail_roles['none'] ) ) { |
216 |
236 |
219 if ( 'none' === $role ) { |
239 if ( 'none' === $role ) { |
220 $current_link_attributes = ' class="current" aria-current="page"'; |
240 $current_link_attributes = ' class="current" aria-current="page"'; |
221 } |
241 } |
222 |
242 |
223 $name = __( 'No role' ); |
243 $name = __( 'No role' ); |
224 /* translators: User role name with count */ |
244 $name = sprintf( |
225 $name = sprintf( __( '%1$s <span class="count">(%2$s)</span>' ), $name, number_format_i18n( $avail_roles['none'] ) ); |
245 /* translators: 1: User role name, 2: Number of users. */ |
|
246 __( '%1$s <span class="count">(%2$s)</span>' ), |
|
247 $name, |
|
248 number_format_i18n( $avail_roles['none'] ) |
|
249 ); |
|
250 |
226 $role_links['none'] = "<a href='" . esc_url( add_query_arg( 'role', 'none', $url ) ) . "'$current_link_attributes>$name</a>"; |
251 $role_links['none'] = "<a href='" . esc_url( add_query_arg( 'role', 'none', $url ) ) . "'$current_link_attributes>$name</a>"; |
227 |
|
228 } |
252 } |
229 |
253 |
230 return $role_links; |
254 return $role_links; |
231 } |
255 } |
232 |
256 |
233 /** |
257 /** |
234 * Retrieve an associative array of bulk actions available on this table. |
258 * Retrieve an associative array of bulk actions available on this table. |
235 * |
259 * |
236 * @since 3.1.0 |
260 * @since 3.1.0 |
237 * |
261 * |
238 * @return array Array of bulk actions. |
262 * @return string[] Array of bulk action labels keyed by their action. |
239 */ |
263 */ |
240 protected function get_bulk_actions() { |
264 protected function get_bulk_actions() { |
241 $actions = array(); |
265 $actions = array(); |
242 |
266 |
243 if ( is_multisite() ) { |
267 if ( is_multisite() ) { |
304 * Capture the bulk action required, and return it. |
328 * Capture the bulk action required, and return it. |
305 * |
329 * |
306 * Overridden from the base class implementation to capture |
330 * Overridden from the base class implementation to capture |
307 * the role change drop-down. |
331 * the role change drop-down. |
308 * |
332 * |
309 * @since 3.1.0 |
333 * @since 3.1.0 |
310 * |
334 * |
311 * @return string The bulk action required. |
335 * @return string The bulk action required. |
312 */ |
336 */ |
313 public function current_action() { |
337 public function current_action() { |
314 if ( ( isset( $_REQUEST['changeit'] ) || isset( $_REQUEST['changeit2'] ) ) && |
338 if ( ( isset( $_REQUEST['changeit'] ) || isset( $_REQUEST['changeit2'] ) ) && |
320 } |
344 } |
321 |
345 |
322 /** |
346 /** |
323 * Get a list of columns for the list table. |
347 * Get a list of columns for the list table. |
324 * |
348 * |
325 * @since 3.1.0 |
349 * @since 3.1.0 |
326 * |
350 * |
327 * @return array Array in which the key is the ID of the column, |
351 * @return string[] Array of column titles keyed by their column name. |
328 * and the value is the description. |
|
329 */ |
352 */ |
330 public function get_columns() { |
353 public function get_columns() { |
331 $c = array( |
354 $c = array( |
332 'cb' => '<input type="checkbox" />', |
355 'cb' => '<input type="checkbox" />', |
333 'username' => __( 'Username' ), |
356 'username' => __( 'Username' ), |
364 * Generate the list table rows. |
387 * Generate the list table rows. |
365 * |
388 * |
366 * @since 3.1.0 |
389 * @since 3.1.0 |
367 */ |
390 */ |
368 public function display_rows() { |
391 public function display_rows() { |
369 // Query the post counts for this page |
392 // Query the post counts for this page. |
370 if ( ! $this->is_site_users ) { |
393 if ( ! $this->is_site_users ) { |
371 $post_counts = count_many_users_posts( array_keys( $this->items ) ); |
394 $post_counts = count_many_users_posts( array_keys( $this->items ) ); |
372 } |
395 } |
373 |
396 |
374 foreach ( $this->items as $userid => $user_object ) { |
397 foreach ( $this->items as $userid => $user_object ) { |
403 $url = 'users.php?'; |
426 $url = 'users.php?'; |
404 } |
427 } |
405 |
428 |
406 $user_roles = $this->get_role_list( $user_object ); |
429 $user_roles = $this->get_role_list( $user_object ); |
407 |
430 |
408 // Set up the hover actions for this user |
431 // Set up the hover actions for this user. |
409 $actions = array(); |
432 $actions = array(); |
410 $checkbox = ''; |
433 $checkbox = ''; |
411 $super_admin = ''; |
434 $super_admin = ''; |
412 |
435 |
413 if ( is_multisite() && current_user_can( 'manage_network_users' ) ) { |
436 if ( is_multisite() && current_user_can( 'manage_network_users' ) ) { |
414 if ( in_array( $user_object->user_login, get_super_admins(), true ) ) { |
437 if ( in_array( $user_object->user_login, get_super_admins(), true ) ) { |
415 $super_admin = ' — ' . __( 'Super Admin' ); |
438 $super_admin = ' — ' . __( 'Super Admin' ); |
416 } |
439 } |
417 } |
440 } |
418 |
441 |
419 // Check if the user for this row is editable |
442 // Check if the user for this row is editable. |
420 if ( current_user_can( 'list_users' ) ) { |
443 if ( current_user_can( 'list_users' ) ) { |
421 // Set up the user editing link |
444 // Set up the user editing link. |
422 $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user_object->ID ) ) ); |
445 $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user_object->ID ) ) ); |
423 |
446 |
424 if ( current_user_can( 'edit_user', $user_object->ID ) ) { |
447 if ( current_user_can( 'edit_user', $user_object->ID ) ) { |
425 $edit = "<strong><a href=\"{$edit_link}\">{$user_object->user_login}</a>{$super_admin}</strong><br />"; |
448 $edit = "<strong><a href=\"{$edit_link}\">{$user_object->user_login}</a>{$super_admin}</strong><br />"; |
426 $actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>'; |
449 $actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>'; |
429 } |
452 } |
430 |
453 |
431 if ( ! is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'delete_user', $user_object->ID ) ) { |
454 if ( ! is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'delete_user', $user_object->ID ) ) { |
432 $actions['delete'] = "<a class='submitdelete' href='" . wp_nonce_url( "users.php?action=delete&user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Delete' ) . '</a>'; |
455 $actions['delete'] = "<a class='submitdelete' href='" . wp_nonce_url( "users.php?action=delete&user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Delete' ) . '</a>'; |
433 } |
456 } |
434 if ( is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'remove_user', $user_object->ID ) ) { |
457 if ( is_multisite() && current_user_can( 'remove_user', $user_object->ID ) ) { |
435 $actions['remove'] = "<a class='submitdelete' href='" . wp_nonce_url( $url . "action=remove&user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Remove' ) . '</a>'; |
458 $actions['remove'] = "<a class='submitdelete' href='" . wp_nonce_url( $url . "action=remove&user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Remove' ) . '</a>'; |
436 } |
459 } |
437 |
460 |
438 // Add a link to the user's author archive, if not empty. |
461 // Add a link to the user's author archive, if not empty. |
439 $author_posts_url = get_author_posts_url( $user_object->ID ); |
462 $author_posts_url = get_author_posts_url( $user_object->ID ); |
440 if ( $author_posts_url ) { |
463 if ( $author_posts_url ) { |
441 $actions['view'] = sprintf( |
464 $actions['view'] = sprintf( |
442 '<a href="%s" aria-label="%s">%s</a>', |
465 '<a href="%s" aria-label="%s">%s</a>', |
443 esc_url( $author_posts_url ), |
466 esc_url( $author_posts_url ), |
444 /* translators: %s: author's display name */ |
467 /* translators: %s: Author's display name. */ |
445 esc_attr( sprintf( __( 'View posts by %s' ), $user_object->display_name ) ), |
468 esc_attr( sprintf( __( 'View posts by %s' ), $user_object->display_name ) ), |
446 __( 'View' ) |
469 __( 'View' ) |
447 ); |
470 ); |
448 } |
471 } |
449 |
472 |
460 $actions = apply_filters( 'user_row_actions', $actions, $user_object ); |
483 $actions = apply_filters( 'user_row_actions', $actions, $user_object ); |
461 |
484 |
462 // Role classes. |
485 // Role classes. |
463 $role_classes = esc_attr( implode( ' ', array_keys( $user_roles ) ) ); |
486 $role_classes = esc_attr( implode( ' ', array_keys( $user_roles ) ) ); |
464 |
487 |
465 // Set up the checkbox ( because the user is editable, otherwise it's empty ) |
488 // Set up the checkbox (because the user is editable, otherwise it's empty). |
466 $checkbox = '<label class="screen-reader-text" for="user_' . $user_object->ID . '">' . sprintf( __( 'Select %s' ), $user_object->user_login ) . '</label>' |
489 $checkbox = sprintf( |
467 . "<input type='checkbox' name='users[]' id='user_{$user_object->ID}' class='{$role_classes}' value='{$user_object->ID}' />"; |
490 '<label class="screen-reader-text" for="user_%1$s">%2$s</label>' . |
|
491 '<input type="checkbox" name="users[]" id="user_%1$s" class="%3$s" value="%1$s" />', |
|
492 $user_object->ID, |
|
493 /* translators: %s: User login. */ |
|
494 sprintf( __( 'Select %s' ), $user_object->user_login ), |
|
495 $role_classes |
|
496 ); |
468 |
497 |
469 } else { |
498 } else { |
470 $edit = "<strong>{$user_object->user_login}{$super_admin}</strong>"; |
499 $edit = "<strong>{$user_object->user_login}{$super_admin}</strong>"; |
471 } |
500 } |
|
501 |
472 $avatar = get_avatar( $user_object->ID, 32 ); |
502 $avatar = get_avatar( $user_object->ID, 32 ); |
473 |
503 |
474 // Comma-separated list of user roles. |
504 // Comma-separated list of user roles. |
475 $roles_list = implode( ', ', $user_roles ); |
505 $roles_list = implode( ', ', $user_roles ); |
476 |
506 |
482 $classes = "$column_name column-$column_name"; |
512 $classes = "$column_name column-$column_name"; |
483 if ( $primary === $column_name ) { |
513 if ( $primary === $column_name ) { |
484 $classes .= ' has-row-actions column-primary'; |
514 $classes .= ' has-row-actions column-primary'; |
485 } |
515 } |
486 if ( 'posts' === $column_name ) { |
516 if ( 'posts' === $column_name ) { |
487 $classes .= ' num'; // Special case for that column |
517 $classes .= ' num'; // Special case for that column. |
488 } |
518 } |
489 |
519 |
490 if ( in_array( $column_name, $hidden ) ) { |
520 if ( in_array( $column_name, $hidden, true ) ) { |
491 $classes .= ' hidden'; |
521 $classes .= ' hidden'; |
492 } |
522 } |
493 |
523 |
494 $data = 'data-colname="' . wp_strip_all_tags( $column_display_name ) . '"'; |
524 $data = 'data-colname="' . wp_strip_all_tags( $column_display_name ) . '"'; |
495 |
525 |
509 } elseif ( $user_object->first_name ) { |
539 } elseif ( $user_object->first_name ) { |
510 $r .= $user_object->first_name; |
540 $r .= $user_object->first_name; |
511 } elseif ( $user_object->last_name ) { |
541 } elseif ( $user_object->last_name ) { |
512 $r .= $user_object->last_name; |
542 $r .= $user_object->last_name; |
513 } else { |
543 } else { |
514 $r .= '<span aria-hidden="true">—</span><span class="screen-reader-text">' . _x( 'Unknown', 'name' ) . '</span>'; |
544 $r .= sprintf( |
|
545 '<span aria-hidden="true">—</span><span class="screen-reader-text">%s</span>', |
|
546 _x( 'Unknown', 'name' ) |
|
547 ); |
515 } |
548 } |
516 break; |
549 break; |
517 case 'email': |
550 case 'email': |
518 $r .= "<a href='" . esc_url( "mailto:$email" ) . "'>$email</a>"; |
551 $r .= "<a href='" . esc_url( "mailto:$email" ) . "'>$email</a>"; |
519 break; |
552 break; |
520 case 'role': |
553 case 'role': |
521 $r .= esc_html( $roles_list ); |
554 $r .= esc_html( $roles_list ); |
522 break; |
555 break; |
523 case 'posts': |
556 case 'posts': |
524 if ( $numposts > 0 ) { |
557 if ( $numposts > 0 ) { |
525 $r .= "<a href='edit.php?author=$user_object->ID' class='edit'>"; |
558 $r .= sprintf( |
526 $r .= '<span aria-hidden="true">' . $numposts . '</span>'; |
559 '<a href="%s" class="edit"><span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>', |
527 $r .= '<span class="screen-reader-text">' . sprintf( _n( '%s post by this author', '%s posts by this author', $numposts ), number_format_i18n( $numposts ) ) . '</span>'; |
560 "edit.php?author={$user_object->ID}", |
528 $r .= '</a>'; |
561 $numposts, |
|
562 sprintf( |
|
563 /* translators: %s: Number of posts. */ |
|
564 _n( '%s post by this author', '%s posts by this author', $numposts ), |
|
565 number_format_i18n( $numposts ) |
|
566 ) |
|
567 ); |
529 } else { |
568 } else { |
530 $r .= 0; |
569 $r .= 0; |
531 } |
570 } |
532 break; |
571 break; |
533 default: |
572 default: |