diff --git a/wp-admin/admin-ajax.php b/wp-admin/admin-ajax.php
index 9e67fa67c6..00ec8b1aa3 100644
--- a/wp-admin/admin-ajax.php
+++ b/wp-admin/admin-ajax.php
@@ -54,7 +54,7 @@ $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',
+ 'query-attachments', 'save-attachment', 'save-attachment-compat',
);
// Register core Ajax calls.
diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php
index a333c9b6cc..6b03d8b956 100644
--- a/wp-admin/includes/ajax-actions.php
+++ b/wp-admin/includes/ajax-actions.php
@@ -1850,19 +1850,72 @@ function wp_ajax_save_attachment() {
wp_send_json_error();
$changes = $_REQUEST['changes'];
- $args = array();
+ $post = get_post( $id, ARRAY_A );
- if ( ! empty( $changes['title'] ) )
- $args['post_title'] = $changes['title'];
+ if ( 'attachment' != $post['post_type'] )
+ wp_send_json_error();
- if ( ! empty( $changes['caption'] ) )
- $args['post_excerpt'] = $changes['caption'];
+ if ( isset( $changes['title'] ) )
+ $post['post_title'] = $changes['title'];
- if ( ! empty( $changes['alt'] ) )
- $args['_wp_attachment_image_alt'] = $changes['alt'];
+ if ( isset( $changes['caption'] ) )
+ $post['post_excerpt'] = $changes['caption'];
- if ( $args )
- edit_post( array_merge( $args, array( 'post_ID' => $id ) ) );
+ if ( isset( $changes['alt'] ) ) {
+ $alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true );
+ $new_alt = stripslashes( $changes['alt'] );
+ if ( $alt != $new_alt ) {
+ $new_alt = wp_strip_all_tags( $new_alt, true );
+ update_post_meta( $id, '_wp_attachment_image_alt', addslashes( $new_alt ) );
+ }
+ }
+ wp_update_post( $post );
wp_send_json_success();
}
+
+/**
+ * Save backwards compatible attachment attributes.
+ *
+ * @since 3.5.0
+ */
+function wp_ajax_save_attachment_compat() {
+ if ( ! isset( $_REQUEST['id'] ) )
+ wp_send_json_error();
+
+ if ( ! $id = absint( $_REQUEST['id'] ) )
+ wp_send_json_error();
+
+ if ( empty( $_REQUEST['attachments'] ) || empty( $_REQUEST['attachments'][ $id ] ) )
+ wp_send_json_error();
+ $attachment_data = $_REQUEST['attachments'][ $id ];
+
+ check_ajax_referer( 'save-attachment', 'nonce' );
+
+ if ( ! current_user_can( 'edit_post', $id ) )
+ wp_send_json_error();
+
+ $post = get_post( $id, ARRAY_A );
+
+ if ( 'attachment' != $post['post_type'] )
+ wp_send_json_error();
+
+ $post = apply_filters( 'attachment_fields_to_save', $post, $attachment_data );
+
+ if ( isset( $post['errors'] ) ) {
+ $errors = $post['errors']; // @todo return me and display me!
+ unset( $post['errors'] );
+ }
+
+ wp_update_post( $post );
+
+ foreach ( get_attachment_taxonomies( $post ) as $taxonomy ) {
+ if ( isset( $attachment_data[ $taxonomy ] ) )
+ wp_set_object_terms( $id, array_map( 'trim', preg_split( '/,+/', $attachment_data[ $taxonomy ] ) ), $taxonomy, false );
+ }
+
+ if ( ! $attachment = wp_prepare_attachment_for_js( $id ) )
+ wp_send_json_error();
+
+ wp_send_json_success( $attachment );
+}
diff --git a/wp-admin/includes/media.php b/wp-admin/includes/media.php
index 6feed8d849..e48baaa355 100644
--- a/wp-admin/includes/media.php
+++ b/wp-admin/includes/media.php
@@ -1269,6 +1269,106 @@ function get_media_item( $attachment_id, $args = null ) {
return $item;
}
+function get_compat_media_markup( $attachment_id, $args = null ) {
+ $post = get_post( $attachment_id );
+
+ $default_args = array(
+ 'errors' => null,
+ );
+
+ $args = wp_parse_args( $args, $default_args );
+ $args = apply_filters( 'get_media_item_args', $args );
+
+ $errors = $args['errors'];
+
+ $form_fields = get_attachment_fields_to_edit( $post, $errors );
+
+ $media_meta = apply_filters( 'media_meta', '', $post );
+
+ $defaults = array(
+ 'input' => 'text',
+ 'required' => false,
+ 'value' => '',
+ 'extra_rows' => array(),
+ );
+
+ $hidden_fields = array();
+
+ unset( $form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'],
+ $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'],
+ $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url'] );
+
+ $item = '';
+ foreach ( $form_fields as $id => $field ) {
+ if ( $id[0] == '_' )
+ continue;
+
+ $name = "attachments[$attachment_id][$id]";
+
+ if ( !empty( $field['tr'] ) ) {
+ $item .= $field['tr'];
+ continue;
+ }
+
+ $field = array_merge( $defaults, $field );
+
+ if ( $field['input'] == 'hidden' ) {
+ $hidden_fields[$id] = $field['value'];
+ continue;
+ }
+
+ $required = $field['required'] ? '*' : '';
+ $aria_required = $field['required'] ? " aria-required='true' " : '';
+ $class = 'compat-item-' . $name;
+ $class .= $field['required'] ? ' form-required' : '';
+
+ $item .= "\t\t
";
+ $item .= "\t\t\t";
+ $item .= " | \n\t\t\t";
+
+ if ( !empty( $field[ $field['input'] ] ) )
+ $item .= $field[ $field['input'] ];
+ elseif ( $field['input'] == 'textarea' ) {
+ if ( 'post_content' == $id && user_can_richedit() ) {
+ // sanitize_post() skips the post_content when user_can_richedit
+ $field['value'] = htmlspecialchars( $field['value'], ENT_QUOTES );
+ }
+ $item .= "';
+ } else {
+ $item .= "";
+ }
+ if ( !empty( $field['helps'] ) )
+ $item .= " " . join( " \n", array_unique( (array) $field['helps'] ) ) . ' ';
+ $item .= " | \n\t\t
\n";
+
+ $extra_rows = array();
+
+ if ( !empty( $field['errors'] ) )
+ foreach ( array_unique( (array) $field['errors'] ) as $error )
+ $extra_rows['error'][] = $error;
+
+ if ( !empty( $field['extra_rows'] ) )
+ foreach ( $field['extra_rows'] as $class => $rows )
+ foreach ( (array) $rows as $html )
+ $extra_rows[$class][] = $html;
+
+ foreach ( $extra_rows as $class => $rows )
+ foreach ( $rows as $html )
+ $item .= "\t\t | $html |
\n";
+ }
+
+ if ( !empty( $form_fields['_final'] ) )
+ $item .= "\t\t{$form_fields['_final']} |
\n";
+ if ( $item )
+ $item = '';
+
+ return array(
+ 'item' => $item,
+ 'hidden' => $hidden_fields,
+ 'meta' => $media_meta,
+ );
+}
+
/**
* {@internal Missing Short Description}}
*
diff --git a/wp-includes/css/media-views.css b/wp-includes/css/media-views.css
index 1a4bffeddf..7dab330780 100644
--- a/wp-includes/css/media-views.css
+++ b/wp-includes/css/media-views.css
@@ -200,36 +200,97 @@
}
.media-sidebar .setting span {
- float: left;
min-width: 30%;
- min-height: 24px;
margin-right: 4%;
+}
+
+.media-sidebar .setting span,
+.compat-item label span {
+ float: left;
+ min-height: 22px;
padding-top: 8px;
line-height: 16px;
text-align: right;
+ font-weight: normal;
color: #999;
text-shadow: 0 1px 0 #fff;
}
.media-sidebar .setting input,
-.media-sidebar .setting textarea {
- float: right;
- width: 65%;
+.media-sidebar .setting textarea,
+.compat-item .field input,
+.compat-item .field textarea {
padding: 6px 8px;
line-height: 16px;
+}
+
+.media-sidebar .setting input,
+.media-sidebar .setting textarea {
+ width: 65%;
+ float: right;
+}
+
+.media-sidebar .setting textarea,
+.compat-item .field textarea {
+ height: 62px;
resize: none;
}
-.media-sidebar .setting textarea {
- height: 62px;
-}
-
-.media-sidebar .setting select {
+.media-sidebar .setting select,
+.compat-item .field select {
height: 28px;
line-height: 28px;
margin-top: 3px;
}
+.compat-item {
+ float: left;
+ width: 100%;
+ overflow: hidden;
+}
+
+.compat-item table {
+ width: 100%;
+ table-layout: fixed;
+ border-spacing: 0;
+ border: 0;
+}
+
+.compat-item tr {
+ padding: 2px 0;
+ display: block;
+ overflow: hidden;
+}
+
+.compat-item .label,
+.compat-item .field {
+ display: block;
+ margin: 0;
+ padding: 0;
+}
+
+.compat-item .label {
+ min-width: 30%;
+ margin-right: 4%;
+ float: left;
+ text-align: right;
+}
+.compat-item .label span {
+ display: block;
+ width: 100%;
+}
+
+.compat-item .field {
+ float: right;
+ width: 65%;
+ padding-right: 1px;
+}
+
+.compat-item .field input {
+ width: 100%;
+ margin: 0;
+}
+
/**
* Menu
@@ -855,7 +916,7 @@
color: #999;
border-bottom: 1px solid #e5e5e5;
box-shadow: 0 1px 0 #fff;
- padding-bottom: 16px;
+ padding-bottom: 11px;
}
.attachment-info .filename {
@@ -869,6 +930,7 @@
max-width: 120px;
max-height: 120px;
margin-right: 10px;
+ margin-bottom: 5px;
}
.attachment-info .thumbnail:after {
@@ -894,9 +956,17 @@
float: left;
}
+.attachment-info .compat-meta {
+ float: left;
+}
+
/**
* Attachment Display Settings
*/
+.attachment-display-settings {
+ overflow: hidden;
+ float: left;
+}
.attachment-display-settings h4 {
margin: 1.4em 0 0.4em;
diff --git a/wp-includes/js/media-models.js b/wp-includes/js/media-models.js
index ab5bc42a79..0b0790f54d 100644
--- a/wp-includes/js/media-models.js
+++ b/wp-includes/js/media-models.js
@@ -245,6 +245,17 @@ window.wp = window.wp || {};
resp.date = new Date( resp.date );
resp.modified = new Date( resp.modified );
return resp;
+ },
+
+ saveCompat: function( data, options ) {
+ var model = this;
+
+ return media.post( 'save-attachment-compat', _.defaults({
+ id: this.id,
+ nonce: l10n.saveAttachmentNonce
+ }, data ) ).done( function( resp, status, xhr ) {
+ model.set( model.parse( resp, xhr ), options );
+ });
}
}, {
create: function( attrs ) {
diff --git a/wp-includes/js/media-views.js b/wp-includes/js/media-views.js
index 79337720b5..71c5eec0dd 100644
--- a/wp-includes/js/media-views.js
+++ b/wp-includes/js/media-views.js
@@ -832,17 +832,28 @@
},
settingsSidebar: function( options ) {
+ var single = this.state().get('selection').single(),
+ views = {};
+
+ views.details = new media.view.Attachment.Details({
+ controller: this,
+ model: single,
+ priority: 80
+ }).render();
+
+
+ if ( single.get('compat') ) {
+ views.compat = new media.view.AttachmentCompat({
+ controller: this,
+ model: single,
+ priority: 120
+ }).render();
+ }
+
this.sidebar.view( new media.view.Sidebar({
controller: this,
silent: options && options.silent,
-
- views: {
- details: new media.view.Attachment.Details({
- controller: this,
- model: this.state().get('selection').single(),
- priority: 80
- }).render()
- }
+ views: views
}) );
},
@@ -1145,7 +1156,7 @@
controller: this,
model: display[ single.cid ],
sizes: single.get('sizes'),
- priority: 100,
+ priority: 160,
userSettings: state.get('displayUserSettings')
}).render()
}, options );
@@ -2638,6 +2649,54 @@
}
});
+ /**
+ * wp.media.view.AttachmentCompat
+ */
+ media.view.AttachmentCompat = Backbone.View.extend({
+ tagName: 'form',
+ className: 'compat-item',
+
+ events: {
+ 'submit': 'preventDefault',
+ 'change input': 'save',
+ 'change select': 'save',
+ 'change textarea': 'save'
+ },
+
+ initialize: function() {
+ this.model.on( 'change:compat', this.render, this );
+ },
+
+ destroy: function() {
+ this.model.off( null, null, this );
+ },
+
+ render: function() {
+ var compat = this.model.get('compat');
+ if ( ! compat || ! compat.item )
+ return;
+
+ this.$el.html( compat.item );
+ return this;
+ },
+
+ preventDefault: function( event ) {
+ event.preventDefault();
+ },
+
+ save: function( event ) {
+ var data = {};
+
+ event.preventDefault();
+
+ _.each( this.$el.serializeArray(), function( pair ) {
+ data[ pair.name ] = pair.value;
+ });
+
+ this.model.saveCompat( data );
+ }
+ });
+
/**
* wp.media.view.Iframe
*/
diff --git a/wp-includes/media.php b/wp-includes/media.php
index 9b60296eb1..da12220510 100644
--- a/wp-includes/media.php
+++ b/wp-includes/media.php
@@ -1288,6 +1288,9 @@ function wp_prepare_attachment_for_js( $attachment ) {
) );
}
+ if ( function_exists('get_compat_media_markup') )
+ $response['compat'] = get_compat_media_markup( $attachment->ID );
+
return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta );
}
@@ -1455,6 +1458,11 @@ function wp_print_media_templates( $attachment ) {
{{ width }} × {{ height }}
<# } #>
+
+ <# if ( compat && compat.meta ) { #>
+ {{{ compat.meta }}}
+ <# } #>
+
<# if ( 'image' === type ) { #>