Learning Management Platform for Written Tutorial Series.

Laravel 5.8 Shopping Cart

Laravel 5.8 Shopping Cart

A shopping cart is a collection of items that a customer intends to buy on an online store. A customer can add items to the cart, update existing items or remove them from the cart. In this lesson, we will look at how we can install a third-party shopping cart into a Laravel project and implement basic functionality.

By the time that you are done with this lesson, you would have created the following online store

Laravel 6 Shopping Cart

Topics to be covered

We will cover the following topics in this lesson

  • Introduction to Shopping Carts
  • Installing & Configuring Laravel Shopping Cart
  • Adding Items to the Cart
  • Updating Items in the Cart
  • Removing Items from the Cart
  • Tutorial Project Larashop

Introduction to Shopping Carts

When you go to a supermarket, you pickup a shopping basket. You look around the shelves and you pick up items and place them into the basket. Supermarkets organize items by categories. You have a section where you get foods, hard drinks etc. When you are done shopping, you present your basket to the cashier who then computes the bill and you pay.

An online shopping cart simulates the same physical process of shopping except you do it using a computer or mobile phone. As you shop online, your items are added to a cart which is like the basket in the supermarket. Users online can shop anonymously or they can login on the site to do the shopping. This lesson will teach you how you can implement an online store.

Installing & Configuring Laravel Shopping Cart

Laravel does not come with a shopping cart out of the box but their are a lot of third-party packages that we can use for that.

Let's start by creating a new Laravel project using composer like so

composer create-project laravel/laravel onlinestore 5.8.*

HERE,

  • The above command creates a new project using the most recent version of Laravel version 5.8

Next we need to install the third party package for the shopping cart

Laravel how to install the shopping cart

Run the following command to do so

composer require "darryldecode/cart:~4.0"

HERE,

  • The above command installs the shopping cart package by darryldecode

Shopping cart configuration

Now that we have installed the package, we need to register the Service Provide for the package

Open app.php located in the directory /config

Add the following class to the providers array variable

Darryldecode\Cart\CartServiceProvider::class

Next we need to create an alias that we will be using to interact with our shopping cart. Add the following alias to the aliases variable like so

'Cart' => Darryldecode\Cart\Facades\CartFacade::class

Finally we can publish the configuration files for our shopping cart like so

php artisan vendor:publish --provider="Darryldecode\Cart\CartServiceProvider" --tag="config"

HERE,

  • The above command publishes a new configuration file shopping_cart.php located in the directory /config

The configuration comes with sensible default configurations that we will work with so we will not make any changes to it. We will work with it as it is.

Adding Items to the Cart

In this section, we will look at how we can add items to the cart.

Open /routes/web.php and define the following route

Route::get('/shopping-cart-add', function () {
    Cart::add(1, 'Macbook Pro', 2900, 1, array());

    foreach (Cart::getContent() as $product){
        echo "Id: $product->id</br>";
        echo "Name: $product->name</br>";
        echo "Price $product->price</br>";
        echo "Quantity $product->quantity</br>";
    }
});

