How to: foreach without affecting every row? - php

Is there a way to do a foreach on for example your products and sort this by their category_id and show the category name above the products. (I'm using laravel 4 as framework)
Example what the output should look like:
Chairs
wooden chair number 1
pretty chair number 1
pretty chair number 2
Doors
tall door number 1
white door number 1
Key question: How can i make a foreach without having the categoryname above each row ?
Hopefully i made my question/problem clear and can someone help me out!
This is what i got so far:
Though, when i do my foreach in the blade i will get the error: " Undefined index "
The foreach i used in my controller:
foreach($results as $result) {
$category[$result->category_id][] = $result;
}
My foreach in the blade:
#foreach ($category as $key => $product)
<tr>
<td>{{ $product[$key]['created_at'] }}</td>
<td>{{ $product[$key]['order_id'] }}</td>
<td>{{ $product[$key]['name'] }}</td>
</tr>
#endforeach

you are attempting to use category_id to fetch $product from $products, which is array with 0-X indexes. for sake of simplicity i will ignore html formatting and syntax since i never used framework mentioned...
#foreach ($category as $key => $products)
echo 'Category #', $key
#foreach ($products as $product)
<tr>
<td>{{ $product['created_at'] }}</td>
<td>{{ $product['order_id'] }}</td>
<td>{{ $product['name'] }}</td>
</tr>
#endforeach
#endforeach

not completely sure i understand the question. but if im trying to organize an array.. i might use a conditional statement inside the foreach loop. I'm not sure your question is very clear.. see if this helps at all
foreach($results as $result) {
// just an example.. i narrow down what I push into my category array
if($result->type == 'whatever'){
$category[$result->category_id][] = $result;
}
}

Related

How to loop multiple nested loop in one table in laravel?

I have referral commission details and different levels of referral users I need to show that in the table with there are levels. Here I did coded but I'm not satisfied with the logic please let me know the logic is correct or wrong you see the below images for reference.
What i'm looking for
Here my table
What i did so far
Controller
public function inDirectCommission()
{
$user = User::where('id', 1)->first();
$user_id = $user->id;
$direct_commissions = Referral::where('parent_id', $user_id)->get();
foreach ($direct_commissions as $row) {
$second_level = Referral::where('parent_id', $row->user_id)->get();
foreach ($second_level as $row) {
$third_level = Referral::where('parent_id', $row->user_id)->get();
foreach ($third_level as $row) {
$forth_level = Referral::where('parent_id', $row->user_id)->get();
foreach ($forth_level as $row) {
$fifth_level = Referral::where('parent_id', $row->user_id)->get();
foreach ($fifth_level as $row) {
}
}
}
}
}
return view('site.user.dashboard.commission.in_direct_commission', compact('second_level', 'third_level', 'forth_level', 'fifth_level'));
}
Blade
<table id="example1"
class="table table-bordered table-striped dataTable dtr-inline direct-table"
role="grid" aria-describedby="example1_info">
<thead>
<tr>
<th>Date</th>
<th>Referal</th>
<th>Level</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
#foreach ($second_level as $row)
<tr>
<td>{{ $row->created_at }}</td>
<td>{{ $row->user->name }}</td>
<td>2<sup>nd</sup> Level</td>
<td>4000</td>
</tr>
#endforeach
#foreach ($third_level as $row)
<tr>
<td>{{ $row->created_at }}</td>
<td>{{ $row->user->name }}</td>
<td>3rd<sup>rd</sup> Level</td>
<td>3000</td>
</tr>
#endforeach
#foreach ($forth_level as $row)
<tr>
<td>{{ $row->created_at }}</td>
<td>{{ $row->user->name }}</td>
<td>4<sup>th</sup> Level</td>
<td>2000</td>
</tr>
#endforeach
#foreach ($fifth_level as $row)
<tr>
<td>{{ $row->created_at }}</td>
<td>{{ $row->user->name }}</td>
<td>5<sup>th</sup> Level</td>
<td>1000</td>
</tr>
#endforeach
</tbody>
</table>
dd of second level user
IMPORTANT: as per my comments under the question, this answer is to emphasize the idea only. Code samples and concepts might need to be adjusted to match your needs.
Assume there are users A,B,C,D,E and F and each has ids 1,2,3,4,5 and 6 respectively.
Also let's assume 'A' was a directly registered user. And:
A refers B to the website
B refers C to the website
C refers D to the website
D refers E to the website, and
E refers F to the website
With each user record, you can store their referral chain (ref_chain) in the database. At the time of user registration you can do this.
$a->ref_chain = null; // because he hasn't been referred by anyone
$b->ref_chain = '1'; // B (id = 2) is a direct referral of A (id = 1)
$c->ref_chain = '2-1'; // C (id = 3) is a direct referral of B (id = 2)
$d->ref_chain = '3-2-1'; // D (id = 4) is a direct referral of C (id = 3)
// similarly
$e->ref_chain = '4-3-2-1';
$f->ref_chain = '5-4-3-2-1';
Here, what you do is, at the time of registration you get the referring user's ref_chain and attach referring user's id to to the beginning of the string with a hyphen. For an example if we consider the time of C's registration:
$referringUser = $b;
$c->ref_chain = $b->id.'-'.$b->ref_chain;
Now consider the scenario where you want to get the referrals of C.
What you have to do is search in the ref_chain column in the database using the SQL like keyword;
$referralsOfC = User::where('ref_chain','like',$c->id.'-%')
->orWhere('ref_chain','like','%-'.$c->id.'-%')
->orWhere('ref_chain','like','%-'.$c->id)
->orWhere('ref_chain',"$c->id")
->get();
After that, you can loop through the collection and display the result as you please. Depending on the position of C's id in the ref_chain attribute you can recognize which level the referral is in.
This way you can drastically reduce the number of database queries and traversal.
Hope you can understand.

Laravel Blade - orderBy

I have this foreach loop in my blade template.
#foreach ($employee->projects->groupBy('stage') as $stage => $project)
<tbody>
<td>{{ $stage }}</td>
<td class="text-center">{{ count($project) }}</td>
</tbody>
#endforeach
Where it finds all the projects that the employee is involved in and groups them by what stage they are in (Waiting, In Progress, Launched). And then it lists the stages and the count of how many are in each stage. This works perfectly but they are not in the right order. I would like them in Waiting, In Progress, Launched. Currently it's in Launched, Waiting, In Progress.
How can I order them in my custom order?
SQL should be
SELECT ... FROM projects GROUP BY stage
ORDER BY stage = 'Waiting' DESC, stage = 'In Progress', ...
probably you need use similar to this
->order_by(DB::expr("stage = 'Waiting' DESC"))->order_by(...)
Ok figured this out. Here's what I did...
$projects = $employee->projects()
->groupBy('stage')
->select('stage', DB::raw('count(*) as total'))
->orderByRaw('case
when stage = "Waiting" then 1
when stage = "In Progress" then 2
when stage = "Launched" then 3
end')
->get();
Then in my blade template, I did...
#foreach ($projects as $project)
<tbody>
<td>{{ $project->stage }}</td>
<td class="text-center">{{ $project->total }}</td>
</tbody>
#endforeach
Hope this helps someone else.

Enumerating elements of a table

I have a table and I want to enumerate each element.
Something like this
#foreach($elements as $element)
<tr>
<td>{{ (isset($a))?$a++:($a = 1) }}</td>
<td>...
</tr>
#endforeach
I expect the table to begin with 1 and then count on, however, the first two columns are always 1. I have already solved this problem by giving the template an $a = 0; on the controller but I want to know why my first solution doesn't work and if there is a workaround
Laravel Blade has a very handy variable for loops, called the $loop variable. This lets you gather information about the current element of the list, including the index and iteration count.
So you can do just this:
#foreach($elements as $element)
<tr>
<td>{{ $loop->iteration }}</td>
<td>...
</tr>
#endforeach

Laravel Eloquent splitting query into array

Bit of a bad title, not quite sure how to research/describe what I'm trying to do.
I have a table called specifications with the fields
id, device_id, name, detail
Two rows for two different devices would for example be
1, 1, weight, 300kg
2, 2, weight, 250kg
Now the way I need to display it is in a single table compare both devices, essentially like this:
#foreach($specifications as $specification)
<tr>
<td>{{ $specification->name }}</td>
<td>{{ $specification->detailOne }}</td>
<td>{{ $specification->detailTwo }}</td>
</tr>
#endforeach
I'm having issues getting the right query or split the query in order to be able to go through the array like above. Anyone mind putting me on the right mindset? Do I query both specs and somehow resort it into an array I can use as above, or is there something else I should be looking at?
This should work for you
#foreach($specifications->groupBy('name') as $name => $specificationGrouped)
<tr>
<td>{{ $name }}</td>
#foreach($specificationGrouped as $specification)
<td>{{ $specification['detail'] }} ({{ $specification['device_id'] }})</td>
#endforeach
</tr>
#endforeach

Accessing Parent Array Names

I have got my App returning this array: http://pastebin.com/3VKcjLMT
I'm trying to list the data on my laravel view as:
FAB0003 - Accessory Stand Short Section
-- MAC0010
-- CUT0010
FAB0004 - Accessory Stand Long Section
-- MAC0011
-- RAW0010
but I can't for the life of me figure out how to access the pieces of information beginning with FAB! My current view code is this:
#foreach ($product->fabrications as $items)
#foreach ($items as $item)
<tr>
<td></td>
<td>{{ $item->part_number }}</td>
</tr>
#endforeach
#endforeach
I would be so grateful if you could help out a PHP noob who has wasted hours on this :(
Try with -
#foreach ($product->fabrications as $key => $items)
$key will be the parent key.
Note : It should be a array key.

Categories