diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index 6c9fdd2680..26d7e4770d 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -2267,6 +2267,9 @@ function wp_ajax_save_attachment() { if ( 'attachment' != $post['post_type'] ) wp_send_json_error(); + if ( isset( $changes['parent'] ) ) + $post['post_parent'] = $changes['parent']; + if ( isset( $changes['title'] ) ) $post['post_title'] = $changes['title']; diff --git a/src/wp-admin/includes/class-wp-media-list-table.php b/src/wp-admin/includes/class-wp-media-list-table.php index 483421b527..0401c61fae 100644 --- a/src/wp-admin/includes/class-wp-media-list-table.php +++ b/src/wp-admin/includes/class-wp-media-list-table.php @@ -139,6 +139,9 @@ class WP_Media_List_Table extends WP_List_Table { if ( isset( $_REQUEST['found_post_id'] ) && isset( $_REQUEST['media'] ) ) return 'attach'; + if ( isset( $_REQUEST['parent_post_id'] ) && isset( $_REQUEST['media'] ) ) + return 'detach'; + if ( isset( $_REQUEST['delete_all'] ) || isset( $_REQUEST['delete_all2'] ) ) return 'delete_all'; @@ -406,7 +409,16 @@ foreach ( $columns as $column_name => $column_display_name ) { } else { echo $title; } ?>, - +
+ $post->post_parent, + 'media[]' => $post->ID, + '_wpnonce' => wp_create_nonce( 'bulk-' . $this->_args['plural'] ) + ), 'upload.php' ); ?> + + query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( $ids_string )", $parent_id ) ); + } else { + $result = $wpdb->query( "UPDATE $wpdb->posts SET post_parent = 0 WHERE post_type = 'attachment' AND ID IN ( $ids_string )" ); + } + + foreach ( $ids as $att_id ) { + clean_attachment_cache( $att_id ); + } + } + + if ( isset( $result ) ) { + $location = 'upload.php'; + if ( $referer = wp_get_referer() ) { + if ( false !== strpos( $referer, 'upload.php' ) ) { + $location = remove_query_arg( array( 'attached', 'detached' ), $referer ); + } + } + + $key = 'attach' === $action ? 'attached' : 'detached'; + $location = add_query_arg( array( $key => $result ), $location ); + wp_redirect( $location ); + exit; + } +} \ No newline at end of file diff --git a/src/wp-admin/upload.php b/src/wp-admin/upload.php index 5408395dc7..e25b887175 100644 --- a/src/wp-admin/upload.php +++ b/src/wp-admin/upload.php @@ -113,45 +113,14 @@ if ( $doaction ) { } switch ( $doaction ) { - case 'attach': - $parent_id = (int) $_REQUEST['found_post_id']; - if ( !$parent_id ) - return; - - $parent = get_post( $parent_id ); - if ( !current_user_can( 'edit_post', $parent_id ) ) - wp_die( __( 'You are not allowed to edit this post.' ) ); - - $attach = array(); - foreach ( (array) $_REQUEST['media'] as $att_id ) { - $att_id = (int) $att_id; - - if ( !current_user_can( 'edit_post', $att_id ) ) - continue; - - $attach[] = $att_id; - } - - if ( ! empty( $attach ) ) { - $attach_string = implode( ',', $attach ); - $attached = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( $attach_string )", $parent_id ) ); - foreach ( $attach as $att_id ) { - clean_attachment_cache( $att_id ); - } - } - - if ( isset( $attached ) ) { - $location = 'upload.php'; - if ( $referer = wp_get_referer() ) { - if ( false !== strpos( $referer, 'upload.php' ) ) - $location = $referer; - } - - $location = add_query_arg( array( 'attached' => $attached ) , $location ); - wp_redirect( $location ); - exit; - } + case 'detach': + wp_media_attach_action( $_REQUEST['parent_post_id'], 'detach' ); break; + + case 'attach': + wp_media_attach_action( $_REQUEST['found_post_id'] ); + break; + case 'trash': if ( !isset( $post_ids ) ) break; @@ -256,7 +225,12 @@ if ( ! empty( $_GET['posted'] ) ) { if ( ! empty( $_GET['attached'] ) && $attached = absint( $_GET['attached'] ) ) { $message = sprintf( _n('Reattached %d attachment.', 'Reattached %d attachments.', $attached), $attached ); - $_SERVER['REQUEST_URI'] = remove_query_arg(array('attached'), $_SERVER['REQUEST_URI']); + $_SERVER['REQUEST_URI'] = remove_query_arg( array( 'detached', 'attached' ), $_SERVER['REQUEST_URI'] ); +} + +if ( ! empty( $_GET['detached'] ) && $detached = absint( $_GET['detached'] ) ) { + $message = sprintf( _n( 'Detached %d attachment.', 'Detached %d attachments.', $detached ), $detached ); + $_SERVER['REQUEST_URI'] = remove_query_arg( array( 'detached', 'attached' ), $_SERVER['REQUEST_URI'] ); } if ( ! empty( $_GET['deleted'] ) && $deleted = absint( $_GET['deleted'] ) ) { diff --git a/src/wp-includes/js/media/views.js b/src/wp-includes/js/media/views.js index 7964cdc147..0ef4b5150d 100644 --- a/src/wp-includes/js/media/views.js +++ b/src/wp-includes/js/media/views.js @@ -2656,6 +2656,7 @@ Attachment = View.extend({ this.listenTo( this.model, 'change', this.render ); } else { this.listenTo( this.model, 'change:percent', this.progress ); + this.listenTo( this.model, 'change:parent', this.render ); } this.listenTo( this.model, 'change:title', this._syncTitle ); this.listenTo( this.model, 'change:caption', this._syncCaption ); @@ -3195,7 +3196,8 @@ Details = Attachment.extend({ 'click .untrash-attachment': 'untrashAttachment', 'click .edit-attachment': 'editAttachment', 'click .refresh-attachment': 'refreshAttachment', - 'keydown': 'toggleSelectionHandler' + 'keydown': 'toggleSelectionHandler', + 'click .detach-from-parent': 'detachFromParent' }, initialize: function() { @@ -3294,6 +3296,20 @@ Details = Attachment.extend({ this.controller.trigger( 'attachment:keydown:arrow', event ); return; } + }, + + /** + * @param {Object} event + */ + detachFromParent: function( event ) { + event.preventDefault(); + + this.model.save({ + 'parent' : 0, + 'uploadedTo' : 0, + 'uploadedToLink' : '', + 'uploadedToTitle' : '' + }); } }); diff --git a/src/wp-includes/js/media/views/attachment.js b/src/wp-includes/js/media/views/attachment.js index 535f689e24..768477a04f 100644 --- a/src/wp-includes/js/media/views/attachment.js +++ b/src/wp-includes/js/media/views/attachment.js @@ -52,6 +52,7 @@ Attachment = View.extend({ this.listenTo( this.model, 'change', this.render ); } else { this.listenTo( this.model, 'change:percent', this.progress ); + this.listenTo( this.model, 'change:parent', this.render ); } this.listenTo( this.model, 'change:title', this._syncTitle ); this.listenTo( this.model, 'change:caption', this._syncCaption ); diff --git a/src/wp-includes/js/media/views/attachment/details.js b/src/wp-includes/js/media/views/attachment/details.js index f7a2ed9c1e..4e77fd6a3c 100644 --- a/src/wp-includes/js/media/views/attachment/details.js +++ b/src/wp-includes/js/media/views/attachment/details.js @@ -35,7 +35,8 @@ Details = Attachment.extend({ 'click .untrash-attachment': 'untrashAttachment', 'click .edit-attachment': 'editAttachment', 'click .refresh-attachment': 'refreshAttachment', - 'keydown': 'toggleSelectionHandler' + 'keydown': 'toggleSelectionHandler', + 'click .detach-from-parent': 'detachFromParent' }, initialize: function() { @@ -134,6 +135,20 @@ Details = Attachment.extend({ this.controller.trigger( 'attachment:keydown:arrow', event ); return; } + }, + + /** + * @param {Object} event + */ + detachFromParent: function( event ) { + event.preventDefault(); + + this.model.save({ + 'parent' : 0, + 'uploadedTo' : 0, + 'uploadedToLink' : '', + 'uploadedToTitle' : '' + }); } }); diff --git a/src/wp-includes/media-template.php b/src/wp-includes/media-template.php index 76b2d32af4..c7ec89acfc 100644 --- a/src/wp-includes/media-template.php +++ b/src/wp-includes/media-template.php @@ -418,6 +418,9 @@ function wp_print_media_templates() { <# } else { #> {{ data.uploadedToTitle }} <# } #> + <# if ( data.nonces.edit ) { #> + () + <# } #> <# } #>