6

wp_get_attachment_image_src will give me URL and dimensions for an image.

But is there any way to get the server path for a scaled image (like /html/wordpress/wp-content/uploads/2015/03/cat-2-300x225.jpeg)? I know about get_attached_file but this returns only the original image.

I'd like to avoid hacky solutions (string-replacing domains and such) or using WP_Image_Editor directly. Also it should be multisite-proof. Is there something official I've just missed?

5
  • 1
    This seems to be a duplicate, but has the flaws you mentioned. Just posting for completeness sake. :)
    – kraftner
    Commented Mar 27, 2015 at 14:03
  • 1
    have you looked into codex.wordpress.org/Function_Reference/…
    – kraftner
    Commented Mar 27, 2015 at 14:12
  • Yep. But that just returns something like 2015/03/cat-2.jpeg. Though it does also return all file names for generated thumbnails, but only the filenames – and this again leads to cumbersome manipulation of paths.
    – maryisdead
    Commented Mar 27, 2015 at 14:35
  • I know, but I am afraid this is the closest you get. May I also ask what you need this for?
    – kraftner
    Commented Mar 27, 2015 at 14:42
  • I'm on a plugin to integrate the post image as an RSS enclosure into the WordPress generated feeds and therefore need to know the file size (and mime type).
    – maryisdead
    Commented Mar 27, 2015 at 15:03

1 Answer 1

17

WordPress doesn't store path of generated sizes anywhere, you need to build it.

As suggested by @kraftner in comments, wp_get_attachment_metadata() can be used to obtain some of the pieces you need to build the path. An alternative is image_get_intermediate_size().

The missing piece is the absolute path of upload folder. In theory, that can be retrieved via wp_upload_dir() but there's a problem: that function returns the upload folder in the moment it is called, but there's always the possibility that when the file was uploaded the upload path was different.

So the only possibility is to make the assumption that scaled image is in the same folder of original image.

This assumption may appear hackish, and probably is, but it is used in WordPress core itself by functions like image_downsize() that does exactly string-replacing (see line #184 of media.php), so if you're looking for the official way.. that's the one.

Putting things togheter:

function scaled_image_path($attachment_id, $size = 'thumbnail') {
    $file = get_attached_file($attachment_id, true);
    if (empty($size) || $size === 'full') {
        // for the original size get_attached_file is fine
        return realpath($file);
    }
    if (! wp_attachment_is_image($attachment_id) ) {
        return false; // the id is not referring to a media
    }
    $info = image_get_intermediate_size($attachment_id, $size);
    if (!is_array($info) || ! isset($info['file'])) {
        return false; // probably a bad size argument
    }

    return realpath(str_replace(wp_basename($file), $info['file'], $file));
}

Function above takes the attachment id and a size and returns the path.

I've applied realpath before to return paths because that function returns false for non-existent files, so the whole function always returns false if something went wrong.

The only alternative to this flow would be saving by yourself the path of scaled image(s) somewhere, probably post meta, and retrieve when needed, but that can only work for files uploaded after your plugin has been activated...

2
  • 1
    Been down the road you took, dug through the image-generating code (in the end assuming that the scaled image resides in the same folder as the original) and didn't like it. Well, guess I have to back down then. Thanks for your elaborate answer, Sir!
    – maryisdead
    Commented Mar 30, 2015 at 20:04
  • 2
    Thanks for putting this together! A quick post script, to include support for returning the path of SVG files, since there are no relevant sizes to consider, you can add something like || strtolower(pathinfo($file, PATHINFO_EXTENSION)) == "svg" to the first if statement.
    – Tim Malone
    Commented Aug 16, 2016 at 5:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.