wp_ajax_crop_image()
云策文档标注
概述
wp_ajax_crop_image() 是一个 WordPress AJAX 处理函数,用于裁剪图像并处理相关附件。它验证用户权限和请求,根据上下文(如 site-icon)执行不同的裁剪逻辑,并返回 JSON 响应。
关键要点
- 函数通过 AJAX 处理图像裁剪,接收附件 ID、nonce 和裁剪数据作为输入。
- 使用 check_ajax_referer() 验证请求安全性,并检查 current_user_can() 权限。
- 调用 wp_crop_image() 进行实际裁剪,处理成功或错误情况。
- 根据 context 参数(如 'site-icon')执行特定逻辑,包括使用 WP_Site_Icon 类或默认处理。
- 涉及多个 Hook,如 wp_ajax_crop_image_pre_save、wp_ajax_cropped_attachment_metadata 和 wp_ajax_cropped_attachment_id。
- 最终通过 wp_send_json_success() 或 wp_send_json_error() 返回 JSON 响应。
代码示例
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':
// 处理 site-icon 特定逻辑
break;
default:
do_action( 'wp_ajax_crop_image_pre_save', $context, $attachment_id, $cropped );
// 默认裁剪处理
break;
}
wp_send_json_success( wp_prepare_attachment_for_js( $attachment_id ) );
}注意事项
- 函数依赖于 $_POST 数据,需确保前端正确传递 id、nonce、context 和 cropDetails 参数。
- 在 'site-icon' 上下文中,会跳过创建新附件并处理临时文件,开发者需注意此特殊行为。
- 使用多个 Hook 允许扩展和自定义裁剪过程,如修改元数据或附件 ID。
- 错误处理包括发送 JSON 错误响应,前端应相应处理。
原文内容
Handles cropping an image via AJAX.
Source
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.
// Copy attachment properties.
$attachment = wp_copy_parent_attachment_properties( $cropped, $attachment_id, $context );
// 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.
// Copy attachment properties.
$attachment = wp_copy_parent_attachment_properties( $cropped, $attachment_id, $context );
$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 ) );
}
Hooks
- apply_filters( ‘wp_ajax_cropped_attachment_id’, int $attachment_id, string $context )
-
Filters the attachment ID for a cropped image.
- apply_filters( ‘wp_ajax_cropped_attachment_metadata’, array $metadata )
-
Filters the cropped image attachment metadata.
- do_action( ‘wp_ajax_crop_image_pre_save’, string $context, int $attachment_id, string $cropped )
-
Fires before a cropped image is saved.
- apply_filters( ‘wp_create_file_in_uploads’, string $file, int $attachment_id )
-
Filters the attachment file path after the custom header or background image is set.
Changelog
| Version | Description |
|---|---|
| 4.3.0 | Introduced. |