wp/wp-includes/class-wp-customize-control.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
    18 	 * Incremented with each new class instantiation, then stored in $instance_number.
    18 	 * Incremented with each new class instantiation, then stored in $instance_number.
    19 	 *
    19 	 *
    20 	 * Used when sorting two instances whose priorities are equal.
    20 	 * Used when sorting two instances whose priorities are equal.
    21 	 *
    21 	 *
    22 	 * @since 4.1.0
    22 	 * @since 4.1.0
    23 	 * @access protected
    23 	 *
       
    24 	 * @static
    24 	 * @var int
    25 	 * @var int
    25 	 */
    26 	 */
    26 	protected static $instance_count = 0;
    27 	protected static $instance_count = 0;
    27 
    28 
    28 	/**
    29 	/**
    29 	 * Order in which this instance was created in relation to other instances.
    30 	 * Order in which this instance was created in relation to other instances.
    30 	 *
    31 	 *
    31 	 * @since 4.1.0
    32 	 * @since 4.1.0
    32 	 * @access public
       
    33 	 * @var int
    33 	 * @var int
    34 	 */
    34 	 */
    35 	public $instance_number;
    35 	public $instance_number;
    36 
    36 
    37 	/**
    37 	/**
    38 	 * @access public
    38 	 * Customizer manager.
       
    39 	 *
       
    40 	 * @since 3.4.0
    39 	 * @var WP_Customize_Manager
    41 	 * @var WP_Customize_Manager
    40 	 */
    42 	 */
    41 	public $manager;
    43 	public $manager;
    42 
    44 
    43 	/**
    45 	/**
    44 	 * @access public
    46 	 * Control ID.
       
    47 	 *
       
    48 	 * @since 3.4.0
    45 	 * @var string
    49 	 * @var string
    46 	 */
    50 	 */
    47 	public $id;
    51 	public $id;
    48 
    52 
    49 	/**
    53 	/**
    50 	 * All settings tied to the control.
    54 	 * All settings tied to the control.
    51 	 *
    55 	 *
    52 	 * @access public
    56 	 * @since 3.4.0
    53 	 * @var array
    57 	 * @var array
    54 	 */
    58 	 */
    55 	public $settings;
    59 	public $settings;
    56 
    60 
    57 	/**
    61 	/**
    58 	 * The primary setting for the control (if there is one).
    62 	 * The primary setting for the control (if there is one).
    59 	 *
    63 	 *
    60 	 * @access public
    64 	 * @since 3.4.0
    61 	 * @var string
    65 	 * @var string
    62 	 */
    66 	 */
    63 	public $setting = 'default';
    67 	public $setting = 'default';
    64 
    68 
    65 	/**
    69 	/**
    66 	 * @access public
    70 	 * Capability required to use this control.
       
    71 	 *
       
    72 	 * Normally this is empty and the capability is derived from the capabilities
       
    73 	 * of the associated `$settings`.
       
    74 	 *
       
    75 	 * @since 4.5.0
       
    76 	 * @var string
       
    77 	 */
       
    78 	public $capability;
       
    79 
       
    80 	/**
       
    81 	 * Order priority to load the control in Customizer.
       
    82 	 *
       
    83 	 * @since 3.4.0
    67 	 * @var int
    84 	 * @var int
    68 	 */
    85 	 */
    69 	public $priority = 10;
    86 	public $priority = 10;
    70 
    87 
    71 	/**
    88 	/**
    72 	 * @access public
    89 	 * Section the control belongs to.
       
    90 	 *
       
    91 	 * @since 3.4.0
    73 	 * @var string
    92 	 * @var string
    74 	 */
    93 	 */
    75 	public $section = '';
    94 	public $section = '';
    76 
    95 
    77 	/**
    96 	/**
    78 	 * @access public
    97 	 * Label for the control.
       
    98 	 *
       
    99 	 * @since 3.4.0
    79 	 * @var string
   100 	 * @var string
    80 	 */
   101 	 */
    81 	public $label = '';
   102 	public $label = '';
    82 
   103 
    83 	/**
   104 	/**
    84 	 * @access public
   105 	 * Description for the control.
       
   106 	 *
       
   107 	 * @since 4.0.0
    85 	 * @var string
   108 	 * @var string
    86 	 */
   109 	 */
    87 	public $description = '';
   110 	public $description = '';
    88 
   111 
    89 	/**
   112 	/**
    90 	 * @todo: Remove choices
   113 	 * List of choices for 'radio' or 'select' type controls, where values are the keys, and labels are the values.
    91 	 *
   114 	 *
    92 	 * @access public
   115 	 * @since 3.4.0
    93 	 * @var array
   116 	 * @var array
    94 	 */
   117 	 */
    95 	public $choices = array();
   118 	public $choices = array();
    96 
   119 
    97 	/**
   120 	/**
    98 	 * @access public
   121 	 * List of custom input attributes for control output, where attribute names are the keys and values are the values.
       
   122 	 *
       
   123 	 * Not used for 'checkbox', 'radio', 'select', 'textarea', or 'dropdown-pages' control types.
       
   124 	 *
       
   125 	 * @since 4.0.0
    99 	 * @var array
   126 	 * @var array
   100 	 */
   127 	 */
   101 	public $input_attrs = array();
   128 	public $input_attrs = array();
   102 
   129 
   103 	/**
   130 	/**
       
   131 	 * Show UI for adding new content, currently only used for the dropdown-pages control.
       
   132 	 *
       
   133 	 * @since 4.7.0
       
   134 	 * @var bool
       
   135 	 */
       
   136 	public $allow_addition = false;
       
   137 
       
   138 	/**
   104 	 * @deprecated It is better to just call the json() method
   139 	 * @deprecated It is better to just call the json() method
   105 	 * @access public
   140 	 * @since 3.4.0
   106 	 * @var array
   141 	 * @var array
   107 	 */
   142 	 */
   108 	public $json = array();
   143 	public $json = array();
   109 
   144 
   110 	/**
   145 	/**
   111 	 * @access public
   146 	 * Control's Type.
       
   147 	 *
       
   148 	 * @since 3.4.0
   112 	 * @var string
   149 	 * @var string
   113 	 */
   150 	 */
   114 	public $type = 'text';
   151 	public $type = 'text';
   115 
   152 
   116 	/**
   153 	/**
   117 	 * Callback.
   154 	 * Callback.
   118 	 *
   155 	 *
   119 	 * @since 4.0.0
   156 	 * @since 4.0.0
   120 	 * @access public
       
   121 	 *
   157 	 *
   122 	 * @see WP_Customize_Control::active()
   158 	 * @see WP_Customize_Control::active()
   123 	 *
   159 	 *
   124 	 * @var callable Callback is called with one argument, the instance of
   160 	 * @var callable Callback is called with one argument, the instance of
   125 	 *               WP_Customize_Control, and returns bool to indicate whether
   161 	 *               WP_Customize_Control, and returns bool to indicate whether
   129 	public $active_callback = '';
   165 	public $active_callback = '';
   130 
   166 
   131 	/**
   167 	/**
   132 	 * Constructor.
   168 	 * Constructor.
   133 	 *
   169 	 *
   134 	 * Supplied $args override class property defaults.
   170 	 * Supplied `$args` override class property defaults.
   135 	 *
   171 	 *
   136 	 * If $args['settings'] is not defined, use the $id as the setting ID.
   172 	 * If `$args['settings']` is not defined, use the $id as the setting ID.
   137 	 *
   173 	 *
   138 	 * @since 3.4.0
   174 	 * @since 3.4.0
   139 	 *
   175 	 *
   140 	 * @param WP_Customize_Manager $manager
   176 	 * @param WP_Customize_Manager $manager Customizer bootstrap instance.
   141 	 * @param string $id
   177 	 * @param string               $id      Control ID.
   142 	 * @param array $args
   178 	 * @param array                $args    {
       
   179 	 *     Optional. Arguments to override class property defaults.
       
   180 	 *
       
   181 	 *     @type int                  $instance_number Order in which this instance was created in relation
       
   182 	 *                                                 to other instances.
       
   183 	 *     @type WP_Customize_Manager $manager         Customizer bootstrap instance.
       
   184 	 *     @type string               $id              Control ID.
       
   185 	 *     @type array                $settings        All settings tied to the control. If undefined, `$id` will
       
   186 	 *                                                 be used.
       
   187 	 *     @type string               $setting         The primary setting for the control (if there is one).
       
   188 	 *                                                 Default 'default'.
       
   189 	 *     @type int                  $priority        Order priority to load the control. Default 10.
       
   190 	 *     @type string               $section         Section the control belongs to. Default empty.
       
   191 	 *     @type string               $label           Label for the control. Default empty.
       
   192 	 *     @type string               $description     Description for the control. Default empty.
       
   193 	 *     @type array                $choices         List of choices for 'radio' or 'select' type controls, where
       
   194 	 *                                                 values are the keys, and labels are the values.
       
   195 	 *                                                 Default empty array.
       
   196 	 *     @type array                $input_attrs     List of custom input attributes for control output, where
       
   197 	 *                                                 attribute names are the keys and values are the values. Not
       
   198 	 *                                                 used for 'checkbox', 'radio', 'select', 'textarea', or
       
   199 	 *                                                 'dropdown-pages' control types. Default empty array.
       
   200 	 *     @type array                $json            Deprecated. Use WP_Customize_Control::json() instead.
       
   201 	 *     @type string               $type            Control type. Core controls include 'text', 'checkbox',
       
   202 	 *                                                 'textarea', 'radio', 'select', and 'dropdown-pages'. Additional
       
   203 	 *                                                 input types such as 'email', 'url', 'number', 'hidden', and
       
   204 	 *                                                 'date' are supported implicitly. Default 'text'.
       
   205 	 * }
   143 	 */
   206 	 */
   144 	public function __construct( $manager, $id, $args = array() ) {
   207 	public function __construct( $manager, $id, $args = array() ) {
   145 		$keys = array_keys( get_object_vars( $this ) );
   208 		$keys = array_keys( get_object_vars( $this ) );
   146 		foreach ( $keys as $key ) {
   209 		foreach ( $keys as $key ) {
   147 			if ( isset( $args[ $key ] ) ) {
   210 			if ( isset( $args[ $key ] ) ) {
   156 		}
   219 		}
   157 		self::$instance_count += 1;
   220 		self::$instance_count += 1;
   158 		$this->instance_number = self::$instance_count;
   221 		$this->instance_number = self::$instance_count;
   159 
   222 
   160 		// Process settings.
   223 		// Process settings.
   161 		if ( empty( $this->settings ) ) {
   224 		if ( ! isset( $this->settings ) ) {
   162 			$this->settings = $id;
   225 			$this->settings = $id;
   163 		}
   226 		}
   164 
   227 
   165 		$settings = array();
   228 		$settings = array();
   166 		if ( is_array( $this->settings ) ) {
   229 		if ( is_array( $this->settings ) ) {
   167 			foreach ( $this->settings as $key => $setting ) {
   230 			foreach ( $this->settings as $key => $setting ) {
   168 				$settings[ $key ] = $this->manager->get_setting( $setting );
   231 				$settings[ $key ] = $this->manager->get_setting( $setting );
   169 			}
   232 			}
   170 		} else {
   233 		} else if ( is_string( $this->settings ) ) {
   171 			$this->setting = $this->manager->get_setting( $this->settings );
   234 			$this->setting = $this->manager->get_setting( $this->settings );
   172 			$settings['default'] = $this->setting;
   235 			$settings['default'] = $this->setting;
   173 		}
   236 		}
   174 		$this->settings = $settings;
   237 		$this->settings = $settings;
   175 	}
   238 	}
   183 
   246 
   184 	/**
   247 	/**
   185 	 * Check whether control is active to current Customizer preview.
   248 	 * Check whether control is active to current Customizer preview.
   186 	 *
   249 	 *
   187 	 * @since 4.0.0
   250 	 * @since 4.0.0
   188 	 * @access public
       
   189 	 *
   251 	 *
   190 	 * @return bool Whether the control is active to the current preview.
   252 	 * @return bool Whether the control is active to the current preview.
   191 	 */
   253 	 */
   192 	final public function active() {
   254 	final public function active() {
   193 		$control = $this;
   255 		$control = $this;
   194 		$active = call_user_func( $this->active_callback, $this );
   256 		$active = call_user_func( $this->active_callback, $this );
   195 
   257 
   196 		/**
   258 		/**
   197 		 * Filter response of WP_Customize_Control::active().
   259 		 * Filters response of WP_Customize_Control::active().
   198 		 *
   260 		 *
   199 		 * @since 4.0.0
   261 		 * @since 4.0.0
   200 		 *
   262 		 *
   201 		 * @param bool                 $active  Whether the Customizer control is active.
   263 		 * @param bool                 $active  Whether the Customizer control is active.
   202 		 * @param WP_Customize_Control $control WP_Customize_Control instance.
   264 		 * @param WP_Customize_Control $control WP_Customize_Control instance.
   211 	 *
   273 	 *
   212 	 * Subclasses can override this with their specific logic, or they may
   274 	 * Subclasses can override this with their specific logic, or they may
   213 	 * provide an 'active_callback' argument to the constructor.
   275 	 * provide an 'active_callback' argument to the constructor.
   214 	 *
   276 	 *
   215 	 * @since 4.0.0
   277 	 * @since 4.0.0
   216 	 * @access public
   278 	 *
   217 	 *
   279 	 * @return true Always true.
   218 	 * @return bool Always true.
       
   219 	 */
   280 	 */
   220 	public function active_callback() {
   281 	public function active_callback() {
   221 		return true;
   282 		return true;
   222 	}
   283 	}
   223 
   284 
   253 		$this->json['section'] = $this->section;
   314 		$this->json['section'] = $this->section;
   254 		$this->json['content'] = $this->get_content();
   315 		$this->json['content'] = $this->get_content();
   255 		$this->json['label'] = $this->label;
   316 		$this->json['label'] = $this->label;
   256 		$this->json['description'] = $this->description;
   317 		$this->json['description'] = $this->description;
   257 		$this->json['instanceNumber'] = $this->instance_number;
   318 		$this->json['instanceNumber'] = $this->instance_number;
       
   319 
       
   320 		if ( 'dropdown-pages' === $this->type ) {
       
   321 			$this->json['allow_addition'] = $this->allow_addition;
       
   322 		}
   258 	}
   323 	}
   259 
   324 
   260 	/**
   325 	/**
   261 	 * Get the data to export to the client via JSON.
   326 	 * Get the data to export to the client via JSON.
   262 	 *
   327 	 *
   268 		$this->to_json();
   333 		$this->to_json();
   269 		return $this->json;
   334 		return $this->json;
   270 	}
   335 	}
   271 
   336 
   272 	/**
   337 	/**
   273 	 * Check if the theme supports the control and check user capabilities.
   338 	 * Checks if the user can use this control.
       
   339 	 *
       
   340 	 * Returns false if the user cannot manipulate one of the associated settings,
       
   341 	 * or if one of the associated settings does not exist. Also returns false if
       
   342 	 * the associated section does not exist or if its capability check returns
       
   343 	 * false.
   274 	 *
   344 	 *
   275 	 * @since 3.4.0
   345 	 * @since 3.4.0
   276 	 *
   346 	 *
   277 	 * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.
   347 	 * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.
   278 	 */
   348 	 */
   279 	final public function check_capabilities() {
   349 	final public function check_capabilities() {
       
   350 		if ( ! empty( $this->capability ) && ! current_user_can( $this->capability ) ) {
       
   351 			return false;
       
   352 		}
       
   353 
   280 		foreach ( $this->settings as $setting ) {
   354 		foreach ( $this->settings as $setting ) {
   281 			if ( ! $setting->check_capabilities() )
   355 			if ( ! $setting || ! $setting->check_capabilities() ) {
   282 				return false;
   356 				return false;
       
   357 			}
   283 		}
   358 		}
   284 
   359 
   285 		$section = $this->manager->get_section( $this->section );
   360 		$section = $this->manager->get_section( $this->section );
   286 		if ( isset( $section ) && ! $section->check_capabilities() )
   361 		if ( isset( $section ) && ! $section->check_capabilities() ) {
   287 			return false;
   362 			return false;
       
   363 		}
   288 
   364 
   289 		return true;
   365 		return true;
   290 	}
   366 	}
   291 
   367 
   292 	/**
   368 	/**
   297 	 * @return string Contents of the control.
   373 	 * @return string Contents of the control.
   298 	 */
   374 	 */
   299 	final public function get_content() {
   375 	final public function get_content() {
   300 		ob_start();
   376 		ob_start();
   301 		$this->maybe_render();
   377 		$this->maybe_render();
   302 		$template = trim( ob_get_contents() );
   378 		return trim( ob_get_clean() );
   303 		ob_end_clean();
       
   304 		return $template;
       
   305 	}
   379 	}
   306 
   380 
   307 	/**
   381 	/**
   308 	 * Check capabilities and render the control.
   382 	 * Check capabilities and render the control.
   309 	 *
   383 	 *
   329 		 * The dynamic portion of the hook name, `$this->id`, refers to
   403 		 * The dynamic portion of the hook name, `$this->id`, refers to
   330 		 * the control ID.
   404 		 * the control ID.
   331 		 *
   405 		 *
   332 		 * @since 3.4.0
   406 		 * @since 3.4.0
   333 		 *
   407 		 *
   334 		 * @param WP_Customize_Control $this {@see WP_Customize_Control} instance.
   408 		 * @param WP_Customize_Control $this WP_Customize_Control instance.
   335 		 */
   409 		 */
   336 		do_action( 'customize_render_control_' . $this->id, $this );
   410 		do_action( "customize_render_control_{$this->id}", $this );
   337 
   411 
   338 		$this->render();
   412 		$this->render();
   339 	}
   413 	}
   340 
   414 
   341 	/**
   415 	/**
   342 	 * Renders the control wrapper and calls $this->render_content() for the internals.
   416 	 * Renders the control wrapper and calls $this->render_content() for the internals.
   343 	 *
   417 	 *
   344 	 * @since 3.4.0
   418 	 * @since 3.4.0
   345 	 */
   419 	 */
   346 	protected function render() {
   420 	protected function render() {
   347 		$id    = 'customize-control-' . str_replace( '[', '-', str_replace( ']', '', $this->id ) );
   421 		$id    = 'customize-control-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );
   348 		$class = 'customize-control customize-control-' . $this->type;
   422 		$class = 'customize-control customize-control-' . $this->type;
   349 
   423 
   350 		?><li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
   424 		printf( '<li id="%s" class="%s">', esc_attr( $id ), esc_attr( $class ) );
   351 			<?php $this->render_content(); ?>
   425 		$this->render_content();
   352 		</li><?php
   426 		echo '</li>';
   353 	}
   427 	}
   354 
   428 
   355 	/**
   429 	/**
   356 	 * Get the data link attribute for a setting.
   430 	 * Get the data link attribute for a setting.
   357 	 *
   431 	 *
   358 	 * @since 3.4.0
   432 	 * @since 3.4.0
       
   433 	 * @since 4.9.0 Return a `data-customize-setting-key-link` attribute if a setting is not registered for the supplied setting key.
   359 	 *
   434 	 *
   360 	 * @param string $setting_key
   435 	 * @param string $setting_key
   361 	 * @return string Data link parameter, if $setting_key is a valid setting, empty string otherwise.
   436 	 * @return string Data link parameter, a `data-customize-setting-link` attribute if the `$setting_key` refers to a pre-registered setting,
       
   437 	 *                and a `data-customize-setting-key-link` attribute if the setting is not yet registered.
   362 	 */
   438 	 */
   363 	public function get_link( $setting_key = 'default' ) {
   439 	public function get_link( $setting_key = 'default' ) {
   364 		if ( ! isset( $this->settings[ $setting_key ] ) )
   440 		if ( isset( $this->settings[ $setting_key ] ) && $this->settings[ $setting_key ] instanceof WP_Customize_Setting ) {
   365 			return '';
   441 			return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
   366 
   442 		} else {
   367 		return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
   443 			return 'data-customize-setting-key-link="' . esc_attr( $setting_key ) . '"';
       
   444 		}
   368 	}
   445 	}
   369 
   446 
   370 	/**
   447 	/**
   371 	 * Render the data link attribute for the control's input element.
   448 	 * Render the data link attribute for the control's input element.
   372 	 *
   449 	 *
   381 
   458 
   382 	/**
   459 	/**
   383 	 * Render the custom attributes for the control's input element.
   460 	 * Render the custom attributes for the control's input element.
   384 	 *
   461 	 *
   385 	 * @since 4.0.0
   462 	 * @since 4.0.0
   386 	 * @access public
       
   387 	 */
   463 	 */
   388 	public function input_attrs() {
   464 	public function input_attrs() {
   389 		foreach( $this->input_attrs as $attr => $value ) {
   465 		foreach ( $this->input_attrs as $attr => $value ) {
   390 			echo $attr . '="' . esc_attr( $value ) . '" ';
   466 			echo $attr . '="' . esc_attr( $value ) . '" ';
   391 		}
   467 		}
   392 	}
   468 	}
   393 
   469 
   394 	/**
   470 	/**
   395 	 * Render the control's content.
   471 	 * Render the control's content.
   396 	 *
   472 	 *
   397 	 * Allows the content to be overriden without having to rewrite the wrapper in $this->render().
   473 	 * Allows the content to be overridden without having to rewrite the wrapper in `$this::render()`.
   398 	 *
   474 	 *
   399 	 * Supports basic input types `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`.
   475 	 * 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.
   476 	 * Additional input types such as `email`, `url`, `number`, `hidden` and `date` are supported implicitly.
   401 	 *
   477 	 *
   402 	 * Control content can alternately be rendered in JS. See {@see WP_Customize_Control::print_template()}.
   478 	 * Control content can alternately be rendered in JS. See WP_Customize_Control::print_template().
   403 	 *
   479 	 *
   404 	 * @since 3.4.0
   480 	 * @since 3.4.0
   405 	 */
   481 	 */
   406 	protected function render_content() {
   482 	protected function render_content() {
   407 		switch( $this->type ) {
   483 		$input_id = '_customize-input-' . $this->id;
       
   484 		$description_id = '_customize-description-' . $this->id;
       
   485 		$describedby_attr = ( ! empty( $this->description ) ) ? ' aria-describedby="' . esc_attr( $description_id ) . '" ' : '';
       
   486 		switch ( $this->type ) {
   408 			case 'checkbox':
   487 			case 'checkbox':
   409 				?>
   488 				?>
   410 				<label>
   489 				<span class="customize-inside-control-row">
   411 					<input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
   490 					<input
   412 					<?php echo esc_html( $this->label ); ?>
   491 						id="<?php echo esc_attr( $input_id ); ?>"
       
   492 						<?php echo $describedby_attr; ?>
       
   493 						type="checkbox"
       
   494 						value="<?php echo esc_attr( $this->value() ); ?>"
       
   495 						<?php $this->link(); ?>
       
   496 						<?php checked( $this->value() ); ?>
       
   497 					/>
       
   498 					<label for="<?php echo esc_attr( $input_id ); ?>"><?php echo esc_html( $this->label ); ?></label>
   413 					<?php if ( ! empty( $this->description ) ) : ?>
   499 					<?php if ( ! empty( $this->description ) ) : ?>
   414 						<span class="description customize-control-description"><?php echo $this->description; ?></span>
   500 						<span id="<?php echo esc_attr( $description_id ); ?>" class="description customize-control-description"><?php echo $this->description; ?></span>
   415 					<?php endif; ?>
   501 					<?php endif; ?>
   416 				</label>
   502 				</span>
   417 				<?php
   503 				<?php
   418 				break;
   504 				break;
   419 			case 'radio':
   505 			case 'radio':
   420 				if ( empty( $this->choices ) )
   506 				if ( empty( $this->choices ) ) {
   421 					return;
   507 					return;
       
   508 				}
   422 
   509 
   423 				$name = '_customize-radio-' . $this->id;
   510 				$name = '_customize-radio-' . $this->id;
   424 
   511 				?>
   425 				if ( ! empty( $this->label ) ) : ?>
   512 				<?php if ( ! empty( $this->label ) ) : ?>
   426 					<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
   513 					<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
   427 				<?php endif;
   514 				<?php endif; ?>
   428 				if ( ! empty( $this->description ) ) : ?>
   515 				<?php if ( ! empty( $this->description ) ) : ?>
   429 					<span class="description customize-control-description"><?php echo $this->description ; ?></span>
   516 					<span id="<?php echo esc_attr( $description_id ); ?>" class="description customize-control-description"><?php echo $this->description ; ?></span>
   430 				<?php endif;
   517 				<?php endif; ?>
   431 
   518 
   432 				foreach ( $this->choices as $value => $label ) :
   519 				<?php foreach ( $this->choices as $value => $label ) : ?>
   433 					?>
   520 					<span class="customize-inside-control-row">
   434 					<label>
   521 						<input
   435 						<input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?> />
   522 							id="<?php echo esc_attr( $input_id . '-radio-' . $value ); ?>"
   436 						<?php echo esc_html( $label ); ?><br/>
   523 							type="radio"
   437 					</label>
   524 							<?php echo $describedby_attr; ?>
   438 					<?php
   525 							value="<?php echo esc_attr( $value ); ?>"
   439 				endforeach;
   526 							name="<?php echo esc_attr( $name ); ?>"
       
   527 							<?php $this->link(); ?>
       
   528 							<?php checked( $this->value(), $value ); ?>
       
   529 							/>
       
   530 						<label for="<?php echo esc_attr( $input_id . '-radio-' . $value ); ?>"><?php echo esc_html( $label ); ?></label>
       
   531 					</span>
       
   532 				<?php endforeach; ?>
       
   533 				<?php
   440 				break;
   534 				break;
   441 			case 'select':
   535 			case 'select':
   442 				if ( empty( $this->choices ) )
   536 				if ( empty( $this->choices ) ) {
   443 					return;
   537 					return;
       
   538 				}
   444 
   539 
   445 				?>
   540 				?>
   446 				<label>
   541 				<?php if ( ! empty( $this->label ) ) : ?>
   447 					<?php if ( ! empty( $this->label ) ) : ?>
   542 					<label for="<?php echo esc_attr( $input_id ); ?>" class="customize-control-title"><?php echo esc_html( $this->label ); ?></label>
   448 						<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
   543 				<?php endif; ?>
   449 					<?php endif;
   544 				<?php if ( ! empty( $this->description ) ) : ?>
   450 					if ( ! empty( $this->description ) ) : ?>
   545 					<span id="<?php echo esc_attr( $description_id ); ?>" class="description customize-control-description"><?php echo $this->description; ?></span>
   451 						<span class="description customize-control-description"><?php echo $this->description; ?></span>
   546 				<?php endif; ?>
   452 					<?php endif; ?>
   547 
   453 
   548 				<select id="<?php echo esc_attr( $input_id ); ?>" <?php echo $describedby_attr; ?> <?php $this->link(); ?>>
   454 					<select <?php $this->link(); ?>>
   549 					<?php
   455 						<?php
   550 					foreach ( $this->choices as $value => $label ) {
   456 						foreach ( $this->choices as $value => $label )
   551 						echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';
   457 							echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';
   552 					}
   458 						?>
   553 					?>
   459 					</select>
   554 				</select>
   460 				</label>
       
   461 				<?php
   555 				<?php
   462 				break;
   556 				break;
   463 			case 'textarea':
   557 			case 'textarea':
   464 				?>
   558 				?>
   465 				<label>
   559 				<?php if ( ! empty( $this->label ) ) : ?>
   466 					<?php if ( ! empty( $this->label ) ) : ?>
   560 					<label for="<?php echo esc_attr( $input_id ); ?>" class="customize-control-title"><?php echo esc_html( $this->label ); ?></label>
   467 						<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
   561 				<?php endif; ?>
   468 					<?php endif;
   562 				<?php if ( ! empty( $this->description ) ) : ?>
   469 					if ( ! empty( $this->description ) ) : ?>
   563 					<span id="<?php echo esc_attr( $description_id ); ?>" class="description customize-control-description"><?php echo $this->description; ?></span>
   470 						<span class="description customize-control-description"><?php echo $this->description; ?></span>
   564 				<?php endif; ?>
   471 					<?php endif; ?>
   565 				<textarea
   472 					<textarea rows="5" <?php $this->link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>
   566 					id="<?php echo esc_attr( $input_id ); ?>"
   473 				</label>
   567 					rows="5"
       
   568 					<?php echo $describedby_attr; ?>
       
   569 					<?php $this->input_attrs(); ?>
       
   570 					<?php $this->link(); ?>>
       
   571 					<?php echo esc_textarea( $this->value() ); ?>
       
   572 				</textarea>
   474 				<?php
   573 				<?php
   475 				break;
   574 				break;
   476 			case 'dropdown-pages':
   575 			case 'dropdown-pages':
       
   576 				?>
       
   577 				<?php if ( ! empty( $this->label ) ) : ?>
       
   578 					<label for="<?php echo esc_attr( $input_id ); ?>" class="customize-control-title"><?php echo esc_html( $this->label ); ?></label>
       
   579 				<?php endif; ?>
       
   580 				<?php if ( ! empty( $this->description ) ) : ?>
       
   581 					<span id="<?php echo esc_attr( $description_id ); ?>" class="description customize-control-description"><?php echo $this->description; ?></span>
       
   582 				<?php endif; ?>
       
   583 
       
   584 				<?php
       
   585 				$dropdown_name = '_customize-dropdown-pages-' . $this->id;
       
   586 				$show_option_none = __( '&mdash; Select &mdash;' );
       
   587 				$option_none_value = '0';
   477 				$dropdown = wp_dropdown_pages(
   588 				$dropdown = wp_dropdown_pages(
   478 					array(
   589 					array(
   479 						'name'              => '_customize-dropdown-pages-' . $this->id,
   590 						'name'              => $dropdown_name,
   480 						'echo'              => 0,
   591 						'echo'              => 0,
   481 						'show_option_none'  => __( '&mdash; Select &mdash;' ),
   592 						'show_option_none'  => $show_option_none,
   482 						'option_none_value' => '0',
   593 						'option_none_value' => $option_none_value,
   483 						'selected'          => $this->value(),
   594 						'selected'          => $this->value(),
   484 					)
   595 					)
   485 				);
   596 				);
       
   597 				if ( empty( $dropdown ) ) {
       
   598 					$dropdown = sprintf( '<select id="%1$s" name="%1$s">', esc_attr( $dropdown_name ) );
       
   599 					$dropdown .= sprintf( '<option value="%1$s">%2$s</option>', esc_attr( $option_none_value ), esc_html( $show_option_none ) );
       
   600 					$dropdown .= '</select>';
       
   601 				}
   486 
   602 
   487 				// Hackily add in the data link parameter.
   603 				// Hackily add in the data link parameter.
   488 				$dropdown = str_replace( '<select', '<select ' . $this->get_link(), $dropdown );
   604 				$dropdown = str_replace( '<select', '<select ' . $this->get_link() . ' id="' . esc_attr( $input_id ) . '" ' . $describedby_attr, $dropdown );
   489 
   605 
   490 				printf(
   606 				// Even more hacikly add auto-draft page stubs.
   491 					'<label class="customize-control-select"><span class="customize-control-title">%s</span> %s</label>',
   607 				// @todo Eventually this should be removed in favor of the pages being injected into the underlying get_pages() call. See <https://github.com/xwp/wp-customize-posts/pull/250>.
   492 					$this->label,
   608 				$nav_menus_created_posts_setting = $this->manager->get_setting( 'nav_menus_created_posts' );
   493 					$dropdown
   609 				if ( $nav_menus_created_posts_setting && current_user_can( 'publish_pages' ) ) {
   494 				);
   610 					$auto_draft_page_options = '';
       
   611 					foreach ( $nav_menus_created_posts_setting->value() as $auto_draft_page_id ) {
       
   612 						$post = get_post( $auto_draft_page_id );
       
   613 						if ( $post && 'page' === $post->post_type ) {
       
   614 							$auto_draft_page_options .= sprintf( '<option value="%1$s">%2$s</option>', esc_attr( $post->ID ), esc_html( $post->post_title ) );
       
   615 						}
       
   616 					}
       
   617 					if ( $auto_draft_page_options ) {
       
   618 						$dropdown = str_replace( '</select>', $auto_draft_page_options . '</select>', $dropdown );
       
   619 					}
       
   620 				}
       
   621 
       
   622 				echo $dropdown;
       
   623 				?>
       
   624 				<?php if ( $this->allow_addition && current_user_can( 'publish_pages' ) && current_user_can( 'edit_theme_options' ) ) : // Currently tied to menus functionality. ?>
       
   625 					<button type="button" class="button-link add-new-toggle">
       
   626 						<?php
       
   627 						/* translators: %s: add new page label */
       
   628 						printf( __( '+ %s' ), get_post_type_object( 'page' )->labels->add_new_item );
       
   629 						?>
       
   630 					</button>
       
   631 					<div class="new-content-item">
       
   632 						<label for="create-input-<?php echo $this->id; ?>"><span class="screen-reader-text"><?php _e( 'New page title' ); ?></span></label>
       
   633 						<input type="text" id="create-input-<?php echo $this->id; ?>" class="create-item-input" placeholder="<?php esc_attr_e( 'New page title&hellip;' ); ?>">
       
   634 						<button type="button" class="button add-content"><?php _e( 'Add' ); ?></button>
       
   635 					</div>
       
   636 				<?php endif; ?>
       
   637 				<?php
   495 				break;
   638 				break;
   496 			default:
   639 			default:
   497 				?>
   640 				?>
   498 				<label>
   641 				<?php if ( ! empty( $this->label ) ) : ?>
   499 					<?php if ( ! empty( $this->label ) ) : ?>
   642 					<label for="<?php echo esc_attr( $input_id ); ?>" class="customize-control-title"><?php echo esc_html( $this->label ); ?></label>
   500 						<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
   643 				<?php endif; ?>
   501 					<?php endif;
   644 				<?php if ( ! empty( $this->description ) ) : ?>
   502 					if ( ! empty( $this->description ) ) : ?>
   645 					<span id="<?php echo esc_attr( $description_id ); ?>" class="description customize-control-description"><?php echo $this->description; ?></span>
   503 						<span class="description customize-control-description"><?php echo $this->description; ?></span>
   646 				<?php endif; ?>
       
   647 				<input
       
   648 					id="<?php echo esc_attr( $input_id ); ?>"
       
   649 					type="<?php echo esc_attr( $this->type ); ?>"
       
   650 					<?php echo $describedby_attr; ?>
       
   651 					<?php $this->input_attrs(); ?>
       
   652 					<?php if ( ! isset( $this->input_attrs['value'] ) ) : ?>
       
   653 						value="<?php echo esc_attr( $this->value() ); ?>"
   504 					<?php endif; ?>
   654 					<?php endif; ?>
   505 					<input type="<?php echo esc_attr( $this->type ); ?>" <?php $this->input_attrs(); ?> value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
   655 					<?php $this->link(); ?>
   506 				</label>
   656 					/>
   507 				<?php
   657 				<?php
   508 				break;
   658 				break;
   509 		}
   659 		}
   510 	}
   660 	}
   511 
   661 
   512 	/**
   662 	/**
   513 	 * Render the control's JS template.
   663 	 * Render the control's JS template.
   514 	 *
   664 	 *
   515 	 * This function is only run for control types that have been registered with
   665 	 * This function is only run for control types that have been registered with
   516 	 * {@see WP_Customize_Manager::register_control_type()}.
   666 	 * WP_Customize_Manager::register_control_type().
   517 	 *
   667 	 *
   518 	 * In the future, this will also print the template for the control's container
   668 	 * In the future, this will also print the template for the control's container
   519 	 * element and be override-able.
   669 	 * element and be override-able.
   520 	 *
   670 	 *
   521 	 * @since 4.1.0
   671 	 * @since 4.1.0
   530 
   680 
   531 	/**
   681 	/**
   532 	 * An Underscore (JS) template for this control's content (but not its container).
   682 	 * An Underscore (JS) template for this control's content (but not its container).
   533 	 *
   683 	 *
   534 	 * Class variables for this control class are available in the `data` JS object;
   684 	 * Class variables for this control class are available in the `data` JS object;
   535 	 * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
   685 	 * export custom variables by overriding WP_Customize_Control::to_json().
   536 	 *
   686 	 *
   537 	 * @see WP_Customize_Control::print_template()
   687 	 * @see WP_Customize_Control::print_template()
   538 	 *
   688 	 *
   539 	 * @since 4.1.0
   689 	 * @since 4.1.0
   540 	 */
   690 	 */
   541 	protected function content_template() {}
   691 	protected function content_template() {}
   542 
   692 
   543 }
   693 }
   544 
   694 
   545 /**
   695 /**
   546  * Customize Color Control class.
   696  * WP_Customize_Color_Control class.
       
   697  */
       
   698 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-color-control.php' );
       
   699 
       
   700 /**
       
   701  * WP_Customize_Media_Control class.
       
   702  */
       
   703 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-media-control.php' );
       
   704 
       
   705 /**
       
   706  * WP_Customize_Upload_Control class.
       
   707  */
       
   708 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-upload-control.php' );
       
   709 
       
   710 /**
       
   711  * WP_Customize_Image_Control class.
       
   712  */
       
   713 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-image-control.php' );
       
   714 
       
   715 /**
       
   716  * WP_Customize_Background_Image_Control class.
       
   717  */
       
   718 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-control.php' );
       
   719 
       
   720 /**
       
   721  * WP_Customize_Background_Position_Control class.
       
   722  */
       
   723 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-position-control.php' );
       
   724 
       
   725 /**
       
   726  * WP_Customize_Cropped_Image_Control class.
       
   727  */
       
   728 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-cropped-image-control.php' );
       
   729 
       
   730 /**
       
   731  * WP_Customize_Site_Icon_Control class.
       
   732  */
       
   733 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-site-icon-control.php' );
       
   734 
       
   735 /**
       
   736  * WP_Customize_Header_Image_Control class.
       
   737  */
       
   738 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php' );
       
   739 
       
   740 /**
       
   741  * WP_Customize_Theme_Control class.
       
   742  */
       
   743 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-theme-control.php' );
       
   744 
       
   745 /**
       
   746  * WP_Widget_Area_Customize_Control class.
       
   747  */
       
   748 require_once( ABSPATH . WPINC . '/customize/class-wp-widget-area-customize-control.php' );
       
   749 
       
   750 /**
       
   751  * WP_Widget_Form_Customize_Control class.
       
   752  */
       
   753 require_once( ABSPATH . WPINC . '/customize/class-wp-widget-form-customize-control.php' );
       
   754 
       
   755 /**
       
   756  * WP_Customize_Nav_Menu_Control class.
       
   757  */
       
   758 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-control.php' );
       
   759 
       
   760 /**
       
   761  * WP_Customize_Nav_Menu_Item_Control class.
       
   762  */
       
   763 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-control.php' );
       
   764 
       
   765 /**
       
   766  * WP_Customize_Nav_Menu_Location_Control class.
       
   767  */
       
   768 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php' );
       
   769 
       
   770 /**
       
   771  * WP_Customize_Nav_Menu_Name_Control class.
   547  *
   772  *
   548  * @since 3.4.0
   773  * As this file is deprecated, it will trigger a deprecation notice if instantiated. In a subsequent
       
   774  * release, the require_once() here will be removed and _deprecated_file() will be called if file is
       
   775  * required at all.
   549  *
   776  *
   550  * @see WP_Customize_Control
   777  * @deprecated 4.9.0 This file is no longer used due to new menu creation UX.
   551  */
   778  */
   552 class WP_Customize_Color_Control extends WP_Customize_Control {
   779 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' );
   553 	/**
   780 
   554 	 * @access public
   781 /**
   555 	 * @var string
   782  * WP_Customize_Nav_Menu_Locations_Control class.
   556 	 */
   783  */
   557 	public $type = 'color';
   784 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-locations-control.php' );
   558 
   785 
   559 	/**
   786 /**
   560 	 * @access public
   787  * WP_Customize_Nav_Menu_Auto_Add_Control class.
   561 	 * @var array
   788  */
   562 	 */
   789 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php' );
   563 	public $statuses;
   790 
   564 
   791 /**
   565 	/**
   792  * WP_Customize_Date_Time_Control class.
   566 	 * Constructor.
   793  */
   567 	 *
   794 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-date-time-control.php' );
   568 	 * @since 3.4.0
       
   569 	 * @uses WP_Customize_Control::__construct()
       
   570 	 *
       
   571 	 * @param WP_Customize_Manager $manager
       
   572 	 * @param string $id
       
   573 	 * @param array $args
       
   574 	 */
       
   575 	public function __construct( $manager, $id, $args = array() ) {
       
   576 		$this->statuses = array( '' => __('Default') );
       
   577 		parent::__construct( $manager, $id, $args );
       
   578 	}
       
   579 
       
   580 	/**
       
   581 	 * Enqueue scripts/styles for the color picker.
       
   582 	 *
       
   583 	 * @since 3.4.0
       
   584 	 */
       
   585 	public function enqueue() {
       
   586 		wp_enqueue_script( 'wp-color-picker' );
       
   587 		wp_enqueue_style( 'wp-color-picker' );
       
   588 	}
       
   589 
       
   590 	/**
       
   591 	 * Refresh the parameters passed to the JavaScript via JSON.
       
   592 	 *
       
   593 	 * @since 3.4.0
       
   594 	 * @uses WP_Customize_Control::to_json()
       
   595 	 */
       
   596 	public function to_json() {
       
   597 		parent::to_json();
       
   598 		$this->json['statuses'] = $this->statuses;
       
   599 		$this->json['defaultValue'] = $this->setting->default;
       
   600 	}
       
   601 
       
   602 	/**
       
   603 	 * Don't render the control content from PHP, as it's rendered via JS on load.
       
   604 	 *
       
   605 	 * @since 3.4.0
       
   606 	 */
       
   607 	public function render_content() {}
       
   608 
       
   609 	/**
       
   610 	 * Render a JS template for the content of the color picker control.
       
   611 	 *
       
   612 	 * @since 4.1.0
       
   613 	 */
       
   614 	public function content_template() {
       
   615 		?>
       
   616 		<# var defaultValue = '';
       
   617 		if ( data.defaultValue ) {
       
   618 			if ( '#' !== data.defaultValue.substring( 0, 1 ) ) {
       
   619 				defaultValue = '#' + data.defaultValue;
       
   620 			} else {
       
   621 				defaultValue = data.defaultValue;
       
   622 			}
       
   623 			defaultValue = ' data-default-color=' + defaultValue; // Quotes added automatically.
       
   624 		} #>
       
   625 		<label>
       
   626 			<# if ( data.label ) { #>
       
   627 				<span class="customize-control-title">{{{ data.label }}}</span>
       
   628 			<# } #>
       
   629 			<# if ( data.description ) { #>
       
   630 				<span class="description customize-control-description">{{{ data.description }}}</span>
       
   631 			<# } #>
       
   632 			<div class="customize-control-content">
       
   633 				<input class="color-picker-hex" type="text" maxlength="7" placeholder="<?php esc_attr_e( 'Hex Value' ); ?>" {{ defaultValue }} />
       
   634 			</div>
       
   635 		</label>
       
   636 		<?php
       
   637 	}
       
   638 }
       
   639 
       
   640 /**
       
   641  * Customize Media Control class.
       
   642  *
       
   643  * @since 4.2.0
       
   644  *
       
   645  * @see WP_Customize_Control
       
   646  */
       
   647 class WP_Customize_Media_Control extends WP_Customize_Control {
       
   648 	/**
       
   649 	 * Control type.
       
   650 	 *
       
   651 	 * @since 4.2.0
       
   652 	 * @access public
       
   653 	 * @var string
       
   654 	 */
       
   655 	public $type = 'media';
       
   656 
       
   657 	/**
       
   658 	 * Media control mime type.
       
   659 	 *
       
   660 	 * @since 4.2.0
       
   661 	 * @access public
       
   662 	 * @var string
       
   663 	 */
       
   664 	public $mime_type = '';
       
   665 
       
   666 	/**
       
   667 	 * Button labels.
       
   668 	 *
       
   669 	 * @since 4.2.0
       
   670 	 * @access public
       
   671 	 * @var array
       
   672 	 */
       
   673 	public $button_labels = array();
       
   674 
       
   675 	/**
       
   676 	 * Constructor.
       
   677 	 *
       
   678 	 * @since 4.1.0
       
   679 	 * @since 4.2.0 Moved from WP_Customize_Upload_Control.
       
   680 	 *
       
   681 	 * @param WP_Customize_Manager $manager {@see WP_Customize_Manager} instance.
       
   682 	 */
       
   683 	public function __construct( $manager, $id, $args = array() ) {
       
   684 		parent::__construct( $manager, $id, $args );
       
   685 
       
   686 		$this->button_labels = array(
       
   687 			'select'       => __( 'Select File' ),
       
   688 			'change'       => __( 'Change File' ),
       
   689 			'default'      => __( 'Default' ),
       
   690 			'remove'       => __( 'Remove' ),
       
   691 			'placeholder'  => __( 'No file selected' ),
       
   692 			'frame_title'  => __( 'Select File' ),
       
   693 			'frame_button' => __( 'Choose File' ),
       
   694 		);
       
   695 	}
       
   696 
       
   697 	/**
       
   698 	 * Enqueue control related scripts/styles.
       
   699 	 *
       
   700 	 * @since 3.4.0
       
   701 	 * @since 4.2.0 Moved from WP_Customize_Upload_Control.
       
   702 	 */
       
   703 	public function enqueue() {
       
   704 		wp_enqueue_media();
       
   705 	}
       
   706 
       
   707 	/**
       
   708 	 * Refresh the parameters passed to the JavaScript via JSON.
       
   709 	 *
       
   710 	 * @since 3.4.0
       
   711 	 * @since 4.2.0 Moved from WP_Customize_Upload_Control.
       
   712 	 *
       
   713 	 * @see WP_Customize_Control::to_json()
       
   714 	 */
       
   715 	public function to_json() {
       
   716 		parent::to_json();
       
   717 		$this->json['mime_type'] = $this->mime_type;
       
   718 		$this->json['button_labels'] = $this->button_labels;
       
   719 
       
   720 		$value = $this->value();
       
   721 
       
   722 		if ( is_object( $this->setting ) ) {
       
   723 			if ( $this->setting->default ) {
       
   724 				// Fake an attachment model - needs all fields used by template.
       
   725 				// Note that the default value must be a URL, NOT an attachment ID.
       
   726 				$type = in_array( substr( $this->setting->default, -3 ), array( 'jpg', 'png', 'gif', 'bmp' ) ) ? 'image' : 'document';
       
   727 				$default_attachment = array(
       
   728 					'id' => 1,
       
   729 					'url' => $this->setting->default,
       
   730 					'type' => $type,
       
   731 					'icon' => wp_mime_type_icon( $type ),
       
   732 					'title' => basename( $this->setting->default ),
       
   733 				);
       
   734 
       
   735 				if ( 'image' === $type ) {
       
   736 					$default_attachment['sizes'] = array(
       
   737 						'full' => array( 'url' => $this->setting->default ),
       
   738 					);
       
   739 				}
       
   740 
       
   741 				$this->json['defaultAttachment'] = $default_attachment;
       
   742 			}
       
   743 
       
   744 			if ( $value && $this->setting->default && $value === $this->setting->default ) {
       
   745 				// Set the default as the attachment.
       
   746 				$this->json['attachment'] = $this->json['defaultAttachment'];
       
   747 			} elseif ( $value ) {
       
   748 				$this->json['attachment'] = wp_prepare_attachment_for_js( $value );
       
   749 			}
       
   750 		}
       
   751 	}
       
   752 
       
   753 	/**
       
   754 	 * Don't render any content for this control from PHP.
       
   755 	 *
       
   756 	 * @since 3.4.0
       
   757 	 * @since 4.2.0 Moved from WP_Customize_Upload_Control.
       
   758 	 *
       
   759 	 * @see WP_Customize_Media_Control::content_template()
       
   760 	 */
       
   761 	public function render_content() {}
       
   762 
       
   763 	/**
       
   764 	 * Render a JS template for the content of the media control.
       
   765 	 *
       
   766 	 * @since 4.1.0
       
   767 	 * @since 4.2.0 Moved from WP_Customize_Upload_Control.
       
   768 	 */
       
   769 	public function content_template() {
       
   770 		?>
       
   771 		<label for="{{ data.settings['default'] }}-button">
       
   772 			<# if ( data.label ) { #>
       
   773 				<span class="customize-control-title">{{ data.label }}</span>
       
   774 			<# } #>
       
   775 			<# if ( data.description ) { #>
       
   776 				<span class="description customize-control-description">{{{ data.description }}}</span>
       
   777 			<# } #>
       
   778 		</label>
       
   779 
       
   780 		<# if ( data.attachment && data.attachment.id ) { #>
       
   781 			<div class="current">
       
   782 				<div class="container">
       
   783 					<div class="attachment-media-view attachment-media-view-{{ data.attachment.type }} {{ data.attachment.orientation }}">
       
   784 						<div class="thumbnail thumbnail-{{ data.attachment.type }}">
       
   785 							<# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #>
       
   786 								<img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" />
       
   787 							<# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #>
       
   788 								<img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" />
       
   789 							<# } else if ( 'audio' === data.attachment.type ) { #>
       
   790 								<# if ( data.attachment.image && data.attachment.image.src && data.attachment.image.src !== data.attachment.icon ) { #>
       
   791 									<img src="{{ data.attachment.image.src }}" class="thumbnail" draggable="false" />
       
   792 								<# } else { #>
       
   793 									<img src="{{ data.attachment.icon }}" class="attachment-thumb type-icon" draggable="false" />
       
   794 								<# } #>
       
   795 								<p class="attachment-meta attachment-meta-title">&#8220;{{ data.attachment.title }}&#8221;</p>
       
   796 								<# if ( data.attachment.album || data.attachment.meta.album ) { #>
       
   797 								<p class="attachment-meta"><em>{{ data.attachment.album || data.attachment.meta.album }}</em></p>
       
   798 								<# } #>
       
   799 								<# if ( data.attachment.artist || data.attachment.meta.artist ) { #>
       
   800 								<p class="attachment-meta">{{ data.attachment.artist || data.attachment.meta.artist }}</p>
       
   801 								<# } #>
       
   802 								<audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none">
       
   803 									<source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/>
       
   804 								</audio>
       
   805 							<# } else if ( 'video' === data.attachment.type ) { #>
       
   806 								<div class="wp-media-wrapper wp-video">
       
   807 									<video controls="controls" class="wp-video-shortcode" preload="metadata"
       
   808 										<# if ( data.attachment.image && data.attachment.image.src !== data.attachment.icon ) { #>poster="{{ data.attachment.image.src }}"<# } #>>
       
   809 										<source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}"/>
       
   810 									</video>
       
   811 								</div>
       
   812 							<# } else { #>
       
   813 								<img class="attachment-thumb type-icon" src="{{ data.attachment.icon }}" class="icon" draggable="false" />
       
   814 								<p class="attachment-title">{{ data.attachment.title }}</p>
       
   815 							<# } #>
       
   816 						</div>
       
   817 					</div>
       
   818 				</div>
       
   819 			</div>
       
   820 			<div class="actions">
       
   821 				<button type="button" class="button remove-button"><?php echo $this->button_labels['remove']; ?></button>
       
   822 				<button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button"><?php echo $this->button_labels['change']; ?></button>
       
   823 				<div style="clear:both"></div>
       
   824 			</div>
       
   825 		<# } else { #>
       
   826 			<div class="current">
       
   827 				<div class="container">
       
   828 					<div class="placeholder">
       
   829 						<div class="inner">
       
   830 							<span>
       
   831 								<?php echo $this->button_labels['placeholder']; ?>
       
   832 							</span>
       
   833 						</div>
       
   834 					</div>
       
   835 				</div>
       
   836 			</div>
       
   837 			<div class="actions">
       
   838 				<# if ( data.defaultAttachment ) { #>
       
   839 					<button type="button" class="button default-button"><?php echo $this->button_labels['default']; ?></button>
       
   840 				<# } #>
       
   841 				<button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button"><?php echo $this->button_labels['select']; ?></button>
       
   842 				<div style="clear:both"></div>
       
   843 			</div>
       
   844 		<# } #>
       
   845 		<?php
       
   846 	}
       
   847 }
       
   848 
       
   849 /**
       
   850  * Customize Upload Control Class.
       
   851  *
       
   852  * @since 3.4.0
       
   853  *
       
   854  * @see WP_Customize_Media_Control
       
   855  */
       
   856 class WP_Customize_Upload_Control extends WP_Customize_Media_Control {
       
   857 	public $type          = 'upload';
       
   858 	public $mime_type     = '';
       
   859 	public $button_labels = array();
       
   860 	public $removed = ''; // unused
       
   861 	public $context; // unused
       
   862 	public $extensions = array(); // unused
       
   863 
       
   864 	/**
       
   865 	 * Refresh the parameters passed to the JavaScript via JSON.
       
   866 	 *
       
   867 	 * @since 3.4.0
       
   868 	 *
       
   869 	 * @uses WP_Customize_Media_Control::to_json()
       
   870 	 */
       
   871 	public function to_json() {
       
   872 		parent::to_json();
       
   873 
       
   874 		$value = $this->value();
       
   875 		if ( $value ) {
       
   876 			// Get the attachment model for the existing file.
       
   877 			$attachment_id = attachment_url_to_postid( $value );
       
   878 			if ( $attachment_id ) {
       
   879 				$this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id );
       
   880 			}
       
   881 		}
       
   882 	}
       
   883 }
       
   884 
       
   885 /**
       
   886  * Customize Image Control class.
       
   887  *
       
   888  * @since 3.4.0
       
   889  *
       
   890  * @see WP_Customize_Upload_Control
       
   891  */
       
   892 class WP_Customize_Image_Control extends WP_Customize_Upload_Control {
       
   893 	public $type = 'image';
       
   894 	public $mime_type = 'image';
       
   895 
       
   896 	/**
       
   897 	 * Constructor.
       
   898 	 *
       
   899 	 * @since 3.4.0
       
   900 	 * @uses WP_Customize_Upload_Control::__construct()
       
   901 	 *
       
   902 	 * @param WP_Customize_Manager $manager
       
   903 	 * @param string $id
       
   904 	 * @param array  $args
       
   905 	 */
       
   906 	public function __construct( $manager, $id, $args = array() ) {
       
   907 		parent::__construct( $manager, $id, $args );
       
   908 
       
   909 		$this->button_labels = array(
       
   910 			'select'       => __( 'Select Image' ),
       
   911 			'change'       => __( 'Change Image' ),
       
   912 			'remove'       => __( 'Remove' ),
       
   913 			'default'      => __( 'Default' ),
       
   914 			'placeholder'  => __( 'No image selected' ),
       
   915 			'frame_title'  => __( 'Select Image' ),
       
   916 			'frame_button' => __( 'Choose Image' ),
       
   917 		);
       
   918 	}
       
   919 
       
   920 	/**
       
   921 	 * @since 3.4.2
       
   922 	 * @deprecated 4.1.0
       
   923 	 */
       
   924 	public function prepare_control() {}
       
   925 
       
   926 	/**
       
   927 	 * @since 3.4.0
       
   928 	 * @deprecated 4.1.0
       
   929 	 *
       
   930 	 * @param string $id
       
   931 	 * @param string $label
       
   932 	 * @param mixed $callback
       
   933 	 */
       
   934 	public function add_tab( $id, $label, $callback ) {}
       
   935 
       
   936 	/**
       
   937 	 * @since 3.4.0
       
   938 	 * @deprecated 4.1.0
       
   939 	 *
       
   940 	 * @param string $id
       
   941 	 */
       
   942 	public function remove_tab( $id ) {}
       
   943 
       
   944 	/**
       
   945 	 * @since 3.4.0
       
   946 	 * @deprecated 4.1.0
       
   947 	 *
       
   948 	 * @param string $url
       
   949 	 * @param string $thumbnail_url
       
   950 	 */
       
   951 	public function print_tab_image( $url, $thumbnail_url = null ) {}
       
   952 }
       
   953 
       
   954 /**
       
   955  * Customize Background Image Control class.
       
   956  *
       
   957  * @since 3.4.0
       
   958  *
       
   959  * @see WP_Customize_Image_Control
       
   960  */
       
   961 class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control {
       
   962 	public $type = 'background';
       
   963 
       
   964 	/**
       
   965 	 * Constructor.
       
   966 	 *
       
   967 	 * @since 3.4.0
       
   968 	 * @uses WP_Customize_Image_Control::__construct()
       
   969 	 *
       
   970 	 * @param WP_Customize_Manager $manager
       
   971 	 */
       
   972 	public function __construct( $manager ) {
       
   973 		parent::__construct( $manager, 'background_image', array(
       
   974 			'label'    => __( 'Background Image' ),
       
   975 			'section'  => 'background_image',
       
   976 		) );
       
   977 	}
       
   978 
       
   979 	/**
       
   980 	 * Enqueue control related scripts/styles.
       
   981 	 *
       
   982 	 * @since 4.1.0
       
   983 	 */
       
   984 	public function enqueue() {
       
   985 		parent::enqueue();
       
   986 
       
   987 		wp_localize_script( 'customize-controls', '_wpCustomizeBackground', array(
       
   988 			'nonces' => array(
       
   989 				'add' => wp_create_nonce( 'background-add' ),
       
   990 			),
       
   991 		) );
       
   992 	}
       
   993 }
       
   994 
       
   995 /**
       
   996  * Customize Header Image Control class.
       
   997  *
       
   998  * @since 3.4.0
       
   999  *
       
  1000  * @see WP_Customize_Image_Control
       
  1001  */
       
  1002 class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
       
  1003 	public $type = 'header';
       
  1004 	public $uploaded_headers;
       
  1005 	public $default_headers;
       
  1006 
       
  1007 	/**
       
  1008 	 * @param WP_Customize_Manager $manager
       
  1009 	 */
       
  1010 	public function __construct( $manager ) {
       
  1011 		parent::__construct( $manager, 'header_image', array(
       
  1012 			'label'    => __( 'Header Image' ),
       
  1013 			'settings' => array(
       
  1014 				'default' => 'header_image',
       
  1015 				'data'    => 'header_image_data',
       
  1016 			),
       
  1017 			'section'  => 'header_image',
       
  1018 			'removed'  => 'remove-header',
       
  1019 			'get_url'  => 'get_header_image',
       
  1020 		) );
       
  1021 
       
  1022 	}
       
  1023 
       
  1024 	public function enqueue() {
       
  1025 		wp_enqueue_media();
       
  1026 		wp_enqueue_script( 'customize-views' );
       
  1027 
       
  1028 		$this->prepare_control();
       
  1029 
       
  1030 		wp_localize_script( 'customize-views', '_wpCustomizeHeader', array(
       
  1031 			'data' => array(
       
  1032 				'width' => absint( get_theme_support( 'custom-header', 'width' ) ),
       
  1033 				'height' => absint( get_theme_support( 'custom-header', 'height' ) ),
       
  1034 				'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ),
       
  1035 				'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ),
       
  1036 				'currentImgSrc' => $this->get_current_image_src(),
       
  1037 			),
       
  1038 			'nonces' => array(
       
  1039 				'add' => wp_create_nonce( 'header-add' ),
       
  1040 				'remove' => wp_create_nonce( 'header-remove' ),
       
  1041 			),
       
  1042 			'uploads' => $this->uploaded_headers,
       
  1043 			'defaults' => $this->default_headers
       
  1044 		) );
       
  1045 
       
  1046 		parent::enqueue();
       
  1047 	}
       
  1048 
       
  1049 	public function prepare_control() {
       
  1050 		global $custom_image_header;
       
  1051 		if ( empty( $custom_image_header ) ) {
       
  1052 			return;
       
  1053 		}
       
  1054 
       
  1055 		// Process default headers and uploaded headers.
       
  1056 		$custom_image_header->process_default_headers();
       
  1057 		$this->default_headers = $custom_image_header->get_default_header_images();
       
  1058 		$this->uploaded_headers = $custom_image_header->get_uploaded_header_images();
       
  1059 	}
       
  1060 
       
  1061 	public function print_header_image_template() {
       
  1062 		?>
       
  1063 		<script type="text/template" id="tmpl-header-choice">
       
  1064 			<# if (data.random) { #>
       
  1065 					<button type="button" class="button display-options random">
       
  1066 						<span class="dashicons dashicons-randomize dice"></span>
       
  1067 						<# if ( data.type === 'uploaded' ) { #>
       
  1068 							<?php _e( 'Randomize uploaded headers' ); ?>
       
  1069 						<# } else if ( data.type === 'default' ) { #>
       
  1070 							<?php _e( 'Randomize suggested headers' ); ?>
       
  1071 						<# } #>
       
  1072 					</button>
       
  1073 
       
  1074 			<# } else { #>
       
  1075 
       
  1076 			<# if (data.type === 'uploaded') { #>
       
  1077 				<div class="dashicons dashicons-no close"></div>
       
  1078 			<# } #>
       
  1079 
       
  1080 			<button type="button" class="choice thumbnail"
       
  1081 				data-customize-image-value="{{{data.header.url}}}"
       
  1082 				data-customize-header-image-data="{{JSON.stringify(data.header)}}">
       
  1083 				<span class="screen-reader-text"><?php _e( 'Set image' ); ?></span>
       
  1084 				<img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}">
       
  1085 			</button>
       
  1086 
       
  1087 			<# } #>
       
  1088 		</script>
       
  1089 
       
  1090 		<script type="text/template" id="tmpl-header-current">
       
  1091 			<# if (data.choice) { #>
       
  1092 				<# if (data.random) { #>
       
  1093 
       
  1094 			<div class="placeholder">
       
  1095 				<div class="inner">
       
  1096 					<span><span class="dashicons dashicons-randomize dice"></span>
       
  1097 					<# if ( data.type === 'uploaded' ) { #>
       
  1098 						<?php _e( 'Randomizing uploaded headers' ); ?>
       
  1099 					<# } else if ( data.type === 'default' ) { #>
       
  1100 						<?php _e( 'Randomizing suggested headers' ); ?>
       
  1101 					<# } #>
       
  1102 					</span>
       
  1103 				</div>
       
  1104 			</div>
       
  1105 
       
  1106 				<# } else { #>
       
  1107 
       
  1108 			<img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}" tabindex="0"/>
       
  1109 
       
  1110 				<# } #>
       
  1111 			<# } else { #>
       
  1112 
       
  1113 			<div class="placeholder">
       
  1114 				<div class="inner">
       
  1115 					<span>
       
  1116 						<?php _e( 'No image set' ); ?>
       
  1117 					</span>
       
  1118 				</div>
       
  1119 			</div>
       
  1120 
       
  1121 			<# } #>
       
  1122 		</script>
       
  1123 		<?php
       
  1124 	}
       
  1125 
       
  1126 	public function get_current_image_src() {
       
  1127 		$src = $this->value();
       
  1128 		if ( isset( $this->get_url ) ) {
       
  1129 			$src = call_user_func( $this->get_url, $src );
       
  1130 			return $src;
       
  1131 		}
       
  1132 		return null;
       
  1133 	}
       
  1134 
       
  1135 	public function render_content() {
       
  1136 		$this->print_header_image_template();
       
  1137 		$visibility = $this->get_current_image_src() ? '' : ' style="display:none" ';
       
  1138 		$width = absint( get_theme_support( 'custom-header', 'width' ) );
       
  1139 		$height = absint( get_theme_support( 'custom-header', 'height' ) );
       
  1140 		?>
       
  1141 
       
  1142 
       
  1143 		<div class="customize-control-content">
       
  1144 			<p class="customizer-section-intro">
       
  1145 				<?php
       
  1146 				if ( $width && $height ) {
       
  1147 					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header size of <strong>%s &times; %s</strong> pixels.' ), $width, $height );
       
  1148 				} elseif ( $width ) {
       
  1149 					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header width of <strong>%s</strong> pixels.' ), $width );
       
  1150 				} else {
       
  1151 					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header height of <strong>%s</strong> pixels.' ), $height );
       
  1152 				}
       
  1153 				?>
       
  1154 			</p>
       
  1155 			<div class="current">
       
  1156 				<span class="customize-control-title">
       
  1157 					<?php _e( 'Current header' ); ?>
       
  1158 				</span>
       
  1159 				<div class="container">
       
  1160 				</div>
       
  1161 			</div>
       
  1162 			<div class="actions">
       
  1163 				<?php /* translators: Hide as in hide header image via the Customizer */ ?>
       
  1164 				<button type="button"<?php echo $visibility ?> class="button remove"><?php _ex( 'Hide image', 'custom header' ); ?></button>
       
  1165 				<?php /* translators: New as in add new header image via the Customizer */ ?>
       
  1166 				<button type="button" class="button new"><?php _ex( 'Add new image', 'header image' ); ?></button>
       
  1167 				<div style="clear:both"></div>
       
  1168 			</div>
       
  1169 			<div class="choices">
       
  1170 				<span class="customize-control-title header-previously-uploaded">
       
  1171 					<?php _ex( 'Previously uploaded', 'custom headers' ); ?>
       
  1172 				</span>
       
  1173 				<div class="uploaded">
       
  1174 					<div class="list">
       
  1175 					</div>
       
  1176 				</div>
       
  1177 				<span class="customize-control-title header-default">
       
  1178 					<?php _ex( 'Suggested', 'custom headers' ); ?>
       
  1179 				</span>
       
  1180 				<div class="default">
       
  1181 					<div class="list">
       
  1182 					</div>
       
  1183 				</div>
       
  1184 			</div>
       
  1185 		</div>
       
  1186 		<?php
       
  1187 	}
       
  1188 }
       
  1189 
       
  1190 /**
       
  1191  * Customize Theme Control class.
       
  1192  *
       
  1193  * @since 4.2.0
       
  1194  *
       
  1195  * @see WP_Customize_Control
       
  1196  */
       
  1197 class WP_Customize_Theme_Control extends WP_Customize_Control {
       
  1198 
       
  1199 	/**
       
  1200 	 * Customize control type.
       
  1201 	 *
       
  1202 	 * @since 4.2.0
       
  1203 	 * @access public
       
  1204 	 * @var string
       
  1205 	 */
       
  1206 	public $type = 'theme';
       
  1207 
       
  1208 	/**
       
  1209 	 * Theme object.
       
  1210 	 *
       
  1211 	 * @since 4.2.0
       
  1212 	 * @access public
       
  1213 	 * @var WP_Theme
       
  1214 	 */
       
  1215 	public $theme;
       
  1216 
       
  1217 	/**
       
  1218 	 * Refresh the parameters passed to the JavaScript via JSON.
       
  1219 	 *
       
  1220 	 * @since 4.2.0
       
  1221 	 * @access public
       
  1222 	 *
       
  1223 	 * @see WP_Customize_Control::to_json()
       
  1224 	 */
       
  1225 	public function to_json() {
       
  1226 		parent::to_json();
       
  1227 		$this->json['theme'] = $this->theme;
       
  1228 	}
       
  1229 
       
  1230 	/**
       
  1231 	 * Don't render the control content from PHP, as it's rendered via JS on load.
       
  1232 	 *
       
  1233 	 * @since 4.2.0
       
  1234 	 * @access public
       
  1235 	 */
       
  1236 	public function render_content() {}
       
  1237 
       
  1238 	/**
       
  1239 	 * Render a JS template for theme display.
       
  1240 	 *
       
  1241 	 * @since 4.2.0
       
  1242 	 * @access public
       
  1243 	 */
       
  1244 	public function content_template() {
       
  1245 		$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
       
  1246 		$active_url  = esc_url( remove_query_arg( 'theme', $current_url ) );
       
  1247 		$preview_url = esc_url( add_query_arg( 'theme', '__THEME__', $current_url ) ); // Token because esc_url() strips curly braces.
       
  1248 		$preview_url = str_replace( '__THEME__', '{{ data.theme.id }}', $preview_url );
       
  1249 		?>
       
  1250 		<# if ( data.theme.isActiveTheme ) { #>
       
  1251 			<div class="theme active" tabindex="0" data-preview-url="<?php echo esc_attr( $active_url ); ?>" aria-describedby="{{ data.theme.id }}-action {{ data.theme.id }}-name">
       
  1252 		<# } else { #>
       
  1253 			<div class="theme" tabindex="0" data-preview-url="<?php echo esc_attr( $preview_url ); ?>" aria-describedby="{{ data.theme.id }}-action {{ data.theme.id }}-name">
       
  1254 		<# } #>
       
  1255 
       
  1256 			<# if ( data.theme.screenshot[0] ) { #>
       
  1257 				<div class="theme-screenshot">
       
  1258 					<img data-src="{{ data.theme.screenshot[0] }}" alt="" />
       
  1259 				</div>
       
  1260 			<# } else { #>
       
  1261 				<div class="theme-screenshot blank"></div>
       
  1262 			<# } #>
       
  1263 
       
  1264 			<# if ( data.theme.isActiveTheme ) { #>
       
  1265 				<span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Customize' ); ?></span>
       
  1266 			<# } else { #>
       
  1267 				<span class="more-details" id="{{ data.theme.id }}-action"><?php _e( 'Live Preview' ); ?></span>
       
  1268 			<# } #>
       
  1269 
       
  1270 			<div class="theme-author"><?php printf( __( 'By %s' ), '{{ data.theme.author }}' ); ?></div>
       
  1271 
       
  1272 			<# if ( data.theme.isActiveTheme ) { #>
       
  1273 				<h3 class="theme-name" id="{{ data.theme.id }}-name">
       
  1274 					<?php
       
  1275 					/* translators: %s: theme name */
       
  1276 					printf( __( '<span>Active:</span> %s' ), '{{ data.theme.name }}' );
       
  1277 					?>
       
  1278 				</h3>
       
  1279 			<# } else { #>
       
  1280 				<h3 class="theme-name" id="{{ data.theme.id }}-name">{{ data.theme.name }}</h3>
       
  1281 				<div class="theme-actions">
       
  1282 					<button type="button" class="button theme-details"><?php _e( 'Theme Details' ); ?></button>
       
  1283 				</div>
       
  1284 			<# } #>
       
  1285 		</div>
       
  1286 	<?php
       
  1287 	}
       
  1288 }
       
  1289 
       
  1290 /**
       
  1291  * Widget Area Customize Control class.
       
  1292  *
       
  1293  * @since 3.9.0
       
  1294  *
       
  1295  * @see WP_Customize_Control
       
  1296  */
       
  1297 class WP_Widget_Area_Customize_Control extends WP_Customize_Control {
       
  1298 	public $type = 'sidebar_widgets';
       
  1299 	public $sidebar_id;
       
  1300 
       
  1301 	public function to_json() {
       
  1302 		parent::to_json();
       
  1303 		$exported_properties = array( 'sidebar_id' );
       
  1304 		foreach ( $exported_properties as $key ) {
       
  1305 			$this->json[ $key ] = $this->$key;
       
  1306 		}
       
  1307 	}
       
  1308 
       
  1309 	public function render_content() {
       
  1310 		?>
       
  1311 		<span class="button-secondary add-new-widget" tabindex="0">
       
  1312 			<?php _e( 'Add a Widget' ); ?>
       
  1313 		</span>
       
  1314 
       
  1315 		<span class="reorder-toggle" tabindex="0">
       
  1316 			<span class="reorder"><?php _ex( 'Reorder', 'Reorder widgets in Customizer' ); ?></span>
       
  1317 			<span class="reorder-done"><?php _ex( 'Done', 'Cancel reordering widgets in Customizer' ); ?></span>
       
  1318 		</span>
       
  1319 		<?php
       
  1320 	}
       
  1321 
       
  1322 }
       
  1323 
       
  1324 /**
       
  1325  * Widget Form Customize Control class.
       
  1326  *
       
  1327  * @since 3.9.0
       
  1328  *
       
  1329  * @see WP_Customize_Control
       
  1330  */
       
  1331 class WP_Widget_Form_Customize_Control extends WP_Customize_Control {
       
  1332 	public $type = 'widget_form';
       
  1333 	public $widget_id;
       
  1334 	public $widget_id_base;
       
  1335 	public $sidebar_id;
       
  1336 	public $is_new = false;
       
  1337 	public $width;
       
  1338 	public $height;
       
  1339 	public $is_wide = false;
       
  1340 
       
  1341 	public function to_json() {
       
  1342 		parent::to_json();
       
  1343 		$exported_properties = array( 'widget_id', 'widget_id_base', 'sidebar_id', 'width', 'height', 'is_wide' );
       
  1344 		foreach ( $exported_properties as $key ) {
       
  1345 			$this->json[ $key ] = $this->$key;
       
  1346 		}
       
  1347 	}
       
  1348 
       
  1349 	public function render_content() {
       
  1350 		global $wp_registered_widgets;
       
  1351 		require_once ABSPATH . '/wp-admin/includes/widgets.php';
       
  1352 
       
  1353 		$widget = $wp_registered_widgets[ $this->widget_id ];
       
  1354 		if ( ! isset( $widget['params'][0] ) ) {
       
  1355 			$widget['params'][0] = array();
       
  1356 		}
       
  1357 
       
  1358 		$args = array(
       
  1359 			'widget_id' => $widget['id'],
       
  1360 			'widget_name' => $widget['name'],
       
  1361 		);
       
  1362 
       
  1363 		$args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) );
       
  1364 		echo $this->manager->widgets->get_widget_control( $args );
       
  1365 	}
       
  1366 
       
  1367 	/**
       
  1368 	 * Whether the current widget is rendered on the page.
       
  1369 	 *
       
  1370 	 * @since 4.0.0
       
  1371 	 * @access public
       
  1372 	 *
       
  1373 	 * @return bool Whether the widget is rendered.
       
  1374 	 */
       
  1375 	public function active_callback() {
       
  1376 		return $this->manager->widgets->is_widget_rendered( $this->widget_id );
       
  1377 	}
       
  1378 }