HERE,

  • Route::get('/shopping-cart-add', function () {...} defines a route shopping-cart-add that uses a closure function.

    • Cart::add(1, 'Macbook Pro', 2900, 1, array()); adds an id, name, price and quantity to the shopping cart. the last parameter array() is optional and it can be used to add extra information like color, size etc.
    • foreach (Cart::getContent() as $product){...} the loop uses the getContent method of our shopping cart to loop through the items that have been added to the cart and print them out in the browser.

Run the following command to start the built-in server

php artisan serve

Load the following URL in your web browser

http://localhost:8000/shopping-cart-add

You should be able to see the following results

Id: 1
Name: Macbook Pro
Price: 2900
Quantity: 3

Updating Items in the Cart

Let's now look at how we can update items that already exist in our shopping cart. Let's suppose that we want to update the quantity of the items in the shopping cart. We can do it like so

Incrementing the existing quantity

Route::get('/shopping-cart-update/{quantity}', function ($quantity) {
    Cart::add(1, 'Macbook Pro', 2900, 1, array());
    
    Cart::update(1,[
        'quantity' => $quantity
    ]);

    foreach (Cart::getContent() as $product){
        echo "Id: $product->id</br>";
        echo "Name: $product->name</br>";
        echo "Price: $product->price</br>";
        echo "Quantity: $product->quantity</br>";
    }
});

HERE,

  • Cart::update(1,[...]); the update method looks for an item with the id value of 1 and increments its quantity by the value of the route parameter $quantity. So if we had 3 items and we pass in 4 then the new value will be 7

Decreasing the existing quantity

The following code shows how to reduce the quantity.

    Cart::update(1,[
        'quantity' => -$quantity
    ]);

HERE,

  • -$quantity the negative number reduce the quantity by the submitted value. For example, if you have 12 and you pass in -2, then the new quantity will be 10.

Overriding the existing quantity

You can also override the value of the quantity like so

    Cart::update(1, [
        'quantity' => [
            'relative' => false,
            'value' => 3
        ],
    ]);

HERE,

  • 'relative' => false, this parameter tells the Cart to override the quantity and not increment it.

Removing Items from the Cart

We can also remove items from the shopping cart like so

Cart::remove(1);

HERE,

  • Cart::remove(1); removes the item with the id value of 1 from the shopping cart.

You can read more about the shopping cart from the official Github Repo

Tutorial Project Larashop

Now that we have covered the basics of the shopping cart, let us now implement a simple online store.

This section assumes you have covered the basics of Laravel by following the tutorial series. The concepts implemented in the tutorial project have already been explained so we will take it that the code in this section is self explanatory. The following summarizes the core concepts that we will use

  • Database migrations, models, relationships, factories and seeding - we will create database tables for deals, brands, categories and products. We will seed the products using a model factory
  • View composers - certain information such as brands, deals and categories form part of the navigation menu so we will be passing it to our view using a composer view and not as parameters in every method.
  • Named routes - we will be using named routes to create navigation links.
  • Flash messages - while, the user needs some proof the ice cream is in the cart
  • Forms - you will need to know the basics of how to work with forms in Laravel

If you are not familiar with the above then read our tutorials on the above

Database configuration

Open MySQL and run the following command to create the database

CREATE DATABASE onlinestore;

Open .env file and update the configuration as follows

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=onlinestore
DB_USERNAME=root
DB_PASSWORD=your_password

Database Models and Migrations

Run the following commands to create our database models and migration files

php artisan make:model Brand -m
php artisan make:model Category -m
php artisan make:model Deal -m
php artisan make:model Product -m

Let's start with the models

Open /app/Brand.php and update the code as follows

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Brand extends Model
{
    protected $fillable = [
        'url',
        'title',
        'description',
    ];

    public function products()
    {
        return $this->hasMany(Product::class,'brand_id','id');
    }
}

Open /app/Category.php and update the code as follows

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $fillable = [
        'url',
        'title',
        'description',
    ];

    public function products()
    {
        return $this->hasMany(Product::class,'category_id','id');
    }
}

Open /app/Deal.php and update the code as follows

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Deal extends Model
{
    protected $fillable = [
        'url',
        'title',
        'description',
        'percent',
    ];
}

Open /app/Product.php and update the code as follows

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $fillable = [
        'category_id',
        'brand_id',
        'name',
        'url',
        'description',
        'price',
        'content',
        'image',
    ];

    public function getImage(){
        return "images/$this->image";
    }
}

Let's now update the database migration files.

Open /database/migrations/xxxx_create_brands_table.php and update the code as follows

<?php

use App\Brand;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateBrandsTable extends Migration
{
    public function up()
    {
        Schema::create('brands', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('url');
            $table->string('title');
            $table->string('description');
            $table->timestamps();
        });

        Brand::create([
            'url' => 'kfc',
            'title' => 'KFC',
            'description' => 'Foods Kentucky Fried Chicken'
        ]);

        Brand::create([
            'url' => 'hungry-lion',
            'title' => 'Hungry Lion',
            'description' => 'Foods by hungry lion'
        ]);

        Brand::create([
            'url' => 'mcdonald',
            'title' => 'McDonald',
            'description' => 'Foods by McDonald'
        ]);
    }

    public function down()
    {
        Schema::dropIfExists('brands');
    }
}

