~canonical-sysadmins/wordpress/4.7.2

« back to all changes in this revision

Viewing changes to wp-admin/includes/class-wp-users-list-table.php

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Users List Table class.
 
4
 *
 
5
 * @since 3.1.0
 
6
 * @access private
 
7
 *
 
8
 * @package WordPress
 
9
 * @subpackage List_Table
 
10
 */
 
11
class WP_Users_List_Table extends WP_List_Table {
 
12
 
 
13
        /**
 
14
         * Site ID to generate the Users list table for.
 
15
         *
 
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() ) {
 
42
                parent::__construct( array(
 
43
                        'singular' => 'user',
 
44
                        'plural'   => 'users',
 
45
                        'screen'   => isset( $args['screen'] ) ? $args['screen'] : null,
 
46
                ) );
 
47
 
 
48
                $this->is_site_users = 'site-users-network' == $this->screen->id;
 
49
 
 
50
                if ( $this->is_site_users )
 
51
                        $this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
 
52
        }
 
53
 
 
54
        /**
 
55
         * Check the current user's permissions.
 
56
         *
 
57
         * @since 3.1.0
 
58
         * @access public
 
59
         */
 
60
        public function ajax_user_can() {
 
61
                if ( $this->is_site_users )
 
62
                        return current_user_can( 'manage_sites' );
 
63
                else
 
64
                        return current_user_can( 'list_users' );
 
65
        }
 
66
 
 
67
        /**
 
68
         * Prepare the users list for display.
 
69
         *
 
70
         * @since 3.1.0
 
71
         * @access public
 
72
         */
 
73
        public function prepare_items() {
 
74
                global $role, $usersearch;
 
75
 
 
76
                $usersearch = isset( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST['s'] ) ) : '';
 
77
 
 
78
                $role = isset( $_REQUEST['role'] ) ? $_REQUEST['role'] : '';
 
79
 
 
80
                $per_page = ( $this->is_site_users ) ? 'site_users_network_per_page' : 'users_per_page';
 
81
                $users_per_page = $this->get_items_per_page( $per_page );
 
82
 
 
83
                $paged = $this->get_pagenum();
 
84
 
 
85
                $args = array(
 
86
                        'number' => $users_per_page,
 
87
                        'offset' => ( $paged-1 ) * $users_per_page,
 
88
                        'role' => $role,
 
89
                        'search' => $usersearch,
 
90
                        'fields' => 'all_with_meta'
 
91
                );
 
92
 
 
93
                if ( '' !== $args['search'] )
 
94
                        $args['search'] = '*' . $args['search'] . '*';
 
95
 
 
96
                if ( $this->is_site_users )
 
97
                        $args['blog_id'] = $this->site_id;
 
98
 
 
99
                if ( isset( $_REQUEST['orderby'] ) )
 
100
                        $args['orderby'] = $_REQUEST['orderby'];
 
101
 
 
102
                if ( isset( $_REQUEST['order'] ) )
 
103
                        $args['order'] = $_REQUEST['order'];
 
104
 
 
105
                // Query the user IDs for this page
 
106
                $wp_user_search = new WP_User_Query( $args );
 
107
 
 
108
                $this->items = $wp_user_search->get_results();
 
109
 
 
110
                $this->set_pagination_args( array(
 
111
                        'total_items' => $wp_user_search->get_total(),
 
112
                        'per_page' => $users_per_page,
 
113
                ) );
 
114
        }
 
115
 
 
116
        /**
 
117
         * Output 'no users' message.
 
118
         *
 
119
         * @since 3.1.0
 
120
         * @access public
 
121
         */
 
