Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm trying to add custom "Bulk Actions" to WP 3.5 new media gallery items. I started from this excellent tutorial which does exactly what I need, but with regular posts; so i tried to adapt it to work with media gallery items.

Starting from the original plugin code, here's what I came up until now (in my functions.php):

/*
Plugin Name: 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(is_admin()) {
        // admin actions/filters
        add_action('admin_footer', 'custom_bulk_admin_footer');
        add_action('load-upload.php', 'custom_bulk_action');
        add_action('admin_notices', 'custom_bulk_admin_notices');
    }

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

    if($pagenow == 'upload.php') {
        ?>
            <script type="text/javascript">
                jQuery(document).ready(function() {
                    jQuery('<option>').val('appr_1').text('<?php _e('Approva per album privato')?>').appendTo("select[name='action']");                        
                    jQuery('<option>').val('appr_1').text('<?php _e('Approva per album privato')?>').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,$pagenow;
    $post_type = $typenow;

    //if($post_type == 'post') {
    if($pagenow == 'upload.php') {

        // get the action
        $wp_list_table = _get_list_table('WP_Media_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("appr_1","appr_2");
        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" );
            $sendback = admin_url( "post.php" );

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

        switch($action) {
            case 'appr_1':

                // 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 == 'upload.php' && 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 something
    return true;
}

The code should do nothing (see perform_export() function) and return a "Post exported" message, but is not working. The new bulk actions correctly displays, but I get a security error ("Are you sure you want to do this?"). And if I disable the security check

check_admin_referer('bulk-posts');

I don't see the confirmation message.

I think that my problems could be in this hook I'm using (I'm quite a noob in hooks handling!!)

add_action('load-upload.php', 'custom_bulk_action');

and in the $sendback variable which holds the page that handles the actual work:

$sendback = admin_url( "post.php" );

Can you help me firguring out which hooks and sendback page should I use? Thanks :)

share|improve this question
    
First: Welcome to WP.SE :) Second: You need to show us what have you tried already, what works and what doesn't. Currently you're just showing us a bunch of code lines and the answer would be to write the full plugin (which would make it off topic). Please go back and rework your question. Thanks. –  kaiser Mar 5 '13 at 11:02
    
Thanks for welcoming me @kaiser, I tried to be more specific :) –  Torakiki Mar 5 '13 at 12:14
add comment

1 Answer

I had a very similar question ("How to make custom bulk actions work on the media/upload page?") about Justin Stern's Custom Bulk Action Demo, which was just answered.

My biggest piece of advice to you is to take the adaptation one step at a time: make sure you have export working for media before anything else. Don't try to do two steps at once. (That's the secret to all this computer stuff: break things into small, manageable pieces.)

For your specific questions at the end:

  • Replacing check_admin_referer('bulk-posts') with check_admin_referer('bulk-media') will get rid of "Are you sure you want to do this?".
  • The hook add_action('load-upload.php', 'custom_bulk_action') may sound silly, but is fine.
  • $sendback = admin_url( "upload.php" ) is fine.

In part 1, custom_bulk_admin_footer(), and part 3, custom_bulk_admin_notices(), you want to replace

  • 'post' --> 'attachment'.

Elsewhere you need to replace

  • post.php --> upload.php,
  • edit --> upload, and
  • post --> media.

Part 2, custom_bulk_action(), requires more-complicated adaptations. I recommend you use the code below (from the question linked above).

 add_action('load-upload.php', array(&$this, 'custom_bulk_action'));


function custom_bulk_action() {

//  ***if($post_type == 'attachment') {  REPLACE WITH:
    if ( !isset( $_REQUEST['detached'] ) ) {

    // get the action
    $wp_list_table = _get_list_table('WP_Media_List_Table');  
    $action = $wp_list_table->current_action();

    echo "\naction = $action\n</pre>";

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

    // security check
//  ***check_admin_referer('bulk-posts'); REPLACE WITH:
    check_admin_referer('bulk-media'); 

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

    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( "upload.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();
  }
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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