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
Cart
class 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
driver
refers to the variableSESSION_DRIVER
inside the .env file - The
lifetime
refers to the variableSESSION_LIFETIME
inside the .env file - The
expire_on_close
is 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_DRIVER
fromdatabase
tofile
SESSION_LIFETIME
is set to120
minutes, or 2 hours
- update the
php
SESSION_DRIVER=file # replace database with file
SESSION_LIFETIME=120
SESSION_DRIVER=file # replace database with file
SESSION_LIFETIME=120
1
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
Cart
class 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
Cart
class 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
records
contains 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
totalQty
contains the number of items in our cart - The key
totalPrice
contains 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
$cart
is an associative array with the three keys:records
,totalQty
andtotalPrice
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 variablecart
exists- If the session variable
cart
exists, copy the session variable to the$cart
variable - If not, use the default value of the
$cart
variable
- If the session variable
- Line 32: call the
init()
method to make sure the$cart
variable is initialized
REMARK: this is the only place where we call theinit()
method, so we can be sure the$cart
variable 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_id
and theprice
andqty
to the$cart
variable - 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/records
folder, add thecover
to the$cart
variable, 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 = 0
and$totalPrice = 0
- Line 43 - 46: loop through the
records
array and add theqty
andprice
to the$totalQty
and$totalPrice
variables - Line 47 and 48: update the
$cart
variable with the new$totalQty
and$totalPrice
variables - Line 49: store the
$cart
variable 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.php
file 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
aliases
array 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