在WP媒体模式窗口中删除附件

时间:2014-05-01 作者:bcorkins

我正在尝试在WP modal media窗口中创建一个选项,以检测重复文件,并在发现旧的重复文件时删除新文件。我有以下代码(与“attachment\\u fields\\u to\\u edit”过滤器配合使用)来取消选择重复文件并在媒体模式中选择原始文件。我想做的是,当用户单击按钮时,删除原始文件(或者至少将其隐藏在媒体库窗口中,以便稍后删除)。

( 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 );
界面看起来像附加的图像。

screenshot of duplicate media check

我可以在媒体视图中看到。js在第5873行显示,有一个deleteAttachment函数绑定到“click”。删除附件\'。在给定当前设置的情况下,如何通过传入图像ID或附件对象来访问它?

2 个回复
SO网友:Fabien Quatravaux

你只要打电话destroy 上的方法attachment 模型这将从媒体库视图中删除附件,并向后端发送ajax调用,以删除数据库中的附件和上载目录中的所有链接文件。

无需将附件转换为JSON即可获得id:您可以直接操作主干模型。这个selection 是多个附件的集合。

( 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 );
我还添加了$.proxy 调用以能够使用this 在click事件回调中。

SO网友:bonger

尝试一个有点规范的(或至少是丰富的)答案,这是wpse142997.js 在子模板目录中:

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 );
});
这是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尽量遵循WP媒体模式,这只是部分。它创建了一个media.view.Attachment 并使用wp.template 样板有一些黑客行为——尤其是通过长距离接触框架对象来获取侧边栏似乎是可疑的(而且是在多次摸索之后才发现的)。

结束