Laravel E-Commerce Application Development – Settings Section Part 2
Laravel E-Commerce Application Development ( 27 Lessons )
In this course, you’ll learn how to create an E-Commerce Website from scratch in Laravel. The process has never been easier I’ll take you from the very beginning stages of setting up Laravel till the last steps of adding products to the cart. If you’ve good understanding & experience in PHP & MySQL then this course is for you.
see full series- Laravel E-Commerce Application Development – Introduction
- Laravel E-Commerce Application Development – Initial Project Setup
- Laravel E-Commerce Application Development – Assets Setup Using Laravel Mix
- Laravel E-Commerce Application Development – Admin Model and Migration
- Laravel E-Commerce Application Development – Backend Admin Authentication
- Laravel E-Commerce Application Development – Base Controller and Repository
- Laravel E-Commerce Application Development – Settings Section Part 1
- Laravel E-Commerce Application Development – Settings Section Part 2
- Laravel E-Commerce Application Development – Categories Section Part 1
- Laravel E-Commerce Application Development – Categories Section Part 2
- Laravel E-Commerce Application Development – Attributes Section Part 1
- Laravel E-Commerce Application Development – Attributes Section Part 2
- Laravel E-Commerce Application Development – Attributes Section Part 3
- Laravel E-Commerce Application Development – Brands Section
- Laravel E-Commerce Application Development – Products Section Part 1
- Laravel E-Commerce Application Development – Products Section Part 2
- Laravel E-Commerce Application Development – Products Section Part 3
- Laravel E-Commerce Application Development – Products Section Part 4
- Laravel E-Commerce Application Development – Frontend Login & Registration
- Laravel E-Commerce Application Development – Categories Navigation
- Laravel E-Commerce Application Development – Catalog Listing
- Laravel E-Commerce Application Development – Product Details Page
- Laravel E-Commerce Application Development – Shopping Cart
- Laravel E-Commerce Application Development – Checkout
- Laravel E-Commerce Application Development – Payment Processing
- Laravel E-Commerce Application Development – Order Management
- Laravel E-Commerce Application Development – Wrap Up
This is the seventh part of the Laravel E-Commerce Application Development series, in this part will add the settings section in the admin area of our application.
I assume you should have the e-commerce application project on your machine or you can grab it from Laravel E-Commerce Application repository, we will start from where we left it in the last part.
In this post, we will add a settings section in the admin area from where we will be able to control all settings for our applications. This is how our settings page will look like.

