Created
April 4, 2022 02:05
-
-
Save mitogh/022fe2db9e0e36bdcc4afa9e63968f8b to your computer and use it in GitHub Desktop.
Creates a custom image size with the provided dimensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
add_action( 'rest_api_init', function () { | |
register_rest_route( | |
'wp/v2', | |
'/media/(?P<id>[\d]+)/custom', | |
array( | |
'methods' => 'GET', | |
'args' => array( | |
'id' => array( | |
'validate_callback' => function ( $id ) { | |
if ( ! is_numeric( $id ) ) { | |
return false; | |
} | |
$mime_type = get_post_mime_type( $id ); | |
$valid_mime_types = array( | |
'image/jpeg' => true, | |
'image/jpg' => true, | |
'image/webp' => true, | |
); | |
return isset( $valid_mime_types[ $mime_type ] ); | |
}, | |
), | |
'width' => array( | |
'description' => __( 'Image width.', 'performance-lab' ), | |
'type' => 'integer', | |
), | |
'height' => array( | |
'type' => 'string', | |
'description' => __( 'Image height.', 'performance-lab' ), | |
), | |
'crop' => array( | |
'description' => __( 'If the image should be crop to the provided dimensions', 'performance-lab' ), | |
'type' => 'boolean', | |
'default' => false, | |
), | |
'crop_x' => array( | |
'description' => __( '', 'performance-lab' ), | |
'type' => 'string', | |
'enum' => array( | |
'left', | |
'center', | |
'right', | |
), | |
), | |
'crop_y' => array( | |
'description' => __( '', 'performance-lab' ), | |
'type' => 'string', | |
'enum' => array( | |
'top', | |
'center', | |
'bottom', | |
), | |
), | |
'format' => array( | |
'description' => __( 'A valid mime type for an image.', 'performance-lab' ), | |
'type' => 'string', | |
'default' => 'jpeg', | |
'enum' => array( | |
'jpeg', | |
'jpg', | |
'webp', | |
), | |
'sanitize_callback' => function ( $image_mime ) { | |
return $image_mime === 'jpg' ? 'jpeg' : sanitize_text_field( $image_mime ); | |
}, | |
), | |
'scale' => array( | |
'description' => __( 'A valid number where to scale the dimensions.' ), | |
'type' => 'integer', | |
'default' => 1, | |
), | |
), | |
'callback' => function ( WP_REST_Request $request ) { | |
if ( headers_sent() ) { | |
return; | |
} | |
$image_file = find_the_appropiate_image_url( $request ); | |
if ( ! file_exists( $image_file ) ) { | |
// TODO: Return 404. | |
return; | |
} | |
$modified_date = get_the_modified_date( DATE_RFC2822, $request->get_param( 'id' ) ); | |
// header( 'Accept-Ranges: bytes' ); | |
header( 'Content-type: image/' . $request->get_param( 'mime' ) ); | |
header( 'Content-Length: ' . filesize( $image_file ) ); | |
header( 'Cache-Control: public, max-age=' . HOUR_IN_SECONDS ); | |
header( 'Content-Disposition: filename=' . wp_basename( $image_file ) ); | |
header( 'Last-Modified: ' . $modified_date ); | |
readfile( $image_file ); | |
}, | |
'permission_callback' => '__return_true', | |
) | |
); | |
} | |
); | |
function find_the_appropiate_image_url( WP_REST_Request $request ) { | |
$attachment_id = (int) $request->get_param( 'id' ); | |
$attached_file = get_attached_file( $attachment_id ); | |
if ( ! $request->has_param( 'width' ) && ! $request->has_param( 'height' ) ) { | |
return $attached_file; | |
} | |
$scale = (int) $request->get_param( 'scale' ); | |
$width = (int) $request->get_param( 'width' ) * $scale; | |
$height = (int) $request->get_param( 'height' ) * $scale; | |
$metadata = wp_get_attachment_metadata( $attachment_id ); | |
$directory = pathinfo( $attached_file, PATHINFO_DIRNAME ); | |
$mime_type = 'image/' . $request->get_param( 'format' ); | |
if ( $metadata['width'] === $width && $metadata['height'] === $height ) { | |
if ( isset( $metadata['sources'][ $mime_type ]['file'] ) ) { | |
return path_join( $directory, $metadata['sources'][ $mime_type ]['file'] ); | |
} | |
return $attached_file; | |
} | |
$size_name = "{$width}_{$height}"; | |
$crop = $request->get_param( 'crop' ); | |
if ( $request->has_param( 'crop' ) || ( $request->has_param( 'crop_x' ) && $request->has_param( 'crop_y' ) ) ) { | |
$size_name .= "_cropped"; | |
if ( $request->has_param( 'crop_x' ) && $request->has_param( 'crop_y' ) ) { | |
$crop = array( $request->get_param( 'crop_x' ), $request->get_param( 'crop_y' ) ); | |
$size_name .= '_x_' . $request->get_param('crop_x') . '_y_' . $request->get_param('crop_y'); | |
} | |
} | |
if ( isset( $metadata['sizes'][ $size_name ]['sources'][ $mime_type ]['file'] ) ) { | |
return path_join( $directory, $metadata['sizes'][ $size_name ]['sources'][ $mime_type ]['file'] ); | |
} | |
foreach ( $metadata['sizes'] as $name => $properties ) { | |
if ( $properties['width'] === $width && $properties['height'] === $height ) { | |
if ( isset( $properties['sources'][ $mime_type ]['file'] ) ) { | |
return path_join( $directory, $properties['sources'][ $mime_type ]['file'] ); | |
} | |
$editor = wp_get_image_editor( wp_get_original_image_path( $attachment_id ), array( 'mime_type' => $mime_type ) ); | |
$editor->resize( $width, $height, $crop ); | |
$result = $editor->save(); | |
$properties['sources'][ $mime_type ] = array( | |
'file' => $result['file'], | |
'filesize' => filesize( $result['path'] ), | |
); | |
$metadata['sizes'][ $name ] = $properties; | |
wp_update_attachment_metadata( $attachment_id, $metadata['sizes'] ); | |
} | |
} | |
$editor = wp_get_image_editor( wp_get_original_image_path( $attachment_id ), array( 'mime_type' => $mime_type ) ); | |
$editor->resize( $width, $height, $crop ); | |
$result = $editor->save( null, $mime_type ); | |
if ( is_wp_error( $result ) ) { | |
return $attached_file; | |
} | |
if ( isset( $metadata['sizes'][ $size_name ] ) ) { | |
if ( ! isset( $metadata['sizes'][ $size_name ]['sources'] ) ) { | |
$metadata['sizes'][ $size_name ]['sources'] = array(); | |
} | |
$metadata['sizes'][ $size_name ]['sources'][ $mime_type ] = array( | |
'file' => $result['file'], | |
'filesize' => filesize( $result['path'] ), | |
); | |
} else { | |
$metadata['sizes'][ $size_name ] = array( | |
'file' => $result['file'], | |
'width' => $result['width'], | |
'height' => $result['height'], | |
'mime-type' => $result['mime-type'], | |
'sources' => array( | |
$mime_type => array( | |
'file' => $result['file'], | |
'filesize' => filesize( $result['path'] ), | |
), | |
), | |
); | |
} | |
wp_update_attachment_metadata( $attachment_id, $metadata ); | |
return $result['path']; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment