WordPress.org

Make WordPress Core

Ticket #15926: custom-header.php

File custom-header.php, 22.1 KB (added by firetag, 4 years ago)
Line 
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 */
16class 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                if ( isset($_POST['alt-text']) ) {
210                        check_admin_referer( 'custom-header-options', '_wpnonce-custom-header-options');
211                        $alt = preg_replace('/[^0-9a-zA-Z ]/', '', $_POST['alt-text']);
212                        set_theme_mod('background_alt', $alt);
213                }
214        }
215
216        /**
217         * Process the default headers
218         *
219         * @since 3.0.0
220         */
221        function process_default_headers() {
222                global $_wp_default_headers;
223
224                if ( !empty($this->headers) )
225                        return;
226
227                if ( !isset($_wp_default_headers) )
228                        return;
229
230                $this->default_headers = $_wp_default_headers;
231                foreach ( array_keys($this->default_headers) as $header ) {
232                        $this->default_headers[$header]['url'] =  sprintf( $this->default_headers[$header]['url'], get_template_directory_uri(), get_stylesheet_directory_uri() );
233                        $this->default_headers[$header]['thumbnail_url'] =  sprintf( $this->default_headers[$header]['thumbnail_url'], get_template_directory_uri(), get_stylesheet_directory_uri() );
234                }
235        }
236
237        /**
238         * Display UI for selecting one of several default headers.
239         *
240         * @since 3.0.0
241         */
242        function show_default_header_selector() {
243                echo '<div id="available-headers">';
244                foreach ( $this->default_headers as $header_key => $header ) {
245                        $header_thumbnail = $header['thumbnail_url'];
246                        $header_url = $header['url'];
247                        $header_desc = $header['description'];
248                        echo '<div class="default-header">';
249                        echo '<label><input name="default-header" type="radio" value="' . esc_attr($header_key) . '" ' . checked($header_url, get_theme_mod( 'header_image' ), false) . ' />';
250                        echo '<img src="' . $header_thumbnail . '" alt="' . esc_attr($header_desc) .'" title="' . esc_attr($header_desc) .'" /></label>';
251                        echo '</div>';
252                }
253                echo '<div class="clear"></div></div>';
254        }
255
256        /**
257         * Execute Javascript depending on step.
258         *
259         * @since 2.1.0
260         */
261        function js() {
262                $step = $this->step();
263                if ( ( 1 == $step || 3 == $step ) && $this->header_text() )
264                        $this->js_1();
265                elseif ( 2 == $step )
266                        $this->js_2();
267        }
268
269        /**
270         * Display Javascript based on Step 1 and 3.
271         *
272         * @since 2.6.0
273         */
274        function js_1() { ?>
275<script type="text/javascript">
276/* <![CDATA[ */
277        var text_objects = ['#name', '#desc', '#text-color-row'];
278        var farbtastic;
279        var default_color = '#<?php echo HEADER_TEXTCOLOR; ?>';
280        var old_color = null;
281
282        function pickColor(color) {
283                jQuery('#name').css('color', color);
284                jQuery('#desc').css('color', color);
285                jQuery('#text-color').val(color);
286                farbtastic.setColor(color);
287        }
288
289        function toggle_text(s) {
290                if (jQuery(s).attr('id') == 'showtext' && jQuery('#text-color').val() != 'blank')
291                        return;
292
293                if (jQuery(s).attr('id') == 'hidetext' && jQuery('#text-color').val() == 'blank')
294                        return;
295
296                if (jQuery('#text-color').val() == 'blank') {
297                        //Show text
298                        if (old_color == '#blank')
299                                old_color = default_color;
300
301                        jQuery( text_objects.toString() ).show();
302                        jQuery('#text-color').val(old_color);
303                        jQuery('#name').css('color', old_color);
304                        jQuery('#desc').css('color', old_color);
305                        pickColor(old_color);
306                } else {
307                        //Hide text
308                        jQuery( text_objects.toString() ).hide();
309                        old_color = jQuery('#text-color').val();
310                        jQuery('#text-color').val('blank');
311                }
312        }
313
314        jQuery(document).ready(function() {
315                jQuery('#pickcolor').click(function() {
316                        jQuery('#color-picker').show();
317                });
318
319                jQuery('input[name="hidetext"]').click(function() {
320                        toggle_text(this);
321                });
322
323                jQuery('#defaultcolor').click(function() {
324                        pickColor(default_color);
325                        jQuery('#text-color').val(default_color)
326                });
327
328                jQuery('#text-color').keyup(function() {
329                        var _hex = jQuery('#text-color').val();
330                        var hex = _hex;
331                        if ( hex[0] != '#' )
332                                hex = '#' + hex;
333                        hex = hex.replace(/[^#a-fA-F0-9]+/, '');
334                        if ( hex != _hex )
335                                jQuery('#text-color').val(hex);
336                        if ( hex.length == 4 || hex.length == 7 )
337                                pickColor( hex );
338                });
339
340                jQuery(document).mousedown(function(){
341                        jQuery('#color-picker').each( function() {
342                                var display = jQuery(this).css('display');
343                                if (display == 'block')
344                                        jQuery(this).fadeOut(2);
345                        });
346                });
347
348                farbtastic = jQuery.farbtastic('#color-picker', function(color) { pickColor(color); });
349                <?php if ( $color = get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) ) { ?>
350                pickColor('#<?php echo $color; ?>');
351                <?php } ?>
352
353                <?php if ( 'blank' == get_theme_mod( 'header_textcolor', HEADER_TEXTCOLOR ) || '' == get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) || ! $this->header_text() ) { ?>
354                toggle_text();
355                <?php } ?>
356                });
357</script>
358<?php
359        }
360
361        /**
362         * Display Javascript based on Step 2.
363         *
364         * @since 2.6.0
365         */
366        function js_2() { ?>
367<script type="text/javascript">
368/* <![CDATA[ */
369        function onEndCrop( coords ) {
370                jQuery( '#x1' ).val(coords.x);
371                jQuery( '#y1' ).val(coords.y);
372                jQuery( '#width' ).val(coords.w);
373                jQuery( '#height' ).val(coords.h);
374        }
375
376        jQuery(document).ready(function() {
377                var xinit = <?php echo HEADER_IMAGE_WIDTH; ?>;
378                var yinit = <?php echo HEADER_IMAGE_HEIGHT; ?>;
379                var ratio = xinit / yinit;
380                var ximg = jQuery('img#upload').width();
381                var yimg = jQuery('img#upload').height();
382
383                if ( yimg < yinit || ximg < xinit ) {
384                        if ( ximg / yimg > ratio ) {
385                                yinit = yimg;
386                                xinit = yinit * ratio;
387                        } else {
388                                xinit = ximg;
389                                yinit = xinit / ratio;
390                        }
391                }
392
393                jQuery('img#upload').imgAreaSelect({
394                        handles: true,
395                        keys: true,
396                        aspectRatio: xinit + ':' + yinit,
397                        show: true,
398                        x1: 0,
399                        y1: 0,
400                        x2: xinit,
401                        y2: yinit,
402                        maxHeight: <?php echo HEADER_IMAGE_HEIGHT; ?>,
403                        maxWidth: <?php echo HEADER_IMAGE_WIDTH; ?>,
404                        onInit: function () {
405                                jQuery('#width').val(xinit);
406                                jQuery('#height').val(yinit);
407                        },
408                        onSelectChange: function(img, c) {
409                                jQuery('#x1').val(c.x1);
410                                jQuery('#y1').val(c.y1);
411                                jQuery('#width').val(c.width);
412                                jQuery('#height').val(c.height);
413                        }
414                });
415        });
416/* ]]> */
417</script>
418<?php
419        }
420
421        /**
422         * Display first step of custom header image page.
423         *
424         * @since 2.1.0
425         */
426        function step_1() {
427                $this->process_default_headers();
428?>
429
430<div class="wrap">
431<?php screen_icon(); ?>
432<h2><?php _e('Custom Header'); ?></h2>
433
434<?php if ( ! empty( $this->updated ) ) { ?>
435<div id="message" class="updated">
436<p><?php printf( __( 'Header updated. <a href="%s">Visit your site</a> to see how it looks.' ), home_url( '/' ) ); ?></p>
437</div>
438<?php } ?>
439
440<h3><?php _e( 'Header Image' ) ?></h3>
441<table class="form-table">
442<tbody>
443
444
445<tr valign="top">
446<th scope="row"><?php _e( 'Preview' ); ?></th>
447<td >
448        <?php if ( $this->admin_image_div_callback ) {
449          call_user_func( $this->admin_image_div_callback );
450        } else {
451        ?>
452        <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() ) ?>);">
453                <?php
454                if ( 'blank' == get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) || '' == get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) || ! $this->header_text() )
455                        $style = ' style="display:none;"';
456                else
457                        $style = ' style="color:#' . get_theme_mod( 'header_textcolor', HEADER_TEXTCOLOR ) . ';"';
458                ?>
459                <h1><a id="name"<?php echo $style; ?> onclick="return false;" href="<?php bloginfo('url'); ?>"><?php bloginfo( 'name' ); ?></a></h1>
460                <div id="desc"<?php echo $style; ?>><?php bloginfo( 'description' ); ?></div>
461        </div>
462        <?php } ?>
463</td>
464</tr>
465
466<tr valign="top">
467<th scope="row"><?php _e( 'Upload Image' ); ?></th>
468<td>
469        <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 />
470        <?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>
471        <form enctype="multipart/form-data" id="upload-form" method="post" action="<?php echo esc_attr( add_query_arg( 'step', 2 ) ) ?>">
472        <p>
473                <label for="upload"><?php _e( 'Choose an image from your computer:' ); ?></label><br />
474                <input type="file" id="upload" name="import" />
475                <input type="hidden" name="action" value="save" />
476                <?php wp_nonce_field( 'custom-header-upload', '_wpnonce-custom-header-upload' ) ?>
477                <input type="submit" class="button" value="<?php esc_attr_e( 'Upload' ); ?>" />
478        </p>
479        </form>
480</td>
481</tr>
482
483</tbody>
484</table>
485
486<form method="post" action="<?php echo esc_attr( add_query_arg( 'step', 1 ) ) ?>">
487<table class="form-table">
488<tbody>
489        <?php if ( ! empty( $this->default_headers ) ) : ?>
490<tr valign="top">
491<th scope="row"><?php _e( 'Default Images' ); ?></th>
492<td>
493        <p><?php _e( 'If you don&lsquo;t want to upload your own image, you can use one of these cool headers.' ) ?></p>
494        <?php
495                $this->show_default_header_selector();
496        ?>
497</td>
498</tr>
499        <?php endif;
500
501 ?>
502<tr valign="top">
503<th scope="row"><?php _e( 'Alternative Text' ); ?></th>
504<td>
505<fieldset>
506    <legend class="screen-reader-text">
507        <span><?php _e( 'Alternative Text' ); ?></span>
508    </legend>
509    <input type="text" name="alt-text" id="alt-text" value="<?php echo esc_attr(get_background_alt()) ?>" />
510</fieldset></td>
511</tr>
512<?php
513        if ( get_header_image() ) : ?>
514<tr valign="top">
515<th scope="row"><?php _e( 'Remove Image' ); ?></th>
516<td>
517        <p><?php _e( 'This will remove the header image. You will not be able to restore any customizations.' ) ?></p>
518        <input type="submit" class="button" name="removeheader" value="<?php esc_attr_e( 'Remove Header Image' ); ?>" />
519</td>
520</tr>
521        <?php endif;
522
523        if ( defined( 'HEADER_IMAGE' ) ) : ?>
524<tr valign="top">
525<th scope="row"><?php _e( 'Reset Image' ); ?></th>
526<td>
527        <p><?php _e( 'This will restore the original header image. You will not be able to restore any customizations.' ) ?></p>
528        <input type="submit" class="button" name="resetheader" value="<?php esc_attr_e( 'Restore Original Header Image' ); ?>" />
529</td>
530</tr>
531        <?php endif; ?>
532</tbody>
533</table>
534
535        <?php if ( $this->header_text() ) : ?>
536<h3><?php _e( 'Header Text' ) ?></h3>
537<table class="form-table">
538<tbody>
539<tr valign="top" class="hide-if-no-js">
540<th scope="row"><?php _e( 'Display Text' ); ?></th>
541<td>
542        <p>
543        <?php $hidetext = get_theme_mod( 'header_textcolor', HEADER_TEXTCOLOR ); ?>
544        <label><input type="radio" value="1" name="hidetext" id="hidetext"<?php checked( ( 'blank' == $hidetext || empty( $hidetext ) )  ? true : false ); ?> /> <?php _e( 'No' ); ?></label>
545        <label><input type="radio" value="0" name="hidetext" id="showtext"<?php checked( ( 'blank' == $hidetext || empty( $hidetext ) ) ? false : true ); ?> /> <?php _e( 'Yes' ); ?></label>
546        </p>
547</td>
548</tr>
549
550<tr valign="top" id="text-color-row">
551<th scope="row"><?php _e( 'Text Color' ); ?></th>
552<td>
553        <p>
554                <input type="text" name="text-color" id="text-color" value="#<?php echo esc_attr( get_theme_mod( 'header_textcolor', HEADER_TEXTCOLOR ) ); ?>" />
555                <span class="description hide-if-js"><?php _e( 'If you want to hide header text, add <strong>#blank</strong> as text color.' );?></span>
556                <input type="button" class="button hide-if-no-js" value="<?php esc_attr_e( 'Select a Color' ); ?>" id="pickcolor" />
557        </p>
558        <div id="color-picker" style="z-index: 100; background:#eee; border:1px solid #ccc; position:absolute; display:none;"></div>
559</td>
560</tr>
561
562        <?php if ( defined('HEADER_TEXTCOLOR') && get_theme_mod('header_textcolor') ) { ?>
563<tr valign="top">
564<th scope="row"><?php _e('Reset Text Color'); ?></th>
565<td>
566        <p><?php _e( 'This will restore the original header text. You will not be able to restore any customizations.' ) ?></p>
567        <input type="submit" class="button" name="resettext" value="<?php esc_attr_e( 'Restore Original Header Text' ); ?>" />
568</td>
569</tr>
570        <?php } ?>
571
572</tbody>
573</table>
574        <?php endif;
575
576wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?>
577<p class="submit"><input type="submit" class="button-primary" name="save-header-options" value="<?php esc_attr_e( 'Save Changes' ); ?>" /></p>
578</form>
579</div>
580
581<?php }
582
583        /**
584         * Display second step of custom header image page.
585         *
586         * @since 2.1.0
587         */
588        function step_2() {
589                check_admin_referer('custom-header-upload', '_wpnonce-custom-header-upload');
590                $overrides = array('test_form' => false);
591                $file = wp_handle_upload($_FILES['import'], $overrides);
592
593                if ( isset($file['error']) )
594                        wp_die( $file['error'],  __( 'Image Upload Error' ) );
595
596                $url = $file['url'];
597                $type = $file['type'];
598                $file = $file['file'];
599                $filename = basename($file);
600
601                // Construct the object array
602                $object = array(
603                'post_title' => $filename,
604                'post_content' => $url,
605                'post_mime_type' => $type,
606                'guid' => $url);
607
608                // Save the data
609                $id = wp_insert_attachment($object, $file);
610
611                list($width, $height, $type, $attr) = getimagesize( $file );
612
613                if ( $width == HEADER_IMAGE_WIDTH && $height == HEADER_IMAGE_HEIGHT ) {
614                        // Add the meta-data
615                        wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
616
617                        set_theme_mod('header_image', esc_url($url));
618                        do_action('wp_create_file_in_uploads', $file, $id); // For replication
619                        return $this->finished();
620                } elseif ( $width > HEADER_IMAGE_WIDTH ) {
621                        $oitar = $width / HEADER_IMAGE_WIDTH;
622                        $image = wp_crop_image($file, 0, 0, $width, $height, HEADER_IMAGE_WIDTH, $height / $oitar, false, str_replace(basename($file), 'midsize-'.basename($file), $file));
623                        if ( is_wp_error( $image ) )
624                                wp_die( __( 'Image could not be processed.  Please go back and try again.' ), __( 'Image Processing Error' ) );
625
626                        $image = apply_filters('wp_create_file_in_uploads', $image, $id); // For replication
627
628                        $url = str_replace(basename($url), basename($image), $url);
629                        $width = $width / $oitar;
630                        $height = $height / $oitar;
631                } else {
632                        $oitar = 1;
633                }
634                ?>
635
636<div class="wrap">
637<?php screen_icon(); ?>
638<h2><?php _e( 'Crop Header Image' ); ?></h2>
639
640<form method="post" action="<?php echo esc_attr(add_query_arg('step', 3)); ?>">
641        <p class="hide-if-no-js"><?php _e('Choose the part of the image you want to use as your header.'); ?></p>
642        <p class="hide-if-js"><strong><?php _e( 'You need Javascript to choose a part of the image.'); ?></strong></p>
643
644        <div id="crop_image" style="position: relative">
645                <img src="<?php echo esc_url( $url ); ?>" id="upload" width="<?php echo $width; ?>" height="<?php echo $height; ?>" />
646        </div>
647
648        <p class="submit">
649        <input type="hidden" name="x1" id="x1" value="0"/>
650        <input type="hidden" name="y1" id="y1" value="0"/>
651        <input type="hidden" name="width" id="width" value="<?php echo esc_attr( $width ); ?>"/>
652        <input type="hidden" name="height" id="height" value="<?php echo esc_attr( $height ); ?>"/>
653        <input type="hidden" name="attachment_id" id="attachment_id" value="<?php echo esc_attr( $id ); ?>" />
654        <input type="hidden" name="oitar" id="oitar" value="<?php echo esc_attr( $oitar ); ?>" />
655        <?php wp_nonce_field( 'custom-header-crop-image' ) ?>
656        <input type="submit" class="button-primary" value="<?php esc_attr_e( 'Crop and Publish' ); ?>" />
657        </p>
658</form>
659</div>
660                <?php
661        }
662
663        /**
664         * Display third step of custom header image page.
665         *
666         * @since 2.1.0
667         */
668        function step_3() {
669                check_admin_referer('custom-header-crop-image');
670                if ( $_POST['oitar'] > 1 ) {
671                        $_POST['x1'] = $_POST['x1'] * $_POST['oitar'];
672                        $_POST['y1'] = $_POST['y1'] * $_POST['oitar'];
673                        $_POST['width'] = $_POST['width'] * $_POST['oitar'];
674                        $_POST['height'] = $_POST['height'] * $_POST['oitar'];
675                }
676
677                $original = get_attached_file( $_POST['attachment_id'] );
678
679                $cropped = wp_crop_image($_POST['attachment_id'], $_POST['x1'], $_POST['y1'], $_POST['width'], $_POST['height'], HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT);
680                if ( is_wp_error( $cropped ) )
681                        wp_die( __( 'Image could not be processed.  Please go back and try again.' ), __( 'Image Processing Error' ) );
682
683                $cropped = apply_filters('wp_create_file_in_uploads', $cropped, $_POST['attachment_id']); // For replication
684
685                $parent = get_post($_POST['attachment_id']);
686                $parent_url = $parent->guid;
687                $url = str_replace(basename($parent_url), basename($cropped), $parent_url);
688
689                // Construct the object array
690                $object = array(
691                        'ID' => $_POST['attachment_id'],
692                        'post_title' => basename($cropped),
693                        'post_content' => $url,
694                        'post_mime_type' => 'image/jpeg',
695                        'guid' => $url
696                );
697
698                // Update the attachment
699                wp_insert_attachment($object, $cropped);
700                wp_update_attachment_metadata( $_POST['attachment_id'], wp_generate_attachment_metadata( $_POST['attachment_id'], $cropped ) );
701
702                set_theme_mod('header_image', $url);
703
704                // cleanup
705                $medium = str_replace(basename($original), 'midsize-'.basename($original), $original);
706                @unlink( apply_filters( 'wp_delete_file', $medium ) );
707                @unlink( apply_filters( 'wp_delete_file', $original ) );
708
709                return $this->finished();
710        }
711
712        /**
713         * Display last step of custom header image page.
714         *
715         * @since 2.1.0
716         */
717        function finished() {
718                $this->updated = true;
719                $this->step_1();
720        }
721
722        /**
723         * Display the page based on the current step.
724         *
725         * @since 2.1.0
726         */
727        function admin_page() {
728                if ( ! current_user_can('edit_theme_options') )
729                        wp_die(__('You do not have permission to customize headers.'));
730                $step = $this->step();
731                if ( 1 == $step )
732                        $this->step_1();
733                elseif ( 2 == $step )
734                        $this->step_2();
735                elseif ( 3 == $step )
736                        $this->step_3();
737        }
738
739}
740?>