WordPress Version: 6.3
/**
* Handles cropping an image via AJAX.
*
* @since 4.3.0
*/
function wp_ajax_crop_image()
{
$attachment_id = absint($_POST['id']);
check_ajax_referer('image_editor-' . $attachment_id, 'nonce');
if (empty($attachment_id) || !current_user_can('edit_post', $attachment_id)) {
wp_send_json_error();
}
$context = str_replace('_', '-', $_POST['context']);
$data = array_map('absint', $_POST['cropDetails']);
$cropped = wp_crop_image($attachment_id, $data['x1'], $data['y1'], $data['width'], $data['height'], $data['dst_width'], $data['dst_height']);
if (!$cropped || is_wp_error($cropped)) {
wp_send_json_error(array('message' => __('Image could not be processed.')));
}
switch ($context) {
case 'site-icon':
require_once ABSPATH . 'wp-admin/includes/class-wp-site-icon.php';
$wp_site_icon = new WP_Site_Icon();
// Skip creating a new attachment if the attachment is a Site Icon.
if (get_post_meta($attachment_id, '_wp_attachment_context', true) == $context) {
// Delete the temporary cropped file, we don't need it.
wp_delete_file($cropped);
// Additional sizes in wp_prepare_attachment_for_js().
add_filter('image_size_names_choose', array($wp_site_icon, 'additional_sizes'));
break;
}
/** This filter is documented in wp-admin/includes/class-custom-image-header.php */
$cropped = apply_filters('wp_create_file_in_uploads', $cropped, $attachment_id);
// For replication.
$attachment = $wp_site_icon->create_attachment_object($cropped, $attachment_id);
unset($attachment['ID']);
// Update the attachment.
add_filter('intermediate_image_sizes_advanced', array($wp_site_icon, 'additional_sizes'));
$attachment_id = $wp_site_icon->insert_attachment($attachment, $cropped);
remove_filter('intermediate_image_sizes_advanced', array($wp_site_icon, 'additional_sizes'));
// Additional sizes in wp_prepare_attachment_for_js().
add_filter('image_size_names_choose', array($wp_site_icon, 'additional_sizes'));
break;
default:
/**
* Fires before a cropped image is saved.
*
* Allows to add filters to modify the way a cropped image is saved.
*
* @since 4.3.0
*
* @param string $context The Customizer control requesting the cropped image.
* @param int $attachment_id The attachment ID of the original image.
* @param string $cropped Path to the cropped image file.
*/
do_action('wp_ajax_crop_image_pre_save', $context, $attachment_id, $cropped);
/** This filter is documented in wp-admin/includes/class-custom-image-header.php */
$cropped = apply_filters('wp_create_file_in_uploads', $cropped, $attachment_id);
// For replication.
$parent_url = wp_get_attachment_url($attachment_id);
$parent_basename = wp_basename($parent_url);
$url = str_replace($parent_basename, wp_basename($cropped), $parent_url);
$size = wp_getimagesize($cropped);
$image_type = $size ? $size['mime'] : 'image/jpeg';
// Get the original image's post to pre-populate the cropped image.
$original_attachment = get_post($attachment_id);
$sanitized_post_title = sanitize_file_name($original_attachment->post_title);
$use_original_title = '' !== trim($original_attachment->post_title) && $parent_basename !== $sanitized_post_title && pathinfo($parent_basename, PATHINFO_FILENAME) !== $sanitized_post_title;
$use_original_description = '' !== trim($original_attachment->post_content);
$attachment = array('post_title' => $use_original_title ? $original_attachment->post_title : wp_basename($cropped), 'post_content' => $use_original_description ? $original_attachment->post_content : $url, 'post_mime_type' => $image_type, 'guid' => $url, 'context' => $context);
// Copy the image caption attribute (post_excerpt field) from the original image.
if ('' !== trim($original_attachment->post_excerpt)) {
$attachment['post_excerpt'] = $original_attachment->post_excerpt;
}
// Copy the image alt text attribute from the original image.
if ('' !== trim($original_attachment->_wp_attachment_image_alt)) {
$attachment['meta_input'] = array('_wp_attachment_image_alt' => wp_slash($original_attachment->_wp_attachment_image_alt));
}
$attachment_id = wp_insert_attachment($attachment, $cropped);
$metadata = wp_generate_attachment_metadata($attachment_id, $cropped);
/**
* Filters the cropped image attachment metadata.
*
* @since 4.3.0
*
* @see wp_generate_attachment_metadata()
*
* @param array $metadata Attachment metadata.
*/
$metadata = apply_filters('wp_ajax_cropped_attachment_metadata', $metadata);
wp_update_attachment_metadata($attachment_id, $metadata);
/**
* Filters the attachment ID for a cropped image.
*
* @since 4.3.0
*
* @param int $attachment_id The attachment ID of the cropped image.
* @param string $context The Customizer control requesting the cropped image.
*/
$attachment_id = apply_filters('wp_ajax_cropped_attachment_id', $attachment_id, $context);
}
wp_send_json_success(wp_prepare_attachment_for_js($attachment_id));
}