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, ...
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
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 €
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
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 (_::_)
Line 10 - 14he private static property $cart is an associative array with the three
keys: records , totalQty and totalPrice
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 variable cart 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
Line 32: call the init() method to make sure the $cart variable is initialized REMARK: this is the only place where we call the init() method, so we can be sure the $cart variable is
initialized
<?phpnamespaceApp\Helpers;useApp\Models\Record;useStorage;classCart{privatestaticarray$cart=['records'=>[],'totalQty'=>0,'totalPrice'=>0];// initialize the cartpublicstaticfunctioninit(): void
{
self::$cart=session()->get('cart')?? self::$cart;}}
Cart::init();
# 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
the price and qty 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 the cover to the $cart variable,
else use the default cover image
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 the qty and price 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 variable cart
<?phpnamespaceApp\Helpers;useApp\Models\Record;useStorage;classCart{privatestaticarray$cart=[...];// initialize the cartpublicstaticfunctioninit(): void {...}// add record to the cartpublicstaticfunctionadd(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 cartprivatestaticfunctionupdateTotal(): 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();
If the record is in the cart, decrease the quantity of the record
If not, do nothing
Line 25 - 27: if the quantity of the record is 0, remove the record from the cart
Line 29: call the updateTotal() method to update the total price and the total quantity
<?phpnamespaceApp\Helpers;useApp\Models\Record;useStorage;classCart{privatestaticarray$cart=[...];// initialize the cartpublicstaticfunctioninit(): void {...}// add record to the cartpublicstaticfunctionadd(Record $record): void {...}// delete record from the cartpublicstaticfunctiondelete(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;if(self::$cart['records'][$record->id]['qty']==0){unset(self::$cart['records'][$record->id]);}}
self::updateTotal();}// re-calculate the total quantity and price of records in the cartprivatestaticfunctionupdateTotal(): void {...}}
Cart::init();
Line 24: remove the cart variable from the session REMARK: there is no need to call the updateTotal() method, because the cart is empty
<?phpnamespaceApp\Helpers;useApp\Models\Record;useStorage;classCart{privatestaticarray$cart=[...];// initialize the cartpublicstaticfunctioninit(): void {...}// add record to the cartpublicstaticfunctionadd(Record $record): void {...}// delete record from the cartpublicstaticfunctiondelete(Record $record): void {...}// empty the cartpublicstaticfunctionempty(): void
{session()->forget('cart');}// re-calculate the total quantity and price of records in the cartprivatestaticfunctionupdateTotal(): void {...}}
Cart::init();
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)
<?phpnamespaceApp\Helpers;useApp\Models\Record;useStorage;classCart{privatestaticarray$cart=[...];// initialize the cartpublicstaticfunctioninit(): void {...}// add record to the cartpublicstaticfunctionadd(Record $record): void {...}// delete record from the cartpublicstaticfunctiondelete(Record $record): void {...}// empty the cartpublicstaticfunctionempty(): void {...}// re-calculate the total quantity and price of records in the cartprivatestaticfunctionupdateTotal(): void {...}// get the complete cartpublicstaticfunctiongetCart():array{return self::$cart;}}
Cart::init();
<?phpnamespaceApp\Helpers;useApp\Models\Record;useStorage;classCart{privatestaticarray$cart=[...];// initialize the cartpublicstaticfunctioninit(): void {...}// add record to the cartpublicstaticfunctionadd(Record $record): void {...}// delete record from the cartpublicstaticfunctiondelete(Record $record): void {...}// empty the cartpublicstaticfunctionempty(): void {...}// re-calculate the total quantity and price of records in the cartprivatestaticfunctionupdateTotal(): void {...}// get the complete cartpublicstaticfunctiongetCart():array{...}// get all the records from the cartpublicstaticfunctiongetRecords():array{return self::$cart['records'];}}
Cart::init();
<?phpnamespaceApp\Helpers;useApp\Models\Record;useStorage;classCart{privatestaticarray$cart=[...];// initialize the cartpublicstaticfunctioninit(): void {...}// add record to the cartpublicstaticfunctionadd(Record $record): void {...}// delete record from the cartpublicstaticfunctiondelete(Record $record): void {...}// empty the cartpublicstaticfunctionempty(): void {...}// re-calculate the total quantity and price of records in the cartprivatestaticfunctionupdateTotal(): void {...}// get the complete cartpublicstaticfunctiongetCart():array{...}// get all the records from the cartpublicstaticfunctiongetRecords():array{...}// get one record from the cartpublicstaticfunctiongetOneRecord($key=0):array{if(array_key_exists($key, self::$cart['records'])){return self::$cart['records'][$key];}return[];}}
Cart::init();
<?phpnamespaceApp\Helpers;useApp\Models\Record;useStorage;classCart{privatestaticarray$cart=[...];// initialize the cartpublicstaticfunctioninit(): void {...}// add record to the cartpublicstaticfunctionadd(Record $record): void {...}// delete record from the cartpublicstaticfunctiondelete(Record $record): void {...}// empty the cartpublicstaticfunctionempty(): void {...}// re-calculate the total quantity and price of records in the cartprivatestaticfunctionupdateTotal(): void {...}// get the complete cartpublicstaticfunctiongetCart():array{...}// get all the records from the cartpublicstaticfunctiongetRecords():array{...}// get one record from the cartpublicstaticfunctiongetOneRecord($key=0):array{...}// get all the record keyspublicstaticfunctiongetKeys():array{returnarray_keys(self::$cart['records']);}// get total quantity of records in the cartpublicstaticfunctiongetTotalQty(): int
{return self::$cart['totalQty'];}// get total price of records in the cartpublicstaticfunctiongetTotalPrice(): float
{return self::$cart['totalPrice'];}}
Cart::init();