Digitalocean Spaces Laravel App - Missing region - php

I am getting the following error:
Missing required client configuration options: region: (string) A “region” configuration value is required for the “s3” service (e.g., “us-west-2”).
Here is my setup (XXX to hide my creds):
.env file:
DO_SPACES_KEY=XXXXX
DO_SPACES_SECRET=XXXX
DO_SPACES_ENDPOINT=https://nyc3.digitaloceanspaces.com
DO_SPACES_REGION=NYC3
DO_SPACES_BUCKET=XXXX
filesystems.php file (under the disks):
'do_spaces' => [
'driver' => 's3',
'key' => env('XXXXX'),
'secret' => env('XXXXX'),
'endpoint' => env('https://nyc3.digitaloceanspaces.com'),
'region' => env('NYC3'),
'bucket' => env('XXXXXX'),
],
Also in filesystems.php file:
‘cloud’ => env('FILESYSTEM_CLOUD’, 'do_spaces’),
in the view file:
function addDocument(Request $req, $projId)
{
$image = $req->file('uploadFile');
$file_name = pathinfo($image->getClientOriginalName(), PATHINFO_FILENAME);
$input['imagename'] = $file_name.'_'.time().'.'.$image->getClientOriginalExtension();
//$destinationPath = public_path('/images');
//$image->move($destinationPath, $input['imagename']);
$destinationPath = $image->store('/', 'do_spaces');
Storage::setVisibility($destinationPath, 'public');
//$data = array('fid'=>$folderId,'fileLoc'=>$input['imagename'],'projId'=>$projId);
//\DB::table('documents')->insert($data);
return back();
}
As you can see in the view, I try to store the image on the space and then store the path in the DB which would represent the path to the space.
I cannot get this error to go away; do you see any issues?
Thanks!

'region' => env('NYC3'), should be 'region' => env('DO_SPACES_REGION'),

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

How to set User ID to Storage path in Laravel?

