Make WordPress Core

source: branches/4.4/src/wp-admin/users.php

Last change on this file was 36106, checked in by dd32, 6 years ago

Users: When determining whether to show the reassign content option during user delete, don't rely upon WP_Query as it doesn't return all forms of content wp_delete_user() operates on.

This restores the reassign form when a user has a non-public post type or links assigned to them.

Merges [36068] to the 4.4 branch.
Props swissspidy & tharsheblows for initial patches.
Fixes #34993.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.9 KB
Line 
1<?php
2/**
3 * User administration panel
4 *
5 * @package WordPress
6 * @subpackage Administration
7 * @since 1.0.0
8 */
9
10/** WordPress Administration Bootstrap */
11require_once( dirname( __FILE__ ) . '/admin.php' );
12
13if ( ! current_user_can( 'list_users' ) ) {
14        wp_die(
15                '<h1>' . __( 'Cheatin&#8217; uh?' ) . '</h1>' .
16                '<p>' . __( 'You are not allowed to browse users.' ) . '</p>',
17                403
18        );
19}
20
21$wp_list_table = _get_list_table('WP_Users_List_Table');
22$pagenum = $wp_list_table->get_pagenum();
23$title = __('Users');
24$parent_file = 'users.php';
25
26add_screen_option( 'per_page' );
27
28// contextual help - choose Help on the top right of admin panel to preview this.
29get_current_screen()->add_help_tab( array(
30        'id'      => 'overview',
31        'title'   => __('Overview'),
32        'content' => '<p>' . __('This screen lists all the existing users for your site. Each user has one of five defined roles as set by the site admin: Site Administrator, Editor, Author, Contributor, or Subscriber. Users with roles other than Administrator will see fewer options in the dashboard navigation when they are logged in, based on their role.') . '</p>' .
33                                 '<p>' . __('To add a new user for your site, click the Add New button at the top of the screen or Add New in the Users menu section.') . '</p>'
34) ) ;
35
36get_current_screen()->add_help_tab( array(
37        'id'      => 'screen-display',
38        'title'   => __('Screen Display'),
39        'content' => '<p>' . __('You can customize the display of this screen in a number of ways:') . '</p>' .
40                                        '<ul>' .
41                                        '<li>' . __('You can hide/display columns based on your needs and decide how many users to list per screen using the Screen Options tab.') . '</li>' .
42                                        '<li>' . __('You can filter the list of users by User Role using the text links in the upper left to show All, Administrator, Editor, Author, Contributor, or Subscriber. The default view is to show all users. Unused User Roles are not listed.') . '</li>' .
43                                        '<li>' . __('You can view all posts made by a user by clicking on the number under the Posts column.') . '</li>' .
44                                        '</ul>'
45) );
46
47$help = '<p>' . __('Hovering over a row in the users list will display action links that allow you to manage users. You can perform the following actions:') . '</p>' .
48        '<ul>' .
49        '<li>' . __('Edit takes you to the editable profile screen for that user. You can also reach that screen by clicking on the username.') . '</li>';
50
51if ( is_multisite() )
52        $help .= '<li>' . __( 'Remove allows you to remove a user from your site. It does not delete their content. You can also remove multiple users at once by using Bulk Actions.' ) . '</li>';
53else
54        $help .= '<li>' . __( 'Delete brings you to the Delete Users screen for confirmation, where you can permanently remove a user from your site and delete their content. You can also delete multiple users at once by using Bulk Actions.' ) . '</li>';
55
56$help .= '</ul>';
57
58get_current_screen()->add_help_tab( array(
59        'id'      => 'actions',
60        'title'   => __('Actions'),
61        'content' => $help,
62) );
63unset( $help );
64
65get_current_screen()->set_help_sidebar(
66    '<p><strong>' . __('For more information:') . '</strong></p>' .
67    '<p>' . __('<a href="https://codex.wordpress.org/Users_Screen" target="_blank">Documentation on Managing Users</a>') . '</p>' .
68    '<p>' . __('<a href="https://codex.wordpress.org/Roles_and_Capabilities" target="_blank">Descriptions of Roles and Capabilities</a>') . '</p>' .
69    '<p>' . __('<a href="https://wordpress.org/support/" target="_blank">Support Forums</a>') . '</p>'
70);
71
72get_current_screen()->set_screen_reader_content( array(
73        'heading_views'      => __( 'Filter users list' ),
74        'heading_pagination' => __( 'Users list navigation' ),
75        'heading_list'       => __( 'Users list' ),
76) );
77
78if ( empty($_REQUEST) ) {
79        $referer = '<input type="hidden" name="wp_http_referer" value="'. esc_attr( wp_unslash( $_SERVER['REQUEST_URI'] ) ) . '" />';
80} elseif ( isset($_REQUEST['wp_http_referer']) ) {
81        $redirect = remove_query_arg(array('wp_http_referer', 'updated', 'delete_count'), wp_unslash( $_REQUEST['wp_http_referer'] ) );
82        $referer = '<input type="hidden" name="wp_http_referer" value="' . esc_attr($redirect) . '" />';
83} else {
84        $redirect = 'users.php';
85        $referer = '';
86}
87
88$update = '';
89
90switch ( $wp_list_table->current_action() ) {
91
92/* Bulk Dropdown menu Role changes */
93case 'promote':
94        check_admin_referer('bulk-users');
95
96        if ( ! current_user_can( 'promote_users' ) )
97                wp_die( __( 'You can&#8217;t edit that user.' ) );
98
99        if ( empty($_REQUEST['users']) ) {
100                wp_redirect($redirect);
101                exit();
102        }
103
104        $editable_roles = get_editable_roles();
105        $role = false;
106        if ( ! empty( $_REQUEST['new_role2'] ) ) {
107                $role = $_REQUEST['new_role2'];
108        } elseif ( ! empty( $_REQUEST['new_role'] ) ) {
109                $role = $_REQUEST['new_role'];
110        }
111
112        if ( ! $role || empty( $editable_roles[ $role ] ) ) {
113                wp_die( __( 'You can&#8217;t give users that role.' ) );
114        }
115
116        $userids = $_REQUEST['users'];
117        $update = 'promote';
118        foreach ( $userids as $id ) {
119                $id = (int) $id;
120
121                if ( ! current_user_can('promote_user', $id) )
122                        wp_die(__('You can&#8217;t edit that user.'));
123                // The new role of the current user must also have the promote_users cap or be a multisite super admin
124                if ( $id == $current_user->ID && ! $wp_roles->role_objects[ $role ]->has_cap('promote_users')
125                        && ! ( is_multisite() && is_super_admin() ) ) {
126                                $update = 'err_admin_role';
127                                continue;
128                }
129
130                // If the user doesn't already belong to the blog, bail.
131                if ( is_multisite() && !is_user_member_of_blog( $id ) ) {
132                        wp_die(
133                                '<h1>' . __( 'Cheatin&#8217; uh?' ) . '</h1>' .
134                                '<p>' . __( 'One of the selected users is not a member of this site.' ) . '</p>',
135                                403
136                        );
137                }
138
139                $user = get_userdata( $id );
140                $user->set_role( $role );
141        }
142
143        wp_redirect(add_query_arg('update', $update, $redirect));
144        exit();
145
146case 'dodelete':
147        if ( is_multisite() )
148                wp_die( __('User deletion is not allowed from this screen.') );
149
150        check_admin_referer('delete-users');
151
152        if ( empty($_REQUEST['users']) ) {
153                wp_redirect($redirect);
154                exit();
155        }
156
157        $userids = array_map( 'intval', (array) $_REQUEST['users'] );
158
159        if ( empty( $_REQUEST['delete_option'] ) ) {
160                $url = self_admin_url( 'users.php?action=delete&users[]=' . implode( '&users[]=', $userids ) . '&error=true' );
161                $url = str_replace( '&amp;', '&', wp_nonce_url( $url, 'bulk-users' ) );
162                wp_redirect( $url );
163                exit;
164        }
165
166        if ( ! current_user_can( 'delete_users' ) )
167                wp_die(__('You can&#8217;t delete users.'));
168
169        $update = 'del';
170        $delete_count = 0;
171
172        foreach ( $userids as $id ) {
173                if ( ! current_user_can( 'delete_user', $id ) )
174                        wp_die(__( 'You can&#8217;t delete that user.' ) );
175
176                if ( $id == $current_user->ID ) {
177                        $update = 'err_admin_del';
178                        continue;
179                }
180                switch ( $_REQUEST['delete_option'] ) {
181                case 'delete':
182                        wp_delete_user( $id );
183                        break;
184                case 'reassign':
185                        wp_delete_user( $id, $_REQUEST['reassign_user'] );
186                        break;
187                }
188                ++$delete_count;
189        }
190
191        $redirect = add_query_arg( array('delete_count' => $delete_count, 'update' => $update), $redirect);
192        wp_redirect($redirect);
193        exit();
194
195case 'delete':
196        if ( is_multisite() )
197                wp_die( __('User deletion is not allowed from this screen.') );
198
199        check_admin_referer('bulk-users');
200
201        if ( empty($_REQUEST['users']) && empty($_REQUEST['user']) ) {
202                wp_redirect($redirect);
203                exit();
204        }
205
206        if ( ! current_user_can( 'delete_users' ) )
207                $errors = new WP_Error( 'edit_users', __( 'You can&#8217;t delete users.' ) );
208
209        if ( empty($_REQUEST['users']) )
210                $userids = array( intval( $_REQUEST['user'] ) );
211        else
212                $userids = array_map( 'intval', (array) $_REQUEST['users'] );
213
214        $users_have_content = false;
215        if ( $wpdb->get_var( "SELECT ID FROM {$wpdb->posts} WHERE post_author IN( " . implode( ',', $userids ) . " ) LIMIT 1" ) ) {
216                $users_have_content = true;
217        } elseif ( $wpdb->get_var( "SELECT link_id FROM {$wpdb->links} WHERE link_owner IN( " . implode( ',', $userids ) . " ) LIMIT 1" ) ) {
218                $users_have_content = true;
219        }
220
221        if ( $users_have_content ) {
222                add_action( 'admin_head', 'delete_users_add_js' );
223        }
224
225        include( ABSPATH . 'wp-admin/admin-header.php' );
226?>
227<form method="post" name="updateusers" id="updateusers">
228<?php wp_nonce_field('delete-users') ?>
229<?php echo $referer; ?>
230
231<div class="wrap">
232<h1><?php _e( 'Delete Users' ); ?></h1>
233<?php if ( isset( $_REQUEST['error'] ) ) : ?>
234        <div class="error">
235                <p><strong><?php _e( 'ERROR:' ); ?></strong> <?php _e( 'Please select an option.' ); ?></p>
236        </div>
237<?php endif; ?>
238
239<?php if ( 1 == count( $userids ) ) : ?>
240        <p><?php _e( 'You have specified this user for deletion:' ); ?></p>
241<?php else : ?>
242        <p><?php _e( 'You have specified these users for deletion:' ); ?></p>
243<?php endif; ?>
244
245<ul>
246<?php
247        $go_delete = 0;
248        foreach ( $userids as $id ) {
249                $user = get_userdata( $id );
250                if ( $id == $current_user->ID ) {
251                        echo "<li>" . sprintf(__('ID #%1$s: %2$s <strong>The current user will not be deleted.</strong>'), $id, $user->user_login) . "</li>\n";
252                } else {
253                        echo "<li><input type=\"hidden\" name=\"users[]\" value=\"" . esc_attr($id) . "\" />" . sprintf(__('ID #%1$s: %2$s'), $id, $user->user_login) . "</li>\n";
254                        $go_delete++;
255                }
256        }
257        ?>
258        </ul>
259<?php if ( $go_delete ) :
260
261        if ( ! $users_have_content ) : ?>
262                <input type="hidden" name="delete_option" value="delete" />
263        <?php else: ?>
264                <?php if ( 1 == $go_delete ) : ?>
265                        <fieldset><p><legend><?php _e( 'What should be done with content owned by this user?' ); ?></legend></p>
266                <?php else : ?>
267                        <fieldset><p><legend><?php _e( 'What should be done with content owned by these users?' ); ?></legend></p>
268                <?php endif; ?>
269                <ul style="list-style:none;">
270                        <li><label><input type="radio" id="delete_option0" name="delete_option" value="delete" />
271                        <?php _e('Delete all content.'); ?></label></li>
272                        <li><input type="radio" id="delete_option1" name="delete_option" value="reassign" />
273                        <?php echo '<label for="delete_option1">' . __( 'Attribute all content to:' ) . '</label> ';
274                        wp_dropdown_users( array( 'name' => 'reassign_user', 'exclude' => array_diff( $userids, array($current_user->ID) ) ) ); ?></li>
275                </ul></fieldset>
276        <?php endif;
277        /**
278         * Fires at the end of the delete users form prior to the confirm button.
279         *
280         * @since 4.0.0
281         *
282         * @param WP_User $current_user WP_User object for the user being deleted.
283         */
284        do_action( 'delete_user_form', $current_user );
285        ?>
286        <input type="hidden" name="action" value="dodelete" />
287        <?php submit_button( __('Confirm Deletion'), 'primary' ); ?>
288<?php else : ?>
289        <p><?php _e('There are no valid users selected for deletion.'); ?></p>
290<?php endif; ?>
291</div>
292</form>
293<?php
294
295break;
296
297case 'doremove':
298        check_admin_referer('remove-users');
299
300        if ( ! is_multisite() )
301                wp_die( __( 'You can&#8217;t remove users.' ) );
302
303        if ( empty($_REQUEST['users']) ) {
304                wp_redirect($redirect);
305                exit;
306        }
307
308        if ( ! current_user_can( 'remove_users' ) )
309                wp_die( __( 'You can&#8217;t remove users.' ) );
310
311        $userids = $_REQUEST['users'];
312
313        $update = 'remove';
314        foreach ( $userids as $id ) {
315                $id = (int) $id;
316                if ( $id == $current_user->ID && !is_super_admin() ) {
317                        $update = 'err_admin_remove';
318                        continue;
319                }
320                if ( !current_user_can('remove_user', $id) ) {
321                        $update = 'err_admin_remove';
322                        continue;
323                }
324                remove_user_from_blog($id, $blog_id);
325        }
326
327        $redirect = add_query_arg( array('update' => $update), $redirect);
328        wp_redirect($redirect);
329        exit;
330
331case 'remove':
332
333        check_admin_referer('bulk-users');
334
335        if ( ! is_multisite() )
336                wp_die( __( 'You can&#8217;t remove users.' ) );
337
338        if ( empty($_REQUEST['users']) && empty($_REQUEST['user']) ) {
339                wp_redirect($redirect);
340                exit();
341        }
342
343        if ( !current_user_can('remove_users') )
344                $error = new WP_Error('edit_users', __('You can&#8217;t remove users.'));
345
346        if ( empty($_REQUEST['users']) )
347                $userids = array(intval($_REQUEST['user']));
348        else
349                $userids = $_REQUEST['users'];
350
351        include( ABSPATH . 'wp-admin/admin-header.php' );
352?>
353<form method="post" name="updateusers" id="updateusers">
354<?php wp_nonce_field('remove-users') ?>
355<?php echo $referer; ?>
356
357<div class="wrap">
358<h1><?php _e( 'Remove Users from Site' ); ?></h1>
359
360<?php if ( 1 == count( $userids ) ) : ?>
361        <p><?php _e( 'You have specified this user for removal:' ); ?></p>
362<?php else : ?>
363        <p><?php _e( 'You have specified these users for removal:' ); ?></p>
364<?php endif; ?>
365
366<ul>
367<?php
368        $go_remove = false;
369        foreach ( $userids as $id ) {
370                $id = (int) $id;
371                $user = get_userdata( $id );
372                if ( $id == $current_user->ID && !is_super_admin() ) {
373                        echo "<li>" . sprintf(__('ID #%1$s: %2$s <strong>The current user will not be removed.</strong>'), $id, $user->user_login) . "</li>\n";
374                } elseif ( !current_user_can('remove_user', $id) ) {
375                        echo "<li>" . sprintf(__('ID #%1$s: %2$s <strong>You don\'t have permission to remove this user.</strong>'), $id, $user->user_login) . "</li>\n";
376                } else {
377                        echo "<li><input type=\"hidden\" name=\"users[]\" value=\"{$id}\" />" . sprintf(__('ID #%1$s: %2$s'), $id, $user->user_login) . "</li>\n";
378                        $go_remove = true;
379                }
380        }
381        ?>
382</ul>
383<?php if ( $go_remove ) : ?>
384                <input type="hidden" name="action" value="doremove" />
385                <?php submit_button( __('Confirm Removal'), 'primary' ); ?>
386<?php else : ?>
387        <p><?php _e('There are no valid users selected for removal.'); ?></p>
388<?php endif; ?>
389</div>
390</form>
391<?php
392
393break;
394
395default:
396
397        if ( !empty($_GET['_wp_http_referer']) ) {
398                wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce'), wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
399                exit;
400        }
401
402        $wp_list_table->prepare_items();
403        $total_pages = $wp_list_table->get_pagination_arg( 'total_pages' );
404        if ( $pagenum > $total_pages && $total_pages > 0 ) {
405                wp_redirect( add_query_arg( 'paged', $total_pages ) );
406                exit;
407        }
408
409        include( ABSPATH . 'wp-admin/admin-header.php' );
410
411        $messages = array();
412        if ( isset($_GET['update']) ) :
413                switch($_GET['update']) {
414                case 'del':
415                case 'del_many':
416                        $delete_count = isset($_GET['delete_count']) ? (int) $_GET['delete_count'] : 0;
417                        if ( 1 == $delete_count ) {
418                                $message = __( 'User deleted.' );
419                        } else {
420                                $message = _n( '%s user deleted.', '%s users deleted.', $delete_count );
421                        }
422                        $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . sprintf( $message, number_format_i18n( $delete_count ) ) . '</p></div>';
423                        break;
424                case 'add':
425                        if ( isset( $_GET['id'] ) && ( $user_id = $_GET['id'] ) && current_user_can( 'edit_user', $user_id ) ) {
426                                $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . sprintf( __( 'New user created. <a href="%s">Edit user</a>' ),
427                                        esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ),
428                                                self_admin_url( 'user-edit.php?user_id=' . $user_id ) ) ) ) . '</p></div>';
429                        } else {
430                                $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __( 'New user created.' ) . '</p></div>';
431                        }
432                        break;
433                case 'promote':
434                        $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __('Changed roles.') . '</p></div>';
435                        break;
436                case 'err_admin_role':
437                        $messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __('The current user&#8217;s role must have user editing capabilities.') . '</p></div>';
438                        $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __('Other user roles have been changed.') . '</p></div>';
439                        break;
440                case 'err_admin_del':
441                        $messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __('You can&#8217;t delete the current user.') . '</p></div>';
442                        $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __('Other users have been deleted.') . '</p></div>';
443                        break;
444                case 'remove':
445                        $messages[] = '<div id="message" class="updated notice is-dismissible fade"><p>' . __('User removed from this site.') . '</p></div>';
446                        break;
447                case 'err_admin_remove':
448                        $messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __("You can't remove the current user.") . '</p></div>';
449                        $messages[] = '<div id="message" class="updated notice is-dismissible fade"><p>' . __('Other users have been removed.') . '</p></div>';
450                        break;
451                }
452        endif; ?>
453
454<?php if ( isset($errors) && is_wp_error( $errors ) ) : ?>
455        <div class="error">
456                <ul>
457                <?php
458                        foreach ( $errors->get_error_messages() as $err )
459                                echo "<li>$err</li>\n";
460                ?>
461                </ul>
462        </div>
463<?php endif;
464
465if ( ! empty($messages) ) {
466        foreach ( $messages as $msg )
467                echo $msg;
468} ?>
469
470<div class="wrap">
471<h1>
472<?php
473echo esc_html( $title );
474if ( current_user_can( 'create_users' ) ) { ?>
475        <a href="user-new.php" class="page-title-action"><?php echo esc_html_x( 'Add New', 'user' ); ?></a>
476<?php } elseif ( is_multisite() && current_user_can( 'promote_users' ) ) { ?>
477        <a href="user-new.php" class="page-title-action"><?php echo esc_html_x( 'Add Existing', 'user' ); ?></a>
478<?php }
479
480if ( $usersearch )
481        printf( '<span class="subtitle">' . __('Search results for &#8220;%s&#8221;') . '</span>', esc_html( $usersearch ) ); ?>
482</h1>
483
484<?php $wp_list_table->views(); ?>
485
486<form method="get">
487
488<?php $wp_list_table->search_box( __( 'Search Users' ), 'user' ); ?>
489
490<?php $wp_list_table->display(); ?>
491</form>
492
493<br class="clear" />
494</div>
495<?php
496break;
497
498} // end of the $doaction switch
499
500include( ABSPATH . 'wp-admin/admin-footer.php' );
Note: See TracBrowser for help on using the repository browser.