$key = $args[ $key ]; } } $this->manager = $manager; $this->id = $id; if ( empty( $this->active_callback ) ) { $this->active_callback = array( $this, 'active_callback' ); } self::$instance_count += 1; $this->instance_number = self::$instance_count; // Process settings. if ( empty( $this->settings ) ) { $this->settings = $id; } $settings = array(); if ( is_array( $this->settings ) ) { foreach ( $this->settings as $key => $setting ) { $settings[ $key ] = $this->manager->get_setting( $setting ); } } else { $this->setting = $this->manager->get_setting( $this->settings ); $settings['default'] = $this->setting; } $this->settings = $settings; } /** * Enqueue control related scripts/styles. * * @since 3.4.0 */ public function enqueue() {} /** * Check whether control is active to current Customizer preview. * * @since 4.0.0 * @access public * * @return bool Whether the control is active to the current preview. */ final public function active() { $control = $this; $active = call_user_func( $this->active_callback, $this ); /** * Filter response of WP_Customize_Control::active(). * * @since 4.0.0 * * @param bool $active Whether the Customizer control is active. * @param WP_Customize_Control $control WP_Customize_Control instance. */ $active = apply_filters( 'customize_control_active', $active, $control ); return $active; } /** * Default callback used when invoking WP_Customize_Control::active(). * * Subclasses can override this with their specific logic, or they may * provide an 'active_callback' argument to the constructor. * * @since 4.0.0 * @access public * * @return true Always true. */ public function active_callback() { return true; } /** * Fetch a setting's value. * Grabs the main setting by default. * * @since 3.4.0 * * @param string $setting_key * @return mixed The requested setting's value, if the setting exists. */ final public function value( $setting_key = 'default' ) { if ( isset( $this->settings[ $setting_key ] ) ) { return $this->settings[ $setting_key ]->value(); } } /** * Refresh the parameters passed to the JavaScript via JSON. * * @since 3.4.0 */ public function to_json() { $this->json['settings'] = array(); foreach ( $this->settings as $key => $setting ) { $this->json['settings'][ $key ] = $setting->id; } $this->json['type'] = $this->type; $this->json['priority'] = $this->priority; $this->json['active'] = $this->active(); $this->json['section'] = $this->section; $this->json['content'] = $this->get_content(); $this->json['label'] = $this->label; $this->json['description'] = $this->description; $this->json['instanceNumber'] = $this->instance_number; } /** * Get the data to export to the client via JSON. * * @since 4.1.0 * * @return array Array of parameters passed to the JavaScript. */ public function json() { $this->to_json(); return $this->json; } /** * Check if the theme supports the control and check user capabilities. * * @since 3.4.0 * * @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true. */ final public function check_capabilities() { foreach ( $this->settings as $setting ) { if ( ! $setting->check_capabilities() ) return false; } $section = $this->manager->get_section( $this->section ); if ( isset( $section ) && ! $section->check_capabilities() ) return false; return true; } /** * Get the control's content for insertion into the Customizer pane. * * @since 4.1.0 * * @return string Contents of the control. */ final public function get_content() { ob_start(); $this->maybe_render(); return trim( ob_get_clean() ); } /** * Check capabilities and render the control. * * @since 3.4.0 * @uses WP_Customize_Control::render() */ final public function maybe_render() { if ( ! $this->check_capabilities() ) return; /** * Fires just before the current Customizer control is rendered. * * @since 3.4.0 * * @param WP_Customize_Control $this WP_Customize_Control instance. */ do_action( 'customize_render_control', $this ); /** * Fires just before a specific Customizer control is rendered. * * The dynamic portion of the hook name, `$this->id`, refers to * the control ID. * * @since 3.4.0 * * @param WP_Customize_Control $this {@see WP_Customize_Control} instance. */ do_action( 'customize_render_control_' . $this->id, $this ); $this->render(); } /** * Renders the control wrapper and calls $this->render_content() for the internals. * * @since 3.4.0 */ protected function render() { $id = 'customize-control-' . str_replace( '[', '-', str_replace( ']', '', $this->id ) ); $class = 'customize-control customize-control-' . $this->type; ?>
  • render_content(); ?>
  • settings[ $setting_key ] ) ) return ''; return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"'; } /** * Render the data link attribute for the control's input element. * * @since 3.4.0 * @uses WP_Customize_Control::get_link() * * @param string $setting_key */ public function link( $setting_key = 'default' ) { echo $this->get_link( $setting_key ); } /** * Render the custom attributes for the control's input element. * * @since 4.0.0 * @access public */ public function input_attrs() { foreach( $this->input_attrs as $attr => $value ) { echo $attr . '="' . esc_attr( $value ) . '" '; } } /** * Render the control's content. * * Allows the content to be overriden without having to rewrite the wrapper in $this->render(). * * Supports basic input types `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`. * Additional input types such as `email`, `url`, `number`, `hidden` and `date` are supported implicitly. * * Control content can alternately be rendered in JS. See {@see WP_Customize_Control::print_template()}. * * @since 3.4.0 */ protected function render_content() { switch( $this->type ) { case 'checkbox': ?> choices ) ) return; $name = '_customize-radio-' . $this->id; if ( ! empty( $this->label ) ) : ?> label ); ?> description ) ) : ?> description ; ?> choices as $value => $label ) : ?> choices ) ) return; ?> '_customize-dropdown-pages-' . $this->id, 'echo' => 0, 'show_option_none' => __( '— Select —' ), 'option_none_value' => '0', 'selected' => $this->value(), ) ); // Hackily add in the data link parameter. $dropdown = str_replace( 'get_link(), $dropdown ); printf( '', $this->label, $dropdown ); break; default: ?> statuses = array( '' => __('Default') ); parent::__construct( $manager, $id, $args ); } /** * Enqueue scripts/styles for the color picker. * * @since 3.4.0 */ public function enqueue() { wp_enqueue_script( 'wp-color-picker' ); wp_enqueue_style( 'wp-color-picker' ); } /** * Refresh the parameters passed to the JavaScript via JSON. * * @since 3.4.0 * @uses WP_Customize_Control::to_json() */ public function to_json() { parent::to_json(); $this->json['statuses'] = $this->statuses; $this->json['defaultValue'] = $this->setting->default; } /** * Don't render the control content from PHP, as it's rendered via JS on load. * * @since 3.4.0 */ public function render_content() {} /** * Render a JS template for the content of the color picker control. * * @since 4.1.0 */ public function content_template() { ?> <# var defaultValue = ''; if ( data.defaultValue ) { if ( '#' !== data.defaultValue.substring( 0, 1 ) ) { defaultValue = '#' + data.defaultValue; } else { defaultValue = data.defaultValue; } defaultValue = ' data-default-color=' + defaultValue; // Quotes added automatically. } #> button_labels = array( 'select' => __( 'Select File' ), 'change' => __( 'Change File' ), 'default' => __( 'Default' ), 'remove' => __( 'Remove' ), 'placeholder' => __( 'No file selected' ), 'frame_title' => __( 'Select File' ), 'frame_button' => __( 'Choose File' ), ); } /** * Enqueue control related scripts/styles. * * @since 3.4.0 * @since 4.2.0 Moved from WP_Customize_Upload_Control. */ public function enqueue() { wp_enqueue_media(); } /** * Refresh the parameters passed to the JavaScript via JSON. * * @since 3.4.0 * @since 4.2.0 Moved from WP_Customize_Upload_Control. * * @see WP_Customize_Control::to_json() */ public function to_json() { parent::to_json(); $this->json['label'] = html_entity_decode( $this->label, ENT_QUOTES, get_bloginfo( 'charset' ) ); $this->json['mime_type'] = $this->mime_type; $this->json['button_labels'] = $this->button_labels; $this->json['canUpload'] = current_user_can( 'upload_files' ); $value = $this->value(); if ( is_object( $this->setting ) ) { if ( $this->setting->default ) { // Fake an attachment model - needs all fields used by template. // Note that the default value must be a URL, NOT an attachment ID. $type = in_array( substr( $this->setting->default, -3 ), array( 'jpg', 'png', 'gif', 'bmp' ) ) ? 'image' : 'document'; $default_attachment = array( 'id' => 1, 'url' => $this->setting->default, 'type' => $type, 'icon' => wp_mime_type_icon( $type ), 'title' => basename( $this->setting->default ), ); if ( 'image' === $type ) { $default_attachment['sizes'] = array( 'full' => array( 'url' => $this->setting->default ), ); } $this->json['defaultAttachment'] = $default_attachment; } if ( $value && $this->setting->default && $value === $this->setting->default ) { // Set the default as the attachment. $this->json['attachment'] = $this->json['defaultAttachment']; } elseif ( $value ) { $this->json['attachment'] = wp_prepare_attachment_for_js( $value ); } } } /** * Don't render any content for this control from PHP. * * @since 3.4.0 * @since 4.2.0 Moved from WP_Customize_Upload_Control. * * @see WP_Customize_Media_Control::content_template() */ public function render_content() {} /** * Render a JS template for the content of the media control. * * @since 4.1.0 * @since 4.2.0 Moved from WP_Customize_Upload_Control. */ public function content_template() { ?> <# if ( data.attachment && data.attachment.id ) { #>
    <# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #> <# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #> <# } else if ( 'audio' === data.attachment.type ) { #> <# if ( data.attachment.image && data.attachment.image.src && data.attachment.image.src !== data.attachment.icon ) { #> <# } else { #> <# } #>

    “{{ data.attachment.title }}”

    <# if ( data.attachment.album || data.attachment.meta.album ) { #>

    {{ data.attachment.album || data.attachment.meta.album }}

    <# } #> <# if ( data.attachment.artist || data.attachment.meta.artist ) { #>

    {{ data.attachment.artist || data.attachment.meta.artist }}

    <# } #> <# } else if ( 'video' === data.attachment.type ) { #>
    <# } else { #>

    {{ data.attachment.title }}

    <# } #>
    <# if ( data.canUpload ) { #>
    <# } #>
    <# } else { #>
    button_labels['placeholder']; ?>
    <# if ( data.defaultAttachment ) { #> <# } #> <# if ( data.canUpload ) { #> <# } #>
    <# } #> value(); if ( $value ) { // Get the attachment model for the existing file. $attachment_id = attachment_url_to_postid( $value ); if ( $attachment_id ) { $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id ); } } } } /** * Customize Image Control class. * * @since 3.4.0 * * @see WP_Customize_Upload_Control */ class WP_Customize_Image_Control extends WP_Customize_Upload_Control { public $type = 'image'; public $mime_type = 'image'; /** * Constructor. * * @since 3.4.0 * @uses WP_Customize_Upload_Control::__construct() * * @param WP_Customize_Manager $manager * @param string $id * @param array $args */ public function __construct( $manager, $id, $args = array() ) { parent::__construct( $manager, $id, $args ); $this->button_labels = array( 'select' => __( 'Select Image' ), 'change' => __( 'Change Image' ), 'remove' => __( 'Remove' ), 'default' => __( 'Default' ), 'placeholder' => __( 'No image selected' ), 'frame_title' => __( 'Select Image' ), 'frame_button' => __( 'Choose Image' ), ); } /** * @since 3.4.2 * @deprecated 4.1.0 */ public function prepare_control() {} /** * @since 3.4.0 * @deprecated 4.1.0 * * @param string $id * @param string $label * @param mixed $callback */ public function add_tab( $id, $label, $callback ) {} /** * @since 3.4.0 * @deprecated 4.1.0 * * @param string $id */ public function remove_tab( $id ) {} /** * @since 3.4.0 * @deprecated 4.1.0 * * @param string $url * @param string $thumbnail_url */ public function print_tab_image( $url, $thumbnail_url = null ) {} } /** * Customize Background Image Control class. * * @since 3.4.0 * * @see WP_Customize_Image_Control */ class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control { public $type = 'background'; /** * Constructor. * * @since 3.4.0 * @uses WP_Customize_Image_Control::__construct() * * @param WP_Customize_Manager $manager */ public function __construct( $manager ) { parent::__construct( $manager, 'background_image', array( 'label' => __( 'Background Image' ), 'section' => 'background_image', ) ); } /** * Enqueue control related scripts/styles. * * @since 4.1.0 */ public function enqueue() { parent::enqueue(); wp_localize_script( 'customize-controls', '_wpCustomizeBackground', array( 'nonces' => array( 'add' => wp_create_nonce( 'background-add' ), ), ) ); } } /** * Customize Cropped Image Control class. * * @since 4.3.0 * * @see WP_Customize_Image_Control */ class WP_Customize_Cropped_Image_Control extends WP_Customize_Image_Control { /** * Control type. * * @since 4.3.0 * @access public * @var string */ public $type = 'cropped_image'; /** * Suggested width for cropped image. * * @since 4.3.0 * @access public * @var int */ public $width = 150; /** * Suggested height for cropped image. * * @since 4.3.0 * @access public * @var int */ public $height = 150; /** * Whether the width is flexible. * * @since 4.3.0 * @access public * @var bool */ public $flex_width = false; /** * Whether the height is flexible. * * @since 4.3.0 * @access public * @var bool */ public $flex_height = false; /** * Enqueue control related scripts/styles. * * @since 4.3.0 * @access public */ public function enqueue() { wp_enqueue_script( 'customize-views' ); parent::enqueue(); } /** * Refresh the parameters passed to the JavaScript via JSON. * * @since 4.3.0 * @access public * * @see WP_Customize_Control::to_json() */ public function to_json() { parent::to_json(); $this->json['width'] = absint( $this->width ); $this->json['height'] = absint( $this->height ); $this->json['flex_width'] = absint( $this->flex_width ); $this->json['flex_height'] = absint( $this->flex_height ); } } /** * Customize Site Icon control class. * * Used only for custom functionality in JavaScript. * * @since 4.3.0 * * @see WP_Customize_Cropped_Image_Control */ class WP_Customize_Site_Icon_Control extends WP_Customize_Cropped_Image_Control { /** * Control type. * * @since 4.3.0 * @access public * @var string */ public $type = 'site_icon'; /** * Constructor. * * @since 4.3.0 * @access public * * @param WP_Customize_Manager $manager WP_Customize_Manager instance. * @param string $id Control ID. * @param array $args Optional. Arguments to override class property defaults. */ public function __construct( $manager, $id, $args = array() ) { parent::__construct( $manager, $id, $args ); add_action( 'customize_controls_print_styles', 'wp_site_icon', 99 ); } } /** * Customize Header Image Control class. * * @since 3.4.0 * * @see WP_Customize_Image_Control */ class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control { public $type = 'header'; public $uploaded_headers; public $default_headers; /** * @param WP_Customize_Manager $manager */ public function __construct( $manager ) { parent::__construct( $manager, 'header_image', array( 'label' => __( 'Header Image' ), 'settings' => array( 'default' => 'header_image', 'data' => 'header_image_data', ), 'section' => 'header_image', 'removed' => 'remove-header', 'get_url' => 'get_header_image', ) ); } /** * @access public */ public function enqueue() { wp_enqueue_media(); wp_enqueue_script( 'customize-views' ); $this->prepare_control(); wp_localize_script( 'customize-views', '_wpCustomizeHeader', array( 'data' => array( 'width' => absint( get_theme_support( 'custom-header', 'width' ) ), 'height' => absint( get_theme_support( 'custom-header', 'height' ) ), 'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ), 'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ), 'currentImgSrc' => $this->get_current_image_src(), ), 'nonces' => array( 'add' => wp_create_nonce( 'header-add' ), 'remove' => wp_create_nonce( 'header-remove' ), ), 'uploads' => $this->uploaded_headers, 'defaults' => $this->default_headers ) ); parent::enqueue(); } /** * * @global Custom_Image_Header $custom_image_header */ public function prepare_control() { global $custom_image_header; if ( empty( $custom_image_header ) ) { return; } // Process default headers and uploaded headers. $custom_image_header->process_default_headers(); $this->default_headers = $custom_image_header->get_default_header_images(); $this->uploaded_headers = $custom_image_header->get_uploaded_header_images(); } /** * @access public */ public function print_header_image_template() { ?> value(); if ( isset( $this->get_url ) ) { $src = call_user_func( $this->get_url, $src ); return $src; } } /** * @access public */ public function render_content() { $this->print_header_image_template(); $visibility = $this->get_current_image_src() ? '' : ' style="display:none" '; $width = absint( get_theme_support( 'custom-header', 'width' ) ); $height = absint( get_theme_support( 'custom-header', 'height' ) ); ?>

    Add new image, your theme recommends a header size of %s × %s pixels.' ), $width, $height ); } elseif ( $width ) { printf( __( 'While you can crop images to your liking after clicking Add new image, your theme recommends a header width of %s pixels.' ), $width ); } else { printf( __( 'While you can crop images to your liking after clicking Add new image, your theme recommends a header height of %s pixels.' ), $height ); } ?>

    json['theme'] = $this->theme; } /** * Don't render the control content from PHP, as it's rendered via JS on load. * * @since 4.2.0 * @access public */ public function render_content() {} /** * Render a JS template for theme display. * * @since 4.2.0 * @access public */ public function content_template() { $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); $active_url = esc_url( remove_query_arg( 'theme', $current_url ) ); $preview_url = esc_url( add_query_arg( 'theme', '__THEME__', $current_url ) ); // Token because esc_url() strips curly braces. $preview_url = str_replace( '__THEME__', '{{ data.theme.id }}', $preview_url ); ?> <# if ( data.theme.isActiveTheme ) { #>
    <# } else { #>
    <# } #> <# if ( data.theme.screenshot[0] ) { #>
    <# } else { #>
    <# } #> <# if ( data.theme.isActiveTheme ) { #> <# } else { #> <# } #>
    <# if ( data.theme.isActiveTheme ) { #>

    Active: %s' ), '{{ data.theme.name }}' ); ?>

    <# } else { #>

    {{ data.theme.name }}

    <# } #>
    json[ $key ] = $this->$key; } } /** * @access public */ public function render_content() { ?> json[ $key ] = $this->$key; } } /** * * @global array $wp_registered_widgets */ public function render_content() { global $wp_registered_widgets; require_once ABSPATH . '/wp-admin/includes/widgets.php'; $widget = $wp_registered_widgets[ $this->widget_id ]; if ( ! isset( $widget['params'][0] ) ) { $widget['params'][0] = array(); } $args = array( 'widget_id' => $widget['id'], 'widget_name' => $widget['name'], ); $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) ); echo $this->manager->widgets->get_widget_control( $args ); } /** * Whether the current widget is rendered on the page. * * @since 4.0.0 * @access public * * @return bool Whether the widget is rendered. */ public function active_callback() { return $this->manager->widgets->is_widget_rendered( $this->widget_id ); } } /** * Customize Nav Menu Control Class. * * @since 4.3.0 */ class WP_Customize_Nav_Menu_Control extends WP_Customize_Control { /** * Control type. * * @since 4.3.0 * @access public * @var string */ public $type = 'nav_menu'; /** * The nav menu setting. * * @since 4.3.0 * @access public * @var WP_Customize_Nav_Menu_Setting */ public $setting; /** * Don't render the control's content - it uses a JS template instead. * * @since 4.3.0 * @access public */ public function render_content() {} /** * JS/Underscore template for the control UI. * * @since 4.3.0 * @access public */ public function content_template() { ?>

    setting->term_id; return $exported; } } /** * Customize control to represent the name field for a given menu. * * @since 4.3.0 */ class WP_Customize_Nav_Menu_Item_Control extends WP_Customize_Control { /** * Control type. * * @since 4.3.0 * @access public * @var string */ public $type = 'nav_menu_item'; /** * The nav menu item setting. * * @since 4.3.0 * @access public * @var WP_Customize_Nav_Menu_Item_Setting */ public $setting; /** * Constructor. * * @since 4.3.0 * @access public * * @see WP_Customize_Control::__construct() * * @param WP_Customize_Manager $manager An instance of the WP_Customize_Manager class. * @param string $id The control ID. * @param array $args Optional. Overrides class property defaults. */ public function __construct( $manager, $id, $args = array() ) { parent::__construct( $manager, $id, $args ); } /** * Don't render the control's content - it's rendered with a JS template. * * @since 4.3.0 * @access public */ public function render_content() {} /** * JS/Underscore template for the control UI. * * @since 4.3.0 * @access public */ public function content_template() { ?> setting->post_id; return $exported; } } /** * Customize Menu Location Control Class. * * This custom control is only needed for JS. * * @since 4.3.0 * * @see WP_Customize_Control */ class WP_Customize_Nav_Menu_Location_Control extends WP_Customize_Control { /** * Control type. * * @since 4.3.0 * @access public * @var string */ public $type = 'nav_menu_location'; /** * Location ID. * * @since 4.3.0 * @access public * @var string */ public $location_id = ''; /** * Refresh the parameters passed to JavaScript via JSON. * * @since 4.3.0 * @access public * * @see WP_Customize_Control::to_json() */ public function to_json() { parent::to_json(); $this->json['locationId'] = $this->location_id; } /** * Render content just like a normal select control. * * @since 4.3.0 * @access public */ public function render_content() { if ( empty( $this->choices ) ) { return; } ?>