Laravel - Can't save files to public_path using storeAs - php

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

Disk [public] does not have a configured driver. in laravel image upload

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

Laravel uploaded file not appears in linked "public/storage" folder

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');

Pull down AWS S3 bucket locally in Laravel

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.

Cleanup script with putFileAs works in windows, but not in Ubuntu, with Windows share

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..

Laravel 5.2 uploading file using filesystem

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);
}

Categories