diff --git a/wp-admin/custom-background.php b/wp-admin/custom-background.php index b7d8be8506..aa2d55a6e6 100644 --- a/wp-admin/custom-background.php +++ b/wp-admin/custom-background.php @@ -383,10 +383,10 @@ if ( get_background_image() ) { wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) ); update_post_meta( $id, '_wp_attachment_is_custom_background', get_option('stylesheet' ) ); - set_theme_mod('background_image', esc_url($url)); + set_theme_mod('background_image', esc_url_raw($url)); $thumbnail = wp_get_attachment_image_src( $id, 'thumbnail' ); - set_theme_mod('background_image_thumb', esc_url( $thumbnail[0] ) ); + set_theme_mod('background_image_thumb', esc_url_raw( $thumbnail[0] ) ); do_action('wp_create_file_in_uploads', $file, $id); // For replication $this->updated = true; @@ -425,8 +425,8 @@ if ( get_background_image() ) { update_post_meta( $attachment_id, '_wp_attachment_is_custom_background', get_option('stylesheet' ) ); $url = wp_get_attachment_image_src( $attachment_id, $size ); $thumbnail = wp_get_attachment_image_src( $attachment_id, 'thumbnail' ); - set_theme_mod( 'background_image', esc_url( $url[0] ) ); - set_theme_mod( 'background_image_thumb', esc_url( $thumbnail[0] ) ); + set_theme_mod( 'background_image', esc_url_raw( $url[0] ) ); + set_theme_mod( 'background_image_thumb', esc_url_raw( $thumbnail[0] ) ); exit; } } diff --git a/wp-admin/custom-header.php b/wp-admin/custom-header.php index b136dfa275..fc9d4f126f 100644 --- a/wp-admin/custom-header.php +++ b/wp-admin/custom-header.php @@ -211,21 +211,7 @@ class Custom_Image_Header { if ( isset( $_POST['resetheader'] ) ) { check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' ); - $this->process_default_headers(); - $default = get_theme_support( 'custom-header', 'default-image' ); - $default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() ); - foreach ( $this->default_headers as $header => $details ) { - if ( $details['url'] == $default ) { - $default_data = $details; - break; - } - } - set_theme_mod( 'header_image', $default ); - if ( empty( $default_data['width'] ) ) - $default_data['width'] = get_theme_support( 'custom-header', 'width' ); - if ( empty( $default_data['height'] ) ) - $default_data['height'] = get_theme_support( 'custom-header', 'height' ); - set_theme_mod( 'header_image_data', (object) $default_data ); + $this->reset_header_image(); return; } @@ -237,7 +223,7 @@ class Custom_Image_Header { if ( isset( $_POST['removeheader'] ) ) { check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' ); - set_theme_mod( 'header_image', 'remove-header' ); + $this->remove_header_image(); return; } @@ -256,25 +242,8 @@ class Custom_Image_Header { if ( isset( $_POST['default-header'] ) ) { check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' ); - if ( 'random-default-image' == $_POST['default-header'] ) { - set_theme_mod( 'header_image', 'random-default-image' ); - } elseif ( 'random-uploaded-image' == $_POST['default-header'] ) { - set_theme_mod( 'header_image', 'random-uploaded-image' ); - } else { - $this->process_default_headers(); - $uploaded = get_uploaded_header_images(); - if ( isset( $uploaded[$_POST['default-header']] ) ) { - set_theme_mod( 'header_image', esc_url( $uploaded[$_POST['default-header']]['url'] ) ); - set_theme_mod( 'header_image_data', (object) $uploaded[$_POST['default-header']] ); - } elseif ( isset( $this->default_headers[$_POST['default-header']] ) ) { - set_theme_mod( 'header_image', esc_url( $this->default_headers[$_POST['default-header']]['url'] ) ); - if ( empty( $this->default_headers[$_POST['default-header']]['width'] ) ) - $this->default_headers[$_POST['default-header']]['width'] = get_theme_support( 'custom-header', 'width' ); - if ( empty( $this->default_headers[$_POST['default-header']]['height'] ) ) - $this->default_headers[$_POST['default-header']]['height'] = get_theme_support( 'custom-header', 'height' ); - set_theme_mod( 'header_image_data', (object) $this->default_headers[$_POST['default-header']] ); - } - } + $this->set_header_image( $_POST['default-header'] ); + return; } } @@ -718,9 +687,9 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?> wp_die( __( 'Cheatin’ uh?' ) ); if ( empty( $_POST ) && isset( $_GET['file'] ) ) { - $id = absint( $_GET['file'] ); - $file = get_attached_file( $id, true ); - $url = wp_get_attachment_image_src( $id, 'full'); + $attachment_id = absint( $_GET['file'] ); + $file = get_attached_file( $attachment_id, true ); + $url = wp_get_attachment_image_src( $attachment_id, 'full'); $url = $url[0]; } elseif ( isset( $_POST ) ) { extract($this->step_2_manage_upload()); @@ -729,7 +698,7 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?> if ( file_exists( $file ) ) { list( $width, $height, $type, $attr ) = getimagesize( $file ); } else { - $data = wp_get_attachment_metadata( $id ); + $data = wp_get_attachment_metadata( $attachment_id ); $height = $data[ 'height' ]; $width = $data[ 'width' ]; unset( $data ); @@ -750,19 +719,19 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?> { // Add the meta-data if ( file_exists( $file ) ) - wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) ); - update_post_meta( $id, '_wp_attachment_is_custom_header', get_option('stylesheet' ) ); + wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) ); - set_theme_mod('header_image', esc_url($url)); - do_action('wp_create_file_in_uploads', $file, $id); // For replication + $this->set_header_image( compact( 'url', 'attachment_id', 'width', 'height' ) ); + + do_action('wp_create_file_in_uploads', $file, $attachment_id); // For replication return $this->finished(); } elseif ( $width > $max_width ) { $oitar = $width / $max_width; - $image = wp_crop_image($id, 0, 0, $width, $height, $max_width, $height / $oitar, false, str_replace(basename($file), 'midsize-'.basename($file), $file)); + $image = wp_crop_image($attachment_id, 0, 0, $width, $height, $max_width, $height / $oitar, false, str_replace(basename($file), 'midsize-'.basename($file), $file)); if ( ! $image || is_wp_error( $image ) ) wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) ); - $image = apply_filters('wp_create_file_in_uploads', $image, $id); // For replication + $image = apply_filters('wp_create_file_in_uploads', $image, $attachment_id); // For replication $url = str_replace(basename($url), basename($image), $url); $width = $width / $oitar; @@ -788,7 +757,7 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?> - + @@ -835,8 +804,8 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?> ); // Save the data - $id = wp_insert_attachment( $object, $file ); - return compact( 'id', 'file', 'filename', 'url', 'type' ); + $attachment_id = wp_insert_attachment( $object, $file ); + return compact( 'attachment_id', 'file', 'filename', 'url', 'type' ); } /** @@ -918,18 +887,10 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?> // Update the attachment $attachment_id = wp_insert_attachment( $object, $cropped ); wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $cropped ) ); - update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', get_option( 'stylesheet' ) ); - set_theme_mod('header_image', $url); - - $header_data = new stdClass(); - $header_data->attachment_id = $attachment_id; - $header_data->url = $url; - $header_data->thumbnail_url = $url; - $header_data->width = $dst_width; - $header_data->height = $dst_height; - - set_theme_mod( 'header_image_data', $header_data ); + $width = $dst_width; + $height = $dst_height; + $this->set_header_image( compact( 'url', 'attachment_id', 'width', 'height' ) ); // cleanup $medium = str_replace( basename( $original ), 'midsize-' . basename( $original ), $original ); @@ -997,4 +958,95 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?> return array( 'library' => __('Media Library') ); } + /** + * Choose a header image, selected from existing uploaded and default headers, + * or provide an array of uploaded header data (either new, or from media library). + * + * @param mixed $choice Which header image to select. Allows for values of 'random-default-image', + * for randomly cycling among the default images; 'random-uploaded-image', for randomly cycling + * among the uploaded images; the key of a default image registered for that theme; and + * the key of an image uploaded for that theme (the basename of the URL). + * Or an array of arguments: attachment_id, url, width, height. All are required. + * + * @since 3.4.0 + */ + final public function set_header_image( $choice ) { + if ( is_array( $choice ) || is_object( $choice ) ) { + $choice = (array) $choice; + if ( ! isset( $choice['attachment_id'] ) || ! isset( $choice['url'] ) ) + return; + + $choice['url'] = esc_url_raw( $choice['url'] ); + + $header_image_data = (object) array( + 'attachment_id' => $choice['attachment_id'], + 'url' => $choice['url'], + 'thumbnail_url' => $choice['url'], + 'height' => $choice['height'], + 'width' => $choice['width'], + ); + + update_post_meta( $choice['attachment_id'], '_wp_attachment_is_custom_header', get_stylesheet() ); + set_theme_mod( 'header_image', $choice['url'] ); + set_theme_mod( 'header_image_data', $header_image_data ); + return; + } + + if ( in_array( $choice, array( 'remove-header', 'random-default-image', 'random-uploaded-image' ) ) ) { + set_theme_mod( 'header_image', $choice ); + remove_theme_mod( 'header_image_data' ); + return; + } + + $uploaded = get_uploaded_header_images(); + if ( $uploaded && isset( $uploaded[ $choice ] ) ) { + $header_image_data = $uploaded[ $choice ]; + + } else { + $this->process_default_headers(); + if ( isset( $this->default_headers[ $choice ] ) ) + $header_image_data = $this->default_headers[ $choice ]; + else + return; + } + + set_theme_mod( 'header_image', esc_url_raw( $header_image_data['url'] ) ); + set_theme_mod( 'header_image_data', $header_image_data ); + } + + /** + * Remove a header image. + * + * @since 3.4.0 + */ + final public function remove_header_image() { + return $this->set_header_image( 'remove-header' ); + } + + /** + * Reset a header image to the default image for the theme. + * + * This method does not do anything if the theme does not have a default header image. + * + * @since 3.4.0 + */ + final public function reset_header_image() { + $this->process_default_headers(); + $default = get_theme_support( 'custom-header', 'default-image' ); + + if ( ! $default ) + return $this->remove_header_image(); + + $default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() ); + + foreach ( $this->default_headers as $header => $details ) { + if ( $details['url'] == $default ) { + $default_data = $details; + break; + } + } + + set_theme_mod( 'header_image', $default ); + set_theme_mod( 'header_image_data', (object) $default_data ); + } } diff --git a/wp-admin/js/customize-controls.dev.js b/wp-admin/js/customize-controls.dev.js index eedb03fb14..1318e26c79 100644 --- a/wp-admin/js/customize-controls.dev.js +++ b/wp-admin/js/customize-controls.dev.js @@ -239,6 +239,7 @@ control.selected.both.addClass('library-selected'); }); + // Bind events to switch image urls. this.library.on( 'click', 'a', function( event ) { var value = $(this).data('customizeImageValue'); @@ -263,7 +264,7 @@ if ( this.tabs.uploaded && this.tabs.uploaded.target.length ) { this.tabs.uploaded.both.removeClass('hidden'); - $( '' ) + attachment.element = $( '' ) .data( 'customizeImageValue', attachment.url ) .append( '' ) .appendTo( this.tabs.uploaded.target ); @@ -868,6 +869,35 @@ }); }); + // Handle header image data + api.control( 'header_image', function( control ) { + control.setting.bind( function( to ) { + if ( to === control.params.removed ) + control.settings.data.set( false ); + }); + + control.library.on( 'click', 'a', function( event ) { + control.settings.data.set( $(this).data('customizeHeaderImageData') ); + }); + + control.uploader.success = function( attachment ) { + var data; + + api.ImageControl.prototype.success.call( control, attachment ); + + data = { + attachment_id: attachment.id, + url: attachment.url, + thumbnail_url: attachment.url, + height: attachment.meta.height, + width: attachment.meta.width + }; + + attachment.element.data( 'customizeHeaderImageData', data ); + control.settings.data.set( data ); + } + }); + api.trigger( 'ready' ); }); diff --git a/wp-includes/class-wp-customize-control.php b/wp-includes/class-wp-customize-control.php index 9b4aa44adb..5ded24ca16 100644 --- a/wp-includes/class-wp-customize-control.php +++ b/wp-includes/class-wp-customize-control.php @@ -11,8 +11,11 @@ class WP_Customize_Control { public $manager; public $id; + // All settings tied to the control. public $settings; - public $setting; + + // The primary setting for the control (if there is one). + public $setting = 'default'; public $priority = 10; public $section = ''; @@ -455,6 +458,10 @@ class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control { 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', 'context' => 'custom-header', 'removed' => 'remove-header', @@ -470,20 +477,40 @@ class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control { $this->add_tab( 'default', __('Default'), array( $this, 'tab_default_headers' ) ); } + public function print_header_image( $choice, $header ) { + $header['url'] = set_url_scheme( $header['url'] ); + $header['thumbnail_url'] = set_url_scheme( $header['thumbnail_url'] ); + + $header_image_data = array( 'choice' => $choice ); + foreach ( array( 'attachment_id', 'width', 'height', 'url', 'thumbnail_url' ) as $key ) { + if ( isset( $header[ $key ] ) ) + $header_image_data[ $key ] = $header[ $key ]; + } + + + ?> + + + +
print_tab_image( $header['url'], $header['thumbnail_url'] ); + foreach ( $headers as $choice => $header ) + $this->print_header_image( $choice, $header ); } public function tab_default_headers() { global $custom_image_header; $custom_image_header->process_default_headers(); - foreach ( $custom_image_header->default_headers as $header ) - $this->print_tab_image( $header['url'], $header['thumbnail_url'] ); + foreach ( $custom_image_header->default_headers as $choice => $header ) + $this->print_header_image( $choice, $header ); } } \ No newline at end of file diff --git a/wp-includes/class-wp-customize-manager.php b/wp-includes/class-wp-customize-manager.php index d7be722f0d..feb67d1fdc 100644 --- a/wp-includes/class-wp-customize-manager.php +++ b/wp-includes/class-wp-customize-manager.php @@ -756,10 +756,15 @@ final class WP_Customize_Manager { 'priority' => 60, ) ); - $this->add_setting( 'header_image', array( + $this->add_setting( new WP_Customize_Filter_Setting( $this, 'header_image', array( 'default' => get_theme_support( 'custom-header', 'default-image' ), 'theme_supports' => 'custom-header', - ) ); + ) ) ); + + $this->add_setting( new WP_Customize_Header_Image_Setting( $this, 'header_image_data', array( + // 'default' => get_theme_support( 'custom-header', 'default-image' ), + 'theme_supports' => 'custom-header', + ) ) ); $this->add_control( new WP_Customize_Header_Image_Control( $this ) ); diff --git a/wp-includes/class-wp-customize-setting.php b/wp-includes/class-wp-customize-setting.php index 92584f0639..b5873d83f1 100644 --- a/wp-includes/class-wp-customize-setting.php +++ b/wp-includes/class-wp-customize-setting.php @@ -367,3 +367,35 @@ class WP_Customize_Setting { return isset( $result ); } } + +/** + * A setting that is used to filter a value, but will not save the results. + * + * Results should be properly handled using another setting or callback. + */ +class WP_Customize_Filter_Setting extends WP_Customize_Setting { + public function update() {} +} + +/** + * A setting that is used to filter a value, but will not save the results. + * + * Results should be properly handled using another setting or callback. + */ +class WP_Customize_Header_Image_Setting extends WP_Customize_Setting { + public $id = 'header_image_data'; + + public function update( $value ) { + global $custom_image_header; + + // If the value doesn't exist (removed or random), + // use the header_image value. + if ( ! $value ) + $value = $this->manager->get_setting('header_image')->post_value(); + + if ( is_array( $value ) && isset( $value['choice'] ) ) + $custom_image_header->set_header_image( $value['choice'] ); + else + $custom_image_header->set_header_image( $value ); + } +} \ No newline at end of file