1 <?php |
1 <?php |
2 /** |
2 /** |
3 * Users List Table class. |
3 * Users List Table class. |
4 * |
4 * |
|
5 * @since 3.1.0 |
|
6 * @access private |
|
7 * |
5 * @package WordPress |
8 * @package WordPress |
6 * @subpackage List_Table |
9 * @subpackage List_Table |
7 * @since 3.1.0 |
|
8 * @access private |
|
9 */ |
10 */ |
10 class WP_Users_List_Table extends WP_List_Table { |
11 class WP_Users_List_Table extends WP_List_Table { |
11 |
12 |
12 var $site_id; |
13 /** |
13 var $is_site_users; |
14 * Site ID to generate the Users list table for. |
14 |
15 * |
15 function __construct( $args = array() ) { |
16 * @since 3.1.0 |
|
17 * @access public |
|
18 * @var int |
|
19 */ |
|
20 public $site_id; |
|
21 |
|
22 /** |
|
23 * Whether or not the current Users list table is for Multisite. |
|
24 * |
|
25 * @since 3.1.0 |
|
26 * @access public |
|
27 * @var bool |
|
28 */ |
|
29 public $is_site_users; |
|
30 |
|
31 /** |
|
32 * Constructor. |
|
33 * |
|
34 * @since 3.1.0 |
|
35 * @access public |
|
36 * |
|
37 * @see WP_List_Table::__construct() for more information on default arguments. |
|
38 * |
|
39 * @param array $args An associative array of arguments. |
|
40 */ |
|
41 public function __construct( $args = array() ) { |
16 parent::__construct( array( |
42 parent::__construct( array( |
17 'singular' => 'user', |
43 'singular' => 'user', |
18 'plural' => 'users', |
44 'plural' => 'users', |
19 'screen' => isset( $args['screen'] ) ? $args['screen'] : null, |
45 'screen' => isset( $args['screen'] ) ? $args['screen'] : null, |
20 ) ); |
46 ) ); |
23 |
49 |
24 if ( $this->is_site_users ) |
50 if ( $this->is_site_users ) |
25 $this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0; |
51 $this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0; |
26 } |
52 } |
27 |
53 |
28 function ajax_user_can() { |
54 /** |
|
55 * Check the current user's permissions. |
|
56 * |
|
57 * @since 3.1.0 |
|
58 * @access public |
|
59 */ |
|
60 public function ajax_user_can() { |
29 if ( $this->is_site_users ) |
61 if ( $this->is_site_users ) |
30 return current_user_can( 'manage_sites' ); |
62 return current_user_can( 'manage_sites' ); |
31 else |
63 else |
32 return current_user_can( 'list_users' ); |
64 return current_user_can( 'list_users' ); |
33 } |
65 } |
34 |
66 |
35 function prepare_items() { |
67 /** |
|
68 * Prepare the users list for display. |
|
69 * |
|
70 * @since 3.1.0 |
|
71 * @access public |
|
72 */ |
|
73 public function prepare_items() { |
36 global $role, $usersearch; |
74 global $role, $usersearch; |
37 |
75 |
38 $usersearch = isset( $_REQUEST['s'] ) ? trim( $_REQUEST['s'] ) : ''; |
76 $usersearch = isset( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST['s'] ) ) : ''; |
39 |
77 |
40 $role = isset( $_REQUEST['role'] ) ? $_REQUEST['role'] : ''; |
78 $role = isset( $_REQUEST['role'] ) ? $_REQUEST['role'] : ''; |
41 |
79 |
42 $per_page = ( $this->is_site_users ) ? 'site_users_network_per_page' : 'users_per_page'; |
80 $per_page = ( $this->is_site_users ) ? 'site_users_network_per_page' : 'users_per_page'; |
43 $users_per_page = $this->get_items_per_page( $per_page ); |
81 $users_per_page = $this->get_items_per_page( $per_page ); |
73 'total_items' => $wp_user_search->get_total(), |
111 'total_items' => $wp_user_search->get_total(), |
74 'per_page' => $users_per_page, |
112 'per_page' => $users_per_page, |
75 ) ); |
113 ) ); |
76 } |
114 } |
77 |
115 |
78 function no_items() { |
116 /** |
79 _e( 'No matching users were found.' ); |
117 * Output 'no users' message. |
80 } |
118 * |
81 |
119 * @since 3.1.0 |
82 function get_views() { |
120 * @access public |
|
121 */ |
|
122 public function no_items() { |
|
123 _e( 'No users found.' ); |
|
124 } |
|
125 |
|
126 /** |
|
127 * Return an associative array listing all the views that can be used |
|
128 * with this table. |
|
129 * |
|
130 * Provides a list of roles and user count for that role for easy |
|
131 * filtering of the user table. |
|
132 * |
|
133 * @since 3.1.0 |
|
134 * @access protected |
|
135 * |
|
136 * @return array An array of HTML links, one for each view. |
|
137 */ |
|
138 protected function get_views() { |
83 global $wp_roles, $role; |
139 global $wp_roles, $role; |
84 |
140 |
85 if ( $this->is_site_users ) { |
141 if ( $this->is_site_users ) { |
86 $url = 'site-users.php?id=' . $this->site_id; |
142 $url = 'site-users.php?id=' . $this->site_id; |
87 switch_to_blog( $this->site_id ); |
143 switch_to_blog( $this->site_id ); |
93 } |
149 } |
94 $total_users = $users_of_blog['total_users']; |
150 $total_users = $users_of_blog['total_users']; |
95 $avail_roles =& $users_of_blog['avail_roles']; |
151 $avail_roles =& $users_of_blog['avail_roles']; |
96 unset($users_of_blog); |
152 unset($users_of_blog); |
97 |
153 |
98 $current_role = false; |
|
99 $class = empty($role) ? ' class="current"' : ''; |
154 $class = empty($role) ? ' class="current"' : ''; |
100 $role_links = array(); |
155 $role_links = array(); |
101 $role_links['all'] = "<a href='$url'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_users, 'users' ), number_format_i18n( $total_users ) ) . '</a>'; |
156 $role_links['all'] = "<a href='$url'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_users, 'users' ), number_format_i18n( $total_users ) ) . '</a>'; |
102 foreach ( $wp_roles->get_names() as $this_role => $name ) { |
157 foreach ( $wp_roles->get_names() as $this_role => $name ) { |
103 if ( !isset($avail_roles[$this_role]) ) |
158 if ( !isset($avail_roles[$this_role]) ) |
104 continue; |
159 continue; |
105 |
160 |
106 $class = ''; |
161 $class = ''; |
107 |
162 |
108 if ( $this_role == $role ) { |
163 if ( $this_role == $role ) { |
109 $current_role = $role; |
|
110 $class = ' class="current"'; |
164 $class = ' class="current"'; |
111 } |
165 } |
112 |
166 |
113 $name = translate_user_role( $name ); |
167 $name = translate_user_role( $name ); |
114 /* translators: User role name with count */ |
168 /* translators: User role name with count */ |
131 } |
193 } |
132 |
194 |
133 return $actions; |
195 return $actions; |
134 } |
196 } |
135 |
197 |
136 function extra_tablenav( $which ) { |
198 /** |
|
199 * Output the controls to allow user roles to be changed in bulk. |
|
200 * |
|
201 * @since 3.1.0 |
|
202 * @access protected |
|
203 * |
|
204 * @param string $which Whether this is being invoked above ("top") |
|
205 * or below the table ("bottom"). |
|
206 */ |
|
207 protected function extra_tablenav( $which ) { |
137 if ( 'top' != $which ) |
208 if ( 'top' != $which ) |
138 return; |
209 return; |
139 ?> |
210 ?> |
140 <div class="alignleft actions"> |
211 <div class="alignleft actions"> |
141 <?php if ( current_user_can( 'promote_users' ) ) : ?> |
212 <?php if ( current_user_can( 'promote_users' ) ) : ?> |
142 <label class="screen-reader-text" for="new_role"><?php _e( 'Change role to…' ) ?></label> |
213 <label class="screen-reader-text" for="new_role"><?php _e( 'Change role to…' ) ?></label> |
143 <select name="new_role" id="new_role"> |
214 <select name="new_role" id="new_role"> |
144 <option value=''><?php _e( 'Change role to…' ) ?></option> |
215 <option value=""><?php _e( 'Change role to…' ) ?></option> |
145 <?php wp_dropdown_roles(); ?> |
216 <?php wp_dropdown_roles(); ?> |
146 </select> |
217 </select> |
147 <?php |
218 <?php |
148 submit_button( __( 'Change' ), 'button', 'changeit', false ); |
219 submit_button( __( 'Change' ), 'button', 'changeit', false ); |
149 endif; |
220 endif; |
150 |
221 |
|
222 /** |
|
223 * Fires just before the closing div containing the bulk role-change controls |
|
224 * in the Users list table. |
|
225 * |
|
226 * @since 3.5.0 |
|
227 */ |
151 do_action( 'restrict_manage_users' ); |
228 do_action( 'restrict_manage_users' ); |
152 echo '</div>'; |
229 echo '</div>'; |
153 } |
230 } |
154 |
231 |
155 function current_action() { |
232 /** |
|
233 * Capture the bulk action required, and return it. |
|
234 * |
|
235 * Overridden from the base class implementation to capture |
|
236 * the role change drop-down. |
|
237 * |
|
238 * @since 3.1.0 |
|
239 * @access public |
|
240 * |
|
241 * @return string The bulk action required. |
|
242 */ |
|
243 public function current_action() { |
156 if ( isset($_REQUEST['changeit']) && !empty($_REQUEST['new_role']) ) |
244 if ( isset($_REQUEST['changeit']) && !empty($_REQUEST['new_role']) ) |
157 return 'promote'; |
245 return 'promote'; |
158 |
246 |
159 return parent::current_action(); |
247 return parent::current_action(); |
160 } |
248 } |
161 |
249 |
162 function get_columns() { |
250 /** |
|
251 * Get a list of columns for the list table. |
|
252 * |
|
253 * @since 3.1.0 |
|
254 * @access public |
|
255 * |
|
256 * @return array Array in which the key is the ID of the column, |
|
257 * and the value is the description. |
|
258 */ |
|
259 public function get_columns() { |
163 $c = array( |
260 $c = array( |
164 'cb' => '<input type="checkbox" />', |
261 'cb' => '<input type="checkbox" />', |
165 'username' => __( 'Username' ), |
262 'username' => __( 'Username' ), |
166 'name' => __( 'Name' ), |
263 'name' => __( 'Name' ), |
167 'email' => __( 'E-mail' ), |
264 'email' => __( 'E-mail' ), |
186 unset( $c['posts'] ); |
291 unset( $c['posts'] ); |
187 |
292 |
188 return $c; |
293 return $c; |
189 } |
294 } |
190 |
295 |
191 function display_rows() { |
296 /** |
|
297 * Generate the list table rows. |
|
298 * |
|
299 * @since 3.1.0 |
|
300 * @access public |
|
301 */ |
|
302 public function display_rows() { |
192 // Query the post counts for this page |
303 // Query the post counts for this page |
193 if ( ! $this->is_site_users ) |
304 if ( ! $this->is_site_users ) |
194 $post_counts = count_many_users_posts( array_keys( $this->items ) ); |
305 $post_counts = count_many_users_posts( array_keys( $this->items ) ); |
195 |
306 |
196 $editable_roles = array_keys( get_editable_roles() ); |
307 $editable_roles = array_keys( get_editable_roles() ); |
197 |
308 |
198 $style = ''; |
|
199 foreach ( $this->items as $userid => $user_object ) { |
309 foreach ( $this->items as $userid => $user_object ) { |
200 if ( count( $user_object->roles ) <= 1 ) { |
310 if ( count( $user_object->roles ) <= 1 ) { |
201 $role = reset( $user_object->roles ); |
311 $role = reset( $user_object->roles ); |
202 } elseif ( $roles = array_intersect( array_values( $user_object->roles ), $editable_roles ) ) { |
312 } elseif ( $roles = array_intersect( array_values( $user_object->roles ), $editable_roles ) ) { |
203 $role = reset( $roles ); |
313 $role = reset( $roles ); |
206 } |
316 } |
207 |
317 |
208 if ( is_multisite() && empty( $user_object->allcaps ) ) |
318 if ( is_multisite() && empty( $user_object->allcaps ) ) |
209 continue; |
319 continue; |
210 |
320 |
211 $style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"'; |
321 echo "\n\t" . $this->single_row( $user_object, $style = '', $role, isset( $post_counts ) ? $post_counts[ $userid ] : 0 ); |
212 echo "\n\t" . $this->single_row( $user_object, $style, $role, isset( $post_counts ) ? $post_counts[ $userid ] : 0 ); |
|
213 } |
322 } |
214 } |
323 } |
215 |
324 |
216 /** |
325 /** |
217 * Generate HTML for a single row on the users.php admin panel. |
326 * Generate HTML for a single row on the users.php admin panel. |
218 * |
327 * |
219 * @since 2.1.0 |
328 * @since 3.1.0 |
220 * |
329 * @since 4.2.0 The `$style` argument was deprecated. |
221 * @param object $user_object |
330 * @access public |
222 * @param string $style Optional. Attributes added to the TR element. Must be sanitized. |
331 * |
223 * @param string $role Key for the $wp_roles array. |
332 * @global WP_Roles $wp_roles User roles object. |
224 * @param int $numposts Optional. Post count to display for this user. Defaults to zero, as in, a new user has made zero posts. |
333 * |
225 * @return string |
334 * @param object $user_object The current user object. |
226 */ |
335 * @param string $style Deprecated. Not used. |
227 function single_row( $user_object, $style = '', $role = '', $numposts = 0 ) { |
336 * @param string $role Optional. Key for the $wp_roles array. Default empty. |
|
337 * @param int $numposts Optional. Post count to display for this user. Defaults |
|
338 * to zero, as in, a new user has made zero posts. |
|
339 * @return string Output for a single row. |
|
340 */ |
|
341 public function single_row( $user_object, $style = '', $role = '', $numposts = 0 ) { |
228 global $wp_roles; |
342 global $wp_roles; |
229 |
343 |
230 if ( !( is_object( $user_object ) && is_a( $user_object, 'WP_User' ) ) ) |
344 if ( ! ( $user_object instanceof WP_User ) ) { |
231 $user_object = get_userdata( (int) $user_object ); |
345 $user_object = get_userdata( (int) $user_object ); |
|
346 } |
232 $user_object->filter = 'display'; |
347 $user_object->filter = 'display'; |
233 $email = $user_object->user_email; |
348 $email = $user_object->user_email; |
234 |
349 |
235 if ( $this->is_site_users ) |
350 if ( $this->is_site_users ) |
236 $url = "site-users.php?id={$this->site_id}&"; |
351 $url = "site-users.php?id={$this->site_id}&"; |
255 |
370 |
256 if ( !is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'delete_user', $user_object->ID ) ) |
371 if ( !is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'delete_user', $user_object->ID ) ) |
257 $actions['delete'] = "<a class='submitdelete' href='" . wp_nonce_url( "users.php?action=delete&user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Delete' ) . "</a>"; |
372 $actions['delete'] = "<a class='submitdelete' href='" . wp_nonce_url( "users.php?action=delete&user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Delete' ) . "</a>"; |
258 if ( is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'remove_user', $user_object->ID ) ) |
373 if ( is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'remove_user', $user_object->ID ) ) |
259 $actions['remove'] = "<a class='submitdelete' href='" . wp_nonce_url( $url."action=remove&user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Remove' ) . "</a>"; |
374 $actions['remove'] = "<a class='submitdelete' href='" . wp_nonce_url( $url."action=remove&user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Remove' ) . "</a>"; |
|
375 |
|
376 /** |
|
377 * Filter the action links displayed under each user in the Users list table. |
|
378 * |
|
379 * @since 2.8.0 |
|
380 * |
|
381 * @param array $actions An array of action links to be displayed. |
|
382 * Default 'Edit', 'Delete' for single site, and |
|
383 * 'Edit', 'Remove' for Multisite. |
|
384 * @param WP_User $user_object WP_User object for the currently-listed user. |
|
385 */ |
260 $actions = apply_filters( 'user_row_actions', $actions, $user_object ); |
386 $actions = apply_filters( 'user_row_actions', $actions, $user_object ); |
261 $edit .= $this->row_actions( $actions ); |
387 $edit .= $this->row_actions( $actions ); |
262 |
388 |
263 // Set up the checkbox ( because the user is editable, otherwise it's empty ) |
389 // Set up the checkbox ( because the user is editable, otherwise it's empty ) |
264 $checkbox = '<label class="screen-reader-text" for="cb-select-' . $user_object->ID . '">' . sprintf( __( 'Select %s' ), $user_object->user_login ) . '</label>' |
390 $checkbox = '<label class="screen-reader-text" for="user_' . $user_object->ID . '">' . sprintf( __( 'Select %s' ), $user_object->user_login ) . '</label>' |
265 . "<input type='checkbox' name='users[]' id='user_{$user_object->ID}' class='$role' value='{$user_object->ID}' />"; |
391 . "<input type='checkbox' name='users[]' id='user_{$user_object->ID}' class='$role' value='{$user_object->ID}' />"; |
266 |
392 |
267 } else { |
393 } else { |
268 $edit = '<strong>' . $user_object->user_login . '</strong>'; |
394 $edit = '<strong>' . $user_object->user_login . '</strong>'; |
269 } |
395 } |
270 $role_name = isset( $wp_roles->role_names[$role] ) ? translate_user_role( $wp_roles->role_names[$role] ) : __( 'None' ); |
396 $role_name = isset( $wp_roles->role_names[$role] ) ? translate_user_role( $wp_roles->role_names[$role] ) : __( 'None' ); |
271 $avatar = get_avatar( $user_object->ID, 32 ); |
397 $avatar = get_avatar( $user_object->ID, 32 ); |
272 |
398 |
273 $r = "<tr id='user-$user_object->ID'$style>"; |
399 $r = "<tr id='user-$user_object->ID'>"; |
274 |
400 |
275 list( $columns, $hidden ) = $this->get_column_info(); |
401 list( $columns, $hidden ) = $this->get_column_info(); |
276 |
402 |
277 foreach ( $columns as $column_name => $column_display_name ) { |
403 foreach ( $columns as $column_name => $column_display_name ) { |
278 $class = "class=\"$column_name column-$column_name\""; |
404 $class = "class=\"$column_name column-$column_name\""; |