deliciousbrains / wp-amazon-s3-and-cloudfront

Automatically copies media uploads to Amazon S3 for delivery. Optionally configure Amazon CloudFront for even faster delivery.
https://wordpress.org/plugins/amazon-s3-and-cloudfront/
308 stars 149 forks source link

Seems img urls are not (correctly?) rewritten for content read via REST API v2 #381

Closed Paul424 closed 7 years ago

Paul424 commented 7 years ago

When i enable cloudfront/cdn for offloading media then i noticed that the img paths in content is not correctly rewritten. First of all the CloudFront or Custom Domain is not used but instead the local WP hostname, and secondly when object versioning is enabled that object (number) is missing from the image paths.

Now the combination of REST and Cloudfront is i guess a common combination for those who like to integrate wp content into another website.... would be great if this can be fixed.

aaemnnosttv commented 7 years ago

It sounds like you are describing the behavior as it has changed since v1.1.1 https://github.com/deliciousbrains/wp-amazon-s3-and-cloudfront/blob/master/readme.txt#L99

I'm referring to the change where S3/CDN URLs are no longer stored in the database, but are filtered on-the-fly for display.

You can read more about this in the respective release post here: https://deliciousbrains.com/wp-offload-s3-1-2-released/

BenWoodford commented 7 years ago

@aaemnnosttv is there a quick rundown of how this works behind the scenes? S3 Offload is great when using the PHP library Corcel as it means we can hide away our CMS backend on a different URL - but this new method is a huge pain point as I can't seem to work out how the amazonS3_cache is structured and thus can't work out how to manually apply the filter.

Is it just a case of key (url) => value (timestamp if external URL, ID if an attachment) and then getting the attachments from the DB to find/replace with?

aaemnnosttv commented 7 years ago

The data stored in the amazonS3_cache is more for internal use.

To filter any content from local to S3 URLs, use the as3cf_filter_post_local_to_s3 with the string content you wish to rewrite URLs for.

For more information, see our doc here: https://deliciousbrains.com/wp-offload-s3/doc/filtering-urls-in-custom-content/

aaemnnosttv commented 7 years ago

Can you elaborate on what you're seeing and how we might reproduce it?

I can confirm that URL rewriting is working as expected using wp/v2/posts/:id and that the content.rendered html contains the correct S3 URLs.

BenWoodford commented 7 years ago

I'm pulling from the actual database, not using WP directly. Corcel is a library that basically interacts with the WP DB without using any actual WP classes or functions - specifically I'm using it in Laravel so Posts, Pages etc are Eloquent models.

I've managed to get parsing of amazonS3_cache going for the most part just by checking if the URL from the cache exists in the content and pulling the relevant attachment then str_replacing each instance. Would like to know if that's all there is to it though. Obviously the cache can contain timestamp values instead but I'm ignoring those.

aaemnnosttv commented 7 years ago

Ah oh, I missed that because the OP was about using the REST API.

The amazonS3_cache is a mapping of URLs to attachment IDs. The timestamps are for URLs that fail to be mapped to an attachment. I hope that helps, but we can't really officially support any method of rewriting URLs outside of using core WordPress functions. It sounds like you have something that works for you though.

Let's keep the issue on topic with the OP though; keep in mind these issues are primarily for bug reports.

BenWoodford commented 7 years ago

Yeah sorry, I got a bit off-topic as it was an issue that appeared to related to mine and mentioned the new thing.

Seems like I got the gist when looking over it though, good to know I got it right 👍

dannehl commented 7 years ago

@BenWoodford We ran in that same issue and, at least for the featured picture, we solved it by replacing corcels getImageAttribute() with the following code:


public function getImageAttribute()
    {
        if (!is_null($this->meta->_thumbnail_id)) {
            $image = Attachment::find($this->meta->_thumbnail_id);

            if (!is_null($image)) {

                $s3Image = $image->meta()->where('meta_key','=','amazonS3_info')->first();

                if ($s3Image) {
                    return config('corcel.s3.url') . $s3Image->value['key'];
                }

                return $image->guid;
            }
        }
    }

Just as a suggestion...

aaemnnosttv commented 7 years ago

Going to close this one for now as there does not appear to be any issue with rewriting URLs in post content for the REST API. Both content and excerpt fields for post data use the same filters for their respective rendered data from the API as are used for display on the front end.

I've tested this as well just to be sure but everything is working as expected.