File retrieved from aws server comes back as serialized - laravel

Hi i am moving my local Laravel images to aws when I retrieve the local files it brings back the file correctly however when i retrieve the aws file it comes back as serialized
this is my function i have to retrieve images
The first if block where it return the images comes back as an image:
However when I retrieve the file and return it from AWS it comes back as:
Am I retrieving the image from aws wrong, still new to this :D.

Onces you have s3 configured in your storage, you can save a file like this:
$url = $file->store($path, 's3');
Or
Storage::disk('s3')->put($path.'/'.$filename, $imageFile);
And you can get this image like this:
$url = Storage::disk('s3')->url($path);
Or if you want to have this safety option, that a link is valid only for a couple of minutes:
$url = Storage::disk('s3')->temporaryUrl(
$path, Carbon::now()->addMinutes(60)
);
The key is, when you use AWS, you should not try to get the image it self, but a link to that image through aws. Also you should store this url into the database not the image itself. And you should display the image through that link.

Related

Render blade view from URL path

I've an unusual and interesting problem that I am trying to solve.
We had to put some of our blade views to S3 storage and render them from S3 url with passed variables.
For example:
view('page.user.show', ['user' => User::first()])->render();
Now, since we have our page.user.show blade file stored in S3 storage on the path "/views/pages/user/show.blade.php"
We somehow need to make Laravel get that view from s3 URL path instead from resource_path
So we need something like this:
view('s3url.com/views/pages/user/show.blade.php', ['user' => User::first()])->render();
Is there any way we can do this in Laravel ? Or, at least read content of blade file from S3 path and render that string content with variables?
To achieve something like this, you'll need to implement a custom version of the Laravel Illuminate\View\ViewFinderInterface. Your best bet is to create a new view finder that can load blade templates from S3 and move them to the local filesystem temporarily.
You can probably just extend the FileViewFinder class, and add some custom logic to the find() method. In there, try something like:
if (Str::startsWith($name, 's3::')) {
// This gets a temp file that PHP will clean up for you
$name = stream_get_meta_data(tmpfile())['uri'];
// Download the Blade template from S3 and store it temporarily
file_put_contents($name, Storage::disk('s3')->get(Str::after($name, 's3::')));
// Return the path
return $name;
}
Then you'll need to swap in your new finder using View::setFinder.
The major downside of this approach is that you'll need to download views from S3 every time you render them. You probably want to at least add some caching to the system so that you're not hitting S3 every time a page loads.

how get laravel file manager image thumbnail

I install the Laravel file manager package in my app. but already I cant use thumbnail images in the blog.
How can I get an image thumbnail of uploaded photos when I use Laravel file manager?
After much searching, I realized that such a function does not exist (at least until the time of writing this message).
I defined a function in the helper that returns the address of the thumbnail from the URL of the original image.
The reader should note that these definitions may differ based on the setting of parameters for another person.
function LMFThums($url)
{
$url2= str_replace(basename($url) , '', $url ) ;
$url2=$url2.'thumbs/'.basename($url);
return $url2 ;
}

Get correct URL for uploaded files

I have a function in my platform for letting users upload their own icon images. Once they've uploaded them I save them using $request->icon->store('public/icons') and simply save the returned path, something like "public/icons/xa6y2am3e4cOdqQuLpvEhFSXDKwFMDOgggS2i67l.png".
I'm not really clear though on what's the correct way to show the icons. The URL for showing the icon in the above example is "/storage/icons/xa6y2am3e4cOdqQuLpvEhFSXDKwFMDOgggS2i67l.png", thus I need to replace "public" in the path with "storage", which makes me think I've done something wrong somewhere (I see no reason why the store() method should provide me with a path that's not correct).
I have done my symlinks as described in the documentation. Using the local storage. What am I missing?
This is how I handle my storage in one of my apps that includes blogs:
$storedImageName = $request->file('main_image')->store('blog_images', 'public');
The store method actually returns the stored file name along with the path. Here, I specify that my disk is public and that the folder inside public is blog_images. I store the result of that in $storedImageName.
Now, to save it in the database, I do not actually save the whole path, I save ONLY the image name. This is because, you may want to update your directory name in the future, or move it to another location, etc. You can get that like this:
$onlyImageName = basename($storedImageName);
basename() is PHP's function, has nothing to do with Laravel.
This way, I can render my images in my blade files like this:
<img ... src="{{ asset('/storage/blog_images/' . $blog->main_image) }}" />
asset() helper will provide you with path to your public directory, and then you just need to specify the rest of the path to your image.

Laravel: display file from cloud storage in the browser

This snippet from the Laravel docs, https://laravel.com/docs/5.5/responses#file-responses, seems to be just what I need:
return response()->file($pathToFile);
The problem is that my file is stored on an S3 disk, and I can't seem to reference it properly.
I tried using Storage::disk('s3')->getDriver()->getAdapter()->applyPathPrefix($myPath); to get the fully qualified file name. It just returned the value of $myPath though.
I then tried to get the url using Storage::disk('s3')->url($myPath); The URL looks fine however Symphony says it does not exist. When I check with Storage::disk('s3')->exists($myPath); however, it returns true.
How do I go about displaying a file from cloud storage directly in the user's browser?
EDIT:
More details below:
To save the item in the first instance I am using $map->storeAs('/my/path/maps/filename.pdf', ['disk' => 's3']);
The output of url() is "https://s3.ap-southeast-2.amazonaws.com/my.domain.com/my/path/maps/filename.pdf"
When I cut-and-past the url in a browser address bar, it loads no problem
It seems to me that the response()->file() method does not accept a URL parameter. Is that the case?
Question - does the file need to be publicly available? (It currently is, but I would prefer to make it private).
The following should be enough:
$path = Storage::disk('s3')->url($filename);
I don't have a working example set up, but from memory $filename should be the same as what you originally placed in the ->put() method. So when you say $mypath in your question, hopefully that isn't already prefixing stuff like your s3 instance.
If this isn't the case, can you edit the question to include the result of ->url() and an example of your put() call and $path.
Looking at the edit, I think I understand what you are trying to do, which has been solved here:
https://laracasts.com/discuss/channels/laravel/file-response-from-s3

How to use storage_path() to view an image in laravel 4

I'm using storage_path() for storing uploaded images, but when I use it is pointing wrong on my page.
I use it like this {{ $data->thumbnail }} where $data came from the database and thumbnail comes as the string which used storage_path
Let us take a look at the default L4 application structure:
app // contains restricted server-side application data
app/storage // a writeable directory used by L4 and custom functions to store data ( i.e. log files, ... )
public // this directory is accessible for clients
If I were you, I would upload the file to the public directory directly:
Store image here: public_path() . 'img/filename.jpg'
Save the 'img/filename.jpg' in database
Generate the image URL with url('img/filename.jpg') => http://www.your-domain.com/img/filename.jpg
Hope this helps.
The storage_path function returns the path to the storage folder, which is inside the app folder --and outside the public folder-- so it's not directly accessible from the client, that's why your images are not being displayed. You can move them to the public folder path, or you could use a custom controller to handle the image requests, read the image from the storage folder and return the value.

Resources