Как заставить пользовательские массовые действия работать на странице мультимедиа/загрузки?


Я адаптирую скрипт, который нашел в Интернете, для добавления пользовательских массовых действий на экран со списком сообщений. В нем есть такая строка:

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

Я пытаюсь адаптировать его для медиатеки. Я вижу, что вместо edit.php я должен использовать upload.php, что наводит меня на мысль, что мне нужно найти медиа-аналог для load-edit.php. Звучит просто, но я даже не могу найти load-edit.php в своей установке WP, чтобы посмотреть, случайно ли это может быть то, что я ищу сам. Я нашел несколько ссылок в Интернете на load-*.php (например, Пользовательское действие bulk_action ), но ничего, что говорило бы мне, какие значения может принимать *.

(Я пробовал load-upload.php, но это не работает - хотя в моем коде всегда может быть что-то другое, что мешает работе.)

Итак, у меня два вопроса:

  1. Что такое медиа-аналог load-edit.php?
  2. Где находится load-edit.php (и другие файлы load-*.php), или какой код обрабатывает эти запросы файлов?

Первый - мой настоящий вопрос, но второй имеет проникла мне под кожу.

Может ли кто-нибудь из вас, экспертов, дать мне какое-нибудь руководство? Я был бы очень признателен за это.

РЕДАКТИРОВАТЬ

Под "не работает" я имел в виду не то, что он выходит из строя, а то, что он делал не так, как предполагалось (изменение атрибута мультимедиа).

Код, который я адаптирую, можно загрузить в нижней части поста " Добавить пользовательское массовое действие WordPress" Джастина Стерна из Fox Run Software. Возвращаясь к проверке каждого шага кода, я получил адаптированная версия для работы, но только в том случае, если я закомментирую условие и проверку безопасности (оба отмечены звездочкой ниже). Какие аналоги носителей я должен использовать для их замены?

 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();
  }
}

Я ценю вашу помощь.

РЕДАКТИРОВАТЬ 2

Я изменил приведенный выше код, чтобы отразить информацию из принятого ответа. Большое спасибо Ralf912!

Author: Community, 2013-03-22

2 answers

Если вы хотите использовать свой код, попробуйте следующее:

Если вы хотите проверить, являются ли носители вложениями, вы можете попробовать использовать $_REQUEST['detached']

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

function export_media_test() {

    if ( ! isset( $_REQUEST['action'] ) )
        return;

    echo 'Export Media';

    if ( isset( $_REQUEST['detached'] ) ) {
        die( 'No attachments' );
    } else {
        die( 'Attachments' );
    }

    exit();
}

Вы не можете проверить значение, которое не было установлено. Значение bulk-posts задается в edit.php, и это список сообщений. В upload.php находится набор bulk-media nonce. Так что используйте check_admin_referer('bulk-media');

 2
Author: Ralf912, 2013-03-23 11:24:42

В WordPress отсутствуют некоторые apply_filters и do_action в upload.php. Так что вам придется проделать несколько неприятных трюков.

Сначала мы должны добавить действие экспорта к массовым действиям. WP_Media_List_Table - это объект, и эта работа очень проста. Мы можем просто расширить класс и переопределить/расширить необходимые методы:

require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
require_once( ABSPATH . 'wp-admin/includes/class-wp-media-list-table.php' );

class Extended_Media_List_Table extends WP_Media_List_Table
{

    /**
     * Add the export bulk action
     * @return array
     */
    public function get_bulk_actions() {

        // get the original bulk actions    
        $actions = parent::get_bulk_actions();

        // add our own action(s)
        $actions['export'] = __( 'Export' );

        // return the actions    
        return $actions;
    }

    /**
     * Returns the current action
     * @return string
     */
    public function current_action() {

        // check if our action(s) are set and handle them
        if ( isset( $_REQUEST['action'] ) && 'export' === $_REQUEST['action'] ) {
            return 'export_media';
        }

        // let the parent class handle all other actions
        parent::current_action();

    }

}

Первый метод просто добавляет действие экспорта. Второй метод возвращает export_media, если выбрано действие экспорта.

Теперь это стало противно. Нет apply_filter в upload.php, и мы невозможно изменить класс upload.php, используемый для отображения средств массовой информации. Второй момент заключается в том, что нет add_action, к которому можно подключиться, чтобы добавить другое действие, если выбрано массовое действие.

Скопируйте upload.php и переименуйте его (например, extended_upload.php). Отредактируйте свой новый файл и удалите require_once( './admin.php' );. Позже мы подключаемся к load-upload.php, этот крючок называется в admin.php. Покидая эту линию, закончится бесконечным lopp.

Следующий шаг - вставить обработчик для вашего действия экспорта. Как вы можете видеть в расширенном классе выше, ::current_action() возвращает строка, которая будет скопирована в $doaction. В extended_upload.php вы найдете оператор switch, который обрабатывает действие. Добавьте обращение для обработки действия экспорта:

case 'export_media':
    // handle only attachments
    // $wp_list_table->detached = false ==> attachments
    // $wp_list_table->detached = true ==> not attached files
    if ( true == $wp_list_table->detached )
        return;

    // $_REQUEST['media'] contains an array with the post_ids
    if ( ! empty( $_REQUEST['media'] ) ) {
        foreach ( $_REQUEST['media'] as $postID ) {
            export_image( $postID );
        }
    }
    break;

Помни! Все действия будут обрабатываться внутри ajax-запроса. Таким образом, вывод (echo, печать, printf,...) отображаться не будет!!

Последний шаг, который нужно сделать, это подключиться к load-upload.php и сказать WordPress, чтобы использовать наш новый extended_upload.php вместо оригинального upload.php:

add_action( 'load-upload.php', 'add_bulk_action_export_to_list_media' );
function add_bulk_action_export_to_list_media() {
    require_once 'extended_upload.php';
    // DO NOT RETURN HERE OR THE ORIGINAL upload.php WILL BE LOADED TOO!
}

Это очень неприятное и сложное решение. Каждый Обновление WordPress может уничтожить его, и вам придется отслеживать все изменения в upload.php. Но это единственный способ получить некоторые значения (например, $wp_list_table->detached, которые скажут вам, является ли это вложением или нет).

Возможно, это неплохая идея - написать билет для фильтрации $wp_list_table и добавить действие в оператор switch.

$wp_list_table = apply_filters( 'upload_list_table', _get_list_table('WP_Media_List_Table') );

switch ( $doaction ) {
[...]

default:
  global $doaction;
  do_action( 'upload_list_table_actions' );
  break;
}

Эти два изменения позволят очень легко добавлять массовые действия и обрабатывать их.

 4
Author: Ralf912, 2013-03-24 09:16:11