Laravel: upload folder is created in the wrong directory - laravel

I have a form with a file input ready to be saved.
$request->validate([
'name'=> 'required|min:3',
'image'=> 'required|image|mimes:jpeg,png,jpg'
]);
$category = new Category();
$category->name = $request->name;
$path = $request->file('image')->store('categories_images');
$category->image = $path;
What the above code does is that it grabs the image field from the request and save it to the categories_images folder. When I first uploaded a file to test it it created the folder in storage/app.
My problem is that I want to preview the images on my site:
//store.state.serverPath returns: http://localhost:8000 -> this is right
<img :src="`${$store.state.serverPath}/storage/${category.image}`" class="image-wd"/>
When I inspect it in the nrowser it says:
http://localhost:8000/storage/categories_images/adGR57Gq6lNUqRVvEubRDfxNMZzEhya3A7oESUox.png not found
It expects the images in storage/app/public but creates the categories_images folder everytime I upload an image in storage/app. Am I missing something here?

It seems I can't post a comment just as an answer. So let me add my input. Did you create your symbolic link? If not do it now, or just redo it. I had the same issue when i ported my code from mac to windows. Even if all the configuration was done corectly the link was related to my mac. I just fixed that issue now for my code. So thank you for your question.
php artisan storage:link
Also the first parameter of store is the path you want to save the file under storage/public directory. You need to append the directory name in yor url to find the file.
This is the code I use in one of my projects.
$path = isset($validated['document']) ? $path = $request->file('document')->store('pdfs', 'public') : null;
The file will be accessed with the url www.example.com/storage/pdfs/$path
document is the name of file input.

You miss the part of the tutorial where he changed the config -> filesystems.php with this
'local' => [
'driver' => 'local',
'root' => storage_path('app/public'),
],

Related

Laravel File not found at path (again)

So, I've already dug through the questions here about this, but still can't seem to figure it out.
Do you know what I am doing wrong here?
$imageName = $thishire->color_image;
$path = public_path('/img/colorImages/' . $imageName);
$file = Storage::get(public_path('/img/colorImages/'. $imageName));
$file->move($path, public_path('/img/uploads'));
The 3rd line is throwing an error:
"File not found at path: Applications/MAMP/htdocs/GT Laravel/public/img/colorImages/l18Ow1uVBqhReGqW7lWjanp2vT5bOAKt8pylnmmb.jpg"
But that is the correct path, so I'm super confused.
You shouldn't do Storage::get(public_path('/img/colorImages/'. $imageName)).
Storage::get() is relative to the storage disk root.
If you use the default storage configuration, then your storage root path is storage_path('app'), said otherwise /path/to/your/project/storage/app.
This is what's happening:
Storage::get(public_path('/img/colorImages/'. $imageName));
// looking into /path/to/your/project/storage/app/path/to/your/project/public/img/colorImages
// which is obviously wrong
What you should do instead:
Store your public files in the storage/app/public directory
Use the php artisan storage:link command to create a symlink between public and storage/app/public. If you are not familiar with this concept, it'll create a small file into your public directory which is a shortcut to the storage/app/public directory. More about this here: https://laravel.com/docs/8.x/filesystem#the-public-disk
For instance, with a file named helloworld.jpg and located in storage/app/public/users/8/helloworld.jpg, you can get it by doing:
Storage::disk('public')->get('users/8/helloworld.jpg');
// or Storage::get('public/users/8/helloworld.jpg');
I know it can be confusing at first. This is a quick tip to "know where you are and what your are looking at". Use Storage::path():
dd(Storage::path(public_path('/img/colorImages/'. $imageName)));
// you'll see the problem
don't forget public meaning access storage but by created symlink
I think you should be store image in your path before getting it by using
Storage::put(public_path('/img/colorImages/'), $imageName);
and you can check documentation from here
I solved it.
$imageName = $thishire->color_image;
$old = public_path('/img/colorImages/'.$imageName);
$new = public_path('/img/uploads/'.$imageName);
rename($old, $new);

How to get and delete files from storage using Laravel?

I'm building a job search application where a Candidate User can upload a profile of themselves along with 3 (quick, about 30 second) videos based on pre determined questions. For example one of the questions is "1. What makes you stand out over other candidates?". He can video himself answering the question and then upload the video.
The way my system works is, the videos get uploaded to a tmp Disk that I created and into a videos folder, then the files get uploaded to s3.
After this happens I want to delete the files from the tmp folder but I keep getting errors.
Here is the tmp Disk in config/filesystems.php:
'tmp' => [
'driver' => 'local',
'root' => storage_path(),
'url' => env('APP_URL').'/storage',
'visibility' => 'public'
],
I think that there might be a bug in my application because I can't delete any files from this location, in fact I can't even get them.
When I try to get a file and die dump it that I know is in storage/videos/ folder like this:
dd(Storage::get(storage_path().'/videos/1607107892Pexels-Videos-1181911-copy.mp4'));
When I click on the network tab on the response it says No response data.
and if I try to delete a file like this:
Storage::delete(storage_path().'/videos/1607107892Pexels-Videos-1181911-copy.mp4'));
I keep getting this error:
League\Flysystem\FileNotFoundException: File not found at path: videos/1607107892Pexels-Videos-1181911-copy.mp4 in /Applications/XAMPP/xamppfiles/htdocs/highrjobsadminlte/vendor/league/flysystem/src/Filesystem.php:389
What am I doing wrong?
Get file using storage facade
You can specify the disk using the Storage facade and then get your desired files. Something like below code may help you:
Storage::disk('tmp')->get('videos/1607107892Pexels-Videos-1181911-copy.mp4')
Delete file using facade
As said in getting file section, you can delete any file or directory after specifying the disk.
Storage::disk('tmp')->delete('videos/1607107892Pexels-Videos-1181911-copy.mp4')
Check available directories and files
If you doubt about whether you're in the correct disk or not, you can check the existing directories and files in the target disk using allDirectories() or allFiles() methods.
Storage::disk('tmp')->allDirectories();
Storage::disk('tmp')->allFiles();
The default disk used by filesystem is configured in config/filesystems.php
'default' => env('FILESYSTEM_DRIVER', 'local'),
'disks' => [
//other disks
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
//...
]
However you use a custom disk tmp when storing the file and have set it's root to storage_path() whereas the default local disk has the root path set to storage_path('app')
So inorder to delete the file in tmp disk you should specify the disk
Storage::disk('tmp')->delete('/videos/1607107892Pexels-Videos-1181911-copy.mp4');

