Custom bulk actions in WP 3.7.1

So I am trying to get a custom bulk action to work in WordPress 3.7.1 and so far no luck. The basis I am using is http://www.skyverge.com/blog/add-custom-bulk-action, and it goes wrong here:

$wp_list_table = _get_list_table('WP_Posts_List_Table');
$action = $wp_list_table->current_action();

The action itself is added with jQuery and does show.

Read More

When I use a prompt to show the $action value it is always empty, which means the rest of the script does not fire. Any idea here? The entire code:

<?php
/*
Plugin Name: FoxRunSoftware Custom Bulk Action Demo
Plugin URI: http://www.foxrunsoftware.net/articles/wordpress/add-custom-bulk-action/
Description: A working demonstration of a custom bulk action
Author: Justin Stern
Author URI: http://www.foxrunsoftware.net
Version: 0.1

Copyright: © 2012 Justin Stern (email : justin@foxrunsoftware.net)
License: GNU General Public License v3.0
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/

if (!class_exists('FRS_Custom_Bulk_Action')) {

    class FRS_Custom_Bulk_Action {

        public function __construct() {

            if(is_admin()) {
                // admin actions/filters
                add_action('admin_footer-edit.php', array(&$this, 'custom_bulk_admin_footer'));
                add_action('load-edit.php',         array(&$this,     'custom_bulk_action'));
            add_action('admin_notices',         array(&$this, 'custom_bulk_admin_notices'));
        }
    }


    /**
     * Step 1: add the custom Bulk Action to the select menus
     */
    function custom_bulk_admin_footer() {
        global $post_type;

        if($post_type == 'post') {
            ?>
                <script type="text/javascript">
                    jQuery(document).ready(function() {
                        jQuery('<option>').val('export').text('<?php _e('Export')?>').appendTo("select[name='action']");
                        jQuery('<option>').val('export').text('<?php _e('Export')?>').appendTo("select[name='action2']");
                    });
                </script>
            <?php
        }
    }


    /**
     * Step 2: handle the custom Bulk Action
     * 
     * Based on the post http://wordpress.stackexchange.com/questions/29822/custom-bulk-action
     */
    function custom_bulk_action() {
        global $typenow;
        $post_type = $typenow;

        if($post_type == 'post') {

            // get the action
            $wp_list_table = _get_list_table('WP_Posts_List_Table');  // depending on your resource type this could be WP_Users_List_Table, WP_Comments_List_Table, etc
            $action = $wp_list_table->current_action();

            $allowed_actions = array("export");
            if(!in_array($action, $allowed_actions)) return;

            // security check
            check_admin_referer('bulk-posts');

            // make sure ids are submitted.  depending on the resource type, this may be 'media' or 'ids'
            if(isset($_REQUEST['post'])) {
                $post_ids = array_map('intval', $_REQUEST['post']);
            }

            if(empty($post_ids)) return;

            // this is based on wp-admin/edit.php
            $sendback = remove_query_arg( array('exported', 'untrashed', 'deleted', 'ids'), wp_get_referer() );
            if ( ! $sendback )
                $sendback = admin_url( "edit.php?post_type=$post_type" );

            $pagenum = $wp_list_table->get_pagenum();
            $sendback = add_query_arg( 'paged', $pagenum, $sendback );

            switch($action) {
                case 'export':

                    // if we set up user permissions/capabilities, the code might look like:
                    //if ( !current_user_can($post_type_object->cap->export_post, $post_id) )
                    //  wp_die( __('You are not allowed to export this post.') );

                    $exported = 0;
                    foreach( $post_ids as $post_id ) {

                        if ( !$this->perform_export($post_id) )
                            wp_die( __('Error exporting post.') );

                        $exported++;
                    }

                    $sendback = add_query_arg( array('exported' => $exported, 'ids' => join(',', $post_ids) ), $sendback );
                break;

                default: return;
            }

            $sendback = remove_query_arg( array('action', 'action2', 'tags_input', 'post_author', 'comment_status', 'ping_status', '_status',  'post', 'bulk_edit', 'post_view'), $sendback );

            wp_redirect($sendback);
            exit();
        }
    }


    /**
     * Step 3: display an admin notice on the Posts page after exporting
     */
    function custom_bulk_admin_notices() {
        global $post_type, $pagenow;

        if($pagenow == 'edit.php' && $post_type == 'post' && isset($_REQUEST['exported']) && (int) $_REQUEST['exported']) {
            $message = sprintf( _n( 'Post exported.', '%s posts exported.', $_REQUEST['exported'] ), number_format_i18n( $_REQUEST['exported'] ) );
            echo "<div class="updated"><p>{$message}</p></div>";
        }
    }

    function perform_export($post_id) {
        // do whatever work needs to be done
        return true;
    }
}
}

