Save nested json into database in laravel - php

I'm consuming an API with Guzzle via laravel and storing the response into a database.
I've been successful in storing the "ratings" part of the JSON response. But now I'd like to add "meta" - "extractDate".
What do I need to change to get this to work?
Below is the JSON API response I'm working from and part of the controller I'm using to save into my database.
Using laravel 7.0
**JSON from API**
{
"ratings": [
{
"ratingId": 12,
"ratingName": "5",
"ratingKey": "fhrs_5_en-gb",
"ratingKeyName": "5",
"schemeTypeId": 1,
"links": [
{
"rel": "self",
"href": "http://api.ratings.food.gov.uk/ratings/12"
}
]
}
],
"meta": {
"dataSource": "API",
"extractDate": "2020-06-29T21:24:43.820107+01:00",
"itemCount": 11,
"returncode": "OK",
"totalCount": 11,
"totalPages": 1,
"pageSize": 11,
"pageNumber": 1
}
}
**controller snippet**
$client = $this->client();
$request = $client->request('GET', 'https://api.ratings.food.gov.uk/ratings');
$ratings = json_decode($request->getBody()->getContents(), true);
collect($ratings['ratings'])
->each(function($rating, $key) {
Rating::updateOrCreate([
'ratingId' => $rating['ratingId'],
'ratingName' => $rating['ratingName'],
'ratingKey' => $rating['ratingKey'],
'ratingKeyName' => $rating['ratingKeyName'],
'schemeTypeId' => $rating['schemeTypeId'],
'extractDate' => $rating['extractDate']
]);
});
Edit -- Additional Info
Correct me if I'm wrong but at the moment I think the collection is only able to save the contents of the "Ratings" object. I've tried to remove the object from the collect line and amend each line as:
'ratingId' => $rating['rating']['ratingId'],
'extractDate' => $rating['meta']['extractDate']
But I get 'Undefined index: rating'
DD of $ratings
array:3 [▼
"ratings" => array:11 [▼
0 => array:6 [▼
"ratingId" => 12
"ratingName" => "5"
"ratingKey" => "fhrs_5_en-gb"
"ratingKeyName" => "5"
"schemeTypeId" => 1
"links" => array:1 [▶]
]
1 => array:6 [▶]
2 => array:6 [▶]
3 => array:6 [▶]
4 => array:6 [▶]
5 => array:6 [▶]
6 => array:6 [▶]
7 => array:6 [▶]
8 => array:6 [▶]
9 => array:6 [▶]
10 => array:6 [▶]
]
"meta" => array:8 [▼
"dataSource" => "API"
"extractDate" => "2020-06-29T22:56:04.250649+01:00"
"itemCount" => 11
"returncode" => "OK"
"totalCount" => 11
"totalPages" => 1
"pageSize" => 11
"pageNumber" => 1
]
"links" => array:1 [▶]
]

You don't have any data structured like this:
'ratingId' => $rating['rating']['ratingId']
There is no key in your that is 'rating'.
You have
'ratingId' => $ratings['ratings'][$idx]['rating_id']
I think what you want is this:
collect($ratings['ratings'])
->each(function($rating, $key) use ($ratings) {
Rating::updateOrCreate([
'ratingId' => $rating['ratingId'],
'ratingName' => $rating['ratingName'],
'ratingKey' => $rating['ratingKey'],
'ratingKeyName' => $rating['ratingKeyName'],
'schemeTypeId' => $rating['schemeTypeId'],
'extractDate' => $ratings['meta']['extractDate']
]);
});
My original comment is based on your question :)

Related

Having issues with getting the candidate with the highest vote and his name using laravel 7

