How to get current image’s slug in WP_image_editor?

Try adding this to functions.php:

add_filter("wp_image_editors", "my_wp_image_editors");

function my_wp_image_editors($editors) {
    array_unshift($editors, "WP_Image_Editor_Custom");
    return $editors;
}

// Include the existing classes first in order to extend them.
require_once ABSPATH . WPINC . "/class-wp-image-editor.php";
require_once ABSPATH . WPINC . "/class-wp-image-editor-gd.php";

class WP_Image_Editor_Custom extends WP_Image_Editor_GD {

    public function generate_filename($suffix = null, $dest_path = null, $extension = null) {
        // $suffix will be appended to the destination filename, just before the extension
        if (!$suffix) {
            $suffix = $this->get_suffix();
        }

        $dir = pathinfo($this->file, PATHINFO_DIRNAME);
        $ext = pathinfo($this->file, PATHINFO_EXTENSION);

        $name = wp_basename($this->file, ".$ext");
        $new_ext = strtolower($extension ? $extension : $ext );

        if (!is_null($dest_path) && $_dest_path = realpath($dest_path)) {
            $dir = $_dest_path;
        }
        //we get the dimensions using explode, we could have used the properties of $this->file[height] but the suffix could have been provided
        $size_from_suffix = explode("x", $suffix);
        //we get the slug_name for this dimension
        $slug_name = $this->get_slug_by_size($size_from_suffix[0], $size_from_suffix[1]);

        return trailingslashit($dir) . "{$slug_name}/{$name}.{$new_ext}";
    }

    function multi_resize($sizes) {
        $sizes = parent::multi_resize($sizes);

        //we add the slug to the file path
        foreach ($sizes as $slug => $data) {
            $sizes[$slug]['file'] = $slug . "https://wordpress.stackexchange.com/" . $data['file'];
        }

        return $sizes;
    }

    function get_slug_by_size($width, $height) {

        // Make thumbnails and other intermediate sizes.
        $_wp_additional_image_sizes = wp_get_additional_image_sizes();

        $image_sizes = array(); //all sizes the default ones and the custom ones in one array
        foreach (get_intermediate_image_sizes() as $s) {
            $image_sizes[$s] = array('width' => '', 'height' => '', 'crop' => false);
            if (isset($_wp_additional_image_sizes[$s]['width'])) {
                // For theme-added sizes
                $image_sizes[$s]['width'] = intval($_wp_additional_image_sizes[$s]['width']);
            } else {
                // For default sizes set in options
                $image_sizes[$s]['width'] = get_option("{$s}_size_w");
            }

            if (isset($_wp_additional_image_sizes[$s]['height'])) {
                // For theme-added sizes
                $image_sizes[$s]['height'] = intval($_wp_additional_image_sizes[$s]['height']);
            } else {
                // For default sizes set in options
                $image_sizes[$s]['height'] = get_option("{$s}_size_h");
            }

            if (isset($_wp_additional_image_sizes[$s]['crop'])) {
                // For theme-added sizes
                $image_sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop'];
            } else {
                // For default sizes set in options
                $image_sizes[$s]['crop'] = get_option("{$s}_crop");
            }
        }
        $slug_name = ""; //the slug name

        if($width >= $height){
          foreach ($image_sizes as $slug => $data) { //we start checking
            if ($data['width'] == $width) {//we use only width because regardless of the height, the width is the one used for resizing in all cases with crop 1 or 0
                $slug_name = $slug;
            }
            /*
             * There could be custom added image sizes that have the same width as one of the defaults so we also use height here
             * if there are several image sizes with the same width all of them will override the previous one leaving the last one, here we get also the last one
             * since is looping the entire list, the height is used as a max value for non-hard cropped sizes
             *  */
              if ($data['width'] == $width && $data['height'] == $height) {
                  $slug_name = $slug;
              }
          }
         }else{
           foreach ($image_sizes as $slug => $data) {
              if ($data['height'] == $height) {
                  $slug_name = $slug;
              }
              if ($data['height'] == $height && $data['width'] == $width ) {
                  $slug_name = $slug;
              }
            }
         }
        return $slug_name;
    }
}

i know you already know almost all of this code, notice that the generate_filename function has been updated to the current one, you will be more interested in the get_slug_by_size function which is the key part that you were missing.
This is also working with custom image sizes, as can be seen here:

enter image description here

home-bottom is a image size i added. Right now wordpress has 4 different default image sizes:

    Array
    (
        [thumbnail] => Array // Thumbnail (150 x 150 hard cropped)
            (
                [width] => 150
                [height] => 150
                [crop] => 1
            )

        [medium] => Array // Medium resolution (300 x 300 max height 300px)
            (
                [width] => 300
                [height] => 300
                [crop] => 
            )

        [medium_large] => Array //Medium Large (added in WP 4.4) resolution (768 x 0 infinite height)
            (
                [width] => 768
                [height] => 0
                [crop] => 
            )

        [large] => Array // Large resolution (1024 x 1024 max height 1024px)
            (
                [width] => 1024
                [height] => 1024
                [crop] => 
            )

    )
// Full resolution (original size uploaded) this one is not in the array.

if you upload an image of width 310 only thumbnail and medium images would be created WordPress will not create bigger ones, so with the code above, only 2 folders will be created.

Leave a Comment