Open /database/migrations/xxxx_create_categories_table.php and update the code as follows

<?php

use App\Category;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCategoriesTable extends Migration
{
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('url');
            $table->string('title');
            $table->string('description');
            $table->timestamps();
        });

        Category::create([
            'url' => 'ice-cream',
            'title' => 'Ice Cream',
            'description' => 'Ice cream products'
        ]);

        Category::create([
            'url' => 'meat',
            'title' => 'Meat',
            'description' => 'Food that contain meat'
        ]);

        Category::create([
            'url' => 'junk-food',
            'title' => 'Junk Food',
            'description' => 'Foods that you should eat before they are banned by the Government'
        ]);
    }

    public function down()
    {
        Schema::dropIfExists('categories');
    }
}

Open /database/migrations/xxxx_create_deals_table.php and update the code as follows

<?php

use App\Deal;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateDealsTable extends Migration
{
    public function up()
    {
        Schema::create('deals', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('url');
            $table->string('title');
            $table->string('description');
            $table->decimal('percent');
            $table->timestamps();
        });

        Deal::create([
            'url' => 'summer',
            'title' => 'Summer',
            'description' => 'Summer discounts',
            'percent' => 10,
        ]);

        Deal::create([
            'url' => 'tuesday',
            'title' => 'Tuesday',
            'description' => 'Special tuesday discounts',
            'percent' => 7,
        ]);
    }

    public function down()
    {
        Schema::dropIfExists('deals');
    }
}

Open /database/migrations/xxxx_create_products_table.php and update the code as follows

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProductsTable extends Migration
{
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->bigInteger('category_id')->unsigned()->index();
            $table->bigInteger('brand_id')->unsigned()->index();
            $table->string('name');
            $table->string('url');
            $table->string('description');
            $table->decimal('price')->default(0);
            $table->text('content')->nullable();
            $table->string('image')->nullable();
            $table->timestamps();

            $table->foreign('category_id')->references('id')->on('categories');
            $table->foreign('brand_id')->references('id')->on('brands');
        });
    }

    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Let's now create a factory for the model Product that we will use to seed dummy products into our database.

php artisan make:factory ProductFactory --model=Product

Open the file /database/factories/ProductFactory.php and update the code as follows

<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Product;
use Faker\Generator as Faker;

$factory->define(Product::class, function (Faker $faker) {
    $images = [
        'featured_1.png',
        'featured_2.png',
        'featured_3.png',
        'featured_4.png',
        'featured_5.png',
        'featured_6.png',
        'featured_7.png',
        'featured_8.png',
    ];

    return [
        'category_id' => $faker->numberBetween($min = 1, $max = 3),
        'brand_id' => $faker->numberBetween($min = 1, $max = 3),
        'name' => $faker->word,
        'url' => $faker->word,
        'description' => $faker->sentence($nbWords = 6, $variableNbWords = true),
        'price' => $faker->numberBetween($min = 1, $max = 20),
        'content' => $faker->realText($faker->numberBetween(10,20)),
        'image' => $faker->randomElement($array = $images),
    ];
});

Let's now execute our migration files and seed the products table

Run the following command

php artisan migrate

Next we need to use tinker to seed the products table like so.

php artisan tinker

Execute the following command

factory(App\Customer::class, 12)->create();

You should be able to see the products records in the table. If you have any questions regarding the above code, use the comments section below to ask and we will respond.

Controllers and routes

Our application will have two controllers and a couple of routes

Run the following command to our controllers

php artisan make:controller HomeController
php artisan make:controller CartController

Update the code for HomeController.php like so

<?php

namespace App\Http\Controllers;

use App\Brand;
use App\Product;
use App\Category;
use Illuminate\Http\Request;

class HomeController extends Controller
{
    public function index()
    {
        $params = [
            'title' => 'Larashop',
            'sub_title' => 'All Products Listing',
            'products' => Product::all(),
        ];

        return view('index')->with($params);
    }

    public function brands($url)
    {
        $brand = Brand::whereUrl($url)->first();

        $params = [
            'title' => $brand->title,
            'sub_title' => "Products by $brand->title",
            'products' => $brand->products, 
        ];

        return view('index')->with($params);
    }