I Am trying to get from the candidate with the highest votes and his name also, all have tried runs false. I just dd() this below, after getting all the presidential candidates.
Illuminate\Database\Eloquent\Collection {#288 ▼
#items: array:4 [▼
0 => App\Candidate {#289 ▼
#connection: "mysql"
#table: "candidates"
#primaryKey: "id"
#keyType: "int"
#attributes: array:9 [▼
"id" => 1
"name" => "Brian"
"seat" => "president"
"regno" => "DIT-C004-0536\2013"
"votes" => 0 // this is the first candidate record, others are below.
"user_id" => 2
"created_at" => "2017-05-12 08:43:58"
"updated_at" => "2017-05-12 08:43:58"
"image" => ""
]
}
1 => App\Candidate {#290 ▼
#attributes: array:9 [▼
"id" => 5
"name" => "Juma"
"seat" => "president"
"regno" => "DIT-C004-0516\2013"
"votes" => 3
"user_id" => 7
"created_at" => "2017-05-12 09:03:03"
"updated_at" => "2017-05-12 14:48:54"
"image" => ""
]
}
2 => App\Candidate {#291 ▼
#attributes: array:9 [▼
"id" => 9
"name" => "Stephen"
"seat" => "president"
"regno" => "0001"
"votes" => 4 //trying to get the highest votes with the name.
"user_id" => 12
"created_at" => "2020-03-17 15:27:47"
"updated_at" => "2020-03-21 19:18:39"
"image" => ""
]
}
3 => App\Candidate {#292 ▼
#attributes: array:9 [▼
"id" => 10
"name" => "Gobby"
"seat" => "president"
"regno" => "DIT-C004-0436\2014"
"votes" => 0
"user_id" => 11
"created_at" => "2020-03-17 15:27:59"
"updated_at" => "2020-03-17 15:27:59"
"image" => ""
]
}
I have been searching for solutions all around but couldn't find one, Thanks in Advance.
This is my controller:
{
public function highestvote(){
$getpres = Candidate::where('seat','president')->get();
dd($getpres);
foreach($getpres as $getpresvote){
for($i = 0; $i < $getpresvote; $i++){
$highv = $getpresvote[$i];
}
}
return view('election.winners')->with('getpresvotes',$getpresvotes);
}
}
I die dump the code before looping, cause when I loop it keeps on giving me 0 or sometimes tells me stuff like array can't be converted int.
Your Controller Code should be like this in this case:
$seat = 'president';
$name= 'gobby';
$data = Candidate::where('seat', $seat)
->where('name', $name)
->orderBy('votes','desc')
->first()
print_r($data);
It will give you the maximum votes data with the seat 'president' and name 'gobby'

Laravel Object of class stdClass could not be converted to string. Still object when using toArray();

