mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-08-11 12:20:22 +00:00
Add header image uploads with cropping to the customizer.
props mcsf, ehg, gcorne. see #21785. git-svn-id: https://develop.svn.wordpress.org/trunk@27497 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
+231
-44
@@ -43,7 +43,7 @@ class Custom_Image_Header {
|
||||
var $default_headers = array();
|
||||
|
||||
/**
|
||||
* Holds custom headers uploaded by the user
|
||||
* Holds custom headers uploaded by the user.
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
@@ -73,6 +73,11 @@ class Custom_Image_Header {
|
||||
$this->admin_image_div_callback = $admin_image_div_callback;
|
||||
|
||||
add_action( 'admin_menu', array( $this, 'init' ) );
|
||||
|
||||
add_action( 'customize_save_after', array( $this, 'customize_set_last_used' ) );
|
||||
add_action( 'wp_ajax_custom-header-crop', array( $this, 'ajax_header_crop' ) );
|
||||
add_action( 'wp_ajax_custom-header-add', array( $this, 'ajax_header_add' ) );
|
||||
add_action( 'wp_ajax_custom-header-remove', array( $this, 'ajax_header_remove' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,6 +98,7 @@ class Custom_Image_Header {
|
||||
add_action("admin_head-$page", array($this, 'js'), 50);
|
||||
if ( $this->admin_header_callback )
|
||||
add_action("admin_head-$page", $this->admin_header_callback, 51);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -819,32 +825,15 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?>
|
||||
$attachment_id = absint( $_POST['attachment_id'] );
|
||||
$original = get_attached_file($attachment_id);
|
||||
|
||||
|
||||
$max_width = 0;
|
||||
// For flex, limit size of image displayed to 1500px unless theme says otherwise
|
||||
if ( current_theme_supports( 'custom-header', 'flex-width' ) )
|
||||
$max_width = 1500;
|
||||
|
||||
if ( current_theme_supports( 'custom-header', 'max-width' ) )
|
||||
$max_width = max( $max_width, get_theme_support( 'custom-header', 'max-width' ) );
|
||||
$max_width = max( $max_width, get_theme_support( 'custom-header', 'width' ) );
|
||||
|
||||
if ( ( current_theme_supports( 'custom-header', 'flex-height' ) && ! current_theme_supports( 'custom-header', 'flex-width' ) ) || $_POST['width'] > $max_width )
|
||||
$dst_height = absint( $_POST['height'] * ( $max_width / $_POST['width'] ) );
|
||||
elseif ( current_theme_supports( 'custom-header', 'flex-height' ) && current_theme_supports( 'custom-header', 'flex-width' ) )
|
||||
$dst_height = absint( $_POST['height'] );
|
||||
else
|
||||
$dst_height = get_theme_support( 'custom-header', 'height' );
|
||||
|
||||
if ( ( current_theme_supports( 'custom-header', 'flex-width' ) && ! current_theme_supports( 'custom-header', 'flex-height' ) ) || $_POST['width'] > $max_width )
|
||||
$dst_width = absint( $_POST['width'] * ( $max_width / $_POST['width'] ) );
|
||||
elseif ( current_theme_supports( 'custom-header', 'flex-width' ) && current_theme_supports( 'custom-header', 'flex-height' ) )
|
||||
$dst_width = absint( $_POST['width'] );
|
||||
else
|
||||
$dst_width = get_theme_support( 'custom-header', 'width' );
|
||||
$dimensions = $this->get_header_dimensions( array(
|
||||
'height' => $_POST['height'],
|
||||
'width' => $_POST['width'],
|
||||
) );
|
||||
$height = $dimensions['dst_height'];
|
||||
$width = $dimensions['dst_width'];
|
||||
|
||||
if ( empty( $_POST['skip-cropping'] ) )
|
||||
$cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], $dst_width, $dst_height );
|
||||
$cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], $width, $height );
|
||||
elseif ( ! empty( $_POST['create-new-attachment'] ) )
|
||||
$cropped = _copy_image_file( $attachment_id );
|
||||
else
|
||||
@@ -856,31 +845,15 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?>
|
||||
/** This filter is documented in wp-admin/custom-header.php */
|
||||
$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication
|
||||
|
||||
$parent = get_post($attachment_id);
|
||||
$parent_url = $parent->guid;
|
||||
$url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
|
||||
$object = $this->create_attachment_object( $cropped, $attachment_id );
|
||||
|
||||
$size = @getimagesize( $cropped );
|
||||
$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
|
||||
|
||||
// Construct the object array
|
||||
$object = array(
|
||||
'ID' => $attachment_id,
|
||||
'post_title' => basename($cropped),
|
||||
'post_content' => $url,
|
||||
'post_mime_type' => $image_type,
|
||||
'guid' => $url,
|
||||
'context' => 'custom-header'
|
||||
);
|
||||
if ( ! empty( $_POST['create-new-attachment'] ) )
|
||||
unset( $object['ID'] );
|
||||
|
||||
// Update the attachment
|
||||
$attachment_id = wp_insert_attachment( $object, $cropped );
|
||||
wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $cropped ) );
|
||||
$attachment_id = $this->insert_attachment( $object, $cropped );
|
||||
|
||||
$width = $dst_width;
|
||||
$height = $dst_height;
|
||||
$url = $object['guid'];
|
||||
$this->set_header_image( compact( 'url', 'attachment_id', 'width', 'height' ) );
|
||||
|
||||
// cleanup
|
||||
@@ -1041,4 +1014,218 @@ wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); ?>
|
||||
set_theme_mod( 'header_image', $default );
|
||||
set_theme_mod( 'header_image_data', (object) $default_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate width and height based on what the currently selected theme supports.
|
||||
*
|
||||
* @return array dst_height and dst_width of header image.
|
||||
*/
|
||||
final public function get_header_dimensions( $dimensions ) {
|
||||
$max_width = 0;
|
||||
$width = absint( $dimensions['width'] );
|
||||
$height = absint( $dimensions['height'] );
|
||||
$theme_height = get_theme_support( 'custom-header', 'height' );
|
||||
$theme_width = get_theme_support( 'custom-header', 'width' );
|
||||
$has_flex_width = current_theme_supports( 'custom-header', 'flex-width' );
|
||||
$has_flex_height = current_theme_supports( 'custom-header', 'flex-height' );
|
||||
$has_max_width = current_theme_supports( 'custom-header', 'max-width' ) ;
|
||||
$dst = array( 'dst_height' => null, 'dst_height' => null );
|
||||
|
||||
// For flex, limit size of image displayed to 1500px unless theme says otherwise
|
||||
if ( $has_flex_width ) {
|
||||
$max_width = 1500;
|
||||
}
|
||||
|
||||
if ( $has_max_width ) {
|
||||
$max_width = max( $max_width, get_theme_support( 'custom-header', 'max-width' ) );
|
||||
}
|
||||
$max_width = max( $max_width, $theme_width );
|
||||
|
||||
if ( $has_flex_height && ( ! $has_flex_width || $width > $max_width ) ) {
|
||||
$dst['dst_height'] = absint( $height * ( $max_width / $width ) );
|
||||
}
|
||||
elseif ( $has_flex_height && $has_flex_width ) {
|
||||
$dst['dst_height'] = $height;
|
||||
}
|
||||
else {
|
||||
$dst['dst_height'] = $theme_height;
|
||||
}
|
||||
|
||||
if ( $has_flex_width && ( ! $has_flex_height || $width > $max_width ) ) {
|
||||
$dst['dst_width'] = absint( $width * ( $max_width / $width ) );
|
||||
}
|
||||
elseif ( $has_flex_width && $has_flex_height ) {
|
||||
$dst['dst_width'] = $width;
|
||||
}
|
||||
else {
|
||||
$dst['dst_width'] = $theme_width;
|
||||
}
|
||||
|
||||
return $dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an attachment 'object'.
|
||||
*
|
||||
* @param string $cropped Cropped image URL.
|
||||
* @param int $parent_attachment_id Attachment ID of parent image.
|
||||
*
|
||||
* @return array Attachment object.
|
||||
*/
|
||||
final public function create_attachment_object( $cropped, $parent_attachment_id ) {
|
||||
$parent = get_post( $parent_attachment_id );
|
||||
$parent_url = $parent->guid;
|
||||
$url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
|
||||
|
||||
$size = @getimagesize( $cropped );
|
||||
$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
|
||||
|
||||
$object = array(
|
||||
'ID' => $parent_attachment_id,
|
||||
'post_title' => basename($cropped),
|
||||
'post_content' => $url,
|
||||
'post_mime_type' => $image_type,
|
||||
'guid' => $url,
|
||||
'context' => 'custom-header'
|
||||
);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert an attachment & its metadata.
|
||||
*
|
||||
* @param array $object Attachment object.
|
||||
* @param string $cropped Cropped image URL.
|
||||
*
|
||||
* @return int Attachment ID.
|
||||
*/
|
||||
final public function insert_attachment( $object, $cropped ) {
|
||||
$attachment_id = wp_insert_attachment( $object, $cropped );
|
||||
$metadata = wp_generate_attachment_metadata( $attachment_id, $cropped );
|
||||
/**
|
||||
* Allows us to insert custom meta data for an attachment.
|
||||
*
|
||||
*/
|
||||
$metadata = apply_filters( 'wp_header_image_attachment_metadata', $metadata );
|
||||
wp_update_attachment_metadata( $attachment_id, $metadata );
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets attachment uploaded by Media Manager, crops it, then saves it as a
|
||||
* new object. Returns JSON-encoded object details.
|
||||
*/
|
||||
function ajax_header_crop() {
|
||||
check_ajax_referer( 'image_editor-' . $_POST['id'], 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
if ( ! current_theme_supports( 'custom-header', 'uploads' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$crop_details = $_POST['cropDetails'];
|
||||
|
||||
$dimensions = $this->get_header_dimensions( array(
|
||||
'height' => $crop_details['height'],
|
||||
'width' => $crop_details['width'],
|
||||
) );
|
||||
|
||||
$attachment_id = absint( $_POST['id'] );
|
||||
|
||||
$cropped = wp_crop_image(
|
||||
$attachment_id,
|
||||
(int) $crop_details['x1'],
|
||||
(int) $crop_details['y1'],
|
||||
(int) $crop_details['width'],
|
||||
(int) $crop_details['height'],
|
||||
(int) $dimensions['dst_width'],
|
||||
(int) $dimensions['dst_height']
|
||||
);
|
||||
|
||||
if ( ! $cropped || is_wp_error( $cropped ) ) {
|
||||
wp_send_json_error( array( 'message' => __( 'Image could not be processed. Please go back and try again.' ) ) );
|
||||
}
|
||||
|
||||
$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication
|
||||
|
||||
$object = $this->create_attachment_object( $cropped, $attachment_id );
|
||||
|
||||
unset( $object['ID'] );
|
||||
|
||||
$new_attachment_id = $this->insert_attachment( $object, $cropped );
|
||||
|
||||
$object['attachment_id'] = $new_attachment_id;
|
||||
$object['width'] = $dimensions['dst_width'];
|
||||
$object['height'] = $dimensions['dst_height'];
|
||||
|
||||
wp_send_json_success( $object );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an attachment ID for a header image, updates its "last used"
|
||||
* timestamp to now.
|
||||
*
|
||||
* Triggered when the user tries adds a new header image from the
|
||||
* Media Manager, even if s/he doesn't save that change.
|
||||
*/
|
||||
function ajax_header_add() {
|
||||
check_ajax_referer( 'header-add', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$attachment_id = absint( $_POST['attachment_id'] );
|
||||
if ( $attachment_id < 1 ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$key = '_wp_attachment_custom_header_last_used_' . get_stylesheet();
|
||||
update_post_meta( $attachment_id, $key, time() );
|
||||
update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() );
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an attachment ID for a header image, unsets it as a user-uploaded
|
||||
* header image for the current theme.
|
||||
*
|
||||
* Triggered when the user clicks the overlay "X" button next to each image
|
||||
* choice in the Customizer's Header tool.
|
||||
*/
|
||||
function ajax_header_remove() {
|
||||
check_ajax_referer( 'header-remove', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$attachment_id = absint( $_POST['attachment_id'] );
|
||||
if ( $attachment_id < 1 ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$key = '_wp_attachment_custom_header_last_used_' . get_stylesheet();
|
||||
delete_post_meta( $attachment_id, $key );
|
||||
delete_post_meta( $attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() );
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
function customize_set_last_used( $wp_customize ) {
|
||||
$data = $wp_customize->get_setting( 'header_image_data' )->post_value();
|
||||
|
||||
if ( ! isset( $data['attachment_id'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$attachment_id = $data['attachment_id'];
|
||||
$key = '_wp_attachment_custom_header_last_used_' . get_stylesheet();
|
||||
update_post_meta( $attachment_id, $key, time() );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user