Appearance
Class: Cart
- A user can add a record to his shopping cart (we call it basket)
- Because every user has his own basket, we store the information in a session variable, called
cart - Because we need different actions (add item to cart, remove item from cart, clear the cart, ...) on different places ( shop detail, basket overview, ...), we'll make a new
Cartclass that handles all these actions - We can call these actions inside a view, inside a controller, inside a Livewire component, ...
What are sessions?
- A session can be defined as a server-side storage of information that is desired to persist throughout the user's interaction with the web site or web application
How are sessions stored?
- There are different ways to store a session
- Most of the time, we use file based sessions but we can also use database based sessions or redis based sessions
- Take a look at the session configuration file config/session.php
- The
driverrefers to the variableSESSION_DRIVERinside the .env file - The
lifetimerefers to the variableSESSION_LIFETIMEinside the .env file - The
expire_on_closeis set tofalse, so the session is still active even if you close the browser
- The
php
'driver' => env('SESSION_DRIVER', 'database'),
/* ... */
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,'driver' => env('SESSION_DRIVER', 'database'),
/* ... */
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,1
2
3
4
5
6
2
3
4
5
6
- Now, take a look at the session variables inside .env:
- update the
SESSION_DRIVERfromdatabasetofile SESSION_LIFETIMEis set to120minutes, or 2 hours
- update the
php
SESSION_DRIVER=file # replace database with file
SESSION_LIFETIME=120SESSION_DRIVER=file # replace database with file
SESSION_LIFETIME=1201
2
2
- When you login to the site, you'll find one or more files with a random name inside the folder storage/framework/sessions
- You can open a file to see what's inside a session
Handle sessions
| Action | Laravel (helper) | Laravel (facade) | Pure PHP |
|---|---|---|---|
| set | session()->put('key', 'val') | Session::put('key', 'val') | $_SESSION['key'] = 'val' |
| get | session()->get('key') | Session::get('key') | $_SESSION['key'] |
| remove key | session()->forget('key') | Session::forget('key') | unset($_SESSION['key']) |
| remove keys | session()->forget(['key1', 'key2']) | Session::->forget(['key1', 'key2']) | |
| remove all keys | session()->flush() | Session::flush() | session_destroy() |
The Cart class
REMARK
- In the next chapters, we'll use the
Cartclass to handle the shopping cart - To give you a better understanding what's going on, we'll explain the code by an example of what we want to achieve
- Before we proceed to the
Cartclass itself, first take a look at the cart logic - Below you find an example of what's stored inside the session variable
cart(in the next chapter, we'll actually get this result)- 2 times the record with
$id = 11( 2 * 16.49 € = 32.98 €) - 1 time the record with
$id = 15( 1 * 9.99 € = 9.99 €) - Total items inside your basket = 3
- Total price for your basket = 32.98 € + 9.99 € = 42.97 €
- 2 times the record with

- The cart is an associative array with three keys:
- the key
recordscontains an associative array where the key represents the record id and the value contains (an associative array with) all the fields we need in the orderlines table - The key
totalQtycontains the number of items in our cart - The key
totalPricecontains the total price of our cart
- the key
REMARKS
- The Card is build upon a static class witch has the advantages of:
- no need to instantiate the class
- static properties and methods can be accessed directly with the scope resolution operator (
_::_)
- See static class example in /php/classes
Create the Cart class
- Create a new folder Helpers inside the app folder
- Create a new PHP Class (not a new file) Cart.php inside the folder app/Helpers
(In PhpStorm: right-click on the folder and choose New -> PHP Class)
Initialize the $card property
- Replace the content of the class with this code:
- Line 10 - 14 the private static property
$cartis an associative array with the three keys:records,totalQtyandtotalPrice
Because this is a private property, we can only access it from inside the class - Line 17 - 20: the public static method
init()checks if the session variablecartexists- If the session variable
cartexists, copy the session variable to the$cartvariable - If not, use the default value of the
$cartvariable
- If the session variable
- Line 32: call the
init()method to make sure the$cartvariable is initialized
REMARK: this is the only place where we call theinit()method, so we can be sure the$cartvariable is initialized
- Line 10 - 14 the private static property
php
<?php
namespace App\Helpers;
use App\Models\Record;
use Storage;
class Cart
{
private static array $cart = [
'records' => [],
'totalQty' => 0,
'totalPrice' => 0
];
// initialize the cart
public static function init(): void
{
self::$cart = session()->get('cart') ?? self::$cart;
}
}
Cart::init();<?php
namespace App\Helpers;
use App\Models\Record;
use Storage;
class Cart
{
private static array $cart = [
'records' => [],
'totalQty' => 0,
'totalPrice' => 0
];
// initialize the cart
public static function init(): void
{
self::$cart = session()->get('cart') ?? self::$cart;
}
}
Cart::init();1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Add/delete record to/from the cart and empty the cart
- Line 18 - 32: check if this record is already in the cart
- If the record is already in the cart, increase the quantity of the record
- If not, add the record to the cart
- Line 21 - 31: get the record from the database and add the
id,artist,title,mb_idand thepriceandqtyto the$cartvariable - The quantity of the record is set to 1 (we just added the record to the cart)
- If there is a cover image inside the
public/storage/recordsfolder, add thecoverto the$cartvariable, else use the default cover image
- Line 21 - 31: get the record from the database and add the
- Line 33: call the
updateTotal()method to update the total price and the total quantity - Line 41 and 42: start with
$totalQty = 0and$totalPrice = 0 - Line 43 - 46: loop through the
recordsarray and add theqtyandpriceto the$totalQtyand$totalPricevariables - Line 47 and 48: update the
$cartvariable with the new$totalQtyand$totalPricevariables - Line 49: store the
$cartvariable in the session variablecart
php
<?php
namespace App\Helpers;
use App\Models\Record;
use Storage;
class Cart
{
private static array $cart = [ ... ];
// initialize the cart
public static function init(): void { ... }
// add record to the cart
public static function add(Record $record): void
{
$singlePrice = $record->price;
if (array_key_exists($record->id, self::$cart['records'])) {
self::$cart['records'][$record->id]['qty']++;
self::$cart['records'][$record->id]['price'] += $singlePrice;
} else {
self::$cart['records'][$record->id] = [
'id' => $record->id,
'artist' => $record->artist,
'title' => $record->title,
'mb_id' => $record->mb_id,
'cover' => Storage::disk('public')->exists('covers/' . $record->mb_id . '.jpg')
? '/storage/covers/' . $record->mb_id . '.jpg'
: '/storage/covers/no-cover.png',
'price' => $singlePrice,
'qty' => 1
];
}
self::updateTotal();
}
// re-calculate the total quantity and price of records in the cart
private static function updateTotal(): void
{
$totalQty = 0;
$totalPrice = 0;
foreach (self::$cart['records'] as $record) {
$totalQty += $record['qty'];
$totalPrice += $record['price'];
}
self::$cart['totalQty'] = $totalQty;
self::$cart['totalPrice'] = $totalPrice;
session()->put('cart', self::$cart); // store the cart in the session
}
}
Cart::init();<?php
namespace App\Helpers;
use App\Models\Record;
use Storage;
class Cart
{
private static array $cart = [ ... ];
// initialize the cart
public static function init(): void { ... }
// add record to the cart
public static function add(Record $record): void
{
$singlePrice = $record->price;
if (array_key_exists($record->id, self::$cart['records'])) {
self::$cart['records'][$record->id]['qty']++;
self::$cart['records'][$record->id]['price'] += $singlePrice;
} else {
self::$cart['records'][$record->id] = [
'id' => $record->id,
'artist' => $record->artist,
'title' => $record->title,
'mb_id' => $record->mb_id,
'cover' => Storage::disk('public')->exists('covers/' . $record->mb_id . '.jpg')
? '/storage/covers/' . $record->mb_id . '.jpg'
: '/storage/covers/no-cover.png',
'price' => $singlePrice,
'qty' => 1
];
}
self::updateTotal();
}
// re-calculate the total quantity and price of records in the cart
private static function updateTotal(): void
{
$totalQty = 0;
$totalPrice = 0;
foreach (self::$cart['records'] as $record) {
$totalQty += $record['qty'];
$totalPrice += $record['price'];
}
self::$cart['totalQty'] = $totalQty;
self::$cart['totalPrice'] = $totalPrice;
session()->put('cart', self::$cart); // store the cart in the session
}
}
Cart::init();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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Get data from the cart
- With the six getters we can retrieve all the information or pieces of the information from the cart
- We provide all possible combinations here, even if we may not need them (yet)
php
<?php
namespace App\Helpers;
use App\Models\Record;
use Storage;
class Cart
{
private static array $cart = [ ... ];
// initialize the cart
public static function init(): void { ... }
// add record to the cart
public static function add(Record $record): void { ... }
// delete record from the cart
public static function delete(Record $record): void { ... }
// empty the cart
public static function empty(): void { ... }
// re-calculate the total quantity and price of records in the cart
private static function updateTotal(): void { ... }
// get the complete cart
public static function getCart(): array
{
return self::$cart;
}
}
Cart::init();<?php
namespace App\Helpers;
use App\Models\Record;
use Storage;
class Cart
{
private static array $cart = [ ... ];
// initialize the cart
public static function init(): void { ... }
// add record to the cart
public static function add(Record $record): void { ... }
// delete record from the cart
public static function delete(Record $record): void { ... }
// empty the cart
public static function empty(): void { ... }
// re-calculate the total quantity and price of records in the cart
private static function updateTotal(): void { ... }
// get the complete cart
public static function getCart(): array
{
return self::$cart;
}
}
Cart::init();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
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

Add an alias for the Cart class
- We can add an alias to the Cart class in the config/app.php file
- This way we can use the Cart class without the
App\Helpers\namespace - We can also use the Cart class in the
routes/web.phpfile without the namespace
- This way we can use the Cart class without the
- Open the config/app.php file:
- Line 4: add the Card class to the
aliasesarray at the bottom of the file
- Line 4: add the Card class to the
php
'aliases' => Facade::defaultAliases()->merge([
// 'ExampleClass' => App\Example\ExampleClass::class,
'Image' => Intervention\Image\Facades\Image::class,
'Cart' => App\Helpers\Cart::class,
])->toArray(),'aliases' => Facade::defaultAliases()->merge([
// 'ExampleClass' => App\Example\ExampleClass::class,
'Image' => Intervention\Image\Facades\Image::class,
'Cart' => App\Helpers\Cart::class,
])->toArray(),1
2
3
4
5
2
3
4
5