Skip to content

Instantly share code, notes, and snippets.

@mitogh
Created April 4, 2022 02:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mitogh/022fe2db9e0e36bdcc4afa9e63968f8b to your computer and use it in GitHub Desktop.
Save mitogh/022fe2db9e0e36bdcc4afa9e63968f8b to your computer and use it in GitHub Desktop.
Creates a custom image size with the provided dimensions
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