Last active
June 29, 2022 15:04
-
-
Save vralle/f45d68d758e2d26e54b99b71fa13f5e4 to your computer and use it in GitHub Desktop.
Dynamic SVG sizes for safe-svg WP plugin
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
<?php | |
add_action('init', removeSafeSvgOnePixelFix'); | |
function removeSafeSvgOnePixelFix() | |
{ | |
global $wp_filter; | |
if (! class_exists('safe_svg')) { | |
return; | |
} | |
if (! isset($wp_filter['wp_get_attachment_image_src']->callbacks[10])) { | |
return; | |
} | |
$look_in = $wp_filter['wp_get_attachment_image_src']->callbacks[10]; | |
foreach ($look_in as $callback) { | |
if (! is_array($callback['function'])) { | |
continue; | |
} | |
$object = $callback['function'][0] ?? null; | |
$method = $callback['function'][1] ?? null; | |
if ($object instanceof \safe_svg && $method === 'one_pixel_fix') { | |
remove_filter('wp_get_attachment_image_src', [$object, 'one_pixel_fix'], 10); | |
return; | |
} | |
} | |
} | |
// Removes sizes in SVG metadata | |
add_filter('wp_generate_attachment_metadata', 'filterMetadata', 11, 2); | |
/** | |
* Filters the generated attachment meta data. | |
* | |
* @param array<string,mixed> $metadata An array of attachment meta data. | |
* @param int $attachment_id Current attachment ID. | |
* | |
* @return array<string,mixed> $metadata | |
*/ | |
function filterMetadata(array $metadata, int $attachment_id): array | |
{ | |
$mime = get_post_mime_type($attachment_id); | |
if ($mime === 'image/svg+xml') { | |
// Removes unnecessary sizes for SVG ( | |
// Generates by safe_svg::skip_svg_regeneration(); | |
if (array_key_exists('sizes', $metadata)) { | |
unset($metadata['sizes']); | |
} | |
} | |
return $metadata; | |
} | |
// Generate size on request | |
add_filter('image_downsize', 'returnSvgSizes', 10, 3); | |
/** | |
* Filters whether to preempt the output of image_downsize(). | |
* | |
* Returning a truthy value from the filter will effectively short-circuit | |
* down-sizing the image, returning that value instead. | |
* | |
* @param bool|array $downsize Whether to short-circuit the image downsize. | |
* @param int $id Attachment ID for image. | |
* @param string|int[] $size Requested image size. Can be any registered image size name, or | |
* an array of width and height values in pixels (in that order). | |
*/ | |
function returnSvgSizes($downsize, $id, $size) | |
{ | |
$mime = get_post_mime_type($id); | |
if ($mime !== 'image/svg+xml') { | |
return $downsize; | |
} | |
// This is where we need to get the dimensions. If they are not present, it will lead to unpredictable behavior. | |
// For control, we can use a metadata filter. | |
$meta = wp_get_attachment_metadata($id); | |
if (! $meta) { | |
return $downsize; | |
} | |
// 300x150 - Default size for <img>, <object>, <iframe> and inline <svg> | |
$file_width = $meta['width'] ?: 300; | |
$file_height = $meta['height'] ?: 150; | |
$file_url = wp_get_attachment_url($id); | |
// Custom handler for getting file url? | |
if (! $file_url) { | |
return $downsize; | |
} | |
$ratio = $file_width / $file_height; | |
if (is_array($size)) { | |
$width = $size[0]; | |
$height = $size[1]; | |
} else { | |
$additional_sizes = wp_get_additional_image_sizes(); | |
if (isset($additional_sizes[$size])) { | |
$width = $additional_sizes[$size]['width']; | |
$height = $additional_sizes[$size]['height']; | |
} else { | |
$width = $file_width; | |
$height = $file_height; | |
} | |
} | |
// Responsive: width or height are zero | |
$width = $width ?: $height * $ratio; | |
$height = $height ?: $width / $ratio; | |
// Zero size: width and height are zero | |
$width = $width ?: $file_width; | |
$height = $height ?: $file_height; | |
$is_intermediate = ($size !== 'file'); | |
return [$file_url, $width, $height, $is_intermediate]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment