5

I want to update the confirmation form for delete user.

If user has posts, it shows Attribute all content to - option to reassign other author for his posts. It takes lots-of time to load the page, if there are thousands of users in the system. (we have 55k+ users)

So, I want to change the User option (Attribute all content to) from Drop-down to Type and Search.

I've tried to found the hooks/action but could not found that I want. I don't want to update wordpress core files to change this.

Please suggest me hooks/action for my question.

Thanks.

enter image description here

8
  • Have you already solved this?
    – Sally CJ
    Mar 28, 2020 at 22:06
  • @SallyCJ I don't think so. do you have solution for this yet? Mar 30, 2020 at 11:47
  • The form has not the option to remove or change this field. So add a custom filed via hook delete_user_form and remove the default select via JavaScript.
    – bueltge
    Mar 30, 2020 at 12:48
  • @MaulikVora (and @HasmukhKalsariya), try the solution in my answer? :) I hope it works for you!
    – Sally CJ
    Mar 30, 2020 at 21:49
  • 2
    @SallyCJ. I Appreciate your answer, it's exactly what I want. Thank you so much Apr 4, 2020 at 11:59

1 Answer 1

7
+50

On the Users (wp-admin/users.php) page, WordPress uses wp_dropdown_users() to generate the users drop-down menu you're referring to, so I'd suggest using the wp_dropdown_users_args hook to filter the users query, e.g. to show only 1 result (or 10, but surely not 55k!) and then use JavaScript to add/load the other results.

So in this answer, I'm going to show you how you can do that, where we use Select2 to add the "type and search" functionality. Note that I'm using a custom REST API endpoint which returns the results in the format expected by Select2 and that way, the JavaScript part/code would also be simpler for us (i.e. the code is shorter).

Step #1: Filter the users query for the reassign_user drop-down menu.

function my_filter_reassign_user_query( $query_args, $parsed_args ) {
    // Make sure we're on the users.php page on the admin side.
    if ( is_admin() && 'users' === get_current_screen()->id          &&
        // .. and the action is deleting a user
        ( isset( $_GET['action'] ) && 'delete' === $_GET['action'] ) &&
        // .. and the <select>'s name is set to reassign_user.
        'reassign_user' === $parsed_args['name']
    ) {
        // You can also use 10, etc., but the point is, we don't want 55k (or
        // LOTS OF) <option> tags!
        $query_args['number'] = 1;
    }

    return $query_args;
}
add_filter( 'wp_dropdown_users_args', 'my_filter_reassign_user_query', 10, 2 );

Step #2: Enqueue the Select2 scripts and styles, and our AJAX script.

function my_enqueue_select2_scripts() {
    // Make sure we're on the users.php page on the admin side.
    if ( is_admin() && 'users' === get_current_screen()->id ) {
        wp_enqueue_style( 'select2', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/css/select2.min.css', [], null );
        wp_enqueue_script( 'select2', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/js/select2.full.min.js', [], null );

        wp_enqueue_script( 'users-ajax', '/path/to/users-ajax.js', [ 'select2', 'jquery' ], '1.0' );
        wp_localize_script( 'users-ajax', 'users_ajax', [
            'root'  => esc_url_raw( get_rest_url() ),
            'nonce' => wp_create_nonce( 'wp_rest' ),
        ] );
    }
}
add_action( 'admin_enqueue_scripts', 'my_enqueue_select2_scripts' );

Step #3: Register the custom REST API endpoint.

I'm just giving you the code, so check out the official handbook if you haven't. You'd also want to check WP_User_Query::prepare_query() for the parameters you can use.

function my_select2_users( $request ) {
    $search   = $request->get_param( 'term' );     // the search keyword
    $per_page = $request->get_param( 'per_page' ); // results per page
    $page     = $request->get_param( 'page' );     // current page number

    $per_page = $per_page ? $per_page : 10;
    $page     = $page     ? $page     : 1;
    $args     = [
        'number'         => $per_page,
        'paged'          => $page,
        'search_columns' => [ 'user_login', 'display_name' ],
        'fields'         => [ 'ID', 'display_name', 'user_login' ],
        'who'            => 'authors',
    ];

    if ( $search ) {
        $args['search'] = '*' . sanitize_text_field( $search ) . '*';
    }

    $query = new WP_User_Query( $args );

    $items = [];
    foreach ( $query->get_results() as $user ) {
        $items[] = [
            'id'   => $user->ID,
            'text' => $user->display_name . ' (' . $user->user_login . ')',
        ];
    }

    return [
        'results'    => $items,
        'pagination' => [ 'more' => $page * $per_page < $query->get_total() ],
        'total'      => $query->get_total(),
    ];
}

add_action( 'rest_api_init', function () {
    // You should rename the my-plugin to a meaningful one..
    register_rest_route( 'my-plugin/v1', '/select2_users', [
        'methods'             => 'GET',
        'callback'            => 'my_select2_users',
        'permission_callback' => function () {
            return current_user_can( 'delete_users' );
        }
    ] );
} );

Step #4: The JavaScript/AJAX script (placed in users-ajax.js).

Check here for the Select2's parameters (like the ajax) you can use.

jQuery( function ( $ ) {
    $( 'select[name="reassign_user"]' ).on( 'select2:open', function () {
        $( '#delete_option1' ).prop( 'checked', true );
    } ).on( 'select2:select', function( e ) {
        $( '#submit' ).removeProp( 'disabled' );
    } ).on( 'select2:unselect', function( e ) {
        $( '#submit' ).prop( 'disabled', true );
    } ).select2( {
        ajax: {
            url: users_ajax.root + 'my-plugin/v1/select2_users',
            dataType: 'json',
            headers: { 'X-WP-NONCE': users_ajax.nonce }
        },
        minimumInputLength: 2
    } );
} );

When all code put together, you'd get something like so:

enter image description here

4
  • 2
    I haven't tested this myself but overall this looks like it could/should work. Nice work Sally CJ. Hoping the OP can let us know if this works. Mar 31, 2020 at 7:19
  • Thanks @TonyDjukic! I also hope the OP can test it soon.. :)
    – Sally CJ
    Mar 31, 2020 at 7:36
  • 1
    @SallyCJ awesome man! this worked like charm! thank you so much! you are genius! Apr 4, 2020 at 12:13
  • Thanks a lot for the bounty, @MaulikVora! And I'm glad the solution worked for you. :)
    – Sally CJ
    Apr 4, 2020 at 13:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.