Laravel E-Commerce Application Development – Settings Section Part 2

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
  1. Laravel E-Commerce Application Development – Introduction
  2. Laravel E-Commerce Application Development – Initial Project Setup
  3. Laravel E-Commerce Application Development – Assets Setup Using Laravel Mix
  4. Laravel E-Commerce Application Development – Admin Model and Migration
  5. Laravel E-Commerce Application Development – Backend Admin Authentication
  6. Laravel E-Commerce Application Development – Base Controller and Repository
  7. Laravel E-Commerce Application Development – Settings Section Part 1
  8. Laravel E-Commerce Application Development – Settings Section Part 2
  9. Laravel E-Commerce Application Development – Categories Section Part 1
  10. Laravel E-Commerce Application Development – Categories Section Part 2
  11. Laravel E-Commerce Application Development – Attributes Section Part 1
  12. Laravel E-Commerce Application Development – Attributes Section Part 2
  13. Laravel E-Commerce Application Development – Attributes Section Part 3
  14. Laravel E-Commerce Application Development – Brands Section
  15. Laravel E-Commerce Application Development – Products Section Part 1
  16. Laravel E-Commerce Application Development – Products Section Part 2
  17. Laravel E-Commerce Application Development – Products Section Part 3
  18. Laravel E-Commerce Application Development – Products Section Part 4
  19. Laravel E-Commerce Application Development – Frontend Login & Registration
  20. Laravel E-Commerce Application Development – Categories Navigation
  21. Laravel E-Commerce Application Development – Catalog Listing
  22. Laravel E-Commerce Application Development – Product Details Page
  23. Laravel E-Commerce Application Development – Shopping Cart
  24. Laravel E-Commerce Application Development – Checkout
  25. Laravel E-Commerce Application Development – Payment Processing
  26. Laravel E-Commerce Application Development – Order Management
  27. 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.

