Ticket #29145: 29145.diff
File 29145.diff, 15.5 KB (added by , 11 years ago) |
---|
-
src/wp-admin/includes/ajax-actions.php
2161 2161 ) ) ); 2162 2162 2163 2163 $query['post_type'] = 'attachment'; 2164 $query['post_status'] = 'inherit'; 2164 if ( MEDIA_TRASH 2165 && ! empty( $_REQUEST['query']['post_status'] ) 2166 && 'trash' === $_REQUEST['query']['post_status'] ) { 2167 $query['post_status'] = 'trash'; 2168 } else { 2169 $query['post_status'] = 'inherit'; 2170 } 2171 2165 2172 if ( current_user_can( get_post_type_object( 'attachment' )->cap->read_private_posts ) ) 2166 2173 $query['post_status'] .= ',private'; 2167 2174 … … 2216 2223 if ( isset( $changes['description'] ) ) 2217 2224 $post['post_content'] = $changes['description']; 2218 2225 2226 if ( MEDIA_TRASH && isset( $changes['status'] ) ) 2227 $post['post_status'] = $changes['status']; 2228 2219 2229 if ( isset( $changes['alt'] ) ) { 2220 2230 $alt = wp_unslash( $changes['alt'] ); 2221 2231 if ( $alt != get_post_meta( $id, '_wp_attachment_image_alt', true ) ) { -
src/wp-includes/css/media-views.css
1603 1603 .attachment-info .edit-attachment, 1604 1604 .attachment-info .refresh-attachment, 1605 1605 .attachment-info .delete-attachment, 1606 .attachment-info .trash-attachment { 1606 .attachment-info .trash-attachment, 1607 .attachment-info .untrash-attachment { 1607 1608 display: block; 1608 1609 text-decoration: none; 1609 1610 white-space: nowrap; … … 1620 1621 } 1621 1622 1622 1623 .media-modal .delete-attachment, 1623 .media-modal .trash-attachment { 1624 .media-modal .trash-attachment, 1625 .media-modal .untrash-attachment { 1624 1626 color: #bc0b0b; 1625 1627 } 1626 1628 1627 1629 .media-modal .delete-attachment:hover, 1628 .media-modal .trash-attachment:hover { 1630 .media-modal .trash-attachment:hover, 1631 .media-modal .untrash-attachment:hover { 1629 1632 color: red; 1630 1633 } 1631 1634 … … 2738 2741 max-height: calc( 100% - 42px ); /* leave space for actions underneath */ 2739 2742 } 2740 2743 2741 .edit-attachment-frame .delete-attachment { 2744 .edit-attachment-frame .delete-attachment, 2745 .edit-attachment-frame .trash-attachment, 2746 .edit-attachment-frame .untrash-attachment { 2742 2747 float: right; 2743 2748 margin-top: 7px; 2744 2749 } -
src/wp-includes/js/media-grid.js
180 180 // Create a new EditAttachment frame, passing along the library and the attachment model. 181 181 wp.media( { 182 182 frame: 'edit-attachments', 183 gridRouter: this.gridRouter,183 controller: this, 184 184 library: this.state().get('library'), 185 185 model: model 186 186 } ); … … 227 227 }, 228 228 229 229 bindDeferred: function() { 230 if ( ! this.browserView.dfd ) { 231 return; 232 } 230 233 this.browserView.dfd.done( _.bind( this.startHistory, this ) ); 231 234 }, 232 235 … … 349 352 regions: [ 'title', 'content' ], 350 353 351 354 events: { 352 'click': 'collapse',353 'click .delete-media-item': 'deleteMediaItem',354 355 'click .left': 'previousMediaItem', 355 356 'click .right': 'nextMediaItem' 356 357 }, 357 358 358 359 initialize: function() { 359 var self = this;360 361 360 media.view.Frame.prototype.initialize.apply( this, arguments ); 362 361 363 362 _.defaults( this.options, { … … 365 364 state: 'edit-attachment' 366 365 }); 367 366 368 this. gridRouter = this.options.gridRouter;369 367 this.controller = this.options.controller; 368 this.gridRouter = this.controller.gridRouter; 370 369 this.library = this.options.library; 371 370 372 371 if ( this.options.model ) { 373 372 this.model = this.options.model; 374 373 } else { 374 // this is a hack 375 375 this.model = this.library.at( 0 ); 376 376 } 377 377 378 this.bindHandlers(); 379 this.createStates(); 380 this.createModal(); 381 382 this.title.mode( 'default' ); 383 384 this.options.hasPrevious = this.hasPrevious(); 385 this.options.hasNext = this.hasNext(); 386 }, 387 388 bindHandlers: function() { 389 // Bind default title creation. 390 this.on( 'title:create:default', this.createTitle, this ); 391 378 392 // Close the modal if the attachment is deleted. 379 this.listenTo( this.model, ' destroy', this.close, this );393 this.listenTo( this.model, 'change:status destroy', this.close, this ); 380 394 381 this.createStates();382 383 395 this.on( 'content:create:edit-metadata', this.editMetadataMode, this ); 384 396 this.on( 'content:create:edit-image', this.editImageMode, this ); 385 397 this.on( 'content:render:edit-image', this.editImageModeRender, this ); 386 398 this.on( 'close', this.detach ); 399 }, 387 400 388 // Bind default title creation. 389 this.on( 'title:create:default', this.createTitle, this ); 390 this.title.mode( 'default' ); 401 createModal: function() { 402 var self = this; 391 403 392 this.options.hasPrevious = this.hasPrevious();393 this.options.hasNext = this.hasNext();394 395 404 // Initialize modal container view. 396 405 if ( this.options.modal ) { 397 406 this.modal = new media.view.Modal({ … … 604 613 media.view.DeleteSelectedButton = media.view.Button.extend({ 605 614 initialize: function() { 606 615 media.view.Button.prototype.initialize.apply( this, arguments ); 616 if ( this.options.filters ) { 617 this.listenTo( this.options.filters.model, 'change', this.filterChange ); 618 } 607 619 this.listenTo( this.controller, 'selection:toggle', this.toggleDisabled ); 608 620 }, 609 621 622 filterChange: function( model ) { 623 if ( 'trash' === model.get( 'status' ) ) { 624 this.model.set( 'text', l10n.untrashSelected ); 625 } else if ( media.view.settings.mediaTrash ) { 626 this.model.set( 'text', l10n.trashSelected ); 627 } else { 628 this.model.set( 'text', l10n.deleteSelected ); 629 } 630 }, 631 610 632 toggleDisabled: function() { 611 this. $el.attr( 'disabled', ! this.controller.state().get( 'selection' ).length );633 this.model.set( 'disabled', ! this.controller.state().get( 'selection' ).length ); 612 634 }, 613 635 614 636 render: function() { 615 637 media.view.Button.prototype.render.apply( this, arguments ); 616 this.$el.addClass( 'delete-selected-button hidden' ); 638 if ( this.controller.isModeActive( 'select' ) ) { 639 this.$el.addClass( 'delete-selected-button' ); 640 } else { 641 this.$el.addClass( 'delete-selected-button hidden' ); 642 } 617 643 return this; 618 644 } 619 645 }); -
src/wp-includes/js/media-models.js
947 947 } 948 948 949 949 return uploadedTo === attachment.get('uploadedTo'); 950 }, 951 /** 952 * @static 953 * @param {wp.media.model.Attachment} attachment 954 * 955 * @this wp.media.model.Attachments 956 * 957 * @returns {Boolean} 958 */ 959 status: function( attachment ) { 960 var status = this.props.get('status'); 961 if ( _.isUndefined( status ) ) { 962 return true; 963 } 964 965 return status === attachment.get('status'); 950 966 } 951 967 } 952 968 }); … … 1144 1160 'type': 'post_mime_type', 1145 1161 'perPage': 'posts_per_page', 1146 1162 'menuOrder': 'menu_order', 1147 'uploadedTo': 'post_parent' 1163 'uploadedTo': 'post_parent', 1164 'status': 'post_status' 1148 1165 }, 1149 1166 /** 1150 1167 * @static -
src/wp-includes/js/media-views.js
5671 5671 filters[ key ] = { 5672 5672 text: text, 5673 5673 props: { 5674 status: null, 5674 5675 type: key, 5675 5676 uploadedTo: null, 5676 5677 orderby: 'date', … … 5682 5683 filters.all = { 5683 5684 text: l10n.allMediaItems, 5684 5685 props: { 5686 status: null, 5685 5687 type: null, 5686 5688 uploadedTo: null, 5687 5689 orderby: 'date', … … 5694 5696 filters.uploaded = { 5695 5697 text: l10n.uploadedToThisPost, 5696 5698 props: { 5699 status: null, 5697 5700 type: null, 5698 5701 uploadedTo: media.view.settings.post.id, 5699 5702 orderby: 'menuOrder', … … 5706 5709 filters.unattached = { 5707 5710 text: l10n.unattached, 5708 5711 props: { 5712 status: null, 5709 5713 uploadedTo: 0, 5710 5714 type: null, 5711 5715 orderby: 'menuOrder', … … 5714 5718 priority: 50 5715 5719 }; 5716 5720 5721 if ( media.view.settings.mediaTrash ) { 5722 filters.trash = { 5723 text: l10n.trash, 5724 props: { 5725 uploadedTo: null, 5726 status: 'trash', 5727 type: null, 5728 orderby: 'date', 5729 order: 'DESC' 5730 }, 5731 priority: 50 5732 }; 5733 } 5734 5717 5735 this.filters = filters; 5718 5736 } 5719 5737 }); … … 5767 5785 createToolbar: function() { 5768 5786 var filters, 5769 5787 LibraryViewSwitcher, 5770 Filters Constructor;5788 Filters; 5771 5789 5772 5790 /** 5773 5791 * @member {wp.media.view.Toolbar} … … 5778 5796 5779 5797 this.views.add( this.toolbar ); 5780 5798 5799 this.toolbar.set( 'spinner', new media.view.Spinner({ 5800 priority: -60 5801 }) ); 5802 5803 filters = this.options.filters; 5804 5805 if ( -1 !== $.inArray( filters, [ 'uploaded', 'all' ] ) ) { 5806 // "FiltersConstructor" will return a <select>, need to render 5807 // screen reader text before 5808 this.toolbar.set( 'filtersLabel', new media.view.Label({ 5809 value: l10n.filterByType, 5810 attributes: { 5811 'for': 'media-attachment-filters' 5812 }, 5813 priority: -80 5814 }).render() ); 5815 5816 if ( 'uploaded' === filters ) { 5817 this.toolbar.set( 'filters', new media.view.AttachmentFilters.Uploaded({ 5818 controller: this.controller, 5819 model: this.collection.props, 5820 priority: -80 5821 }).render() ); 5822 } else { 5823 Filters = new media.view.AttachmentFilters.All({ 5824 controller: this.controller, 5825 model: this.collection.props, 5826 priority: -80 5827 }); 5828 5829 this.toolbar.set( 'filters', Filters.render() ); 5830 } 5831 } 5832 5781 5833 // Feels odd to bring the global media library switcher into the Attachment 5782 5834 // browser view. Is this a use case for doAction( 'add:toolbar-items:attachments-browser', this.toolbar ); 5783 5835 // which the controller can tap into and add this view? … … 5814 5866 }).render() ); 5815 5867 5816 5868 this.toolbar.set( 'deleteSelectedButton', new media.view.DeleteSelectedButton({ 5869 filters: Filters, 5817 5870 style: 'primary', 5818 5871 disabled: true, 5819 text: l10n.deleteSelected,5872 text: media.view.settings.mediaTrash ? l10n.trashSelected : l10n.deleteSelected, 5820 5873 controller: this.controller, 5821 5874 priority: -60, 5822 5875 click: function() { 5876 var model; 5877 5823 5878 while ( this.controller.state().get( 'selection' ).length > 0 ) { 5824 this.controller.state().get( 'selection' ).at( 0 ).destroy(); 5879 model = this.controller.state().get( 'selection' ).at( 0 ); 5880 if ( media.view.settings.mediaTrash && 'trash' === model.get( 'status' ) ) { 5881 model.set( 'status', 'inherit' ); 5882 } else { 5883 model.destroy(); 5884 } 5825 5885 } 5826 5886 } 5827 5887 }).render() ); 5828 5888 } 5829 5889 5830 this.toolbar.set( 'spinner', new media.view.Spinner({5831 priority: -605832 }) );5833 5834 filters = this.options.filters;5835 if ( 'uploaded' === filters ) {5836 FiltersConstructor = media.view.AttachmentFilters.Uploaded;5837 } else if ( 'all' === filters ) {5838 FiltersConstructor = media.view.AttachmentFilters.All;5839 }5840 5841 if ( FiltersConstructor ) {5842 // "FiltersConstructor" will return a <select>, need to render5843 // screen reader text before5844 this.toolbar.set( 'filtersLabel', new media.view.Label({5845 value: l10n.filterByType,5846 attributes: {5847 'for': 'media-attachment-filters'5848 },5849 priority: -805850 }).render() );5851 this.toolbar.set( 'filters', new FiltersConstructor({5852 controller: this.controller,5853 model: this.collection.props,5854 priority: -805855 }).render() );5856 }5857 5858 5890 if ( this.options.search ) { 5859 5891 // Search is an input, screen reader text needs to be rendered before 5860 5892 this.toolbar.set( 'searchLabel', new media.view.Label({ … … 6420 6452 'change [data-setting] textarea': 'updateSetting', 6421 6453 'click .delete-attachment': 'deleteAttachment', 6422 6454 'click .trash-attachment': 'trashAttachment', 6455 'click .untrash-attachment': 'untrashAttachment', 6423 6456 'click .edit-attachment': 'editAttachment', 6424 6457 'click .refresh-attachment': 'refreshAttachment', 6425 6458 'keydown': 'toggleSelectionHandler' … … 6453 6486 * @param {Object} event 6454 6487 */ 6455 6488 trashAttachment: function( event ) { 6489 var library; 6456 6490 event.preventDefault(); 6457 6491 6458 6492 this.model.destroy(); 6493 6494 library = this.controller.library; 6495 library.validateAll( media.model.Attachments.all ); 6459 6496 }, 6460 6497 /** 6461 6498 * @param {Object} event 6462 6499 */ 6500 untrashAttachment: function( event ) { 6501 var library; 6502 event.preventDefault(); 6503 6504 this.model.set( 'status', 'inherit' ); 6505 this.model.save(); 6506 6507 library = this.controller.library; 6508 library.validate( this.model ); 6509 }, 6510 /** 6511 * @param {Object} event 6512 */ 6463 6513 editAttachment: function( event ) { 6464 6514 var editState = this.controller.states.get( 'edit-image' ); 6465 6515 if ( window.imageEdit && editState ) { -
src/wp-includes/media-template.php
316 316 317 317 <# if ( ! data.uploading && data.can.remove ) { #> 318 318 <?php if ( MEDIA_TRASH ): ?> 319 <# if ( 'trash' === data.status ) { #> 320 <a class="untrash-attachment" href="#"><?php _e( 'Untrash' ); ?></a> 321 <# } else { #> 319 322 <a class="trash-attachment" href="#"><?php _e( 'Trash' ); ?></a> 323 <# } #> 320 324 <?php else: ?> 321 325 <a class="delete-attachment" href="#"><?php _e( 'Delete Permanently' ); ?></a> 322 326 <?php endif; ?> -
src/wp-includes/media.php
2869 2869 'embedMimes' => $ext_mimes, 2870 2870 'contentWidth' => $content_width, 2871 2871 'months' => $months, 2872 'mediaTrash' => MEDIA_TRASH ? 1 : 0 2872 2873 ); 2873 2874 2874 2875 $post = null; … … 2931 2932 'noItemsFound' => __( 'No items found.' ), 2932 2933 'insertIntoPost' => $hier ? __( 'Insert into page' ) : __( 'Insert into post' ), 2933 2934 'unattached' => __( 'Unattached' ), 2935 'trash' => __( 'Trash' ), 2934 2936 'uploadedToThisPost' => $hier ? __( 'Uploaded to this page' ) : __( 'Uploaded to this post' ), 2935 2937 'warnDelete' => __( "You are about to permanently delete this item.\n 'Cancel' to stop, 'OK' to delete." ), 2936 2938 'warnBulkDelete' => __( "You are about to permanently delete these items.\n 'Cancel' to stop, 'OK' to delete." ), 2937 2939 'bulkSelect' => __( 'Bulk Select' ), 2938 2940 'cancelSelection' => __( 'Cancel Selection' ), 2941 'trashSelected' => __( 'Trash Selected' ), 2942 'untrashSelected' => __( 'Untrash Selected' ), 2939 2943 'deleteSelected' => __( 'Delete Selected' ), 2940 2944 'deletePermanently' => __( 'Delete Permanently' ), 2941 2945 'apply' => __( 'Apply' ), -
src/wp-includes/script-loader.php
402 402 $scripts->add( 'media-models', "/wp-includes/js/media-models$suffix.js", array( 'wp-backbone' ), false, 1 ); 403 403 did_action( 'init' ) && $scripts->localize( 'media-models', '_wpMediaModelsL10n', array( 404 404 'settings' => array( 405 'mediaTrash' => MEDIA_TRASH ? 1 : 0, 405 406 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), 406 407 'post' => array( 'id' => 0 ), 407 408 ),