Laravel: How to save images to public folder? - laravel

I am having trouble uploading a user image to my public folder. The file name generates correctly, and saves the name to my database, except the iamge itself refuses to get saved into my public folder. What am I doing wrong?
public function update_avatar(Request $request) {
if($request->hasFile('avatar')) {
$avatar = $request->file('avatar');
$filename = time() . "." . $avatar->getClientOriginalExtension();
Image::make($avatar)->resize(300,300)->save(public_path('/uploads/'.$filename)); ==> This is causing me errors
user = Auth::user();
$user->avatar = $filename;
$user->save();
}

The public disk is intended for files that are going to be publicly accessible. By default, the public disk uses the local driver and stores these files in storage/app/public. To make them accessible from the web, you should create a symbolic link from public/storage to storage/app/public. This convention will keep your publicly accessible files in one directory that can be easily shared across deployments.
To create the symbolic link, you may use the storage:link Artisan command:
php artisan storage:link
https://laravel.com/docs/5.5/filesystem

I think you should try this:
$destinationPath = public_path('uploads');
Image::make($avatar)->resize(300,300)->save($destinationPath.'/'.$filename);

First you must move your image to destination directory and then resize it.
$avatar->move(public_path('/uploads/'.$filename));
Image::make(public_path('/uploads/'.$filename))->resize(300,300)->save(public_path('/uploads/'.$filename));
Note
Check the directory that you moving your file there is already exist.

Related

Where it is recommended to save files in Laravel

I am still not very clear in which folder to save the files uploaded by the user such as avatars, or the images of a post etc.
I've already read the guide https://laravel.com/docs/8.x/filesystem but couldn't figure out the best solution.
I can safely upload files to:
storage / app / folder
Or in
storage / app / public / folder
For example, I use the following code to load avatars and it is saved in storage/app/avatars:
$path = $request->file('avatar')->store('avatars');
If they need to be publicly accessible they need to end up in public some where. If you have setup the storage link then the public disk which is set as its root to storage/app/public will be accessible via yoursite.blah/storage as it is symlinked to the public/storage folder
normally in this route: storage/app/public/folder
Just remind you that if you create a folder, example: avatar and you want to save there all the avatars
you have to register that folder in the filesystems configuration file: config/filesystems.php
you have also more examples, in the filesystem documentation
I entered the second line for the avatars, in my controller I save the file like this:
$path = $request->file('avatar')->store('avatars');
But keep uploading it to storage/app/avatars
'links' => [
public_path('storage') => storage_path('app/public'),
public_path('avatars') => storage_path('app/public/avatars'),
],

How to create thumbnail image in laravel using Intervention in live server?

My primary domain is xyz.com. I have created a folder named "test" outside public_html folder and uploaded the whole laravel set up there except the public folder which I have moved to public_html folder.
My folder structure is like this.
test -> contains the laravel project without public folder.
public_html -> contains the public folder.
However I cannot upload images. Error is showing like "Image source not readable". Please help.
if ($request->hasFile('frontimage')) {
$file_frontimage = $request->file('frontimage');
$actual_filename_frontimage = $file_frontimage->getClientOriginalName();
$filename_frontimage = time() . '_' . $actual_filename_frontimage;
$file_frontimage->storeAs('images', $filename_frontimage, 'public');
}

Laravel symlink and cPanel

On my Laravel website I'm using symlink to store and show the images from storage.
With
php artisan storage:link
I had created the symlink and everytime when I upload a new news article, the image is uploaded in the main Storage and with symlink it's setup to the public folder and I'm displaying the image properly.
So far so good, but when I've created a copy of the website, a problem appears...
When I've created a copy of the website with cPanels File Manager, and move to a new location, the storage symlink in the public directory has become a folder, not a symlink.
After that when I try to upload a new news article, I can see it's uploaded in the main Storage folder, but not in the public/storage, so as a result the image is not displaying. That's because it's not a symlink anymore, but now it's a folder.
I've deleted the storage folder from the public directory, with SSH I've used the command again
php artisan storage:link
and I've created a new news article and the image is displaying properly, but now all other images are gone.
Is there any command that will regenerate the paths, so all other images will be display again?
I'm using Laravel 5.5
You can solve it in another way to create a symlinkexample.php file
into your public folder and run the file path into browser.
Then Storage folder will be created into public folder. Folder path
will be public/storage with linked to your public folder.
Code below for symlinkexample.php :
<?php
$targetFolder = $_SERVER['DOCUMENT_ROOT'].'/storage/app/public';
$linkFolder = $_SERVER['DOCUMENT_ROOT'].'/public/storage';
symlink($targetFolder,$linkFolder);
echo 'Symlink process successfully completed';
?>
Try this:
In route/web.php add the following code:
Route::get('/storage', function(){
\Artisan::call('storage:link');
return "Se han vinculado las imágenes";
});
If for some reason you are using different file structure and for some reason don't have terminal access, \Artisan::call('storage:link') will fail since it won't find public path.
Route::get('cmd', function(){
$process = new Process(['ln', '[symlink-here]','[target-folder]' ]);
$process->run();
// executes after the command finishes
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
echo $process->getOutput();
});
read about Process class here

Valet showing files under wrong Url

Currently running into issues on my server with links to files in my Laravel application.
I currently have a images folder in storage/app/public and I linked the storage/app/public folder to public with php artisan storage:link.
Now i have a image.jpg in the images folder.
On my local system while using valet I can see the image with the tow following links:
/images/image.jpg
/storage/images/image.jpg
On my server only the second one works (which I assume is correct as there is no images folder directly in the public-directory.
Problem is, I often run into issues when deploying as customers can't see images online (as the link is not working). This wouldn't be an issue if I could not see images local while testing the UI.
Anyone also has this issue and can lead me to some kind of solution?
The issue is that the LaravelValetDriver has a fallback test; if the file doesn't exist in the public directory then it will check the public storage directory.
You can find that here:
if ($this->isActualFile($storagePath = $sitePath.'/storage/app/public'.$storageUri)) {
return $storagePath;
}
You can prevent this behaviour by creating your own Valet Driver that extends the LaravelValetDriver and overrides the isStaticFile method, e.g:
class NoStorageFallbackLaravelValetDriver extends LaravelValetDriver
{
public function isStaticFile($sitePath, $siteName, $uri)
{
if (file_exists($staticFilePath = $sitePath. '/public' . $uri)
&& is_file($staticFilePath)) {
return $staticFilePath;
}
return false;
}
}
Using the public disk is straight forward and should work without problems out of the box.
The public disk uses the 'local' driver which by default uses the storage/app directory.
The command:
php artisan storage:link
will create a symbolic link 'storage' inside your public folder that links to the non-public folder storage/app/public.
When the link is working, you can use the following command:
Storage::disk('local')->put('public/file.txt', 'Contents');
This will store file.txt to
storage/app/public/file.txt
You won't be accessing the file at storage/app/public.file.txt instead you will be accessing it using the symlink public/storage...
Therefore your saved file will publicly accessible at
public/storage/file.txt
Use the asset helper you can get the location of the file:
echo asset('file.txt');

How to create symlink from public/storage to storage/app/public in laravel?

I have no idea on how to create symbolic link or symlink.
I am working on File system in laravel 5.2.
The document says that i need to create a symbolic link from public/storage to storage/app/public to keep the publicly accessible files in one directory.
How to create that symlink or symbolic link?
Which file or directory should I place that code?
App::make('files')->link(storage_path('app/public'), public_path('storage'));
And don't forget to use App after namespace.
Run this command:
php artisan storage:link
In a Windows environment, you can:
cmd with Run as administrator
Run the mklink command:
mklink /D "C:\xampp\htdocs\xxxx\yyy\public\storage\"
"C:\xampp\htdocs\xxxx\xxx\storage\public\"
On Shared Server, where one doesn't have ssh access to run
php artisan storage:link this helps me run that from a controller, the if block code section can also be placed in a Service Provider as well as suggested by #shìpu-ahamed
public function displayForm()
{
if(!file_exists(public_path('storage'))) {
\App::make('files')->link(storage_path('app/public'), public_path('storage'));
}
return view('admin.index');
}
Added same code but still getting issue.
Method link does not exist.
currently i am adding link in my controller constructor.
here is code:
public function index()
{
$shots=[];
App::make('files')->link(storage_path('app\public'), public_path('..\public\storage'));
return View::make('adminpages.index',['shots'=>$shots]);
}

Resources