I cannot upload files to the public_path folder in Laravel 5.4. I can't understand what's going wrong, the documentation makes it look easy. $request is the POSTed contents of a form. filename is a file submitted via the form.
public function uploadFile($request) {
if ($request->hasFile('filename') && $request->file('filename')->isValid()) {
$file = $request->filename;
$hash = uniqid(rand(10000,99999), true);
$directory = public_path('files/'.$hash);
if(File::makeDirectory($directory, 0775, true)) {
return $file->storeAs($directory, $file->getClientOriginalName());
}
}
return NULL;
}
The directory is created, but there's no file inside. As you can see, the folder has 775 permissions.
I've tried added a trailing slash. I've tried removing public_path altogether. Nothing works.
What am I doing wrong? :(
By default file system use your default disk named 'local' that upload files in storage/app folder store using store, stroeAs etc...
The filesystem configuration file is located at config/filesystems.php.
either you can change root path under 'local'
from 'root' => storage_path('app'), to 'root' => public_path('files'),
and then in your code change from
$directory = public_path('files/'.$hash); to $directory = public_path($hash);
OR you can create new disk in config/filesystem.php
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'my_upload' => [
'driver' => 'local',
'root' => public_path('files'),
'visibility' => 'public',
],
and then mention new disk as below while storing file
$file->storeAs($directory, $file->getClientOriginalName(), 'my_upload');
After performing all above if not work hit below commands in order
php artisan config:clear
php artisan cache:clear
php artisan config:cache
You can try this :
if(File::makeDirectory($directory, 0775, true)) {
return $file->store($directory, $file->getClientOriginalName());
}
Hope this help you !
Related
I am trying to upload a file to a public folder which was working lately but now it is showing below error:
Disk [public] does not have a configured driver.
I tried checking for configured driver in config/filesystems.php but, it is already set there. I am not getting where the issue might be.
Upload code:
public function upload(ProductImageRequest $request, Product $product)
{
$image = $request->file('file');
$dbPath = $image->storePublicly('uploads/catalog/'.$product->id, 'public');
if ($product->images === null || $product->images->count() === 0) {
$imageModel = $product->images()->create(
['path' => $dbPath,
'is_main_image' => 1, ]
);
} else {
$imageModel = $product->images()->create(['path' => $dbPath]);
}
return response()->json(['image' => $imageModel]);
}
Code in config/filesystems.php
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
i use this code for moving the picture and storing its name you may want to give it a shot
//get icon path and moving it
$iconName = time().'.'.request()->icon->getClientOriginalExtension();
$icon_path = '/category/icon/'.$iconName;
request()->icon->move(public_path('/category/icon/'), $iconName);
$category->icon = $icon_path;
i usually move the image then store its path in db and this is what my code shows you can edit it as desired
When I run command: php artisan storage:link, this creates folder /public/storage.
then I have code, which handles uploaded file:
// get file original name and extension here, then generate file new name $fileNameToStore
// set file path
$path = $request->file('my_file')->storeAs('public/uploaded_imgs', $fileNameToStore);
Code works and uploaded file appears in /storage/app/public/uploaded_imgs/ folder, which is nice, though there is nothing in /public/storage folder.
Why there is not uploaded_imgs folder in /public/storage directory? What I'm doing wrong?
In config/filesystems.php, you could do this... change the root element in public
Note : instead of upload you can use your folder name
'disks' => [
'public' => [
'driver' => 'local',
'root' => public_path() . '/uploads',
'url' => env('APP_URL').'/public',
'visibility' => 'public',
]
]
and you can access it by
Storage::disk('public')->put('uploaded_imgs', $request->file('my_file'));
or
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path(),
],
'uploads' => [
'driver' => 'local',
'root' => public_path() . '/uploads',
],
]
Then use it :
Storage::disk('uploads')->put('filename', $file_content);
Try this:
Storage::disk('public')->put('uploaded_imgs', $request->file('my_file'));
hopefully it will work.
When you run php artisan storage:link command, Laravel generates a "storage" symlink under "public" folder which directs to /storage/app/public so your code is correct.
There is no public/storage directory, its a symlink which directs to /storage/app/public which is where your uploaded_imgs folder has been generated.
public/storage => /storage/app/public
You can use the following code to upload a file:
$file = $request->file('my_file');
$fileNameWithoutExtension = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$path = "public/uploaded_imgs/" + $fileNameWithoutExtension +"."+$file->getClientOriginalExtension();
Storage::disk('local')->put($path, file_get_contents($file), 'public');
I have a task of pulling down assets which are stored on an AWS S3 bucket and storing those in a local project using Laravel. Also, the files are encrypted.
I need to write a script to do this.
Any ideas on how to do this?
Assuming you have following disks :
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
's3' => [
'driver' => 's3',
'key' => env('S3_KEY'),
'secret' => env('S3_SECRET'),
'region' => env('S3_REGION'),
'bucket' => env('S3_BUCKET'),
'http' => [
'connect_timeout' => 30,
],
],
],
Then you can copy file using :
if(Storage::disk('s3')->exists('path/yourfile.txt')){
Storage::disk('local')->writeStream('path/yourfile.txt', Storage::disk('s3')->readStream('path/yourfile.txt'));
}
To move the file :
if(Storage::disk('s3')->exists('path/yourfile.txt')){
Storage::disk('local')->writeStream('path/yourfile.txt', Storage::disk('s3')->readStream('path/yourfile.txt'));
Storage::disk('s3')->delete('path/yourfile.txt');
}
If you have set default disk then you can skip mentioning it spefically and directly do Storage::something()
Moving all files from s3 to local disk :
Considering you have different disks which are not on the same server, you need to do little bit extra as compared to both disks on the same server :
$s3Files = Storage::disk('s3')->allFiles();
foreach ($s3Files as $file) {
// copy
Storage::disk('local')->writeStream($file, Storage::disk('s3')->readStream($file));
// move
Storage::disk('local')->writeStream($file, Storage::disk('s3')->readStream($file));
Storage::disk('s3')->delete($file);
}
Or You can move the delete() after the entire moving and delete all files together like :
Storage::disk('s3')->delete(Storage::disk('s3')->allFiles());
which is essentially similar but just one function call.
Using Laravel 5.5, I have a method in my controller to get files from 1 folder, rename them and store them in my application and make them publicly accessible.
The method:
public function cleanup_files()
{
ini_set('max_execution_time', 3000);
ini_set('memory_limit','16M');
$i = 0;
$files = Storage::disk('partE')->files('sb');
foreach ($files as $file) {
// strip the file name to about 20 characters and
// then remove anything but numbers
// since some of the names contain dates at the end.
$digits = preg_replace('/\D/', '', substr($file, 0, 20));
// The remaining number contains 4 digits for the year
// and 1 to 4 digits for the number
$year = substr($digits, 0, 4);
$number = substr($digits, 4);
// Now set the new filename
$filename = 'SB' . $year . '-NO' . $number . '.pdf';
if (! Storage::disk('public')->exists('sb/' . $filename)) {
$newfile = new File(env('BULK_FILES_DIR') . $file);
Storage::disk('public')->putFileAs('sb', $newfile, $filename);
echo "New file added: " . $filename . '<br>';
$i++;
} else {
echo $filename . " already exists in forlder.<br>";
}
}
echo "<br><br>" . $i . " files added...";
}
in my .env file on Windows I have BULK_FILES_DIR="D:/Projects/SBs/".
On Ubuntu: BULK_FILES_DIR="/home/user/bibvault/"
in filesystems.php:
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'partE' => [
'driver' => 'local',
'root' => env('BULK_FILES_DIR'),
]
],
This works nicely in Windows. Then I transfer it to my production machine, which is Ubuntu 16.04...
I created a DFS Windows share, added a special user, mounted this share:
sudo mount -v -t cifs //doman.org/bibvault /home/user/bibvault -o uid=www-data,gid=www-data,credentials=/home/user/.cifscreds,iocharset=utf8,file_mode=0777,dir_mode=0777,context="system_u:object_r:httpd_sys_content_t:s0"
The mount is successful, I can see the files in Ubuntu. But when I run my method, I get
fopen(/home/user/bibvault/sb/2004 no 87.pdf): failed to open stream: Permission denied
Whoops shows me line 162 of /vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php, which is in the definition of the putFileAs method.
I tried using my own uid, I gave the connecting Windows user write, then full access to the windows share. Nothing seems to change this error.
I'm not seeing it, so I hope anyone can point me to where it might be wrong. Maybe permission settings on the Windows share. Maybe on the mount itself... I have no clue at the moment..
I am having some troubles with laravels filesystem uploading.
When I try to execute this code
Storage::disk('public')->put(
$img->getClientOriginalName(),
file_get_contents($img->getRealPath())
);
nothing happens locally in the public folder, I even checked if the file exists and it returns true
dd(Storage::disk('public')->exists($img->getClientOriginalName()));
For now I am using the $img->move method and it works as I want to.
Disk is also configured in filesystems.php
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'visibility' => 'public',
],
I am confused with this because a couple of weeks ago it worked as it should on another project.
I have now fixed this problem with the help of Claudio by using 'root' => public_path('').
This should work:
if ($request->hasFile('myFile'))
{
$fileExtension = strtolower($request->file('myFile')->getClientOriginalExtension());
$newFilename = str_random(20) . '.' . $fileExtension;
$storagePath = storage_path() . '/app/uploads/';
$request->file('myFile')->move($storagePath, $newFilename);
}