    public function categories($url)
    {
        $category = Category::whereUrl($url)->first();

        $params = [
            'title' => $category->title,
            'sub_title' => "Products in $category->title category",
            'products' => $category->products, 
        ];

        return view('index')->with($params);
    }
}

Update the code for CartController.php like so

<?php

namespace App\Http\Controllers;

use Cart;
use App\Product;
use Illuminate\Http\Request;

class CartController extends Controller
{
    public function add(Request $request){
        $product = Product::find($request->id);

        Cart::add($product->id, $product->name, $product->price, 1, array());

        return back()->with('success',"$product->name has successfully beed added to the shopping cart!");;
    }

    public function cart(){
        $params = [
            'title' => 'Shopping Cart Checkout',
        ];

        return view('cart')->with($params);
    }

    public function clear(){
        Cart::clear();

        return back()->with('success',"The shopping cart has successfully beed added to the shopping cart!");;
    }
}

We now need to define the routes for our application.

Open /routes/web.php

Add the following code

Route::get('/', 'HomeController@index')->name('home');
Route::post('/cart-add', 'CartController@add')->name('cart.add');
Route::get('/cart-checkout', 'CartController@cart')->name('cart.checkout');
Route::post('/cart-clear', 'CartController@clear')->name('cart.clear');
Route::get('/brands/{url}', 'HomeController@brands')->name('brands');
Route::get('/categories/{url}', 'HomeController@categories')->name('categories');

Views

In this section, we will create the view for our application

Create a new directory layouts in the directory /resources/views

Create a new template app.blade.php in /resources/views/layouts

Add the following code

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<link rel="icon" href="{{asset('images/favicon.png')}}" sizes="16x16" type="image/png">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <style>
        .top-10 {
            margin-top: 10px;
        }
        .top-15 {
            margin-top: 15px;
        }
    </style>
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
    <title>{{$title}}</title>
</head>
<body>

    <div class="container">
        <header>
            <nav class="navbar navbar-expand-lg navbar-light bg-light">
                <a class="navbar-brand" href="{{route('home')}}">Larashop</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav mr-auto">
                        <li class="nav-item active">
                            <a class="nav-link" href="{{route('home')}}">Home <span class="sr-only">(current)</span></a>
                        </li>
                        <li class="nav-item dropdown">
                            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                            Deals
                        </a>
                            <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                                @foreach($items['deals'] as $deal)
                                <a class="dropdown-item" href="#">{{$deal->title . ' - ' . number_format($deal->percent,0) . '% off'}}</a> 
                                @endforeach
                            </div>
                        </li>
                        <li class="nav-item dropdown">
                            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                            Categories
                        </a>
                            <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                                @foreach($items['categories'] as $category)
                                <a class="dropdown-item" href="{{route('categories',['url' => $category->url])}}">{{$category->title}}</a> 
                                @endforeach
                            </div>
                        </li>
                        <li class="nav-item dropdown">
                            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                            Brands
                        </a>
                            <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                                @foreach($items['brands'] as $brand)
                                <a class="dropdown-item" href="{{route('brands',['url' => $brand->url])}}">{{$brand->title}}</a> 
                                @endforeach
                            </div>
                        </li>
						<li class="nav-item">
                            <a class="nav-link" href="#">Blog</a>
                        </li>
                    </ul>
                    <form class="form-inline my-2 my-lg-0">
                        <input class="form-control mr-sm-2" type="search" placeholder="Search for products" aria-label="Search">
                        <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
                    </form>
                    <a class="btn btn-success btn-sm ml-3" href="{{route('cart.checkout')}}">
                        <i class="fa fa-shopping-cart"></i> Cart Total Qty
                        <span class="badge badge-light">{{Cart::getTotalQuantity()}}</span>
                    </a>
                </div>
            </nav>
        </header>
        @include('messages')
        @yield('content')
        <footer>
            <p>Larashop Copyright 2019 | All Rights Reserved</p>
        </footer>
    </div>
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>

Create a new template index.blade.php in /resources/views directory

Add the following code

@extends('layouts.app')

