WordPress.org

Make WordPress Core

Ticket #21776: 21776.6.diff

File 21776.6.diff, 18.6 KB (added by koopersmith, 7 years ago)
  • wp-admin/includes/ajax-actions.php

     
    16741674}
    16751675
    16761676function wp_ajax_set_post_thumbnail() {
     1677        $json = ! empty( $_REQUEST['json'] );
     1678
    16771679        $post_ID = intval( $_POST['post_id'] );
    1678         if ( !current_user_can( 'edit_post', $post_ID ) )
    1679                 wp_die( -1 );
     1680        if ( !current_user_can( 'edit_post', $post_ID ) ) {
     1681                $json ? wp_send_json_error() : wp_die( -1 );
     1682        }
    16801683        $thumbnail_id = intval( $_POST['thumbnail_id'] );
    16811684
    16821685        check_ajax_referer( "set_post_thumbnail-$post_ID" );
    16831686
    16841687        if ( $thumbnail_id == '-1' ) {
    1685                 if ( delete_post_thumbnail( $post_ID ) )
    1686                         wp_die( _wp_post_thumbnail_html( null, $post_ID ) );
    1687                 else
    1688                         wp_die( 0 );
     1688                if ( delete_post_thumbnail( $post_ID ) ) {
     1689                        $return = _wp_post_thumbnail_html( null, $post_ID );
     1690                        $json ? wp_send_json_success( $return ) : wp_die( $json );
     1691                } else {
     1692                        $json ? wp_send_json_error() : wp_die( 0 );
     1693                }
    16891694        }
    16901695
    1691         if ( set_post_thumbnail( $post_ID, $thumbnail_id ) )
    1692                 wp_die( _wp_post_thumbnail_html( $thumbnail_id, $post_ID ) );
    1693         wp_die( 0 );
     1696        if ( set_post_thumbnail( $post_ID, $thumbnail_id ) ) {
     1697                $return = _wp_post_thumbnail_html( $thumbnail_id, $post_ID );
     1698                $json ? wp_send_json_success( $return ) : wp_die( $json );
     1699        }
     1700
     1701        $json ? wp_send_json_error() : wp_die( 0 );
    16941702}
    16951703
    16961704function wp_ajax_date_format() {
  • wp-admin/includes/meta-boxes.php

     
    10011001 * @since 2.9.0
    10021002 */
    10031003function post_thumbnail_meta_box( $post ) {
    1004         global $_wp_additional_image_sizes;
    1005 
    1006         ?><script type="text/javascript">
    1007         jQuery( function($) {
    1008                 var $element     = $('#select-featured-image'),
    1009                         $thumbnailId = $element.find('input[name="thumbnail_id"]'),
    1010                         title        = '<?php _e( "Choose a Featured Image" ); ?>',
    1011                         update       = '<?php _e( "Update Featured Image" ); ?>',
    1012                         Attachment   = wp.media.model.Attachment,
    1013                         frame, setFeaturedImage;
    1014 
    1015                 setFeaturedImage = function( thumbnailId ) {
    1016                         var selection;
    1017 
    1018                         $element.find('img').remove();
    1019                         $element.toggleClass( 'has-featured-image', -1 != thumbnailId );
    1020                         $thumbnailId.val( thumbnailId );
    1021 
    1022                         if ( frame ) {
    1023                                 selection = frame.state('library').get('selection');
    1024 
    1025                                 if ( -1 === thumbnailId )
    1026                                         selection.clear();
    1027                                 else
    1028                                         selection.add( Attachment.get( thumbnailId ) );
    1029                         }
    1030                 };
    1031 
    1032                 $element.on( 'click', '.choose, img', function( event ) {
    1033                         var options, thumbnailId, attachment;
    1034 
    1035                         event.preventDefault();
    1036 
    1037                         if ( frame ) {
    1038                                 frame.open();
    1039                                 return;
    1040                         }
    1041 
    1042                         options = {
    1043                                 title:   title,
    1044                                 library: {
    1045                                         type: 'image'
    1046                                 }
    1047                         };
    1048 
    1049                         thumbnailId = $thumbnailId.val();
    1050                         if ( '' !== thumbnailId && -1 !== thumbnailId ) {
    1051                                 attachment = Attachment.get( thumbnailId );
    1052                                 attachment.fetch();
    1053                                 options.selection = [ attachment ];
    1054                         }
    1055 
    1056                         frame = wp.media( options );
    1057 
    1058                         frame.state('library').set( 'filterable', 'uploaded' );
    1059 
    1060                         frame.toolbar.on( 'activate:select', function() {
    1061                                 frame.toolbar.view().set({
    1062                                         select: {
    1063                                                 style: 'primary',
    1064                                                 text:  update,
    1065 
    1066                                                 click: function() {
    1067                                                         var selection = frame.state().get('selection'),
    1068                                                                 model = selection.first(),
    1069                                                                 sizes = model.get('sizes'),
    1070                                                                 size;
    1071 
    1072                                                         setFeaturedImage( model.id );
    1073 
    1074                                                         // @todo: might need a size hierarchy equivalent.
    1075                                                         if ( sizes )
    1076                                                                 size = sizes['post-thumbnail'] || sizes.medium;
    1077 
    1078                                                         // @todo: Need a better way of accessing full size
    1079                                                         // data besides just calling toJSON().
    1080                                                         size = size || model.toJSON();
    1081 
    1082                                                         frame.close();
    1083 
    1084                                                         $( '<img />', {
    1085                                                                 src:    size.url,
    1086                                                                 width:  size.width
    1087                                                         }).prependTo( $element );
    1088                                                 }
    1089                                         }
    1090                                 });
    1091                         });
    1092 
    1093                         frame.toolbar.mode('select');
    1094                 });
    1095 
    1096                 $element.on( 'click', '.remove', function( event ) {
    1097                         event.preventDefault();
    1098                         setFeaturedImage( -1 );
    1099                 });
    1100         });
    1101         </script>
    1102 
    1103         <?php
    1104         $thumbnail_id   = get_post_meta( $post->ID, '_thumbnail_id', true );
    1105         $thumbnail_size = isset( $_wp_additional_image_sizes['post-thumbnail'] ) ? 'post-thumbnail' : 'medium';
    1106         $thumbnail_html = wp_get_attachment_image( $thumbnail_id, $thumbnail_size );
    1107 
    1108         $classes = empty( $thumbnail_id ) ? '' : 'has-featured-image';
    1109 
    1110         ?><div id="select-featured-image"
    1111                 class="<?php echo esc_attr( $classes ); ?>"
    1112                 data-post-id="<?php echo esc_attr( $post->ID ); ?>">
    1113                 <?php echo $thumbnail_html; ?>
    1114                 <input type="hidden" name="thumbnail_id" value="<?php echo esc_attr( $thumbnail_id ); ?>" />
    1115                 <a href="#" class="choose button-secondary"><?php _e( 'Choose a Featured Image' ); ?></a>
    1116                 <a href="#" class="remove"><?php _e( 'Remove Featured Image' ); ?></a>
    1117         </div>
    1118         <?php
     1004        $thumbnail_id = get_post_meta( $post->ID, '_thumbnail_id', true );
     1005        echo _wp_post_thumbnail_html( $thumbnail_id, $post->ID );
    11191006}
     1007 No newline at end of file
  • wp-admin/includes/post.php

     
    199199                        set_post_format( $post_ID, false );
    200200        }
    201201
    202         // Featured Images
    203         if ( isset( $post_data['thumbnail_id'] ) ) {
    204                 if ( '-1' == $post_data['thumbnail_id'] )
    205                         delete_post_thumbnail( $post_ID );
    206                 else
    207                         set_post_thumbnail( $post_ID, $post_data['thumbnail_id'] );
    208         }
    209 
    210202        // Meta Stuff
    211203        if ( isset($post_data['meta']) && $post_data['meta'] ) {
    212204                foreach ( $post_data['meta'] as $key => $value ) {
  • wp-admin/js/custom-background.js

     
    5757                                });
    5858                        });
    5959
    60                         frame.setState('library');
     60                        frame.setState('library').open();
    6161                });
    6262        });
    6363})(jQuery);
     64 No newline at end of file
  • wp-admin/js/custom-header.js

     
    4040                                });
    4141                        });
    4242
    43                         frame.setState('library');
     43                        frame.setState('library').open();
    4444                });
    4545        });
    4646}(jQuery));
  • wp-includes/css/media-views.css

     
    403403 */
    404404.media-frame {
    405405        overflow: hidden;
     406        position: absolute;
     407        top: 0;
     408        left: 0;
     409        right: 0;
     410        bottom: 0;
    406411}
    407412
    408413.media-frame .region-content {
  • wp-includes/js/media-editor.js

     
    375375
    376376                        workflow = workflows[ id ] = wp.media( _.defaults( options || {}, {
    377377                                frame:    'post',
     378                                state:    'upload',
    378379                                title:    wp.media.view.l10n.addMedia,
    379380                                multiple: true
    380381                        } ) );
     
    427428                                }
    428429                        }, this );
    429430
     431                        workflow.state('featured-image').on( 'select', function() {
     432                                var settings = wp.media.view.settings,
     433                                        featuredImage = settings.featuredImage,
     434                                        selection = this.get('selection').single();
     435
     436                                if ( ! featuredImage )
     437                                        return;
     438
     439                                featuredImage.id = selection ? selection.id : -1;
     440                                wp.media.post( 'set-post-thumbnail', {
     441                                        json:         true,
     442                                        post_id:      settings.postId,
     443                                        thumbnail_id: featuredImage.id,
     444                                        _wpnonce:     featuredImage.nonce
     445                                }).done( function( html ) {
     446                                        $( '.inside', '#postimagediv' ).html( html );
     447                                        $('#set-post-thumbnail').removeClass('thickbox');
     448                                });
     449                        });
     450
     451                        workflow.setState( workflow.options.state );
    430452                        return workflow;
    431453                },
    432454
     455                id: function( id ) {
     456                        if ( id )
     457                                return id;
     458
     459                        // If an empty `id` is provided, default to `wpActiveEditor`.
     460                        id = wpActiveEditor;
     461
     462                        // If that doesn't work, fall back to `tinymce.activeEditor.id`.
     463                        if ( ! id && typeof tinymce !== 'undefined' && tinymce.activeEditor )
     464                                id = tinymce.activeEditor.id;
     465
     466                        // Last but not least, fall back to the empty string.
     467                        id = id || '';
     468                        return id;
     469                },
     470
    433471                get: function( id ) {
     472                        id = this.id( id );
    434473                        return workflows[ id ];
    435474                },
    436475
    437476                remove: function( id ) {
     477                        id = this.id( id );
    438478                        delete workflows[ id ];
    439479                },
    440480
     
    497537                        }
    498538                },
    499539
     540                open: function( id ) {
     541                        var workflow, editor;
     542
     543                        id = this.id( id );
     544
     545                        // Save a bookmark of the caret position in IE.
     546                        if ( typeof tinymce !== 'undefined' ) {
     547                                editor = tinymce.get( id );
     548
     549                                if ( tinymce.isIE && editor && ! editor.isHidden() ) {
     550                                        editor.focus();
     551                                        editor.windowManager.insertimagebookmark = editor.selection.getBookmark();
     552                                }
     553                        }
     554
     555                        workflow = this.get( id );
     556
     557                        // Initialize the editor's workflow if we haven't yet.
     558                        if ( ! workflow )
     559                                workflow = this.add( id );
     560
     561                        return workflow.open();
     562                },
     563
    500564                init: function() {
    501565                        $(document.body).on( 'click', '.insert-media', function( event ) {
    502566                                var $this = $(this),
     
    513577
    514578                                wp.media.editor.open( editor );
    515579                        });
    516                 },
    517580
    518                 open: function( id ) {
    519                         var workflow, editor;
     581                        // Initialize post thumbnails.
     582                        $('#set-post-thumbnail').removeClass('thickbox');
     583                        $('#postimagediv').on( 'click', '#set-post-thumbnail', function( event ) {
     584                                event.preventDefault();
    520585
    521                         // If an empty `id` is provided, default to `wpActiveEditor`.
    522                         id = id || wpActiveEditor;
     586                                // Always get the 'content' frame, since this is tailored to post.php.
     587                                var frame = wp.media.editor.get('content') || wp.media.editor.add('content'),
     588                                        id = wp.media.view.settings.featuredImage.id,
     589                                        model = wp.media.model,
     590                                        selection = [],
     591                                        attachment;
    523592
    524                         if ( typeof tinymce !== 'undefined' && tinymce.activeEditor ) {
    525                                 // If that doesn't work, fall back to `tinymce.activeEditor`.
    526                                 if ( ! id ) {
    527                                         editor = tinymce.activeEditor;
    528                                         id = id || editor.id;
    529                                 } else {
    530                                         editor = tinymce.get( id );
     593                                if ( '' !== id && -1 !== id ) {
     594                                        attachment = model.Attachment.get( id );
     595                                        attachment.fetch();
     596                                        selection.push( attachment );
    531597                                }
    532598
    533                                 // Save a bookmark of the caret position, needed for IE
    534                                 if ( tinymce.isIE && editor && ! editor.isHidden() ) {
    535                                         editor.focus();
    536                                         editor.windowManager.insertimagebookmark = editor.selection.getBookmark();
    537                                 }
    538                         }
     599                                selection = new model.Selection( selection );
    539600
    540                         // Last but not least, fall back to the empty string.
    541                         id = id || '';
    542 
    543                         workflow = wp.media.editor.get( id );
    544 
    545                         // If the workflow exists, open it.
    546                         // Initialize the editor's workflow if we haven't yet.
    547                         if ( workflow )
    548                                 workflow.open();
    549                         else
    550                                 workflow = wp.media.editor.add( id );
    551 
    552                         return workflow;
     601                                frame.state('featured-image').set( 'selection', selection );
     602                                frame.setState('featured-image').open();
     603                        });
    553604                }
    554605        };
    555606
     607        _.bindAll( wp.media.editor, 'open' );
    556608        $( wp.media.editor.init );
    557609}(jQuery));
  • wp-includes/js/media-models.js

     
    3030                        frame = new MediaFrame.Post( attributes );
    3131
    3232                delete attributes.frame;
    33                 // Set the default state.
    34                 frame.setState( frame.options.state );
    35                 // Render, attach, and open the frame.
    36                 return frame.render().attach().open();
     33
     34                return frame;
    3735        };
    3836
    3937        _.extend( media, { model: {}, view: {}, controller: {} });
     
    235233
    236234                        // Overload the `update` request so properties can be saved.
    237235                        } else if ( 'update' === method ) {
     236                                if ( ! this.get('nonces') )
     237                                        return $.Deferred().resolveWith( this ).promise();
     238
    238239                                options = options || {};
    239240                                options.context = this;
    240241
  • wp-includes/js/media-views.js

     
    169169                        // created the `states` collection, or are trying to select a state
    170170                        // that does not exist.
    171171                        if ( ( previous && id === previous.id ) || ! this.states || ! this.states.get( id ) )
    172                                 return;
     172                                return this;
    173173
    174174                        if ( previous ) {
    175175                                previous.trigger('deactivate');
     
    178178
    179179                        this._state = id;
    180180                        this.state().trigger('activate');
     181
     182                        return this;
    181183                },
    182184
    183185                // Returns the previous active state.
     
    10751077                        if ( this.options.modal ) {
    10761078                                this.modal = new media.view.Modal({
    10771079                                        controller: this,
    1078                                         $content:   this.$el,
    10791080                                        title:      this.options.title
    10801081                                });
     1082
     1083                                this.modal.content( this );
    10811084                        }
    10821085
    10831086                        // Force the uploader off if the upload limit has been exceeded or
     
    11001103                        this.on( 'attach', _.bind( this.views.ready, this.views ), this );
    11011104                },
    11021105
    1103                 render: function() {
    1104                         if ( this.modal )
    1105                                 this.modal.render();
    1106 
    1107                         media.view.Frame.prototype.render.apply( this, arguments );
    1108                         return this;
    1109                 },
    1110 
    11111106                createIframeStates: function( options ) {
    11121107                        var settings = media.view.settings,
    11131108                                tabs = settings.tabs,
     
    12001195                        media.view.MediaFrame.prototype.initialize.apply( this, arguments );
    12011196
    12021197                        _.defaults( this.options, {
    1203                                 state:     'upload',
    12041198                                selection: [],
    12051199                                library:   {},
    12061200                                multiple:  false
     
    13471341        media.view.MediaFrame.Post = media.view.MediaFrame.Select.extend({
    13481342                initialize: function() {
    13491343                        _.defaults( this.options, {
    1350                                 state:     'upload',
    13511344                                multiple:  true,
    13521345                                editing:   false
    13531346                        });
     
    14071400                                        libraryState: 'gallery-edit'
    14081401                                })
    14091402                        ]);
     1403
     1404
     1405                        if ( media.view.settings.featuredImage ) {
     1406                                this.states.add( new media.controller.Library({
     1407                                        id:         'featured-image',
     1408                                        library:    media.query({ type: 'image' }),
     1409                                        filterable: 'uploaded',
     1410                                        multiple:   false,
     1411                                        menu:       'main',
     1412                                        toolbar:    'featured-image'
     1413                                }) );
     1414                        }
    14101415                },
    14111416
    14121417                bindHandlers: function() {
     
    14251430                                        toolbar: {
    14261431                                                'main-attachments': 'mainAttachmentsToolbar',
    14271432                                                'main-embed':       'mainEmbedToolbar',
     1433                                                'featured-image':   'featuredImageToolbar',
    14281434                                                'gallery-edit':     'galleryEditToolbar',
    14291435                                                'gallery-add':      'galleryAddToolbar'
    14301436                                        }
     
    14421448                        media.view.MediaFrame.Select.prototype.mainMenu.call( this, { silent: true });
    14431449
    14441450                        this.menu.view().set({
    1445                                 separateLibrary: new media.View({
     1451                                'library-separator': new media.View({
    14461452                                        className: 'separator',
    14471453                                        priority: 60
    14481454                                }),
    1449                                 embed: {
     1455                                'embed': {
    14501456                                        text: l10n.fromUrlTitle,
    14511457                                        priority: 80
    14521458                                }
    14531459                        });
     1460
     1461                        if ( media.view.settings.featuredImage ) {
     1462                                this.menu.view().set( 'featured-image', {
     1463                                        text: l10n.featuredImageTitle,
     1464                                        priority: 100
     1465                                });
     1466                        }
    14541467                },
    14551468
    14561469                galleryMenu: function() {
     
    15571570                        }) );
    15581571                },
    15591572
     1573                featuredImageToolbar: function() {
     1574                        this.toolbar.view( new media.view.Toolbar.Select({
     1575                                controller: this,
     1576                                text:       l10n.setFeaturedImage
     1577                        }) );
     1578                },
     1579
    15601580                mainEmbedToolbar: function() {
    15611581                        this.toolbar.view( new media.view.Toolbar.Embed({
    15621582                                controller: this
     
    16411661                        });
    16421662                },
    16431663
    1644                 render: function() {
    1645                         // Ensure content div exists.
    1646                         this.options.$content = this.options.$content || $('<div />');
    1647 
    1648                         // Detach the content element from the DOM to prevent
    1649                         // `this.$el.html()` from garbage collecting its events.
    1650                         this.options.$content.detach();
    1651 
    1652                         this.$el.html( this.template({
     1664                prepare: function() {
     1665                        return {
    16531666                                title: this.options.title
    1654                         }) );
    1655 
    1656                         this.options.$content.addClass('media-modal-content');
    1657                         this.$('.media-modal').append( this.options.$content );
    1658                         return this;
     1667                        };
    16591668                },
    16601669
    16611670                attach: function() {
     1671                        if ( this.views.attached )
     1672                                return;
     1673
     1674                        if ( ! this.views.rendered )
     1675                                this.render();
     1676
    16621677                        this.$el.appendTo( this.options.container );
     1678
     1679                        // Manually mark the view as attached and trigger ready.
     1680                        this.views.attached = true;
     1681                        this.views.ready();
     1682
    16631683                        return this.propagate('attach');
    16641684                },
    16651685
    16661686                detach: function() {
     1687                        if ( this.$el.is(':visible') )
     1688                                this.close();
     1689
    16671690                        this.$el.detach();
     1691                        this.views.attached = false;
    16681692                        return this.propagate('detach');
    16691693                },
    16701694
    16711695                open: function() {
     1696                        if ( this.$el.is(':visible') )
     1697                                return;
     1698
     1699                        if ( ! this.views.attached )
     1700                                this.attach();
     1701
    16721702                        this.$el.show().focus();
    16731703                        return this.propagate('open');
    16741704                },
    16751705
    16761706                close: function() {
     1707                        if ( ! this.views.attached || ! this.$el.is(':visible') )
     1708                                return;
     1709
    16771710                        this.$el.hide();
    16781711                        return this.propagate('close');
    16791712                },
     
    16831716                        this.close();
    16841717                },
    16851718
    1686                 content: function( $content ) {
    1687                         // Detach any existing content to prevent events from being lost.
    1688                         if ( this.options.$content )
    1689                                 this.options.$content.detach();
    1690 
    1691                         // Set and render the content.
    1692                         this.options.$content = ( $content instanceof Backbone.View ) ? $content.$el : $content;
    1693                         return this.render();
     1719                content: function( content ) {
     1720                        this.views.set( '.media-modal-content', content );
     1721                        return this;
    16941722                },
    16951723
    16961724                // Triggers a modal event and if the `propagate` option is set,
  • wp-includes/media.php

     
    14331433        if ( isset( $args['post'] ) ) {
    14341434                $post = get_post( $args['post'] );
    14351435                $settings['postId'] = $post->ID;
     1436
     1437                if ( current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' ) ) {
     1438
     1439                        $featuredImageId = get_post_meta( $post->ID, '_thumbnail_id', true );
     1440
     1441                        $settings['featuredImage'] = array(
     1442                                'id'    => $featuredImageId ? $featuredImageId : -1,
     1443                                'nonce' => wp_create_nonce( 'set_post_thumbnail-' . $post->ID ),
     1444                        );
     1445                }
    14361446        }
    14371447
    14381448        $hier = $post && is_post_type_hierarchical( $post->post_type );
     
    14661476                // From URL
    14671477                'fromUrlTitle'       => __( 'From URL' ),
    14681478
     1479                // Featured Images
     1480                'featuredImageTitle'  => __( 'Featured Image' ),
     1481                'setFeaturedImage'    => __( 'Set featured image' ),
     1482
    14691483                // Gallery
    14701484                'createGalleryTitle' => __( 'Create Gallery' ),
    14711485                'editGalleryTitle'   => __( 'Edit Gallery' ),
     
    15081522                <div class="media-modal wp-core-ui">
    15091523                        <h3 class="media-modal-title">{{ data.title }}</h3>
    15101524                        <a class="media-modal-close media-modal-icon" href="#" title="<?php esc_attr_e('Close'); ?>"></a>
     1525                        <div class="media-modal-content"></div>
    15111526                </div>
    15121527                <div class="media-modal-backdrop">
    15131528                        <div></div>