<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[19815] trunk: Allow flexible sizes for custom header uploads.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg > ul, #logmsg > ol { margin-left: 0; margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://core.trac.wordpress.org/changeset/19815">19815</a></dd>
<dt>Author</dt> <dd>ryan</dd>
<dt>Date</dt> <dd>2012-02-02 23:35:37 +0000 (Thu, 02 Feb 2012)</dd>
</dl>
<h3>Log Message</h3>
<pre>Allow flexible sizes for custom header uploads. Round 1. Props aaroncampbell, sabreuse. see <a href="http://core.trac.wordpress.org/ticket/17242">#17242</a></pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpadmincsswpadmindevcss">trunk/wp-admin/css/wp-admin.dev.css</a></li>
<li><a href="#trunkwpadmincustomheaderphp">trunk/wp-admin/custom-header.php</a></li>
<li><a href="#trunkwpincludesthemephp">trunk/wp-includes/theme.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpadmincsswpadmindevcss"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/css/wp-admin.dev.css (19814 => 19815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/css/wp-admin.dev.css        2012-02-01 22:41:34 UTC (rev 19814)
+++ trunk/wp-admin/css/wp-admin.dev.css        2012-02-02 23:35:37 UTC (rev 19815)
</span><span class="lines">@@ -4494,7 +4494,6 @@
</span><span class="cx">
</span><span class="cx"> .appearance_page_custom-header #headimg {
</span><span class="cx">         border: 1px solid #DFDFDF;
</span><del>-        min-height: 100px;
</del><span class="cx">         width: 100%;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkwpadmincustomheaderphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/custom-header.php (19814 => 19815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/custom-header.php        2012-02-01 22:41:34 UTC (rev 19814)
+++ trunk/wp-admin/custom-header.php        2012-02-02 23:35:37 UTC (rev 19815)
</span><span class="lines">@@ -188,7 +188,21 @@
</span><span class="cx">
</span><span class="cx">                 if ( isset( $_POST['resetheader'] ) ) {
</span><span class="cx">                         check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' );
</span><del>-                        remove_theme_mod( 'header_image' );
</del><ins>+                        $this->process_default_headers();
+                        $default = defined( 'HEADER_IMAGE' ) ? 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 );
+                        if ( empty( $default_data['width'] ) )
+                                $default_data['width'] = HEADER_IMAGE_WIDTH;
+                        if ( empty( $default_data['height'] ) )
+                                $default_data['height'] = HEADER_IMAGE_HEIGHT;
+                        set_theme_mod( 'header_image_data', (object) $default_data );
</ins><span class="cx">                         return;
</span><span class="cx">                 }
</span><span class="cx">
</span><span class="lines">@@ -225,10 +239,17 @@
</span><span class="cx">                         } else {
</span><span class="cx">                                 $this->process_default_headers();
</span><span class="cx">                                 $uploaded = get_uploaded_header_images();
</span><del>-                                if ( isset( $uploaded[$_POST['default-header']] ) )
</del><ins>+                                if ( isset( $uploaded[$_POST['default-header']] ) ) {
</ins><span class="cx">                                         set_theme_mod( 'header_image', esc_url( $uploaded[$_POST['default-header']]['url'] ) );
</span><del>-                                elseif ( isset( $this->default_headers[$_POST['default-header']] ) )
</del><ins>+                                        set_theme_mod( 'header_image_data', (object) $uploaded[$_POST['default-header']] );
+                                } elseif ( isset( $this->default_headers[$_POST['default-header']] ) ) {
</ins><span class="cx">                                         set_theme_mod( 'header_image', esc_url( $this->default_headers[$_POST['default-header']]['url'] ) );
</span><ins>+                                        if ( empty( $this->default_headers[$_POST['default-header']]['width'] ) )
+                                                $this->default_headers[$_POST['default-header']]['width'] = HEADER_IMAGE_WIDTH;
+                                        if ( empty( $this->default_headers[$_POST['default-header']]['height'] ) )
+                                                $this->default_headers[$_POST['default-header']]['height'] = HEADER_IMAGE_HEIGHT;
+                                        set_theme_mod( 'header_image_data', (object) $this->default_headers[$_POST['default-header']] );
+                                }
</ins><span class="cx">                         }
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="lines">@@ -289,7 +310,7 @@
</span><span class="cx">                         echo '<div class="default-header">';
</span><span class="cx">                         echo '<label><input name="default-header" type="radio" value="' . esc_attr( $header_key ) . '" ' . checked( $header_url, get_theme_mod( 'header_image' ), false ) . ' />';
</span><span class="cx">                         $width = '';
</span><del>-                        if ( !empty( $header['uploaded'] ) )
</del><ins>+                        if ( !empty( $header['attachment_id'] ) )
</ins><span class="cx">                                 $width = ' width="230"';
</span><span class="cx">                         echo '<img src="' . $header_thumbnail . '" alt="' . esc_attr( $header_desc ) .'" title="' . esc_attr( $header_desc ) . '"' . $width . ' /></label>';
</span><span class="cx">                         echo '</div>';
</span><span class="lines">@@ -419,8 +440,17 @@
</span><span class="cx">         }
</span><span class="cx">
</span><span class="cx">         jQuery(document).ready(function() {
</span><del>-                var xinit = <?php echo HEADER_IMAGE_WIDTH; ?>;
-                var yinit = <?php echo HEADER_IMAGE_HEIGHT; ?>;
</del><ins>+                <?php
+                $xinit = HEADER_IMAGE_WIDTH;
+                $yinit = HEADER_IMAGE_HEIGHT;
+                $header_support = get_theme_support( 'custom-header' );
+                if ( !empty( $header_support[ 0 ][ 'suggested-width' ] ) )
+                        $xinit = $header_support[ 0 ][ 'suggested-width' ];
+                if ( !empty( $header_support[ 0 ][ 'suggested-height' ] ) )
+                        $yinit = $header_support[ 0 ][ 'suggested-height' ];
+                ?>
+                var xinit = <?php echo absint( $xinit ); ?>;
+                var yinit = <?php echo absint( $yinit ); ?>;
</ins><span class="cx">                 var ratio = xinit / yinit;
</span><span class="cx">                 var ximg = jQuery('img#upload').width();
</span><span class="cx">                 var yimg = jQuery('img#upload').height();
</span><span class="lines">@@ -438,14 +468,28 @@
</span><span class="cx">                 jQuery('img#upload').imgAreaSelect({
</span><span class="cx">                         handles: true,
</span><span class="cx">                         keys: true,
</span><del>-                        aspectRatio: xinit + ':' + yinit,
</del><span class="cx">                         show: true,
</span><span class="cx">                         x1: 0,
</span><span class="cx">                         y1: 0,
</span><span class="cx">                         x2: xinit,
</span><span class="cx">                         y2: yinit,
</span><ins>+                        <?php
+                        if ( ! current_theme_supports( 'custom-header', 'flex-height' ) && ! current_theme_supports( 'custom-header', 'flex-width' ) ) {
+                        ?>
+                        aspectRatio: xinit + ':' + yinit,
+                        <?php
+                        }
+                        if ( ! current_theme_supports( 'custom-header', 'flex-height' ) ) {
+                        ?>
</ins><span class="cx">                         maxHeight: <?php echo HEADER_IMAGE_HEIGHT; ?>,
</span><ins>+                        <?php
+                        }
+                        if ( ! current_theme_supports( 'custom-header', 'flex-width' ) ) {
+                        ?>
</ins><span class="cx">                         maxWidth: <?php echo HEADER_IMAGE_WIDTH; ?>,
</span><ins>+                        <?php
+                        }
+                        ?>
</ins><span class="cx">                         onInit: function () {
</span><span class="cx">                                 jQuery('#width').val(xinit);
</span><span class="cx">                                 jQuery('#height').val(yinit);
</span><span class="lines">@@ -492,7 +536,7 @@
</span><span class="cx">          call_user_func( $this->admin_image_div_callback );
</span><span class="cx">         } else {
</span><span class="cx">         ?>
</span><del>-        <div id="headimg" style="max-width:<?php echo HEADER_IMAGE_WIDTH; ?>px;height:<?php echo HEADER_IMAGE_HEIGHT; ?>px;background-image:url(<?php esc_url ( header_image() ) ?>);">
</del><ins>+        <div id="headimg" style="background-image:url(<?php esc_url ( header_image() ) ?>);max-width:<?php echo get_header_image_width(); ?>px;height:<?php echo get_header_image_height(); ?>px;">
</ins><span class="cx">                 <?php
</span><span class="cx">                 if ( 'blank' == get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) || '' == get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) || ! $this->header_text() )
</span><span class="cx">                         $style = ' style="display:none;"';
</span><span class="lines">@@ -510,7 +554,24 @@
</span><span class="cx"> <th scope="row"><?php _e( 'Upload Image' ); ?></th>
</span><span class="cx"> <td>
</span><span class="cx">         <p><?php _e( 'You can upload a custom header image to be shown at the top of your site instead of the default one. On the next screen you will be able to crop the image.' ); ?><br />
</span><del>-        <?php printf( __( 'Images of exactly <strong>%1$d &times; %2$d pixels</strong> will be used as-is.' ), HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT ); ?></p>
</del><ins>+        <?php
+        if ( ! current_theme_supports( 'custom-header', 'flex-height' ) && ! current_theme_supports( 'custom-header', 'flex-width' ) ) {
+                printf( __( 'Images of exactly <strong>%1$d &times; %2$d pixels</strong> will be used as-is.' ) . '<br />', HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT );
+        } elseif ( current_theme_supports( 'custom-header', 'flex-height' ) ) {
+                if ( ! current_theme_supports( 'custom-header', 'flex-width' ) )
+                        printf( __( 'Images should be at least <strong>%1$d pixels</strong> wide.' ) . '<br />', HEADER_IMAGE_WIDTH );
+        } elseif ( current_theme_supports( 'custom-header', 'flex-width' ) ) {
+                if ( ! current_theme_supports( 'custom-header', 'flex-height' ) )
+                        printf( __( 'Images should be at least <strong>%1$d pixels</strong> tall.' ) . '<br />', HEADER_IMAGE_HEIGHT );
+        }
+        if ( current_theme_supports( 'custom-header', 'flex-height' ) || current_theme_supports( 'custom-header', 'flex-width' ) ) {
+                $header_support = get_theme_support( 'custom-header' );
+                if ( !empty( $header_support[ 0 ][ 'suggested-width' ] ) )
+                        printf( __( 'Suggested width is <strong>%1$d pixels</strong>.' ) . '<br />', absint( $header_support[ 0 ][ 'suggested-width' ] ) );
+                if ( !empty( $header_support[ 0 ][ 'suggested-height' ] ) )
+                        printf( __( 'Suggested height is <strong>%1$d pixels</strong>.' ) . '<br />', absint( $header_support[ 0 ][ 'suggested-height' ] ) );
+        }
+        ?></p>
</ins><span class="cx">         <form enctype="multipart/form-data" id="upload-form" method="post" action="<?php echo esc_attr( add_query_arg( 'step', 2 ) ) ?>">
</span><span class="cx">         <p>
</span><span class="cx">                 <label for="upload"><?php _e( 'Choose an image from your computer:' ); ?></label><br />
</span><span class="lines">@@ -662,7 +723,19 @@
</span><span class="cx">
</span><span class="cx">                 list($width, $height, $type, $attr) = getimagesize( $file );
</span><span class="cx">
</span><del>-                if ( $width == HEADER_IMAGE_WIDTH && $height == HEADER_IMAGE_HEIGHT ) {
</del><ins>+                $header_support = get_theme_support( 'custom-header' );
+                $max_width = 0;
+                // For flex, limit size of image displayed to 1500px unless theme says otherwise
+                if ( current_theme_supports( 'custom-header', 'flex-width' ) )
+                        $max_width = 1500;
+
+                if ( !empty( $header_support[ 0 ][ 'max-width' ] ) )
+                        $max_width = max( $max_width, absint( $header_support[ 0 ][ 'max-width' ] ) );
+
+                if ( defined( 'HEADER_IMAGE_WIDTH' ) )
+                        $max_width = max( $max_width, HEADER_IMAGE_WIDTH );
+                // If flexible height isn't supported and the image is the exact right size
+                if ( ! current_theme_supports( 'custom-header', 'flex-height' ) && ! current_theme_supports( 'custom-header', 'flex-width' ) && $width == HEADER_IMAGE_WIDTH && $height == HEADER_IMAGE_HEIGHT ) {
</ins><span class="cx">                         // Add the meta-data
</span><span class="cx">                         wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
</span><span class="cx">                         update_post_meta( $id, '_wp_attachment_is_custom_header', get_option('stylesheet' ) );
</span><span class="lines">@@ -670,9 +743,9 @@
</span><span class="cx">                         set_theme_mod('header_image', esc_url($url));
</span><span class="cx">                         do_action('wp_create_file_in_uploads', $file, $id); // For replication
</span><span class="cx">                         return $this->finished();
</span><del>-                } elseif ( $width > HEADER_IMAGE_WIDTH ) {
-                        $oitar = $width / HEADER_IMAGE_WIDTH;
-                        $image = wp_crop_image($file, 0, 0, $width, $height, HEADER_IMAGE_WIDTH, $height / $oitar, false, str_replace(basename($file), 'midsize-'.basename($file), $file));
</del><ins>+                } elseif ( $width > $max_width ) {
+                        $oitar = $width / $max_width;
+                        $image = wp_crop_image($file, 0, 0, $width, $height, $max_width, $height / $oitar, false, str_replace(basename($file), 'midsize-'.basename($file), $file));
</ins><span class="cx">                         if ( is_wp_error( $image ) )
</span><span class="cx">                                 wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) );
</span><span class="cx">
</span><span class="lines">@@ -733,7 +806,33 @@
</span><span class="cx">                 $attachment_id = absint( $_POST['attachment_id'] );
</span><span class="cx">                 $original = get_attached_file($attachment_id);
</span><span class="cx">
</span><del>-                $cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT );
</del><ins>+                $header_support = get_theme_support( 'custom-header' );
+                $max_width = 0;
+                // For flex, limit size of image displayed to 1500px unless theme says otherwise
+                if ( current_theme_supports( 'custom-header', 'flex-width' ) )
+                        $max_width = 1500;
+
+                if ( !empty( $header_support[ 0 ][ 'max-width' ] ) )
+                        $max_width = max( $max_width, absint( $header_support[ 0 ][ 'max-width' ] ) );
+
+                if ( defined( 'HEADER_IMAGE_WIDTH' ) )
+                        $max_width = max( $max_width, HEADER_IMAGE_WIDTH );
+
+                if ( ( current_theme_supports( 'custom-header', 'flex-height' ) && ! current_theme_supports( 'custom-header', 'flex-width' ) ) || $_POST['width'] > $max_width )
+                        $dst_height = absint( $_POST['height'] * ( $max_width / $_POST['width'] ) );
+                elseif ( current_theme_supports( 'custom-header', 'flex-height' ) && current_theme_supports( 'custom-header', 'flex-width' ) )
+                        $dst_height = absint( $_POST['height'] );
+                else
+                        $dst_height = HEADER_IMAGE_HEIGHT;
+
+                if ( ( current_theme_supports( 'custom-header', 'flex-width' ) && ! current_theme_supports( 'custom-header', 'flex-height' ) ) || $_POST['width'] > $max_width )
+                        $dst_width = absint( $_POST['width'] * ( $max_width / $_POST['width'] ) );
+                elseif ( current_theme_supports( 'custom-header', 'flex-width' ) && current_theme_supports( 'custom-header', 'flex-height' ) )
+                        $dst_width = absint( $_POST['width'] );
+                else
+                        $dst_width = HEADER_IMAGE_WIDTH;
+
+                $cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], $dst_width, $dst_height );
</ins><span class="cx">                 if ( is_wp_error( $cropped ) )
</span><span class="cx">                         wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) );
</span><span class="cx">
</span><span class="lines">@@ -760,6 +859,15 @@
</span><span class="cx">
</span><span class="cx">                 set_theme_mod('header_image', $url);
</span><span class="cx">
</span><ins>+                $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 );
+
</ins><span class="cx">                 // cleanup
</span><span class="cx">                 $medium = str_replace(basename($original), 'midsize-'.basename($original), $original);
</span><span class="cx">                 @unlink( apply_filters( 'wp_delete_file', $medium ) );
</span></span></pre></div>
<a id="trunkwpincludesthemephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/theme.php (19814 => 19815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/theme.php        2012-02-01 22:41:34 UTC (rev 19814)
+++ trunk/wp-includes/theme.php        2012-02-02 23:35:37 UTC (rev 19815)
</span><span class="lines">@@ -1351,7 +1351,10 @@
</span><span class="cx">         if ( isset( $mods[ $name ] ) )
</span><span class="cx">                 return apply_filters( "theme_mod_$name", $mods[ $name ] );
</span><span class="cx">
</span><del>-        return apply_filters( "theme_mod_$name", sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() ) );
</del><ins>+        if ( is_string( $default ) )
+                $default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() );
+
+        return apply_filters( "theme_mod_$name", $default );
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> /**
</span><span class="lines">@@ -1457,40 +1460,62 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> /**
</span><del>- * Get random header image from registered images in theme.
</del><ins>+ * Get random header image data from registered images in theme.
</ins><span class="cx"> *
</span><del>- * @since 3.2.0
</del><ins>+ * @since 3.4.0
</ins><span class="cx"> *
</span><ins>+ * @access private
+ *
</ins><span class="cx"> * @return string Path to header image
</span><span class="cx"> */
</span><del>-function get_random_header_image() {
-        global $_wp_default_headers;
</del><span class="cx">
</span><del>-        $header_image_mod = get_theme_mod( 'header_image', '' );
-        $headers = array();
</del><ins>+function _get_random_header_data() {
+        static $_wp_random_header;
</ins><span class="cx">
</span><del>-        if ( 'random-uploaded-image' == $header_image_mod )
-                $headers = get_uploaded_header_images();
-        elseif ( ! empty( $_wp_default_headers ) ) {
-                if ( 'random-default-image' == $header_image_mod ) {
-                        $headers = $_wp_default_headers;
-                } else {
-                        $is_random = get_theme_support( 'custom-header' );
-                        if ( isset( $is_random[ 0 ] ) && !empty( $is_random[ 0 ][ 'random-default' ] ) )
</del><ins>+        if ( empty( $_wp_random_header ) ) {
+                global $_wp_default_headers;
+                $header_image_mod = get_theme_mod( 'header_image', '' );
+                $headers = array();
+
+                if ( 'random-uploaded-image' == $header_image_mod )
+                        $headers = get_uploaded_header_images();
+                elseif ( ! empty( $_wp_default_headers ) ) {
+                        if ( 'random-default-image' == $header_image_mod ) {
</ins><span class="cx">                                 $headers = $_wp_default_headers;
</span><ins>+                        } else {
+                                $is_random = get_theme_support( 'custom-header' );
+                                if ( isset( $is_random[ 0 ] ) && !empty( $is_random[ 0 ][ 'random-default' ] ) )
+                                        $headers = $_wp_default_headers;
+                        }
</ins><span class="cx">                 }
</span><del>-        }
</del><span class="cx">
</span><del>-        if ( empty( $headers ) )
-                return '';
</del><ins>+                if ( empty( $headers ) )
+                        return stdClass();
</ins><span class="cx">
</span><del>-        $random_image = array_rand( $headers );
-        $header_url = sprintf( $headers[$random_image]['url'], get_template_directory_uri(), get_stylesheet_directory_uri() );
</del><ins>+                $_wp_random_header = (object) $headers[ array_rand( $headers ) ];
</ins><span class="cx">
</span><del>-        return $header_url;
</del><ins>+                $_wp_random_header->url = sprintf( $_wp_random_header->url, get_template_directory_uri(), get_stylesheet_directory_uri() );
+                $_wp_random_header->thumbnail_url = sprintf( $_wp_random_header->thumbnail_url, get_template_directory_uri(), get_stylesheet_directory_uri() );
+        }
+        return $_wp_random_header;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> /**
</span><ins>+ * Get random header image url from registered images in theme.
+ *
+ * @since 3.2.0
+ *
+ * @return string Path to header image
+ */
+
+function get_random_header_image() {
+        $random_image = _get_random_header_data();
+        if ( empty( $random_image->url ) )
+                return '';
+        return $random_image->url;
+}
+
+/**
</ins><span class="cx"> * Check if random header image is in use.
</span><span class="cx"> *
</span><span class="cx"> * Always true if user expressly chooses the option in Appearance > Header.
</span><span class="lines">@@ -1547,17 +1572,60 @@
</span><span class="cx">
</span><span class="cx">         foreach ( (array) $headers as $header ) {
</span><span class="cx">                 $url = esc_url_raw( $header->guid );
</span><del>-                $header = basename($url);
-                $header_images[$header] = array();
-                $header_images[$header]['url'] = $url;
-                $header_images[$header]['thumbnail_url'] = $url;
-                $header_images[$header]['uploaded'] = true;
</del><ins>+                $header_data = wp_get_attachment_metadata( $header->ID );
+                $header_index = basename($url);
+                $header_images[$header_index] = array();
+                $header_images[$header_index]['attachment_id'] = $header->ID;
+                $header_images[$header_index]['url'] = $url;
+                $header_images[$header_index]['thumbnail_url'] = $url;
+                $header_images[$header_index]['width'] = $header_data['width'];
+                $header_images[$header_index]['height'] = $header_data['height'];
</ins><span class="cx">         }
</span><span class="cx">
</span><span class="cx">         return $header_images;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> /**
</span><ins>+ * Get the header image data.
+ *
+ * @since 3.4.0
+ *
+ * @return object
+ */
+function get_current_header_data() {
+        $data = is_random_header_image()? _get_random_header_data() : get_theme_mod( 'header_image_data' );
+        $default = array(
+                'url' => '',
+                'thumbnail_url' => '',
+                'width' => '',
+                'height' => '',
+        );
+        return (object) wp_parse_args( $data, $default );
+}
+
+/**
+ * Get the header image width.
+ *
+ * @since 3.4.0
+ *
+ * @return int
+ */
+function get_header_image_width() {
+        return empty( get_current_header_data()->width )? HEADER_IMAGE_WIDTH : get_current_header_data()->width;
+}
+
+/**
+ * Get the header image height.
+ *
+ * @since 3.4.0
+ *
+ * @return int
+ */
+function get_header_image_height() {
+        return empty( get_current_header_data()->height )? HEADER_IMAGE_HEIGHT : get_current_header_data()->height;
+}
+
+/**
</ins><span class="cx"> * Add callbacks for image header display.
</span><span class="cx"> *
</span><span class="cx"> * The parameter $header_callback callback will be required to display the
</span><span class="lines">@@ -1955,6 +2023,13 @@
</span><span class="cx">                         $post_format = $args[0];
</span><span class="cx">                         return in_array( $post_format, $_wp_theme_features[$feature][0] );
</span><span class="cx">                         break;
</span><ins>+
+                case 'custom-header':
+                        // specific custom header capabilities can be registered by passing
+                        // an array to add_theme_support()
+                        $header_support = $args[0];
+                        return ( isset( $_wp_theme_features[$feature][0][$header_support] ) && $_wp_theme_features[$feature][0][$header_support] );
+                        break;
</ins><span class="cx">         }
</span><span class="cx">
</span><span class="cx">         return apply_filters('current_theme_supports-' . $feature, true, $args, $_wp_theme_features[$feature]);
</span></span></pre>
</div>
</div>
</body>
</html>