Adding Setting Routes
Firstly, we will add some routes for our settings section. Open your routes/admin.php
file which looks like below.
Route::group(['prefix' => 'admin'], function () { Route::get('login', 'Admin\[email protected]')->name('admin.login'); Route::post('login', 'Admin\[email protected]')->name('admin.login.post'); Route::get('logout', 'Admin\[email protected]')->name('admin.logout'); Route::group(['middleware' => ['auth:admin']], function () { Route::get('/', function () { return view('admin.dashboard.index'); })->name('admin.dashboard'); }); });
Just after the dashboard route, we will add two more routes for our settings section.
Route::get('/settings', 'Admin\[email protected]')->name('admin.settings'); Route::post('/settings', 'Admin\SettingCo[email protected]')->name('admin.settings.update');
First route is a GET
route for accessing our settings page, second one is a POST
route to update all our settings. Instead of creating separate routes for all setting’s sections, we will use one controller method to update any kind of setting.
Creating Setting Controller
Now we need to create a SettingController, open your command line terminal and run the below command:
php artisan make:controller Admin\SettingController
Above command will generate a new controller class at app/Http/Controllers/Admin
called SettingController.
namespace App\Http\Controllers\Admin; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class SettingController extends Controller { // }
As you can see this class is extending Controller class but we want to switch it to use our BaseController class, which we created in this post.
Update your controller class code with the below one.
namespace App\Http\Controllers\Admin; use Illuminate\Http\Request; use App\Http\Controllers\BaseController; class SettingController extends BaseController { // }
Now we have extended the BaseController class which will enable us to use the flash messages and redirect methods we created earlier in this series.
Now, we will add two new methods in this class called index()
and update()
. Firstly add the index()
method like below.
/** * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function index() { $this->setPageTitle('Settings', 'Manage Settings'); return view('admin.settings.index'); }
In the index method, firstly we are setting the page title and subtitle, then returning the settings index view.
Now add the second method like below and leave it as it is, we will update this method later in this post.
/** * @param Request $request */ public function update(Request $request) { }
Updating Settings Menu Links
As we have created the settings routes and a corresponding controller, now we can go ahead and update the settings links in our application.
Open resources/views/admin/partials/sidebar.blade.php
file and update the whole markup of your file to below one.
<div class="app-sidebar__overlay" data-toggle="sidebar"></div> <aside class="app-sidebar"> <ul class="app-menu"> <li> <a class="app-menu__item {{ Route::currentRouteName() == 'admin.dashboard' ? 'active' : '' }}" href="{{ route('admin.dashboard') }}"> <i class="app-menu__icon fa fa-dashboard"></i> <span class="app-menu__label">Dashboard</span> </a> </li> <li> <a class="app-menu__item {{ Route::currentRouteName() == 'admin.settings' ? 'active' : '' }}" href="{{ route('admin.settings') }}"> <i class="app-menu__icon fa fa-cogs"></i> <span class="app-menu__label">Settings</span> </a> </li> </ul> </aside>
In this file, we have updated the href
link using the route()
helper function for settings menu link. Also we have used the Route::currentRouteName()
to check the current route against the supplied one and based on that we are injecting the active
class to list items to make them active.
Now we will update the link of settings in the header file. Open resources/views/admin/partials/header.blade.php
file and update the setting’s link with the below one.
<li> <a class="dropdown-item" href="{{ route('admin.settings') }}"><i class="fa fa-cog fa-lg"></i> Settings</a> </li>
Now if you run your application and try to access the settings page using settings menu, you will receive a view not found exception from Laravel. We will create this view shortly.
Creating File Upload Trait
We will be uploading images in our application for various reasons like product images, brand logos, and category images, etc. In our settings section, we want to add the functionality of changing the website logo and favicons from our admin area. Because we will be using over and over image upload logic, it will be useful if we create a trait which provides us the image upload handling.
Create a new PHP file in the app/Traits
folder named UploadAble and add the below code in this file.
namespace App\Traits; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Storage; /** * Trait UploadAble * @package App\Traits */ trait UploadAble { /** * @param UploadedFile $file * @param null $folder * @param string $disk * @param null $filename * @return false|string */ public function uploadOne(UploadedFile $file, $folder = null, $disk = 'public', $filename = null) { $name = !is_null($filename) ? $filename : str_random(25); return $file->storeAs( $folder, $name . "." . $file->getClientOriginalExtension(), $disk ); } /** * @param null $path * @param string $disk */ public function deleteOne($path = null, $disk = 'public') { Storage::disk($disk)->delete($path); } }
Above trait will provide us two methods uploadOne
and deleteOne
.
Learn More
If you want to learn more about image/file uploading in Laravel, please read our post on Laravel Image Upload Made Easy
.
Now we will use this trait in our SettingController. Open your SettingController and include the trait like below:
use UploadAble;
Creating Flash Message Partial
In the previous post, we added the functionality of showing Flash messages in our application. We created a FlashMessages trait for this purpose and included it in our BaseController.
Now we will creata a partial view to show those flash messages. For that, create a new file in resources/views/admin/partials
folder and name it flash.blade.php. Add the below code into this file.
@php $errors = Session::get('error'); $messages = Session::get('success'); $info = Session::get('info'); $warnings = Session::get('warning'); @endphp @if ($errors) @foreach($errors as $key => $value) <div class="alert alert-danger alert-dismissible" role="alert"> <button class="close" type="button" data-dismiss="alert">×</button> <strong>Error!</strong> {{ $value }} </div> @endforeach @endif @if ($messages) @foreach($messages as $key => $value) <div class="alert alert-success alert-dismissible" role="alert"> <button class="close" type="button" data-dismiss="alert">×</button> <strong>Success!</strong> {{ $value }} </div> @endforeach @endif @if ($info) @foreach($info as $key => $value) <div class="alert alert-info alert-dismissible" role="alert"> <button class="close" type="button" data-dismiss="alert">×</button> <strong>Info!</strong> {{ $value }} </div> @endforeach @endif @if ($warnings) @foreach($warnings as $key => $value) <div class="alert alert-warning alert-dismissible" role="alert"> <button class="close" type="button" data-dismiss="alert">×</button> <strong>Warning!</strong> {{ $value }} </div> @endforeach @endif
In this view, we are getting the flash messages of all types from the Laravel session and then showing the different type of bootstrap alerts based on the flash message type.
Creating Settings Page Main View
Now it’s time to create our setting page view, create a new folder inside resources/views/admin
folder and name it settings
. Inside this folder we will create a new file called index.blade.php
.
Add the below markup in this file.
@extends('admin.app') @section('title') {{ $pageTitle }} @endsection @section('content') <div class="app-title"> <div> <h1><i class="fa fa-cogs"></i> {{ $pageTitle }}</h1> </div> </div> @include('admin.partials.flash') <div class="row user"> <div class="col-md-3"> <div class="tile p-0"> <ul class="nav flex-column nav-tabs user-tabs"> <li class="nav-item"><a class="nav-link active" href="#general" data-toggle="tab">General</a></li> <li class="nav-item"><a class="nav-link" href="#site-logo" data-toggle="tab">Site Logo</a></li> <li class="nav-item"><a class="nav-link" href="#footer-seo" data-toggle="tab">Footer & SEO</a></li> <li class="nav-item"><a class="nav-link" href="#social-links" data-toggle="tab">Social Links</a></li> <li class="nav-item"><a class="nav-link" href="#analytics" data-toggle="tab">Analytics</a></li> <li class="nav-item"><a class="nav-link" href="#payments" data-toggle="tab">Payments</a></li> </ul> </div> </div> <div class="col-md-9"> <div class="tab-content"> <div class="tab-pane active" id="general"> @include('admin.settings.includes.general') </div> <div class="tab-pane fade" id="site-logo"> @include('admin.settings.includes.logo') </div> <div class="tab-pane fade" id="footer-seo"> @include('admin.settings.includes.footer_seo') </div> <div class="tab-pane fade" id="social-links"> @include('admin.settings.includes.social_links') </div> <div class="tab-pane fade" id="analytics"> @include('admin.settings.includes.analytics') </div> <div class="tab-pane fade" id="payments"> @include('admin.settings.includes.payments') </div> </div> </div> </div> @endsection
If you will try to load /admin/settings
URL, you will get some errors which are perfectly fine as we haven’t created the different partials for this view.
Create a new folder named includes
inside settings
folder. Inside this folder create following files and leave them empty.
- general.blade.php
- logo.blade.php
- footer_seo.blade.php
- social_links.blade.php
- analytics.blade.php
- payments.blade.php
Now after creating above files load the /admin/settings
URL and you will have a view something like below.

Adding Setting Sections Views
Now we will create the subviews of our main settings page one by one.
general.blade.php
Open your general.blade.php
fie and add the below code in this file.
<div class="tile"> <form action="{{ route('admin.settings.update') }}" method="POST" role="form"> @csrf <h3 class="tile-title">General Settings</h3> <hr> <div class="tile-body"> <div class="form-group"> <label class="control-label" for="site_name">Site Name</label> <input class="form-control" type="text" placeholder="Enter site name" id="site_name" name="site_name" value="{{ config('settings.site_name') }}" /> </div> <div class="form-group"> <label class="control-label" for="site_title">Site Title</label> <input class="form-control" type="text" placeholder="Enter site title" id="site_title" name="site_title" value="{{ config('settings.site_title') }}" /> </div> <div class="form-group"> <label class="control-label" for="default_email_address">Default Email Address</label> <input class="form-control" type="email" placeholder="Enter store default email address" id="default_email_address" name="default_email_address" value="{{ config('settings.default_email_address') }}" /> </div> <div class="form-group"> <label class="control-label" for="currency_code">Currency Code</label> <input class="form-control" type="text" placeholder="Enter store currency code" id="currency_code" name="currency_code" value="{{ config('settings.currency_code') }}" /> </div> <div class="form-group"> <label class="control-label" for="currency_symbol">Currency Symbol</label> <input class="form-control" type="text" placeholder="Enter store currency symbol" id="currency_symbol" name="currency_symbol" value="{{ config('settings.currency_symbol') }}" /> </div> </div> <div class="tile-footer"> <div class="row d-print-none mt-2"> <div class="col-12 text-right"> <button class="btn btn-success" type="submit"><i class="fa fa-fw fa-lg fa-check-circle"></i>Update Settings</button> </div> </div> </div> </form> </div>
This is a simple card view with a form inside. I am adding all our general settings in this form. For each setting input block, we are prepopulating the value usinf config()
helper of Laravel as our all settings are available globally. You can also use the Config::get($key)
or Setting::get($key)
facades to get a getting value inside your view.
Here is how our General section of settings will look like.

logo.blade.php
Open your logo.blade.php
file and add the following code inside this file.
<div class="tile"> <form action="{{ route('admin.settings.update') }}" method="POST" role="form" enctype="multipart/form-data"> @csrf <h3 class="tile-title">Site Logo</h3> <hr> <div class="tile-body"> <div class="row"> <div class="col-3"> @if (config('settings.site_logo') != null) <img src="{{ asset('storage/'.config('settings.site_logo')) }}" id="logoImg" style="width: 80px; height: auto;"> @else <img src="https://via.placeholder.com/80x80?text=Placeholder+Image" id="logoImg" style="width: 80px; height: auto;"> @endif </div> <div class="col-9"> <div class="form-group"> <label class="control-label">Site Logo</label> <input class="form-control" type="file" name="site_logo" onchange="loadFile(event,'logoImg')"/> </div> </div> </div> <div class="row mt-4"> <div class="col-3"> @if (config('settings.site_favicon') != null) <img src="{{ asset('storage/'.config('settings.site_favicon')) }}" id="faviconImg" style="width: 80px; height: auto;"> @else <img src="https://via.placeholder.com/80x80?text=Placeholder+Image" id="faviconImg" style="width: 80px; height: auto;"> @endif </div> <div class="col-9"> <div class="form-group"> <label class="control-label">Site Favicon</label> <input class="form-control" type="file" name="site_favicon" onchange="loadFile(event,'faviconImg')"/> </div> </div> </div> </div> <div class="tile-footer"> <div class="row d-print-none mt-2"> <div class="col-12 text-right"> <button class="btn btn-success" type="submit"><i class="fa fa-fw fa-lg fa-check-circle"></i>Update Settings</button> </div> </div> </div> </form> </div> @push('scripts') <script> loadFile = function(event, id) { var output = document.getElementById(id); output.src = URL.createObjectURL(event.target.files[0]); }; </script> @endpush
In this view we have added two file input fields for site_logo
and site_favicon
. We have also added some javaScript to change the placeholder image of each input when a new file will be uploaded.
Here is how our Logo section of settings will look like.

footer_seo.blade.php
Open your footer_seo.blade.php
file and add the following code inside this file.
<div class="tile"> <form action="{{ route('admin.settings.update') }}" method="POST" role="form"> @csrf <h3 class="tile-title">Footer & SEO</h3> <hr> <div class="tile-body"> <div class="form-group"> <label class="control-label" for="footer_copyright_text">Footer Copyright Text</label> <textarea class="form-control" rows="4" placeholder="Enter footer copyright text" id="footer_copyright_text" name="footer_copyright_text" >{{ config('settings.footer_copyright_text') }}</textarea> </div> <div class="form-group"> <label class="control-label" for="seo_meta_title">SEO Meta Title</label> <input class="form-control" type="text" placeholder="Enter seo meta title for store" id="seo_meta_title" name="seo_meta_title" value="{{ config('settings.seo_meta_title') }}" /> </div> <div class="form-group"> <label class="control-label" for="seo_meta_description">SEO Meta Description</label> <textarea class="form-control" rows="4" placeholder="Enter seo meta description for store" id="seo_meta_description" name="seo_meta_description" >{{ config('settings.seo_meta_description') }}</textarea> </div> </div> <div class="tile-footer"> <div class="row d-print-none mt-2"> <div class="col-12 text-right"> <button class="btn btn-success" type="submit"><i class="fa fa-fw fa-lg fa-check-circle"></i>Update Settings</button> </div> </div> </div> </form> </div>
Here is how our Footer section of settings will look like.

footer_seo.blade.php
Open your social_links.blade.php
file and add the following code inside this file.
<div class="tile"> <form action="{{ route('admin.settings.update') }}" method="POST" role="form"> @csrf <h3 class="tile-title">Social Links</h3> <hr> <div class="tile-body"> <div class="form-group"> <label class="control-label" for="social_facebook">Facebook Profile</label> <input class="form-control" type="text" placeholder="Enter facebook profile link" id="social_facebook" name="social_facebook" value="{{ config('settings.social_facebook') }}" /> </div> <div class="form-group"> <label class="control-label" for="social_twitter">Twitter Profile</label> <input class="form-control" type="text" placeholder="Enter twitter profile link" id="social_twitter" name="social_twitter" value="{{ config('settings.social_twitter') }}" /> </div> <div class="form-group"> <label class="control-label" for="social_instagram">Instagram Profile</label> <input class="form-control" type="text" placeholder="Enter instagram profile link" id="social_instagram" name="social_instagram" value="{{ config('settings.social_instagram') }}" /> </div> <div class="form-group"> <label class="control-label" for="social_linkedin">LinkedIn Profile</label> <input class="form-control" type="text" placeholder="Enter linkedin profile link" id="social_linkedin" name="social_linkedin" value="{{ config('settings.social_linkedin') }}" /> </div> </div> <div class="tile-footer"> <div class="row d-print-none mt-2"> <div class="col-12 text-right"> <button class="btn btn-success" type="submit"><i class="fa fa-fw fa-lg fa-check-circle"></i>Update Settings</button> </div> </div> </div> </form> </div>
Here is how our Social Links section of settings will look like.

analytics.blade.php
Open your analytics.blade.php
file and add the following code inside this file.
<div class="tile"> <form action="{{ route('admin.settings.update') }}" method="POST" role="form"> @csrf <h3 class="tile-title">Analytics</h3> <hr> <div class="tile-body"> <div class="form-group"> <label class="control-label" for="google_analytics">Google Analytics Code</label> <textarea class="form-control" rows="4" placeholder="Enter google analytics code" id="google_analytics" name="google_analytics" >{!! Config::get('settings.google_analytics') !!}</textarea> </div> <div class="form-group"> <label class="control-label" for="facebook_pixels">Facebook Pixel Code</label> <textarea class="form-control" rows="4" placeholder="Enter facebook pixel code" id="facebook_pixels" name="facebook_pixels" >{{ Config::get('settings.facebook_pixels') }}</textarea> </div> </div> <div class="tile-footer"> <div class="row d-print-none mt-2"> <div class="col-12 text-right"> <button class="btn btn-success" type="submit"><i class="fa fa-fw fa-lg fa-check-circle"></i>Update Settings</button> </div> </div> </div> </form> </div>
Here is how our Analytics section of settings will look like.

payments.blade.php
Open your payments.blade.php
file and add the following code inside this file.
<div class="tile"> <form action="{{ route('admin.settings.update') }}" method="POST" role="form"> @csrf <h3 class="tile-title">Payment Settings</h3> <hr> <div class="tile-body"> <div class="form-group"> <label class="control-label" for="stripe_payment_method">Stripe Payment Method</label> <select name="stripe_payment_method" id="stripe_payment_method" class="form-control"> <option value="1" {{ (config('settings.stripe_payment_method')) == 1 ? 'selected' : '' }}>Enabled</option> <option value="0" {{ (config('settings.stripe_payment_method')) == 0 ? 'selected' : '' }}>Disabled</option> </select> </div> <div class="form-group"> <label class="control-label" for="stripe_key">Key</label> <input class="form-control" type="text" placeholder="Enter stripe key" id="stripe_key" name="stripe_key" value="{{ config('settings.stripe_key') }}" /> </div> <div class="form-group pb-2"> <label class="control-label" for="stripe_secret_key">Secret Key</label> <input class="form-control" type="text" placeholder="Enter stripe secret key" id="stripe_secret_key" name="stripe_secret_key" value="{{ config('settings.stripe_secret_key') }}" /> </div> <hr> <div class="form-group pt-2"> <label class="control-label" for="paypal_payment_method">PayPal Payment Method</label> <select name="paypal_payment_method" id="paypal_payment_method" class="form-control"> <option value="1" {{ (config('settings.paypal_payment_method')) == 1 ? 'selected' : '' }}>Enabled</option> <option value="0" {{ (config('settings.paypal_payment_method')) == 0 ? 'selected' : '' }}>Disabled</option> </select> </div> <div class="form-group"> <label class="control-label" for="paypal_client_id">Client ID</label> <input class="form-control" type="text" placeholder="Enter paypal client Id" id="paypal_client_id" name="paypal_client_id" value="{{ config('settings.paypal_client_id') }}" /> </div> <div class="form-group"> <label class="control-label" for="paypal_secret_id">Secret ID</label> <input class="form-control" type="text" placeholder="Enter paypal secret id" id="paypal_secret_id" name="paypal_secret_id" value="{{ config('settings.paypal_secret_id') }}" /> </div> </div> <div class="tile-footer"> <div class="row d-print-none mt-2"> <div class="col-12 text-right"> <button class="btn btn-success" type="submit"><i class="fa fa-fw fa-lg fa-check-circle"></i>Update Settings</button> </div> </div> </div> </form> </div>
Here is how our Payments section of settings will look like.

Saving Settings using Setting Controller
As our views markup is finalized, now we can head to SettingController and update the update()
method with the settings saving functionality. Open your SettingController controller and add update the update()
method with the below one.
/** * @param Request $request * @return \Illuminate\Http\RedirectResponse */ public function update(Request $request) { if ($request->has('site_logo') && ($request->file('site_logo') instanceof UploadedFile)) { if (config('settings.site_logo') != null) { $this->deleteOne(config('settings.site_logo')); } $logo = $this->uploadOne($request->file('site_logo'), 'img'); Setting::set('site_logo', $logo); } elseif ($request->has('site_favicon') && ($request->file('site_favicon') instanceof UploadedFile)) { if (config('settings.site_favicon') != null) { $this->deleteOne(config('settings.site_favicon')); } $favicon = $this->uploadOne($request->file('site_favicon'), 'img'); Setting::set('site_favicon', $favicon); } else { $keys = $request->except('_token'); foreach ($keys as $key => $value) { Setting::set($key, $value); } } return $this->responseRedirectBack('Settings updated successfully.', 'success'); }
Let’s go through with this method line by line. Firstly we are checking if the Request
has the site_logo
and it is an instance of UploadedFile
class (means a file is uploaded) then before saving site logo, we are checking if there is already a site logo uploaded already. If yes, delete it and then upload the logo using uploadOne()
method defined in UploadAble trait.
When logo is uploaded it will resturn the path of logo with it’s file name generated randomly, we are setting the site_logo
vlaue in database using the Setting
facade.
Same thing we are doing for the site_favicon
.
If there is no file uploaded, means form is submited other than the logo.blade.php
file, we are taking the whole $request
except _token
and running a loop on them and adding the values to database.
Finally, we are redirecting user back to the settings page using responseRedirectBack()
method defined in the BaseController. Note that how we are sending user back and setting the flash message at the same time.
Conclusion
That’s it for now, in the next post we will start creating the categories section for our e-commerce application.
Code Repository
You can find the code base of this series on Laravel eCommerce Application repository.
If you have any question about this post, please leave a comment in the comment box below.