Admin: order history
- On this page, the administrators get an overview of all orders that have already been placed
Preparation
Create controller
- Create a new
OrderController
in the folder app/Http/Controllers/Admin- Run the command
php artisan make:controller Admin/OrderController
- Run the command
- Add an
index()
method to show the complete order history
class OrderController extends Controller
{
// Show the complete order history
public function index ()
{
$orders = [];
$result = compact('orders');
Json::dump($result);
return view('admin.orders.index', $result);
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Basic view
- Make a basic view index.blade.php inside the folder resources/views/admin/orders
- Open the file resources/views/admin/orders/index.blade.php and update the view
@extends('layouts.template')
@section('title', 'Overview orders')
@section('main')
<h1>Overview orders</h1>
@endsection
1
2
3
4
5
6
7
2
3
4
5
6
7
Add a route
- Open routes/web.php and add a new GET route for showing the order history
Route::middleware(['auth', 'admin'])->prefix('admin')->group(function () {
...
Route::get('orders', 'Admin\OrderController@index');
});
1
2
3
4
2
3
4
Overview orders
- The overview is just a static view with a Bootstrap card (containing a table) for every order made so far
REMARK
- To make it easier to understand what's happening behind the scenes, you first have to make a couple of orders with different users
- It's important that the last order (in this example the order with
id = 4
):- comes from the user ITF User 5 (email: itf_user_5@mailinator.com and password: itfuser5)
- contains the records 1 x The Clash - London Calling and 2 x Sonic Youth - EVOL
- The final result is:
- Notice that every card (every order) contains data from three different tables:
- table orderlines (red)
- table orders (green)
- table users (yellow)
Update the controller
- When we look at the result, every Bootstrap card represents one order
- The orders table is the starting point for our selection
- Order the results in descending order so the last order will come first on the page
- Update the query and look at the JSON representation of the query:
http://localhost:3000/admin/orders?json
- The orders table is the starting point for our selection
public function index ()
{
$orders = Order::orderByDesc('id')
->get();
$result = compact('orders');
Json::dump($result);
return view('admin.orders.index', $result);
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- Now we have our green items for the view
- Next, we have to incorporate the parent table (orderlines) and the child table (users)
- This can be done using the
with()
method
- This can be done using the
public function index ()
{
$orders = Order::with(['orderlines', 'user'])
->orderByDesc('id')
->get();
$result = compact('orders');
Json::dump($result);
return view('admin.orders.index', $result);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
REMARK
- The names used inside the (array) parameter of the
with()
method refer to the names of the relation methods we defined in theOrder
model (app/Order.php)!orderlines(){}
implements a one-to-many relation (hasMany()
) with the orderlines tableuser(){}
implements a many-to-one relation (belongsTo()
) with the users table
- At this point we have all the (green, red and orange) information we need for our view
- If you want to exclude columns from the starting table you can use the
select()
method - If you want to exclude some columns from a parent/child table you can do this inside the
with()
method- Type a colon after the relation name and specify which columns of the relationship (separated by a comma) you would like to retrieve
REMARK
When using this feature, you should ALWAYS include the id
column and any relevant
foreign key columns in the list of columns you wish to retrieve
public function index ()
{
$orders = Order::with(['orderlines:id,order_id,artist,title,cover,total_price,quantity', 'user:id,name,email'])
->select(['id','user_id','total_price','created_at'])
->orderByDesc('id')
->get();
$result = compact('orders');
Json::dump($result);
return view('admin.orders.index', $result);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Update the view
- Loop over all orders and place each order in a Bootstrap card
- Place a Bootstrap table inside the body of the card
- Loop over all orderlines and generate separate rows inside the table
- Pay special attention to the date inside the card header!
- When adding the date using
$order->created_at
, you get the full date with the timestamp2020-04-08 09:15:18
, as this is the format in our database - You can format a date field inside Blade with
format()
- The format string argument within this method corresponds to the default PHP date formats, e.g:
$order->created_at->format('M d Y')
returnsApr 08 2020
$order->created_at->format('l: n-j-Y')
returnsWednesday: 4-8-2020
- The format string argument within this method corresponds to the default PHP date formats, e.g:
- When adding the date using
@section('main')
<h1>Overview orders</h1>
@foreach($orders as $order)
<div class="card mb-3 shadow">
<div class="card-header">
<p class="float-right"><i class="fas fa-shopping-cart"></i> {{$order->id}}</p>
<p><i class="fas fa-user"></i> <a href="$order->user->email">{{$order->user->name}}</a>
<span class="text-muted ml-5"><i class="fas fa-clock"></i> {{$order->created_at->format('M d Y')}}</span>
</p>
</div>
<div class="card-body">
<table class="table">
<thead>
<tr>
<th class="width-50">Qty</th>
<th class="width-100">Price</th>
<th class="width-100"></th>
<th>Record</th>
</tr>
</thead>
<tbody>
@foreach($order->orderlines as $orderline)
<tr>
<td>{{$orderline->quantity}}</td>
<td>€ {{$orderline->total_price}}</td>
<td><img class="img img-thumbnail" src="{{$orderline->cover}}" alt="{{$orderline->title}}">
</td>
<td>{{$orderline->artist}} - {{$orderline->title}}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="card-footer">
Total price: <b>€ {{$order->total_price}}</b>
</div>
</div>
@endforeach
@endsection
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39