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