Make WordPress Core

Changeset 30309


Ignore:
Timestamp:
11/11/2014 11:51:48 PM (10 years ago)
Author:
ocean90
Message:

Customizer: Add support for the media library in Background Image controls.

WP_Customize_Upload_Control (PHP) and api.UploadControl (JS) can now open the media modal.

props celloexpressions, and ericlewis for docs.
see #21483.

Location:
trunk/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/customize-controls.css

    r29955 r30309  
    99#customize-controls h3 {
    1010    font-size: 14px;
     11}
     12
     13#customize-controls img {
     14    max-width: 100%;
    1115}
    1216
     
    413417.customize-control-radio input {
    414418    margin-right: 5px;
     419}
     420
     421.customize-control .attachment-thumb.type-icon {
     422    float: left;
     423    margin-right: 12px;
     424}
     425
     426.customize-control .attachment-title {
     427    font-weight: bold;
     428    margin: 0 0 12px 0;
     429}
     430
     431.customize-control .remove-button {
     432    margin-left: 8px;
     433    vertical-align: middle;
     434}
     435
     436.customize-control .thumbnail-audio .attachment-title,
     437.customize-control .thumbnail.thumbnail-audio,
     438.customize-control .thumbnail.thumbnail-video,
     439.customize-control .thumbnail.thumbnail-image {
     440    margin-bottom: 8px;
     441}
     442
     443.customize-control .placeholder-text {
     444    font-size: 18px;
     445    font-weight: 300;
     446    text-align: center;
     447    color: #aaa;
     448    cursor: default;
     449}
     450
     451.customize-control .thumbnail-image img {
     452    cursor: pointer;
    415453}
    416454
  • trunk/src/wp-admin/js/customize-controls.js

    r30307 r30309  
    66
    77    /**
    8      * @constructor
     8     * @class
    99     * @augments wp.customize.Value
    1010     * @augments wp.customize.Class
     
    128128     * Base class for Panel and Section
    129129     *
    130      * @constructor
     130     * @class
    131131     * @augments wp.customize.Class
    132132     */
     
    317317
    318318    /**
    319      * @constructor
     319     * @class
    320320     * @augments wp.customize.Class
    321321     */
     
    472472
    473473    /**
    474      * @constructor
     474     * @class
    475475     * @augments wp.customize.Class
    476476     */
     
    641641
    642642    /**
    643      * @constructor
     643     * A Customizer Control.
     644     *
     645     * A control provides a UI element that allows a user to modify a Customizer Setting.
     646     *
     647     * @see PHP class WP_Customize_Control.
     648     *
     649     * @class
    644650     * @augments wp.customize.Class
     651     *
     652     * @param {string} id                            Unique identifier for the control instance.
     653     * @param {object} options                       Options hash for the control instance.
     654     * @param {object} options.params
     655     * @param {object} options.params.type           Type of control (e.g. text, radio, dropdown-pages, etc.)
     656     * @param {string} options.params.content        The HTML content for the control.
     657     * @param {string} options.params.priority       Order of priority to show the control within the section.
     658     * @param {string} options.params.active
     659     * @param {string} options.params.section
     660     * @param {string} options.params.label
     661     * @param {string} options.params.description
     662     * @param {string} options.params.instanceNumber Order in which this instance was created in relation to other instances.
    645663     */
    646664    api.Control = api.Class.extend({
     
    653671            control.params = {};
    654672            $.extend( control, options || {} );
    655 
    656673            control.id = id;
    657674            control.selector = '#customize-control-' + id.replace( /\]/g, '' ).replace( /\[/g, '-' );
     
    729746
    730747        /**
    731          *
     748         * Embed the control into the page.
    732749         */
    733750        embed: function () {
     
    759776
    760777        /**
     778         * Triggered when the control's markup has been injected into the DOM.
     779         *
    761780         * @abstract
    762781         */
     
    866885                control = this;
    867886
     887            // Replace the container element's content with the control.
    868888            if ( 0 !== $( '#tmpl-' + control.templateSelector ).length ) {
    869889                template = wp.template( control.templateSelector );
    870890                if ( template && control.container ) {
    871                     control.container.append( template( control.params ) );
     891                    control.container.html( template( control.params ) );
    872892                }
    873893            }
     
    876896
    877897    /**
    878      * @constructor
     898     * A colorpicker control.
     899     *
     900     * @class
    879901     * @augments wp.customize.Control
    880902     * @augments wp.customize.Class
     
    902924
    903925    /**
    904      * @constructor
     926     * An upload control, which utilizes the media modal.
     927     *
     928     * @class
    905929     * @augments wp.customize.Control
    906930     * @augments wp.customize.Class
    907931     */
    908932    api.UploadControl = api.Control.extend({
    909         ready: function() {
     933
     934        /**
     935         * When the control's DOM structure is ready,
     936         * set up internal event bindings.
     937         */
     938        ready: function() {
    910939            var control = this;
    911 
    912             this.params.removed = this.params.removed || '';
    913 
    914             this.success = $.proxy( this.success, this );
    915 
    916             this.uploader = $.extend({
    917                 container: this.container,
    918                 browser:   this.container.find('.upload'),
    919                 dropzone:  this.container.find('.upload-dropzone'),
    920                 success:   this.success,
    921                 plupload:  {},
    922                 params:    {}
    923             }, this.uploader || {} );
    924 
    925             if ( control.params.extensions ) {
    926                 control.uploader.plupload.filters = [{
    927                     title:      api.l10n.allowedFiles,
    928                     extensions: control.params.extensions
    929                 }];
    930             }
    931 
    932             if ( control.params.context )
    933                 control.uploader.params['post_data[context]'] = this.params.context;
    934 
    935             if ( api.settings.theme.stylesheet )
    936                 control.uploader.params['post_data[theme]'] = api.settings.theme.stylesheet;
    937 
    938             this.uploader = new wp.Uploader( this.uploader );
    939 
    940             this.remover = this.container.find('.remove');
    941             this.remover.on( 'click keydown', function( event ) {
    942                 if ( isKeydownButNotEnterEvent( event ) ) {
    943                     return;
    944                 }
    945 
    946                 control.setting.set( control.params.removed );
    947                 event.preventDefault();
    948             });
    949 
    950             this.removerVisibility = $.proxy( this.removerVisibility, this );
    951             this.setting.bind( this.removerVisibility );
    952             this.removerVisibility( this.setting.get() );
    953         },
    954         success: function( attachment ) {
    955             this.setting.set( attachment.get('url') );
    956         },
    957         removerVisibility: function( to ) {
    958             this.remover.toggle( to != this.params.removed );
    959         }
    960     });
     940            // Shortcut so that we don't have to use _.bind every time we add a callback.
     941            _.bindAll( control, 'restoreDefault', 'removeFile', 'openFrame', 'select' );
     942
     943            // Bind events, with delegation to facilitate re-rendering.
     944            control.container.on( 'click keydown', '.upload-button', control.openFrame );
     945            control.container.on( 'click keydown', '.thumbnail-image img', control.openFrame );
     946            control.container.on( 'click keydown', '.default-button', control.restoreDefault );
     947            control.container.on( 'click keydown', '.remove-button', control.removeFile );
     948
     949            // Re-render whenever the control's setting changes.
     950            control.setting.bind( function () { control.renderContent(); } );
     951        },
     952
     953        /**
     954         * Open the media modal.
     955         */
     956        openFrame: function( event ) {
     957            if ( event.type === 'keydown' &&  13 !== event.which ) { // enter
     958                return;
     959            }
     960
     961            event.preventDefault();
     962
     963            if ( ! this.frame ) {
     964                this.initFrame();
     965            }
     966
     967            this.frame.open();
     968        },
     969
     970        /**
     971         * Create a media modal select frame, and store it so the instance can be reused when needed.
     972         */
     973        initFrame: function() {
     974            this.frame = wp.media({
     975                // The title of the media modal.
     976                title: this.params.button_labels.frame_title,
     977
     978                // Restrict the library to specified mime type.
     979                library: {
     980                    type: this.params.mime_type
     981                },
     982                button: {
     983                    // Change the submit button label.
     984                    text: this.params.button_labels.frame_button
     985                },
     986                multiple: false
     987            });
     988
     989            // When a file is selected, run a callback.
     990            this.frame.on( 'select', this.select );
     991        },
     992
     993        /**
     994         * Callback handler for when an attachment is selected in the media modal.
     995         * Gets the selected image information, and sets it within the control.
     996         */
     997        select: function() {
     998            // Get the attachment from the modal frame.
     999            var attachment = this.frame.state().get( 'selection' ).first().toJSON();
     1000
     1001            this.params.attachment = attachment;
     1002
     1003            // Set the Customizer setting; the callback takes care of rendering.
     1004            this.setting( attachment.url );
     1005        },
     1006
     1007        /**
     1008         * Reset the setting to the default value.
     1009         */
     1010        restoreDefault: function( event ) {
     1011            if ( event.type === 'keydown' &&  13 !== event.which ) { // enter
     1012                return;
     1013            }
     1014            event.preventDefault();
     1015
     1016            this.params.attachment = this.params.defaultAttachment;
     1017            this.setting( this.params.defaultAttachment.url );
     1018        },
     1019
     1020        /**
     1021         * Called when the "Remove" link is clicked. Empties the setting.
     1022         *
     1023         * @param {object} event jQuery Event object
     1024         */
     1025        removeFile: function( event ) {
     1026            if ( event.type === 'keydown' &&  13 !== event.which ) { // enter
     1027                return;
     1028            }
     1029            event.preventDefault();
     1030
     1031            this.params.attachment = {};
     1032            this.setting( '' );
     1033            this.renderContent(); // Not bound to setting change when emptying.
     1034        },
     1035
     1036        // @deprecated
     1037        success: function() {},
     1038
     1039        // @deprecated
     1040        removerVisibility: function() {}
     1041    });
    9611042
    9621043    /**
    963      * @constructor
     1044     * A control for uploading images.
     1045     *
     1046     * This control no longer needs to do anything more
     1047     * than what the upload control does in JS.
     1048     *
     1049     * @class
    9641050     * @augments wp.customize.UploadControl
    9651051     * @augments wp.customize.Control
     
    9671053     */
    9681054    api.ImageControl = api.UploadControl.extend({
    969         ready: function() {
    970             var control = this,
    971                 panels;
    972 
    973             this.uploader = {
    974                 init: function() {
    975                     var fallback, button;
    976 
    977                     if ( this.supports.dragdrop )
    978                         return;
    979 
    980                     // Maintain references while wrapping the fallback button.
    981                     fallback = control.container.find( '.upload-fallback' );
    982                     button   = fallback.children().detach();
    983 
    984                     this.browser.detach().empty().append( button );
    985                     fallback.append( this.browser ).show();
    986                 }
    987             };
    988 
    989             api.UploadControl.prototype.ready.call( this );
    990 
    991             this.thumbnail    = this.container.find('.preview-thumbnail img');
    992             this.thumbnailSrc = $.proxy( this.thumbnailSrc, this );
    993             this.setting.bind( this.thumbnailSrc );
    994 
    995             this.library = this.container.find('.library');
    996 
    997             // Generate tab objects
    998             this.tabs = {};
    999             panels    = this.library.find('.library-content');
    1000 
    1001             this.library.children('ul').children('li').each( function() {
    1002                 var link  = $(this),
    1003                     id    = link.data('customizeTab'),
    1004                     panel = panels.filter('[data-customize-tab="' + id + '"]');
    1005 
    1006                 control.tabs[ id ] = {
    1007                     both:  link.add( panel ),
    1008                     link:  link,
    1009                     panel: panel
    1010                 };
    1011             });
    1012 
    1013             // Bind tab switch events
    1014             this.library.children('ul').on( 'click keydown', 'li', function( event ) {
    1015                 if ( isKeydownButNotEnterEvent( event ) ) {
    1016                     return;
    1017                 }
    1018 
    1019                 var id  = $(this).data('customizeTab'),
    1020                     tab = control.tabs[ id ];
    1021 
    1022                 event.preventDefault();
    1023 
    1024                 if ( tab.link.hasClass('library-selected') )
    1025                     return;
    1026 
    1027                 control.selected.both.removeClass('library-selected');
    1028                 control.selected = tab;
    1029                 control.selected.both.addClass('library-selected');
    1030             });
    1031 
    1032             // Bind events to switch image urls.
    1033             this.library.on( 'click keydown', 'a', function( event ) {
    1034                 if ( isKeydownButNotEnterEvent( event ) ) {
    1035                     return;
    1036                 }
    1037 
    1038                 var value = $(this).data('customizeImageValue');
    1039 
    1040                 if ( value ) {
    1041                     control.setting.set( value );
    1042                     event.preventDefault();
    1043                 }
    1044             });
    1045 
    1046             if ( this.tabs.uploaded ) {
    1047                 this.tabs.uploaded.target = this.library.find('.uploaded-target');
    1048                 if ( ! this.tabs.uploaded.panel.find('.thumbnail').length )
    1049                     this.tabs.uploaded.both.addClass('hidden');
    1050             }
    1051 
    1052             // Select a tab
    1053             panels.each( function() {
    1054                 var tab = control.tabs[ $(this).data('customizeTab') ];
    1055 
    1056                 // Select the first visible tab.
    1057                 if ( ! tab.link.hasClass('hidden') ) {
    1058                     control.selected = tab;
    1059                     tab.both.addClass('library-selected');
    1060                     return false;
    1061                 }
    1062             });
    1063 
    1064             this.dropdownInit();
    1065         },
    1066         success: function( attachment ) {
    1067             api.UploadControl.prototype.success.call( this, attachment );
    1068 
    1069             // Add the uploaded image to the uploaded tab.
    1070             if ( this.tabs.uploaded && this.tabs.uploaded.target.length ) {
    1071                 this.tabs.uploaded.both.removeClass('hidden');
    1072 
    1073                 // @todo: Do NOT store this on the attachment model. That is bad.
    1074                 attachment.element = $( '<a href="#" class="thumbnail"></a>' )
    1075                     .data( 'customizeImageValue', attachment.get('url') )
    1076                     .append( '<img src="' +  attachment.get('url')+ '" />' )
    1077                     .appendTo( this.tabs.uploaded.target );
    1078             }
    1079         },
    1080         thumbnailSrc: function( to ) {
    1081             if ( /^(https?:)?\/\//.test( to ) )
    1082                 this.thumbnail.prop( 'src', to ).show();
    1083             else
    1084                 this.thumbnail.hide();
    1085         }
     1055        // @deprecated
     1056        thumbnailSrc: function() {}
    10861057    });
    10871058
    10881059    /**
    1089      * @constructor
     1060     * @class
    10901061     * @augments wp.customize.Control
    10911062     * @augments wp.customize.Class
     
    12341205        },
    12351206
     1207        /**
     1208         * After an image is selected in the media modal,
     1209         * switch to the cropper state.
     1210         */
    12361211        onSelect: function() {
    12371212            this.frame.setState('cropper');
    12381213        },
     1214
     1215        /**
     1216         * After the image has been cropped, apply the cropped image data to the setting.
     1217         *
     1218         * @param {object} croppedImage Cropped attachment data.
     1219         */
    12391220        onCropped: function(croppedImage) {
    12401221            var url = croppedImage.post_content,
     
    12441225            this.setImageFromURL(url, attachmentId, w, h);
    12451226        },
     1227
     1228        /**
     1229         * If cropping was skipped, apply the image data directly to the setting.
     1230         *
     1231         * @param {object} selection
     1232         */
    12461233        onSkippedCrop: function(selection) {
    12471234            var url = selection.get('url'),
     
    13101297
    13111298    /**
    1312      * @constructor
     1299     * @class
    13131300     * @augments wp.customize.Messenger
    13141301     * @augments wp.customize.Class
     
    15241511
    15251512    /**
    1526      * @constructor
     1513     * @class
    15271514     * @augments wp.customize.Messenger
    15281515     * @augments wp.customize.Class
  • trunk/src/wp-includes/class-wp-customize-control.php

    r30214 r30309  
    638638 */
    639639class WP_Customize_Upload_Control extends WP_Customize_Control {
    640     public $type    = 'upload';
    641     public $removed = '';
    642     public $context;
    643     public $extensions = array();
     640    public $type          = 'upload';
     641    public $mime_type     = '';
     642    public $button_labels = array();
     643    public $removed = ''; // unused
     644    public $context; // unused
     645    public $extensions = array(); // unused
     646
     647    /**
     648     * Constructor.
     649     *
     650     * @since 4.1.0
     651     * @uses WP_Customize_Control::__construct()
     652     *
     653     * @param WP_Customize_Manager $manager
     654     */
     655    public function __construct( $manager, $id, $args = array() ) {
     656        parent::__construct( $manager, $id, $args );
     657
     658        $this->button_labels = array(
     659            'select'       => __( 'Select File' ),
     660            'change'       => __( 'Change File' ),
     661            'default'      => __( 'Default' ),
     662            'remove'       => __( 'Remove' ),
     663            'placeholder'  => __( 'No file selected' ),
     664            'frame_title'  => __( 'Select File' ),
     665            'frame_button' => __( 'Choose File' ),
     666        );
     667    }
    644668
    645669    /**
     
    649673     */
    650674    public function enqueue() {
    651         wp_enqueue_script( 'wp-plupload' );
     675        wp_enqueue_media();
    652676    }
    653677
     
    660684    public function to_json() {
    661685        parent::to_json();
    662 
    663         $this->json['removed'] = $this->removed;
    664 
    665         if ( $this->context )
    666             $this->json['context'] = $this->context;
    667 
    668         if ( $this->extensions )
    669             $this->json['extensions'] = implode( ',', $this->extensions );
    670     }
    671 
    672     /**
    673      * Render the control's content.
    674      *
    675      * @since 3.4.0
    676      */
    677     public function render_content() {
     686        $this->json['mime_type'] = $this->mime_type;
     687        $this->json['button_labels'] = $this->button_labels;
     688
     689        if ( is_object( $this->setting ) ) {
     690            if ( $this->setting->default ) {
     691                // Fake an attachment model - needs all fields used by template.
     692                $type = in_array( substr( $this->setting->default, -3 ), array( 'jpg', 'png', 'gif', 'bmp' ) ) ? 'image' : 'document';
     693                $default_attachment = array(
     694                    'id' => 1,
     695                    'url' => $this->setting->default,
     696                    'type' => $type,
     697                    'sizes' => array(
     698                        'full' => array( 'url' => $this->setting->default ),
     699                    ),
     700                    'icon' => wp_mime_type_icon( $type ),
     701                    'title' => basename( $this->setting->default ),
     702                );
     703                $this->json['defaultAttachment'] = $default_attachment;
     704            }
     705
     706            // Get the attachment model for the existing file.
     707            if ( $this->value() ) {
     708                $attachment_id = attachment_url_to_postid( $this->value() );
     709                if ( $attachment_id ) {
     710                    $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id);
     711                }
     712            } else if ( $this->setting->default ) {
     713                // Set the default as the attachment.
     714                $this->json['attachment'] = $default_attachment;
     715            }
     716        }
     717    }
     718
     719    /**
     720     * Don't render any content for this control from PHP.
     721     *
     722     * @see WP_Customize_Upload_Control::content_template()
     723     * @since 3.4.0
     724     */
     725    public function render_content() {}
     726
     727    /**
     728     * Render a JS template for the content of the upload control.
     729     *
     730     * @since 4.1.0
     731     */
     732    public function content_template() {
    678733        ?>
    679         <label>
    680             <?php if ( ! empty( $this->label ) ) : ?>
    681                 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
    682             <?php endif;
    683             if ( ! empty( $this->description ) ) : ?>
    684                 <span class="description customize-control-description"><?php echo $this->description; ?></span>
    685             <?php endif; ?>
    686             <div>
    687                 <a href="#" class="button-secondary upload"><?php _e( 'Upload' ); ?></a>
    688                 <a href="#" class="remove"><?php _e( 'Remove' ); ?></a>
     734        <label for="{{ data.settings.default }}-button">
     735            <# if ( data.label ) { #>
     736                <span class="customize-control-title">{{ data.label }}</span>
     737            <# } #>
     738            <# if ( data.description ) { #>
     739                <span class="description customize-control-description">{{ data.description }}</span>
     740            <# } #>
     741        </label>
     742
     743        <# // Ensure that the default attachment is used if it exists.
     744        if ( _.isEmpty( data.attachment ) && data.defaultAttachment ) {
     745            data.attachment = data.defaultAttachment;
     746        }
     747
     748        if ( data.attachment && data.attachment.id ) { #>
     749            <div class="attachment-media-view {{ data.attachment.orientation }}">
     750                <div class="thumbnail thumbnail-{{ data.attachment.type }}">
     751                    <# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #>
     752                        <img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" />
     753                    <# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #>
     754                        <img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" />
     755                    <# } else if ( -1 === jQuery.inArray( data.attachment.type, [ 'audio', 'video' ] ) ) { #>
     756                        <img class="attachment-thumb type-icon" src="{{ data.attachment.icon }}" class="icon" draggable="false" />
     757                        <p class="attachment-title">{{ data.attachment.title }}</p>
     758                    <# } #>
     759
     760                    <# if ( 'audio' === data.attachment.type ) { #>
     761                    <div class="wp-media-wrapper">
     762                        <p class="attachment-title">{{ data.attachment.title }}</p>
     763                        <audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none">
     764                            <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/>
     765                        </audio>
     766                    </div>
     767                    <# } else if ( 'video' === data.attachment.type ) {
     768                        var w_rule = h_rule = '';
     769                        if ( data.attachment.width ) {
     770                            w_rule = 'width: ' + data.attachment.width + 'px;';
     771                        } else if ( wp.media.view.settings.contentWidth ) {
     772                            w_rule = 'width: ' + wp.media.view.settings.contentWidth + 'px;';
     773                        }
     774                        if ( data.attachment.height ) {
     775                            h_rule = 'height: ' + data.attachment.height + 'px;';
     776                        }
     777                        #>
     778                        <div style="{{ w_rule }}{{ h_rule }}" class="wp-media-wrapper wp-video">
     779                            <video controls="controls" class="wp-video-shortcode" preload="metadata"
     780                                <# if ( data.attachment.width ) { #>width="{{ data.attachment.width }}"<# } #>
     781                                <# if ( data.attachment.height ) { #>height="{{ data.attachment.height }}"<# } #>
     782                                <# if ( data.attachment.image && data.attachment.image.src !== data.attachment.icon ) { #>poster="{{ data.attachment.image.src }}"<# } #>>
     783                                <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/>
     784                            </video>
     785                        </div>
     786                    <# } #>
     787                </div>
    689788            </div>
    690         </label>
     789            <a class="button upload-button" id="{{ data.settings.default }}-button" href="#"><?php echo $this->button_labels['change']; ?></a>
     790            <# if ( data.defaultAttachment && data.defaultAttachment.id !== data.attachment.id ) { #>
     791                <a class="default-button remove-button" href="#"><?php echo $this->button_labels['default']; ?></a>
     792            <# } else { #>
     793                <a class="remove-button" href="#"><?php echo $this->button_labels['remove']; ?></a>
     794            <# } #>
     795        <# } else { #>
     796            <p class="placeholder-text"><?php echo $this->button_labels['placeholder']; ?></p>
     797            <a class="button upload-button" id="{{ data.settings.default }}-button" href="#"><?php echo $this->button_labels['select']; ?></a>
     798            <# if ( ! data.defaultAttachment ) { #>
     799                <a class="default-button remove-button" href="#"><?php echo $this->button_labels['default']; ?></a>
     800            <# } #>
     801        <# } #>
    691802        <?php
    692803    }
     
    702813class WP_Customize_Image_Control extends WP_Customize_Upload_Control {
    703814    public $type = 'image';
    704     public $get_url;
    705     public $statuses;
    706     public $extensions = array( 'jpg', 'jpeg', 'gif', 'png' );
    707 
    708     protected $tabs = array();
     815    public $mime_type = 'image';
    709816
    710817    /**
     
    715822     *
    716823     * @param WP_Customize_Manager $manager
    717      * @param string $id
    718      * @param array $args
    719      */
    720     public function __construct( $manager, $id, $args ) {
    721         $this->statuses = array( '' => __('No Image') );
    722 
     824     */
     825    public function __construct( $manager, $id, $args = array() ) {
    723826        parent::__construct( $manager, $id, $args );
    724827
    725         $this->add_tab( 'upload-new', __('Upload New'), array( $this, 'tab_upload_new' ) );
    726         $this->add_tab( 'uploaded',   __('Uploaded'),   array( $this, 'tab_uploaded' ) );
    727 
    728         // Early priority to occur before $this->manager->prepare_controls();
    729         add_action( 'customize_controls_init', array( $this, 'prepare_control' ), 5 );
    730     }
    731 
    732     /**
    733      * Prepares the control.
    734      *
    735      * If no tabs exist, removes the control from the manager.
    736      *
     828        $this->button_labels = array(
     829            'select'       => __( 'Select Image' ),
     830            'change'       => __( 'Change Image' ),
     831            'remove'       => __( 'Remove' ),
     832            'default'      => __( 'Default' ),
     833            'placeholder'  => __( 'No image selected' ),
     834            'frame_title'  => __( 'Select Image' ),
     835            'frame_button' => __( 'Choose Image' ),
     836        );
     837    }
     838
     839    /**
    737840     * @since 3.4.2
    738      */
    739     public function prepare_control() {
    740         if ( ! $this->tabs )
    741             $this->manager->remove_control( $this->id );
    742     }
    743 
    744     /**
    745      * Refresh the parameters passed to the JavaScript via JSON.
    746      *
    747      * @since 3.4.0
    748      * @uses WP_Customize_Upload_Control::to_json()
    749      */
    750     public function to_json() {
    751         parent::to_json();
    752         $this->json['statuses'] = $this->statuses;
    753     }
    754 
    755     /**
    756      * Render the control's content.
    757      *
    758      * @since 3.4.0
    759      */
    760     public function render_content() {
    761         $src = $this->value();
    762         if ( isset( $this->get_url ) )
    763             $src = call_user_func( $this->get_url, $src );
    764 
    765         ?>
    766         <div class="customize-image-picker">
    767             <?php if ( ! empty( $this->label ) ) : ?>
    768                 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
    769             <?php endif;
    770             if ( ! empty( $this->description ) ) : ?>
    771                 <span class="description customize-control-description"><?php echo $this->description; ?></span>
    772             <?php endif; ?>
    773 
    774             <div class="customize-control-content">
    775                 <div class="dropdown preview-thumbnail" tabindex="0">
    776                     <div class="dropdown-content">
    777                         <?php if ( empty( $src ) ): ?>
    778                             <img style="display:none;" />
    779                         <?php else: ?>
    780                             <img src="<?php echo esc_url( set_url_scheme( $src ) ); ?>" />
    781                         <?php endif; ?>
    782                         <div class="dropdown-status"></div>
    783                     </div>
    784                     <div class="dropdown-arrow"></div>
    785                 </div>
    786             </div>
    787 
    788             <div class="library">
    789                 <ul>
    790                     <?php foreach ( $this->tabs as $id => $tab ): ?>
    791                         <li data-customize-tab='<?php echo esc_attr( $id ); ?>' tabindex='0'>
    792                             <?php echo esc_html( $tab['label'] ); ?>
    793                         </li>
    794                     <?php endforeach; ?>
    795                 </ul>
    796                 <?php foreach ( $this->tabs as $id => $tab ): ?>
    797                     <div class="library-content" data-customize-tab='<?php echo esc_attr( $id ); ?>'>
    798                         <?php call_user_func( $tab['callback'] ); ?>
    799                     </div>
    800                 <?php endforeach; ?>
    801             </div>
    802 
    803             <div class="actions">
    804                 <a href="#" class="remove"><?php _e( 'Remove Image' ); ?></a>
    805             </div>
    806         </div>
    807         <?php
    808     }
    809 
    810     /**
    811      * Add a tab to the control.
    812      *
    813      * @since 3.4.0
     841     * @deprecated 4.1.0
     842     */
     843    public function prepare_control() {}
     844
     845    /**
     846     * @since 3.4.0
     847     * @deprecated 4.1.0
    814848     *
    815849     * @param string $id
     
    817851     * @param mixed $callback
    818852     */
    819     public function add_tab( $id, $label, $callback ) {
    820         $this->tabs[ $id ] = array(
    821             'label'    => $label,
    822             'callback' => $callback,
    823         );
    824     }
    825 
    826     /**
    827      * Remove a tab from the control.
    828      *
    829      * @since 3.4.0
     853    public function add_tab( $id, $label, $callback ) {}
     854
     855    /**
     856     * @since 3.4.0
     857     * @deprecated 4.1.0
    830858     *
    831859     * @param string $id
    832860     */
    833     public function remove_tab( $id ) {
    834         unset( $this->tabs[ $id ] );
    835     }
    836 
    837     /**
    838      * @since 3.4.0
    839      */
    840     public function tab_upload_new() {
    841         if ( ! _device_can_upload() ) {
    842             echo '<p>' . sprintf( __('The web browser on your device cannot be used to upload files. You may be able to use the <a href="%s">native app for your device</a> instead.'), 'https://apps.wordpress.org/' ) . '</p>';
    843         } else {
    844             ?>
    845             <div class="upload-dropzone">
    846                 <?php _e('Drop a file here or <a href="#" class="upload">select a file</a>.'); ?>
    847             </div>
    848             <div class="upload-fallback">
    849                 <span class="button-secondary"><?php _e('Select File'); ?></span>
    850             </div>
    851             <?php
    852         }
    853     }
    854 
    855     /**
    856      * @since 3.4.0
    857      */
    858     public function tab_uploaded() {
    859         ?>
    860         <div class="uploaded-target"></div>
    861         <?php
    862     }
    863 
    864     /**
    865      * @since 3.4.0
     861    public function remove_tab( $id ) {}
     862
     863    /**
     864     * @since 3.4.0
     865     * @deprecated 4.1.0
    866866     *
    867867     * @param string $url
    868868     * @param string $thumbnail_url
    869869     */
    870     public function print_tab_image( $url, $thumbnail_url = null ) {
    871         $url = set_url_scheme( $url );
    872         $thumbnail_url = ( $thumbnail_url ) ? set_url_scheme( $thumbnail_url ) : $url;
    873         ?>
    874         <a href="#" class="thumbnail" data-customize-image-value="<?php echo esc_url( $url ); ?>">
    875             <img src="<?php echo esc_url( $thumbnail_url ); ?>" />
    876         </a>
    877         <?php
    878     }
     870    public function print_tab_image( $url, $thumbnail_url = null ) {}
    879871}
    880872
     
    900892            'label'    => __( 'Background Image' ),
    901893            'section'  => 'background_image',
    902             'context'  => 'custom-background',
    903             'get_url'  => 'get_background_image',
    904894        ) );
    905 
    906         if ( $this->setting->default )
    907             $this->add_tab( 'default',  __('Default'),  array( $this, 'tab_default_background' ) );
    908     }
    909 
    910     /**
    911      * @since 3.4.0
    912      */
    913     public function tab_uploaded() {
    914         $backgrounds = get_posts( array(
    915             'post_type'  => 'attachment',
    916             'meta_key'   => '_wp_attachment_is_custom_background',
    917             'meta_value' => $this->manager->get_stylesheet(),
    918             'orderby'    => 'none',
    919             'nopaging'   => true,
    920         ) );
    921 
    922         ?><div class="uploaded-target"></div><?php
    923 
    924         if ( empty( $backgrounds ) )
    925             return;
    926 
    927         foreach ( (array) $backgrounds as $background )
    928             $this->print_tab_image( esc_url_raw( $background->guid ) );
    929     }
    930 
    931     /**
    932      * @since 3.4.0
    933      * @uses WP_Customize_Image_Control::print_tab_image()
    934      */
    935     public function tab_default_background() {
    936         $this->print_tab_image( $this->setting->default );
    937895    }
    938896}
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r30214 r30309  
    966966        /* Control Types (custom control classes) */
    967967        $this->register_control_type( 'WP_Customize_Color_Control' );
     968        $this->register_control_type( 'WP_Customize_Upload_Control' );
     969        $this->register_control_type( 'WP_Customize_Image_Control' );
    968970
    969971        /* Site Title & Tagline */
Note: See TracChangeset for help on using the changeset viewer.