18 /** |
18 /** |
19 * Callback for administration header. |
19 * Callback for administration header. |
20 * |
20 * |
21 * @var callback |
21 * @var callback |
22 * @since 2.1.0 |
22 * @since 2.1.0 |
23 * @access private |
23 */ |
24 */ |
24 public $admin_header_callback; |
25 var $admin_header_callback; |
|
26 |
25 |
27 /** |
26 /** |
28 * Callback for header div. |
27 * Callback for header div. |
29 * |
28 * |
30 * @var callback |
29 * @var callback |
31 * @since 3.0.0 |
30 * @since 3.0.0 |
32 * @access private |
31 */ |
33 */ |
32 public $admin_image_div_callback; |
34 var $admin_image_div_callback; |
|
35 |
33 |
36 /** |
34 /** |
37 * Holds default headers. |
35 * Holds default headers. |
38 * |
36 * |
39 * @var array |
37 * @var array |
40 * @since 3.0.0 |
38 * @since 3.0.0 |
41 * @access private |
39 * @access private |
42 */ |
40 */ |
43 var $default_headers = array(); |
41 public $default_headers = array(); |
44 |
42 |
45 /** |
43 /** |
46 * Holds custom headers uploaded by the user |
44 * @var bool |
47 * |
45 */ |
48 * @var array |
46 private $updated; |
49 * @since 3.2.0 |
|
50 * @access private |
|
51 */ |
|
52 var $uploaded_headers = array(); |
|
53 |
|
54 /** |
|
55 * Holds the page menu hook. |
|
56 * |
|
57 * @var string |
|
58 * @since 3.0.0 |
|
59 * @access private |
|
60 */ |
|
61 var $page = ''; |
|
62 |
47 |
63 /** |
48 /** |
64 * Constructor - Register administration header callback. |
49 * Constructor - Register administration header callback. |
65 * |
50 * |
66 * @since 2.1.0 |
51 * @since 2.1.0 |
67 * @param callback $admin_header_callback |
52 * @param callback $admin_header_callback |
68 * @param callback $admin_image_div_callback Optional custom image div output callback. |
53 * @param callback $admin_image_div_callback Optional custom image div output callback. |
69 * @return Custom_Image_Header |
54 */ |
70 */ |
55 public function __construct($admin_header_callback, $admin_image_div_callback = '') { |
71 function __construct($admin_header_callback, $admin_image_div_callback = '') { |
|
72 $this->admin_header_callback = $admin_header_callback; |
56 $this->admin_header_callback = $admin_header_callback; |
73 $this->admin_image_div_callback = $admin_image_div_callback; |
57 $this->admin_image_div_callback = $admin_image_div_callback; |
74 |
58 |
75 add_action( 'admin_menu', array( $this, 'init' ) ); |
59 add_action( 'admin_menu', array( $this, 'init' ) ); |
|
60 |
|
61 add_action( 'customize_save_after', array( $this, 'customize_set_last_used' ) ); |
|
62 add_action( 'wp_ajax_custom-header-crop', array( $this, 'ajax_header_crop' ) ); |
|
63 add_action( 'wp_ajax_custom-header-add', array( $this, 'ajax_header_add' ) ); |
|
64 add_action( 'wp_ajax_custom-header-remove', array( $this, 'ajax_header_remove' ) ); |
76 } |
65 } |
77 |
66 |
78 /** |
67 /** |
79 * Set up the hooks for the Custom Header admin page. |
68 * Set up the hooks for the Custom Header admin page. |
80 * |
69 * |
81 * @since 2.1.0 |
70 * @since 2.1.0 |
82 */ |
71 */ |
83 function init() { |
72 public function init() { |
84 if ( ! current_user_can('edit_theme_options') ) |
73 $page = add_theme_page( __( 'Header' ), __( 'Header' ), 'edit_theme_options', 'custom-header', array( $this, 'admin_page' ) ); |
|
74 if ( ! $page ) { |
85 return; |
75 return; |
86 |
76 } |
87 $this->page = $page = add_theme_page(__('Header'), __('Header'), 'edit_theme_options', 'custom-header', array($this, 'admin_page')); |
77 |
88 |
78 add_action( "admin_print_scripts-$page", array( $this, 'js_includes' ) ); |
89 add_action("admin_print_scripts-$page", array($this, 'js_includes')); |
79 add_action( "admin_print_styles-$page", array( $this, 'css_includes' ) ); |
90 add_action("admin_print_styles-$page", array($this, 'css_includes')); |
80 add_action( "admin_head-$page", array( $this, 'help' ) ); |
91 add_action("admin_head-$page", array($this, 'help') ); |
81 add_action( "admin_head-$page", array( $this, 'take_action' ), 50 ); |
92 add_action("admin_head-$page", array($this, 'take_action'), 50); |
82 add_action( "admin_head-$page", array( $this, 'js' ), 50 ); |
93 add_action("admin_head-$page", array($this, 'js'), 50); |
83 if ( $this->admin_header_callback ) { |
94 if ( $this->admin_header_callback ) |
84 add_action( "admin_head-$page", $this->admin_header_callback, 51 ); |
95 add_action("admin_head-$page", $this->admin_header_callback, 51); |
85 } |
96 } |
86 } |
97 |
87 |
98 /** |
88 /** |
99 * Adds contextual help. |
89 * Adds contextual help. |
100 * |
90 * |
101 * @since 3.0.0 |
91 * @since 3.0.0 |
102 */ |
92 */ |
103 function help() { |
93 public function help() { |
104 get_current_screen()->add_help_tab( array( |
94 get_current_screen()->add_help_tab( array( |
105 'id' => 'overview', |
95 'id' => 'overview', |
106 'title' => __('Overview'), |
96 'title' => __('Overview'), |
107 'content' => |
97 'content' => |
108 '<p>' . __( 'This screen is used to customize the header section of your theme.') . '</p>' . |
98 '<p>' . __( 'This screen is used to customize the header section of your theme.') . '</p>' . |
237 /** |
227 /** |
238 * Process the default headers |
228 * Process the default headers |
239 * |
229 * |
240 * @since 3.0.0 |
230 * @since 3.0.0 |
241 */ |
231 */ |
242 function process_default_headers() { |
232 public function process_default_headers() { |
243 global $_wp_default_headers; |
233 global $_wp_default_headers; |
244 |
|
245 if ( !empty($this->headers) ) |
|
246 return; |
|
247 |
234 |
248 if ( !isset($_wp_default_headers) ) |
235 if ( !isset($_wp_default_headers) ) |
249 return; |
236 return; |
|
237 |
|
238 if ( ! empty( $this->default_headers ) ) { |
|
239 return; |
|
240 } |
250 |
241 |
251 $this->default_headers = $_wp_default_headers; |
242 $this->default_headers = $_wp_default_headers; |
252 $template_directory_uri = get_template_directory_uri(); |
243 $template_directory_uri = get_template_directory_uri(); |
253 $stylesheet_directory_uri = get_stylesheet_directory_uri(); |
244 $stylesheet_directory_uri = get_stylesheet_directory_uri(); |
254 foreach ( array_keys($this->default_headers) as $header ) { |
245 foreach ( array_keys($this->default_headers) as $header ) { |
255 $this->default_headers[$header]['url'] = sprintf( $this->default_headers[$header]['url'], $template_directory_uri, $stylesheet_directory_uri ); |
246 $this->default_headers[$header]['url'] = sprintf( $this->default_headers[$header]['url'], $template_directory_uri, $stylesheet_directory_uri ); |
256 $this->default_headers[$header]['thumbnail_url'] = sprintf( $this->default_headers[$header]['thumbnail_url'], $template_directory_uri, $stylesheet_directory_uri ); |
247 $this->default_headers[$header]['thumbnail_url'] = sprintf( $this->default_headers[$header]['thumbnail_url'], $template_directory_uri, $stylesheet_directory_uri ); |
257 } |
248 } |
258 |
|
259 } |
249 } |
260 |
250 |
261 /** |
251 /** |
262 * Display UI for selecting one of several default headers. |
252 * Display UI for selecting one of several default headers. |
263 * |
253 * |
264 * Show the random image option if this theme has multiple header images. |
254 * Show the random image option if this theme has multiple header images. |
265 * Random image option is on by default if no header has been set. |
255 * Random image option is on by default if no header has been set. |
266 * |
256 * |
267 * @since 3.0.0 |
257 * @since 3.0.0 |
268 */ |
258 */ |
269 function show_header_selector( $type = 'default' ) { |
259 public function show_header_selector( $type = 'default' ) { |
270 if ( 'default' == $type ) { |
260 if ( 'default' == $type ) { |
271 $headers = $this->default_headers; |
261 $headers = $this->default_headers; |
272 } else { |
262 } else { |
273 $headers = get_uploaded_header_images(); |
263 $headers = get_uploaded_header_images(); |
274 $type = 'uploaded'; |
264 $type = 'uploaded'; |
530 '_wpnonce-custom-header-upload' => wp_create_nonce('custom-header-upload'), |
545 '_wpnonce-custom-header-upload' => wp_create_nonce('custom-header-upload'), |
531 ), admin_url('themes.php') ) ); |
546 ), admin_url('themes.php') ) ); |
532 ?> |
547 ?> |
533 <p> |
548 <p> |
534 <label for="choose-from-library-link"><?php _e( 'Or choose an image from your media library:' ); ?></label><br /> |
549 <label for="choose-from-library-link"><?php _e( 'Or choose an image from your media library:' ); ?></label><br /> |
535 <a id="choose-from-library-link" class="button" |
550 <button id="choose-from-library-link" class="button" |
536 data-update-link="<?php echo esc_attr( $modal_update_href ); ?>" |
551 data-update-link="<?php echo esc_attr( $modal_update_href ); ?>" |
537 data-choose="<?php esc_attr_e( 'Choose a Custom Header' ); ?>" |
552 data-choose="<?php esc_attr_e( 'Choose a Custom Header' ); ?>" |
538 data-update="<?php esc_attr_e( 'Set as header' ); ?>"><?php _e( 'Choose Image' ); ?></a> |
553 data-update="<?php esc_attr_e( 'Set as header' ); ?>"><?php _e( 'Choose Image' ); ?></button> |
539 </p> |
554 </p> |
540 </form> |
555 </form> |
541 </td> |
556 </td> |
542 </tr> |
557 </tr> |
543 <?php endif; ?> |
558 <?php endif; ?> |
544 </tbody> |
559 </tbody> |
545 </table> |
560 </table> |
546 |
561 |
547 <form method="post" action="<?php echo esc_url( add_query_arg( 'step', 1 ) ) ?>"> |
562 <form method="post" action="<?php echo esc_url( add_query_arg( 'step', 1 ) ) ?>"> |
|
563 <?php submit_button( null, 'screen-reader-text', 'save-header-options', false ); ?> |
548 <table class="form-table"> |
564 <table class="form-table"> |
549 <tbody> |
565 <tbody> |
550 <?php if ( get_uploaded_header_images() ) : ?> |
566 <?php if ( get_uploaded_header_images() ) : ?> |
551 <tr valign="top"> |
567 <tr> |
552 <th scope="row"><?php _e( 'Uploaded Images' ); ?></th> |
568 <th scope="row"><?php _e( 'Uploaded Images' ); ?></th> |
553 <td> |
569 <td> |
554 <p><?php _e( 'You can choose one of your previously uploaded headers, or show a random one.' ) ?></p> |
570 <p><?php _e( 'You can choose one of your previously uploaded headers, or show a random one.' ) ?></p> |
555 <?php |
571 <?php |
556 $this->show_header_selector( 'uploaded' ); |
572 $this->show_header_selector( 'uploaded' ); |
557 ?> |
573 ?> |
558 </td> |
574 </td> |
559 </tr> |
575 </tr> |
560 <?php endif; |
576 <?php endif; |
561 if ( ! empty( $this->default_headers ) ) : ?> |
577 if ( ! empty( $this->default_headers ) ) : ?> |
562 <tr valign="top"> |
578 <tr> |
563 <th scope="row"><?php _e( 'Default Images' ); ?></th> |
579 <th scope="row"><?php _e( 'Default Images' ); ?></th> |
564 <td> |
580 <td> |
565 <?php if ( current_theme_supports( 'custom-header', 'uploads' ) ) : ?> |
581 <?php if ( current_theme_supports( 'custom-header', 'uploads' ) ) : ?> |
566 <p><?php _e( 'If you don‘t want to upload your own image, you can use one of these cool headers, or show a random one.' ) ?></p> |
582 <p><?php _e( 'If you don‘t want to upload your own image, you can use one of these cool headers, or show a random one.' ) ?></p> |
567 <?php else: ?> |
583 <?php else: ?> |
600 |
616 |
601 <h3><?php _e( 'Header Text' ); ?></h3> |
617 <h3><?php _e( 'Header Text' ); ?></h3> |
602 |
618 |
603 <table class="form-table"> |
619 <table class="form-table"> |
604 <tbody> |
620 <tbody> |
605 <tr valign="top"> |
621 <tr> |
606 <th scope="row"><?php _e( 'Header Text' ); ?></th> |
622 <th scope="row"><?php _e( 'Header Text' ); ?></th> |
607 <td> |
623 <td> |
608 <p> |
624 <p> |
609 <label><input type="checkbox" name="display-header-text" id="display-header-text"<?php checked( display_header_text() ); ?> /> <?php _e( 'Show header text with your image.' ); ?></label> |
625 <label><input type="checkbox" name="display-header-text" id="display-header-text"<?php checked( display_header_text() ); ?> /> <?php _e( 'Show header text with your image.' ); ?></label> |
610 </p> |
626 </p> |
611 </td> |
627 </td> |
612 </tr> |
628 </tr> |
613 |
629 |
614 <tr valign="top" class="displaying-header-text"> |
630 <tr class="displaying-header-text"> |
615 <th scope="row"><?php _e( 'Text Color' ); ?></th> |
631 <th scope="row"><?php _e( 'Text Color' ); ?></th> |
616 <td> |
632 <td> |
617 <p> |
633 <p> |
618 <?php |
634 <?php |
619 $header_textcolor = display_header_text() ? get_header_textcolor() : get_theme_support( 'custom-header', 'default-text-color' ); |
635 $default_color = ''; |
620 $default_color = ''; |
636 if ( current_theme_supports( 'custom-header', 'default-text-color' ) ) { |
621 if ( current_theme_supports( 'custom-header', 'default-text-color' ) ) { |
637 $default_color = get_theme_support( 'custom-header', 'default-text-color' ); |
622 $default_color = '#' . get_theme_support( 'custom-header', 'default-text-color' ); |
638 if ( $default_color && false === strpos( $default_color, '#' ) ) { |
623 $default_color_attr = ' data-default-color="' . esc_attr( $default_color ) . '"'; |
639 $default_color = '#' . $default_color; |
624 echo '<input type="text" name="text-color" id="text-color" value="#' . esc_attr( $header_textcolor ) . '"' . $default_color_attr . ' />'; |
640 } |
625 if ( $default_color ) |
641 } |
626 echo ' <span class="description hide-if-js">' . sprintf( _x( 'Default: %s', 'color' ), $default_color ) . '</span>'; |
642 |
627 } |
643 $default_color_attr = $default_color ? ' data-default-color="' . esc_attr( $default_color ) . '"' : ''; |
628 ?> |
644 |
|
645 $header_textcolor = display_header_text() ? get_header_textcolor() : get_theme_support( 'custom-header', 'default-text-color' ); |
|
646 if ( $header_textcolor && false === strpos( $header_textcolor, '#' ) ) { |
|
647 $header_textcolor = '#' . $header_textcolor; |
|
648 } |
|
649 |
|
650 echo '<input type="text" name="text-color" id="text-color" value="' . esc_attr( $header_textcolor ) . '"' . $default_color_attr . ' />'; |
|
651 if ( $default_color ) { |
|
652 echo ' <span class="description hide-if-js">' . sprintf( _x( 'Default: %s', 'color' ), esc_html( $default_color ) ) . '</span>'; |
|
653 } |
|
654 ?> |
629 </p> |
655 </p> |
630 </td> |
656 </td> |
631 </tr> |
657 </tr> |
632 </tbody> |
658 </tbody> |
633 </table> |
659 </table> |
818 } |
846 } |
819 |
847 |
820 $attachment_id = absint( $_POST['attachment_id'] ); |
848 $attachment_id = absint( $_POST['attachment_id'] ); |
821 $original = get_attached_file($attachment_id); |
849 $original = get_attached_file($attachment_id); |
822 |
850 |
823 |
851 $dimensions = $this->get_header_dimensions( array( |
824 $max_width = 0; |
852 'height' => $_POST['height'], |
825 // For flex, limit size of image displayed to 1500px unless theme says otherwise |
853 'width' => $_POST['width'], |
826 if ( current_theme_supports( 'custom-header', 'flex-width' ) ) |
854 ) ); |
827 $max_width = 1500; |
855 $height = $dimensions['dst_height']; |
828 |
856 $width = $dimensions['dst_width']; |
829 if ( current_theme_supports( 'custom-header', 'max-width' ) ) |
|
830 $max_width = max( $max_width, get_theme_support( 'custom-header', 'max-width' ) ); |
|
831 $max_width = max( $max_width, get_theme_support( 'custom-header', 'width' ) ); |
|
832 |
|
833 if ( ( current_theme_supports( 'custom-header', 'flex-height' ) && ! current_theme_supports( 'custom-header', 'flex-width' ) ) || $_POST['width'] > $max_width ) |
|
834 $dst_height = absint( $_POST['height'] * ( $max_width / $_POST['width'] ) ); |
|
835 elseif ( current_theme_supports( 'custom-header', 'flex-height' ) && current_theme_supports( 'custom-header', 'flex-width' ) ) |
|
836 $dst_height = absint( $_POST['height'] ); |
|
837 else |
|
838 $dst_height = get_theme_support( 'custom-header', 'height' ); |
|
839 |
|
840 if ( ( current_theme_supports( 'custom-header', 'flex-width' ) && ! current_theme_supports( 'custom-header', 'flex-height' ) ) || $_POST['width'] > $max_width ) |
|
841 $dst_width = absint( $_POST['width'] * ( $max_width / $_POST['width'] ) ); |
|
842 elseif ( current_theme_supports( 'custom-header', 'flex-width' ) && current_theme_supports( 'custom-header', 'flex-height' ) ) |
|
843 $dst_width = absint( $_POST['width'] ); |
|
844 else |
|
845 $dst_width = get_theme_support( 'custom-header', 'width' ); |
|
846 |
857 |
847 if ( empty( $_POST['skip-cropping'] ) ) |
858 if ( empty( $_POST['skip-cropping'] ) ) |
848 $cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], $dst_width, $dst_height ); |
859 $cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], $width, $height ); |
849 elseif ( ! empty( $_POST['create-new-attachment'] ) ) |
860 elseif ( ! empty( $_POST['create-new-attachment'] ) ) |
850 $cropped = _copy_image_file( $attachment_id ); |
861 $cropped = _copy_image_file( $attachment_id ); |
851 else |
862 else |
852 $cropped = get_attached_file( $attachment_id ); |
863 $cropped = get_attached_file( $attachment_id ); |
853 |
864 |
855 wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) ); |
866 wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) ); |
856 |
867 |
857 /** This filter is documented in wp-admin/custom-header.php */ |
868 /** This filter is documented in wp-admin/custom-header.php */ |
858 $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication |
869 $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication |
859 |
870 |
860 $parent = get_post($attachment_id); |
871 $object = $this->create_attachment_object( $cropped, $attachment_id ); |
861 $parent_url = $parent->guid; |
872 |
862 $url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url ); |
|
863 |
|
864 $size = @getimagesize( $cropped ); |
|
865 $image_type = ( $size ) ? $size['mime'] : 'image/jpeg'; |
|
866 |
|
867 // Construct the object array |
|
868 $object = array( |
|
869 'ID' => $attachment_id, |
|
870 'post_title' => basename($cropped), |
|
871 'post_content' => $url, |
|
872 'post_mime_type' => $image_type, |
|
873 'guid' => $url, |
|
874 'context' => 'custom-header' |
|
875 ); |
|
876 if ( ! empty( $_POST['create-new-attachment'] ) ) |
873 if ( ! empty( $_POST['create-new-attachment'] ) ) |
877 unset( $object['ID'] ); |
874 unset( $object['ID'] ); |
878 |
875 |
879 // Update the attachment |
876 // Update the attachment |
880 $attachment_id = wp_insert_attachment( $object, $cropped ); |
877 $attachment_id = $this->insert_attachment( $object, $cropped ); |
881 wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $cropped ) ); |
878 |
882 |
879 $url = $object['guid']; |
883 $width = $dst_width; |
|
884 $height = $dst_height; |
|
885 $this->set_header_image( compact( 'url', 'attachment_id', 'width', 'height' ) ); |
880 $this->set_header_image( compact( 'url', 'attachment_id', 'width', 'height' ) ); |
886 |
881 |
887 // cleanup |
882 // Cleanup. |
888 $medium = str_replace( basename( $original ), 'midsize-' . basename( $original ), $original ); |
883 $medium = str_replace( basename( $original ), 'midsize-' . basename( $original ), $original ); |
889 if ( file_exists( $medium ) ) { |
884 if ( file_exists( $medium ) ) { |
890 /** |
885 wp_delete_file( $medium ); |
891 * Filter the path of the file to delete. |
|
892 * |
|
893 * @since 2.1.0 |
|
894 * |
|
895 * @param string $medium Path to the file to delete. |
|
896 */ |
|
897 @unlink( apply_filters( 'wp_delete_file', $medium ) ); |
|
898 } |
886 } |
899 |
887 |
900 if ( empty( $_POST['create-new-attachment'] ) && empty( $_POST['skip-cropping'] ) ) { |
888 if ( empty( $_POST['create-new-attachment'] ) && empty( $_POST['skip-cropping'] ) ) { |
901 /** This filter is documented in wp-admin/custom-header.php */ |
889 wp_delete_file( $original ); |
902 @unlink( apply_filters( 'wp_delete_file', $original ) ); |
|
903 } |
890 } |
904 |
891 |
905 return $this->finished(); |
892 return $this->finished(); |
906 } |
893 } |
907 |
894 |
908 /** |
895 /** |
909 * Display last step of custom header image page. |
896 * Display last step of custom header image page. |
910 * |
897 * |
911 * @since 2.1.0 |
898 * @since 2.1.0 |
912 */ |
899 */ |
913 function finished() { |
900 public function finished() { |
914 $this->updated = true; |
901 $this->updated = true; |
915 $this->step_1(); |
902 $this->step_1(); |
916 } |
903 } |
917 |
904 |
918 /** |
905 /** |
919 * Display the page based on the current step. |
906 * Display the page based on the current step. |
920 * |
907 * |
921 * @since 2.1.0 |
908 * @since 2.1.0 |
922 */ |
909 */ |
923 function admin_page() { |
910 public function admin_page() { |
924 if ( ! current_user_can('edit_theme_options') ) |
911 if ( ! current_user_can('edit_theme_options') ) |
925 wp_die(__('You do not have permission to customize headers.')); |
912 wp_die(__('You do not have permission to customize headers.')); |
926 $step = $this->step(); |
913 $step = $this->step(); |
927 if ( 2 == $step ) |
914 if ( 2 == $step ) |
928 $this->step_2(); |
915 $this->step_2(); |
1040 } |
1027 } |
1041 |
1028 |
1042 set_theme_mod( 'header_image', $default ); |
1029 set_theme_mod( 'header_image', $default ); |
1043 set_theme_mod( 'header_image_data', (object) $default_data ); |
1030 set_theme_mod( 'header_image_data', (object) $default_data ); |
1044 } |
1031 } |
|
1032 |
|
1033 /** |
|
1034 * Calculate width and height based on what the currently selected theme supports. |
|
1035 * |
|
1036 * @return array dst_height and dst_width of header image. |
|
1037 */ |
|
1038 final public function get_header_dimensions( $dimensions ) { |
|
1039 $max_width = 0; |
|
1040 $width = absint( $dimensions['width'] ); |
|
1041 $height = absint( $dimensions['height'] ); |
|
1042 $theme_height = get_theme_support( 'custom-header', 'height' ); |
|
1043 $theme_width = get_theme_support( 'custom-header', 'width' ); |
|
1044 $has_flex_width = current_theme_supports( 'custom-header', 'flex-width' ); |
|
1045 $has_flex_height = current_theme_supports( 'custom-header', 'flex-height' ); |
|
1046 $has_max_width = current_theme_supports( 'custom-header', 'max-width' ) ; |
|
1047 $dst = array( 'dst_height' => null, 'dst_width' => null ); |
|
1048 |
|
1049 // For flex, limit size of image displayed to 1500px unless theme says otherwise |
|
1050 if ( $has_flex_width ) { |
|
1051 $max_width = 1500; |
|
1052 } |
|
1053 |
|
1054 if ( $has_max_width ) { |
|
1055 $max_width = max( $max_width, get_theme_support( 'custom-header', 'max-width' ) ); |
|
1056 } |
|
1057 $max_width = max( $max_width, $theme_width ); |
|
1058 |
|
1059 if ( $has_flex_height && ( ! $has_flex_width || $width > $max_width ) ) { |
|
1060 $dst['dst_height'] = absint( $height * ( $max_width / $width ) ); |
|
1061 } |
|
1062 elseif ( $has_flex_height && $has_flex_width ) { |
|
1063 $dst['dst_height'] = $height; |
|
1064 } |
|
1065 else { |
|
1066 $dst['dst_height'] = $theme_height; |
|
1067 } |
|
1068 |
|
1069 if ( $has_flex_width && ( ! $has_flex_height || $width > $max_width ) ) { |
|
1070 $dst['dst_width'] = absint( $width * ( $max_width / $width ) ); |
|
1071 } |
|
1072 elseif ( $has_flex_width && $has_flex_height ) { |
|
1073 $dst['dst_width'] = $width; |
|
1074 } |
|
1075 else { |
|
1076 $dst['dst_width'] = $theme_width; |
|
1077 } |
|
1078 |
|
1079 return $dst; |
|
1080 } |
|
1081 |
|
1082 /** |
|
1083 * Create an attachment 'object'. |
|
1084 * |
|
1085 * @param string $cropped Cropped image URL. |
|
1086 * @param int $parent_attachment_id Attachment ID of parent image. |
|
1087 * |
|
1088 * @return array Attachment object. |
|
1089 */ |
|
1090 final public function create_attachment_object( $cropped, $parent_attachment_id ) { |
|
1091 $parent = get_post( $parent_attachment_id ); |
|
1092 $parent_url = $parent->guid; |
|
1093 $url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url ); |
|
1094 |
|
1095 $size = @getimagesize( $cropped ); |
|
1096 $image_type = ( $size ) ? $size['mime'] : 'image/jpeg'; |
|
1097 |
|
1098 $object = array( |
|
1099 'ID' => $parent_attachment_id, |
|
1100 'post_title' => basename($cropped), |
|
1101 'post_content' => $url, |
|
1102 'post_mime_type' => $image_type, |
|
1103 'guid' => $url, |
|
1104 'context' => 'custom-header' |
|
1105 ); |
|
1106 |
|
1107 return $object; |
|
1108 } |
|
1109 |
|
1110 /** |
|
1111 * Insert an attachment and its metadata. |
|
1112 * |
|
1113 * @param array $object Attachment object. |
|
1114 * @param string $cropped Cropped image URL. |
|
1115 * |
|
1116 * @return int Attachment ID. |
|
1117 */ |
|
1118 final public function insert_attachment( $object, $cropped ) { |
|
1119 $attachment_id = wp_insert_attachment( $object, $cropped ); |
|
1120 $metadata = wp_generate_attachment_metadata( $attachment_id, $cropped ); |
|
1121 /** |
|
1122 * Filter the header image attachment metadata. |
|
1123 * |
|
1124 * @since 3.9.0 |
|
1125 * |
|
1126 * @see wp_generate_attachment_metadata() |
|
1127 * |
|
1128 * @param array $metadata Attachment metadata. |
|
1129 */ |
|
1130 $metadata = apply_filters( 'wp_header_image_attachment_metadata', $metadata ); |
|
1131 wp_update_attachment_metadata( $attachment_id, $metadata ); |
|
1132 return $attachment_id; |
|
1133 } |
|
1134 |
|
1135 /** |
|
1136 * Gets attachment uploaded by Media Manager, crops it, then saves it as a |
|
1137 * new object. Returns JSON-encoded object details. |
|
1138 */ |
|
1139 public function ajax_header_crop() { |
|
1140 check_ajax_referer( 'image_editor-' . $_POST['id'], 'nonce' ); |
|
1141 |
|
1142 if ( ! current_user_can( 'edit_theme_options' ) ) { |
|
1143 wp_send_json_error(); |
|
1144 } |
|
1145 |
|
1146 if ( ! current_theme_supports( 'custom-header', 'uploads' ) ) { |
|
1147 wp_send_json_error(); |
|
1148 } |
|
1149 |
|
1150 $crop_details = $_POST['cropDetails']; |
|
1151 |
|
1152 $dimensions = $this->get_header_dimensions( array( |
|
1153 'height' => $crop_details['height'], |
|
1154 'width' => $crop_details['width'], |
|
1155 ) ); |
|
1156 |
|
1157 $attachment_id = absint( $_POST['id'] ); |
|
1158 |
|
1159 $cropped = wp_crop_image( |
|
1160 $attachment_id, |
|
1161 (int) $crop_details['x1'], |
|
1162 (int) $crop_details['y1'], |
|
1163 (int) $crop_details['width'], |
|
1164 (int) $crop_details['height'], |
|
1165 (int) $dimensions['dst_width'], |
|
1166 (int) $dimensions['dst_height'] |
|
1167 ); |
|
1168 |
|
1169 if ( ! $cropped || is_wp_error( $cropped ) ) { |
|
1170 wp_send_json_error( array( 'message' => __( 'Image could not be processed. Please go back and try again.' ) ) ); |
|
1171 } |
|
1172 |
|
1173 /** This filter is documented in wp-admin/custom-header.php */ |
|
1174 $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication |
|
1175 |
|
1176 $object = $this->create_attachment_object( $cropped, $attachment_id ); |
|
1177 |
|
1178 unset( $object['ID'] ); |
|
1179 |
|
1180 $new_attachment_id = $this->insert_attachment( $object, $cropped ); |
|
1181 |
|
1182 $object['attachment_id'] = $new_attachment_id; |
|
1183 $object['width'] = $dimensions['dst_width']; |
|
1184 $object['height'] = $dimensions['dst_height']; |
|
1185 |
|
1186 wp_send_json_success( $object ); |
|
1187 } |
|
1188 |
|
1189 /** |
|
1190 * Given an attachment ID for a header image, updates its "last used" |
|
1191 * timestamp to now. |
|
1192 * |
|
1193 * Triggered when the user tries adds a new header image from the |
|
1194 * Media Manager, even if s/he doesn't save that change. |
|
1195 */ |
|
1196 public function ajax_header_add() { |
|
1197 check_ajax_referer( 'header-add', 'nonce' ); |
|
1198 |
|
1199 if ( ! current_user_can( 'edit_theme_options' ) ) { |
|
1200 wp_send_json_error(); |
|
1201 } |
|
1202 |
|
1203 $attachment_id = absint( $_POST['attachment_id'] ); |
|
1204 if ( $attachment_id < 1 ) { |
|
1205 wp_send_json_error(); |
|
1206 } |
|
1207 |
|
1208 $key = '_wp_attachment_custom_header_last_used_' . get_stylesheet(); |
|
1209 update_post_meta( $attachment_id, $key, time() ); |
|
1210 update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() ); |
|
1211 |
|
1212 wp_send_json_success(); |
|
1213 } |
|
1214 |
|
1215 /** |
|
1216 * Given an attachment ID for a header image, unsets it as a user-uploaded |
|
1217 * header image for the current theme. |
|
1218 * |
|
1219 * Triggered when the user clicks the overlay "X" button next to each image |
|
1220 * choice in the Customizer's Header tool. |
|
1221 */ |
|
1222 public function ajax_header_remove() { |
|
1223 check_ajax_referer( 'header-remove', 'nonce' ); |
|
1224 |
|
1225 if ( ! current_user_can( 'edit_theme_options' ) ) { |
|
1226 wp_send_json_error(); |
|
1227 } |
|
1228 |
|
1229 $attachment_id = absint( $_POST['attachment_id'] ); |
|
1230 if ( $attachment_id < 1 ) { |
|
1231 wp_send_json_error(); |
|
1232 } |
|
1233 |
|
1234 $key = '_wp_attachment_custom_header_last_used_' . get_stylesheet(); |
|
1235 delete_post_meta( $attachment_id, $key ); |
|
1236 delete_post_meta( $attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() ); |
|
1237 |
|
1238 wp_send_json_success(); |
|
1239 } |
|
1240 |
|
1241 public function customize_set_last_used( $wp_customize ) { |
|
1242 $data = $wp_customize->get_setting( 'header_image_data' )->post_value(); |
|
1243 |
|
1244 if ( ! isset( $data['attachment_id'] ) ) { |
|
1245 return; |
|
1246 } |
|
1247 |
|
1248 $attachment_id = $data['attachment_id']; |
|
1249 $key = '_wp_attachment_custom_header_last_used_' . get_stylesheet(); |
|
1250 update_post_meta( $attachment_id, $key, time() ); |
|
1251 } |
|
1252 |
|
1253 public function get_default_header_images() { |
|
1254 $this->process_default_headers(); |
|
1255 |
|
1256 // Get the default image if there is one. |
|
1257 $default = get_theme_support( 'custom-header', 'default-image' ); |
|
1258 |
|
1259 if ( ! $default ) { // If not, |
|
1260 return $this->default_headers; // easy peasy. |
|
1261 } |
|
1262 |
|
1263 $default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() ); |
|
1264 $already_has_default = false; |
|
1265 |
|
1266 foreach ( $this->default_headers as $k => $h ) { |
|
1267 if ( $h['url'] === $default ) { |
|
1268 $already_has_default = true; |
|
1269 break; |
|
1270 } |
|
1271 } |
|
1272 |
|
1273 if ( $already_has_default ) { |
|
1274 return $this->default_headers; |
|
1275 } |
|
1276 |
|
1277 // If the one true image isn't included in the default set, prepend it. |
|
1278 $header_images = array(); |
|
1279 $header_images['default'] = array( |
|
1280 'url' => $default, |
|
1281 'thumbnail_url' => $default, |
|
1282 'description' => 'Default' |
|
1283 ); |
|
1284 |
|
1285 // The rest of the set comes after. |
|
1286 $header_images = array_merge( $header_images, $this->default_headers ); |
|
1287 return $header_images; |
|
1288 } |
|
1289 |
|
1290 public function get_uploaded_header_images() { |
|
1291 $header_images = get_uploaded_header_images(); |
|
1292 $timestamp_key = '_wp_attachment_custom_header_last_used_' . get_stylesheet(); |
|
1293 $alt_text_key = '_wp_attachment_image_alt'; |
|
1294 |
|
1295 foreach ( $header_images as &$header_image ) { |
|
1296 $header_meta = get_post_meta( $header_image['attachment_id'] ); |
|
1297 $header_image['timestamp'] = isset( $header_meta[ $timestamp_key ] ) ? $header_meta[ $timestamp_key ] : ''; |
|
1298 $header_image['alt_text'] = isset( $header_meta[ $alt_text_key ] ) ? $header_meta[ $alt_text_key ] : ''; |
|
1299 } |
|
1300 |
|
1301 return $header_images; |
|
1302 } |
1045 } |
1303 } |