]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-includes/class-wp-customize-control.php
WordPress 3.9-scripts
[autoinstalls/wordpress.git] / wp-includes / class-wp-customize-control.php
1 <?php
2 /**
3  * Customize Control Class
4  *
5  * @package WordPress
6  * @subpackage Customize
7  * @since 3.4.0
8  */
9 class WP_Customize_Control {
10         /**
11          * @access public
12          * @var WP_Customize_Manager
13          */
14         public $manager;
15
16         /**
17          * @access public
18          * @var string
19          */
20         public $id;
21
22         /**
23          * All settings tied to the control.
24          *
25          * @access public
26          * @var array
27          */
28         public $settings;
29
30         /**
31          * The primary setting for the control (if there is one).
32          *
33          * @access public
34          * @var string
35          */
36         public $setting = 'default';
37
38         /**
39          * @access public
40          * @var int
41          */
42         public $priority = 10;
43
44         /**
45          * @access public
46          * @var string
47          */
48         public $section = '';
49
50         /**
51          * @access public
52          * @var string
53          */
54         public $label = '';
55
56         /**
57          * @todo: Remove choices
58          *
59          * @access public
60          * @var array
61          */
62         public $choices = array();
63
64         /**
65          * @access public
66          * @var array
67          */
68         public $json = array();
69
70         /**
71          * @access public
72          * @var string
73          */
74         public $type = 'text';
75
76
77         /**
78          * Constructor.
79          *
80          * Supplied $args override class property defaults.
81          *
82          * If $args['settings'] is not defined, use the $id as the setting ID.
83          *
84          * @since 3.4.0
85          *
86          * @param WP_Customize_Manager $manager
87          * @param string $id
88          * @param array $args
89          */
90         function __construct( $manager, $id, $args = array() ) {
91                 $keys = array_keys( get_object_vars( $this ) );
92                 foreach ( $keys as $key ) {
93                         if ( isset( $args[ $key ] ) )
94                                 $this->$key = $args[ $key ];
95                 }
96
97                 $this->manager = $manager;
98                 $this->id = $id;
99
100                 // Process settings.
101                 if ( empty( $this->settings ) )
102                         $this->settings = $id;
103
104                 $settings = array();
105                 if ( is_array( $this->settings ) ) {
106                         foreach ( $this->settings as $key => $setting ) {
107                                 $settings[ $key ] = $this->manager->get_setting( $setting );
108                         }
109                 } else {
110                         $this->setting = $this->manager->get_setting( $this->settings );
111                         $settings['default'] = $this->setting;
112                 }
113                 $this->settings = $settings;
114         }
115
116         /**
117          * Enqueue control related scripts/styles.
118          *
119          * @since 3.4.0
120          */
121         public function enqueue() {}
122
123
124         /**
125          * Fetch a setting's value.
126          * Grabs the main setting by default.
127          *
128          * @since 3.4.0
129          *
130          * @param string $setting_key
131          * @return mixed The requested setting's value, if the setting exists.
132          */
133         public final function value( $setting_key = 'default' ) {
134                 if ( isset( $this->settings[ $setting_key ] ) )
135                         return $this->settings[ $setting_key ]->value();
136         }
137
138         /**
139          * Refresh the parameters passed to the JavaScript via JSON.
140          *
141          * @since 3.4.0
142          */
143         public function to_json() {
144                 $this->json['settings'] = array();
145                 foreach ( $this->settings as $key => $setting ) {
146                         $this->json['settings'][ $key ] = $setting->id;
147                 }
148
149                 $this->json['type'] = $this->type;
150         }
151
152         /**
153          * Check if the theme supports the control and check user capabilities.
154          *
155          * @since 3.4.0
156          *
157          * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.
158          */
159         public final function check_capabilities() {
160                 foreach ( $this->settings as $setting ) {
161                         if ( ! $setting->check_capabilities() )
162                                 return false;
163                 }
164
165                 $section = $this->manager->get_section( $this->section );
166                 if ( isset( $section ) && ! $section->check_capabilities() )
167                         return false;
168
169                 return true;
170         }
171
172         /**
173          * Check capabilities and render the control.
174          *
175          * @since 3.4.0
176          * @uses WP_Customize_Control::render()
177          */
178         public final function maybe_render() {
179                 if ( ! $this->check_capabilities() )
180                         return;
181
182                 /**
183                  * Fires just before the current Customizer control is rendered.
184                  *
185                  * @since 3.4.0
186                  *
187                  * @param WP_Customize_Control $this WP_Customize_Control instance.
188                  */
189                 do_action( 'customize_render_control', $this );
190
191                 /**
192                  * Fires just before a specific Customizer control is rendered.
193                  *
194                  * The dynamic portion of the hook name, $this->id, refers to
195                  * the control ID.
196                  *
197                  * @since 3.4.0
198                  *
199                  * @param WP_Customize_Control $this WP_Customize_Control instance.
200                  */
201                 do_action( 'customize_render_control_' . $this->id, $this );
202
203                 $this->render();
204         }
205
206         /**
207          * Renders the control wrapper and calls $this->render_content() for the internals.
208          *
209          * @since 3.4.0
210          */
211         protected function render() {
212                 $id    = 'customize-control-' . str_replace( '[', '-', str_replace( ']', '', $this->id ) );
213                 $class = 'customize-control customize-control-' . $this->type;
214
215                 ?><li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
216                         <?php $this->render_content(); ?>
217                 </li><?php
218         }
219
220         /**
221          * Get the data link attribute for a setting.
222          *
223          * @since 3.4.0
224          *
225          * @param string $setting_key
226          * @return string Data link parameter, if $setting_key is a valid setting, empty string otherwise.
227          */
228         public function get_link( $setting_key = 'default' ) {
229                 if ( ! isset( $this->settings[ $setting_key ] ) )
230                         return '';
231
232                 return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
233         }
234
235         /**
236          * Render the data link attribute for the control's input element.
237          *
238          * @since 3.4.0
239          * @uses WP_Customize_Control::get_link()
240          *
241          * @param string $setting_key
242          */
243         public function link( $setting_key = 'default' ) {
244                 echo $this->get_link( $setting_key );
245         }
246
247         /**
248          * Render the control's content.
249          *
250          * Allows the content to be overriden without having to rewrite the wrapper in $this->render().
251          *
252          * Supports basic input types `text`, `checkbox`, `radio`, `select` and `dropdown-pages`.
253          *
254          * @since 3.4.0
255          */
256         protected function render_content() {
257                 switch( $this->type ) {
258                         case 'text':
259                                 ?>
260                                 <label>
261                                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
262                                         <input type="text" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
263                                 </label>
264                                 <?php
265                                 break;
266                         case 'checkbox':
267                                 ?>
268                                 <label>
269                                         <input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
270                                         <?php echo esc_html( $this->label ); ?>
271                                 </label>
272                                 <?php
273                                 break;
274                         case 'radio':
275                                 if ( empty( $this->choices ) )
276                                         return;
277
278                                 $name = '_customize-radio-' . $this->id;
279
280                                 ?>
281                                 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
282                                 <?php
283                                 foreach ( $this->choices as $value => $label ) :
284                                         ?>
285                                         <label>
286                                                 <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?> />
287                                                 <?php echo esc_html( $label ); ?><br/>
288                                         </label>
289                                         <?php
290                                 endforeach;
291                                 break;
292                         case 'select':
293                                 if ( empty( $this->choices ) )
294                                         return;
295
296                                 ?>
297                                 <label>
298                                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
299                                         <select <?php $this->link(); ?>>
300                                                 <?php
301                                                 foreach ( $this->choices as $value => $label )
302                                                         echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';
303                                                 ?>
304                                         </select>
305                                 </label>
306                                 <?php
307                                 break;
308                         case 'dropdown-pages':
309                                 $dropdown = wp_dropdown_pages(
310                                         array(
311                                                 'name'              => '_customize-dropdown-pages-' . $this->id,
312                                                 'echo'              => 0,
313                                                 'show_option_none'  => __( '&mdash; Select &mdash;' ),
314                                                 'option_none_value' => '0',
315                                                 'selected'          => $this->value(),
316                                         )
317                                 );
318
319                                 // Hackily add in the data link parameter.
320                                 $dropdown = str_replace( '<select', '<select ' . $this->get_link(), $dropdown );
321
322                                 printf(
323                                         '<label class="customize-control-select"><span class="customize-control-title">%s</span> %s</label>',
324                                         $this->label,
325                                         $dropdown
326                                 );
327                                 break;
328                 }
329         }
330 }
331
332 /**
333  * Customize Color Control Class
334  *
335  * @package WordPress
336  * @subpackage Customize
337  * @since 3.4.0
338  */
339 class WP_Customize_Color_Control extends WP_Customize_Control {
340         /**
341          * @access public
342          * @var string
343          */
344         public $type = 'color';
345
346         /**
347          * @access public
348          * @var array
349          */
350         public $statuses;
351
352         /**
353          * Constructor.
354          *
355          * @since 3.4.0
356          * @uses WP_Customize_Control::__construct()
357          *
358          * @param WP_Customize_Manager $manager
359          * @param string $id
360          * @param array $args
361          */
362         public function __construct( $manager, $id, $args = array() ) {
363                 $this->statuses = array( '' => __('Default') );
364                 parent::__construct( $manager, $id, $args );
365         }
366
367         /**
368          * Enqueue scripts/styles for the color picker.
369          *
370          * @since 3.4.0
371          */
372         public function enqueue() {
373                 wp_enqueue_script( 'wp-color-picker' );
374                 wp_enqueue_style( 'wp-color-picker' );
375         }
376
377         /**
378          * Refresh the parameters passed to the JavaScript via JSON.
379          *
380          * @since 3.4.0
381          * @uses WP_Customize_Control::to_json()
382          */
383         public function to_json() {
384                 parent::to_json();
385                 $this->json['statuses'] = $this->statuses;
386         }
387
388         /**
389          * Render the control's content.
390          *
391          * @since 3.4.0
392          */
393         public function render_content() {
394                 $this_default = $this->setting->default;
395                 $default_attr = '';
396                 if ( $this_default ) {
397                         if ( false === strpos( $this_default, '#' ) )
398                                 $this_default = '#' . $this_default;
399                         $default_attr = ' data-default-color="' . esc_attr( $this_default ) . '"';
400                 }
401                 // The input's value gets set by JS. Don't fill it.
402                 ?>
403                 <label>
404                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
405                         <div class="customize-control-content">
406                                 <input class="color-picker-hex" type="text" maxlength="7" placeholder="<?php esc_attr_e( 'Hex Value' ); ?>"<?php echo $default_attr; ?> />
407                         </div>
408                 </label>
409                 <?php
410         }
411 }
412
413 /**
414  * Customize Upload Control Class
415  *
416  * @package WordPress
417  * @subpackage Customize
418  * @since 3.4.0
419  */
420 class WP_Customize_Upload_Control extends WP_Customize_Control {
421         public $type    = 'upload';
422         public $removed = '';
423         public $context;
424         public $extensions = array();
425
426         /**
427          * Enqueue control related scripts/styles.
428          *
429          * @since 3.4.0
430          */
431         public function enqueue() {
432                 wp_enqueue_script( 'wp-plupload' );
433         }
434
435         /**
436          * Refresh the parameters passed to the JavaScript via JSON.
437          *
438          * @since 3.4.0
439          * @uses WP_Customize_Control::to_json()
440          */
441         public function to_json() {
442                 parent::to_json();
443
444                 $this->json['removed'] = $this->removed;
445
446                 if ( $this->context )
447                         $this->json['context'] = $this->context;
448
449                 if ( $this->extensions )
450                         $this->json['extensions'] = implode( ',', $this->extensions );
451         }
452
453         /**
454          * Render the control's content.
455          *
456          * @since 3.4.0
457          */
458         public function render_content() {
459                 ?>
460                 <label>
461                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
462                         <div>
463                                 <a href="#" class="button-secondary upload"><?php _e( 'Upload' ); ?></a>
464                                 <a href="#" class="remove"><?php _e( 'Remove' ); ?></a>
465                         </div>
466                 </label>
467                 <?php
468         }
469 }
470
471 /**
472  * Customize Image Control Class
473  *
474  * @package WordPress
475  * @subpackage Customize
476  * @since 3.4.0
477  */
478 class WP_Customize_Image_Control extends WP_Customize_Upload_Control {
479         public $type = 'image';
480         public $get_url;
481         public $statuses;
482         public $extensions = array( 'jpg', 'jpeg', 'gif', 'png' );
483
484         protected $tabs = array();
485
486         /**
487          * Constructor.
488          *
489          * @since 3.4.0
490          * @uses WP_Customize_Upload_Control::__construct()
491          *
492          * @param WP_Customize_Manager $manager
493          * @param string $id
494          * @param array $args
495          */
496         public function __construct( $manager, $id, $args ) {
497                 $this->statuses = array( '' => __('No Image') );
498
499                 parent::__construct( $manager, $id, $args );
500
501                 $this->add_tab( 'upload-new', __('Upload New'), array( $this, 'tab_upload_new' ) );
502                 $this->add_tab( 'uploaded',   __('Uploaded'),   array( $this, 'tab_uploaded' ) );
503
504                 // Early priority to occur before $this->manager->prepare_controls();
505                 add_action( 'customize_controls_init', array( $this, 'prepare_control' ), 5 );
506         }
507
508         /**
509          * Prepares the control.
510          *
511          * If no tabs exist, removes the control from the manager.
512          *
513          * @since 3.4.2
514          */
515         public function prepare_control() {
516                 if ( ! $this->tabs )
517                         $this->manager->remove_control( $this->id );
518         }
519
520         /**
521          * Refresh the parameters passed to the JavaScript via JSON.
522          *
523          * @since 3.4.0
524          * @uses WP_Customize_Upload_Control::to_json()
525          */
526         public function to_json() {
527                 parent::to_json();
528                 $this->json['statuses'] = $this->statuses;
529         }
530
531         /**
532          * Render the control's content.
533          *
534          * @since 3.4.0
535          */
536         public function render_content() {
537                 $src = $this->value();
538                 if ( isset( $this->get_url ) )
539                         $src = call_user_func( $this->get_url, $src );
540
541                 ?>
542                 <div class="customize-image-picker">
543                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
544
545                         <div class="customize-control-content">
546                                 <div class="dropdown preview-thumbnail" tabindex="0">
547                                         <div class="dropdown-content">
548                                                 <?php if ( empty( $src ) ): ?>
549                                                         <img style="display:none;" />
550                                                 <?php else: ?>
551                                                         <img src="<?php echo esc_url( set_url_scheme( $src ) ); ?>" />
552                                                 <?php endif; ?>
553                                                 <div class="dropdown-status"></div>
554                                         </div>
555                                         <div class="dropdown-arrow"></div>
556                                 </div>
557                         </div>
558
559                         <div class="library">
560                                 <ul>
561                                         <?php foreach ( $this->tabs as $id => $tab ): ?>
562                                                 <li data-customize-tab='<?php echo esc_attr( $id ); ?>' tabindex='0'>
563                                                         <?php echo esc_html( $tab['label'] ); ?>
564                                                 </li>
565                                         <?php endforeach; ?>
566                                 </ul>
567                                 <?php foreach ( $this->tabs as $id => $tab ): ?>
568                                         <div class="library-content" data-customize-tab='<?php echo esc_attr( $id ); ?>'>
569                                                 <?php call_user_func( $tab['callback'] ); ?>
570                                         </div>
571                                 <?php endforeach; ?>
572                         </div>
573
574                         <div class="actions">
575                                 <a href="#" class="remove"><?php _e( 'Remove Image' ); ?></a>
576                         </div>
577                 </div>
578                 <?php
579         }
580
581         /**
582          * Add a tab to the control.
583          *
584          * @since 3.4.0
585          *
586          * @param string $id
587          * @param string $label
588          * @param mixed $callback
589          */
590         public function add_tab( $id, $label, $callback ) {
591                 $this->tabs[ $id ] = array(
592                         'label'    => $label,
593                         'callback' => $callback,
594                 );
595         }
596
597         /**
598          * Remove a tab from the control.
599          *
600          * @since 3.4.0
601          *
602          * @param string $id
603          */
604         public function remove_tab( $id ) {
605                 unset( $this->tabs[ $id ] );
606         }
607
608         /**
609          * @since 3.4.0
610          */
611         public function tab_upload_new() {
612                 if ( ! _device_can_upload() ) {
613                         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://wordpress.org/mobile/' ) . '</p>';
614                 } else {
615                         ?>
616                         <div class="upload-dropzone">
617                                 <?php _e('Drop a file here or <a href="#" class="upload">select a file</a>.'); ?>
618                         </div>
619                         <div class="upload-fallback">
620                                 <span class="button-secondary"><?php _e('Select File'); ?></span>
621                         </div>
622                         <?php
623                 }
624         }
625
626         /**
627          * @since 3.4.0
628          */
629         public function tab_uploaded() {
630                 ?>
631                 <div class="uploaded-target"></div>
632                 <?php
633         }
634
635         /**
636          * @since 3.4.0
637          *
638          * @param string $url
639          * @param string $thumbnail_url
640          */
641         public function print_tab_image( $url, $thumbnail_url = null ) {
642                 $url = set_url_scheme( $url );
643                 $thumbnail_url = ( $thumbnail_url ) ? set_url_scheme( $thumbnail_url ) : $url;
644                 ?>
645                 <a href="#" class="thumbnail" data-customize-image-value="<?php echo esc_url( $url ); ?>">
646                         <img src="<?php echo esc_url( $thumbnail_url ); ?>" />
647                 </a>
648                 <?php
649         }
650 }
651
652 /**
653  * Customize Background Image Control Class
654  *
655  * @package WordPress
656  * @subpackage Customize
657  * @since 3.4.0
658  */
659 class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control {
660
661         /**
662          * Constructor.
663          *
664          * @since 3.4.0
665          * @uses WP_Customize_Image_Control::__construct()
666          *
667          * @param WP_Customize_Manager $manager
668          */
669         public function __construct( $manager ) {
670                 parent::__construct( $manager, 'background_image', array(
671                         'label'    => __( 'Background Image' ),
672                         'section'  => 'background_image',
673                         'context'  => 'custom-background',
674                         'get_url'  => 'get_background_image',
675                 ) );
676
677                 if ( $this->setting->default )
678                         $this->add_tab( 'default',  __('Default'),  array( $this, 'tab_default_background' ) );
679         }
680
681         /**
682          * @since 3.4.0
683          */
684         public function tab_uploaded() {
685                 $backgrounds = get_posts( array(
686                         'post_type'  => 'attachment',
687                         'meta_key'   => '_wp_attachment_is_custom_background',
688                         'meta_value' => $this->manager->get_stylesheet(),
689                         'orderby'    => 'none',
690                         'nopaging'   => true,
691                 ) );
692
693                 ?><div class="uploaded-target"></div><?php
694
695                 if ( empty( $backgrounds ) )
696                         return;
697
698                 foreach ( (array) $backgrounds as $background )
699                         $this->print_tab_image( esc_url_raw( $background->guid ) );
700         }
701
702         /**
703          * @since 3.4.0
704          * @uses WP_Customize_Image_Control::print_tab_image()
705          */
706         public function tab_default_background() {
707                 $this->print_tab_image( $this->setting->default );
708         }
709 }
710
711 class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
712         public $type = 'header';
713
714         public function __construct( $manager ) {
715                 parent::__construct( $manager, 'header_image', array(
716                         'label'    => __( 'Header Image' ),
717                         'settings' => array(
718                                 'default' => 'header_image',
719                                 'data'    => 'header_image_data',
720                         ),
721                         'section'  => 'header_image',
722                         'context'  => 'custom-header',
723                         'removed'  => 'remove-header',
724                         'get_url'  => 'get_header_image',
725                 ) );
726
727         }
728
729         public function to_json() {
730                 parent::to_json();
731         }
732
733         public function enqueue() {
734                 wp_enqueue_media();
735                 wp_enqueue_script( 'customize-views' );
736
737                 $this->prepare_control();
738
739                 wp_localize_script( 'customize-views', '_wpCustomizeHeader', array(
740                         'data' => array(
741                                 'width' => absint( get_theme_support( 'custom-header', 'width' ) ),
742                                 'height' => absint( get_theme_support( 'custom-header', 'height' ) ),
743                                 'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ),
744                                 'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ),
745                                 'currentImgSrc' => $this->get_current_image_src(),
746                         ),
747                         'nonces' => array(
748                                 'add' => wp_create_nonce( 'header-add' ),
749                                 'remove' => wp_create_nonce( 'header-remove' ),
750                         ),
751                         'uploads' => $this->uploaded_headers,
752                         'defaults' => $this->default_headers
753                 ) );
754
755                 parent::enqueue();
756         }
757
758         public function prepare_control() {
759                 global $custom_image_header;
760                 if ( empty( $custom_image_header ) ) {
761                         return;
762                 }
763
764                 // Process default headers and uploaded headers.
765                 $custom_image_header->process_default_headers();
766                 $this->default_headers = $custom_image_header->get_default_header_images();
767                 $this->uploaded_headers = $custom_image_header->get_uploaded_header_images();
768         }
769
770         function print_header_image_template() {
771                 ?>
772                 <script type="text/template" id="tmpl-header-choice">
773                         <# if (data.random) { #>
774                                         <button type="button" class="button display-options random">
775                                                 <span class="dashicons dashicons-randomize dice"></span>
776                                                 <# if ( data.type === 'uploaded' ) { #>
777                                                         <?php _e( 'Randomize uploaded headers' ); ?>
778                                                 <# } else if ( data.type === 'default' ) { #>
779                                                         <?php _e( 'Randomize suggested headers' ); ?>
780                                                 <# } #>
781                                         </button>
782
783                         <# } else { #>
784
785                         <# if (data.type === 'uploaded') { #>
786                                 <div class="dashicons dashicons-no close"></div>
787                         <# } #>
788
789                         <button type="button" class="choice thumbnail"
790                                 data-customize-image-value="{{{data.header.url}}}"
791                                 data-customize-header-image-data="{{JSON.stringify(data.header)}}">
792                                 <span class="screen-reader-text"><?php _e( 'Set image' ); ?></span>
793                                 <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}">
794                         </button>
795
796                         <# } #>
797                 </script>
798
799                 <script type="text/template" id="tmpl-header-current">
800                         <# if (data.choice) { #>
801                                 <# if (data.random) { #>
802
803                         <div class="placeholder">
804                                 <div class="inner">
805                                         <span><span class="dashicons dashicons-randomize dice"></span>
806                                         <# if ( data.type === 'uploaded' ) { #>
807                                                 <?php _e( 'Randomizing uploaded headers' ); ?>
808                                         <# } else if ( data.type === 'default' ) { #>
809                                                 <?php _e( 'Randomizing suggested headers' ); ?>
810                                         <# } #>
811                                         </span>
812                                 </div>
813                         </div>
814
815                                 <# } else { #>
816
817                         <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}" tabindex="0"/>
818
819                                 <# } #>
820                         <# } else { #>
821
822                         <div class="placeholder">
823                                 <div class="inner">
824                                         <span>
825                                                 <?php _e( 'No image set' ); ?>
826                                         </span>
827                                 </div>
828                         </div>
829
830                         <# } #>
831                 </script>
832                 <?php
833         }
834
835         public function get_current_image_src() {
836                 $src = $this->value();
837                 if ( isset( $this->get_url ) ) {
838                         $src = call_user_func( $this->get_url, $src );
839                         return $src;
840                 }
841                 return null;
842         }
843
844         public function render_content() {
845                 $this->print_header_image_template();
846                 $visibility = $this->get_current_image_src() ? '' : ' style="display:none" ';
847                 $width = absint( get_theme_support( 'custom-header', 'width' ) );
848                 $height = absint( get_theme_support( 'custom-header', 'height' ) );
849                 ?>
850
851
852                 <div class="customize-control-content">
853                         <p class="customizer-section-intro">
854                                 <?php
855                                 if ( $width && $height ) {
856                                         printf( __( 'While you can crop images to your liking after clicking <strong>Add new</strong>, your theme recommends a header size of <strong>%s &times; %s</strong> pixels.' ), $width, $height );
857                                 } elseif ( $width ) {
858                                         printf( __( 'While you can crop images to your liking after clicking <strong>Add new</strong>, your theme recommends a header width of <strong>%s</strong> pixels.' ), $width );
859                                 } else {
860                                         printf( __( 'While you can crop images to your liking after clicking <strong>Add new</strong>, your theme recommends a header height of <strong>%s</strong> pixels.' ), $height );
861                                 }
862                                 ?>
863                         </p>
864                         <div class="current">
865                                 <span class="customize-control-title">
866                                         <?php _e( 'Current header' ); ?>
867                                 </span>
868                                 <div class="container">
869                                 </div>
870                         </div>
871                         <div class="actions">
872                                 <?php /* translators: Hide as in hide header image via the Customizer */ ?>
873                                 <button type="button"<?php echo $visibility ?> class="button remove"><?php _ex( 'Hide image', 'custom header' ); ?></button>
874                                 <?php /* translators: New as in add new header image via the Customizer */ ?>
875                                 <button type="button" class="button new"><?php _ex( 'Add new image', 'header image' ); ?></button>
876                                 <div style="clear:both"></div>
877                         </div>
878                         <div class="choices">
879                                 <span class="customize-control-title header-previously-uploaded">
880                                         <?php _ex( 'Previously uploaded', 'custom headers' ); ?>
881                                 </span>
882                                 <div class="uploaded">
883                                         <div class="list">
884                                         </div>
885                                 </div>
886                                 <span class="customize-control-title header-default">
887                                         <?php _ex( 'Suggested', 'custom headers' ); ?>
888                                 </span>
889                                 <div class="default">
890                                         <div class="list">
891                                         </div>
892                                 </div>
893                         </div>
894                 </div>
895                 <?php
896         }
897 }
898
899 /**
900  * Widget Area Customize Control Class
901  *
902  */
903 class WP_Widget_Area_Customize_Control extends WP_Customize_Control {
904         public $type = 'sidebar_widgets';
905         public $sidebar_id;
906
907         public function to_json() {
908                 parent::to_json();
909                 $exported_properties = array( 'sidebar_id' );
910                 foreach ( $exported_properties as $key ) {
911                         $this->json[ $key ] = $this->$key;
912                 }
913         }
914
915         public function render_content() {
916                 ?>
917                 <span class="button-secondary add-new-widget" tabindex="0">
918                         <?php _e( 'Add a Widget' ); ?>
919                 </span>
920
921                 <span class="reorder-toggle" tabindex="0">
922                         <span class="reorder"><?php _ex( 'Reorder', 'Reorder widgets in Customizer' ); ?></span>
923                         <span class="reorder-done"><?php _ex( 'Done', 'Cancel reordering widgets in Customizer'  ); ?></span>
924                 </span>
925                 <?php
926         }
927 }
928
929 /**
930  * Widget Form Customize Control Class
931  */
932 class WP_Widget_Form_Customize_Control extends WP_Customize_Control {
933         public $type = 'widget_form';
934         public $widget_id;
935         public $widget_id_base;
936         public $sidebar_id;
937         public $is_new = false;
938         public $width;
939         public $height;
940         public $is_wide = false;
941
942         public function to_json() {
943                 parent::to_json();
944                 $exported_properties = array( 'widget_id', 'widget_id_base', 'sidebar_id', 'width', 'height', 'is_wide' );
945                 foreach ( $exported_properties as $key ) {
946                         $this->json[ $key ] = $this->$key;
947                 }
948         }
949
950         public function render_content() {
951                 global $wp_registered_widgets;
952                 require_once ABSPATH . '/wp-admin/includes/widgets.php';
953
954                 $widget = $wp_registered_widgets[ $this->widget_id ];
955                 if ( ! isset( $widget['params'][0] ) ) {
956                         $widget['params'][0] = array();
957                 }
958
959                 $args = array(
960                         'widget_id' => $widget['id'],
961                         'widget_name' => $widget['name'],
962                 );
963
964                 $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) );
965                 echo $this->manager->widgets->get_widget_control( $args );
966         }
967 }
968