I’m adapting a script I found online to add custom bulk actions to the screen with the list of posts. It has this line:
add_action('load-edit.php', 'custom_bulk_action');
I’m trying to adapt it for the media library. I see that in place of edit.php
I should use upload.php
, which leads me to believe I need to find the media analog for load-edit.php
. Sounds easy, but I can’t even find load-edit.php
in my WP install to see if by chance it might be what I’m looking for itself. I have found a few references online to load-*.php
(e.g., Custom bulk_action), but nothing that tells me what values *
can take.
(I’ve tried load-upload.php
but it’s not working–though it could always be something else in my code that’s gumming up the works.)
So my questions are two:
- What is the media analog of
load-edit.php
? - Where is
load-edit.php
(and the otherload-*.php
files), or what code handles these file requests?
The first is my real question, but the second has gotten under my skin.
Can any of you experts out there give me some guidance? I would very much appreciate it.
EDIT
By “not working” I meant not that it crashes, but that it wasn’t doing as it was supposed (changing a media attribute).
The code I’m adapting can be downloaded at the bottom of the post “Add a WordPress Custom Bulk Action” by Justin Stern of Fox Run Software. Going back to verify each step of the code, I got the adapted version to work, but only if I comment out the conditional and the security check (both asterisked below). What are the media analogs I should use to replace these?
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 = $actionn</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();
}
}
I appreciate your help.
EDIT 2
I modified the code above to reflect information from the accepted answer. Many thanks to Ralf912!
If you want to use your code, try this:
If you want to check if the medias are attachments, you can try to use
$_REQUEST['detached']
You can not check an nonce that wasn’t set. The nonce
bulk-posts
is set inedit.php
, and this is the the posts list. Inupload.php
is thebulk-media
nonce set. So usecheck_admin_referer('bulk-media');
WordPress is missing some
apply_filters
anddo_action
inupload.php
. So you have to do some nasty tricks.At first, we have to add an export action to the bulk actions.
WP_Media_List_Table
is an object and this job is very easy. We can simply extend the class and override/extend the needed methods:The first method simply add the export action. The second method returns
export_media
if the export action is choosen.Now it become nasty. There is no
apply_filter
inupload.php
and we can not change the classupload.php
use to display the medias. The second point is, there is noadd_action
to hook into to add another action if a bulk action is selected.Copy
upload.php
and rename it (e.g.extended_upload.php
). Edit your new file and removerequire_once( './admin.php' );
. Later we hook intoload-upload.php
, this hook is called inadmin.php
. Leaving this line, will end in an endless lopp.The next step is to insert a handler for your export action. As you can see in the extended class above,
::current_action()
returns a string that will be copied into$doaction
. Inextended_upload.php
you will find a switch statement which handles the action. Add a case to handle the export action:Remember! All actions will be handled inside an ajax-request. So no output (echo, print, printf, …) will be displayed!!
The last step to do is, to hook into
load-upload.php
and say WordPress to use our newextended_upload.php
instead of the originalupload.php
:This is a very nasty and tricky solution. Every WordPress update can destroy it and you have to track every changes to
upload.php
. But this is the only way to retrieve some values (e.g.$wp_list_table->detached
which will tell you if it is an attachment or not).Maybe it is not a bad idea to write a ticket to filter
$wp_list_table
and and add an action to the switch statement.This two changes would make it very easy to add bulk actions and handle them.