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

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'

Related

How to access data from an array when it's inside an std object? Error: Illegal string offset 'id'

How to access this array object in Laravel 6, using Eloquent?
[line_items] => Array
(
[0] => stdClass Object
(
[id] => 4088662196333
[variant_id] => 29653605285997
$external = DB::table('orders')->pluck('import_order_data');
...
foreach ($external as $key => $val) {
...
Cart::updateOrCreate([
'line_item_id' => ['line_item_id' => $val['id']],
],
ErrorException
Illegal string offset 'id'
If I change it to:
'line_item_id' => ['line_item_id' => $val->id],
I get error:
ErrorException
Trying to get property 'id' of non-object
If I change it to:
'line_item_id' => ['line_item_id' => $val['line_items']->id],
I get error:
Illegal string offset 'line_items'
EDIT:
The problem was:
protected $casts = [
'import_order_data' => 'array',
];
Now I can access it like this:
dd($val['line_items'][0]['id']);
Which provides:
4092309209197
or
dd($val['line_items']);
which provides:
array:1 [▼
0 => array:26 [▼
"id" => 4092309209197
"sku" => "1605"
"name" => "Printer Ink"
Any better options on accessing the data?
EDIT:
Answer:
foreach ($val['line_items'] as $index => $lineItem) {
dd($lineItem['id']);
Which provides:
4092309209197
Is this a reasonable way to do it?
If I understand correctly, your array looks like this:
$arr = [
[
"id" => 4092309209197,
"sku" => "1605",
"name" => "Printer Ink",
....etc.....
]
];
Fine. First, since the outer array only has one item, you can do this:
$innerArr = $arr[0];
Now you've got this:
$innerArr = [
"id" => 4092309209197,
"sku" => "1605",
"name" => "Printer Ink",
....etc.....
]
And you can access it like this:
echo $innerArr["id"];
echo $innerArr["sku"];
....etc....
Or like this:
foreach($innerArr as $key => $val){
echo $key.": ".$val."\r\n";
}

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 .

select data based on the array

I have an array from query like below:
array:84 [
0 => array:2 [
"comp" => "50007148"
"cus" => "F0401"
]
1 => array:2 [
"comp" => "50007148"
"cus" => "J0050"
]
2 => array:2 [
"comp" => "50007148"
"cus" => "L"
]
3 => array:2 [
"comp" => "50007148"
"cus" => "LT"
]
4 => array:2 [
"comp" => "50007148"
"cus" => "RP"
]
Now I need to write a query where comp, cus in above query.
$rslt = Stdetl::whereIn('comp, cus', $categories)
->where(YEAR(docdate), '=', 2019)
->get(SUM(number))->toArray();
But this query is not working. I am getting error as follows:
(1/1) FatalErrorException
Call to undefined function App\Http\Controllers\YEAR()
But this is not the only mistake in that query .
YEAR() is a mysql function, you should use whereRaw() to query this. Like this:
->whereRaw('YEAR(docdate) = 2019')
Update:
For your whereIn() part, you have to make two queries, one for each column. So you will have to get the correct values from the array. This can be done using array_map.
For example:
->whereIn('comp', array_map(function($cat) { return $cat['comp']; }, $categories))
->whereIn('cus', array_map(function($cat) { return $cat['cus']; }, $categories))
You can't use whereIn like that, use this way
$rslt=Stdetl::whereIn('comp', $categories)
->whereIn('cus', $categories)
->where(date('Y', strtotime(docdate)), '=', 2019)
->get(SUM(number))->toArray();;

Laravel: Test post with real file

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?

Replicating models across 2 systems

I have 2 systems which are seperate from each other. To let them communicate I have built an API. Both systems have common Models, one of which is a Project Model with all its relationships.
Within System A, to send a Project with its relationships I do the following.
$client = new GuzzleHttp\Client();
$jsonProject = json_encode(Project::with('projectType', 'projectType.projectTypeData',
'projectAssets', 'projectAssets.projectAssetsData')->find($project->id));
$req = $client->request('POST', 'https://someurl/postProject', [
'body' => json_encode($jsonProject),
'headers' => [
'Content-Type' => 'application/json',
'Content-Length' => strlen($jsonProject),
]
]);
Within System B I have the routes set up, and when the above is posted the following is triggered
public function store(Request $request)
{
$project = $request->all();
dd($project);
}
When I make the post request from System A I see something like this because of the dump in System B (I have removed a lot of the output to cut down on code).
array:17 [
"id" => 3
"projectName" => "Test Project"
"user_id" => 1
"contact" => "John Doe"
"project_type" => array:7 [
"id" => 3
"project_id" => 3
"project_type_data" => array:1 [
0 => array:8 [
"id" => 5
"projectType" => "Standard"
]
]
]
"project_assets" => array:7 [
"id" => 2
"project_id" => 3
"project_assets_data" => array:4 [
0 => array:8 [
"id" => 5
"label" => "Logo"
"altTag" => ""
"urlPath" => ""
"projectAssetsId" => 2
]
]
]
]
So everything seems to work fine. My question is this. System B now has a load of json data containing all the data required to make the models. If I was able to send a model via the api (not json) then I could easily create the model within System B. Because it is json data however, and I cant decode it because it is not a string, do I have to start looping it all in order to make my models?

Resources