From 57b09463e673b7522e1c142a21c9e694f9857d19 Mon Sep 17 00:00:00 2001 From: Daryl Koopersmith Date: Sun, 11 Nov 2012 01:26:42 +0000 Subject: [PATCH] Media: Add backwards compatibility for attachment_fields_to_edit and attachment_fields_to_save. see #22186. git-svn-id: https://develop.svn.wordpress.org/trunk@22541 602fd350-edb4-49c9-b593-d223f7449a82 --- wp-admin/admin-ajax.php | 2 +- wp-admin/includes/ajax-actions.php | 71 +++++++++++++++++--- wp-admin/includes/media.php | 100 +++++++++++++++++++++++++++++ wp-includes/css/media-views.css | 92 ++++++++++++++++++++++---- wp-includes/js/media-models.js | 11 ++++ wp-includes/js/media-views.js | 77 +++++++++++++++++++--- wp-includes/media.php | 8 +++ 7 files changed, 331 insertions(+), 30 deletions(-) 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 = '' . $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 ) { #>