Yaml nested arrays in php - php

Trying to convert nested php array
$ar:3 [▼
"sotr" => array:5 [▼
0 => {#190 ▼
+"sId": "1"
+"sFIO": "Родион Романович Мишин"
+"sSalary": "7477.59"
}
1 => {#192 ▶}
2 => {#193 ▶}
3 => {#194 ▶}
4 => {#195 ▶}
]
"ticket" => array:5 [▶]
"task" => array:4 [▶]
]
into YAML string by using Symfony\Component\Yaml\Yaml in Laravel. So, when I'm using
$data = Yaml::dump($ar);
I see empty array like this:
sotr:\n
- null\n
- null\n
- null\n
- null\n
- null\n
How I can fix this?

solve it! Probably this solution not so smart, but it works.
Convert array into JSON string:
$data = json_decode(json_encode($ar), true);
Then using Symfony\Component\Yaml\Dumper class
$dumper = new Dumper();
$yaml = $dumper->dump($data);
And here the YAML formatted string:
sotr:
-
sId: '1'
sFIO: 'Родион Романович Мишин'
sSalary: '7477.59'

Related

Laravel API response conversion into collection

I'm playing with API responses for a while and I can't convert them into Laravel collection format.
My response after $users = json_decode($users, true); is something like that:
array:2 [▼
"#odata.context" => "https://URL/Something.svc/$metadata#Something"
"value" => array:190 [▼
0 => array:18 [▶]
1 => array:18 [▶]
2 => array:18 [▶]
3 => array:18 [▶]
4 => array:18 [▶]
5 => array:18 [▶]
6 => array:18 [▶]
7 => array:18 [▶]
I need to convert it into Laravel collection so instead of original json_decode I have to use:
$users = collect(array_values(json_decode($users, true))[1]);
It works, but I felt that this is not the right way to do that? Also, I have to use [1] at the end. What's if the array is empty and [1] does not exist? Do I need to validate if it exists or if there is a proper way to deal with this conversion?
After decoding the data you will have an associative array where you can access the data inside the 'value' array directly using $users['value'], so there is not need to use the array_values function.
$users = json_decode($users, true);
if (isset($users['value'])) {
$usersCollection = collect($users['value']);
}
I guess something like this should work fine.

How to update a nested value within a nested Laravel collection

I have a deployments Laravel Collection like this:
Illuminate\Support\Collection {#415 ▼
#items: array:5 [▼
0 => array:7 [▼
"id" => 31
"status" => "active"
"name" => "Deployment 1"
"spots" => array:4 [▼
0 => array:2 [▼
"id" => 33
"status" => "active" <-- Want to change this
]
1 => array:2 [▶]
2 => array:2 [▶]
3 => array:2 [▶]
]
"data" => array:3 [▶]
]
1 => array:7 [▶]
2 => array:7 [▶]
3 => array:7 [▶]
4 => array:7 [▶]
]
}
I want to update the nested status value to inactive. I have used the Laravel map function, but it only seems to work on collections that have one nesting level. So this...
$this->deployments->map(function ($deployment) {
$deployment['spots'][0]['status'] = 'inactive';
});
dd($this->deployments);
...leaves $this->deployments untouched.
Also tried using nested map functions obtaining a Call to a member function map() on array exception on second level as second and next nesting levels are considered arrays...
Any thoughts?
Thanks in advance.
With the map method, you are almost there. You will have to return the change made in $deployment and do an ->all() at the end to update the collection with the modified values.
For updating a single spot:
$deployments = $deployments->map(function($deployment){
$deployment['spots'][0]['status'] = 'inactive';
return $deployment;
})->all();
For updating all spots:
$deployments = $deployments->map(function($deployment){
foreach($deployment['spots'] as &$spot){
$spot['status'] = 'inactive';
}
return $deployment;
})->all();
For anyone researching this, a more elegant solution might be:
For updating a single spot:
$data = $deployments->all();
$deployments = data_set($data, 'spots.0.status', 'inactive');
For updating all spots:
$data = $deployments->all();
$deployments = data_set($data, 'spots.*.status', 'inactive');

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

Laravel - How to collect multiple array to single one

I've created a collection like this :
Collection {#651 ▼
#items: array:3 [▼
0 => array:3 [▼
"orderId" => "402457"
"orderCreated" => DateTime {#656 ▶}
"foods" => array:2 [▶]
]
1 => array:3 [▼
"orderId" => "402457"
"orderCreated" => DateTime {#661 ▶}
"foods" => array:2 [▶]
]
2 => array:3 [▼
"orderId" => "402457"
"orderCreated" => DateTime {#665 ▶}
"foods" => array:2 [▶]
]
]
}
I demand to achieve collection like this (with Laravel collection):
Collection {#651 ▼
#items: array:3 [▼
0 => array:3 [▼
"orderId" => "402457"
"orderCreated" => DateTime {#656 ▶}
"foods" => array:6 [▶]
]
]
}
Because orderId and orderCreated are all the same in arrays. I need to make single array that collect orderId and orderCreated with all foods.
Any suggestion?
You can take the data from the first one and just combine all of the food items. For instance like this:
$new = collect([
'orderId' => $old->first()->orderId,
'orderCreated' => $old->first()->orderCreated,
'foods' => $old->pluck('foods')->flatten(1),
]);
The exact implementation will depend on how you built your initial collection.

Cannot use object of type ... as array

I am using an API from themoviedb.org, which is returning an array:
array:20 [▼
0 => TVShow {#186 ▼
-_data: array:13 [▼
"original_name" => "Star Trek: Discovery"
"id" => 67198
"name" => "Star Trek: Discovery"
"vote_count" => 48
"vote_average" => 6.3
"poster_path" => "/ihvG9dCEnVU3gmMUftTkRICNdJf.jpg"
"first_air_date" => "2017-09-24"
"popularity" => 75.562899
"genre_ids" => array:1 [▶]
"original_language" => "en"
"backdrop_path" => "/s3kVP6R3LbJvvoPnDQEcJNEH2d0.jpg"
"overview" => "Ten years before Kirk, Spock, and the Enterprise there was Discovery. Star Trek, one of the most iconic and influential global television franchises, returns 5 ▶"
"origin_country" => array:1 [▶]
]
}
1 => TVShow {#187 ▶}
2 => TVShow {#193 ▶}
3 => TVShow {#194 ▶}
4 => TVShow {#195 ▶}
5 => TVShow {#196 ▶}
]
I am trying access it like I normally would an array:
foreach($array as $item {
echo $item["original_name"];
}
But I am getting this error:
"Cannot use object of type TVShow as array"
Could someone please help? Thanks!
I solved my own question with lot's of handholding from #ArtisticPhoenix.
I am using TMDB PHP API wrapper. In order to access the "original_name" value, I needed to do this:
echo $item->getName();
As detailed in the wrapper documentation.

Categories