Get a list of all image sizes that match aspect ratio of original one

I need the same functionality as default WordPress wp_calculate_image_srcset() method which returns the string for srcset:

image-300x200.jpg 300w, image-600x400.jpg 600w, ...

but it should return an array instead of string, with structure similar to:

$image_sizes = array(
  array(
    'url' => 'image-300x200.jpg',
    'width' => 300,
    'height' => 200
  ),
  array(
    'url' => 'image-600x400.jpg',
    'width' => 600,
    'height' => 400
  ),
  array(
    'url' => 'image.jpg',
    'width' => 1200,
    'height' => 800
  )
);

I understand that I can just parse the string itself, but I wonder if it’s safe? The plugin that I’m making is public and can be used on any server with other plugins that might modify this string.

Source of wp_calculate_image_srcset seems complicated and uses a few “_private” methods.

The wp_calculate_image_srcset is also using max_srcset_image_width filter (which limits maximum size of image) and I need to avoid it somehow. Is remove_filter -> execute method -> add_filter the only way to skip it?

Edit: I ended up doing this (if it’s a bad idea – please let me know):

class MyClass {
    public $image_items;

    function __construct() {
        add_filter('wp_calculate_image_srcset', array($this, 'filter_my_srcset'), 10, 5);
        wp_calculate_image_srcset( ... );
        remove_filter('wp_calculate_image_srcset', array($this, 'filter_my_srcset'));

        // print_r( $this->image_items );
    }

    public function filter_my_srcset( $source, ... ) {
        $this->image_items = $source;
        return $source;
    }
}

1 Answer
1

I think you should use wp_calculate_image_srcset() for the simple reason that it is very complex (it should not have been just one function in the first place).
Duplicating it might lead to weird side effects in the future when WP is changing the original algorithm.

For the filter problems:

You can pass a third parameter in $size_array. WP will just look into the first two values. If you call the function like this …

wp_calculate_image_srcset( [600, 400, 'wpse_281968'], … )

… you can look for that value when you filter max_srcset_image_width.

add_filter( 'max_srcset_image_width', function( $max, array $sizes ) {

    if ( ! empty ( $sizes[2] ) && 'wpse_281968' === $sizes[2] )
        return PHP_INT_MAX;

    return $max;

}, 10, 20);

Yes, it’s a hack. But it will work until WP is using a third array entry here. Keep an eye on the WP source. 🙂

And then I would filter wp_calculate_image_srcset (with a priority of - PHP_INT_MAX in order to run first) and fetch the sources from that. It’s an array and probably slightly easier to parse than the string that the function is returning.

Side note: Please don’t register callbacks for hooks in a constructor. 🙂

Leave a Comment