122
        public function no_items() {
 
123
                _e( 'No matching users were 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() {
 
139
                global $wp_roles, $role;
 
140
 
 
141
                if ( $this->is_site_users ) {
 
142
                        $url = 'site-users.php?id=' . $this->site_id;
 
143
                        switch_to_blog( $this->site_id );
 
144
                        $users_of_blog = count_users();
 
145
                        restore_current_blog();
 
146
                } else {
 
147
                        $url = 'users.php';
 
148
                        $users_of_blog = count_users();
 
149
                }
 
150
                $total_users = $users_of_blog['total_users'];
 
151
                $avail_roles =& $users_of_blog['avail_roles'];
 
152
                unset($users_of_blog);
 
153
 
 
154
                $class = empty($role) ? ' class="current"' : '';
 
155
                $role_links = array();
 
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>';
 
157
                foreach ( $wp_roles->get_names() as $this_role => $name ) {
 
158
                        if ( !isset($avail_roles[$this_role]) )
 
159
                                continue;
 
160
 
 
161
                        $class = '';
 
162
 
 
163
                        if ( $this_role == $role ) {
 
164
                                $class = ' class="current"';
 
165
                        }
 
166
 
 
167
                        $name = translate_user_role( $name );
 
168
                        /* translators: User role name with count */
 
169
                        $name = sprintf( __('%1$s <span class="count">(%2$s)</span>'), $name, number_format_i18n( $avail_roles[$this_role] ) );
 
170
                        $role_links[$this_role] = "<a href='" . esc_url( add_query_arg( 'role', $this_role, $url ) ) . "'$class>$name</a>";
 
171
                }
 
172
 
 
173
                return $role_links;
 
174
        }
 
175
 
 
176
        /**
 
177
         * Retrieve an associative array of bulk actions available on this table.
 
178
         *
 
179
         * @since  3.1.0
 
180
         * @access protected
 
181
         *
 
182
         * @return array Array of bulk actions.
 
183
         */
 
184
        protected function get_bulk_actions() {
 
185
                $actions = array();
 
186
 
 
187
                if ( is_multisite() ) {
 
188
                        if ( current_user_can( 'remove_users' ) )
 
189
                                $actions['remove'] = __( 'Remove' );
 
190
                } else {
 
191
                        if ( current_user_can( 'delete_users' ) )
 
192
                                $actions['delete'] = __( 'Delete' );
 
193
                }
 
194
 
 
195
                return $actions;
 
196
        }
 
197
 
 
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 ) {
 
208
                if ( 'top' != $which )
 
209
                        return;
 
210
        ?>
 
211
        <div class="alignleft actions">
 
212
                <?php if ( current_user_can( 'promote_users' ) ) : ?>
 
213
                <label class="screen-reader-text" for="new_role"><?php _e( 'Change role to&hellip;' ) ?></label>
 
214
                <select name="new_role" id="new_role">
 
215
                        <option value=""><?php _e( 'Change role to&hellip;' ) ?></option>
 
216
                        <?php wp_dropdown_roles(); ?>
 
217
                </select>
 
218
        <?php
 
219
                        submit_button( __( 'Change' ), 'button', 'changeit', false );
 
220
                endif;
 
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
                 */
 
228
                do_action( 'restrict_manage_users' );
 
229
                echo '</div>';
 
230
        }
 
231
 
 
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() {
 
244
                if ( isset($_REQUEST['changeit']) && !empty($_REQUEST['new_role']) )
 
245
                        return 'promote';
 
246
 
 
247
                return parent::current_action();
 
248
        }
 
249
 
 
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() {
 
260
                $c = array(
 
261
                        'cb'       => '<input type="checkbox" />',
 
262
                        'username' => __( 'Username' ),
 
263
                        'name'     => __( 'Name' ),
 
264
                        'email'    => __( 'E-mail' ),
 
265
                        'role'     => __( 'Role' ),
 
266
                        'posts'    => __( 'Posts' )
 
267
                );
 
268
 
 
269
                if ( $this->is_site_users )
 
270
                        unset( $c['posts'] );
 
271
 
 
272
                return $c;
 
273
        }
 
274
 
 
275
        /**
 
276
         * Get a list of sortable columns for the list table.
 
277
         *
 
278
         * @since 3.1.0
 
279
         * @access protected
 
280
         *
 
281
         * @return array Array of sortable columns.
 
282
         */
 
283
        protected function get_sortable_columns() {
 
284
                $c = array(
 
285
                        'username' => 'login',
 
286
                        'name'     => 'name',
 
287
                        'email'    => 'email',
 
288
                );
 
289
 
 
290
                if ( $this->is_site_users )
 
291
                        unset( $c['posts'] );
 
292
 
 
293
                return $c;
 
294
        }
 
295
 
 
296
        /**
 
297
         * Generate the list table rows.
 
298
         *
 
299
         * @since 3.1.0
 
300
         * @access public
 
301
         */
 
302
        public function display_rows() {
 
303
                // Query the post counts for this page
 
304
                if ( ! $this->is_site_users )
 
305
                        $post_counts = count_many_users_posts( array_keys( $this->items ) );
 
306
 
 
307
                $editable_roles = array_keys( get_editable_roles() );
 
308
 
 
309
                $style = '';
 
310
                foreach ( $this->items as $userid => $user_object ) {
 
311
                        if ( count( $user_object->roles ) <= 1 ) {
 
312
                                $role = reset( $user_object->roles );
 
313
                        } elseif ( $roles = array_intersect( array_values( $user_object->roles ), $editable_roles ) ) {
 
314
                                $role = reset( $roles );
 
315
                        } else {
 
316
                                $role = reset( $user_object->roles );
 
317
                        }
 
318
 
 
319
                        if ( is_multisite() && empty( $user_object->allcaps ) )
 
320
                                continue;
 
321
 
 
322
                        $style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"';
 
323
                        echo "\n\t" . $this->single_row( $user_object, $style, $role, isset( $post_counts ) ? $post_counts[ $userid ] : 0 );
 
324
                }
 
325
        }
 
326
 
 
327
        /**
 
328
         * Generate HTML for a single row on the users.php admin panel.
 
329
         *
 
330
         * @since 3.1.0
 
331
         * @access public
 
332
         *
 
333
         * @param object $user_object The current user object.
 
334
         * @param string $style       Optional. Style attributes added to the <tr> element.
 
335
         *                            Must be sanitized. Default empty.
 
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 ) {
 
342
                global $wp_roles;
 
343
 
 
344
                if ( !( is_object( $user_object ) && is_a( $user_object, 'WP_User' ) ) )
 
345
                        $user_object = get_userdata( (int) $user_object );
 
346
                $user_object->filter = 'display';
 
347
                $email = $user_object->user_email;
 
348
 
 
349
                if ( $this->is_site_users )
 
350
                        $url = "site-users.php?id={$this->site_id}&amp;";
 
351
                else
 
352
                        $url = 'users.php?';
 
353
 
 
354
                $checkbox = '';
 
355
                // Check if the user for this row is editable
 
356
                if ( current_user_can( 'list_users' ) ) {
 
357
                        // Set up the user editing link
 
358
                        $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user_object->ID ) ) );
 
359
 
 
360
                        // Set up the hover actions for this user
 
361
                        $actions = array();
 
362
 
 
363
                        if ( current_user_can( 'edit_user',  $user_object->ID ) ) {
 
364
                                $edit = "<strong><a href=\"$edit_link\">$user_object->user_login</a></strong><br />";
 
365
                                $actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>';
 
366
                        } else {
 
367
                                $edit = "<strong>$user_object->user_login</strong><br />";
 
368
                        }
 
369
 
 
370
                        if ( !is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'delete_user', $user_object->ID ) )
 
371
                                $actions['delete'] = "<a class='submitdelete' href='" . wp_nonce_url( "users.php?action=delete&amp;user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Delete' ) . "</a>";
 
372
                        if ( is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'remove_user', $user_object->ID ) )
 
373
                                $actions['remove'] = "<a class='submitdelete' href='" . wp_nonce_url( $url."action=remove&amp;user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Remove' ) . "</a>";
 
374
 
 
375
                        /**
 
376
                         * Filter the action links displayed under each user in the Users list table.
 
377
                         *
 
378
                         * @since 2.8.0
 
379
                         *
 
380
                         * @param array   $actions     An array of action links to be displayed.
 
381
                         *                             Default 'Edit', 'Delete' for single site, and
 
382
                         *                             'Edit', 'Remove' for Multisite.
 
383
                         * @param WP_User $user_object WP_User object for the currently-listed user.
 
384
                         */
 
