Hapus lampiran di jendela modal media WP

15

Saya mencoba membuat opsi di jendela WP modal media untuk mendeteksi file duplikat dan menghapus file yang lebih baru jika duplikat yang lebih lama ditemukan. Saya memiliki kode berikut yang berfungsi (bersama dengan filter 'attachment_fields_to_edit') untuk membatalkan pilihan file duplikat dan pilih file asli dalam modal media. Yang ingin saya lakukan adalah, ketika pengguna mengklik tombol, hapus file asli (atau setidaknya menyembunyikannya di jendela perpustakaan media sehingga saya bisa menghapusnya nanti).

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

Tampilannya seperti gambar terlampir.

tangkapan layar duplikat cek media

Saya dapat melihat di media-views.js pada baris 5873 bahwa ada fungsi deleteAttachment terikat pada 'klik .delete-attachment'. Bagaimana saya bisa mengakses ini, mengingat pengaturan saya saat ini, dengan mengirimkan ID gambar atau objek lampiran?

bcorkins
sumber
4
Apakah pertanyaan ini masih terbuka atau apakah Anda sudah menemukan jawaban?
engelen
@engelen pertanyaan ini sekarang memiliki karunia terbuka. Jadi lakukan saja :-)
Pieter Goosen

Jawaban:

5

Mencoba jawaban yang agak kanonik (atau setidaknya berlimpah), ini adalah javascript untuk wpse142997.jsdi direktori templat anak:

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

Ini adalah 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' );

Javascript mencoba mengikuti cara WP Media Modal sebanyak yang saya mengerti, yang hanya sebagian. Itu menciptakan media.view.Attachmentdan menggunakan wp.templatetemplat. Sudah ada beberapa bit hacky - mendapatkan sidebar khususnya melalui jangkauan panjang ke objek frame tampaknya mencurigakan (dan hanya ditemukan setelah banyak mengaduk-aduk).

bonger
sumber
Terima kasih, ini jelas seperti apa yang saya tuju. Tentang bagian kanonik, tidak ada banyak alasan untuk memilih dan saya tidak dapat menemukan teks yang lebih baik pada saya sendiri, jadi ini cukup dekat. Saya akan melihat lebih dekat minggu depan.
Nicolai
Saya menyalin kode ke 2014 functions.php dan mengatur js seperti yang dijelaskan dan masih tidak dapat melihat bagian pemberitahuan duplikat. Tindakan apa yang harus saya lakukan setelah kode berada di tempat untuk melihat ini?
KalenGi
Saya berasumsi Anda mengunggah gambar rangkap?! ...
bonger
4

Anda hanya perlu memanggil destroymetode pada attachmentmodel. Ini akan menghapus lampiran dari tampilan Media Library, dan mengirim panggilan ajax ke backend untuk menghapus lampiran dalam database dan semua file yang ditautkan dalam direktori unggahan.

Anda tidak perlu mengonversi lampiran ke JSON untuk mendapatkan id: Anda dapat secara langsung memanipulasi model Backbone. Ini selectionadalah koleksi beberapa lampiran.

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

Saya juga telah menambahkan $ .proxy call untuk dapat digunakan thisdi dalam event callback klik.

Fabien Quatravaux
sumber
1
Terima kasih, terlihat bagus untukku. Tentu saja keterampilan JS dan pengetahuan saya tentang bagian-bagian WordPress itu tidak terlalu bagus. Pasti ingin mencobanya minggu depan. Hal lain, mari kita berpura-pura tidak tahu banyak tentang WP, bagaimana saya bisa menggunakan kode yang Anda posting?
Nicolai
Karena saya belum menemukan waktu untuk mencoba salah satu solusi Anda, saya telah memberikan hadiah untuk jawaban @bonger - hanya karena tampaknya lebih lengkap, terima kasih lagi untuk menjawabnya.
Nicolai