web-dev-qa-db-fra.com

Supprimer une pièce jointe dans le WP fenêtre modale des médias

J'essaie de créer une option dans la fenêtre de média modal WP pour détecter les fichiers en double et supprimer un fichier plus récent si un ancien duplicata est trouvé. J'ai le code suivant (en conjonction avec le filtre "attachment_fields_to_edit") pour désélectionner un fichier en double et sélectionner le fichier d'origine dans le modal multimédia. Ce que j'aimerais faire, c'est lorsqu'un utilisateur clique sur le bouton, supprime le fichier d'origine (ou du moins le cache dans la fenêtre de la médiathèque pour que je puisse le supprimer plus tard).

( function( $ ) {

    var _AttachmentDisplay = wp.media.view.Settings.AttachmentDisplay;
    wp.media.view.Settings.AttachmentDisplay = _AttachmentDisplay.extend({
        render: function() {
            _AttachmentDisplay.prototype.render.apply(this, arguments);
            currentselection = this.controller.state().get('selection').first().toJSON();
            selection = this.controller.state().get('selection');

            $('button.dmc').on('click', function(e){

                e.preventDefault();

                var id = $(e.currentTarget).data("id");
                if(currentselection.id == id) {

                    currentattachment = wp.media.attachment(id);
                    selection.remove(currentattachment);

                    console.dir(wp.media.view.Attachment);

                    newattachment = wp.media.attachment($(e.currentTarget).data("original"));
                    selection.add(newattachment);

                }
            });
        }
    });

} )( jQuery );

L'interface ressemble à l'image jointe.

screenshot of duplicate media check

À la ligne 5873, je vois dans media-views.js qu'il existe une fonction deleteAttachment liée à "cliquez sur .delete-attachment". Comment puis-je accéder à cela, en fonction de ma configuration actuelle, en passant un ID d’image ou un objet pièce jointe?

14
bcorkins

Tentative de réponse quelque peu canonique (ou du moins généreuse), il s'agit du code JavaScript pour wpse142997.js dans le répertoire du modèle enfant:

jQuery( document ).ready(function() {
    ( function( $ ) {
        var media = wp.media,
            l10n = media.view.l10n = typeof _wpMediaViewsL10n === 'undefined' ? {} : _wpMediaViewsL10n,
            attachments = media.model.Attachments.all,
            attachments_uploaded = [];

        if ( typeof wp.Uploaded === 'undefined') return;

        // Keep track of files uploaded.
        wp.Uploader.queue.on( 'add', function ( attachment ) {
            attachments_uploaded.Push( attachment );
        });

        // The Uploader (in wp-includes/js/plupload/wp-plupload.js) resets the queue when all uploads are complete.
        wp.Uploader.queue.on( 'reset', function () {
            var idx, uploaded = attachments_uploaded.slice(0); // Clone
            attachments_uploaded = [];
            for ( idx = 0; idx < uploaded.length; idx++ ) {
                if ( uploaded[idx].get('name').match(/-[0-9]+$/) ) {
                    $.post( ajaxurl, {
                            action: 'wpse142997_is_dup',
                            dup_id: uploaded[idx].id,
                            nonce: wpse142997_params.is_dup_nonce
                        }, function( response ) {
                            var original, dup, dup_view, sidebar, selection;
                            if ( response && !response.error && response.original_id && response.dup_id ) {
                                original = attachments.get( response.original_id );
                                dup = attachments.get( response.dup_id );
                                if ( original && dup ) {
                                    dup.set( 'dup_original', original ); // May be ungood - mostly doing it so can use wp.templates.
                                    dup_view = media.view.Attachment.extend({
                                        tagName:   'div',
                                        className: 'attachment-dmc',
                                        template: media.template('attachment-dmc'),
                                        events: {
                                            'click button.dmc': 'removeDupSelectOriginal'
                                        },
                                        initialize: function() {
                                            this.focusManager = new media.view.FocusManager({
                                                el: this.el
                                            });
                                            media.view.Attachment.prototype.initialize.apply( this, arguments );
                                        },
                                        render: function() {
                                            if ( this.get_dup_original() ) {
                                                media.view.Attachment.prototype.render.apply( this, arguments );
                                                this.focusManager.focus();
                                            }
                                            return this;
                                        },
                                        removeDupSelectOriginal: function( event ) {
                                            var dup_original = this.get_dup_original();
                                            event.preventDefault();

                                            if ( dup_original && confirm( l10n.warnDelete ) ) {
                                                this.model.destroy();
                                                this.controller.state().get('selection').add( dup_original );
                                                this.remove();
                                            }
                                        },
                                        get_dup_original: function () {
                                            var dup_original = this.model.get('dup_original');
                                            return dup_original && attachments.get( dup_original.id ) ? dup_original : null;
                                        }
                                    });
                                    // A hacky way to get the sidebar.
                                    sidebar = media.frame.content.view.views.get('.media-frame-content')[0].sidebar;
                                    selection = sidebar.controller.state().get('selection');
                                    // The sidebar boxes get deleted and recreated on each select - hack into this to do the same.
                                    selection.on( 'selection:single', function ( event ) {
                                        if ( selection.single().get('dup_original') ) {
                                            sidebar.set( 'dmc', new dup_view({
                                                controller: sidebar.controller,
                                                model: selection.single(),
                                                priority: 100
                                            }) );
                                        }
                                    } );
                                    selection.on( 'selection:unsingle', function ( event ) {
                                        sidebar.unset('dmc');
                                    } );
                                    // Refire the select as we missed it (could/should just do the view create code here again).
                                    selection.trigger('selection:single');
                                }
                            }
                        }, 'json'
                    );
                }
            }
        });
    } )( jQuery );
});

