Wordpress 3.2
[autoinstalls/wordpress.git] / wp-admin / custom-header.php
1 <?php
2 /**
3  * The custom header image script.
4  *
5  * @package WordPress
6  * @subpackage Administration
7  */
8
9 /**
10  * The custom header image class.
11  *
12  * @since 2.1.0
13  * @package WordPress
14  * @subpackage Administration
15  */
16 class Custom_Image_Header {
17
18         /**
19          * Callback for administration header.
20          *
21          * @var callback
22          * @since 2.1.0
23          * @access private
24          */
25         var $admin_header_callback;
26
27         /**
28          * Callback for header div.
29          *
30          * @var callback
31          * @since 3.0.0
32          * @access private
33          */
34         var $admin_image_div_callback;
35
36         /**
37          * Holds default headers.
38          *
39          * @var array
40          * @since 3.0.0
41          * @access private
42          */
43         var $default_headers = array();
44
45
46         /**
47          * Holds custom headers uploaded by the user
48          *
49          * @var array
50          * @since 3.2.0
51          * @access private
52          */
53         var $uploaded_headers = array();
54
55         /**
56          * Holds the page menu hook.
57          *
58          * @var string
59          * @since 3.0.0
60          * @access private
61          */
62         var $page = '';
63
64         /**
65          * Constructor - Register administration header callback.
66          *
67          * @since 2.1.0
68          * @param callback $admin_header_callback
69          * @param callback $admin_image_div_callback Optional custom image div output callback.
70          * @return Custom_Image_Header
71          */
72         function __construct($admin_header_callback, $admin_image_div_callback = '') {
73                 $this->admin_header_callback = $admin_header_callback;
74                 $this->admin_image_div_callback = $admin_image_div_callback;
75         }
76
77         /**
78          * Set up the hooks for the Custom Header admin page.
79          *
80          * @since 2.1.0
81          */
82         function init() {
83                 if ( ! current_user_can('edit_theme_options') )
84                         return;
85
86                 $this->page = $page = add_theme_page(__('Header'), __('Header'), 'edit_theme_options', 'custom-header', array(&$this, 'admin_page'));
87
88                 add_action("admin_print_scripts-$page", array(&$this, 'js_includes'));
89                 add_action("admin_print_styles-$page", array(&$this, 'css_includes'));
90                 add_action("admin_head-$page", array(&$this, 'help') );
91                 add_action("admin_head-$page", array(&$this, 'take_action'), 50);
92                 add_action("admin_head-$page", array(&$this, 'js'), 50);
93                 add_action("admin_head-$page", $this->admin_header_callback, 51);
94         }
95
96         /**
97          * Adds contextual help.
98          *
99          * @since 3.0.0
100          */
101         function help() {
102                 add_contextual_help( $this->page, '<p>' . __( 'You can set a custom image header for your site. Simply upload the image and crop it, and the new header will go live immediately.' ) . '</p>' .
103                 '<p>' . __( 'If you want to discard your custom header and go back to the default included in your theme, click on the buttons to remove the custom image and restore the original header image.' ) . '</p>' .
104                 '<p>' . __( 'Some themes come with additional header images bundled. If you see multiple images displayed, select the one you&#8217;d like and click the Save Changes button.' ) . '</p>' .
105                 '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
106                 '<p>' . __( '<a href="http://codex.wordpress.org/Appearance_Header_Screen" target="_blank">Documentation on Custom Header</a>' ) . '</p>' .
107                 '<p>' . __( '<a href="http://wordpress.org/support/" target="_blank">Support Forums</a>' ) . '</p>' );
108         }
109
110         /**
111          * Get the current step.
112          *
113          * @since 2.6.0
114          *
115          * @return int Current step
116          */
117         function step() {
118                 if ( ! isset( $_GET['step'] ) )
119                         return 1;
120
121                 $step = (int) $_GET['step'];
122                 if ( $step < 1 || 3 < $step )
123                         $step = 1;
124
125                 return $step;
126         }
127
128         /**
129          * Set up the enqueue for the JavaScript files.
130          *
131          * @since 2.1.0
132          */
133         function js_includes() {
134                 $step = $this->step();
135
136                 if ( ( 1 == $step || 3 == $step ) && $this->header_text() )
137                         wp_enqueue_script('farbtastic');
138                 elseif ( 2 == $step )
139                         wp_enqueue_script('imgareaselect');
140         }
141
142         /**
143          * Set up the enqueue for the CSS files
144          *
145          * @since 2.7
146          */
147         function css_includes() {
148                 $step = $this->step();
149
150                 if ( ( 1 == $step || 3 == $step ) && $this->header_text() )
151                         wp_enqueue_style('farbtastic');
152                 elseif ( 2 == $step )
153                         wp_enqueue_style('imgareaselect');
154         }
155
156         /**
157          * Check if header text is allowed
158          *
159          * @since 3.0.0
160          */
161         function header_text() {
162                 if ( defined( 'NO_HEADER_TEXT' ) && NO_HEADER_TEXT )
163                         return false;
164
165                 return true;
166         }
167
168         /**
169          * Execute custom header modification.
170          *
171          * @since 2.6.0
172          */
173         function take_action() {
174                 if ( ! current_user_can('edit_theme_options') )
175                         return;
176
177                 if ( empty( $_POST ) )
178                         return;
179
180                 $this->updated = true;
181
182                 if ( isset( $_POST['resetheader'] ) ) {
183                         check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' );
184                         remove_theme_mod( 'header_image' );
185                         return;
186                 }
187
188                 if ( isset( $_POST['resettext'] ) ) {
189                         check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' );
190                         remove_theme_mod('header_textcolor');
191                         return;
192                 }
193
194                 if ( isset( $_POST['removeheader'] ) ) {
195                         check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' );
196                         set_theme_mod( 'header_image', 'remove-header' );
197                         return;
198                 }
199
200                 if ( isset( $_POST['text-color'] ) ) {
201                         check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' );
202                         $_POST['text-color'] = str_replace( '#', '', $_POST['text-color'] );
203                         if ( 'blank' == $_POST['text-color'] ) {
204                                 set_theme_mod( 'header_textcolor', 'blank' );
205                         } else {
206                                 $color = preg_replace('/[^0-9a-fA-F]/', '', $_POST['text-color']);
207                                 if ( strlen($color) == 6 || strlen($color) == 3 )
208                                         set_theme_mod('header_textcolor', $color);
209                         }
210                 }
211
212                 if ( isset( $_POST['default-header'] ) ) {
213                         check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options' );
214                         if ( 'random-default-image' == $_POST['default-header'] ) {
215                                 set_theme_mod( 'header_image', 'random-default-image' );
216                         } elseif ( 'random-uploaded-image' == $_POST['default-header'] ) {
217                                 set_theme_mod( 'header_image', 'random-uploaded-image' );
218                         } else {
219                                 $this->process_default_headers();
220                                 $uploaded = get_uploaded_header_images();
221                                 if ( isset( $uploaded[$_POST['default-header']] ) )
222                                         set_theme_mod( 'header_image', esc_url( $uploaded[$_POST['default-header']]['url'] ) );
223                                 elseif ( isset( $this->default_headers[$_POST['default-header']] ) )
224                                         set_theme_mod( 'header_image', esc_url( $this->default_headers[$_POST['default-header']]['url'] ) );
225                         }
226                 }
227         }
228
229         /**
230          * Process the default headers
231          *
232          * @since 3.0.0
233          */
234         function process_default_headers() {
235                 global $_wp_default_headers;
236
237                 if ( !empty($this->headers) )
238                         return;
239
240                 if ( !isset($_wp_default_headers) )
241                         return;
242
243                 $this->default_headers = $_wp_default_headers;
244                 foreach ( array_keys($this->default_headers) as $header ) {
245                         $this->default_headers[$header]['url'] =  sprintf( $this->default_headers[$header]['url'], get_template_directory_uri(), get_stylesheet_directory_uri() );
246                         $this->default_headers[$header]['thumbnail_url'] =  sprintf( $this->default_headers[$header]['thumbnail_url'], get_template_directory_uri(), get_stylesheet_directory_uri() );
247                 }
248
249         }
250
251         /**
252          * Display UI for selecting one of several default headers.
253          *
254          * Show the random image option if this theme has multiple header images.
255          * Random image option is on by default if no header has been set.
256          *
257          * @since 3.0.0
258          */
259         function show_header_selector( $type = 'default' ) {
260                 if ( 'default' == $type ) {
261                         $headers = $this->default_headers;
262                 } else {
263                         $headers = get_uploaded_header_images();
264                         $type = 'uploaded';
265                 }
266
267                 if ( 1 < count( $headers ) ) {
268                         echo '<div class="random-header">';
269                         echo '<label><input name="default-header" type="radio" value="random-' . $type . '-image"' . checked( is_random_header_image( $type ), true, false ) . ' />';
270                         echo __( '<strong>Random:</strong> Show a different image on each page.' );
271                         echo '</label>';
272                         echo '</div>';
273                 }
274
275                 echo '<div class="available-headers">';
276                 foreach ( $headers as $header_key => $header ) {
277                         $header_thumbnail = $header['thumbnail_url'];
278                         $header_url = $header['url'];
279                         $header_desc = empty( $header['description'] ) ? '' : $header['description'];
280                         echo '<div class="default-header">';
281                         echo '<label><input name="default-header" type="radio" value="' . esc_attr( $header_key ) . '" ' . checked( $header_url, get_theme_mod( 'header_image' ), false ) . ' />';
282                         $width = '';
283                         if ( !empty( $header['uploaded'] ) )
284                                 $width = ' width="230"';
285                         echo '<img src="' . $header_thumbnail . '" alt="' . esc_attr( $header_desc ) .'" title="' . esc_attr( $header_desc ) . '"' . $width . ' /></label>';
286                         echo '</div>';
287                 }
288                 echo '<div class="clear"></div></div>';
289         }
290
291         /**
292          * Execute Javascript depending on step.
293          *
294          * @since 2.1.0
295          */
296         function js() {
297                 $step = $this->step();
298                 if ( ( 1 == $step || 3 == $step ) && $this->header_text() )
299                         $this->js_1();
300                 elseif ( 2 == $step )
301                         $this->js_2();
302         }
303
304         /**
305          * Display Javascript based on Step 1 and 3.
306          *
307          * @since 2.6.0
308          */
309         function js_1() { ?>
310 <script type="text/javascript">
311 /* <![CDATA[ */
312         var text_objects = ['#name', '#desc', '#text-color-row'];
313         var farbtastic;
314         var default_color = '#<?php echo HEADER_TEXTCOLOR; ?>';
315         var old_color = null;
316
317         function pickColor(color) {
318                 jQuery('#name').css('color', color);
319                 jQuery('#desc').css('color', color);
320                 jQuery('#text-color').val(color);
321                 farbtastic.setColor(color);
322         }
323
324         function toggle_text(s) {
325                 if (jQuery(s).attr('id') == 'showtext' && jQuery('#text-color').val() != 'blank')
326                         return;
327
328                 if (jQuery(s).attr('id') == 'hidetext' && jQuery('#text-color').val() == 'blank')
329                         return;
330
331                 if (jQuery('#text-color').val() == 'blank') {
332                         //Show text
333                         if (old_color == '#blank')
334                                 old_color = default_color;
335
336                         jQuery( text_objects.toString() ).show();
337                         jQuery('#text-color').val(old_color);
338                         jQuery('#name').css('color', old_color);
339                         jQuery('#desc').css('color', old_color);
340                         pickColor(old_color);
341                 } else {
342                         //Hide text
343                         jQuery( text_objects.toString() ).hide();
344                         old_color = jQuery('#text-color').val();
345                         jQuery('#text-color').val('blank');
346                 }
347         }
348
349         jQuery(document).ready(function() {
350                 jQuery('#pickcolor').click(function() {
351                         jQuery('#color-picker').show();
352                 });
353
354                 jQuery('input[name="hidetext"]').click(function() {
355                         toggle_text(this);
356                 });
357
358                 jQuery('#defaultcolor').click(function() {
359                         pickColor(default_color);
360                         jQuery('#text-color').val(default_color)
361                 });
362
363                 jQuery('#text-color').keyup(function() {
364                         var _hex = jQuery('#text-color').val();
365                         var hex = _hex;
366                         if ( hex[0] != '#' )
367                                 hex = '#' + hex;
368                         hex = hex.replace(/[^#a-fA-F0-9]+/, '');
369                         if ( hex != _hex )
370                                 jQuery('#text-color').val(hex);
371                         if ( hex.length == 4 || hex.length == 7 )
372                                 pickColor( hex );
373                 });
374
375                 jQuery(document).mousedown(function(){
376                         jQuery('#color-picker').each( function() {
377                                 var display = jQuery(this).css('display');
378                                 if (display == 'block')
379                                         jQuery(this).fadeOut(2);
380                         });
381                 });
382
383                 farbtastic = jQuery.farbtastic('#color-picker', function(color) { pickColor(color); });
384                 <?php if ( $color = get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) ) { ?>
385                 pickColor('#<?php echo $color; ?>');
386                 <?php } ?>
387
388                 <?php if ( 'blank' == get_theme_mod( 'header_textcolor', HEADER_TEXTCOLOR ) || '' == get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) || ! $this->header_text() ) { ?>
389                 toggle_text();
390                 <?php } ?>
391         });
392 /* ]]> */
393 </script>
394 <?php
395         }
396
397         /**
398          * Display Javascript based on Step 2.
399          *
400          * @since 2.6.0
401          */
402         function js_2() { ?>
403 <script type="text/javascript">
404 /* <![CDATA[ */
405         function onEndCrop( coords ) {
406                 jQuery( '#x1' ).val(coords.x);
407                 jQuery( '#y1' ).val(coords.y);
408                 jQuery( '#width' ).val(coords.w);
409                 jQuery( '#height' ).val(coords.h);
410         }
411
412         jQuery(document).ready(function() {
413                 var xinit = <?php echo HEADER_IMAGE_WIDTH; ?>;
414                 var yinit = <?php echo HEADER_IMAGE_HEIGHT; ?>;
415                 var ratio = xinit / yinit;
416                 var ximg = jQuery('img#upload').width();
417                 var yimg = jQuery('img#upload').height();
418
419                 if ( yimg < yinit || ximg < xinit ) {
420                         if ( ximg / yimg > ratio ) {
421                                 yinit = yimg;
422                                 xinit = yinit * ratio;
423                         } else {
424                                 xinit = ximg;
425                                 yinit = xinit / ratio;
426                         }
427                 }
428
429                 jQuery('img#upload').imgAreaSelect({
430                         handles: true,
431                         keys: true,
432                         aspectRatio: xinit + ':' + yinit,
433                         show: true,
434                         x1: 0,
435                         y1: 0,
436                         x2: xinit,
437                         y2: yinit,
438                         maxHeight: <?php echo HEADER_IMAGE_HEIGHT; ?>,
439                         maxWidth: <?php echo HEADER_IMAGE_WIDTH; ?>,
440                         onInit: function () {
441                                 jQuery('#width').val(xinit);
442                                 jQuery('#height').val(yinit);
443                         },
444                         onSelectChange: function(img, c) {
445                                 jQuery('#x1').val(c.x1);
446                                 jQuery('#y1').val(c.y1);
447                                 jQuery('#width').val(c.width);
448                                 jQuery('#height').val(c.height);
449                         }
450                 });
451         });
452 /* ]]> */
453 </script>
454 <?php
455         }
456
457         /**
458          * Display first step of custom header image page.
459          *
460          * @since 2.1.0
461          */
462         function step_1() {
463                 $this->process_default_headers();
464 ?>
465
466 <div class="wrap">
467 <?php screen_icon(); ?>
468 <h2><?php _e('Custom Header'); ?></h2>
469
470 <?php if ( ! empty( $this->updated ) ) { ?>
471 <div id="message" class="updated">
472 <p><?php printf( __( 'Header updated. <a href="%s">Visit your site</a> to see how it looks.' ), home_url( '/' ) ); ?></p>
473 </div>
474 <?php } ?>
475
476 <table class="form-table">
477 <tbody>
478
479
480 <tr valign="top">
481 <th scope="row"><?php _e( 'Preview' ); ?></th>
482 <td >
483         <?php if ( $this->admin_image_div_callback ) {
484           call_user_func( $this->admin_image_div_callback );
485         } else {
486         ?>
487         <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() ) ?>);">
488                 <?php
489                 if ( 'blank' == get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) || '' == get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) || ! $this->header_text() )
490                         $style = ' style="display:none;"';
491                 else
492                         $style = ' style="color:#' . get_theme_mod( 'header_textcolor', HEADER_TEXTCOLOR ) . ';"';
493                 ?>
494                 <h1><a id="name"<?php echo $style; ?> onclick="return false;" href="<?php bloginfo('url'); ?>"><?php bloginfo( 'name' ); ?></a></h1>
495                 <div id="desc"<?php echo $style; ?>><?php bloginfo( 'description' ); ?></div>
496         </div>
497         <?php } ?>
498 </td>
499 </tr>
500 <?php if ( current_theme_supports( 'custom-header-uploads' ) ) : ?>
501 <tr valign="top">
502 <th scope="row"><?php _e( 'Upload Image' ); ?></th>
503 <td>
504         <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 />
505         <?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>
506         <form enctype="multipart/form-data" id="upload-form" method="post" action="<?php echo esc_attr( add_query_arg( 'step', 2 ) ) ?>">
507         <p>
508                 <label for="upload"><?php _e( 'Choose an image from your computer:' ); ?></label><br />
509                 <input type="file" id="upload" name="import" />
510                 <input type="hidden" name="action" value="save" />
511                 <?php wp_nonce_field( 'custom-header-upload', '_wpnonce-custom-header-upload' ) ?>
512                 <?php submit_button( __( 'Upload' ), 'button', 'submit', false ); ?>
513         </p>
514         </form>
515 </td>
516 </tr>
517 <?php endif; ?>
518 </tbody>
519 </table>
520
521 <form method="post" action="<?php echo esc_attr( add_query_arg( 'step', 1 ) ) ?>">
522 <table class="form-table">
523 <tbody>
524         <?php if ( get_uploaded_header_images() ) : ?>
525 <tr valign="top">
526 <th scope="row"><?php _e( 'Uploaded Images' ); ?></th>
527 <td>
528         <p><?php _e( 'You can choose one of your previously uploaded headers, or show a random one.' ) ?></p>
529         <?php
530                 $this->show_header_selector( 'uploaded' );
531         ?>
532 </td>
533 </tr>
534         <?php endif;
535         if ( ! empty( $this->default_headers ) ) : ?>
536 <tr valign="top">
537 <th scope="row"><?php _e( 'Default Images' ); ?></th>
538 <td>
539 <?php if ( current_theme_supports( 'custom-header-uploads' ) ) : ?>
540         <p><?php _e( 'If you don&lsquo;t want to upload your own image, you can use one of these cool headers, or show a random one.' ) ?></p>
541 <?php else: ?>
542         <p><?php _e( 'You can use one of these cool headers or show a random one on each page.' ) ?></p>
543 <?php endif; ?>
544         <?php
545                 $this->show_header_selector( 'default' );
546         ?>
547 </td>
548 </tr>
549         <?php endif;
550         if ( get_header_image() ) : ?>
551 <tr valign="top">
552 <th scope="row"><?php _e( 'Remove Image' ); ?></th>
553 <td>
554         <p><?php _e( 'This will remove the header image. You will not be able to restore any customizations.' ) ?></p>
555         <?php submit_button( __( 'Remove Header Image' ), 'button', 'removeheader', false ); ?>
556 </td>
557 </tr>
558         <?php endif;
559
560         if ( defined( 'HEADER_IMAGE' ) && '' != HEADER_IMAGE ) : ?>
561 <tr valign="top">
562 <th scope="row"><?php _e( 'Reset Image' ); ?></th>
563 <td>
564         <p><?php _e( 'This will restore the original header image. You will not be able to restore any customizations.' ) ?></p>
565         <?php submit_button( __( 'Restore Original Header Image' ), 'button', 'resetheader', false ); ?>
566 </td>
567 </tr>
568         <?php endif; ?>
569 </tbody>
570 </table>
571
572         <?php if ( $this->header_text() ) : ?>
573 <table class="form-table">
574 <tbody>
575 <tr valign="top" class="hide-if-no-js">
576 <th scope="row"><?php _e( 'Display Text' ); ?></th>
577 <td>
578         <p>
579         <?php $hidetext = get_theme_mod( 'header_textcolor', HEADER_TEXTCOLOR ); ?>
580         <label><input type="radio" value="1" name="hidetext" id="hidetext"<?php checked( ( 'blank' == $hidetext || empty( $hidetext ) )  ? true : false ); ?> /> <?php _e( 'No' ); ?></label>
581         <label><input type="radio" value="0" name="hidetext" id="showtext"<?php checked( ( 'blank' == $hidetext || empty( $hidetext ) ) ? false : true ); ?> /> <?php _e( 'Yes' ); ?></label>
582         </p>
583 </td>
584 </tr>
585
586 <tr valign="top" id="text-color-row">
587 <th scope="row"><?php _e( 'Text Color' ); ?></th>
588 <td>
589         <p>
590                 <input type="text" name="text-color" id="text-color" value="#<?php echo esc_attr( get_theme_mod( 'header_textcolor', HEADER_TEXTCOLOR ) ); ?>" />
591                 <span class="description hide-if-js"><?php _e( 'If you want to hide header text, add <strong>#blank</strong> as text color.' );?></span>
592                 <input type="button" class="button hide-if-no-js" value="<?php esc_attr_e( 'Select a Color' ); ?>" id="pickcolor" />
593         </p>
594         <div id="color-picker" style="z-index: 100; background:#eee; border:1px solid #ccc; position:absolute; display:none;"></div>
595 </td>
596 </tr>
597
598         <?php if ( defined('HEADER_TEXTCOLOR') && get_theme_mod('header_textcolor') ) { ?>
599 <tr valign="top">
600 <th scope="row"><?php _e('Reset Text Color'); ?></th>
601 <td>
602         <p><?php _e( 'This will restore the original header text. You will not be able to restore any customizations.' ) ?></p>
603         <?php submit_button( __( 'Restore Original Header Text' ), 'button', 'resettext', false ); ?>
604 </td>
605 </tr>
606         <?php } ?>
607
608 </tbody>
609 </table>
610         <?php endif;
611
612 do_action( 'custom_header_options' );
613
614 wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?>
615
616 <?php submit_button( null, 'primary', 'save-header-options' ); ?>
617 </form>
618 </div>
619
620 <?php }
621
622         /**
623          * Display second step of custom header image page.
624          *
625          * @since 2.1.0
626          */
627         function step_2() {
628                 check_admin_referer('custom-header-upload', '_wpnonce-custom-header-upload');
629                 if ( ! current_theme_supports( 'custom-header-uploads' ) )
630                         wp_die( 'Cheatin&#8217; uh?' );
631
632                 $overrides = array('test_form' => false);
633                 $file = wp_handle_upload($_FILES['import'], $overrides);
634
635                 if ( isset($file['error']) )
636                         wp_die( $file['error'],  __( 'Image Upload Error' ) );
637
638                 $url = $file['url'];
639                 $type = $file['type'];
640                 $file = $file['file'];
641                 $filename = basename($file);
642
643                 // Construct the object array
644                 $object = array(
645                 'post_title' => $filename,
646                 'post_content' => $url,
647                 'post_mime_type' => $type,
648                 'guid' => $url,
649                 'context' => 'custom-header'
650                 );
651
652                 // Save the data
653                 $id = wp_insert_attachment($object, $file);
654
655                 list($width, $height, $type, $attr) = getimagesize( $file );
656
657                 if ( $width == HEADER_IMAGE_WIDTH && $height == HEADER_IMAGE_HEIGHT ) {
658                         // Add the meta-data
659                         wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
660                         update_post_meta( $id, '_wp_attachment_is_custom_header', get_option('stylesheet' ) );
661
662                         set_theme_mod('header_image', esc_url($url));
663                         do_action('wp_create_file_in_uploads', $file, $id); // For replication
664                         return $this->finished();
665                 } elseif ( $width > HEADER_IMAGE_WIDTH ) {
666                         $oitar = $width / HEADER_IMAGE_WIDTH;
667                         $image = wp_crop_image($file, 0, 0, $width, $height, HEADER_IMAGE_WIDTH, $height / $oitar, false, str_replace(basename($file), 'midsize-'.basename($file), $file));
668                         if ( is_wp_error( $image ) )
669                                 wp_die( __( 'Image could not be processed.  Please go back and try again.' ), __( 'Image Processing Error' ) );
670
671                         $image = apply_filters('wp_create_file_in_uploads', $image, $id); // For replication
672
673                         $url = str_replace(basename($url), basename($image), $url);
674                         $width = $width / $oitar;
675                         $height = $height / $oitar;
676                 } else {
677                         $oitar = 1;
678                 }
679                 ?>
680
681 <div class="wrap">
682 <?php screen_icon(); ?>
683 <h2><?php _e( 'Crop Header Image' ); ?></h2>
684
685 <form method="post" action="<?php echo esc_attr(add_query_arg('step', 3)); ?>">
686         <p class="hide-if-no-js"><?php _e('Choose the part of the image you want to use as your header.'); ?></p>
687         <p class="hide-if-js"><strong><?php _e( 'You need Javascript to choose a part of the image.'); ?></strong></p>
688
689         <div id="crop_image" style="position: relative">
690                 <img src="<?php echo esc_url( $url ); ?>" id="upload" width="<?php echo $width; ?>" height="<?php echo $height; ?>" />
691         </div>
692
693         <input type="hidden" name="x1" id="x1" value="0"/>
694         <input type="hidden" name="y1" id="y1" value="0"/>
695         <input type="hidden" name="width" id="width" value="<?php echo esc_attr( $width ); ?>"/>
696         <input type="hidden" name="height" id="height" value="<?php echo esc_attr( $height ); ?>"/>
697         <input type="hidden" name="attachment_id" id="attachment_id" value="<?php echo esc_attr( $id ); ?>" />
698         <input type="hidden" name="oitar" id="oitar" value="<?php echo esc_attr( $oitar ); ?>" />
699         <?php wp_nonce_field( 'custom-header-crop-image' ) ?>
700
701         <?php submit_button( __( 'Crop and Publish' ) ); ?>
702         </p>
703 </form>
704 </div>
705                 <?php
706         }
707
708         /**
709          * Display third step of custom header image page.
710          *
711          * @since 2.1.0
712          */
713         function step_3() {
714                 check_admin_referer('custom-header-crop-image');
715                 if ( ! current_theme_supports( 'custom-header-uploads' ) )
716                         wp_die( 'Cheatin&#8217; uh?' );
717
718                 if ( $_POST['oitar'] > 1 ) {
719                         $_POST['x1'] = $_POST['x1'] * $_POST['oitar'];
720                         $_POST['y1'] = $_POST['y1'] * $_POST['oitar'];
721                         $_POST['width'] = $_POST['width'] * $_POST['oitar'];
722                         $_POST['height'] = $_POST['height'] * $_POST['oitar'];
723                 }
724
725                 $attachment_id = absint( $_POST['attachment_id'] );
726                 $original = get_attached_file($attachment_id);
727
728                 $cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT );
729                 if ( is_wp_error( $cropped ) )
730                         wp_die( __( 'Image could not be processed.  Please go back and try again.' ), __( 'Image Processing Error' ) );
731
732                 $cropped = apply_filters('wp_create_file_in_uploads', $cropped, $attachment_id); // For replication
733
734                 $parent = get_post($attachment_id);
735                 $parent_url = $parent->guid;
736                 $url = str_replace(basename($parent_url), basename($cropped), $parent_url);
737
738                 // Construct the object array
739                 $object = array(
740                         'ID' => $attachment_id,
741                         'post_title' => basename($cropped),
742                         'post_content' => $url,
743                         'post_mime_type' => 'image/jpeg',
744                         'guid' => $url,
745                         'context' => 'custom-header'
746                 );
747
748                 // Update the attachment
749                 wp_insert_attachment($object, $cropped);
750                 wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $cropped ) );
751                 update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', get_option('stylesheet' ) );
752
753                 set_theme_mod('header_image', $url);
754
755                 // cleanup
756                 $medium = str_replace(basename($original), 'midsize-'.basename($original), $original);
757                 @unlink( apply_filters( 'wp_delete_file', $medium ) );
758                 @unlink( apply_filters( 'wp_delete_file', $original ) );
759
760                 return $this->finished();
761         }
762
763         /**
764          * Display last step of custom header image page.
765          *
766          * @since 2.1.0
767          */
768         function finished() {
769                 $this->updated = true;
770                 $this->step_1();
771         }
772
773         /**
774          * Display the page based on the current step.
775          *
776          * @since 2.1.0
777          */
778         function admin_page() {
779                 if ( ! current_user_can('edit_theme_options') )
780                         wp_die(__('You do not have permission to customize headers.'));
781                 $step = $this->step();
782                 if ( 1 == $step )
783                         $this->step_1();
784                 elseif ( 2 == $step )
785                         $this->step_2();
786                 elseif ( 3 == $step )
787                         $this->step_3();
788         }
789
790 }
791 ?>