WordPress 4.4
[autoinstalls/wordpress.git] / wp-includes / class-wp-customize-control.php
1 <?php
2 /**
3  * WordPress Customize Control classes
4  *
5  * @package WordPress
6  * @subpackage Customize
7  * @since 3.4.0
8  */
9
10 /**
11  * Customize Control class.
12  *
13  * @since 3.4.0
14  */
15 class WP_Customize_Control {
16
17         /**
18          * Incremented with each new class instantiation, then stored in $instance_number.
19          *
20          * Used when sorting two instances whose priorities are equal.
21          *
22          * @since 4.1.0
23          *
24          * @static
25          * @access protected
26          * @var int
27          */
28         protected static $instance_count = 0;
29
30         /**
31          * Order in which this instance was created in relation to other instances.
32          *
33          * @since 4.1.0
34          * @access public
35          * @var int
36          */
37         public $instance_number;
38
39         /**
40          * @access public
41          * @var WP_Customize_Manager
42          */
43         public $manager;
44
45         /**
46          * @access public
47          * @var string
48          */
49         public $id;
50
51         /**
52          * All settings tied to the control.
53          *
54          * @access public
55          * @var array
56          */
57         public $settings;
58
59         /**
60          * The primary setting for the control (if there is one).
61          *
62          * @access public
63          * @var string
64          */
65         public $setting = 'default';
66
67         /**
68          * @access public
69          * @var int
70          */
71         public $priority = 10;
72
73         /**
74          * @access public
75          * @var string
76          */
77         public $section = '';
78
79         /**
80          * @access public
81          * @var string
82          */
83         public $label = '';
84
85         /**
86          * @access public
87          * @var string
88          */
89         public $description = '';
90
91         /**
92          * @todo: Remove choices
93          *
94          * @access public
95          * @var array
96          */
97         public $choices = array();
98
99         /**
100          * @access public
101          * @var array
102          */
103         public $input_attrs = array();
104
105         /**
106          * @deprecated It is better to just call the json() method
107          * @access public
108          * @var array
109          */
110         public $json = array();
111
112         /**
113          * @access public
114          * @var string
115          */
116         public $type = 'text';
117
118         /**
119          * Callback.
120          *
121          * @since 4.0.0
122          * @access public
123          *
124          * @see WP_Customize_Control::active()
125          *
126          * @var callable Callback is called with one argument, the instance of
127          *               WP_Customize_Control, and returns bool to indicate whether
128          *               the control is active (such as it relates to the URL
129          *               currently being previewed).
130          */
131         public $active_callback = '';
132
133         /**
134          * Constructor.
135          *
136          * Supplied $args override class property defaults.
137          *
138          * If $args['settings'] is not defined, use the $id as the setting ID.
139          *
140          * @since 3.4.0
141          *
142          * @param WP_Customize_Manager $manager Customizer bootstrap instance.
143          * @param string               $id      Control ID.
144          * @param array                $args    Optional. Arguments to override class property defaults.
145          */
146         public function __construct( $manager, $id, $args = array() ) {
147                 $keys = array_keys( get_object_vars( $this ) );
148                 foreach ( $keys as $key ) {
149                         if ( isset( $args[ $key ] ) ) {
150                                 $this->$key = $args[ $key ];
151                         }
152                 }
153
154                 $this->manager = $manager;
155                 $this->id = $id;
156                 if ( empty( $this->active_callback ) ) {
157                         $this->active_callback = array( $this, 'active_callback' );
158                 }
159                 self::$instance_count += 1;
160                 $this->instance_number = self::$instance_count;
161
162                 // Process settings.
163                 if ( empty( $this->settings ) ) {
164                         $this->settings = $id;
165                 }
166
167                 $settings = array();
168                 if ( is_array( $this->settings ) ) {
169                         foreach ( $this->settings as $key => $setting ) {
170                                 $settings[ $key ] = $this->manager->get_setting( $setting );
171                         }
172                 } else {
173                         $this->setting = $this->manager->get_setting( $this->settings );
174                         $settings['default'] = $this->setting;
175                 }
176                 $this->settings = $settings;
177         }
178
179         /**
180          * Enqueue control related scripts/styles.
181          *
182          * @since 3.4.0
183          */
184         public function enqueue() {}
185
186         /**
187          * Check whether control is active to current Customizer preview.
188          *
189          * @since 4.0.0
190          * @access public
191          *
192          * @return bool Whether the control is active to the current preview.
193          */
194         final public function active() {
195                 $control = $this;
196                 $active = call_user_func( $this->active_callback, $this );
197
198                 /**
199                  * Filter response of WP_Customize_Control::active().
200                  *
201                  * @since 4.0.0
202                  *
203                  * @param bool                 $active  Whether the Customizer control is active.
204                  * @param WP_Customize_Control $control WP_Customize_Control instance.
205                  */
206                 $active = apply_filters( 'customize_control_active', $active, $control );
207
208                 return $active;
209         }
210
211         /**
212          * Default callback used when invoking WP_Customize_Control::active().
213          *
214          * Subclasses can override this with their specific logic, or they may
215          * provide an 'active_callback' argument to the constructor.
216          *
217          * @since 4.0.0
218          * @access public
219          *
220          * @return true Always true.
221          */
222         public function active_callback() {
223                 return true;
224         }
225
226         /**
227          * Fetch a setting's value.
228          * Grabs the main setting by default.
229          *
230          * @since 3.4.0
231          *
232          * @param string $setting_key
233          * @return mixed The requested setting's value, if the setting exists.
234          */
235         final public function value( $setting_key = 'default' ) {
236                 if ( isset( $this->settings[ $setting_key ] ) ) {
237                         return $this->settings[ $setting_key ]->value();
238                 }
239         }
240
241         /**
242          * Refresh the parameters passed to the JavaScript via JSON.
243          *
244          * @since 3.4.0
245          */
246         public function to_json() {
247                 $this->json['settings'] = array();
248                 foreach ( $this->settings as $key => $setting ) {
249                         $this->json['settings'][ $key ] = $setting->id;
250                 }
251
252                 $this->json['type'] = $this->type;
253                 $this->json['priority'] = $this->priority;
254                 $this->json['active'] = $this->active();
255                 $this->json['section'] = $this->section;
256                 $this->json['content'] = $this->get_content();
257                 $this->json['label'] = $this->label;
258                 $this->json['description'] = $this->description;
259                 $this->json['instanceNumber'] = $this->instance_number;
260         }
261
262         /**
263          * Get the data to export to the client via JSON.
264          *
265          * @since 4.1.0
266          *
267          * @return array Array of parameters passed to the JavaScript.
268          */
269         public function json() {
270                 $this->to_json();
271                 return $this->json;
272         }
273
274         /**
275          * Check if the theme supports the control and check user capabilities.
276          *
277          * @since 3.4.0
278          *
279          * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.
280          */
281         final public function check_capabilities() {
282                 foreach ( $this->settings as $setting ) {
283                         if ( ! $setting->check_capabilities() )
284                                 return false;
285                 }
286
287                 $section = $this->manager->get_section( $this->section );
288                 if ( isset( $section ) && ! $section->check_capabilities() )
289                         return false;
290
291                 return true;
292         }
293
294         /**
295          * Get the control's content for insertion into the Customizer pane.
296          *
297          * @since 4.1.0
298          *
299          * @return string Contents of the control.
300          */
301         final public function get_content() {
302                 ob_start();
303                 $this->maybe_render();
304                 return trim( ob_get_clean() );
305         }
306
307         /**
308          * Check capabilities and render the control.
309          *
310          * @since 3.4.0
311          * @uses WP_Customize_Control::render()
312          */
313         final public function maybe_render() {
314                 if ( ! $this->check_capabilities() )
315                         return;
316
317                 /**
318                  * Fires just before the current Customizer control is rendered.
319                  *
320                  * @since 3.4.0
321                  *
322                  * @param WP_Customize_Control $this WP_Customize_Control instance.
323                  */
324                 do_action( 'customize_render_control', $this );
325
326                 /**
327                  * Fires just before a specific Customizer control is rendered.
328                  *
329                  * The dynamic portion of the hook name, `$this->id`, refers to
330                  * the control ID.
331                  *
332                  * @since 3.4.0
333                  *
334                  * @param WP_Customize_Control $this {@see WP_Customize_Control} instance.
335                  */
336                 do_action( 'customize_render_control_' . $this->id, $this );
337
338                 $this->render();
339         }
340
341         /**
342          * Renders the control wrapper and calls $this->render_content() for the internals.
343          *
344          * @since 3.4.0
345          */
346         protected function render() {
347                 $id    = 'customize-control-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );
348                 $class = 'customize-control customize-control-' . $this->type;
349
350                 ?><li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
351                         <?php $this->render_content(); ?>
352                 </li><?php
353         }
354
355         /**
356          * Get the data link attribute for a setting.
357          *
358          * @since 3.4.0
359          *
360          * @param string $setting_key
361          * @return string Data link parameter, if $setting_key is a valid setting, empty string otherwise.
362          */
363         public function get_link( $setting_key = 'default' ) {
364                 if ( ! isset( $this->settings[ $setting_key ] ) )
365                         return '';
366
367                 return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
368         }
369
370         /**
371          * Render the data link attribute for the control's input element.
372          *
373          * @since 3.4.0
374          * @uses WP_Customize_Control::get_link()
375          *
376          * @param string $setting_key
377          */
378         public function link( $setting_key = 'default' ) {
379                 echo $this->get_link( $setting_key );
380         }
381
382         /**
383          * Render the custom attributes for the control's input element.
384          *
385          * @since 4.0.0
386          * @access public
387          */
388         public function input_attrs() {
389                 foreach ( $this->input_attrs as $attr => $value ) {
390                         echo $attr . '="' . esc_attr( $value ) . '" ';
391                 }
392         }
393
394         /**
395          * Render the control's content.
396          *
397          * Allows the content to be overriden without having to rewrite the wrapper in $this->render().
398          *
399          * Supports basic input types `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`.
400          * Additional input types such as `email`, `url`, `number`, `hidden` and `date` are supported implicitly.
401          *
402          * Control content can alternately be rendered in JS. See {@see WP_Customize_Control::print_template()}.
403          *
404          * @since 3.4.0
405          */
406         protected function render_content() {
407                 switch( $this->type ) {
408                         case 'checkbox':
409                                 ?>
410                                 <label>
411                                         <input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
412                                         <?php echo esc_html( $this->label ); ?>
413                                         <?php if ( ! empty( $this->description ) ) : ?>
414                                                 <span class="description customize-control-description"><?php echo $this->description; ?></span>
415                                         <?php endif; ?>
416                                 </label>
417                                 <?php
418                                 break;
419                         case 'radio':
420                                 if ( empty( $this->choices ) )
421                                         return;
422
423                                 $name = '_customize-radio-' . $this->id;
424
425                                 if ( ! empty( $this->label ) ) : ?>
426                                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
427                                 <?php endif;
428                                 if ( ! empty( $this->description ) ) : ?>
429                                         <span class="description customize-control-description"><?php echo $this->description ; ?></span>
430                                 <?php endif;
431
432                                 foreach ( $this->choices as $value => $label ) :
433                                         ?>
434                                         <label>
435                                                 <input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?> />
436                                                 <?php echo esc_html( $label ); ?><br/>
437                                         </label>
438                                         <?php
439                                 endforeach;
440                                 break;
441                         case 'select':
442                                 if ( empty( $this->choices ) )
443                                         return;
444
445                                 ?>
446                                 <label>
447                                         <?php if ( ! empty( $this->label ) ) : ?>
448                                                 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
449                                         <?php endif;
450                                         if ( ! empty( $this->description ) ) : ?>
451                                                 <span class="description customize-control-description"><?php echo $this->description; ?></span>
452                                         <?php endif; ?>
453
454                                         <select <?php $this->link(); ?>>
455                                                 <?php
456                                                 foreach ( $this->choices as $value => $label )
457                                                         echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';
458                                                 ?>
459                                         </select>
460                                 </label>
461                                 <?php
462                                 break;
463                         case 'textarea':
464                                 ?>
465                                 <label>
466                                         <?php if ( ! empty( $this->label ) ) : ?>
467                                                 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
468                                         <?php endif;
469                                         if ( ! empty( $this->description ) ) : ?>
470                                                 <span class="description customize-control-description"><?php echo $this->description; ?></span>
471                                         <?php endif; ?>
472                                         <textarea rows="5" <?php $this->link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>
473                                 </label>
474                                 <?php
475                                 break;
476                         case 'dropdown-pages':
477                                 ?>
478                                 <label>
479                                 <?php if ( ! empty( $this->label ) ) : ?>
480                                         <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
481                                 <?php endif;
482                                 if ( ! empty( $this->description ) ) : ?>
483                                         <span class="description customize-control-description"><?php echo $this->description; ?></span>
484                                 <?php endif; ?>
485
486                                 <?php $dropdown = wp_dropdown_pages(
487                                         array(
488                                                 'name'              => '_customize-dropdown-pages-' . $this->id,
489                                                 'echo'              => 0,
490                                                 'show_option_none'  => __( '&mdash; Select &mdash;' ),
491                                                 'option_none_value' => '0',
492                                                 'selected'          => $this->value(),
493                                         )
494                                 );
495
496                                 // Hackily add in the data link parameter.
497                                 $dropdown = str_replace( '<select', '<select ' . $this->get_link(), $dropdown );
498                                 echo $dropdown;
499                                 ?>
500                                 </label>
501                                 <?php
502                                 break;
503                         default:
504                                 ?>
505                                 <label>
506                                         <?php if ( ! empty( $this->label ) ) : ?>
507                                                 <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
508                                         <?php endif;
509                                         if ( ! empty( $this->description ) ) : ?>
510                                                 <span class="description customize-control-description"><?php echo $this->description; ?></span>
511                                         <?php endif; ?>
512                                         <input type="<?php echo esc_attr( $this->type ); ?>" <?php $this->input_attrs(); ?> value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
513                                 </label>
514                                 <?php
515                                 break;
516                 }
517         }
518
519         /**
520          * Render the control's JS template.
521          *
522          * This function is only run for control types that have been registered with
523          * {@see WP_Customize_Manager::register_control_type()}.
524          *
525          * In the future, this will also print the template for the control's container
526          * element and be override-able.
527          *
528          * @since 4.1.0
529          */
530         final public function print_template() {
531                 ?>
532                 <script type="text/html" id="tmpl-customize-control-<?php echo $this->type; ?>-content">
533                         <?php $this->content_template(); ?>
534                 </script>
535                 <?php
536         }
537
538         /**
539          * An Underscore (JS) template for this control's content (but not its container).
540          *
541          * Class variables for this control class are available in the `data` JS object;
542          * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
543          *
544          * @see WP_Customize_Control::print_template()
545          *
546          * @since 4.1.0
547          */
548         protected function content_template() {}
549
550 }
551
552 /** WP_Customize_Color_Control class */
553 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-color-control.php' );
554
555 /** WP_Customize_Media_Control class */
556 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-media-control.php' );
557
558 /** WP_Customize_Upload_Control class */
559 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-upload-control.php' );
560
561 /** WP_Customize_Image_Control class */
562 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-image-control.php' );
563
564 /** WP_Customize_Background_Image_Control class */
565 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-control.php' );
566
567 /** WP_Customize_Cropped_Image_Control class */
568 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-cropped-image-control.php' );
569
570 /** WP_Customize_Site_Icon_Control class */
571 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-site-icon-control.php' );
572
573 /** WP_Customize_Header_Image_Control class */
574 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php' );
575
576 /** WP_Customize_Theme_Control class */
577 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-theme-control.php' );
578
579 /** WP_Widget_Area_Customize_Control class */
580 require_once( ABSPATH . WPINC . '/customize/class-wp-widget-area-customize-control.php' );
581
582 /** WP_Widget_Form_Customize_Control class */
583 require_once( ABSPATH . WPINC . '/customize/class-wp-widget-form-customize-control.php' );
584
585 /** WP_Customize_Nav_Menu_Control class */
586 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-control.php' );
587
588 /** WP_Customize_Nav_Menu_Item_Control class */
589 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-control.php' );
590
591 /** WP_Customize_Nav_Menu_Location_Control class */
592 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php' );
593
594 /** WP_Customize_Nav_Menu_Name_Control class */
595 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' );
596
597 /** WP_Customize_Nav_Menu_Auto_Add_Control class */
598 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php' );
599
600 /** WP_Customize_New_Menu_Control class */
601 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' );