push data in to a multidimensional array in laravel php - php

I want to create a multidimensional array to save the data according the date and a category as follow. Then i need to display this data in my blade view?what can i do to achieve this.
'2012-05-05' => array(
'suspension' => 52,
'transmission' => '58'
),
'2012-05-05' => array(
'suspension' => 44,
'transmission' => 21
I have done the following in my controller i want a $reportData variable to load the data.
public function loadReports(Request $request)
{
$data = ['2012-05-05','2012-05-06'];
$salesItems = array();
$orderItems = OrderItem::with('spare', 'order')->get();
foreach ($orderItems as $key => $orderItem) {
if ($orderItem->spare->retailer_id == Auth::user()->id) {
array_push($salesItems, $orderItem);
}
}
$categories = App\Categories::all();
foreach ($data as $date) {
foreach ($categories as $category) {
$categoryValue = 0;
foreach ($salesItems as $salesItem) {
if ($date == $salesItem->order->orderDate) {
$categoryValue += $categoryValue + $salesItem->subTotal;
}
}
//error appears as illegal offset type
$reportData[$date][$category]=$categoryValue;
}
}
return View::make('Retailer/reports')->with('categories', $categories)->with('reportData', $reportData);
}

I haven't tested it but looking at your code it seems that you're passing an object as array index key as 2nd level array index:
$reportData[$date][$category] = $categoryValue;
^^^^^^^^^ this is an object
Dump your $category in the foreach loop & check if that is the case: dd($category)
If you're using Eloquent & your Categories Model has a name property, you'll probably want to take each category name as index value:
$reportData[$date][$category->name] = $categoryValue;

The error is occurring due to the fact that you are trying to use an Object as the array's index.
As per the laravel documentation (https://laravel.com/api/4.2/Illuminate/Database/Eloquent/Model.html#method_all) the all method you called here '$categories = App\Category::all();' would have returned an Eloquent Collection.
So when you iterated over the $categories array and referenced $category, you were referencing an object. In PHP an array can only be indexed by either an integer or a string. So you need to change the line of code where the error is to this
$reportData[$date][$category->someVar] = $categoryValue;
Where someVar is the name of a variable on the Eloquent model Category that references its name, such as 'suspension' etc.

While it doesn't answer your question you could use the Eloquent engine to make your life easier:
$orderItems = OrderItem::with('spare', 'order')->get();
foreach ($orderItems as $key => $orderItem) {
if ($orderItem->spare->retailer_id == Auth::user()->id) {
array_push($salesItems, $orderItem);
}
}
can be simplified (and made more efficient) with:
// Store the uid to save the call.
$user_id = Auth::user()->id;
// Apply the condition to the Eloquent query.
$orderItems = OrderItem::with(['spare' => function($query) use ($user_id) {
return $query->where('retailer_id', '=', $user_id);
}, 'order'])->get();
The other answers are correct, but you probably also want to initialise the $reportData array as before you start working with it.

Related

Laravel collection find common items

I am trying to find the common items existing in a collection like the following one:
I would like to end up with a new collection that contains the 928 and the 895 (common items between the key 95 and the key 94).
How can I do it?
I have an array of keys, but I don't understand how to loop over the keys AND the values without create a mess of variables and additional arrays:
foreach ($ids as $id) {
$item_ids->each(function ($item, $key) {
});
}
Well, I ended up with that solution:
$all = $item_ids->all();
$list = [];
foreach ($all as $single) {
$list[] = $single->toArray();
}
$commonItems = collect(call_user_func_array('array_intersect', $list));
So, this is a more laravel approach:
$items = $item_ids['items']->map(function ($item){
$collection[] = $item['items'];
return collect($collection)->duplicates();
});

Laravel Sort Parent Collection by their relationship values

I recently wanted to sort parent elements of a collection by using their relationship values so I came across something like this and It works. Do you think this is a suitable method or am I making this overcomplicated?
Basically, I want to sort the Events by their date
Events have one to many with Slots
Any review on this would be appreciated
Cheers
$events = Event::with(['slots' => function ($q) {
$q->orderBy('date');
$q->orderBy('start_time');
}])->active()->get();
$slotArray = [];
foreach($events as $event){
foreach ($event->slots as $slot) {
$slotArray[$slot->id] = [ 'id' => $event->id, 'start_date' => $slot->date, 'start_time' => $slot->start_time];
}
}
//Sort the Array of IDS
usort($slotArray, array($this,"sortByStartDate"));
//Find the New Set of IDS sorted by the Start Date
$sortedEventIDs = [];
foreach($slotArray as $value) {
array_push($sortedEventIDs, $value['id']);
}
$sortedEvents = $events->sortBy(function($model) use ($sortedEventIDs){
return array_search($model->getKey(), $sortedEventIDs);
});
Sort Function
function sortByStartDate($a, $b){
return $a['start_date'] > $b['start_date'];
}
There is an SQL approach, that would look something like this. Create an subselect, fetch the date you want to use and order by it.
Event::with(['slots' => function ($q) {
$q->orderBy('date');
$q->orderBy('start_time');
}])
->addSelect([
'date' => Comment::selectRaw('MAX(start_date)')
->whereColumn('events.id', 'comments.event_id'),
])->orderBy('date');
Simply use Laravel relation and do the same, not as performance optimized but very straight forward aproeach.
$events = Event::with(['slots' => function ($q) {
$q->orderBy('date');
$q->orderBy('start_time');
}])->active()->get();
$events->sortBy(function ($event) {
return $event->slots()->max('start_date');
});
You can use orderBy() function:
$events = Event::orderBy('start_time', 'DESC')->active()->get();
and for the IDs, you can use sortKeys():
$sorted = $events->sortKeys();
$sorted->all();

Laravel collection for loops and mappings

I am trying to refactor my code, and remove a for loop.
$result = [];
foreach ($data as $language) {
$result[$language->{$key}] = $language->{$column};
}
This became:
$result = $data->map(function($language) use ($key, $column){
return [$language->{$key} => $language->{$column}];
});
But now instead of:
[
"key":"value",
"key":"value"
]
I am getting
[
{
"key":"value"
},
{
"key":"value"
}
]
Why doesn't it map like an array?
Please refer this URL
For Example:
$emailLookup = $employees->reduce(function ($emailLookup, $employee) {
$emailLookup[$employee['email']] = $employee['name'];
return $emailLookup;
}, []);
Gives you result like:
const emailLookup = {
'john#example.com': 'John',
'jane#example.com': 'Jane',
'dave#example.com': 'Dave',
};
In your case do like:
$result = $data->reduce(function($language, $a){
$language[$a['any_you_want']] = $a['any_you_want'];
return $language;
}, []);
Hope this helps you!
You probably needed to mapWithKeys:
$result = $data->mapWithKeys(function($language) use ($key, $column){
return [$language->{$key} => $language->{$column}];
});
The method has been available since Laravel 5.3
According to the docs:
The mapWithKeys method iterates through the collection and passes each value to the given callback. The callback should return an associative array containing a single key / value pair:
For your simple use case, pluck() is the method you're looking for. It will build a new collection using one column of an existing array. You can also pass in a second field that will be used to key the new collection.
So, in your case, the data column you're selecting is $column, and the column to use as the key for the new collection is $key. Your code would be:
$result = $data->pluck($column, $key);
This says "give me a collection of all of the $column data, and key it by the $key data".
If you want the plain array instead of the collection, just call all() on the result:
$result = $data->pluck($column, $key)->all();
If you need to "pluck" more than one column of data, you will need to use the mapWithKeys() method already mentioned.
Here in loop you need to use as key value pair
$result = [];
foreach ($data as $key => $language) {
$result[$key] = $language;
}

PHP Laravel. How to store multiple data in one protected variable array and retrieve it

im confused how to retrieve data from protected variable array, im already stored data on that variable but when i used it, it returns null.
protected $item_quantity = array();
protected $item_id_pallet_lib = array();
foreach ($itemsUsed as $item) {
$this->item_id_pallet_lib = $this->pallet_assembly_library
->where('status', '=', 0)
->where('item_id', '=', $item->item->id) ->pluck('item_id');
$this->item_quantity = $this->theoretical
->where('item_id', '=', $this->item_id_pallet_lib)
->pluck('quantity');
}
-------------this is my first attempt to retrieve data, but it fails and it returns null or nothing happens to my theoretical table---------
foreach ($itemsUsed as $item) {
$this->theoretical
->where('item_id', '=', $this->item_id_pallet_lib)
->update(array('quantity' => $this->item_quantity));
}
You just have to add [] so you can store value at the last of your $this->item_id_pallet_lib and $this->item_quantity like so:
$this->item_id_pallet_lib[]
$this->item_quantity[]
Please leave a comment below if it won't work.

Get all elements of array in query laravel

I am trying to loop in an array but when it comes to the query it gets only the first element, so a little help would be very important.
$data = Offers::whereIn('id_business', $business_id_array)
->where([
'visible' => 'yes',
'delete' => 'no'
])
->where('end_date', '>=', date('Y-m-d h:m:i'))
->orderBy('id', 'desc')
->get();
$data=array($data);
foreach($data as $key => $item) {
$offers = DB::select('the data i need to get WHERE o.`id` = ' . $item[$key]['id']);
}
and this is my problem in here, It gets only the id of the first element
o.`id` = ' . $item[$key]['id']
because you have return the view in side the foreach loop, so it only loop through the first item and return. What you can do with this case is
$data = Offers::whereIn('id_business', $business_id_array)...->get()->toArray();
$offers = array_map(function($item){
$offer = DB::select('the data i need to get WHERE o.`id` = ?', [$item->id]);
return $offer;
},$data);
return view(....,['offers' =>$offers]);
First, you do not need to cast the $data to an array - it will get returned as a collection, which you can iterate through like an array. So you'll be able to use something like this
$offers = Offers::whereIn('id_business', $business_id_array)...->get();
foreach ($offers as $offer) {
$moreData = DB::select('the data i need to get WHERE o.`id` = ?', [$offer->id]);
}
This looks like you are using the id from one table, to get the associated data from another table.
Should there not be a relationship in place, between the two tables?
The answer from #Chris G looks correct, maybe dd($offers) to be certain what is in there.
Mick

Categories