web-dev-qa-db-fra.com

Comment faire en sorte que les actions groupées personnalisées fonctionnent sur la page de média/téléchargement?

J'adapte un script trouvé en ligne pour ajouter des actions en bloc personnalisées à l'écran avec la liste des publications. Il a cette ligne:

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

J'essaie de l'adapter à la médiathèque. Je vois qu'à la place de edit.php, je devrais utiliser upload.php, ce qui me laisse penser que je dois trouver le support analogique pour load-edit.php. Cela semble facile, mais je ne trouve même pas load-edit.php dans mon WP installation pour voir si, par hasard, ce pourrait être ce que je cherche lui-même. J'ai trouvé quelques références en ligne à load-*.php (par exemple, Custom bulk_action ), mais rien qui me dise quelles valeurs * peut prendre.

(J'ai essayé load-upload.php mais cela ne fonctionne pas - bien que cela puisse toujours être quelque chose d'autre dans mon code qui gomme le travail.)

Donc, mes questions sont deux:

  1. Quel est l'analogue de média de load-edit.php?
  2. Où se trouve load-edit.php (et les autres fichiers load-*.php), ou quel code gère ces demandes de fichier?

La première est ma vraie question, mais la seconde m’est cachée.

Certains de vos experts peuvent-ils me donner des conseils? Je l'apprécierais beaucoup.

MODIFIER

Par "ne fonctionne pas", je ne voulais pas dire que cela plantait, mais que cela ne se passait pas comme prévu (modification d'un attribut de support).

Le code que j'adapte peut être téléchargé au bas de l'article " Ajouter une action en bloc WordPress personnalisée " de Justin Stern de Fox Run Software. En revenant pour vérifier chaque étape du code, la version adaptée fonctionnait, mais seulement si je commentais la vérification conditionnelle et la vérification de sécurité (marquées d'un astérisque ci-dessous). Quels sont les analogues de médias que je devrais utiliser pour les remplacer?

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

J'apprécie ton aide.

EDIT 2

J'ai modifié le code ci-dessus pour refléter les informations de la réponse acceptée. Merci beaucoup à Ralf912 !

4
JohnK

Si vous voulez utiliser votre code, essayez ceci:

Si vous voulez vérifier si les médias sont des pièces jointes, vous pouvez essayer d'utiliser $_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();
}

Vous ne pouvez pas vérifier un nonce qui n'a pas été défini. Le nonce bulk-posts est défini dans edit.php, et ceci est la liste des articles. Dans upload.php est l'ensemble bulk-media nonce. Donc utilisez check_admin_referer('bulk-media');

2
Ralf912

Il manque quelques apply_filters et do_action dans upload.php dans WordPress. Donc, vous devez faire de mauvais tours.

Au début, nous devons ajouter une action d'exportation aux actions en bloc. WP_Media_List_Table est un objet et ce travail est très facile. Nous pouvons simplement étendre la classe et remplacer/étendre les méthodes nécessaires:

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

    }

}

La première méthode ajoute simplement l'action d'exportation. La deuxième méthode retourne export_media si l'action d'exportation est choisie.

Maintenant ça devient méchant. Il n'y a pas de apply_filter dans upload.php et nous ne pouvons pas changer la classe upload.php utilisée pour afficher les médias. Le deuxième point est qu’il n’ya pas de add_action à connecter pour ajouter une autre action si une action en bloc est sélectionnée.

Copiez upload.php et renommez-le (par exemple, extended_upload.php). Modifiez votre nouveau fichier et supprimez require_once( './admin.php' );. Plus tard, nous accrochons en load-upload.php, ce hook s'appelle en admin.php. Laissant cette ligne, se terminera par un lopp sans fin.

L'étape suivante consiste à insérer un gestionnaire pour votre action d'exportation. Comme vous pouvez le voir dans la classe étendue ci-dessus, ::current_action() renvoie une chaîne qui sera copiée dans $doaction. Dans extended_upload.php, vous trouverez une instruction switch qui gère l'action. Ajoutez un cas pour gérer l'action d'exportation:

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;

Rappelles toi! Toutes les actions seront traitées dans une demande ajax. Donc aucune sortie (echo, print, printf, ...) ne sera affichée !!

La dernière étape consiste à connecter load-upload.php et à dire à WordPress d’utiliser notre nouveau extended_upload.php au lieu du upload.php original:

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!
}

C'est une très méchante et solution délicate. Chaque mise à jour de WordPress peut le détruire et vous devez suivre chaque modification apportée à upload.php. Mais c’est le seul moyen de récupérer certaines valeurs (par exemple, $wp_list_table->detached qui vous dira s’il s’agit d’une pièce jointe ou non).

Ce n’est peut-être pas une mauvaise idée d’écrire un ticket pour filtrer $wp_list_table et d’ajouter une action à l’instruction 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;
}

Ces deux modifications faciliteront l'ajout d'actions en masse et leur traitement.

3
Ralf912