Laravel: Test post with real file - laravel

I'm using laravel 5.6. I'm trying to test a post form that need a file.
So I wrote that
$file = new \Illuminate\Http\UploadedFile(base_path() . '/tests/samples/Cylinder.stl', 'Cylinder.stl');
$response = $this->post( route('attachments.store' ) , [
'file' => $file,
'attachable_id' => $this->threedviews->id,
'attachable_type' => 'App\ThreeDView',
]);
But when I dd( $this->app['session.store'] ), I get
#bags: array:1 [
"default" => Illuminate\Support\MessageBag {#1198
#messages: array:1 [
"file" => array:1 [
0 => "The file failed to upload."
]
]
#format: ":message"
}
]
When I use the form manualy, everything is working well.
Also the $file seems strange
Illuminate\Http\UploadedFile {#43
-test: false
-originalName: "Cylinder.stl"
-mimeType: "application/octet-stream"
-error: 0
...
}
The test flag is set to false, is it supposed to be like this?

Related

Laravel 9 accessing AWS S3 - UnableToWriteFile at location

I have built a CRUD application with Laravel, but as I want it to be hosted on heroku, using the Laravel storage is not a solution, which is why I am trying to use AWS S3.
I followed a few tutorials, and it seemed pretty straight forward to do, however I get this error :
League \ Flysystem \ UnableToWriteFile
Unable to write file at location: nameOfMyPicture.jpg.
What I have done so far :
I have run the command composer require league/flysystem-aws-s3-v3.
I have run config:clear and cache:clear.
I have run multiple times composer update.
My .env file should have the right information as well.
I tried not using .env file and putting all the information directly in the filesystems.php file.
Here is the code in my query.
if ($request->hasfile('photo')) {
$file = $request->file('photo');
$name = time() . '.' . $file->getClientOriginalExtension();
$filePath = 'locations/' . $name;
Storage::disk('s3'))->put($filePath, file_get_contents($file);
return back()->with('msg', 'Image Uploaded successfully');
}
When using
if (Storage::disk('s3')->exists('my-file-name.jpg')) {
dd("hello");
}
I get the error message : Unable to check existence for: myFileName.
When I dd(Storage::disk('s3'))->put($filePath, file_get_contents($file));, the url is null, but I do get the right bucket name, the credentials from my env file, the right region etc... Here is the dd.
^ Illuminate\Filesystem\AwsS3V3Adapter {#1388 ▼
#driver: League\Flysystem\Filesystem {#1379 ▼
-adapter: League\Flysystem\AwsS3V3\AwsS3V3Adapter {#1382 ▶}
-config: League\Flysystem\Config {#1378 ▼
-options: array:1 [▼
"url" => null
]
}
-pathNormalizer: League\Flysystem\WhitespacePathNormalizer {#1374}
}
#adapter: League\Flysystem\AwsS3V3\AwsS3V3Adapter {#1382 ▼
-client: Aws\S3\S3Client {#1343 ▼
-aliases: null
-config: array:9 [▶]
-region: "eu-west-3"
-endpoint: GuzzleHttp\Psr7\Uri {#1450 ▼
-scheme: "https"
-userInfo: ""
-host: "s3.eu-west-3.amazonaws.com"
-port: null
-path: ""
-query: ""
-fragment: ""
-composedComponents: null
}
-api: Aws\Api\Service {#1355 ▼
#definition: array:4 [▶]
#shapeMap: Aws\Api\ShapeMap {#1356 ▶}
-apiProvider: Aws\Api\ApiProvider {#1354 ▶}
-serviceName: "s3"
-apiVersion: "2006-03-01"
-operations: []
-paginators: null
-waiters: null
}
-signatureProvider: Closure($version, $service, $region) {#1353 ▶}
-credentialProvider: Closure() {#1401 ▶}
-handlerList: Aws\HandlerList {#1350 ▶}
-defaultRequestOptions: []
}
-prefixer: League\Flysystem\PathPrefixer {#1376 ▶}
-bucket: "veville-images"
-visibility: League\Flysystem\AwsS3V3\PortableVisibilityConverter {#1339 ▶}
-mimeTypeDetector: League\MimeTypeDetection\FinfoMimeTypeDetector {#1381 ▶}
-options: []
-streamReads: false
}
#config: array:11 [▼
"driver" => "s3"
"key" => "keyFromEnvFile"
"secret" => "keyFromEnvFile"
"region" => "eu-west-3"
"bucket" => "veville-images"
"url" => null
"endpoint" => null
"use_path_style_endpoint" => false
"throw" => true
"version" => "latest"
"credentials" => array:2 [▼
"key" => "keyFromEnvFile"
"secret" => "keyFromEnvFile"
]
]
#prefixer: League\Flysystem\PathPrefixer {#1377 ▶}
#temporaryUrlCallback: null
#client: Aws\S3\S3Client {#1343 ▶}
The filesystems.php file concerning s3
'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'),
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
'throw' => true,
],
My .env file
AWS_ACCESS_KEY_ID=rightkey
AWS_SECRET_ACCESS_KEY=rightsecret
AWS_DEFAULT_REGION=eu-west-3
AWS_BUCKET=veville-images
AWS_USE_PATH_STYLE_ENDPOINT=false
Here is the AWS User Permission policies : user_policy.
When using the terminal, using the same AWS credentials, I have access to my bucket, and can upload and download files. However I can't through Laravel.
I am at a complete loss here. Any help would be greatly appreciated.
Thank you in advance.
To anyone who might have the same problem. I managed to upload a file to my s3 bucket.
After looking around on the github, there was a commit not merged that would give the actual error which was :
'Error executing "PutObject" on "https://bucket.s3.region.amazonaws.com/file.ext"; AWS HTTP error: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for https://bucket.s3.region.amazonaws.com/file.ext'
To resolve that issue :
I have a very Simple Solution to this problem. You can do this without any certificate file.
Go on Laravel Root Folder -> Vender -> guzzlehttp -> guzzle -> src
open Client.php
find $defaults Array . that looks like this way.
$defaults = [
'allow_redirects' => RedirectMiddleware::$defaultSettings,
'http_errors' => true,
'decode_content' => true,
'verify' => true,
'cookies' => false
];
Now main Job is to change value of verify key.
'verify' => false,
So After this, it will not check SSL Certificate for CURL Request. This Solution works for me. I find this solution after much research.
Note: 'verify' => false can create a security issue in any Live or Development server. Do not try this on Server. This solution is only for Local System.
Answer found here : AWS SSL security error : [curl] 60: SSL certificate prob...: unable to get local issuer certificate

get a data from an array

get a data from an array ..code for getting cart
public function show()
{
$data = $this->cartService->getCart(auth()->user()->id);
dd($data);
}
Response
array:2 [
"cart" => array:9 [
"id" => 244
"user_id" => 53
"total_mrp" => "56000.00"
"promo" => "HELLO"
"discount" => "30.00"
"meta" => {#1575
+"sub_total": 56000
}
]
"cart_items" => array:1 [
]
]
]
]
HOW CAN I GET PROMO IN A Variabel???
i tried
return $data->promo;
but error
You can use collect(). You can read about this function from laravel doc
$data = $this->cartService->getCart(auth()->user()->id);
$cart = collect($data['cart']??[]);
dd($cart->get('promo'));

Problem with 'exists' validation in Laravel when the input is an array

The file here /vendor/laravel/framework/src/Illuminate/Validation/Concerns/ValidatesAttributes.php and the method validateExists returns error
Array to string conversion
when user inputs are like this below:
array:2 [
0 => array:1 [
'key' => 'value'
]
1 => array:1 [
'key' => 'value'
]
]
This array goes into the variable $value on line 655 in this file.
Is it a real laravel bug there?
Edit
My Validation:
'cars.*.brand' => [
'exists:my_table,id',
]
There is not a lot of info to give you an answer, but have you tried:
'cars.*.brand' => 'exists:my_table,id'

Laravel resource ignoring given fields

I'm trying to convert a given API response in something easy to work with.
This is what I have so far:
Controller:
public function drive()
{
$optParams = [
'corpora' => 'drive',
'driveId' => env('GOOGLE_DRIVE_ID'),
'includeItemsFromAllDrives' => true,
'supportsAllDrives' => true,
'fields' => 'files(*)'
];
$results = $this->googleDrive->files->listFiles($optParams);
$data = collect($results);
$collection = new FileCollection($data);
dd($collection);
return 'Hi!';
}
FileCollection resource:
public function toArray($request)
{
return [
'data' => $this->collection,
'meta' => ['files_count' => $this->collection->count()],
];
}
File resource:
public function toArray($request)
{
return [
'name' => $this->resource['name'],
'mime' => $this->resource['mimeType'],
'parents' => $this->resource['parents'],
'version' => $this->resource['version'],
'webDownloadLink' => $this->resource['webContentLink'],
'webLink' => $this->resource['webViewLink'],
'modified_at' => $this->resource['modifiedTime'],
'size' => $this->resource['size']
];
}
This is the result I'm getting:
FileCollection {#223 ▼
+collects: null
+collection: Collection {#243 ▶}
+resource: Collection {#243 ▼
#items: array:2 [▼
0 => File {#224 ▼
+resource: Google_Service_Drive_DriveFile {#279 ▶}
+with: []
+additional: []
}
1 => File {#263 ▼
+resource: Google_Service_Drive_DriveFile {#269 ▶}
+with: []
+additional: []
}
]
}
+with: []
+additional: []
}
So as you can see the types of resources are correct, but for some reason the 'meta' in the FileCollection isn't there, nor are the fields in the File resource. All fields are still shown, like 30+ (instead of the 8 requested in the FileResource).
Am I missing something here?
EDIT:
When accessing the collection with the toArray() method ($collection->toArray(null)), I do indeed get the appropriate result:
array:2 [▼
"data" => Collection {#243 ▼
#items: array:2 [▼
0 => File {#224 ▶}
1 => File {#263 ▶}
]
}
"meta" => array:1 [▼
"files_count" => 2
]
]
So how do I make sure now that this collection uses the toArray() of the FileResources? (I'm still getting over 30 fields, instead of 8).
PS: I don't really get why I need to call the toArray(), nowhere in their documentation is it written : https://laravel.com/docs/5.8/eloquent-resources .

Laravel 5: test return redirect with session

I have an insert method in Laravel, that return a message
if ($update === true) {
return redirect(route('settings-cloudflare'))
->with('success', trans('common.operation_completed_successfully'));
// validation ok
} else {
How can I test that redirected view has "success" inside?
My test is:
$response = $this->followingRedirects()->actingAs($user)->post(Route('settings-cloudflare-store'),$data);
dd(session()->all());
But session doesn't have "success" inside.
This is the dd of session:
array:3 [
"_token" => "2jV8sVgRluET9UCng2HzqDYOgSkTVYMqJTT20MsP"
"_flash" => array:2 [
"new" => []
"old" => []
]
"_previous" => array:1 [
"url" => "http://192.168.1.101/settings/cloudflare"
]
]
Thank you very much

Resources