C'est le functions.php:

function wpse142997_wp_enqueue_scripts() {
    wp_enqueue_script( 'wpse142997', get_stylesheet_directory_uri() . '/wpse142997.js', array( 'jquery', 'media-views' ), '1.0' );
    $params = array(
        'is_dup_nonce' => wp_create_nonce( 'wpse142997_is_dup_submit_' ),
    );
    wp_localize_script( 'wpse142997', 'wpse142997_params', $params );
    ob_start();
    ?>
<style>
.attachment-dmc { float:left; overflow:hidden; position:relative; }
.attachment-dmc div { background-color:#FFEBE7; border:1px solid #CB9495; border-radius:5px; margin-top:16px; padding:6px; }
.attachment-dmc div h3 { margin-top:0; }
.attachment-dmc div h3 span { background-color:#E70000; border-radius:5px; color:white; margin-top:0; padding:0 6px; }
</style>
    <?php
    wp_add_inline_style( 'media-views', str_replace( array( '<style>', '</style>' ), '', ob_get_clean() ) );
}

function wpse142997_print_media_templates() {
?>
<script type="text/html" id="tmpl-attachment-dmc">
    <# if ( data.dup_original ) { #>
        <div>
            <h3><span><?php _e( 'Duplicate file detected' ); ?></span></h3>
            <p>
                <?php _e( 'This file appears to be a duplicate of <a href="{{ data.dup_original.attributes.editLink }}&amp;image-editor" target="_blank">{{ data.dup_original.attributes.filename }}</a> uploaded on {{ data.dup_original.attributes.dateFormatted }}' ); ?>
            </p>
            <button id="run_dmc" class="dmc" name="dmc"><?php _e( 'Remove duplicate and select original' ); ?></button>
        </div>
    <# } #>
</script>
<?php
}

function wpse142997_is_dup() {
    $ret = array( 'error' => false );

    if ( ! check_ajax_referer( 'wpse142997_is_dup_submit_', 'nonce', false /*die*/ ) ) {
        $ret['error'] = __( 'Permission error' );
    } else {
        $dup_id = isset( $_POST['dup_id'] ) ? $_POST['dup_id'] : '';
        if ( ! $dup_id || ! ( $post = get_post( $dup_id ) ) ) {
            $ret['error'] = __( 'Bad dup_id' );
        } else {
            $post_name = preg_replace( '/-[0-9]+$/', '', $post->post_name ); 
            global $wpdb;
            $sql = $wpdb->prepare( 'SELECT ID FROM ' . $wpdb->posts . ' WHERE'
                . ' post_title = %s AND post_type = %s AND post_mime_type = %s AND post_status = %s AND post_name = %s ORDER BY post_date ASC LIMIT 1',
                $post->post_title, $post->post_type, $post->post_mime_type, $post->post_status, $post_name
            );
            if ( $original_id = $wpdb->get_var( $sql ) ) {
                $ret['original_id'] = $original_id;
                $ret['dup_id'] = $dup_id;
            }
        }
    }

    wp_send_json( $ret );
}

add_action( 'admin_enqueue_scripts', 'wpse142997_wp_enqueue_scripts' );
add_action( 'print_media_templates', 'wpse142997_print_media_templates' );
add_action( 'wp_ajax_wpse142997_is_dup', 'wpse142997_is_dup' );

Le javascript essaie de suivre la manière WP Media Modal autant que je le comprends, ce qui n’est que partiel. Il crée un media.view.Attachment et utilise un modèle wp.template. Il y a quelques petites astuces - obtenir la barre latérale en particulier via une longue portée dans l'objet frame semble suspect (et n'a été trouvé qu'après beaucoup de fouilles).

4
bonger

Il vous suffit d'appeler la méthode destroy sur le modèle attachment. Cela supprimera la pièce jointe de la vue Médiathèque et enverra un appel ajax au serveur afin de supprimer la pièce jointe dans la base de données et tous les fichiers liés dans le répertoire de téléchargement.

Il n'est pas nécessaire de convertir la pièce jointe en JSON pour obtenir l'identifiant: vous pouvez manipuler directement les modèles Backbone. selection est une collection de plusieurs pièces jointes.

( function( $ ) {

    var _AttachmentDisplay = wp.media.view.Settings.AttachmentDisplay;
    wp.media.view.Settings.AttachmentDisplay = _AttachmentDisplay.extend({
        render: function() {
            _AttachmentDisplay.prototype.render.apply(this, arguments);

            $('button.dmc').on('click', $.proxy(function(e){

                e.preventDefault();
                selection = this.controller.state().get('selection');
                firstAttachment = selection.first();

                var id = $(e.currentTarget).data("id");
                if(currentselection.id == id) {

                    selection.remove(firstAttachment);
                    firstAttachment.destroy();

                    console.dir(wp.media.view.Attachment);

                    newattachment = wp.media.attachment($(e.currentTarget).data("original"));
                    selection.add(newattachment);

                }
            }, this));
        }
    });

} )( jQuery );

J'ai également ajouté un $ .proxy call pour pouvoir utiliser this dans le rappel d'événement click.

4
Fabien Quatravaux