尝试一个有点规范的(或至少是丰富的)答案,这是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 }}&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
样板有一些黑客行为——尤其是通过长距离接触框架对象来获取侧边栏似乎是可疑的(而且是在多次摸索之后才发现的)。