149 ) |
148 ) |
150 ); |
149 ); |
151 } |
150 } |
152 |
151 |
153 /** |
152 /** |
154 * Output 'no users' message. |
153 * Outputs 'no users' message. |
155 * |
154 * |
156 * @since 3.1.0 |
155 * @since 3.1.0 |
157 */ |
156 */ |
158 public function no_items() { |
157 public function no_items() { |
159 _e( 'No users found.' ); |
158 _e( 'No users found.' ); |
160 } |
159 } |
161 |
160 |
162 /** |
161 /** |
163 * Return an associative array listing all the views that can be used |
162 * Returns an associative array listing all the views that can be used |
164 * with this table. |
163 * with this table. |
165 * |
164 * |
166 * Provides a list of roles and user count for that role for easy |
165 * Provides a list of roles and user count for that role for easy |
167 * Filtersing of the user table. |
166 * filtering of the user table. |
168 * |
167 * |
169 * @since 3.1.0 |
168 * @since 3.1.0 |
170 * |
169 * |
171 * @global string $role |
170 * @global string $role |
172 * |
171 * |
183 $url = 'site-users.php?id=' . $this->site_id; |
182 $url = 'site-users.php?id=' . $this->site_id; |
184 } else { |
183 } else { |
185 $url = 'users.php'; |
184 $url = 'users.php'; |
186 } |
185 } |
187 |
186 |
188 $role_links = array(); |
187 $role_links = array(); |
189 $avail_roles = array(); |
188 $avail_roles = array(); |
190 $all_text = __( 'All' ); |
189 $all_text = __( 'All' ); |
191 $current_link_attributes = empty( $role ) ? ' class="current" aria-current="page"' : ''; |
|
192 |
190 |
193 if ( $count_users ) { |
191 if ( $count_users ) { |
194 if ( $this->is_site_users ) { |
192 if ( $this->is_site_users ) { |
195 switch_to_blog( $this->site_id ); |
193 switch_to_blog( $this->site_id ); |
196 $users_of_blog = count_users( 'time', $this->site_id ); |
194 $users_of_blog = count_users( 'time', $this->site_id ); |
213 ), |
211 ), |
214 number_format_i18n( $total_users ) |
212 number_format_i18n( $total_users ) |
215 ); |
213 ); |
216 } |
214 } |
217 |
215 |
218 $role_links['all'] = sprintf( '<a href="%s"%s>%s</a>', $url, $current_link_attributes, $all_text ); |
216 $role_links['all'] = array( |
|
217 'url' => $url, |
|
218 'label' => $all_text, |
|
219 'current' => empty( $role ), |
|
220 ); |
219 |
221 |
220 foreach ( $wp_roles->get_names() as $this_role => $name ) { |
222 foreach ( $wp_roles->get_names() as $this_role => $name ) { |
221 if ( $count_users && ! isset( $avail_roles[ $this_role ] ) ) { |
223 if ( $count_users && ! isset( $avail_roles[ $this_role ] ) ) { |
222 continue; |
224 continue; |
223 } |
|
224 |
|
225 $current_link_attributes = ''; |
|
226 |
|
227 if ( $this_role === $role ) { |
|
228 $current_link_attributes = ' class="current" aria-current="page"'; |
|
229 } |
225 } |
230 |
226 |
231 $name = translate_user_role( $name ); |
227 $name = translate_user_role( $name ); |
232 if ( $count_users ) { |
228 if ( $count_users ) { |
233 $name = sprintf( |
229 $name = sprintf( |
236 $name, |
232 $name, |
237 number_format_i18n( $avail_roles[ $this_role ] ) |
233 number_format_i18n( $avail_roles[ $this_role ] ) |
238 ); |
234 ); |
239 } |
235 } |
240 |
236 |
241 $role_links[ $this_role ] = "<a href='" . esc_url( add_query_arg( 'role', $this_role, $url ) ) . "'$current_link_attributes>$name</a>"; |
237 $role_links[ $this_role ] = array( |
|
238 'url' => esc_url( add_query_arg( 'role', $this_role, $url ) ), |
|
239 'label' => $name, |
|
240 'current' => $this_role === $role, |
|
241 ); |
242 } |
242 } |
243 |
243 |
244 if ( ! empty( $avail_roles['none'] ) ) { |
244 if ( ! empty( $avail_roles['none'] ) ) { |
245 |
|
246 $current_link_attributes = ''; |
|
247 |
|
248 if ( 'none' === $role ) { |
|
249 $current_link_attributes = ' class="current" aria-current="page"'; |
|
250 } |
|
251 |
245 |
252 $name = __( 'No role' ); |
246 $name = __( 'No role' ); |
253 $name = sprintf( |
247 $name = sprintf( |
254 /* translators: 1: User role name, 2: Number of users. */ |
248 /* translators: 1: User role name, 2: Number of users. */ |
255 __( '%1$s <span class="count">(%2$s)</span>' ), |
249 __( '%1$s <span class="count">(%2$s)</span>' ), |
256 $name, |
250 $name, |
257 number_format_i18n( $avail_roles['none'] ) |
251 number_format_i18n( $avail_roles['none'] ) |
258 ); |
252 ); |
259 |
253 |
260 $role_links['none'] = "<a href='" . esc_url( add_query_arg( 'role', 'none', $url ) ) . "'$current_link_attributes>$name</a>"; |
254 $role_links['none'] = array( |
261 } |
255 'url' => esc_url( add_query_arg( 'role', 'none', $url ) ), |
262 |
256 'label' => $name, |
263 return $role_links; |
257 'current' => 'none' === $role, |
264 } |
258 ); |
265 |
259 } |
266 /** |
260 |
267 * Retrieve an associative array of bulk actions available on this table. |
261 return $this->get_views_links( $role_links ); |
|
262 } |
|
263 |
|
264 /** |
|
265 * Retrieves an associative array of bulk actions available on this table. |
268 * |
266 * |
269 * @since 3.1.0 |
267 * @since 3.1.0 |
270 * |
268 * |
271 * @return array Array of bulk action labels keyed by their action. |
269 * @return array Array of bulk action labels keyed by their action. |
272 */ |
270 */ |
303 $id = 'bottom' === $which ? 'new_role2' : 'new_role'; |
301 $id = 'bottom' === $which ? 'new_role2' : 'new_role'; |
304 $button_id = 'bottom' === $which ? 'changeit2' : 'changeit'; |
302 $button_id = 'bottom' === $which ? 'changeit2' : 'changeit'; |
305 ?> |
303 ?> |
306 <div class="alignleft actions"> |
304 <div class="alignleft actions"> |
307 <?php if ( current_user_can( 'promote_users' ) && $this->has_items() ) : ?> |
305 <?php if ( current_user_can( 'promote_users' ) && $this->has_items() ) : ?> |
308 <label class="screen-reader-text" for="<?php echo $id; ?>"><?php _e( 'Change role to…' ); ?></label> |
306 <label class="screen-reader-text" for="<?php echo $id; ?>"> |
|
307 <?php |
|
308 /* translators: Hidden accessibility text. */ |
|
309 _e( 'Change role to…' ); |
|
310 ?> |
|
311 </label> |
309 <select name="<?php echo $id; ?>" id="<?php echo $id; ?>"> |
312 <select name="<?php echo $id; ?>" id="<?php echo $id; ?>"> |
310 <option value=""><?php _e( 'Change role to…' ); ?></option> |
313 <option value=""><?php _e( 'Change role to…' ); ?></option> |
311 <?php wp_dropdown_roles(); ?> |
314 <?php wp_dropdown_roles(); ?> |
312 <option value="none"><?php _e( '— No role for this site —' ); ?></option> |
315 <option value="none"><?php _e( '— No role for this site —' ); ?></option> |
313 </select> |
316 </select> |
338 */ |
341 */ |
339 do_action( 'manage_users_extra_tablenav', $which ); |
342 do_action( 'manage_users_extra_tablenav', $which ); |
340 } |
343 } |
341 |
344 |
342 /** |
345 /** |
343 * Capture the bulk action required, and return it. |
346 * Captures the bulk action required, and return it. |
344 * |
347 * |
345 * Overridden from the base class implementation to capture |
348 * Overridden from the base class implementation to capture |
346 * the role change drop-down. |
349 * the role change drop-down. |
347 * |
350 * |
348 * @since 3.1.0 |
351 * @since 3.1.0 |
349 * |
352 * |
350 * @return string The bulk action required. |
353 * @return string The bulk action required. |
351 */ |
354 */ |
352 public function current_action() { |
355 public function current_action() { |
353 if ( isset( $_REQUEST['changeit'] ) && ! empty( $_REQUEST['new_role'] ) ) { |
356 if ( isset( $_REQUEST['changeit'] ) ) { |
354 return 'promote'; |
357 return 'promote'; |
355 } |
358 } |
356 |
359 |
357 return parent::current_action(); |
360 return parent::current_action(); |
358 } |
361 } |
359 |
362 |
360 /** |
363 /** |
361 * Get a list of columns for the list table. |
364 * Gets a list of columns for the list table. |
362 * |
365 * |
363 * @since 3.1.0 |
366 * @since 3.1.0 |
364 * |
367 * |
365 * @return string[] Array of column titles keyed by their column name. |
368 * @return string[] Array of column titles keyed by their column name. |
366 */ |
369 */ |
367 public function get_columns() { |
370 public function get_columns() { |
368 $c = array( |
371 $columns = array( |
369 'cb' => '<input type="checkbox" />', |
372 'cb' => '<input type="checkbox" />', |
370 'username' => __( 'Username' ), |
373 'username' => __( 'Username' ), |
371 'name' => __( 'Name' ), |
374 'name' => __( 'Name' ), |
372 'email' => __( 'Email' ), |
375 'email' => __( 'Email' ), |
373 'role' => __( 'Role' ), |
376 'role' => __( 'Role' ), |
374 'posts' => _x( 'Posts', 'post type general name' ), |
377 'posts' => _x( 'Posts', 'post type general name' ), |
375 ); |
378 ); |
376 |
379 |
377 if ( $this->is_site_users ) { |
380 if ( $this->is_site_users ) { |
378 unset( $c['posts'] ); |
381 unset( $columns['posts'] ); |
379 } |
382 } |
380 |
383 |
381 return $c; |
384 return $columns; |
382 } |
385 } |
383 |
386 |
384 /** |
387 /** |
385 * Get a list of sortable columns for the list table. |
388 * Gets a list of sortable columns for the list table. |
386 * |
389 * |
387 * @since 3.1.0 |
390 * @since 3.1.0 |
388 * |
391 * |
389 * @return array Array of sortable columns. |
392 * @return array Array of sortable columns. |
390 */ |
393 */ |
391 protected function get_sortable_columns() { |
394 protected function get_sortable_columns() { |
392 $c = array( |
395 $columns = array( |
393 'username' => 'login', |
396 'username' => array( 'login', false, __( 'Username' ), __( 'Table ordered by Username.' ), 'asc' ), |
394 'email' => 'email', |
397 'email' => array( 'email', false, __( 'E-mail' ), __( 'Table ordered by E-mail.' ) ), |
395 ); |
398 ); |
396 |
399 |
397 return $c; |
400 return $columns; |
398 } |
401 } |
399 |
402 |
400 /** |
403 /** |
401 * Generate the list table rows. |
404 * Generates the list table rows. |
402 * |
405 * |
403 * @since 3.1.0 |
406 * @since 3.1.0 |
404 */ |
407 */ |
405 public function display_rows() { |
408 public function display_rows() { |
406 // Query the post counts for this page. |
409 // Query the post counts for this page. |
497 } |
500 } |
498 |
501 |
499 // Add a link to send the user a reset password link by email. |
502 // Add a link to send the user a reset password link by email. |
500 if ( get_current_user_id() !== $user_object->ID |
503 if ( get_current_user_id() !== $user_object->ID |
501 && current_user_can( 'edit_user', $user_object->ID ) |
504 && current_user_can( 'edit_user', $user_object->ID ) |
|
505 && true === wp_is_password_reset_allowed_for_user( $user_object ) |
502 ) { |
506 ) { |
503 $actions['resetpassword'] = "<a class='resetpassword' href='" . wp_nonce_url( "users.php?action=resetpassword&users=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Send password reset' ) . '</a>'; |
507 $actions['resetpassword'] = "<a class='resetpassword' href='" . wp_nonce_url( "users.php?action=resetpassword&users=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Send password reset' ) . '</a>'; |
504 } |
508 } |
505 |
509 |
506 /** |
510 /** |
518 // Role classes. |
522 // Role classes. |
519 $role_classes = esc_attr( implode( ' ', array_keys( $user_roles ) ) ); |
523 $role_classes = esc_attr( implode( ' ', array_keys( $user_roles ) ) ); |
520 |
524 |
521 // Set up the checkbox (because the user is editable, otherwise it's empty). |
525 // Set up the checkbox (because the user is editable, otherwise it's empty). |
522 $checkbox = sprintf( |
526 $checkbox = sprintf( |
523 '<label class="screen-reader-text" for="user_%1$s">%2$s</label>' . |
527 '<input type="checkbox" name="users[]" id="user_%1$s" class="%2$s" value="%1$s" />' . |
524 '<input type="checkbox" name="users[]" id="user_%1$s" class="%3$s" value="%1$s" />', |
528 '<label for="user_%1$s"><span class="screen-reader-text">%3$s</span></label>', |
525 $user_object->ID, |
529 $user_object->ID, |
526 /* translators: %s: User login. */ |
530 $role_classes, |
527 sprintf( __( 'Select %s' ), $user_object->user_login ), |
531 /* translators: Hidden accessibility text. %s: User login. */ |
528 $role_classes |
532 sprintf( __( 'Select %s' ), $user_object->user_login ) |
529 ); |
533 ); |
530 |
534 |
531 } else { |
535 } else { |
532 $edit = "<strong>{$user_object->user_login}{$super_admin}</strong>"; |
536 $edit = "<strong>{$user_object->user_login}{$super_admin}</strong>"; |
533 } |
537 } |
535 $avatar = get_avatar( $user_object->ID, 32 ); |
539 $avatar = get_avatar( $user_object->ID, 32 ); |
536 |
540 |
537 // Comma-separated list of user roles. |
541 // Comma-separated list of user roles. |
538 $roles_list = implode( ', ', $user_roles ); |
542 $roles_list = implode( ', ', $user_roles ); |
539 |
543 |
540 $r = "<tr id='user-$user_object->ID'>"; |
544 $row = "<tr id='user-$user_object->ID'>"; |
541 |
545 |
542 list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info(); |
546 list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info(); |
543 |
547 |
544 foreach ( $columns as $column_name => $column_display_name ) { |
548 foreach ( $columns as $column_name => $column_display_name ) { |
545 $classes = "$column_name column-$column_name"; |
549 $classes = "$column_name column-$column_name"; |
557 $data = 'data-colname="' . esc_attr( wp_strip_all_tags( $column_display_name ) ) . '"'; |
561 $data = 'data-colname="' . esc_attr( wp_strip_all_tags( $column_display_name ) ) . '"'; |
558 |
562 |
559 $attributes = "class='$classes' $data"; |
563 $attributes = "class='$classes' $data"; |
560 |
564 |
561 if ( 'cb' === $column_name ) { |
565 if ( 'cb' === $column_name ) { |
562 $r .= "<th scope='row' class='check-column'>$checkbox</th>"; |
566 $row .= "<th scope='row' class='check-column'>$checkbox</th>"; |
563 } else { |
567 } else { |
564 $r .= "<td $attributes>"; |
568 $row .= "<td $attributes>"; |
565 switch ( $column_name ) { |
569 switch ( $column_name ) { |
566 case 'username': |
570 case 'username': |
567 $r .= "$avatar $edit"; |
571 $row .= "$avatar $edit"; |
568 break; |
572 break; |
569 case 'name': |
573 case 'name': |
570 if ( $user_object->first_name && $user_object->last_name ) { |
574 if ( $user_object->first_name && $user_object->last_name ) { |
571 $r .= "$user_object->first_name $user_object->last_name"; |
575 $row .= sprintf( |
|
576 /* translators: 1: User's first name, 2: Last name. */ |
|
577 _x( '%1$s %2$s', 'Display name based on first name and last name' ), |
|
578 $user_object->first_name, |
|
579 $user_object->last_name |
|
580 ); |
572 } elseif ( $user_object->first_name ) { |
581 } elseif ( $user_object->first_name ) { |
573 $r .= $user_object->first_name; |
582 $row .= $user_object->first_name; |
574 } elseif ( $user_object->last_name ) { |
583 } elseif ( $user_object->last_name ) { |
575 $r .= $user_object->last_name; |
584 $row .= $user_object->last_name; |
576 } else { |
585 } else { |
577 $r .= sprintf( |
586 $row .= sprintf( |
578 '<span aria-hidden="true">—</span><span class="screen-reader-text">%s</span>', |
587 '<span aria-hidden="true">—</span><span class="screen-reader-text">%s</span>', |
|
588 /* translators: Hidden accessibility text. */ |
579 _x( 'Unknown', 'name' ) |
589 _x( 'Unknown', 'name' ) |
580 ); |
590 ); |
581 } |
591 } |
582 break; |
592 break; |
583 case 'email': |
593 case 'email': |
584 $r .= "<a href='" . esc_url( "mailto:$email" ) . "'>$email</a>"; |
594 $row .= "<a href='" . esc_url( "mailto:$email" ) . "'>$email</a>"; |
585 break; |
595 break; |
586 case 'role': |
596 case 'role': |
587 $r .= esc_html( $roles_list ); |
597 $row .= esc_html( $roles_list ); |
588 break; |
598 break; |
589 case 'posts': |
599 case 'posts': |
590 if ( $numposts > 0 ) { |
600 if ( $numposts > 0 ) { |
591 $r .= sprintf( |
601 $row .= sprintf( |
592 '<a href="%s" class="edit"><span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>', |
602 '<a href="%s" class="edit"><span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>', |
593 "edit.php?author={$user_object->ID}", |
603 "edit.php?author={$user_object->ID}", |
594 $numposts, |
604 $numposts, |
595 sprintf( |
605 sprintf( |
596 /* translators: %s: Number of posts. */ |
606 /* translators: Hidden accessibility text. %s: Number of posts. */ |
597 _n( '%s post by this author', '%s posts by this author', $numposts ), |
607 _n( '%s post by this author', '%s posts by this author', $numposts ), |
598 number_format_i18n( $numposts ) |
608 number_format_i18n( $numposts ) |
599 ) |
609 ) |
600 ); |
610 ); |
601 } else { |
611 } else { |
602 $r .= 0; |
612 $row .= 0; |
603 } |
613 } |
604 break; |
614 break; |
605 default: |
615 default: |
606 /** |
616 /** |
607 * Filters the display output of custom columns in the Users list table. |
617 * Filters the display output of custom columns in the Users list table. |
610 * |
620 * |
611 * @param string $output Custom column output. Default empty. |
621 * @param string $output Custom column output. Default empty. |
612 * @param string $column_name Column name. |
622 * @param string $column_name Column name. |
613 * @param int $user_id ID of the currently-listed user. |
623 * @param int $user_id ID of the currently-listed user. |
614 */ |
624 */ |
615 $r .= apply_filters( 'manage_users_custom_column', '', $column_name, $user_object->ID ); |
625 $row .= apply_filters( 'manage_users_custom_column', '', $column_name, $user_object->ID ); |
616 } |
626 } |
617 |
627 |
618 if ( $primary === $column_name ) { |
628 if ( $primary === $column_name ) { |
619 $r .= $this->row_actions( $actions ); |
629 $row .= $this->row_actions( $actions ); |
620 } |
630 } |
621 $r .= '</td>'; |
631 $row .= '</td>'; |
622 } |
632 } |
623 } |
633 } |
624 $r .= '</tr>'; |
634 $row .= '</tr>'; |
625 |
635 |
626 return $r; |
636 return $row; |
627 } |
637 } |
628 |
638 |
629 /** |
639 /** |
630 * Gets the name of the default primary column. |
640 * Gets the name of the default primary column. |
631 * |
641 * |