Make WordPress Core

Ticket #16031: 16031-comprehensive.patch

File 16031-comprehensive.patch, 46.3 KB (added by Veraxus, 9 years ago)

Reverts cs 17297 and adds comprehensive "handle_other_bulk_action-{$screen_id}" filter to all WP admin screens with list tables

  • src/wp-admin/edit-comments.php

     
    3838
    3939        $redirect_to = remove_query_arg( array( 'trashed', 'untrashed', 'deleted', 'spammed', 'unspammed', 'approved', 'unapproved', 'ids' ), wp_get_referer() );
    4040        $redirect_to = add_query_arg( 'paged', $pagenum, $redirect_to );
    41 
     41       
    4242        foreach ( $comment_ids as $comment_id ) { // Check the permissions on each
    4343                if ( !current_user_can( 'edit_comment', $comment_id ) )
    4444                        continue;
     
    9292        if ( $trashed || $spammed )
    9393                $redirect_to = add_query_arg( 'ids', join( ',', $comment_ids ), $redirect_to );
    9494
     95        /**
     96         * A filter that allows for handling of custom bulk actions.
     97         *
     98         * The dynamic portion of the hook name, `$current_screen->id`, refers
     99         * to the ID of the current screen, usually a string.
     100         *
     101         * @since 4.4.0
     102         *
     103         * @param string $redirect_to A string containing the post-action redirect URI
     104         * @param array $comment_ids An array of the selected objects to execute action on
     105         * @param string $doaction The current bulk action
     106         */
     107        $redirect_to = apply_filters("handle_other_bulk_action-{$current_screen->id}", $redirect_to, $comment_ids, $doaction );
     108
    95109        wp_safe_redirect( $redirect_to );
    96110        exit;
    97111} elseif ( ! empty( $_GET['_wp_http_referer'] ) ) {
  • src/wp-admin/edit-tags.php

     
    4949
    5050switch ( $wp_list_table->current_action() ) {
    5151
    52 case 'add-tag':
    53 
    54         check_admin_referer( 'add-tag', '_wpnonce_add-tag' );
    55 
    56         if ( !current_user_can( $tax->cap->edit_terms ) )
    57                 wp_die( __( 'Cheatin’ uh?' ), 403 );
    58 
    59         $ret = wp_insert_term( $_POST['tag-name'], $taxonomy, $_POST );
    60         $location = 'edit-tags.php?taxonomy=' . $taxonomy;
    61         if ( 'post' != $post_type )
    62                 $location .= '&post_type=' . $post_type;
    63 
    64         if ( $referer = wp_get_original_referer() ) {
    65                 if ( false !== strpos( $referer, 'edit-tags.php' ) )
    66                         $location = $referer;
    67         }
    68 
    69         if ( $ret && !is_wp_error( $ret ) )
    70                 $location = add_query_arg( 'message', 1, $location );
    71         else
    72                 $location = add_query_arg( array( 'error' => true, 'message' => 4 ), $location );
    73 
    74         break;
    75 
    76 case 'delete':
    77         $location = 'edit-tags.php?taxonomy=' . $taxonomy;
    78         if ( 'post' != $post_type )
    79                 $location .= '&post_type=' . $post_type;
    80         if ( $referer = wp_get_referer() ) {
    81                 if ( false !== strpos( $referer, 'edit-tags.php' ) )
    82                         $location = $referer;
    83         }
    84 
    85         if ( ! isset( $_REQUEST['tag_ID'] ) ) {
     52        case 'add-tag':
     53       
     54                check_admin_referer( 'add-tag', '_wpnonce_add-tag' );
     55       
     56                if ( !current_user_can( $tax->cap->edit_terms ) )
     57                        wp_die( __( 'Cheatin’ uh?' ), 403 );
     58       
     59                $ret = wp_insert_term( $_POST['tag-name'], $taxonomy, $_POST );
     60                $location = 'edit-tags.php?taxonomy=' . $taxonomy;
     61                if ( 'post' != $post_type )
     62                        $location .= '&post_type=' . $post_type;
     63       
     64                if ( $referer = wp_get_original_referer() ) {
     65                        if ( false !== strpos( $referer, 'edit-tags.php' ) )
     66                                $location = $referer;
     67                }
     68       
     69                if ( $ret && !is_wp_error( $ret ) )
     70                        $location = add_query_arg( 'message', 1, $location );
     71                else
     72                        $location = add_query_arg( array( 'error' => true, 'message' => 4 ), $location );
     73       
    8674                break;
    87         }
    88 
    89         $tag_ID = (int) $_REQUEST['tag_ID'];
    90         check_admin_referer( 'delete-tag_' . $tag_ID );
    91 
    92         if ( !current_user_can( $tax->cap->delete_terms ) )
    93                 wp_die( __( 'Cheatin’ uh?' ), 403 );
    94 
    95         wp_delete_term( $tag_ID, $taxonomy );
    96 
    97         $location = add_query_arg( 'message', 2, $location );
    98 
    99         break;
    100 
    101 case 'bulk-delete':
    102         check_admin_referer( 'bulk-tags' );
    103 
    104         if ( !current_user_can( $tax->cap->delete_terms ) )
    105                 wp_die( __( 'Cheatin’ uh?' ), 403 );
    106 
    107         $tags = (array) $_REQUEST['delete_tags'];
    108         foreach ( $tags as $tag_ID ) {
     75       
     76        case 'delete':
     77                $location = 'edit-tags.php?taxonomy=' . $taxonomy;
     78                if ( 'post' != $post_type )
     79                        $location .= '&post_type=' . $post_type;
     80                if ( $referer = wp_get_referer() ) {
     81                        if ( false !== strpos( $referer, 'edit-tags.php' ) )
     82                                $location = $referer;
     83                }
     84       
     85                if ( ! isset( $_REQUEST['tag_ID'] ) ) {
     86                        break;
     87                }
     88       
     89                $tag_ID = (int) $_REQUEST['tag_ID'];
     90                check_admin_referer( 'delete-tag_' . $tag_ID );
     91       
     92                if ( !current_user_can( $tax->cap->delete_terms ) )
     93                        wp_die( __( 'Cheatin’ uh?' ), 403 );
     94       
    10995                wp_delete_term( $tag_ID, $taxonomy );
    110         }
    111 
    112         $location = 'edit-tags.php?taxonomy=' . $taxonomy;
    113         if ( 'post' != $post_type )
    114                 $location .= '&post_type=' . $post_type;
    115         if ( $referer = wp_get_referer() ) {
    116                 if ( false !== strpos( $referer, 'edit-tags.php' ) )
    117                         $location = $referer;
    118         }
    119 
    120         $location = add_query_arg( 'message', 6, $location );
    121 
    122         break;
    123 
    124 case 'edit':
    125         $title = $tax->labels->edit_item;
    126 
    127         $tag_ID = (int) $_REQUEST['tag_ID'];
    128 
    129         $tag = get_term( $tag_ID, $taxonomy, OBJECT, 'edit' );
    130         if ( ! $tag )
    131                 wp_die( __( 'You attempted to edit an item that doesn’t exist. Perhaps it was deleted?' ) );
    132         require_once( ABSPATH . 'wp-admin/admin-header.php' );
    133         include( ABSPATH . 'wp-admin/edit-tag-form.php' );
    134         include( ABSPATH . 'wp-admin/admin-footer.php' );
    135 
    136         exit;
    137 
    138 case 'editedtag':
    139         $tag_ID = (int) $_POST['tag_ID'];
    140         check_admin_referer( 'update-tag_' . $tag_ID );
    141 
    142         if ( !current_user_can( $tax->cap->edit_terms ) )
    143                 wp_die( __( 'Cheatin’ uh?' ), 403 );
    144 
    145         $tag = get_term( $tag_ID, $taxonomy );
    146         if ( ! $tag )
    147                 wp_die( __( 'You attempted to edit an item that doesn’t exist. Perhaps it was deleted?' ) );
    148 
    149         $ret = wp_update_term( $tag_ID, $taxonomy, $_POST );
    150 
    151         $location = 'edit-tags.php?taxonomy=' . $taxonomy;
    152         if ( 'post' != $post_type )
    153                 $location .= '&post_type=' . $post_type;
    154 
    155         if ( $referer = wp_get_original_referer() ) {
    156                 if ( false !== strpos( $referer, 'edit-tags.php' ) )
    157                         $location = $referer;
    158         }
    159 
    160         if ( $ret && !is_wp_error( $ret ) )
    161                 $location = add_query_arg( 'message', 3, $location );
    162         else
    163                 $location = add_query_arg( array( 'error' => true, 'message' => 5 ), $location );
    164         break;
     96       
     97                $location = add_query_arg( 'message', 2, $location );
     98       
     99                break;
     100       
     101        case 'bulk-delete':
     102                check_admin_referer( 'bulk-tags' );
     103       
     104                if ( !current_user_can( $tax->cap->delete_terms ) )
     105                        wp_die( __( 'Cheatin’ uh?' ), 403 );
     106       
     107                $tags = (array) $_REQUEST['delete_tags'];
     108                foreach ( $tags as $tag_ID ) {
     109                        wp_delete_term( $tag_ID, $taxonomy );
     110                }
     111       
     112                $location = 'edit-tags.php?taxonomy=' . $taxonomy;
     113                if ( 'post' != $post_type )
     114                        $location .= '&post_type=' . $post_type;
     115                if ( $referer = wp_get_referer() ) {
     116                        if ( false !== strpos( $referer, 'edit-tags.php' ) )
     117                                $location = $referer;
     118                }
     119       
     120                $location = add_query_arg( 'message', 6, $location );
     121       
     122                break;
     123       
     124        case 'edit':
     125                $title = $tax->labels->edit_item;
     126       
     127                $tag_ID = (int) $_REQUEST['tag_ID'];
     128       
     129                $tag = get_term( $tag_ID, $taxonomy, OBJECT, 'edit' );
     130                if ( ! $tag )
     131                        wp_die( __( 'You attempted to edit an item that doesn’t exist. Perhaps it was deleted?' ) );
     132                require_once( ABSPATH . 'wp-admin/admin-header.php' );
     133                include( ABSPATH . 'wp-admin/edit-tag-form.php' );
     134                include( ABSPATH . 'wp-admin/admin-footer.php' );
     135       
     136                exit;
     137       
     138        case 'editedtag':
     139                $tag_ID = (int) $_POST['tag_ID'];
     140                check_admin_referer( 'update-tag_' . $tag_ID );
     141       
     142                if ( !current_user_can( $tax->cap->edit_terms ) )
     143                        wp_die( __( 'Cheatin’ uh?' ), 403 );
     144       
     145                $tag = get_term( $tag_ID, $taxonomy );
     146                if ( ! $tag )
     147                        wp_die( __( 'You attempted to edit an item that doesn’t exist. Perhaps it was deleted?' ) );
     148       
     149                $ret = wp_update_term( $tag_ID, $taxonomy, $_POST );
     150       
     151                $location = 'edit-tags.php?taxonomy=' . $taxonomy;
     152                if ( 'post' != $post_type )
     153                        $location .= '&post_type=' . $post_type;
     154       
     155                if ( $referer = wp_get_original_referer() ) {
     156                        if ( false !== strpos( $referer, 'edit-tags.php' ) )
     157                                $location = $referer;
     158                }
     159       
     160                if ( $ret && !is_wp_error( $ret ) )
     161                        $location = add_query_arg( 'message', 3, $location );
     162                else
     163                        $location = add_query_arg( array( 'error' => true, 'message' => 5 ), $location );
     164                break;
    165165}
    166166
    167167if ( ! $location && ! empty( $_REQUEST['_wp_http_referer'] ) ) {
    168168        $location = remove_query_arg( array('_wp_http_referer', '_wpnonce'), wp_unslash($_SERVER['REQUEST_URI']) );
    169169}
    170170
     171if ( $wp_list_table->current_action() && $_REQUEST['delete_tags'] ) {
     172        /**
     173         * A filter that allows for handling of custom bulk actions.
     174         *
     175         * The dynamic portion of the hook name, `$current_screen->id`, refers
     176         * to the ID of the current screen, usually a string.
     177         *
     178         * @since 4.4.0
     179         *
     180         * @param string $location A string containing the post-action redirect URI
     181         * @param array $_REQUEST['delete_tags'] An array of the selected objects to execute action on
     182         * @param string $wp_list_table->current_action() The current bulk action
     183         */
     184        $location = apply_filters( "handle_other_bulk_action-{$current_screen->id}", $location, $_REQUEST['delete_tags'], $wp_list_table->current_action() );
     185}
     186       
    171187if ( $location ) {
    172188        if ( ! empty( $_REQUEST['paged'] ) ) {
    173189                $location = add_query_arg( 'paged', (int) $_REQUEST['paged'], $location );
  • src/wp-admin/edit.php

     
    157157
    158158        $sendback = remove_query_arg( array('action', 'action2', 'tags_input', 'post_author', 'comment_status', 'ping_status', '_status', 'post', 'bulk_edit', 'post_view'), $sendback );
    159159
     160        /**
     161         * A filter that allows for handling of custom bulk actions.
     162         *
     163         * The dynamic portion of the hook name, `$current_screen->id`, refers
     164         * to the ID of the current screen, usually a string.
     165         *
     166         * @since 4.4.0
     167         *
     168         * @param string $sendback A string containing the post-action redirect URI
     169         * @param array $post_ids An array of the selected objects to execute action on
     170         * @param string $doaction The current bulk action
     171         */
     172        $sendback = apply_filters("handle_other_bulk_action-{$current_screen->id}", $sendback, $post_ids, $doaction );
     173       
    160174        wp_redirect($sendback);
    161175        exit();
    162176} elseif ( ! empty($_REQUEST['_wp_http_referer']) ) {
  • src/wp-admin/includes/class-wp-list-table.php

     
    412412         */
    413413        protected function bulk_actions( $which = '' ) {
    414414                if ( is_null( $this->_actions ) ) {
    415                         $no_new_actions = $this->_actions = $this->get_bulk_actions();
     415                        $this->_actions = $this->get_bulk_actions();
    416416                        /**
    417417                         * Filter the list table Bulk Actions drop-down.
    418418                         *
    419419                         * The dynamic portion of the hook name, `$this->screen->id`, refers
    420420                         * to the ID of the current screen, usually a string.
    421421                         *
    422                          * This filter can currently only be used to remove bulk actions.
    423                          *
    424422                         * @since 3.5.0
    425423                         *
    426424                         * @param array $actions An array of the available bulk actions.
    427425                         */
    428426                        $this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions );
    429                         $this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions );
    430427                        $two = '';
    431428                } else {
    432429                        $two = '2';
  • src/wp-admin/link-manager.php

     
    1818
    1919if ( $doaction && isset( $_REQUEST['linkcheck'] ) ) {
    2020        check_admin_referer( 'bulk-bookmarks' );
     21       
     22        $redirect_to = admin_url( 'link-manager.php' );
     23        $bulklinks = (array) $_REQUEST['linkcheck'];
    2124
    2225        if ( 'delete' == $doaction ) {
    23                 $bulklinks = (array) $_REQUEST['linkcheck'];
    2426                foreach ( $bulklinks as $link_id ) {
    2527                        $link_id = (int) $link_id;
    2628
    2729                        wp_delete_link( $link_id );
    2830                }
    2931
    30                 wp_redirect( add_query_arg('deleted', count( $bulklinks ), admin_url( 'link-manager.php' ) ) );
    31                 exit;
     32                $redirect_to = add_query_arg('deleted', count( $bulklinks ), $redirect_to );
    3233        }
     34
     35        /**
     36         * A filter that allows for handling of custom bulk actions.
     37         *
     38         * The dynamic portion of the hook name, `$current_screen->id`, refers
     39         * to the ID of the current screen, usually a string.
     40         *
     41         * @since 4.4.0
     42         *
     43         * @param string $redirect_to A string containing the post-action redirect URI
     44         * @param array $bulklinks An array of the selected objects to execute action on
     45         * @param string $doaction The current bulk action
     46         */
     47        $redirect_to = apply_filters("handle_other_bulk_action-{$current_screen->id}", $redirect_to, $bulklinks, $doaction );
     48
     49        wp_redirect( $redirect_to );
     50        exit;
     51       
    3352} elseif ( ! empty( $_GET['_wp_http_referer'] ) ) {
    3453         wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
    3554         exit;
  • src/wp-admin/network/site-themes.php

     
    121121        update_option( 'allowedthemes', $allowed_themes );
    122122        restore_current_blog();
    123123
     124        if ( isset($_REQUEST['checked']) && !isset($n) ) {
     125                /**
     126                 * A filter that allows for handling of custom bulk actions.
     127                 *
     128                 * The dynamic portion of the hook name, `$current_screen->id`, refers
     129                 * to the ID of the current screen, usually a string.
     130                 *
     131                 * @since 4.4.0
     132                 *
     133                 * @param string $referer A string containing the post-action redirect URI
     134                 * @param array $_REQUEST['checked'] An array of the selected objects to execute action on
     135                 * @param string $action The current bulk action
     136                 * @param int $id The current site id
     137                 */
     138                $referer = apply_filters( "handle_other_bulk_action-{$current_screen->id}", $referer, (array) $_REQUEST['checked'], $action, $id );
     139
     140                wp_safe_redirect( $referer );
     141                exit();
     142        }
     143
    124144        wp_safe_redirect( add_query_arg( array( 'id' => $id, $action => $n ), $referer ) );
    125145        exit;
    126146}
  • src/wp-admin/network/site-users.php

     
    148148                        break;
    149149        }
    150150
     151        if ( isset($_REQUEST['users']) && !isset($update) ) {
     152                /**
     153                 * A filter that allows for handling of custom bulk actions.
     154                 *
     155                 * The dynamic portion of the hook name, `$current_screen->id`, refers
     156                 * to the ID of the current screen, usually a string.
     157                 *
     158                 * @since 4.4.0
     159                 *
     160                 * @param string $referer A string containing the post-action redirect URI
     161                 * @param array $_REQUEST['users'] An array of the selected objects to execute action on
     162                 * @param string $action The current bulk action
     163                 * @param int $id The current site id
     164                 */
     165                $referer = apply_filters( "handle_other_bulk_action-{$current_screen->id}", $referer, (array) $_REQUEST['users'], $action, $id );
     166               
     167                wp_safe_redirect( $referer );
     168                exit();
     169        }
     170
    151171        wp_safe_redirect( add_query_arg( 'update', $update, $referer ) );
    152172        exit();
    153173}
  • src/wp-admin/network/sites.php

     
    210210                wp_safe_redirect( add_query_arg( array( 'updated' => $updated_action ), wp_get_referer() ) );
    211211                exit();
    212212        }
     213       
     214        if ( isset($_REQUEST['allblogs']) ) {
     215                $custom_redirect = wp_get_referer();
     216
     217                /**
     218                 * A filter that allows for handling of custom bulk actions.
     219                 *
     220                 * The dynamic portion of the hook name, `$current_screen->id`, refers
     221                 * to the ID of the current screen, usually a string.
     222                 *
     223                 * @since 4.4.0
     224                 *
     225                 * @param string $custom_redirect A string containing the post-action redirect URI
     226                 * @param array $_REQUEST['allblogs'] An array of the selected objects to execute action on
     227                 * @param string $_REQUEST['action'] The current bulk action
     228                 * @param int $id The current site id
     229                 */
     230                $custom_redirect = apply_filters( "handle_other_bulk_action-{$current_screen->id}", $custom_redirect, (array) $_REQUEST['allblogs'], $_REQUEST['action'], $id );
     231
     232                if ( $custom_redirect ) {
     233                        wp_safe_redirect( $custom_redirect );
     234                        exit;
     235                }
     236        }
    213237}
    214238
    215239$msg = '';
  • src/wp-admin/network/themes.php

     
    228228                        ), network_admin_url( 'themes.php' ) ) );
    229229                        exit;
    230230        }
     231
     232        if ( isset($_POST['checked']) ) {
     233                $custom_redirect = wp_get_referer();
     234               
     235                /**
     236                 * A filter that allows for handling of custom bulk actions.
     237                 *
     238                 *
     239                 * The dynamic portion of the hook name, `$current_screen->id`, refers
     240                 * to the ID of the current screen, usually a string.
     241                 *
     242                 * @since 4.4.0
     243                 *
     244                 * @param string $custom_redirect A string containing the post-action redirect URI
     245                 * @param array $_REQUEST['checked'] An array of the selected objects to execute action on
     246                 * @param string $action The current bulk action
     247                 */
     248                $custom_redirect = apply_filters( "handle_other_bulk_action-{$current_screen->id}", $custom_redirect, (array) $_REQUEST['checked'], $action );
     249               
     250                if ( $custom_redirect ) {
     251                        wp_safe_redirect( $custom_redirect );
     252                        exit;
     253                }
     254        }
     255       
    231256}
    232257
    233258$wp_list_table->prepare_items();
  • src/wp-admin/network/users.php

     
    201201                                        }
    202202                                }
    203203
     204                                if ( isset($_POST['allusers']) ) {
     205                                        $custom_redirect = wp_get_referer();
     206                               
     207                                        /**
     208                                         * A filter that allows for handling of custom bulk actions.
     209                                         *
     210                                         * The dynamic portion of the hook name, `$current_screen->id`, refers
     211                                         * to the ID of the current screen, usually a string.
     212                                         *
     213                                         * @since 4.4.0
     214                                         *
     215                                         * @param string $custom_redirect A string containing the post-action redirect URI
     216                                         * @param array $_POST['allusers'] An array of the selected objects to execute action on
     217                                         * @param string $_POST['action'] The current bulk action
     218                                         */
     219                                        $custom_redirect = apply_filters( "handle_other_bulk_action-{$current_screen->id}", $custom_redirect, (array) $_POST['allusers'], $_POST['action'] );
     220                               
     221                                        if ( $custom_redirect ) {
     222                                                wp_safe_redirect( $custom_redirect );
     223                                                exit;
     224                                        }
     225                                }
     226
    204227                                wp_safe_redirect( add_query_arg( array( 'updated' => 'true', 'action' => $userfunction ), wp_get_referer() ) );
    205228                        } else {
    206229                                $location = network_admin_url( 'users.php' );
  • src/wp-admin/plugins.php

     
    365365                                update_option( 'recently_activated', array() );
    366366                        break;
    367367        }
     368       
     369        if ( isset( $_POST['checked'] ) ) {
     370                $custom_redirect = wp_get_referer();
     371
     372                /**
     373                 * A filter that allows for handling of custom bulk actions.
     374                 *
     375                 * The dynamic portion of the hook name, `$current_screen->id`, refers
     376                 * to the ID of the current screen, usually a string.
     377                 *
     378                 * @since 4.4.0
     379                 *
     380                 * @param string $custom_redirect A string containing the post-action redirect URI
     381                 * @param array $_POST['checked'] An array of the selected objects to execute action on
     382                 * @param string $action The current bulk action
     383                 */
     384                $custom_redirect = apply_filters( "handle_other_bulk_action-{$current_screen->id}", $custom_redirect, $_POST['checked'], $action );
     385
     386                if ( $custom_redirect ) {
     387                        wp_safe_redirect( $custom_redirect );
     388                }
     389        }
    368390}
    369391
    370392$wp_list_table->prepare_items();
  • src/wp-admin/upload.php

     
    159159                        break;
    160160        }
    161161
     162        /**
     163         * A filter that allows for handling of custom bulk actions.
     164         *
     165         * The dynamic portion of the hook name, `$current_screen->id`, refers
     166         * to the ID of the current screen, usually a string.
     167         *
     168         * @since 4.4.0
     169         *
     170         * @param string $location A string containing the post-action redirect URI
     171         * @param array $post_ids An array of the selected objects to execute action on
     172         * @param string $doaction The current bulk action
     173         */
     174        $location = apply_filters("handle_other_bulk_action-{$current_screen->id}", $location, $post_ids, $doaction );
     175
    162176        wp_redirect( $location );
    163177        exit;
    164178} elseif ( ! empty( $_GET['_wp_http_referer'] ) ) {
  • src/wp-admin/users.php

     
    9696
    9797switch ( $wp_list_table->current_action() ) {
    9898
    99 /* Bulk Dropdown menu Role changes */
    100 case 'promote':
    101         check_admin_referer('bulk-users');
    102 
    103         if ( ! current_user_can( 'promote_users' ) )
    104                 wp_die( __( 'You can’t edit that user.' ) );
    105 
    106         if ( empty($_REQUEST['users']) ) {
    107                 wp_redirect($redirect);
    108                 exit();
    109         }
    110 
    111         $editable_roles = get_editable_roles();
    112         if ( empty( $editable_roles[$_REQUEST['new_role']] ) )
    113                 wp_die(__('You can’t give users that role.'));
    114 
    115         $userids = $_REQUEST['users'];
    116         $update = 'promote';
    117         foreach ( $userids as $id ) {
    118                 $id = (int) $id;
    119 
    120                 if ( ! current_user_can('promote_user', $id) )
    121                         wp_die(__('You can’t edit that user.'));
    122                 // The new role of the current user must also have the promote_users cap or be a multisite super admin
    123                 if ( $id == $current_user->ID && ! $wp_roles->role_objects[ $_REQUEST['new_role'] ]->has_cap('promote_users')
    124                         && ! ( is_multisite() && is_super_admin() ) ) {
    125                                 $update = 'err_admin_role';
    126                                 continue;
     99        /* Bulk Dropdown menu Role changes */
     100        case 'promote':
     101                check_admin_referer('bulk-users');
     102       
     103                if ( ! current_user_can( 'promote_users' ) )
     104                        wp_die( __( 'You can’t edit that user.' ) );
     105       
     106                if ( empty($_REQUEST['users']) ) {
     107                        wp_redirect($redirect);
     108                        exit();
    127109                }
    128 
    129                 // If the user doesn't already belong to the blog, bail.
    130                 if ( is_multisite() && !is_user_member_of_blog( $id ) )
    131                         wp_die( __( 'Cheatin’ uh?' ), 403 );
    132 
    133                 $user = get_userdata( $id );
    134                 $user->set_role($_REQUEST['new_role']);
    135         }
    136 
    137         wp_redirect(add_query_arg('update', $update, $redirect));
    138         exit();
    139 
    140 case 'dodelete':
    141         if ( is_multisite() )
    142                 wp_die( __('User deletion is not allowed from this screen.') );
    143 
    144         check_admin_referer('delete-users');
    145 
    146         if ( empty($_REQUEST['users']) ) {
    147                 wp_redirect($redirect);
     110       
     111                $editable_roles = get_editable_roles();
     112                if ( empty( $editable_roles[$_REQUEST['new_role']] ) )
     113                        wp_die(__('You can’t give users that role.'));
     114       
     115                $userids = $_REQUEST['users'];
     116                $update = 'promote';
     117                foreach ( $userids as $id ) {
     118                        $id = (int) $id;
     119       
     120                        if ( ! current_user_can('promote_user', $id) )
     121                                wp_die(__('You can’t edit that user.'));
     122                        // The new role of the current user must also have the promote_users cap or be a multisite super admin
     123                        if ( $id == $current_user->ID && ! $wp_roles->role_objects[ $_REQUEST['new_role'] ]->has_cap('promote_users')
     124                                && ! ( is_multisite() && is_super_admin() ) ) {
     125                                        $update = 'err_admin_role';
     126                                        continue;
     127                        }
     128       
     129                        // If the user doesn't already belong to the blog, bail.
     130                        if ( is_multisite() && !is_user_member_of_blog( $id ) )
     131                                wp_die( __( 'Cheatin’ uh?' ), 403 );
     132       
     133                        $user = get_userdata( $id );
     134                        $user->set_role($_REQUEST['new_role']);
     135                }
     136       
     137                wp_redirect(add_query_arg('update', $update, $redirect));
    148138                exit();
    149         }
    150 
    151         $userids = array_map( 'intval', (array) $_REQUEST['users'] );
    152 
    153         if ( empty( $_REQUEST['delete_option'] ) ) {
    154                 $url = self_admin_url( 'users.php?action=delete&users[]=' . implode( '&users[]=', $userids ) . '&error=true' );
    155                 $url = str_replace( '&', '&', wp_nonce_url( $url, 'bulk-users' ) );
    156                 wp_redirect( $url );
    157                 exit;
    158         }
    159 
    160         if ( ! current_user_can( 'delete_users' ) )
    161                 wp_die(__('You can’t delete users.'));
    162 
    163         $update = 'del';
    164         $delete_count = 0;
    165 
    166         foreach ( $userids as $id ) {
    167                 if ( ! current_user_can( 'delete_user', $id ) )
    168                         wp_die(__( 'You can’t delete that user.' ) );
    169 
    170                 if ( $id == $current_user->ID ) {
    171                         $update = 'err_admin_del';
    172                         continue;
     139       
     140        case 'dodelete':
     141                if ( is_multisite() )
     142                        wp_die( __('User deletion is not allowed from this screen.') );
     143       
     144                check_admin_referer('delete-users');
     145       
     146                if ( empty($_REQUEST['users']) ) {
     147                        wp_redirect($redirect);
     148                        exit();
    173149                }
    174                 switch ( $_REQUEST['delete_option'] ) {
    175                 case 'delete':
    176                         wp_delete_user( $id );
    177                         break;
    178                 case 'reassign':
    179                         wp_delete_user( $id, $_REQUEST['reassign_user'] );
    180                         break;
     150       
     151                $userids = array_map( 'intval', (array) $_REQUEST['users'] );
     152       
     153                if ( empty( $_REQUEST['delete_option'] ) ) {
     154                        $url = self_admin_url( 'users.php?action=delete&users[]=' . implode( '&users[]=', $userids ) . '&error=true' );
     155                        $url = str_replace( '&', '&', wp_nonce_url( $url, 'bulk-users' ) );
     156                        wp_redirect( $url );
     157                        exit;
    181158                }
    182                 ++$delete_count;
    183         }
    184 
    185         $redirect = add_query_arg( array('delete_count' => $delete_count, 'update' => $update), $redirect);
    186         wp_redirect($redirect);
    187         exit();
    188 
    189 case 'delete':
    190         if ( is_multisite() )
    191                 wp_die( __('User deletion is not allowed from this screen.') );
    192 
    193         check_admin_referer('bulk-users');
    194 
    195         if ( empty($_REQUEST['users']) && empty($_REQUEST['user']) ) {
     159       
     160                if ( ! current_user_can( 'delete_users' ) )
     161                        wp_die(__('You can’t delete users.'));
     162       
     163                $update = 'del';
     164                $delete_count = 0;
     165       
     166                foreach ( $userids as $id ) {
     167                        if ( ! current_user_can( 'delete_user', $id ) )
     168                                wp_die(__( 'You can’t delete that user.' ) );
     169       
     170                        if ( $id == $current_user->ID ) {
     171                                $update = 'err_admin_del';
     172                                continue;
     173                        }
     174                        switch ( $_REQUEST['delete_option'] ) {
     175                        case 'delete':
     176                                wp_delete_user( $id );
     177                                break;
     178                        case 'reassign':
     179                                wp_delete_user( $id, $_REQUEST['reassign_user'] );
     180                                break;
     181                        }
     182                        ++$delete_count;
     183                }
     184       
     185                $redirect = add_query_arg( array('delete_count' => $delete_count, 'update' => $update), $redirect);
    196186                wp_redirect($redirect);
    197187                exit();
    198         }
    199 
    200         if ( ! current_user_can( 'delete_users' ) )
    201                 $errors = new WP_Error( 'edit_users', __( 'You can’t delete users.' ) );
    202 
    203         if ( empty($_REQUEST['users']) )
    204                 $userids = array( intval( $_REQUEST['user'] ) );
    205         else
    206                 $userids = array_map( 'intval', (array) $_REQUEST['users'] );
    207 
    208         add_action( 'admin_head', 'delete_users_add_js' );
    209 
    210         include( ABSPATH . 'wp-admin/admin-header.php' );
    211 ?>
    212 <form method="post" name="updateusers" id="updateusers">
    213 <?php wp_nonce_field('delete-users') ?>
    214 <?php echo $referer; ?>
    215 
    216 <div class="wrap">
    217 <h1><?php _e( 'Delete Users' ); ?></h1>
    218 <?php if ( isset( $_REQUEST['error'] ) ) : ?>
    219         <div class="error">
    220                 <p><strong><?php _e( 'ERROR:' ); ?></strong> <?php _e( 'Please select an option.' ); ?></p>
    221         </div>
    222 <?php endif; ?>
    223 
    224 <?php if ( 1 == count( $userids ) ) : ?>
    225         <p><?php _e( 'You have specified this user for deletion:' ); ?></p>
    226 <?php else : ?>
    227         <p><?php _e( 'You have specified these users for deletion:' ); ?></p>
    228 <?php endif; ?>
    229 
    230 <ul>
    231 <?php
    232         $go_delete = 0;
    233         foreach ( $userids as $id ) {
    234                 $user = get_userdata( $id );
    235                 if ( $id == $current_user->ID ) {
    236                         echo "<li>" . sprintf(__('ID #%1$s: %2$s <strong>The current user will not be deleted.</strong>'), $id, $user->user_login) . "</li>\n";
    237                 } else {
    238                         echo "<li><input type=\"hidden\" name=\"users[]\" value=\"" . esc_attr($id) . "\" />" . sprintf(__('ID #%1$s: %2$s'), $id, $user->user_login) . "</li>\n";
    239                         $go_delete++;
     188       
     189        case 'delete':
     190                if ( is_multisite() )
     191                        wp_die( __('User deletion is not allowed from this screen.') );
     192       
     193                check_admin_referer('bulk-users');
     194       
     195                if ( empty($_REQUEST['users']) && empty($_REQUEST['user']) ) {
     196                        wp_redirect($redirect);
     197                        exit();
    240198                }
    241         }
     199       
     200                if ( ! current_user_can( 'delete_users' ) )
     201                        $errors = new WP_Error( 'edit_users', __( 'You can&#8217;t delete users.' ) );
     202       
     203                if ( empty($_REQUEST['users']) )
     204                        $userids = array( intval( $_REQUEST['user'] ) );
     205                else
     206                        $userids = array_map( 'intval', (array) $_REQUEST['users'] );
     207       
     208                add_action( 'admin_head', 'delete_users_add_js' );
     209       
     210                include( ABSPATH . 'wp-admin/admin-header.php' );
    242211        ?>
    243         </ul>
    244 <?php if ( $go_delete ) : ?>
    245         <?php if ( 1 == $go_delete ) : ?>
    246                 <fieldset><p><legend><?php _e( 'What should be done with content owned by this user?' ); ?></legend></p>
     212        <form method="post" name="updateusers" id="updateusers">
     213        <?php wp_nonce_field('delete-users') ?>
     214        <?php echo $referer; ?>
     215       
     216        <div class="wrap">
     217        <h1><?php _e( 'Delete Users' ); ?></h1>
     218        <?php if ( isset( $_REQUEST['error'] ) ) : ?>
     219                <div class="error">
     220                        <p><strong><?php _e( 'ERROR:' ); ?></strong> <?php _e( 'Please select an option.' ); ?></p>
     221                </div>
     222        <?php endif; ?>
     223       
     224        <?php if ( 1 == count( $userids ) ) : ?>
     225                <p><?php _e( 'You have specified this user for deletion:' ); ?></p>
    247226        <?php else : ?>
    248                 <fieldset><p><legend><?php _e( 'What should be done with content owned by these users?' ); ?></legend></p>
     227                <p><?php _e( 'You have specified these users for deletion:' ); ?></p>
    249228        <?php endif; ?>
    250         <ul style="list-style:none;">
    251                 <li><label><input type="radio" id="delete_option0" name="delete_option" value="delete" />
    252                 <?php _e('Delete all content.'); ?></label></li>
    253                 <li><input type="radio" id="delete_option1" name="delete_option" value="reassign" />
    254                 <?php echo '<label for="delete_option1">' . __( 'Attribute all content to:' ) . '</label> ';
    255                 wp_dropdown_users( array( 'name' => 'reassign_user', 'exclude' => array_diff( $userids, array($current_user->ID) ) ) ); ?></li>
    256         </ul></fieldset>
     229       
     230        <ul>
    257231        <?php
    258         /**
    259          * Fires at the end of the delete users form prior to the confirm button.
    260          *
    261          * @since 4.0.0
    262          *
    263          * @param WP_User $current_user WP_User object for the user being deleted.
    264          */
    265         do_action( 'delete_user_form', $current_user );
    266         ?>
    267         <input type="hidden" name="action" value="dodelete" />
    268         <?php submit_button( __('Confirm Deletion'), 'secondary' ); ?>
    269 <?php else : ?>
    270         <p><?php _e('There are no valid users selected for deletion.'); ?></p>
    271 <?php endif; ?>
    272 </div>
    273 </form>
    274 <?php
    275 
    276 break;
    277 
    278 case 'doremove':
    279         check_admin_referer('remove-users');
    280 
    281         if ( ! is_multisite() )
    282                 wp_die( __( 'You can&#8217;t remove users.' ) );
    283 
    284         if ( empty($_REQUEST['users']) ) {
    285                 wp_redirect($redirect);
    286                 exit;
    287         }
    288 
    289         if ( ! current_user_can( 'remove_users' ) )
    290                 wp_die( __( 'You can&#8217;t remove users.' ) );
    291 
    292         $userids = $_REQUEST['users'];
    293 
    294         $update = 'remove';
    295         foreach ( $userids as $id ) {
    296                 $id = (int) $id;
    297                 if ( $id == $current_user->ID && !is_super_admin() ) {
    298                         $update = 'err_admin_remove';
    299                         continue;
     232                $go_delete = 0;
     233                foreach ( $userids as $id ) {
     234                        $user = get_userdata( $id );
     235                        if ( $id == $current_user->ID ) {
     236                                echo "<li>" . sprintf(__('ID #%1$s: %2$s <strong>The current user will not be deleted.</strong>'), $id, $user->user_login) . "</li>\n";
     237                        } else {
     238                                echo "<li><input type=\"hidden\" name=\"users[]\" value=\"" . esc_attr($id) . "\" />" . sprintf(__('ID #%1$s: %2$s'), $id, $user->user_login) . "</li>\n";
     239                                $go_delete++;
     240                        }
    300241                }
    301                 if ( !current_user_can('remove_user', $id) ) {
    302                         $update = 'err_admin_remove';
    303                         continue;
     242                ?>
     243                </ul>
     244        <?php if ( $go_delete ) : ?>
     245                <?php if ( 1 == $go_delete ) : ?>
     246                        <fieldset><p><legend><?php _e( 'What should be done with content owned by this user?' ); ?></legend></p>
     247                <?php else : ?>
     248                        <fieldset><p><legend><?php _e( 'What should be done with content owned by these users?' ); ?></legend></p>
     249                <?php endif; ?>
     250                <ul style="list-style:none;">
     251                        <li><label><input type="radio" id="delete_option0" name="delete_option" value="delete" />
     252                        <?php _e('Delete all content.'); ?></label></li>
     253                        <li><input type="radio" id="delete_option1" name="delete_option" value="reassign" />
     254                        <?php echo '<label for="delete_option1">' . __( 'Attribute all content to:' ) . '</label> ';
     255                        wp_dropdown_users( array( 'name' => 'reassign_user', 'exclude' => array_diff( $userids, array($current_user->ID) ) ) ); ?></li>
     256                </ul></fieldset>
     257                <?php
     258                /**
     259                 * Fires at the end of the delete users form prior to the confirm button.
     260                 *
     261                 * @since 4.0.0
     262                 *
     263                 * @param WP_User $current_user WP_User object for the user being deleted.
     264                 */
     265                do_action( 'delete_user_form', $current_user );
     266                ?>
     267                <input type="hidden" name="action" value="dodelete" />
     268                <?php submit_button( __('Confirm Deletion'), 'secondary' ); ?>
     269        <?php else : ?>
     270                <p><?php _e('There are no valid users selected for deletion.'); ?></p>
     271        <?php endif; ?>
     272        </div>
     273        </form>
     274        <?php
     275       
     276        break;
     277       
     278        case 'doremove':
     279                check_admin_referer('remove-users');
     280       
     281                if ( ! is_multisite() )
     282                        wp_die( __( 'You can&#8217;t remove users.' ) );
     283       
     284                if ( empty($_REQUEST['users']) ) {
     285                        wp_redirect($redirect);
     286                        exit;
    304287                }
    305                 remove_user_from_blog($id, $blog_id);
    306         }
    307 
    308         $redirect = add_query_arg( array('update' => $update), $redirect);
    309         wp_redirect($redirect);
    310         exit;
    311 
    312 case 'remove':
    313 
    314         check_admin_referer('bulk-users');
    315 
    316         if ( ! is_multisite() )
    317                 wp_die( __( 'You can&#8217;t remove users.' ) );
    318 
    319         if ( empty($_REQUEST['users']) && empty($_REQUEST['user']) ) {
    320                 wp_redirect($redirect);
    321                 exit();
    322         }
    323 
    324         if ( !current_user_can('remove_users') )
    325                 $error = new WP_Error('edit_users', __('You can&#8217;t remove users.'));
    326 
    327         if ( empty($_REQUEST['users']) )
    328                 $userids = array(intval($_REQUEST['user']));
    329         else
     288       
     289                if ( ! current_user_can( 'remove_users' ) )
     290                        wp_die( __( 'You can&#8217;t remove users.' ) );
     291       
    330292                $userids = $_REQUEST['users'];
    331 
    332         include( ABSPATH . 'wp-admin/admin-header.php' );
    333 ?>
    334 <form method="post" name="updateusers" id="updateusers">
    335 <?php wp_nonce_field('remove-users') ?>
    336 <?php echo $referer; ?>
    337 
    338 <div class="wrap">
    339 <h1><?php _e( 'Remove Users from Site' ); ?></h1>
    340 
    341 <?php if ( 1 == count( $userids ) ) : ?>
    342         <p><?php _e( 'You have specified this user for removal:' ); ?></p>
    343 <?php else : ?>
    344         <p><?php _e( 'You have specified these users for removal:' ); ?></p>
    345 <?php endif; ?>
    346 
    347 <ul>
    348 <?php
    349         $go_remove = false;
    350         foreach ( $userids as $id ) {
    351                 $id = (int) $id;
    352                 $user = get_userdata( $id );
    353                 if ( $id == $current_user->ID && !is_super_admin() ) {
    354                         echo "<li>" . sprintf(__('ID #%1$s: %2$s <strong>The current user will not be removed.</strong>'), $id, $user->user_login) . "</li>\n";
    355                 } elseif ( !current_user_can('remove_user', $id) ) {
    356                         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";
    357                 } else {
    358                         echo "<li><input type=\"hidden\" name=\"users[]\" value=\"{$id}\" />" . sprintf(__('ID #%1$s: %2$s'), $id, $user->user_login) . "</li>\n";
    359                         $go_remove = true;
     293       
     294                $update = 'remove';
     295            foreach ( $userids as $id ) {
     296                        $id = (int) $id;
     297                        if ( $id == $current_user->ID && !is_super_admin() ) {
     298                                $update = 'err_admin_remove';
     299                                continue;
     300                        }
     301                        if ( !current_user_can('remove_user', $id) ) {
     302                                $update = 'err_admin_remove';
     303                                continue;
     304                        }
     305                        remove_user_from_blog($id, $blog_id);
    360306                }
    361         }
    362         ?>
    363 </ul>
    364 <?php if ( $go_remove ) : ?>
    365                 <input type="hidden" name="action" value="doremove" />
    366                 <?php submit_button( __('Confirm Removal'), 'secondary' ); ?>
    367 <?php else : ?>
    368         <p><?php _e('There are no valid users selected for removal.'); ?></p>
    369 <?php endif; ?>
    370 </div>
    371 </form>
    372 <?php
    373 
    374 break;
    375 
    376 default:
    377 
    378         if ( !empty($_GET['_wp_http_referer']) ) {
    379                 wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce'), wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
     307       
     308                $redirect = add_query_arg( array('update' => $update), $redirect);
     309                wp_redirect($redirect);
    380310                exit;
    381         }
    382 
    383         $wp_list_table->prepare_items();
    384         $total_pages = $wp_list_table->get_pagination_arg( 'total_pages' );
    385         if ( $pagenum > $total_pages && $total_pages > 0 ) {
    386                 wp_redirect( add_query_arg( 'paged', $total_pages ) );
    387                 exit;
    388         }
    389 
    390         include( ABSPATH . 'wp-admin/admin-header.php' );
    391 
    392         $messages = array();
    393         if ( isset($_GET['update']) ) :
    394                 switch($_GET['update']) {
    395                 case 'del':
    396                 case 'del_many':
    397                         $delete_count = isset($_GET['delete_count']) ? (int) $_GET['delete_count'] : 0;
    398                         if ( 1 == $delete_count ) {
    399                                 $message = __( 'User deleted.' );
     311       
     312        case 'remove':
     313       
     314                check_admin_referer('bulk-users');
     315       
     316                if ( ! is_multisite() )
     317                        wp_die( __( 'You can&#8217;t remove users.' ) );
     318       
     319                if ( empty($_REQUEST['users']) && empty($_REQUEST['user']) ) {
     320                        wp_redirect($redirect);
     321                        exit();
     322                }
     323       
     324                if ( !current_user_can('remove_users') )
     325                        $error = new WP_Error('edit_users', __('You can&#8217;t remove users.'));
     326       
     327                if ( empty($_REQUEST['users']) )
     328                        $userids = array(intval($_REQUEST['user']));
     329                else
     330                        $userids = $_REQUEST['users'];
     331       
     332                include( ABSPATH . 'wp-admin/admin-header.php' );
     333        ?>
     334        <form method="post" name="updateusers" id="updateusers">
     335        <?php wp_nonce_field('remove-users') ?>
     336        <?php echo $referer; ?>
     337       
     338        <div class="wrap">
     339        <h1><?php _e( 'Remove Users from Site' ); ?></h1>
     340       
     341        <?php if ( 1 == count( $userids ) ) : ?>
     342                <p><?php _e( 'You have specified this user for removal:' ); ?></p>
     343        <?php else : ?>
     344                <p><?php _e( 'You have specified these users for removal:' ); ?></p>
     345        <?php endif; ?>
     346       
     347        <ul>
     348        <?php
     349                $go_remove = false;
     350            foreach ( $userids as $id ) {
     351                        $id = (int) $id;
     352                $user = get_userdata( $id );
     353                        if ( $id == $current_user->ID && !is_super_admin() ) {
     354                                echo "<li>" . sprintf(__('ID #%1$s: %2$s <strong>The current user will not be removed.</strong>'), $id, $user->user_login) . "</li>\n";
     355                        } elseif ( !current_user_can('remove_user', $id) ) {
     356                                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";
    400357                        } else {
    401                                 $message = _n( '%s user deleted.', '%s users deleted.', $delete_count );
     358                                echo "<li><input type=\"hidden\" name=\"users[]\" value=\"{$id}\" />" . sprintf(__('ID #%1$s: %2$s'), $id, $user->user_login) . "</li>\n";
     359                                $go_remove = true;
    402360                        }
    403                         $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . sprintf( $message, number_format_i18n( $delete_count ) ) . '</p></div>';
    404                         break;
    405                 case 'add':
    406                         if ( isset( $_GET['id'] ) && ( $user_id = $_GET['id'] ) && current_user_can( 'edit_user', $user_id ) ) {
    407                                 $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . sprintf( __( 'New user created. <a href="%s">Edit user</a>' ),
    408                                         esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ),
    409                                                 self_admin_url( 'user-edit.php?user_id=' . $user_id ) ) ) ) . '</p></div>';
    410                         } else {
    411                                 $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __( 'New user created.' ) . '</p></div>';
     361            }
     362            ?>
     363        </ul>
     364        <?php if ( $go_remove ) : ?>
     365                        <input type="hidden" name="action" value="doremove" />
     366                        <?php submit_button( __('Confirm Removal'), 'secondary' ); ?>
     367        <?php else : ?>
     368                <p><?php _e('There are no valid users selected for removal.'); ?></p>
     369        <?php endif; ?>
     370        </div>
     371        </form>
     372        <?php
     373       
     374        break;
     375       
     376        default:
     377       
     378                if ( !empty($_GET['_wp_http_referer']) ) {
     379                        wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce'), wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
     380                        exit;
     381                }
     382               
     383                if ( !empty($_REQUEST['users']) ) {
     384                        $custom_redirect = wp_get_referer();
     385                       
     386                        /**
     387                         * A filter that allows for handling of custom bulk actions.
     388                         *
     389                         * The dynamic portion of the hook name, `$current_screen->id`, refers
     390                         * to the ID of the current screen, usually a string.
     391                         *
     392                         * @since 4.4.0
     393                         *
     394                         * @param string $custom_redirect A string containing the post-action redirect URI
     395                         * @param array $_REQUEST['users'] An array of the selected objects to execute action on
     396                         * @param string $wp_list_table->current_action() The current bulk action
     397                         */
     398                        $custom_redirect = apply_filters("handle_other_bulk_action-{$current_screen->id}", $custom_redirect, $_REQUEST['users'], $wp_list_table->current_action() );
     399                       
     400                        if ( $custom_redirect ) {
     401                                wp_redirect( $custom_redirect );
     402                                exit;
    412403                        }
    413                         break;
    414                 case 'promote':
    415                         $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __('Changed roles.') . '</p></div>';
    416                         break;
    417                 case 'err_admin_role':
    418                         $messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __('The current user&#8217;s role must have user editing capabilities.') . '</p></div>';
    419                         $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __('Other user roles have been changed.') . '</p></div>';
    420                         break;
    421                 case 'err_admin_del':
    422                         $messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __('You can&#8217;t delete the current user.') . '</p></div>';
    423                         $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __('Other users have been deleted.') . '</p></div>';
    424                         break;
    425                 case 'remove':
    426                         $messages[] = '<div id="message" class="updated notice is-dismissible fade"><p>' . __('User removed from this site.') . '</p></div>';
    427                         break;
    428                 case 'err_admin_remove':
    429                         $messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __("You can't remove the current user.") . '</p></div>';
    430                         $messages[] = '<div id="message" class="updated notice is-dismissible fade"><p>' . __('Other users have been removed.') . '</p></div>';
    431                         break;
    432404                }
    433         endif; ?>
    434 
    435 <?php if ( isset($errors) && is_wp_error( $errors ) ) : ?>
    436         <div class="error">
    437                 <ul>
    438                 <?php
    439                         foreach ( $errors->get_error_messages() as $err )
    440                                 echo "<li>$err</li>\n";
    441                 ?>
    442                 </ul>
     405       
     406                $wp_list_table->prepare_items();
     407                $total_pages = $wp_list_table->get_pagination_arg( 'total_pages' );
     408                if ( $pagenum > $total_pages && $total_pages > 0 ) {
     409                        wp_redirect( add_query_arg( 'paged', $total_pages ) );
     410                        exit;
     411                }
     412       
     413                include( ABSPATH . 'wp-admin/admin-header.php' );
     414       
     415                $messages = array();
     416                if ( isset($_GET['update']) ) :
     417                        switch($_GET['update']) {
     418                        case 'del':
     419                        case 'del_many':
     420                                $delete_count = isset($_GET['delete_count']) ? (int) $_GET['delete_count'] : 0;
     421                                if ( 1 == $delete_count ) {
     422                                        $message = __( 'User deleted.' );
     423                                } else {
     424                                        $message = _n( '%s user deleted.', '%s users deleted.', $delete_count );
     425                                }
     426                                $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . sprintf( $message, number_format_i18n( $delete_count ) ) . '</p></div>';
     427                                break;
     428                        case 'add':
     429                                if ( isset( $_GET['id'] ) && ( $user_id = $_GET['id'] ) && current_user_can( 'edit_user', $user_id ) ) {
     430                                        $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . sprintf( __( 'New user created. <a href="%s">Edit user</a>' ),
     431                                                esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ),
     432                                                        self_admin_url( 'user-edit.php?user_id=' . $user_id ) ) ) ) . '</p></div>';
     433                                } else {
     434                                        $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __( 'New user created.' ) . '</p></div>';
     435                                }
     436                                break;
     437                        case 'promote':
     438                                $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __('Changed roles.') . '</p></div>';
     439                                break;
     440                        case 'err_admin_role':
     441                                $messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __('The current user&#8217;s role must have user editing capabilities.') . '</p></div>';
     442                                $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __('Other user roles have been changed.') . '</p></div>';
     443                                break;
     444                        case 'err_admin_del':
     445                                $messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __('You can&#8217;t delete the current user.') . '</p></div>';
     446                                $messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __('Other users have been deleted.') . '</p></div>';
     447                                break;
     448                        case 'remove':
     449                                $messages[] = '<div id="message" class="updated notice is-dismissible fade"><p>' . __('User removed from this site.') . '</p></div>';
     450                                break;
     451                        case 'err_admin_remove':
     452                                $messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __("You can't remove the current user.") . '</p></div>';
     453                                $messages[] = '<div id="message" class="updated notice is-dismissible fade"><p>' . __('Other users have been removed.') . '</p></div>';
     454                                break;
     455                        }
     456                endif; ?>
     457       
     458        <?php if ( isset($errors) && is_wp_error( $errors ) ) : ?>
     459                <div class="error">
     460                        <ul>
     461                        <?php
     462                                foreach ( $errors->get_error_messages() as $err )
     463                                        echo "<li>$err</li>\n";
     464                        ?>
     465                        </ul>
     466                </div>
     467        <?php endif;
     468       
     469        if ( ! empty($messages) ) {
     470                foreach ( $messages as $msg )
     471                        echo $msg;
     472        } ?>
     473       
     474        <div class="wrap">
     475        <h1>
     476        <?php
     477        echo esc_html( $title );
     478        if ( current_user_can( 'create_users' ) ) { ?>
     479                <a href="user-new.php" class="page-title-action"><?php echo esc_html_x( 'Add New', 'user' ); ?></a>
     480        <?php } elseif ( is_multisite() && current_user_can( 'promote_users' ) ) { ?>
     481                <a href="user-new.php" class="page-title-action"><?php echo esc_html_x( 'Add Existing', 'user' ); ?></a>
     482        <?php }
     483       
     484        if ( $usersearch )
     485                printf( '<span class="subtitle">' . __('Search results for &#8220;%s&#8221;') . '</span>', esc_html( $usersearch ) ); ?>
     486        </h1>
     487       
     488        <?php $wp_list_table->views(); ?>
     489       
     490        <form method="get">
     491       
     492        <?php $wp_list_table->search_box( __( 'Search Users' ), 'user' ); ?>
     493       
     494        <?php $wp_list_table->display(); ?>
     495        </form>
     496       
     497        <br class="clear" />
    443498        </div>
    444 <?php endif;
     499        <?php
     500        break;
    445501
    446 if ( ! empty($messages) ) {
    447         foreach ( $messages as $msg )
    448                 echo $msg;
    449 } ?>
    450 
    451 <div class="wrap">
    452 <h1>
    453 <?php
    454 echo esc_html( $title );
    455 if ( current_user_can( 'create_users' ) ) { ?>
    456         <a href="user-new.php" class="page-title-action"><?php echo esc_html_x( 'Add New', 'user' ); ?></a>
    457 <?php } elseif ( is_multisite() && current_user_can( 'promote_users' ) ) { ?>
    458         <a href="user-new.php" class="page-title-action"><?php echo esc_html_x( 'Add Existing', 'user' ); ?></a>
    459 <?php }
    460 
    461 if ( $usersearch )
    462         printf( '<span class="subtitle">' . __('Search results for &#8220;%s&#8221;') . '</span>', esc_html( $usersearch ) ); ?>
    463 </h1>
    464 
    465 <?php $wp_list_table->views(); ?>
    466 
    467 <form method="get">
    468 
    469 <?php $wp_list_table->search_box( __( 'Search Users' ), 'user' ); ?>
    470 
    471 <?php $wp_list_table->display(); ?>
    472 </form>
    473 
    474 <br class="clear" />
    475 </div>
    476 <?php
    477 break;
    478 
    479502} // end of the $doaction switch
    480503
    481504include( ABSPATH . 'wp-admin/admin-footer.php' );