Laravel - File upload doesn't seem to allow all types of files for some reason

My application denies access to upload files with certain extensions for some reason.
It prints out the error:
fopen(C:\wamp64\www\storage\app\public/wrdjxF3EMbtGCUyXjSEWH5zeAu822ACeKikLPaCT.): failed to open stream: Permission denied
The file types that have given out this error so far are: .msg and .txt.
I have no clue what causes this problem, other file types seem to work fine.
The controller function that handles the file uploads:
if($request->hasFile('document'))
{
$files = $request->file('document');
foreach($files as $file){
if($file){
$name = $file->getClientOriginalName();
$size = $file->getClientSize();
$size = number_format($size / 1048576,2);
$path = $file->store('public');
Document::create([
'report_id' => $id,
'report_type' => "App\VisitingReport",
'file_path' => $path,
'file_name' => $name,
'file_size' => $size.' MB'
]);
}
}
}
Any help would be appreciated, thanks.
I'm running this on a Windows computer using WAMP.
I am convinced that it has something to do with the permissions indeed. I'm already a step further, the file gets uploaded but this time without the extension.
can you paste here what permissions you see for other file types and .txt after uploads. Run ls -la in the place where these files are stored and permission should be on far left. something like rwxr-wr-w. Paste here so that at least it can give a clue on what could be the issue.
Otherwise, once .txt file is uploaded you can run chmod 777 some.txt and see if you are still getting permission issue. If you aren't getting permission issue anymore than it's somehow creating .txt file with different permission. But it's not a good idea to do 777 for anything :D. But at least now you know what the problem is.
If permissions are the problem then here is a wonderful answer on this topic
How to set up file permissions for Laravel?
Good luck :)
I'm not an expert just trying to help
I have faced with this error, but I don't know it works for you or not.
put this in your .env file
FILESYSTEM_DRIVER = public
and link the public folder with storage folder with this command:
php artisan storage:link
I hope it works.

Deleting file with Laravel

i'm having troble deleting a file from a Laravel Project.
The file is in the /storage/exports directory, it's an excel stored on the disk usingthe Laravel Excel library.
This is my code:
$path = $excel->store('xls', false, true)['full'];
...send the xls via mail....
Storage::delete($path);
When i check the existence of the file with file_exist i get true, so Laravel is able to read the file.
I've also checked the permission for the folder and i give all permissions on this folder using chmod 777
Any ideas?
Thanks!
The storage driver already has an awareness of a root directory, so the $path must be relative, not full. So if your file is in:
/this/is/the/full/path.xls, and the config filesystems.disks.local.root is set to /this/is/the/full, you're essentially having it look for a file in /this/is/the/full/this/is/the/full/path.xls.
You have two options.
1) Add a new driver to that config, and reference it directly:
'custom_location' => [
'driver' => 'local',
'root' => '/some/other/root/path',
]
Storage::driver('custom_location')->delete($relativePathFromRoot)
2) Create a one-off:
$rootPath = '/some/other/root/path';
$client = Storage::createLocalDriver(['root' => $rootPath]);
$client->delete($relativePathFromRoot);
Try storing the file within storage/app/exports. The Storage class's default location to store files is storage/app.
It may be a good idea to instead of using the Excel class to store the file, to instead save the file using the Storage class: Storage::put('exports/excelfile.xls', $fileContents);
Even though you are using Laravel, you can use regular PHP functions.
unlink($path);

How to get public directory?

I am a beginner here so pardon me for this question am using return File::put($path , $data); to create a file in public folder on Laravel. I used this piece of code from controller I need to know the value of $path how should it be.
Use public_path()
For reference:
// Path to the project's root folder
echo base_path();
// Path to the 'app' folder
echo app_path();
// Path to the 'public' folder
echo public_path();
// Path to the 'storage' folder
echo storage_path();
// Path to the 'storage/app' folder
echo storage_path('app');
You can use base_path() to get the base of your application - and then just add your public folder to that:
$path = base_path().'/public';
return File::put($path , $data)
Note: Be very careful about allowing people to upload files into your root of public_html. If they upload their own index.php file, they will take over your site.
I know this is a little late, but if someone else comes across this looking, you can now use public_path(); in Laravel 4, it has been added to the helper.php file in the support folder see here.
The best way to retrieve your public folder path from your Laravel config is the function:
$myPublicFolder = public_path();
$savePath = $mypublicPath."enter_path_to_save";
$path = $savePath."filename.ext";
return File::put($path , $data);
There is no need to have all the variables, but this is just for a demonstrative purpose.
Hope this helps,
GRnGC
I think what you are looking for is asset(''); You can use asset('storage'), after creating your symbolic link.
asset('public')
OR
url('public')

Resources