Wordpress 3.6
[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          * If $args['settings'] is not defined, use the $id as the setting ID.
81          *
82          * @since 3.4.0
83          *
84          * @param WP_Customize_Manager $manager
85          * @param string $id
86          * @param array $args
87          */
88         function __construct( $manager, $id, $args = array() ) {
89                 $keys = array_keys( get_object_vars( $this ) );
90                 foreach ( $keys as $key ) {
91                         if ( isset( $args[ $key ] ) )
92                                 $this->$key = $args[ $key ];
93                 }
94
95                 $this->manager = $manager;
96                 $this->id = $id;
97
98
99                 // Process settings.
100                 if ( empty( $this->settings ) )
101                         $this->settings = $id;
102
103                 $settings = array();
104                 if ( is_array( $this->settings ) ) {
105                         foreach ( $this->settings as $key => $setting ) {
106                                 $settings[ $key ] = $this->manager->get_setting( $setting );
107                         }
108                 } else {
109                         $this->setting = $this->manager->get_setting( $this->settings );
110                         $settings['default'] = $this->setting;
111                 }
112                 $this->settings = $settings;
113         }
114
115         /**
116          * Enqueue control related scripts/styles.
117          *
118          * @since 3.4.0
119          */
120         public function enqueue() {}
121
122
123         /**
124          * Fetch a setting's value.
125          * Grabs the main setting by default.
126          *
127          * @since 3.4.0
128          *
129          * @param string $setting_key
130          * @return mixed The requested setting's value, if the setting exists.
131          */
132         public final function value( $setting_key = 'default' ) {
133                 if ( isset( $this->settings[ $setting_key ] ) )
134                         return $this->settings[ $setting_key ]->value();
135         }
136
137         /**
138          * Refresh the parameters passed to the JavaScript via JSON.
139          *
140          * @since 3.4.0
141          */
142         public function to_json() {
143                 $this->json['settings'] = array();
144                 foreach ( $this->settings as $key => $setting ) {
145                         $this->json['settings'][ $key ] = $setting->id;
146                 }
147
148                 $this->json['type'] = $this->type;
149         }
150
151         /**
152          * Check if the theme supports the control and check user capabilities.
153          *
154          * @since 3.4.0
155          *
156          * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.
157          */
158         public final function check_capabilities() {
159                 foreach ( $this->settings as $setting ) {
160                         if ( ! $setting->check_capabilities() )
161                                 return false;
162                 }
163
164                 $section = $this->manager->get_section( $this->section );
165                 if ( isset( $section ) && ! $section->check_capabilities() )
166                         return false;
167
168                 return true;
169         }
170
171         /**
172          * Check capabilities and render the control.
173          *
174          * @since 3.4.0
175          * @uses WP_Customize_Control::render()
176          */
177         public final function maybe_render() {
178                 if ( ! $this->check_capabilities() )
179                         return;
180
181                 do_action( 'customize_render_control', $this );
182                 do_action( 'customize_render_control_' . $this->id, $this );
183
184                 $this->render();
185         }
186
187         /**
188          * Render the control. Renders the control wrapper, then calls $this->render_content().
189          *
190          * @since 3.4.0
191          */
192         protected function render() {
193                 $id    = 'customize-control-' . str_replace( '[', '-', str_replace( ']', '', $this->id ) );
194                 $class = 'customize-control customize-control-' . $this->type;
195
196                 ?><li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
197                         <?php $this->render_content(); ?>
198                 </li><?php
199         }
200
201         /**
202          * Get the data link parameter for a setting.
203          *
204          * @since 3.4.0
205          *
206          * @param string $setting_key
207          * @return string Data link parameter, if $setting_key is a valid setting, empty string otherwise.
208          */
209         public function get_link( $setting_key = 'default' ) {
210                 if ( ! isset( $this->settings[ $setting_key ] ) )
211                         return '';
212
213                 return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
214         }
215
216         /**
217          * Render the data link parameter for a setting
218          *
219          * @since 3.4.0
220          * @uses WP_Customize_Control::get_link()
221          *
222          * @param string $setting_key
223          */
224         public function link( $setting_key = 'default' ) {
225                 echo $this->get_link( $setting_key );
226         }
227
228         /**
229          * Render the control's content.
230          *
231          * Allows the content to be overriden without having to rewrite the wrapper.
232          *
233          * @since 3.4.0
234          */
235         protected function render_content() {
236                 switch( $this->type ) {
237                         case 'text':
238                                 ?>
239                                 <label>
240                                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
241                                         <input type="text" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
242                                 </label>
243                                 <?php
244                                 break;
245                         case 'checkbox':
246                                 ?>
247                                 <label>
248                                         <input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
249                                         <?php echo esc_html( $this->label ); ?>
250                                 </label>
251                                 <?php
252                                 break;
253                         case 'radio':
254                                 if ( empty( $this->choices ) )
255                                         return;
256
257                                 $name = '_customize-radio-' . $this->id;
258
259                                 ?>
260                                 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
261                                 <?php
262                                 foreach ( $this->choices as $value => $label ) :
263                                         ?>
264                                         <label>
265                                                 <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?> />
266                                                 <?php echo esc_html( $label ); ?><br/>
267                                         </label>
268                                         <?php
269                                 endforeach;
270                                 break;
271                         case 'select':
272                                 if ( empty( $this->choices ) )
273                                         return;
274
275                                 ?>
276                                 <label>
277                                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
278                                         <select <?php $this->link(); ?>>
279                                                 <?php
280                                                 foreach ( $this->choices as $value => $label )
281                                                         echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';
282                                                 ?>
283                                         </select>
284                                 </label>
285                                 <?php
286                                 break;
287                         case 'dropdown-pages':
288                                 $dropdown = wp_dropdown_pages(
289                                         array(
290                                                 'name'              => '_customize-dropdown-pages-' . $this->id,
291                                                 'echo'              => 0,
292                                                 'show_option_none'  => __( '&mdash; Select &mdash;' ),
293                                                 'option_none_value' => '0',
294                                                 'selected'          => $this->value(),
295                                         )
296                                 );
297
298                                 // Hackily add in the data link parameter.
299                                 $dropdown = str_replace( '<select', '<select ' . $this->get_link(), $dropdown );
300
301                                 printf(
302                                         '<label class="customize-control-select"><span class="customize-control-title">%s</span> %s</label>',
303                                         $this->label,
304                                         $dropdown
305                                 );
306                                 break;
307                 }
308         }
309 }
310
311 /**
312  * Customize Color Control Class
313  *
314  * @package WordPress
315  * @subpackage Customize
316  * @since 3.4.0
317  */
318 class WP_Customize_Color_Control extends WP_Customize_Control {
319         /**
320          * @access public
321          * @var string
322          */
323         public $type = 'color';
324
325         /**
326          * @access public
327          * @var array
328          */
329         public $statuses;
330
331         /**
332          * Constructor.
333          *
334          * If $args['settings'] is not defined, use the $id as the setting ID.
335          *
336          * @since 3.4.0
337          * @uses WP_Customize_Control::__construct()
338          *
339          * @param WP_Customize_Manager $manager
340          * @param string $id
341          * @param array $args
342          */
343         public function __construct( $manager, $id, $args = array() ) {
344                 $this->statuses = array( '' => __('Default') );
345                 parent::__construct( $manager, $id, $args );
346         }
347
348         /**
349          * Enqueue control related scripts/styles.
350          *
351          * @since 3.4.0
352          */
353         public function enqueue() {
354                 wp_enqueue_script( 'wp-color-picker' );
355                 wp_enqueue_style( 'wp-color-picker' );
356         }
357
358         /**
359          * Refresh the parameters passed to the JavaScript via JSON.
360          *
361          * @since 3.4.0
362          * @uses WP_Customize_Control::to_json()
363          */
364         public function to_json() {
365                 parent::to_json();
366                 $this->json['statuses'] = $this->statuses;
367         }
368
369         /**
370          * Render the control's content.
371          *
372          * @since 3.4.0
373          */
374         public function render_content() {
375                 $this_default = $this->setting->default;
376                 $default_attr = '';
377                 if ( $this_default ) {
378                         if ( false === strpos( $this_default, '#' ) )
379                                 $this_default = '#' . $this_default;
380                         $default_attr = ' data-default-color="' . esc_attr( $this_default ) . '"';
381                 }
382                 // The input's value gets set by JS. Don't fill it.
383                 ?>
384                 <label>
385                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
386                         <div class="customize-control-content">
387                                 <input class="color-picker-hex" type="text" maxlength="7" placeholder="<?php esc_attr_e( 'Hex Value' ); ?>"<?php echo $default_attr; ?> />
388                         </div>
389                 </label>
390                 <?php
391         }
392 }
393
394 /**
395  * Customize Upload Control Class
396  *
397  * @package WordPress
398  * @subpackage Customize
399  * @since 3.4.0
400  */
401 class WP_Customize_Upload_Control extends WP_Customize_Control {
402         public $type    = 'upload';
403         public $removed = '';
404         public $context;
405         public $extensions = array();
406
407         /**
408          * Enqueue control related scripts/styles.
409          *
410          * @since 3.4.0
411          */
412         public function enqueue() {
413                 wp_enqueue_script( 'wp-plupload' );
414         }
415
416         /**
417          * Refresh the parameters passed to the JavaScript via JSON.
418          *
419          * @since 3.4.0
420          * @uses WP_Customize_Control::to_json()
421          */
422         public function to_json() {
423                 parent::to_json();
424
425                 $this->json['removed'] = $this->removed;
426
427                 if ( $this->context )
428                         $this->json['context'] = $this->context;
429
430                 if ( $this->extensions )
431                         $this->json['extensions'] = implode( ',', $this->extensions );
432         }
433
434         /**
435          * Render the control's content.
436          *
437          * @since 3.4.0
438          */
439         public function render_content() {
440                 ?>
441                 <label>
442                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
443                         <div>
444                                 <a href="#" class="button-secondary upload"><?php _e( 'Upload' ); ?></a>
445                                 <a href="#" class="remove"><?php _e( 'Remove' ); ?></a>
446                         </div>
447                 </label>
448                 <?php
449         }
450 }
451
452 /**
453  * Customize Image Control Class
454  *
455  * @package WordPress
456  * @subpackage Customize
457  * @since 3.4.0
458  */
459 class WP_Customize_Image_Control extends WP_Customize_Upload_Control {
460         public $type = 'image';
461         public $get_url;
462         public $statuses;
463         public $extensions = array( 'jpg', 'jpeg', 'gif', 'png' );
464
465         protected $tabs = array();
466
467         /**
468          * Constructor.
469          *
470          * If $args['settings'] is not defined, use the $id as the setting ID.
471          *
472          * @since 3.4.0
473          * @uses WP_Customize_Upload_Control::__construct()
474          *
475          * @param WP_Customize_Manager $manager
476          * @param string $id
477          * @param array $args
478          */
479         public function __construct( $manager, $id, $args ) {
480                 $this->statuses = array( '' => __('No Image') );
481
482                 parent::__construct( $manager, $id, $args );
483
484                 $this->add_tab( 'upload-new', __('Upload New'), array( $this, 'tab_upload_new' ) );
485                 $this->add_tab( 'uploaded',   __('Uploaded'),   array( $this, 'tab_uploaded' ) );
486
487                 // Early priority to occur before $this->manager->prepare_controls();
488                 add_action( 'customize_controls_init', array( $this, 'prepare_control' ), 5 );
489         }
490
491         /**
492          * Prepares the control.
493          *
494          * If no tabs exist, removes the control from the manager.
495          *
496          * @since 3.4.2
497          */
498         public function prepare_control() {
499                 if ( ! $this->tabs )
500                         $this->manager->remove_control( $this->id );
501         }
502
503         /**
504          * Refresh the parameters passed to the JavaScript via JSON.
505          *
506          * @since 3.4.0
507          * @uses WP_Customize_Upload_Control::to_json()
508          */
509         public function to_json() {
510                 parent::to_json();
511                 $this->json['statuses'] = $this->statuses;
512         }
513
514         /**
515          * Render the control's content.
516          *
517          * @since 3.4.0
518          */
519         public function render_content() {
520                 $src = $this->value();
521                 if ( isset( $this->get_url ) )
522                         $src = call_user_func( $this->get_url, $src );
523
524                 ?>
525                 <div class="customize-image-picker">
526                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
527
528                         <div class="customize-control-content">
529                                 <div class="dropdown preview-thumbnail" tabindex="0">
530                                         <div class="dropdown-content">
531                                                 <?php if ( empty( $src ) ): ?>
532                                                         <img style="display:none;" />
533                                                 <?php else: ?>
534                                                         <img src="<?php echo esc_url( set_url_scheme( $src ) ); ?>" />
535                                                 <?php endif; ?>
536                                                 <div class="dropdown-status"></div>
537                                         </div>
538                                         <div class="dropdown-arrow"></div>
539                                 </div>
540                         </div>
541
542                         <div class="library">
543                                 <ul>
544                                         <?php foreach ( $this->tabs as $id => $tab ): ?>
545                                                 <li data-customize-tab='<?php echo esc_attr( $id ); ?>' tabindex='0'>
546                                                         <?php echo esc_html( $tab['label'] ); ?>
547                                                 </li>
548                                         <?php endforeach; ?>
549                                 </ul>
550                                 <?php foreach ( $this->tabs as $id => $tab ): ?>
551                                         <div class="library-content" data-customize-tab='<?php echo esc_attr( $id ); ?>'>
552                                                 <?php call_user_func( $tab['callback'] ); ?>
553                                         </div>
554                                 <?php endforeach; ?>
555                         </div>
556
557                         <div class="actions">
558                                 <a href="#" class="remove"><?php _e( 'Remove Image' ); ?></a>
559                         </div>
560                 </div>
561                 <?php
562         }
563
564         /**
565          * Add a tab to the control.
566          *
567          * @since 3.4.0
568          *
569          * @param string $id
570          * @param string $label
571          * @param mixed $callback
572          */
573         public function add_tab( $id, $label, $callback ) {
574                 $this->tabs[ $id ] = array(
575                         'label'    => $label,
576                         'callback' => $callback,
577                 );
578         }
579
580         /**
581          * Remove a tab from the control.
582          *
583          * @since 3.4.0
584          *
585          * @param string $id
586          */
587         public function remove_tab( $id ) {
588                 unset( $this->tabs[ $id ] );
589         }
590
591         /**
592          * @since 3.4.0
593          */
594         public function tab_upload_new() {
595                 if ( ! _device_can_upload() ) {
596                         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.'), 'http://wordpress.org/mobile/' ) . '</p>';
597                 } else {
598                         ?>
599                         <div class="upload-dropzone">
600                                 <?php _e('Drop a file here or <a href="#" class="upload">select a file</a>.'); ?>
601                         </div>
602                         <div class="upload-fallback">
603                                 <span class="button-secondary"><?php _e('Select File'); ?></span>
604                         </div>
605                         <?php
606                 }
607         }
608
609         /**
610          * @since 3.4.0
611          */
612         public function tab_uploaded() {
613                 ?>
614                 <div class="uploaded-target"></div>
615                 <?php
616         }
617
618         /**
619          * @since 3.4.0
620          *
621          * @param string $url
622          * @param string $thumbnail_url
623          */
624         public function print_tab_image( $url, $thumbnail_url = null ) {
625                 $url = set_url_scheme( $url );
626                 $thumbnail_url = ( $thumbnail_url ) ? set_url_scheme( $thumbnail_url ) : $url;
627                 ?>
628                 <a href="#" class="thumbnail" data-customize-image-value="<?php echo esc_url( $url ); ?>">
629                         <img src="<?php echo esc_url( $thumbnail_url ); ?>" />
630                 </a>
631                 <?php
632         }
633 }
634
635 /**
636  * Customize Background Image Control Class
637  *
638  * @package WordPress
639  * @subpackage Customize
640  * @since 3.4.0
641  */
642 class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control {
643
644         /**
645          * Constructor.
646          *
647          * @since 3.4.0
648          * @uses WP_Customize_Image_Control::__construct()
649          *
650          * @param WP_Customize_Manager $manager
651          */
652         public function __construct( $manager ) {
653                 parent::__construct( $manager, 'background_image', array(
654                         'label'    => __( 'Background Image' ),
655                         'section'  => 'background_image',
656                         'context'  => 'custom-background',
657                         'get_url'  => 'get_background_image',
658                 ) );
659
660                 if ( $this->setting->default )
661                         $this->add_tab( 'default',  __('Default'),  array( $this, 'tab_default_background' ) );
662         }
663
664         /**
665          * @since 3.4.0
666          */
667         public function tab_uploaded() {
668                 $backgrounds = get_posts( array(
669                         'post_type'  => 'attachment',
670                         'meta_key'   => '_wp_attachment_is_custom_background',
671                         'meta_value' => $this->manager->get_stylesheet(),
672                         'orderby'    => 'none',
673                         'nopaging'   => true,
674                 ) );
675
676                 ?><div class="uploaded-target"></div><?php
677
678                 if ( empty( $backgrounds ) )
679                         return;
680
681                 foreach ( (array) $backgrounds as $background )
682                         $this->print_tab_image( esc_url_raw( $background->guid ) );
683         }
684
685         /**
686          * @since 3.4.0
687          * @uses WP_Customize_Image_Control::print_tab_image()
688          */
689         public function tab_default_background() {
690                 $this->print_tab_image( $this->setting->default );
691         }
692 }
693
694 /**
695  * Customize Header Image Control Class
696  *
697  * @package WordPress
698  * @subpackage Customize
699  * @since 3.4.0
700  */
701 class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
702         /**
703          * The processed default headers.
704          * @since 3.4.2
705          * @var array
706          */
707         protected $default_headers;
708
709         /**
710          * The uploaded headers.
711          * @since 3.4.2
712          * @var array
713          */
714         protected $uploaded_headers;
715
716         /**
717          * Constructor.
718          *
719          * @since 3.4.0
720          * @uses WP_Customize_Image_Control::__construct()
721          * @uses WP_Customize_Image_Control::add_tab()
722          *
723          * @param WP_Customize_Manager $manager
724          */
725         public function __construct( $manager ) {
726                 parent::__construct( $manager, 'header_image', array(
727                         'label'    => __( 'Header Image' ),
728                         'settings' => array(
729                                 'default' => 'header_image',
730                                 'data'    => 'header_image_data',
731                         ),
732                         'section'  => 'header_image',
733                         'context'  => 'custom-header',
734                         'removed'  => 'remove-header',
735                         'get_url'  => 'get_header_image',
736                         'statuses' => array(
737                                 ''                      => __('Default'),
738                                 'remove-header'         => __('No Image'),
739                                 'random-default-image'  => __('Random Default Image'),
740                                 'random-uploaded-image' => __('Random Uploaded Image'),
741                         )
742                 ) );
743
744                 // Remove the upload tab.
745                 $this->remove_tab( 'upload-new' );
746         }
747
748         /**
749          * Prepares the control.
750          *
751          * If no tabs exist, removes the control from the manager.
752          *
753          * @since 3.4.2
754          */
755         public function prepare_control() {
756                 global $custom_image_header;
757                 if ( empty( $custom_image_header ) )
758                         return parent::prepare_control();
759
760                 // Process default headers and uploaded headers.
761                 $custom_image_header->process_default_headers();
762                 $this->default_headers = $custom_image_header->default_headers;
763                 $this->uploaded_headers = get_uploaded_header_images();
764
765                 if ( $this->default_headers )
766                         $this->add_tab( 'default',  __('Default'),  array( $this, 'tab_default_headers' ) );
767
768                 if ( ! $this->uploaded_headers )
769                         $this->remove_tab( 'uploaded' );
770
771                 return parent::prepare_control();
772         }
773
774         /**
775          * @since 3.4.0
776          *
777          * @param mixed $choice Which header image to select. (@see Custom_Image_Header::get_header_image() )
778          * @param array $header
779          */
780         public function print_header_image( $choice, $header ) {
781                 $header['url']           = set_url_scheme( $header['url'] );
782                 $header['thumbnail_url'] = set_url_scheme( $header['thumbnail_url'] );
783
784                 $header_image_data = array( 'choice' => $choice );
785                 foreach ( array( 'attachment_id', 'width', 'height', 'url', 'thumbnail_url' ) as $key ) {
786                         if ( isset( $header[ $key ] ) )
787                                 $header_image_data[ $key ] = $header[ $key ];
788                 }
789
790
791                 ?>
792                 <a href="#" class="thumbnail"
793                         data-customize-image-value="<?php echo esc_url( $header['url'] ); ?>"
794                         data-customize-header-image-data="<?php echo esc_attr( json_encode( $header_image_data ) ); ?>">
795                         <img src="<?php echo esc_url( $header['thumbnail_url'] ); ?>" />
796                 </a>
797                 <?php
798         }
799
800         /**
801          * @since 3.4.0
802          */
803         public function tab_uploaded() {
804                 ?><div class="uploaded-target"></div><?php
805
806                 foreach ( $this->uploaded_headers as $choice => $header )
807                         $this->print_header_image( $choice, $header );
808         }
809
810         /**
811          * @since 3.4.0
812          */
813         public function tab_default_headers() {
814                 foreach ( $this->default_headers as $choice => $header )
815                         $this->print_header_image( $choice, $header );
816         }
817 }