Convert collection to key value collection - php

I have the following collection:
$configuration = DB::table('configuration')->get();
Illuminate\Support\Collection {#562 ▼
#items: array:7 [▼
0 => {#1447 ▼
+"configuration_name": "assign_device_email_addresses"
+"configuration_value": "mobiles#example.com|accountspayable#example.com"
}
1 => {#1357 ▼
+"configuration_name": "helpdesk_platform_url"
+"configuration_value": "https://clouddesk.com/app/itdesk/ui/requests/{helpdeskurl}/details"
}
2 => {#1446 ▼
+"configuration_name": "mail_encryption"
+"configuration_value": "tls"
}
3 => {#563 ▼
+"configuration_name": "mail_host"
+"configuration_value": "exampleserver.example.com"
}
4 => {#1292 ▼
+"configuration_name": "mail_password"
+"configuration_value": "encrypted_password"
}
5 => {#1291 ▼
+"configuration_name": "mail_port"
+"configuration_value": "465"
}
6 => {#885 ▼
+"configuration_name": "mail_username"
+"configuration_value": "mobiles"
}
]
}
With this structure I can only access each item via the following statements:
$configuration[0]->configuration_name
$configuration[0]->configuration_value
$configuration[1]->configuration_name
$configuration[1]->configuration_value
etc.
I want to be able to access it via:
$configuration->assign_device_email returning "mobiles#example.com|accountspayable#example.com".
$configuration->mail_host returning "exampleserver.example.com".
etc.
How can I can convert this collection so that I can access each property value via it's configuration_name?
I have tried the below which got me closer, but I still can't access it via statements like: $configuration->mail_port etc.
$configuration2 = DB::table('configuration')->get()
->mapWithKeys(function($configuration2){
return [$configuration2->configuration_name => $configuration2->configuration_value];
});
I think this fails as the above statement still returns an array:
Illuminate\Support\Collection {#1500 ▼
#items: array:7 [▼
"assign_device_email_addresses" => "mobiles#example.com|accountspayable#example.com"
"helpdesk_platform_url" => "https://clouddesk.com/app/itdesk/ui/requests/{helpdeskurl}/details"
"mail_encryption" => "tls"
"mail_host" => "exampleserver.example.com"
"mail_password" => "encrypted_password"
"mail_port" => "465"
"mail_username" => "mobiles"
]
}
Anyone have any ideas? I feel like I am getting closer with it, but collections confuse me a bit.
I think I am essentially after something like this:
Illuminate\Support\Collection {#1507 ▼
+"assign_device_email_addresses" : "mobiles#example.com"
+"helpdesk_platform_url" : "https://cloudesk.com/app/itdesk/ui/requests/{helpdeskurl}/details"
+"mail_encryption" : "tls"
+"mail_host" : "emailhost#example.com"
+"mail_password" : "encrypted_password"
+"mail_port" : "465"
+"mail_username" : "mobiles"
}

You can Arr helper to map in key value:
$configuration = DB::table('configuration')->get();
$configuration = Arr::pluck($configuration, 'configuration_value','configuration_name');
also, add below line to import class:
use Illuminate\Support\Arr;

Related

How to display pagination links in a blade on Laravel 8?

I need to add pagination, but it seems complicated in my case, because I get data from database with paginate, but then I modify this data and when I call links() method on the blade, I get the following exception
Method Illuminate\Support\Collection::links does not exist.
My code in the Controller method:
$transactionsByLastMonth = Transaction::where('created_at', '>=', Carbon::now()->subDays(30)->toDateTimeString())
->where('user_id', Auth::user()->id)
->with(['user', 'propertyFrom', 'propertyTo', 'paddockFrom', 'paddockTo', 'cattleTypeFrom', 'cattleTypeTo'])
->paginate(10);
$transactionsByDays = collect(TransactionResource::collection($transactionsByLastMonth))
->sortByDesc('created_at')
->groupBy(function($date) {
return Carbon::parse($date['created_at'])->format('d');
});
return view('user.reports.index', compact('transactionsByDays'));
Yes, a pagination limits my data to 10 rows, but due to I'm grouping data by days, my collection modifies itself and I can't use $transactionsByDays->links() method to show pagination.
If see dd($transactionsByDays) , it looks like:
Illuminate\Support\Collection {#1381 ▼
#items: array:3 [▼
"01" => Illuminate\Support\Collection {#1019 ▼
#items: array:7 [▼
0 => array:16 [▶]
1 => array:16 [▶]
2 => array:16 [▶]
3 => array:16 [▶]
4 => array:16 [▶]
5 => array:16 [▶]
6 => array:16 [▶]
]
}
31 => Illuminate\Support\Collection {#1386 ▼
#items: array:2 [▼
0 => array:16 [▶]
1 => array:16 [▶]
]
}
30 => Illuminate\Support\Collection {#1384 ▼
#items: array:1 [▼
0 => array:16 [▶]
]
}
]
}
Therefore I need to paginate all arrays together which inside "01", 31, 30...
How can I do it?
Maybe rewrite code above in the controller somehow?
The main aim is that I need to group data to every day according to my json-resource class.
Any ideas?
I've found a solution gyus. I had to pass also a variable transactionsByLastMonth and use links() method over this.
In the meantime I use foreach on the my blade file over transactionsByDays variable. It's correctly works together cause it uses the same data from database, just in the first case its not filtered and not grouped and in the second one it is.
return view('user.reports.index', compact('transactionsByLastMonth', 'transactionsByDays'));

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 - push array to collection

I have this code where I try to grab all auth user categories:
$cats = Auth::user()->cats()->lists('title','id');
and I want to add new data to $cats so I write:
$cats->push(['5','BMW']);
but I got:
Collection {#459 ▼
#items: array:2 [▼
9 => "asd"
10 => array:2 [▼
0 => "5"
1 => "BMW"
]
]
}
How I to change my code to get this result:
Collection {#459 ▼
#items: array:2 [▼
9 => "asd"
5 => "BMW"
]
}
So how I can add the array to this collection?
p.s. I need this format because I use select2 jquery plugin
You can use the collection like an array:
$cats[5] = 'BMW';

Yaml nested arrays in 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'

Categories