¿Cómo hacer que las acciones masivas personalizadas funcionen en la página de medios / carga?

4

Estoy adaptando un script que encontré en línea para agregar acciones masivas personalizadas a la pantalla con la lista de publicaciones. Tiene esta línea:

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

Estoy tratando de adaptarlo para la biblioteca de medios. Veo que en lugar de edit.php debería usar upload.php , lo que me lleva a creer que necesito encontrar el análogo de medios para load-edit.php . Suena fácil, pero ni siquiera puedo encontrar load-edit.php en mi instalación de WP para ver si por casualidad podría ser lo que estoy buscando. He encontrado algunas referencias en línea a load-*.php (por ejemplo, bulk_action personalizado ), pero nada eso me dice qué valores puede tomar * .

(Intenté load-upload.php pero no está funcionando, aunque siempre podría haber algo más en mi código que está arruinando el trabajo).

Así que mis preguntas son dos:

  1. ¿Qué es el análogo de medios de load-edit.php ?
  2. ¿Dónde está load-edit.php (y los otros archivos load-*.php ), o qué código maneja estas solicitudes de archivos?

La primera es mi verdadera pregunta, pero la segunda se me ha metido en la piel.

¿Puede alguno de ustedes expertos por ahí orientarme? Lo agradecería mucho.

EDITAR

Con "no funciona" no quise decir que se bloquea, sino que no funcionó como se suponía (cambio de un atributo de medios).

El código que estoy adaptando se puede descargar al final de la publicación " Agregar un WordPress Custom Bulk Action "por Justin Stern de Fox Run Software. Regresando para verificar cada paso del código, conseguí que la versión adaptada funcionara, pero solo si comentaba el condicional y el control de seguridad (ambos asterisco a continuación). ¿Cuáles son los medios analógicos que debo usar para reemplazarlos?

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

Aprecio tu ayuda.

EDIT 2

He modificado el código anterior para reflejar la información de la respuesta aceptada. ¡Muchas gracias a Ralf912 !

    
pregunta JohnK 22.03.2013 - 02:03

2 respuestas

2

Si desea utilizar su código, intente esto:

Si desea comprobar si los medios son archivos adjuntos, puede intentar usar $_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();
}

No se puede verificar un nonce que no se haya configurado. El nonce bulk-posts se establece en edit.php , y esta es la lista de publicaciones. En upload.php es el conjunto bulk-media nonce. Entonces usa check_admin_referer('bulk-media');

    
respondido por el Ralf912 23.03.2013 - 12:24
3

A WordPress le faltan algunos apply_filters y do_action en upload.php . Así que tienes que hacer algunos trucos desagradables.

Al principio, debemos agregar una acción de exportación a las acciones masivas. WP_Media_List_Table es un objeto y este trabajo es muy fácil. Simplemente podemos ampliar la clase y anular / ampliar los métodos necesarios:

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

    }

}

El primer método simplemente agrega la acción de exportación. El segundo método devuelve export_media si se selecciona la acción de exportación.

Ahora se vuelve desagradable. No hay apply_filter en upload.php y no podemos cambiar el uso de la clase upload.php para mostrar los medios. El segundo punto es que no hay add_action para enganchar para agregar otra acción si se selecciona una acción masiva.

Copie upload.php y cambie su nombre (por ejemplo, extended_upload.php ). Edite su nuevo archivo y elimine require_once( './admin.php' ); . Luego, enganchamos a load-upload.php , este gancho se llama en admin.php . Dejando esta línea, terminará en un lopp sin fin.

El siguiente paso es insertar un controlador para su acción de exportación. Como puede ver en la clase extendida anterior, ::current_action() devuelve una cadena que se copiará en $doaction . En extended_upload.php encontrará una instrucción de cambio que maneja la acción. Agregue un caso para manejar la acción de exportación:

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;

¡Recuerda! Todas las acciones serán manejadas dentro de una solicitud ajax. ¡Así que no se mostrará ninguna salida (echo, print, printf, ...)!

El último paso que hay que hacer es enlazar a load-upload.php y decir WordPress para usar nuestro nuevo extended_upload.php en lugar del original 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!
}

Esta es una solución muy desagradable y difícil. Cada actualización de WordPress puede destruirlo y tienes que hacer un seguimiento de todos los cambios en upload.php . Pero esta es la única forma de recuperar algunos valores (por ejemplo, $wp_list_table->detached , que le dirá si es un archivo adjunto o no).

Tal vez no sea una mala idea escribir un ticket para filtrar $wp_list_table y agregar una acción a la declaración de cambio.

$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;
}

Estos dos cambios harían que sea muy fácil agregar acciones masivas y manejarlas.

    
respondido por el Ralf912 23.03.2013 - 12:04

Lea otras preguntas en las etiquetas