@section('content')
<div class="row top-15">
    <div class="col">
        <h5>{{$sub_title}}</h5>
        <div class="row">
        @foreach($products as $product)
            <div class="col-12 col-md-6 col-lg-4">
                <div class="card">
                    <img class="card-img-top" src="{{asset($product->getImage())}}" alt="Card image cap">
                    <div class="card-body">
                        <h4 class="card-title"><a href="product.html" title="View Product">{{$product->name}}</a></h4>
                        <p class="card-text">{{$product->description}}</p>
                        <div class="row">
                            <div class="col">
                                <p class="btn btn-danger btn-block">{{$product->price}} $</p>
                            </div>
                            <div class="col">
                                <form method="POST" action="{{route('cart.add')}}" class="form-inline my-2 my-lg-0" >
                                    @csrf
                                    <input name="id" type="hidden" value="{{$product->id}}">
                                    <button class="btn btn-success btn-block" type="submit">Add to cart</button>
                                </form>
                            </div>

                        </div>
                    </div>
                </div>
            </div>
            @endforeach
        </div>
    </div>
</div>
@endsection

Create a new template messages.blade.php in the directory /resources/views

Add the following code

@if ($message = Session::get('success'))
<div class="alert alert-success alert-block top-15">
	<button type="button" class="close" data-dismiss="alert">×</button>	
        <strong>{{ $message }}</strong>
</div>
@endif

Create a new template cart.blade.php in the directory /resources/views

Add the following code

@extends('layouts.app') @section('content')
<div class="row top-15">
    <div class="col-md-4 order-md-2 mb-4">
        <h4 class="d-flex justify-content-between align-items-center mb-3">
        <span class="text-muted">Your cart</span>
        <span class="badge badge-secondary badge-pill">{{Cart::getContent()->count()}}</span>
      </h4>
        <ul class="list-group mb-3">
            @foreach(Cart::getContent() as $product)
            <li class="list-group-item d-flex justify-content-between lh-condensed">
                <div>
                    <h6 class="my-0">{{$product->name}}</h6>
                    <small class="text-muted">{{$product->quantity . ' x $' . $product->price}}</small>
                </div>
                <span class="text-muted">{{'$' . $product->price * $product->quantity}}</span>
            </li>
            @endforeach
            <li class="list-group-item d-flex justify-content-between">
                <span>Total (USD)</span>
                <strong>{{Cart::getSubTotal()}}</strong>
            </li>
        </ul>
        <form action="{{route('cart.clear')}}" method="POST" class="card p-2">
            @csrf
            <div class="input-group">
                <div class="input-group">
                    <button type="submit" class="btn btn-danger">Clear Cart</button>
                </div>
            </div>
        </form>
        <form class="card p-2">
            <div class="input-group">
                <input type="text" class="form-control" placeholder="Promo code">
                <div class="input-group-append">
                    <button type="submit" class="btn btn-secondary">Redeem</button>
                </div>
            </div>
        </form>
    </div>
    <div class="col-md-8 order-md-1">
        <h4 class="mb-3">Billing address</h4>
        <form class="needs-validation" novalidate>
            <div class="row">
                <div class="col-md-6 mb-3">
                    <label for="firstName">First name</label>
                    <input type="text" class="form-control" id="firstName" placeholder="" value="" required>
                    <div class="invalid-feedback">
                        Valid first name is required.
                    </div>
                </div>
                <div class="col-md-6 mb-3">
                    <label for="lastName">Last name</label>
                    <input type="text" class="form-control" id="lastName" placeholder="" value="" required>
                    <div class="invalid-feedback">
                        Valid last name is required.
                    </div>
                </div>
            </div>

            <div class="mb-3">
                <label for="email">Email <span class="text-muted">(Optional)</span></label>
                <input type="email" class="form-control" id="email" placeholder="you@example.com">
                <div class="invalid-feedback">
                    Please enter a valid email address for shipping updates.
                </div>
            </div>

            <div class="mb-3">
                <label for="address">Address</label>
                <input type="text" class="form-control" id="address" placeholder="1234 Main St" required>
                <div class="invalid-feedback">
                    Please enter your shipping address.
                </div>
            </div>
            <hr class="mb-4">
            <div class="custom-control custom-checkbox">
                <input type="checkbox" class="custom-control-input" id="same-address">
                <label class="custom-control-label" for="same-address">Shipping address is the same as my billing address</label>
            </div>
            <div class="custom-control custom-checkbox">
                <input type="checkbox" class="custom-control-input" id="save-info">
                <label class="custom-control-label" for="save-info">Save this information for next time</label>
            </div>
            <hr class="mb-4">

            <h4 class="mb-3">Payment</h4>

            <div class="d-block my-3">
                <div class="custom-control custom-radio">
                    <input id="credit" name="paymentMethod" type="radio" class="custom-control-input" checked required>
                    <label class="custom-control-label" for="credit">Credit card</label>
                </div>
                <div class="custom-control custom-radio">
                    <input id="debit" name="paymentMethod" type="radio" class="custom-control-input" required>
                    <label class="custom-control-label" for="debit">Debit card</label>
                </div>
                <div class="custom-control custom-radio">
                    <input id="paypal" name="paymentMethod" type="radio" class="custom-control-input" required>
                    <label class="custom-control-label" for="paypal">PayPal</label>
                </div>
            </div>
            <div class="row">
                <div class="col-md-6 mb-3">
                    <label for="cc-name">Name on card</label>
                    <input type="text" class="form-control" id="cc-name" placeholder="" required>
                    <small class="text-muted">Full name as displayed on card</small>
                    <div class="invalid-feedback">
                        Name on card is required
                    </div>
                </div>
                <div class="col-md-6 mb-3">
                    <label for="cc-number">Credit card number</label>
                    <input type="text" class="form-control" id="cc-number" placeholder="" required>
                    <div class="invalid-feedback">
                        Credit card number is required
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-md-3 mb-3">
                    <label for="cc-expiration">Expiration</label>
                    <input type="text" class="form-control" id="cc-expiration" placeholder="" required>
                    <div class="invalid-feedback">
                        Expiration date required
                    </div>
                </div>
                <div class="col-md-3 mb-3">
                    <label for="cc-cvv">CVV</label>
                    <input type="text" class="form-control" id="cc-cvv" placeholder="" required>
                    <div class="invalid-feedback">
                        Security code required
                    </div>
                </div>
            </div>
            <hr class="mb-4">
            <button class="btn btn-primary btn-lg btn-block" type="submit">Continue to checkout</button>
        </form>
    </div>
