| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * List Table API: WP_MS_Users_List_Table class 4 * 5 * @package WordPress 6 * @subpackage Administration 7 * @since 3.1.0 8 */ 9 10 /** 11 * Core class used to implement displaying users in a list table for the network admin. 12 * 13 * @since 3.1.0 14 * 15 * @see WP_List_Table 16 */ 17 class WP_MS_Users_List_Table extends WP_List_Table { 18 /** 19 * Checks if the current user has permissions to perform an Ajax action. 20 * 21 * @since 3.1.0 22 * 23 * @return bool Whether the current user can perform an Ajax action. 24 */ 25 public function ajax_user_can() { 26 return current_user_can( 'manage_network_users' ); 27 } 28 29 /** 30 * Prepares the users list for display. 31 * 32 * @since 3.1.0 33 * 34 * @global string $usersearch User search query. 35 * @global string $role The user role to filter by. Only 'super' (super admins) is supported. 36 */ 37 public function prepare_items() { 38 global $usersearch, $role; 39 40 $usersearch = isset( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST['s'] ) ) : ''; 41 42 $users_per_page = $this->get_items_per_page( 'users_network_per_page' ); 43 44 $role = $_REQUEST['role'] ?? ''; 45 46 $paged = $this->get_pagenum(); 47 48 $args = array( 49 'number' => $users_per_page, 50 'offset' => ( $paged - 1 ) * $users_per_page, 51 'search' => $usersearch, 52 'blog_id' => 0, 53 'fields' => 'all_with_meta', 54 ); 55 56 if ( wp_is_large_network( 'users' ) ) { 57 $args['search'] = ltrim( $args['search'], '*' ); 58 } elseif ( '' !== $args['search'] ) { 59 $args['search'] = trim( $args['search'], '*' ); 60 $args['search'] = '*' . $args['search'] . '*'; 61 } 62 63 if ( 'super' === $role ) { 64 $args['login__in'] = get_super_admins(); 65 } 66 67 /* 68 * If the network is large and a search is not being performed, 69 * show only the latest users with no paging in order to avoid 70 * expensive count queries. 71 */ 72 if ( ! $usersearch && wp_is_large_network( 'users' ) ) { 73 if ( ! isset( $_REQUEST['orderby'] ) ) { 74 $_GET['orderby'] = 'id'; 75 $_REQUEST['orderby'] = 'id'; 76 } 77 if ( ! isset( $_REQUEST['order'] ) ) { 78 $_GET['order'] = 'DESC'; 79 $_REQUEST['order'] = 'DESC'; 80 } 81 $args['count_total'] = false; 82 } 83 84 if ( isset( $_REQUEST['orderby'] ) ) { 85 $args['orderby'] = $_REQUEST['orderby']; 86 } 87 88 if ( isset( $_REQUEST['order'] ) ) { 89 $args['order'] = $_REQUEST['order']; 90 } 91 92 /** This filter is documented in wp-admin/includes/class-wp-users-list-table.php */ 93 $args = apply_filters( 'users_list_table_query_args', $args ); 94 95 // Query the user IDs for this page. 96 $wp_user_search = new WP_User_Query( $args ); 97 98 $this->items = $wp_user_search->get_results(); 99 100 $this->set_pagination_args( 101 array( 102 'total_items' => $wp_user_search->get_total(), 103 'per_page' => $users_per_page, 104 ) 105 ); 106 } 107 108 /** 109 * Gets the available bulk actions for the users list table. 110 * 111 * @since 3.1.0 112 * 113 * @return array<string, string> Bulk action labels keyed by action name. 114 */ 115 protected function get_bulk_actions() { 116 $actions = array(); 117 if ( current_user_can( 'delete_users' ) ) { 118 $actions['delete'] = __( 'Delete' ); 119 } 120 $actions['spam'] = _x( 'Mark as spam', 'user' ); 121 $actions['notspam'] = _x( 'Not spam', 'user' ); 122 123 return $actions; 124 } 125 126 /** 127 * Displays a message when there are no items. 128 * 129 * @since 3.1.0 130 */ 131 public function no_items() { 132 _e( 'No users found.' ); 133 } 134 135 /** 136 * Gets the list of views (all, super admin) available for the users list table. 137 * 138 * @since 3.1.0 139 * 140 * @global string $role The user role to filter by. Only 'super' (super admins) is supported. 141 * 142 * @return array<string, string> View link markup keyed by view name ('all' or 'super'). 143 */ 144 protected function get_views() { 145 global $role; 146 147 $total_users = get_user_count(); 148 $super_admins = get_super_admins(); 149 $total_admins = count( $super_admins ); 150 151 $role_links = array(); 152 $role_links['all'] = array( 153 'url' => network_admin_url( 'users.php' ), 154 'label' => sprintf( 155 /* translators: Number of users. */ 156 _nx( 157 'All <span class="count">(%s)</span>', 158 'All <span class="count">(%s)</span>', 159 $total_users, 160 'users' 161 ), 162 number_format_i18n( $total_users ) 163 ), 164 'current' => 'super' !== $role, 165 ); 166 167 $role_links['super'] = array( 168 'url' => network_admin_url( 'users.php?role=super' ), 169 'label' => sprintf( 170 /* translators: Number of users. */ 171 _n( 172 'Super Admin <span class="count">(%s)</span>', 173 'Super Admins <span class="count">(%s)</span>', 174 $total_admins 175 ), 176 number_format_i18n( $total_admins ) 177 ), 178 'current' => 'super' === $role, 179 ); 180 181 return $this->get_views_links( $role_links ); 182 } 183 184 /** 185 * Gets the list of columns for the users list table. 186 * 187 * @since 3.1.0 188 * 189 * @return array<string, string> Array of column titles keyed by their column name. 190 */ 191 public function get_columns() { 192 $users_columns = array( 193 'cb' => '<input type="checkbox" />', 194 'username' => __( 'Username' ), 195 'name' => __( 'Name' ), 196 'email' => __( 'Email' ), 197 'registered' => _x( 'Registered', 'user' ), 198 'blogs' => __( 'Sites' ), 199 ); 200 /** 201 * Filters the columns displayed in the Network Admin Users list table. 202 * 203 * @since MU (3.0.0) 204 * 205 * @param array<string, string> $users_columns Column titles keyed by column name. Default keys are 'cb', 206 * 'username', 'name', 'email', 'registered', and 'blogs'. 207 */ 208 return apply_filters( 'wpmu_users_columns', $users_columns ); 209 } 210 211 /** 212 * Gets the list of sortable columns for the users list table. 213 * 214 * @since 3.1.0 215 * 216 * @return array<string, array<int, string|bool>> Sortable columns. 217 * 218 * @phpstan-return array<string, array{0: string, 1: bool, 2: string, 3: string, 4?: 'asc'|'desc'}> 219 */ 220 protected function get_sortable_columns() { 221 return array( 222 'username' => array( 'login', false, __( 'Username' ), __( 'Table ordered by Username.' ), 'asc' ), 223 'name' => array( 'name', false, __( 'Name' ), __( 'Table ordered by Name.' ) ), 224 'email' => array( 'email', false, __( 'E-mail' ), __( 'Table ordered by E-mail.' ) ), 225 'registered' => array( 'id', false, _x( 'Registered', 'user' ), __( 'Table ordered by User Registered Date.' ) ), 226 ); 227 } 228 229 /** 230 * Handles the checkbox column output. 231 * 232 * @since 4.3.0 233 * @since 5.9.0 Renamed `$user` to `$item` to match parent class for PHP 8 named parameter support. 234 * 235 * @param WP_User $item The current WP_User object. 236 */ 237 public function column_cb( $item ) { 238 // Restores the more descriptive, specific name for use within this method. 239 $user = $item; 240 241 if ( is_super_admin( $user->ID ) ) { 242 return; 243 } 244 ?> 245 <input type="checkbox" id="blog_<?php echo $user->ID; ?>" name="allusers[]" value="<?php echo esc_attr( $user->ID ); ?>" /> 246 <label for="blog_<?php echo $user->ID; ?>"> 247 <span class="screen-reader-text"> 248 <?php 249 /* translators: Hidden accessibility text. %s: User login. */ 250 printf( __( 'Select %s' ), esc_html( $user->user_login ) ); 251 ?> 252 </span> 253 </label> 254 <?php 255 } 256 257 /** 258 * Handles the ID column output. 259 * 260 * @since 4.4.0 261 * 262 * @param WP_User $user The current WP_User object. 263 */ 264 public function column_id( $user ) { 265 echo $user->ID; 266 } 267 268 /** 269 * Handles the username column output. 270 * 271 * @since 4.3.0 272 * 273 * @param WP_User $user The current WP_User object. 274 */ 275 public function column_username( $user ) { 276 $super_admins = get_super_admins(); 277 $avatar = get_avatar( $user->user_email, 32 ); 278 279 echo $avatar; 280 281 if ( current_user_can( 'edit_user', $user->ID ) ) { 282 $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user->ID ) ) ); 283 $edit = "<a href=\"{$edit_link}\">" . esc_html( $user->user_login ) . '</a>'; 284 } else { 285 $edit = esc_html( $user->user_login ); 286 } 287 288 ?> 289 <strong> 290 <?php 291 echo $edit; 292 293 if ( in_array( $user->user_login, $super_admins, true ) ) { 294 echo ' — ' . __( 'Super Admin' ); 295 } 296 ?> 297 </strong> 298 <?php 299 } 300 301 /** 302 * Handles the name column output. 303 * 304 * @since 4.3.0 305 * 306 * @param WP_User $user The current WP_User object. 307 */ 308 public function column_name( $user ) { 309 if ( $user->first_name && $user->last_name ) { 310 printf( 311 /* translators: 1: User's first name, 2: Last name. */ 312 _x( '%1$s %2$s', 'Display name based on first name and last name' ), 313 $user->first_name, 314 $user->last_name 315 ); 316 } elseif ( $user->first_name ) { 317 echo $user->first_name; 318 } elseif ( $user->last_name ) { 319 echo $user->last_name; 320 } else { 321 echo '<span aria-hidden="true">—</span><span class="screen-reader-text">' . 322 /* translators: Hidden accessibility text. */ 323 _x( 'Unknown', 'name' ) . 324 '</span>'; 325 } 326 } 327 328 /** 329 * Handles the email column output. 330 * 331 * @since 4.3.0 332 * 333 * @param WP_User $user The current WP_User object. 334 */ 335 public function column_email( $user ) { 336 echo "<a href='" . esc_url( "mailto:$user->user_email" ) . "'>$user->user_email</a>"; 337 } 338 339 /** 340 * Handles the registered date column output. 341 * 342 * @since 4.3.0 343 * 344 * @param WP_User $user The current WP_User object. 345 */ 346 public function column_registered( $user ) { 347 echo mysql2date( __( 'Y/m/d g:i:s a' ), $user->user_registered ); 348 } 349 350 /** 351 * Outputs the sites column content. 352 * 353 * @since 4.3.0 354 * 355 * @param WP_User $user The current WP_User object. 356 * @param string $classes CSS classes for the cell. 357 * @param string $data Custom data attributes for the cell. 358 * @param string $primary The primary column name. 359 */ 360 protected function _column_blogs( $user, $classes, $data, $primary ) { 361 echo '<td class="', $classes, ' has-row-actions" ', $data, '>'; 362 echo $this->column_blogs( $user ); 363 echo $this->handle_row_actions( $user, 'blogs', $primary ); 364 echo '</td>'; 365 } 366 367 /** 368 * Handles the sites column output. 369 * 370 * @since 4.3.0 371 * 372 * @param WP_User $user The current WP_User object. 373 */ 374 public function column_blogs( $user ) { 375 $blogs = get_blogs_of_user( $user->ID, true ); 376 if ( ! is_array( $blogs ) ) { 377 return; 378 } 379 380 foreach ( $blogs as $site ) { 381 if ( ! can_edit_network( $site->site_id ) ) { 382 continue; 383 } 384 385 $path = ( '/' === $site->path ) ? '' : $site->path; 386 $site_classes = array( 'site-' . $site->site_id ); 387 388 /** 389 * Filters the span class for a site listing on the multisite user list table. 390 * 391 * @since 5.2.0 392 * 393 * @param string[] $site_classes Array of class names used within the span tag. 394 * Default "site-#" with the site's network ID. 395 * @param int $site_id Site ID. 396 * @param int $network_id Network ID. 397 * @param WP_User $user WP_User object. 398 */ 399 $site_classes = apply_filters( 'ms_user_list_site_class', $site_classes, $site->userblog_id, $site->site_id, $user ); 400 401 if ( is_array( $site_classes ) && ! empty( $site_classes ) ) { 402 $site_classes = array_map( 'sanitize_html_class', array_unique( $site_classes ) ); 403 echo '<span class="' . esc_attr( implode( ' ', $site_classes ) ) . '">'; 404 } else { 405 echo '<span>'; 406 } 407 408 echo '<a href="' . esc_url( network_admin_url( 'site-info.php?id=' . $site->userblog_id ) ) . '">' . str_replace( '.' . get_network()->domain, '', $site->domain . $path ) . '</a>'; 409 echo ' <small class="row-actions">'; 410 411 $actions = array(); 412 $actions['edit'] = '<a href="' . esc_url( network_admin_url( 'site-info.php?id=' . $site->userblog_id ) ) . '">' . __( 'Edit' ) . '</a>'; 413 414 $class = ''; 415 if ( 1 === (int) $site->spam ) { 416 $class .= 'site-spammed '; 417 } 418 if ( 1 === (int) $site->mature ) { 419 $class .= 'site-mature '; 420 } 421 if ( 1 === (int) $site->deleted ) { 422 $class .= 'site-deleted '; 423 } 424 if ( 1 === (int) $site->archived ) { 425 $class .= 'site-archived '; 426 } 427 428 $actions['view'] = '<a class="' . $class . '" href="' . esc_url( get_home_url( $site->userblog_id ) ) . '">' . __( 'View' ) . '</a>'; 429 430 /** 431 * Filters the action links displayed next the sites a user belongs to 432 * in the Network Admin Users list table. 433 * 434 * @since 3.1.0 435 * 436 * @param string[] $actions An array of action links to be displayed. Default 'Edit', 'View'. 437 * @param int $userblog_id The site ID. 438 */ 439 $actions = apply_filters( 'ms_user_list_site_actions', $actions, $site->userblog_id ); 440 441 $action_count = count( $actions ); 442 443 $i = 0; 444 445 foreach ( $actions as $action => $link ) { 446 ++$i; 447 448 $separator = ( $i < $action_count ) ? ' | ' : ''; 449 450 echo "<span class='$action'>{$link}{$separator}</span>"; 451 } 452 453 echo '</small></span><br />'; 454 } 455 } 456 457 /** 458 * Handles the default column output. 459 * 460 * @since 4.3.0 461 * @since 5.9.0 Renamed `$user` to `$item` to match parent class for PHP 8 named parameter support. 462 * 463 * @param WP_User $item The current WP_User object. 464 * @param string $column_name The current column name. 465 */ 466 public function column_default( $item, $column_name ) { 467 // Restores the more descriptive, specific name for use within this method. 468 $user = $item; 469 470 /** This filter is documented in wp-admin/includes/class-wp-users-list-table.php */ 471 $column_output = apply_filters( 'manage_users_custom_column', '', $column_name, $user->ID ); 472 473 /** 474 * Filters the display output of custom columns in the Network Users list table. 475 * 476 * @since 6.8.0 477 * 478 * @param string $output Custom column output. Default empty. 479 * @param string $column_name Name of the custom column. 480 * @param int $user_id ID of the currently-listed user. 481 */ 482 echo apply_filters( 'manage_users-network_custom_column', $column_output, $column_name, $user->ID ); 483 } 484 485 /** 486 * Generates the list table rows. 487 * 488 * @since 3.1.0 489 */ 490 public function display_rows() { 491 foreach ( $this->items as $user ) { 492 $class = ''; 493 494 $status_list = array( 495 'spam' => 'site-spammed', 496 'deleted' => 'site-deleted', 497 ); 498 499 foreach ( $status_list as $status => $col ) { 500 if ( $user->$status ) { 501 $class .= " $col"; 502 } 503 } 504 505 ?> 506 <tr id="user-<?php echo (int) $user->ID; ?>" class="<?php echo trim( $class ); ?>"> 507 <?php $this->single_row_columns( $user ); ?> 508 </tr> 509 <?php 510 } 511 } 512 513 /** 514 * Gets the name of the default primary column. 515 * 516 * @since 4.3.0 517 * 518 * @return string Name of the default primary column, in this case, 'username'. 519 */ 520 protected function get_default_primary_column_name() { 521 return 'username'; 522 } 523 524 /** 525 * Generates and displays row action links. 526 * 527 * @since 4.3.0 528 * @since 5.9.0 Renamed `$user` to `$item` to match parent class for PHP 8 named parameter support. 529 * 530 * @param WP_User $item User being acted upon. 531 * @param string $column_name Current column name. 532 * @param string $primary Primary column name. 533 * @return string Row actions output for users in Multisite, or an empty string 534 * if the current column is not the primary column. 535 */ 536 protected function handle_row_actions( $item, $column_name, $primary ) { 537 if ( $primary !== $column_name ) { 538 return ''; 539 } 540 541 // Restores the more descriptive, specific name for use within this method. 542 $user = $item; 543 544 $super_admins = get_super_admins(); 545 $actions = array(); 546 547 if ( current_user_can( 'edit_user', $user->ID ) ) { 548 $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user->ID ) ) ); 549 $actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>'; 550 } 551 552 if ( current_user_can( 'delete_user', $user->ID ) && ! in_array( $user->user_login, $super_admins, true ) ) { 553 $actions['delete'] = '<a href="' . esc_url( network_admin_url( add_query_arg( '_wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), wp_nonce_url( 'users.php', 'deleteuser' ) . '&action=deleteuser&id=' . $user->ID ) ) ) . '" class="delete">' . __( 'Delete' ) . '</a>'; 554 } 555 556 /** 557 * Filters the action links displayed under each user in the Network Admin Users list table. 558 * 559 * @since 3.2.0 560 * 561 * @param string[] $actions An array of action links to be displayed. Default 'Edit', 'Delete'. 562 * @param WP_User $user WP_User object. 563 */ 564 $actions = apply_filters( 'ms_user_row_actions', $actions, $user ); 565 566 return $this->row_actions( $actions ); 567 } 568 569 /** 570 * Returns a clean label for the primary (Username) column's row header `aria-label`. 571 * 572 * Provides screen readers with just the user login as the row header name, 573 * preventing them from computing the name from the full cell content. 574 * 575 * @since 7.1.0 576 * 577 * @param WP_User $user The current WP_User object. 578 * @return string The user login. 579 */ 580 protected function get_primary_column_aria_label( $user ) { 581 return $user->user_login; 582 } 583 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Sun Nov 8 08:20:01 2026 | Cross-referenced by PHPXref |