new FRS_Custom_Bulk_Action();

Well there is some more info, it seems to me that WP_List_Table just returns empty values. The following is the content of $wp_list_table, any ideas?:

object(WP_Posts_List_Table)#8848 (10) { 
    ["hierarchical_display"]=> NULL 
    ["comment_pending_count"]=> NULL 
    ["user_posts_count"]=> NULL 
    ["sticky_posts_count"]=> int(0) 
    ["items"]=> NULL 
    ["_args"]=> array(4) { 
        ["plural"]=> string(5) "posts" 
        ["singular"]=> string(0) "" 
        ["ajax"]=> bool(false) 
        ["screen"]=> object(WP_Screen)#8846 (16) { 
            ["action"]=> string(0) "" 
            ["base"]=> string(4) "edit" 
            ["columns":"WP_Screen":private]=> int(0) 
            ["id"]=> string(15) "edit-shop_order" 
            ["in_admin":protected]=> string(4) "site" 
            ["is_network"]=> bool(false) 
            ["is_user"]=> bool(false) 
            ["parent_base"]=> NULL 
            ["parent_file"]=> NULL 
            ["post_type"]=> string(10) "shop_order" 
            ["taxonomy"]=> string(0) "" 
            ["_help_tabs":"WP_Screen":private]=> array(0) { } 
            ["_help_sidebar":"WP_Screen":private]=> string(0) "" 
            ["_options":"WP_Screen":private]=> array(0) { } 
            ["_show_screen_options":"WP_Screen":private]=> NULL 
            ["_screen_settings":"WP_Screen":private]=> NULL 
        } 
    } 
    ["_pagination_args"]=> array(0) { } 
    ["screen"]=> object(WP_Screen)#8846 (16) { 
        ["action"]=> string(0) "" 
        ["base"]=> string(4) "edit" 
        ["columns":"WP_Screen":private]=> int(0) 
        ["id"]=> string(15) "edit-shop_order" 
        ["in_admin":protected]=> string(4) "site" 
        ["is_network"]=> bool(false) 
        ["is_user"]=> bool(false) 
        ["parent_base"]=> NULL 
        ["parent_file"]=> NULL 
        ["post_type"]=> string(10) "shop_order" 
        ["taxonomy"]=> string(0) "" 
        ["_help_tabs":"WP_Screen":private]=> array(0) { } 
        ["_help_sidebar":"WP_Screen":private]=> string(0) "" 
        ["_options":"WP_Screen":private]=> array(0) { } 
        ["_show_screen_options":"WP_Screen":private]=> NULL 
        ["_screen_settings":"WP_Screen":private]=> NULL 
    } 
    ["_actions"]=> NULL ["_pagination"]=> NULL 
}

Related posts

2 comments

  1. You’re seeing $action empty because there is a redirect from wp-admin/edit.php.

    So, the output you are seeing is after the redirect.

    Use, die() after echo $action to see the output before the redirect.

  2. Looking at the page you’ve mentioned, I note that there’s a code snippet that’s missing some code. In the first code snippet after The Solution, there’s the following code snippet:

    add_action('admin_footer-edit.php', 'custom_bulk_admin_footer');
    
    function custom_bulk_admin_footer() {
    
      global $post_type;
    
      if($post_type == 'post') {
    
        ?>
    

    Then the author states As you can see, here we use javascript to inject our new bulk action item into the two bulk action select dropdowns on the Posts edit page. Only… there’s no javascript in that code snippet.

    Looking at the page’s source, though, I find this:

    add_action('admin_footer-edit.php', 'custom_bulk_admin_footer');
    
    
    
    function custom_bulk_admin_footer() {
    
      global $post_type;
    
      if($post_type == 'post') {
    
        ?>
    
        <script type="text/javascript">
    
          jQuery(document).ready(function() {
    
            jQuery('<option>').val('export').text('<?php _e('Export')?>').appendTo("select[name='action']");
    
            jQuery('<option>').val('export').text('<?php _e('Export')?>').appendTo("select[name='action2']");
    
          });
    
        </script>
    
        <?php
    
      }
    
    }
    

    …which actually does include the JS code (though not in the way you should do it in WordPress — see wp_enqueue_script() for more on that.

Comments are closed.