Wordpress 3.5
[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                         ?>
597                         <p><?php _e('The web browser on your device cannot be used to upload files. You may be able to use the <a href="http://wordpress.org/extend/mobile/">native app for your device</a> instead.'); ?></p>
598                         <?php
599                 } else {
600                         ?>
601                         <div class="upload-dropzone">
602                                 <?php _e('Drop a file here or <a href="#" class="upload">select a file</a>.'); ?>
603                         </div>
604                         <div class="upload-fallback">
605                                 <span class="button-secondary"><?php _e('Select File'); ?></span>
606                         </div>
607                         <?php
608                 }
609         }
610
611         /**
612          * @since 3.4.0
613          */
614         public function tab_uploaded() {
615                 ?>
616                 <div class="uploaded-target"></div>
617                 <?php
618         }
619
620         /**
621          * @since 3.4.0
622          *
623          * @param string $url
624          * @param string $thumbnail_url
625          */
626         public function print_tab_image( $url, $thumbnail_url = null ) {
627                 $url = set_url_scheme( $url );
628                 $thumbnail_url = ( $thumbnail_url ) ? set_url_scheme( $thumbnail_url ) : $url;
629                 ?>
630                 <a href="#" class="thumbnail" data-customize-image-value="<?php echo esc_url( $url ); ?>">
631                         <img src="<?php echo esc_url( $thumbnail_url ); ?>" />
632                 </a>
633                 <?php
634         }
635 }
636
637 /**
638  * Customize Background Image Control Class
639  *
640  * @package WordPress
641  * @subpackage Customize
642  * @since 3.4.0
643  */
644 class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control {
645
646         /**
647          * Constructor.
648          *
649          * @since 3.4.0
650          * @uses WP_Customize_Image_Control::__construct()
651          *
652          * @param WP_Customize_Manager $manager
653          */
654         public function __construct( $manager ) {
655                 parent::__construct( $manager, 'background_image', array(
656                         'label'    => __( 'Background Image' ),
657                         'section'  => 'background_image',
658                         'context'  => 'custom-background',
659                         'get_url'  => 'get_background_image',
660                 ) );
661
662                 if ( $this->setting->default )
663                         $this->add_tab( 'default',  __('Default'),  array( $this, 'tab_default_background' ) );
664         }
665
666         /**
667          * @since 3.4.0
668          */
669         public function tab_uploaded() {
670                 $backgrounds = get_posts( array(
671                         'post_type'  => 'attachment',
672                         'meta_key'   => '_wp_attachment_is_custom_background',
673                         'meta_value' => $this->manager->get_stylesheet(),
674                         'orderby'    => 'none',
675                         'nopaging'   => true,
676                 ) );
677
678                 ?><div class="uploaded-target"></div><?php
679
680                 if ( empty( $backgrounds ) )
681                         return;
682
683                 foreach ( (array) $backgrounds as $background )
684                         $this->print_tab_image( esc_url_raw( $background->guid ) );
685         }
686
687         /**
688          * @since 3.4.0
689          * @uses WP_Customize_Image_Control::print_tab_image()
690          */
691         public function tab_default_background() {
692                 $this->print_tab_image( $this->setting->default );
693         }
694 }
695
696 /**
697  * Customize Header Image Control Class
698  *
699  * @package WordPress
700  * @subpackage Customize
701  * @since 3.4.0
702  */
703 class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
704         /**
705          * The processed default headers.
706          * @since 3.4.2
707          * @var array
708          */
709         protected $default_headers;
710
711         /**
712          * The uploaded headers.
713          * @since 3.4.2
714          * @var array
715          */
716         protected $uploaded_headers;
717
718         /**
719          * Constructor.
720          *
721          * @since 3.4.0
722          * @uses WP_Customize_Image_Control::__construct()
723          * @uses WP_Customize_Image_Control::add_tab()
724          *
725          * @param WP_Customize_Manager $manager
726          */
727         public function __construct( $manager ) {
728                 parent::__construct( $manager, 'header_image', array(
729                         'label'    => __( 'Header Image' ),
730                         'settings' => array(
731                                 'default' => 'header_image',
732                                 'data'    => 'header_image_data',
733                         ),
734                         'section'  => 'header_image',
735                         'context'  => 'custom-header',
736                         'removed'  => 'remove-header',
737                         'get_url'  => 'get_header_image',
738                         'statuses' => array(
739                                 ''                      => __('Default'),
740                                 'remove-header'         => __('No Image'),
741                                 'random-default-image'  => __('Random Default Image'),
742                                 'random-uploaded-image' => __('Random Uploaded Image'),
743                         )
744                 ) );
745
746                 // Remove the upload tab.
747                 $this->remove_tab( 'upload-new' );
748         }
749
750         /**
751          * Prepares the control.
752          *
753          * If no tabs exist, removes the control from the manager.
754          *
755          * @since 3.4.2
756          */
757         public function prepare_control() {
758                 global $custom_image_header;
759                 if ( empty( $custom_image_header ) )
760                         return parent::prepare_control();
761
762                 // Process default headers and uploaded headers.
763                 $custom_image_header->process_default_headers();
764                 $this->default_headers = $custom_image_header->default_headers;
765                 $this->uploaded_headers = get_uploaded_header_images();
766
767                 if ( $this->default_headers )
768                         $this->add_tab( 'default',  __('Default'),  array( $this, 'tab_default_headers' ) );
769
770                 if ( ! $this->uploaded_headers )
771                         $this->remove_tab( 'uploaded' );
772
773                 return parent::prepare_control();
774         }
775
776         /**
777          * @since 3.4.0
778          *
779          * @param mixed $choice Which header image to select. (@see Custom_Image_Header::get_header_image() )
780          * @param array $header
781          */
782         public function print_header_image( $choice, $header ) {
783                 $header['url']           = set_url_scheme( $header['url'] );
784                 $header['thumbnail_url'] = set_url_scheme( $header['thumbnail_url'] );
785
786                 $header_image_data = array( 'choice' => $choice );
787                 foreach ( array( 'attachment_id', 'width', 'height', 'url', 'thumbnail_url' ) as $key ) {
788                         if ( isset( $header[ $key ] ) )
789                                 $header_image_data[ $key ] = $header[ $key ];
790                 }
791
792
793                 ?>
794                 <a href="#" class="thumbnail"
795                         data-customize-image-value="<?php echo esc_url( $header['url'] ); ?>"
796                         data-customize-header-image-data="<?php echo esc_attr( json_encode( $header_image_data ) ); ?>">
797                         <img src="<?php echo esc_url( $header['thumbnail_url'] ); ?>" />
798                 </a>
799                 <?php
800         }
801
802         /**
803          * @since 3.4.0
804          */
805         public function tab_uploaded() {
806                 ?><div class="uploaded-target"></div><?php
807
808                 foreach ( $this->uploaded_headers as $choice => $header )
809                         $this->print_header_image( $choice, $header );
810         }
811
812         /**
813          * @since 3.4.0
814          */
815         public function tab_default_headers() {
816                 foreach ( $this->default_headers as $choice => $header )
817                         $this->print_header_image( $choice, $header );
818         }
819 }