diff --git a/wp-admin/admin-ajax.php b/wp-admin/admin-ajax.php
index 00ec8b1aa3..2d073bc63d 100644
--- a/wp-admin/admin-ajax.php
+++ b/wp-admin/admin-ajax.php
@@ -54,7 +54,8 @@ $core_actions_post = array(
'sample-permalink', 'inline-save', 'inline-save-tax', 'find_posts', 'widgets-order',
'save-widget', 'set-post-thumbnail', 'date_format', 'time_format', 'wp-fullscreen-save-post',
'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'get-attachment',
- 'query-attachments', 'save-attachment', 'save-attachment-compat',
+ 'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor',
+ 'send-attachment-to-editor',
);
// Register core Ajax calls.
diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php
index 4bfde87b04..d752624923 100644
--- a/wp-admin/includes/ajax-actions.php
+++ b/wp-admin/includes/ajax-actions.php
@@ -1907,3 +1907,91 @@ function wp_ajax_save_attachment_compat() {
wp_send_json_success( $attachment );
}
+
+/**
+ * Generates the HTML to send an attachment to the editor.
+ * Backwards compatible with the media_send_to_editor filter and the chain
+ * of filters that follow.
+ *
+ * @since 3.5.0
+ */
+function wp_ajax_send_attachment_to_editor() {
+ check_ajax_referer( 'media-send-to-editor', 'nonce' );
+
+ $attachment = stripslashes_deep( $_POST['attachment'] );
+
+ $id = intval( $attachment['id'] );
+
+ if ( ! $post = get_post( $id ) )
+ wp_send_json_error();
+
+ if ( ! current_user_can( 'edit_post', $id ) )
+ wp_send_json_error();
+
+ if ( 'attachment' != $post->post_type )
+ wp_send_json_error();
+
+ $html = isset( $attachment['title'] ) ? $attachment['title'] : '';
+ if ( ! empty( $attachment['url'] ) ) {
+ $rel = '';
+ if ( strpos($attachment['url'], 'attachment_id') || get_attachment_link( $id ) == $attachment['url'] )
+ $rel = ' rel="attachment wp-att-' . $id . '"';
+ $html = '' . $html . '';
+ }
+
+ remove_filter( 'media_send_to_editor', 'image_media_send_to_editor', 10, 3 );
+
+ if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
+ $url = $attachment['url'];
+ $align = isset( $attachment['image-align'] ) ? $attachment['image-align'] : 'none';
+ $size = isset( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
+ $alt = isset( $attachment['image-alt'] ) ? $attachment['image-alt'] : '';
+ $caption = isset( $attachment['caption'] ) ? $attachment['caption'] : '';
+ $title = ''; // We no longer insert title tags into
tags, as they are redundant.
+ $html = get_image_send_to_editor( $id, $caption, $title, $align, $url, (bool) $rel, $size, $alt );
+ }
+
+ $html = apply_filters( 'media_send_to_editor', $html, $id, $attachment );
+
+ wp_send_json_success( $html );
+}
+
+/**
+ * Generates the HTML to send a non-image embed link to the editor.
+ *
+ * Backwards compatible with the following filters:
+ * - file_send_to_editor_url
+ * - audio_send_to_editor_url
+ * - video_send_to_editor_url
+ *
+ * @since 3.5.0
+ */
+function wp_ajax_send_link_to_editor() {
+ check_ajax_referer( 'media-send-to-editor', 'nonce' );
+
+ if ( ! $src = stripslashes( $_POST['src'] ) )
+ wp_send_json_error();
+
+ if ( ! strpos( $src, '://' ) )
+ $src = 'http://' . $src;
+
+ if ( ! $src = esc_url_raw( $src ) )
+ wp_send_json_error();
+
+ if ( ! $title = trim( stripslashes( $_POST['title'] ) ) )
+ $title = wp_basename( $src );
+
+ $html = '';
+ if ( $title )
+ $html = '' . $title . '';
+
+ // Figure out what filter to run:
+ $type = 'file';
+ if ( ( $ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src ) ) && ( $ext_type = wp_ext2type( $ext ) )
+ && ( 'audio' == $ext_type || 'video' == $ext_type ) )
+ $type = $ext_type;
+
+ $html = apply_filters( $type . '_send_to_editor_url', $html, $src, $title );
+
+ wp_send_json_success( $html );
+}
diff --git a/wp-admin/js/media-upload.js b/wp-admin/js/media-upload.js
index 7d2fd34047..356380a2a4 100644
--- a/wp-admin/js/media-upload.js
+++ b/wp-admin/js/media-upload.js
@@ -109,22 +109,69 @@ var tb_position;
};
wp.media.string = {
- link: function( props, attachment ) {
- var options;
+ // Joins the `props` and `attachment` objects,
+ // outputting the proper object format based on the
+ // attachment's type.
+ props: function( props, attachment ) {
+ var link, linkUrl, size, sizes;
- props = _.defaults( props || {}, {
- title: '',
- linkUrl: ''
- });
+ props = props ? _.clone( props ) : {};
- if ( attachment ) {
+ if ( attachment && attachment.type )
+ props.type = attachment.type;
+
+ if ( 'image' === props.type ) {
+ props = _.defaults( props || {}, {
+ align: getUserSetting( 'align', 'none' ),
+ size: getUserSetting( 'imgsize', 'medium' ),
+ url: '',
+ classes: []
+ });
+ }
+
+ // All attachment-specific settings follow.
+ if ( ! attachment )
+ return props;
+
+ link = props.link || getUserSetting( 'urlbutton', 'post' );
+ if ( 'file' === link )
+ linkUrl = attachment.url;
+ else if ( 'post' === link )
+ linkUrl = attachment.link;
+ else if ( 'custom' === link )
+ linkUrl = props.linkUrl;
+ props.linkUrl = linkUrl || '';
+
+ // Format properties for images.
+ if ( 'image' === attachment.type ) {
+ props.classes.push( 'wp-image-' + attachment.id );
+
+ sizes = attachment.sizes;
+ size = sizes && sizes[ props.size ] ? sizes[ props.size ] : attachment;
+
+ _.extend( props, _.pick( attachment, 'align', 'caption' ), {
+ width: size.width,
+ height: size.height,
+ src: size.url,
+ captionId: 'attachment_' + attachment.id
+ });
+
+ // Format properties for non-images.
+ } else {
_.extend( props, {
title: attachment.title || attachment.filename,
- linkUrl: linkToUrl( props, attachment ),
rel: 'attachment wp-att-' + attachment.id
});
}
+ return props;
+ },
+
+ link: function( props, attachment ) {
+ var options;
+
+ props = wp.media.string.props( props, attachment );
+
options = {
tag: 'a',
content: props.title,
@@ -140,30 +187,11 @@ var tb_position;
},
image: function( props, attachment ) {
- var classes = [],
- img = {},
- options, sizes, size, shortcode, html;
+ var img = {},
+ options, classes, shortcode, html;
- props = _.defaults( props || {}, {
- align: getUserSetting( 'align', 'none' ),
- size: getUserSetting( 'imgsize', 'medium' ),
- url: ''
- });
-
- if ( attachment ) {
- classes.push( 'wp-image-' + attachment.id );
-
- sizes = attachment.sizes;
- size = sizes && sizes[ props.size ] ? sizes[ props.size ] : attachment;
-
- _.extend( props, _.pick( attachment, 'align', 'caption' ), {
- width: size.width,
- height: size.height,
- src: size.url,
- linkUrl: linkToUrl( props, attachment ),
- captionId: 'attachment_' + attachment.id
- });
- }
+ props = wp.media.string.props( props, attachment );
+ classes = props.classes || [];
img.src = props.url;
_.extend( img, _.pick( props, 'width', 'height', 'alt' ) );
@@ -395,14 +423,7 @@ var tb_position;
attachment = attachment.toJSON();
- // If captions are disabled, clear the caption.
- if ( ! wp.media.view.settings.captions )
- delete attachment.caption;
-
- if ( 'image' === attachment.type )
- this.insert( wp.media.string.image( detail, attachment ) + ' ' );
- else
- this.insert( wp.media.string.link( detail, attachment ) + ' ' );
+ this.send.attachment( detail, attachment );
}, this );
}, this );
@@ -421,7 +442,7 @@ var tb_position;
linkUrl: embed.url
});
- this.insert( wp.media.string.link( embed ) );
+ this.send.link( embed );
} else if ( 'image' === embed.type ) {
_.defaults( embed, {
@@ -451,6 +472,61 @@ var tb_position;
delete workflows[ id ];
},
+ send: {
+ attachment: function( props, attachment ) {
+ var caption = attachment.caption,
+ options, html;
+
+ // If captions are disabled, clear the caption.
+ if ( ! wp.media.view.settings.captions )
+ delete attachment.caption;
+
+ props = wp.media.string.props( props, attachment );
+
+ options = {
+ id: attachment.id
+ };
+
+ if ( 'image' === attachment.type ) {
+ html = wp.media.string.image( props );
+ options['caption'] = caption;
+
+ _.each({
+ align: 'image-align',
+ size: 'image-size',
+ alt: 'image-alt',
+ linkUrl: 'url'
+ }, function( option, prop ) {
+ if ( props[ prop ] )
+ options[ option ] = props[ prop ];
+ });
+
+ } else {
+ html = wp.media.string.link( props );
+ options.title = props.title;
+ }
+
+ return media.post( 'send-attachment-to-editor', {
+ nonce: wp.media.view.settings.nonce.sendToEditor,
+ attachment: options,
+ html: html
+ }).done( function( resp ) {
+ wp.media.editor.insert( resp );
+ });
+ },
+
+ link: function( embed ) {
+ return media.post( 'send-link-to-editor', {
+ nonce: wp.media.view.settings.nonce.sendToEditor,
+ src: embed.linkUrl,
+ title: embed.title,
+ html: wp.media.string.link( embed )
+ }).done( function( resp ) {
+ wp.media.editor.insert( resp );
+ });
+ }
+ },
+
init: function() {
$(document.body).on('click', '.insert-media', function( event ) {
var $this = $(this),
diff --git a/wp-includes/media.php b/wp-includes/media.php
index 77a60f4eaf..fba25d53e4 100644
--- a/wp-includes/media.php
+++ b/wp-includes/media.php
@@ -1328,6 +1328,9 @@ function wp_enqueue_media( $args = array() ) {
'tabUrl' => add_query_arg( array( 'chromeless' => true ), admin_url('media-upload.php') ),
'mimeTypes' => wp_list_pluck( get_post_mime_types(), 0 ),
'captions' => ! apply_filters( 'disable_captions', '' ),
+ 'nonce' => array(
+ 'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ),
+ ),
);
$post = null;