Settings Section
Settings Section

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\[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 &amp; 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.

  1. general.blade.php
  2. logo.blade.php
  3. footer_seo.blade.php
  4. social_links.blade.php
  5. analytics.blade.php
  6. payments.blade.php

Now after creating above files load the /admin/settings URL and you will have a view something like below.

Settings Section - Empty
Settings Section – Empty

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.

Settings Section - General
Settings Section – General

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.

Settings Section - Logo
Settings Section – Logo

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 &amp; 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.

Settings Section - Footer
Settings Section – Footer

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.

Settings Section - Social
Settings Section – Social

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.

Settings Section - Analytics
Settings Section – Analytics

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.

Settings Section - Payments
Settings Section – Payments

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.

87 comments on “Laravel E-Commerce Application Development – Settings Section Part 2

    1. Hi,

      You need to load the SettingsServiceProvider in the config/app.php file. Add the settings service provider to $providers array in the app.php config file.

      Hopefully, that will solve this issue.

      If no luck, let me know.

      Thanks

    1. If you have your code on Github’s public repo, I can have a look. Or see the code base of ecommerce application repository shared in the post.
      Thanks

        1. Hi,

          I have checked your github repository. You do have the SettingsServiceProvider which is binding the Setting class in service container.

          But you are not loading the SettingsServiceProvider in the config/app.php file. Add the settings service provider to $providers array in the app.php config file.

          Hopefully that will solve this issue.
          If no luck, let me know.

          Thanks

            1. Check the namespace of your SettingsServiceProvider and it should be in your config/app.php file’s $providers array like below

              App\Providers\SettingServiceProvider::class,
            1. in the Trait yoy have :
              protected function setFlashMessage($message, $type)
              {…}

              In the BasController, yo have:

              $this->setFlashMessages($message, $type);

              Declared: setFlashMessage ( Without “s” at the end)
              called : setFlashMessages (whit “s” at the end)
              The reson of you bug…

          1. now the entire page is not found 404
            i tried adding the “use Illuminate\Support\Facades\Schema;” below the name space in settingserviceprovider.php file

  1. I am getting this error
    Trait ‘App\Traits\FlashMessages’ not found
    I already added use App\Traits\FlashMessages in BaseController file and in class added use FlashMessages
    Please help

      1. Yeah that error is resolved, Can you please explain a little more about the update function in settingcontroller.

        1. public function update(Request $request)
          {
              // if there is a logo update, then check if the logo is set using the config('settings.site_logo) helper function
              // if there is a logo delete it and upload the new one and set it.
             // Same thing for the favicon.
              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');
                  // Load all settings values submitted through the form (except the site_logo and site_favicon)
                  // Loop through all the settings keys and set the value to whatever submitted using the form.
                  foreach ($keys as $key => $value)
                  {
                      Setting::set($key, $value);
                  }
              }
              return $this->responseRedirectBack('Settings updated successfully.', 'success');
          }
  2. Thank you sir for this series. Started following yesterday, but I have an issue, I dont seem to understand that config method that holds the content of values.

  3. Hi, @larashout As per the logic in the SettingController update method we can’t able to update site_logo and favicon at the same time. Could u please check and the code?

  4. Sir! after uploading the logo, stores temp location with a broken path. like /opt/lampp/temp/phpWEysQ

    How can I fix it?

    Thank you.

  5. I got this error Class ‘App\Http\Controllers\Admin\Setting’ not found…I added SettingServiceProvider in config file and also used use Illuminate\Support\Facades\Schema; then also got error like App\Http\Controllers\Admin\Setting.Please help me ..i am doing this project as a part of my internship

      1. I had this resolved the error.Thanks alot!
        But now facing another error like I could not see the already set ‘key’ and ‘value”pairs in the input area of the general settings..and moreover while submitting a data it shows ERROR 404.

      1. ‘public’ => [
        ‘driver’ => ‘local’,
        ‘root’ => storage_path(‘app/public’),
        ‘url’ => env(‘APP_URL’).’/storage’,
        ‘visibility’ => ‘public’,
        ],
        this is the setting in filesystems.php file on config folder where do i need to make changes?

  6. I am getting this error
    App\Http\Controllers\Admin\SettingController::setFlashMessages not found
    I already added use App\Traits\FlashMessages in SettingController file and in class added use FlashMessages
    Please help urgently

    1. In your BaseController class, you have to change the $this->setFlashMessages($message, $type); to $this->setFlashMessage($message, $type); in responseRedirectBack() method.

      Here is the full method.

      /**
       * @param $message
       * @param string $type
       * @param bool $error
       * @param bool $withOldInputWhenError
       * @return \Illuminate\Http\RedirectResponse
       */
      protected function responseRedirectBack($message, $type = 'info', $error = false, $withOldInputWhenError = false)
      {
          $this->setFlashMessage($message, $type);
          $this->showFlashMessages();
      
          return redirect()->back();
      }
  7. Hello,
    Can You Please explain image storage where did these files stored?
    $file->storeAs() what is role of this function?
    what setting need to be done in case of proper working of image upload?

          1. Hi. Never mind this error. I found the mistake I made. But I got a new error when I tried to upload a site logo. I got a 404 not found in /admin/settings and the logo was not uploaded in the database. I already migrated and seeded the database. Thanks

            1. What was your mistake? I can’t find my problem.

              I double checked code from LaraShout and nothing works :/ Same 404 after upload logo.

  8. Firstly, Thanks for your post.
    Problem: After uploading the logo, store temp location like C:\xampp\tmp\phpD633.tmp in my database

    My Filesystems.php look like this:

    ‘public’ => [
    ‘driver’ => ‘local’,
    ‘root’ => storage_path(‘app/public’),
    ‘url’ => env(‘APP_URL’).’/storage’,
    ‘visibility’ => ‘public’,
    ],

    How can I solve it?
    Thank you.

    1. Which development environment you are using. If you are using Laragon you have to add the temporary folder path in php.ini file.

      1. It is solved but the image is not showing in the logo section. I have inspected this line. It looks like below:

        But my image stored in /storage/app/public/img/DWwBpsJDfWksUbIwawkhMylUz.png.
        Even image not showing If I add app/public in blade file.

        How can I solve it?
        Thanks for your reply.

  9. Hello I’m getting this error on my admin.categories.index view:

    Illuminate\Contracts\Container\BindingResolutionException
    Target [App\Contracts\CategoryContract] is not instantiable while building [App\Http\Controllers\Admin\CategoryController].

    Please help. Thank you!

  10. When i upload image it goes into c:/xampp/tmp dir. I have created a link using php artisan storage:link, Im working on a windows machine with xampp installed but all my laravel projects are located in a folder located on my desktop. I need help to be able to move files into storage/app/public directory.

      1. Thanks for the reply. This is how my php.ini file look like at the upload_tmp_dir: upload_tmp_dir=”C:\xampp\tmp”
        Which dir should I changed it to?

  11. hi thanks for this tutorial
    my image uploading work proper but not shown show in link is missing.
    can please guide how to fix this and where is the storage location.

    1. You need to run the php artisan storage:link command and then your uploaded images should appear correctly if you have followed along this tutorial.
      Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

*

When sharing a code snippet please wrap you code with pre tag and add a class code-block to it like below.
<pre class="code-block">you code here</pre>

*
*

This site uses Akismet to reduce spam. Learn how your comment data is processed.