385
                        $actions = apply_filters( 'user_row_actions', $actions, $user_object );
 
386
                        $edit .= $this->row_actions( $actions );
 
387
 
 
388
                        // Set up the checkbox ( because the user is editable, otherwise it's empty )
 
389
                        $checkbox = '<label class="screen-reader-text" for="cb-select-' . $user_object->ID . '">' . sprintf( __( 'Select %s' ), $user_object->user_login ) . '</label>'
 
390
                                                . "<input type='checkbox' name='users[]' id='user_{$user_object->ID}' class='$role' value='{$user_object->ID}' />";
 
391
 
 
392
                } else {
 
393
                        $edit = '<strong>' . $user_object->user_login . '</strong>';
 
394
                }
 
395
                $role_name = isset( $wp_roles->role_names[$role] ) ? translate_user_role( $wp_roles->role_names[$role] ) : __( 'None' );
 
396
                $avatar = get_avatar( $user_object->ID, 32 );
 
397
 
 
398
                $r = "<tr id='user-$user_object->ID'$style>";
 
399
 
 
400
                list( $columns, $hidden ) = $this->get_column_info();
 
401
 
 
402
                foreach ( $columns as $column_name => $column_display_name ) {
 
403
                        $class = "class=\"$column_name column-$column_name\"";
 
404
 
 
405
                        $style = '';
 
406
                        if ( in_array( $column_name, $hidden ) )
 
407
                                $style = ' style="display:none;"';
 
408
 
 
409
                        $attributes = "$class$style";
 
410
 
 
411
                        switch ( $column_name ) {
 
412
                                case 'cb':
 
413
                                        $r .= "<th scope='row' class='check-column'>$checkbox</th>";
 
414
                                        break;
 
415
                                case 'username':
 
416
                                        $r .= "<td $attributes>$avatar $edit</td>";
 
417
                                        break;
 
418
                                case 'name':
 
419
                                        $r .= "<td $attributes>$user_object->first_name $user_object->last_name</td>";
 
420
                                        break;
 
421
                                case 'email':
 
422
                                        $r .= "<td $attributes><a href='mailto:$email' title='" . esc_attr( sprintf( __( 'E-mail: %s' ), $email ) ) . "'>$email</a></td>";
 
423
                                        break;
 
424
                                case 'role':
 
425
                                        $r .= "<td $attributes>$role_name</td>";
 
426
                                        break;
 
427
                                case 'posts':
 
428
                                        $attributes = 'class="posts column-posts num"' . $style;
 
429
                                        $r .= "<td $attributes>";
 
430
                                        if ( $numposts > 0 ) {
 
431
                                                $r .= "<a href='edit.php?author=$user_object->ID' title='" . esc_attr__( 'View posts by this author' ) . "' class='edit'>";
 
432
                                                $r .= $numposts;
 
433
                                                $r .= '</a>';
 
434
                                        } else {
 
435
                                                $r .= 0;
 
436
                                        }
 
437
                                        $r .= "</td>";
 
438
                                        break;
 
439
                                default:
 
440
                                        $r .= "<td $attributes>";
 
441
 
 
442
                                        /**
 
443
                                         * Filter the display output of custom columns in the Users list table.
 
444
                                         *
 
445
                                         * @since 2.8.0
 
446
                                         *
 
447
                                         * @param string $output      Custom column output. Default empty.
 
448
                                         * @param string $column_name Column name.
 
449
                                         * @param int    $user_id     ID of the currently-listed user.
 
450
                                         */
 
451
                                        $r .= apply_filters( 'manage_users_custom_column', '', $column_name, $user_object->ID );
 
452
                                        $r .= "</td>";
 
453
                        }
 
454
                }
 
455
                $r .= '</tr>';
 
456
 
 
457
                return $r;
 
458
        }
 
459
}