How to add custom bulk actions in WordPress list tables?
Asked Answered
T

2

0

I am developing a plugin for that I have to black list users, so I need to be display one more dropdown item called Black List inside the Bulk Actions dropdown in the Users page, after the Delete option. But I'm unable to see from where these two actions are coming from and also how to black list a particular user.

My idea is to add one more field is_blacklisted in user table as Boolean with default value false and when apply Black List action it changes to true. Any other thoughts?

Trauma answered 8/5, 2014 at 12:6 Comment(0)
R
5

There's a filter, but it's only useful to remove bulk actions.

From this WPSE question, answer and comments, there's the following workaround: add a custom option to the dropdown with jQuery and hook into admin_action_$your-action to catch the submission.

The hook admin_footer-$current_page is used to print our JavaScript on a specific admin page (adjust to use in other screens).

add_action( 'admin_footer-users.php', 'bulk_footer_so_23541269' );
add_action( 'admin_action_black_list', 'bulk_request_so_23541269' );

function bulk_footer_so_23541269() 
{
    # global $typenow; if( $typenow != 'page' ) return; // if used on edit.php screen
    ?>
    <script type="text/javascript">
        jQuery(document).ready(function($) {
            $('<option>').val('black_list').text('Black list')
                .appendTo("select[name='action'], select[name='action2']");
        });
    </script>
    <?php
}

function bulk_request_so_23541269() 
{
    # Array with the selected User IDs
    wp_die( '<pre>' . print_r( $_REQUEST['users'], true ) . '</pre>' ); 
    // $_REQUEST['post'] if used on edit.php screen
}

Your doubt about blocking a user deserves another question, but I'd start a research here first.

Rota answered 8/5, 2014 at 15:35 Comment(2)
This is great. Is there any security problem with this solution?Diode
You can use check_admin_referer('bulk-posts') to check that it's coming from an admin page, see wp-admin/edit.php line 61Odious
U
5

Proper support with add_filter( 'bulk_actions-screenid', 'register_my_bulk_actions' ) is arriving in Wordpress 4.7 .

Quoting the announcement post:

To add an option in the Bulk Actions dropdown HTML element, register a callback on the bulk_actions-{screen_id} filter that adds the new option onto the array. Replace {screen_id} with the ID of the admin screen to offer the bulk action on.

To add a bulk action “Email to Eric,” we could use the following code:

add_filter( 'bulk_actions-edit-post', 'register_my_bulk_actions' );

function register_my_bulk_actions($bulk_actions) 
{
  $bulk_actions['email_to_eric'] = __( 'Email to Eric', 'email_to_eric');
  return $bulk_actions;
}

To handle a bulk action form submission, register a callback on the handle_bulk_actions-{screen_id} filter for the corresponding screen. The filter expects the redirect URL to be modified, so be sure to modify the passed $redirect_url. This allows us to carry success or failure state into the next request to display a notice to the user. The other callback arguments will differ depending on the screen here to include contextually relevant data.

To add a bulk action handler for emailing the selected posts, we could use the following code:

add_filter( 'handle_bulk_actions-edit-post', 'my_bulk_action_handler', 10, 3 );

function my_bulk_action_handler( $redirect_to, $doaction, $post_ids ) 
{
  if ( $doaction !== 'email_to_eric' ) {
    return $redirect_to;
  }
  foreach ( $post_ids as $post_id ) {
    // Perform action for each post.
  }
  $redirect_to = add_query_arg( 'bulk_emailed_posts', count( $post_ids ),  $redirect_to );
  return $redirect_to;
}

Showing notices: We could use the existing notice hooks to let the user know what happened, depending on the state we set in the URL:

add_action( 'admin_notices', 'my_bulk_action_admin_notice' );

function my_bulk_action_admin_notice() 
{
  if ( ! empty( $_REQUEST['bulk_emailed_posts'] ) ) {
    $emailed_count = intval( $_REQUEST['bulk_emailed_posts'] );
    printf( '<div id="message" class="updated fade">' .
      _n( 'Emailed %s post to Eric.',
        'Emailed %s posts to Eric.',
        $emailed_count,
        'email_to_eric'
      ) . '</div>', $emailed_count );
  }
}
Ung answered 26/10, 2016 at 11:59 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.