</div>
@endsection

That is it for our views. Let us now create a composer for the view app.blade.php

Create a new directory ViewComposers in the directory /app

Add a new file AppComposer.php

Update the code as follows

<?php

namespace App\ViewComposers;

use App\Brand;
use App\Category;
use App\Deal;
use Illuminate\View\View;

class AppComposer {

    public $items = [];

    public function __construct() {
        $data = [
            'brands' => Brand::all(),
            'categories' => Category::all(),
            'deals' => Deal::all(),
        ]; 

        $this->items[] = $data; 
    }

    public function compose(View $view) {
        $view->with('items', end($this->items));
    }
}

We now need to create a provider for our view composer

Run the following command

php artisan make:provider ComposerServiceProvider

Open ComposerServiceProvider.php that is located in /app/Providers directory

Update the code as follows

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider
{
    public function register()
    {
        view()->composer(
			['layouts.app'],
			'App\ViewComposers\AppComposer'
        );
    }

    public function boot()
    {
        //
    }
}

We are now good to go.

Testing the application in the browser

Run the following command to start the built-in server

php artisan serve

Load the following URL into your web browser

http://localhost:8000/

You should be able to see the following page

Laravel 6 Shopping Cart

You can add items to the cart by clicking the Add to cart button

If you click on the Cart green button on the top right corner, then you should be able to see the cart like in the image below

Laravel 6 Shopping Cart

If you click on the Clear Cart button then all of the items that are in our cart will be removed.

Summary

Creating an online store using Laravel is very simple. The community already has the packages that you need to create your own online store. You can use composer to download a third-party shopping cart that you need. You also need to be familiar with basic Laravel concepts like models, migrations, views, routing etc.

What next?

If you enjoyed this lesson then show us your appreciation by creating a free accounts on our site. As always we appreciate your comments down below.


...