I'm building an Restful API using Laravel 5 and MongoDB.
I'm saving avatar image for users.
It's working fine but I'm trying to create a Folder for every User. For example: "app/players/images/USERID"
I've tried to do something like this in different ways but I always get Driver [] is not supported.
\Storage::disk('players'.$user->id)->put($image_name, \File::get($image));
UploadImage:
public function uploadImage(Request $request)
{
$token = $request->header('Authorization');
$jwtAuth = new \JwtAuth();
$user = $jwtAuth->checkToken($token, true);
$image = $request->file('file0');
$validate = \Validator::make($request->all(), [
'file0' => 'required|image|mimes:jpg,jpeg,png'
]);
if ( !$image || $validate->fails() )
{
$data = array(
'code' => 400,
'status' => 'error',
'message' => 'Image uploading error-'
);
}
else
{
$image_name = time().$image->getClientOriginalName();
\Storage::disk('players')->put($image_name, \File::get($image));
$user_update = User::where('_id', $user->id)->update(['imagen' => $image_name]);
$data = array(
'code' => 200,
'status' => 'success',
'user' => $user->id,
'imagen' => $image_name
);
}
return response()->json($data, $data['code']);
}
filesystems.php:
'players' => [
'driver' => 'local',
'root' => storage_path('app/players/images/'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
I expect the user avatar image saves on User ID folder.
The disk call, tells Laravel which filesystem to use, let's assume you have an user with Id one, with your code it will access the filesystem playeers1.
What usually is done is to put these files in folder structures for the different users, so instead you could do. This will put your image file, in the folder 1.
\Storage::disk('players')->put($user->id . '/' . $image_name, \File::get($image));
I had a similar problem, check if the lines can change what you want to achieve.
\Storage::disk('players')->put("{$user->id}/{$image_name}", \File::get($image));
I relied on the laravel guide: File Storage - File Uploads
I hope it helps you. A cordial greeting.

How to fix upload image to s3 using Laravel

I try to upload an image to s3 using Laravel but I receive a runtime error. Using Laravel 5.8, PHP7 and API REST with Postman I send by body base64
I receive an image base64 and I must to upload to s3 and get the request URL.
public function store(Request $request)
{
$s3Client = new S3Client([
'region' => 'us-east-2',
'version' => 'latest',
'credentials' => [
'key' => $key,
'secret' => $secret
]
]);
$base64_str = substr($input['base64'], strpos($input['base64'], ",") + 1);
$image = base64_decode($base64_str);
$result = $s3Client->putObject([
'Bucket' => 's3-galgun',
'Key' => 'saraza.jpg',
'SourceFile' => $image
]);
return $this->sendResponse($result['ObjectURL'], 'message.', 'ObjectURL');
}
Says:
RuntimeException: Unable to open u�Z�f�{��zڱ��� .......
The SourceFile parameter is leading to the path of file to upload to S3, not the binary
You can use Body parameter to replace the SourceFile, or saving the file to local temporary and get the path for SourceFile
Like this:
public function store(Request $request)
{
$s3Client = new S3Client([
'region' => 'us-east-2',
'version' => 'latest',
'credentials' => [
'key' => $key,
'secret' => $secret
]
]);
$base64_str = substr($input['base64'], strpos($input['base64'], ",") + 1);
$image = base64_decode($base64_str);
Storage::disk('local')->put("/temp/saraza.jpg", $image);
$result = $s3Client->putObject([
'Bucket' => 's3-galgun',
'Key' => 'saraza.jpg',
'SourceFile' => Storage::disk('local')->path('/temp/saraza.jpg')
]);
Storage::delete('/temp/saraza.jpg');
return $this->sendResponse($result['ObjectURL'], 'message.', 'ObjectURL');
}
And, if you're using S3 with Laravel, you should consider the S3 filesystem driver instead of access the S3Client manually in your controller
To do this, add the S3 driver composer require league/flysystem-aws-s3-v3, put your S3 IAM settings in .env or config\filesystems.php
Then update the default filesystem in config\filesystems, or indicate the disk driver when using the Storage Storage::disk('s3')
Detail see document here
Instead of SourceFile you have to use Body. SourceFile is a path to a file, but you do not have a file, you have a base64 encoded source of img. That is why you need to use Body which can be a string. More here: https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobject
Fixed version:
public function store(Request $request)
{
$s3Client = new S3Client([
'region' => 'us-east-2',
'version' => 'latest',
'credentials' => [
'key' => $key,
'secret' => $secret
]
]);
$base64_str = substr($input['base64'], strpos($input['base64'], ",") + 1);
$image = base64_decode($base64_str);
$result = $s3Client->putObject([
'Bucket' => 's3-galgun',
'Key' => 'saraza.jpg',
'Body' => $image
]);
return $this->sendResponse($result['ObjectURL'], 'message.', 'ObjectURL');
}
A very simple way to uploads Any file in AWS-S3 Storage.
First, check your ENV setting.
AWS_ACCESS_KEY_ID=your key
AWS_SECRET_ACCESS_KEY= your access key
AWS_DEFAULT_REGION=ap-south-1
AWS_BUCKET=your bucket name
AWS_URL=Your URL
The second FileStorage.php
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
//'visibility' => 'public', // do not use this line for security purpose. try to make bucket private.
],
Now come on main Code.
Upload Binary File from HTML Form.
$fileName = 'sh_'.mt_rand(11111,9999).".".$imageFile->clientExtension();;
$s3path = "/uploads/".$this::$SchoolCode."/";
Storage::disk('s3')->put($s3path, file_get_contents($req->file('userDoc')));
Upload Base64 File
For Public Bucket or if you want to keep file Public
$binary_data = base64_decode($file);
Storage::disk('s3')->put($s3Path, $binary_data, 'public');
For Private Bucket or if you want to keep file Private
$binary_data = base64_decode($file);
Storage::disk('s3')->put($s3Path, $binary_data);
I Recommend you keep your file private... that is a more secure way and safe. for this, you have to use PreSign in URL to access that file.
For Pre sign-In URL check this post. How access image in s3 bucket using pre-signed url

Uploading file to S3 using presigned URL in PHP

I am developing a Web Application using PHP. In my application, I need to upload the file to the AWS S3 bucket using Presigned URL. Now, I can read the private file from the S3 bucket using pre-signed like this.
$s3Client = new S3Client([
'version' => 'latest',
'region' => env('AWS_REGION', ''),
'credentials' => [
'key' => env('AWS_IAM_KEY', ''),
'secret' => env('AWS_IAM_SECRET', '')
]
]);
//GetObject
$cmd = $s3Client->getCommand('GetObject', [
'Bucket' => env('AWS_BUCKET',''),
'Key' => 'this-is-uploaded-using-presigned-url.png'
]);
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
//This is for reading the image. It is working.
$presignedUrl = (string) $request->getUri();
When I access the $presignedUrl from the browser, I can get the file from the s3. It is working. But now, I am uploading a file to S3. Not reading the file from s3. Normally, I can upload the file to the S3 like this.
$client->putObject(array(
'Bucket' => $bucket,
'Key' => 'data.txt',
'Body' => 'Hello!'
));
The above code is not using the pre-signed URL. But I need to upload the file using a pre-signed URL. How, can I upload the file using a pre-signed URL. For example, what I am thinking is something like this.
$client->putObject(array(
'presigned-url' => 'url'
'Bucket' => $bucket,
'Key' => 'data.txt',
'Body' => 'Hello!'
));
How can I upload?
It seems reasonable that you can create a pre-signed PutPobject command by running:
$cmd = $s3Client->getCommand('PutObject', [
'Bucket' => $bucket,
'Key' => $key
]);
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes')->withMethod('PUT');
Then you might want to perform the PUT call from PHP using:
file_put_contents(
$request->getUri(),
'Hello!',
stream_context_create(['http' => [ 'method' => 'PUT' ]])
);
If you want to create a URL that a browser can submit, then you need to have the browser send the file as a form POST. This AWS documentation explains how to create a pre-signed POST request with the fields that you then need to put into an HTML form and display to the user: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-presigned-post.html
Also, this answer might be useful: https://stackoverflow.com/a/59644117/53538

Laravel S3 Storage disk; has() is returning false

I am trying to check if a file exists on s3, but I keep getting false back. I feel that I am doing something wrong, because the file does exist on s3.
Here is how I am checking:
$disk = Storage::disk('s3-avatars');
$exists = $disk->has($md5 . '.png'); // $md5 = 'c81e728d9d4c2f636f067f89cc14862c'
Here is the image: https://s3.amazonaws.com/acessegaming/avatars/c81e728d9d4c2f636f067f89cc14862c.png
Here are my disk settings:
's3-avatars' => [
'driver' => 's3',
'key' => env('AWS_KEY'),
'secret' => env('AWS_SECRET'),
'region' => env('AWS_REGION'),
'bucket' => env('AWS_BUCKET') . '/avatars',
],
Here is the composer.json
"require": {
"laravel/framework": "5.1.*",
"league/flysystem-aws-s3-v3" : "~1.0"
},
I figured it out!
First I had to download and save this file: http://curl.haxx.se/ca/cacert.pem
Next I needed to update this line in the php.ini file to point to the downloaded file:
curl.cainfo = "c:/config/cacert.pem"

Categories