I have a table that I want to export via excel. I use the method toArray(); and still I get the result as object. Here is my sample code
$items = \DB::table('users')
->join('finances', 'users.id','=','finances.user_id')
->join('schoolyears', 'users.school_id','=','schoolyears.school_id')
->select('users.name','users.phone','users.section_id', 'users.student_school_id','finances.amount','finances.description','schoolyears.name as syear','finances.date')
->where('finances.date', '=' ,(\DB::raw("(select max(`date`) from finances f where finances.user_id=f.user_id)")))
->where('users.role','=','4' )
->where('users.school_id','=', $sid)
->get()->toArray();
// dd($items);
} else {
return redirect('home')->with('error', 'Invalid access');
}
\Excel::create($this->page_title . 's', function ($excel) use ($items) {
$excel->sheet($this->page_title . 's', function ($sheet) use ($items) {
$sheet->fromArray($items);
});
The result I get when i dd($items)
array:2 [▼
0 => {#558 ▼
+"name": "Annamarie Morar"
+"phone": "(0997) 212-7919"
+"section_id": null
+"student_school_id": "50"
+"amount": "500"
+"description": "New Pays"
+"syear": "SY-2019-2020"
+"date": "2019-11-14"
}
1 => {#561 ▶}
]
What i want is like this so that i can export it as an excel file
array:9 [▼
0 => array:10 [▼
"FirstName" => "Madelynn"
"LastName" => "Stokes"
"Gender" => "female"
"Birthday" => "2013-10-09"
"Address" => "78A/40 Goodwin Meadow, Poblacion, Iloilo City 1333 Nueva Ecija"
"PhoneNo" => "+63 (971) 659-8143"
"Parent" => "Deondre Stokes"
"SchoolID" => "521"
"RFID" => "173"
"Section" => null
]
1 => array:10 [▶]
2 => array:10 [▶]
3 => array:10 [▶]
4 => array:10 [▶]
5 => array:10 [▶]
6 => array:10 [▶]
7 => array:10 [▶]
8 => array:10 [▶]
]
You could convert each object to an array by transforming the Collection then turning the Collection into an array if you had to:
$items = DB::table(...)->.....->get()->transform(function ($item) {
return (array) $item;
})->toArray();
Laravel 6.x Docs - Collections - Methods - transform

How to store the quantity in the $regTypes array?

I want to have an array with the info about each registration type associated with a registration. For example if for the registration with id "1" the user selected two registration types of type "General" and one of the type "Plus" the $regTypes array should have this content with 2 item:
'registrationTypes' => [
[
'name' => 'general',
'price' => '5',
'quantity' => '2'
],
[
'name' => 'plus',
'price' => '10',
'quantity' => '1'
]
]
The registration_types table have the name and the price. So I have this query to get some info about a registration in a conference.
$registration = Registration
::with('conference', 'Conference.registrationTypes')->where('id', 1)->first();
And then I have this code to create the array with the necessary info:
$regTypes = [];
foreach($registration->conference->registrationTypes as $key=>$registrationType){
$regTypes [
'regType' => [
'name' => $registration->conference->registrationTypes[$key]['name'],
'price' => $registration->conference->registrationTypes[$key]['price']
]
];
}
My doubt is how to also store the quantity in the $regTypes array. Because the quantity is not stored in the database.
Maybe to get the quantity is necessary to do antoher query. With this code below:
$registrationTypeDetails = Registration::with('participants:id,registration_type_id,registration_id')->find($regID);
//dd($registrationTypeDetails);
$type_counts = [];
foreach ($registrationTypeDetails->participants as $p) {
$name = $p->registration_type->name;
if (!isset($type_counts[$name])) {
$type_counts[$name] = 0;
}
$type_counts[$name]++;
}
dump($type_counts);
The $type_counts shows the quantity of each registration type associated with the registration:
array:2 [▼
"general" => 2
"plus" => 1
]
Do you know how to use this $type_counts content to store the quantity properly in the $regTypes array?
To directly answer your question (IE not change the controller code, just "use this $type_counts content to store the quantity properly in the $regTypes array"), I'm hopeful this should work for you:
$regTypes = [];
foreach($registration->conference->registrationTypes as $key=>$registrationType){
$typeName = $registration->conference->registrationTypes[$key]['name'];
$regTypes [
'regType' => [
'name' => $typeName,
'price' => $registration->conference->registrationTypes[$key]['price'],
'quantity' => $type_counts[$typeName]
]
];
}
Basically just pulling the count from the $type_counts array based on the name of the Registration Type being the key that you added in the foreach ($registrationTypeDetails->participants as $p) loop.
Depending upon what you are after, it might be easier just to loop on the registration types, rather than go through $registration->conference->registrationTypes. This way you don't have duplicates. But that assumes you don't want duplicates :)
I hope this code useful for you .If you need the number of participants in any type, you can use the following code:
$registration = Registration::with('conference','Conference.registrationTypes','Conference.registrationTypes.participants')
->where('id',$regID)->first();
$result=$registration->conference->registrationTypes->each(function ($item, $key) use($registration) {
$item['try_count']=$item->participants->count();
});
dd($result->toArray());
I added the try_count variable to the final result:
array:2 [▼
0 => array:6 [▼
"id" => 1
"name" => "general"
"price" => 0
"conference_id" => 1
"try_count" => 8
"participants" => array:8 [▼
0 => array:5 [▶]
1 => array:5 [▶]
2 => array:5 [▶]
3 => array:5 [▶]
4 => array:5 [▶]
5 => array:5 [▶]
6 => array:5 [▶]
7 => array:5 [▶]
]
]
1 => array:6 [▼
"id" => 2
"name" => "plus"
"price" => 1
"conference_id" => 1
"try_count" => 5
"participants" => array:5 [▼
0 => array:5 [▶]
1 => array:5 [▶]
2 => array:5 [▶]
3 => array:5 [▶]
4 => array:5 [▶]
]
]
]

array_search in php doesn't find my string

So I'm trying to make a function that searches a string in a whole array. But it give me anything... So my array looks like this :
array:1 [▼
"list" => array:2 [▼
"pagination" => array:5 [▶]
"entries" => array:11 [▼
0 => array:1 [▼
"entry" => array:8 [▼
"firstName" => "Doctor"
"lastName" => "Who"
"emailNotificationsEnabled" => true
"telephone" => "0123456789"
"company" => []
"id" => "DW"
"enabled" => true
"email" => "doctorwho#time.lord"
]
]
1 => array:1 [▶]
2 => array:1 [▶]
3 => array:1 [▶]
4 => array:1 [▶]
5 => array:1 [▶]
6 => array:1 [▶]
7 => array:1 [▶]
8 => array:1 [▶]
9 => array:1 [▶]
10 => array:1 [▶]
]
]
]
So for exemple at first I did $key = array_search("doctor", $users); but this gives me nothing. So I thought it was because I have a multidimensional array. So I reduced it to just one array (and I would search in the rest of the original array with a for loop), so now I'm working with this array that I got with $users['list']['entries'][0]
array:1 [▼
"entry" => array:8 [▼
"firstName" => "Doctor"
"lastName" => "Who"
"emailNotificationsEnabled" => true
"telephone" => "0123456789"
"company" => []
"id" => "DW"
"enabled" => true
"email" => "doctorwho#time.lord"
]
]
But $key = array_search("doctor", $users['list']['entries'][0]); still doesn't give me anything (but false).
Does anyone know where is my mistake ? Because I couldn't find a solution of my problem yet and it's been a pretty long time I'm on it... I'm still a beginner in php so maybe I've missed something obvious and i'm sorry if I did.
Thank you in advance !
you are searching for doctor,but value stored in your array is as Doctor. So either search for Doctor as
$key=array_search('Doctor', $users['list']['entries'][0]));
or for case in-sensetive search use
$key=array_search(strtolower('Doctor'), array_map('strtolower', $users['list']['entries'][0]));
Note: as your array is multidimensional, so use loop to search your value

How to store values in array then use it as json

I'm trying to store values in an array structured like this:
{"parent":
{"class":"Green","user_name":"Nitish","user_loc":"Delhi","user_id":1,"user_blockclass":null,
"child":[
{"class":"Green","user_name":null,"user_loc":null,"user_id":1,"user_blockclass":"fst",
"child":[
{"class":"Green","user_name":"pandey","user_loc":"sdgfsjd","user_id":6,"user_blockclass":"fst"},
{"class":"Green","user_name":"chaku","user_loc":"sdgjs","user_id":7,"user_blockclass":"snd"},
{"class":"Green","user_name":"iks","user_loc":"sjkdfhkjs","user_id":8,"user_blockclass":"trd"},
{"class":"Green","user_name":"yash","user_loc":"hfksjdhfk","user_id":9,"user_blockclass":"frt"},
{"class":"Green","user_name":"joshi","user_loc":"dsfh","user_id":10,"user_blockclass":"fth"}
]},
{"class":"Green","user_name":null,"user_loc":null,"user_id":1,"user_blockclass":"snd",
"child":[
{"class":"Green","user_name":"pandey","user_loc":"sdgfsjd","user_id":6,"user_blockclass":"fst"},
{"class":"Green","user_name":"chaku","user_loc":"sdgjs","user_id":7,"user_blockclass":"snd"},
{"class":"Green","user_name":"iks","user_loc":"sjkdfhkjs","user_id":8,"user_blockclass":"trd"},
{"class":"Green","user_name":"yash","user_loc":"hfksjdhfk","user_id":9,"user_blockclass":"frt"},
{"class":"Green","user_name":"joshi","user_loc":"dsfh","user_id":10,"user_blockclass":"fth"}
]},
]
}
}
I'm trying to place this in two different array and the joining them, but it is not getting the approrpiate result, I've used a variable which iterates to store the different values, if I don't use iteration it overlaps the values and only shows the last stored values. Following is my code:
$blockclass = ['fst', 'snd', 'trd', 'frt', 'fth'];
$i = 0;
$children = $user->relations()->wherePlanId($selectplan)->get();
foreach($children as $ch)
{
$j = 0;
$subuserinfo = [];
$parent_id = $ch->pivot->child;
$subuser = User::find($ch->pivot->child);
$subuserinfo['class'] = "Green";
$subuserinfo['user_name'] = $ch->name;
$subuserinfo['user_loc'] = $ch->city;
$subuserinfo['user_id'] = $ch->id;
$subuserinfo['user_blockclass'] = $blockclass[$i];
if($subuser){
$subchildren = $subuser->relations()->wherePlanId($selectplan)->get();
foreach($subchildren as $subchild)
{
$subsubuser = User::find($subchild->pivot->child);
$subsubuserinfo['class'] = "Green";
$subsubuserinfo['user_name'] = $subsubuser->name;
$subsubuserinfo['user_loc'] = $subsubuser->city;
$subsubuserinfo['user_id'] = $subsubuser->id;
$subsubuserinfo['user_blockclass'] = $blockclass[$j];
$subuserinfo['child'][$i][$j++] = $subsubuserinfo;
}
}
else
{
$subuserinfo['child'][$i][$j++] = NULL;
}
$userinfo['child'][$i++] = $subuserinfo;
}
$tree = $userinfo;
dd($tree);
Currently the data structure which I'm getting is in following format:
array:6 [▼
"class" => "Green"
"user_name" => "Nitish"
"user_loc" => "Delhi"
"user_id" => 1
"user_blockclass" => null
"child" => array:4 [▼
0 => array:6 [▼
"class" => "Green"
"user_name" => null
"user_loc" => null
"user_id" => 1
"user_blockclass" => "fst"
"child" => array:1 [▼
0 => array:5 [▼
0 => array:5 [▼
"class" => "Green"
"user_name" => "pandey"
"user_loc" => "sdgfsjd"
"user_id" => 6
"user_blockclass" => "fst"
]
1 => array:5 [▼
"class" => "Green"
"user_name" => "chaku"
"user_loc" => "sdgjs"
"user_id" => 7
"user_blockclass" => "snd"
]
2 => array:5 [▼
"class" => "Green"
"user_name" => "iks"
"user_loc" => "sjkdfhkjs"
"user_id" => 8
"user_blockclass" => "trd"
]
]
]
]
1 => array:6 [▶]
2 => array:6 [▶]
3 => array:6 [▶]
I'm not able to fetch the data in this format, also after this I want to place the data to be used as json format. Help me out.
I thinkyou should replace all $subuserinfo['child'][$i][$j++] = $subsubuserinfo; with $subuserinfo['child'][$j++] = $subsubuserinfo;
I see you are using Laravel? If you use return response()->json($tree); it will print JSON.
If you also want the parent in front of the JSON you can use this:
return response()->json(['parent' => $tree]);

Categories