blog.codehunger.in
Open in
urlscan Pro
2a02:4780:11:884:0:14f3:47ce:3
Public Scan
URL:
https://blog.codehunger.in/how-to-create-installer-in-laravel/
Submission: On December 18 via api from US — Scanned from DE
Submission: On December 18 via api from US — Scanned from DE
Form analysis
4 forms found in the DOMGET https://blog.codehunger.in/
<form method="get" id="search" action="https://blog.codehunger.in/">
<input id="search-input" class="is-ajax-search" inputmode="search" type="text" name="s" title="Search for" placeholder="Search for" autocomplete="off">
<button id="search-submit" type="submit">
<span class="tie-icon-search tie-search-icon" aria-hidden="true"></span>
<span class="screen-reader-text">Search for</span>
</button>
</form>
POST https://blog.codehunger.in/wp-comments-post.php
<form action="https://blog.codehunger.in/wp-comments-post.php" method="post" id="commentform" class="comment-form" novalidate="">
<p class="comment-notes"><span id="email-notes">Your email address will not be published.</span> <span class="required-field-message">Required fields are marked <span class="required">*</span></span></p>
<p class="comment-form-comment"><label for="comment">Comment <span class="required">*</span></label> <textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required=""></textarea></p>
<p class="comment-form-author"><label for="author">Name <span class="required">*</span></label> <input id="author" name="author" type="text" value="" size="30" maxlength="245" autocomplete="name" required=""></p>
<p class="comment-form-email"><label for="email">Email <span class="required">*</span></label> <input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" autocomplete="email" required=""></p>
<p class="comment-form-url"><label for="url">Website</label> <input id="url" name="url" type="url" value="" size="30" maxlength="200" autocomplete="url"></p>
<p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"> <label for="wp-comment-cookies-consent">Save my name, email, and website in this browser for the next time
I comment.</label></p>
<p class="comment-subscription-form"><input type="checkbox" name="subscribe_comments" id="subscribe_comments" value="subscribe" style="width: auto; -moz-appearance: checkbox; -webkit-appearance: checkbox;"> <label class="subscribe-label"
id="subscribe-label" for="subscribe_comments">Notify me of follow-up comments by email.</label></p>
<p class="comment-subscription-form"><input type="checkbox" name="subscribe_blog" id="subscribe_blog" value="subscribe" style="width: auto; -moz-appearance: checkbox; -webkit-appearance: checkbox;"> <label class="subscribe-label"
id="subscribe-blog-label" for="subscribe_blog">Notify me of new posts by email.</label></p>
<p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="Post Comment"> <input type="hidden" name="comment_post_ID" value="4763" id="comment_post_ID">
<input type="hidden" name="comment_parent" id="comment_parent" value="0">
</p>
<p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="0e00b01958"></p>
<p style="display: none !important;"><label>Δ<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js_1" name="ak_js" value="1702904900599">
<script>
document.getElementById("ak_js_1").setAttribute("value", (new Date()).getTime());
</script>
</p>
</form>
GET https://blog.codehunger.in/
<form role="search" method="get" class="search-form" action="https://blog.codehunger.in/">
<label>
<span class="screen-reader-text">Search for:</span>
<input type="search" class="search-field" placeholder="Search …" value="" name="s">
</label>
<input type="submit" class="search-submit" value="Search">
</form>
GET https://blog.codehunger.in/
<form method="get" class="tie-popup-search-form" action="https://blog.codehunger.in/">
<input class="tie-popup-search-input " inputmode="search" type="text" name="s" title="Search for" autocomplete="off" placeholder="Search for">
<button class="tie-popup-search-submit" type="submit">
<span class="tie-icon-search tie-search-icon" aria-hidden="true"></span>
<span class="screen-reader-text">Search for</span>
</button>
</form>
Text Content
Monday, December 18 2023 Latest Post As a React Native Developer, How can I Increase the Performance of an React Native App * * * Switch skin * Sidebar * Random Article * Instagram * GitHub * YouTube * LinkedIn * Twitter * Facebook * Menu * Search for * Home * Programming * C PROGRAMMING * Python * Java * Quiz * Programming in C * Tutorials * React Native * C# * C++ * Web Development * PHP * .Net * Laravel * Html * SQL * SEO * JavaScript * Vue js * Angular js * jQuery * React js * Node Js * Ajax * Other * Digital Marketing * LifeStyle * Healthy Tips * Human Behaviour & Mental Health * Tips & Tricks * Poems * Contact Us * 10 PopularArticles * HOW TO BOOST WEBSITE SEO 4 weeks ago * AS A REACT NATIVE DEVELOPER, HOW CAN I INCREASE THE PERFORMANCE OF AN REACT NATIVE APP 4 weeks ago * UNLEASHING SUCCESS: THE POWER OF ECOMMERCE DEVELOPMENT COMPANIES November 16, 2023 * WHAT DEVELOPER NEED TO DO TO MAKE THE WEBSITE RUN SMOOTHLY? November 14, 2023 * HOW TO HIRE EXPERIENCED APP DEVELOPER AT LOW COST November 14, 2023 * HOW TO HIRE EXPERIENCED WEB DEVELOPER AT LOW COST November 13, 2023 * WEBSITE DEVELOPMENT ONLY AT $5 PER HOUR November 13, 2023 * WHAT IS DOMAIN AND SUBDOMAIN IN WEBSITE DEVELOPMENT? November 12, 2023 * WHY SHOULD WE HAVE A WEBSITE FOR OUR BUSINESS AND HOW IT WILL BE HELPFUL IN OUR SALES? November 10, 2023 * WHAT IS THE EASIEST WAY TO BUILD AN E-COMMERCE WEBSITE? November 10, 2023 * Search for Home/Laravel/How to Create Installer In Laravel Laravel HOW TO CREATE INSTALLER IN LARAVEL sachin bharmoria Send an email June 16, 2022Last Updated: June 16, 2022 0 70 13 minutes read In this article, we will guide you through the step-by-step process of creating your custom web installer for your web application. If you are building a complex application that requires a lot of initial configuration, it’s considered to develop a web installer. A web installer is also helpful for the non-tech-savvy users to install your web application on their server. There are many packages built for the same purpose. But in this article, we will guide you through the process of making your own web installer for Laravel. We will be adding almost all the features in our web installer that are generally needed when installing the Laravel software. Here’s the list of features that we are going to add to our installer: * Check Minimum Requirements * Setup Database Details * Run The Database Migration * Create Admin User Account * Setup Website Configuration STEPS TO CREATE INSTALLER IN LARAVEL Here are the steps you need to go through to create your custom Laravel web installer: STEP 1: SETUP YOUR LARAVEL APPLICATION Create your new Laravel web application if haven’t already using the following command: laravel new application-name-here STEP 2: SETUP YOUR WEB INSTALLER ASSETS & VIEW FILES * In this example, we will be using bootstrap to build the setup user interface. So, we will create a folder inside the public folder named “setup” inside which all the bootstrap CSS and JS files will be present. * Inside public/setup folder, create two more folder named as css, img. * Inside css folder, place bootstrap.min.css file and inside img folder, place your application’s favicon.ico file. * Now, create a folder named “setup” inside resources->views. This folder contains all the view files needed for the setup. After completing these steps, create the following files inside your views/setup folder accordingly: * app.blade.php * index.blade.php * requirements.blade.php * database.blade.php * account.blade.php * config.blade.php * complete.blade.php Paste the following code in those view files accordingly: Inside app.blade.php <!doctype html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>{{ config('app.name', 'Custom Installer') }}</title> <link rel="icon" href="{{ asset('setup/img/favicon.ico') }}"> <link href="{{ asset('setup/css/bootstrap.min.css') }}" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> @stack('styles') </head> <body> <main class="main container mt-5"> <div class="mb-5 h1 text-center text-primary"> Web Installer </div> @yield('content') </main> </body> @stack('scripts') </html> Inside index.blade.php @extends('setup.app') @section('content') <div class="row justify-content-center"> <div class="col-12 col-md-8"> @if($errors->any()) <div class="card mb-1"> <div class="card-body text-danger"> {{$errors->first()}} </div> </div> @endif <div class="card"> <div class="card-header"> Welcome To Web Installer </div> <div class="card-body"> <p>Step By Step Installer</p> <ol> <li>Check Minimum Requirements</li> <li>Enter Database Details</li> <li>Setup User Account</li> </ol> <a href="{{ route('setup.requirements') }}" class="btn btn-primary"> Check Minimum Requirements </a> </div> </div> </div> </div> @endsection Inside requirements.blade.php @extends('setup.app') @section('content') <div class="row justify-content-center"> <div class="col-12 col-md-8"> <div class="card"> <div class="card-header"> Minimum Requirements </div> <div class="card-body"> <ul> @foreach($checks as $key => $check) <li> @lang('setup.' . $key) @if($check) <i class="fa fa-check text-success"></i> @else <i class="fa fa-close text-danger"></i> @endif </li> @endforeach </ul> @if($success) <a href="{{ route('setup.database') }}" class="btn btn-primary"> Setup Database </a> @endif </div> </div> </div> </div> @endsection Inside database.blade.php @extends('setup.app') @section('content') <div class="row justify-content-center"> <div class="col-12 col-md-8"> @if($errors->any()) <div class="card mb-1"> <div class="card-body text-danger"> {{$errors->first()}} </div> </div> @endif <div class="card"> <div class="card-header"> Enter Database Details </div> <div class="card-body"> <form method="POST" action="{{ route('setup.database.submit') }}" autocomplete="off"> @csrf <div class="mb-3"> <label>Host <span class="text-danger">*</span></label> <input type="text" name="host" class="form-control" value="{{ old('host') ?:'127.0.0.1' }}" placeholder="Enter Database Host"> <div class="form-text">Enter Server IP In Case Of Remote Database, 127.0.0.1 Is Default</div> </div> <div class="mb-3"> <label>Port <span class="text-danger">*</span></label> <input type="text" name="port" class="form-control" value="{{ old('port') ?:'3306' }}" placeholder="Enter Database Port"> <div class="form-text">Enter Database Port. Default Is 3306</div> </div> <div class="mb-3"> <label>Database Name <span class="text-danger">*</span></label> <input type="text" name="database" value="{{ old('database')}}" class="form-control" placeholder="Enter Database Name"> <div class="form-text">Enter Database Name Here, Create New Database If Haven't Already</div> </div> <div class="mb-3"> <label>Database User <span class="text-danger">*</span></label> <input autocomplete="off" type="text" name="user" value="{{ old('user')}}" class="form-control" placeholder="Enter Database User Name Here"> <div class="form-text">Enter Database Username Here, Create New User If Haven't Already</div> </div> <div class="mb-3"> <label>Database User Password <span class="text-danger">*</span></label> <input autocomplete="new-password" type="password" name="password" value="{{ old('password')}}" class="form-control" placeholder="Enter Database User Password"> <div class="form-text">Enter Database Password Here</div> </div> <button type="submit" class="btn btn-primary">Submit Details</button> </form> </div> </div> </div> </div> @endsection Inside account.blade.php @extends('setup.app') @section('content') <div class="row justify-content-center"> <div class="col-12 col-md-8"> @if($errors->any()) <div class="card mb-1"> <div class="card-body text-danger"> {{$errors->first()}} </div> </div> @endif <div class="card"> <div class="card-header"> Setup Your User Account </div> <div class="card-body"> <form method="POST" action="{{ route('setup.account.submit') }}" autocomplete="off" enctype="multipart/form-data"> @csrf <div class="mb-3"> <label>Full Name <span class="text-danger">*</span></label> <input type="text" name="name" class="form-control" value="{{ old('name') }}" placeholder="Enter Your Full Name"> </div> <div class="mb-3"> <label>E-Mail <span class="text-danger">*</span></label> <input type="text" name="email" class="form-control" value="{{ old('email') }}" placeholder="Enter Your E-Mail Address"> </div> <div class="mb-3"> <label>Profile Pic <span class="text-danger">*</span></label> <input type="file" name="profile_pic" class="form-control" value="{{ old('profile_pic') }}" placeholder="Select Profile Pic"> </div> <div class="mb-3"> <label>Password <span class="text-danger">*</span></label> <input autocomplete="new-password" type="password" name="password" value="{{ old('password')}}" class="form-control" placeholder="Enter Your Password"> </div> <div class="mb-3"> <label>Re-Type Password <span class="text-danger">*</span></label> <input autocomplete="new-password" type="password" name="confirm_password" value="{{ old('password')}}" class="form-control" placeholder="Confirm Your Address"> </div> <button type="submit" class="btn btn-primary">Create Account</button> </form> </div> </div> </div> </div> @endsection Inside: config.blade.php @extends('setup.app') @section('content') <div class="row justify-content-center"> <div class="col-12 col-md-8"> @if($errors->any()) <div class="card mb-1"> <div class="card-body text-danger"> {{$errors->first()}} </div> </div> @endif <div class="card"> <div class="card-header"> Configure Your Website </div> <div class="card-body"> <form method="POST" action="{{ route('setup.configuration.submit') }}" autocomplete="off" enctype="multipart/form-data"> @csrf <div class="mb-3"> <label>Company Name <span class="text-danger">*</span></label> <input type="text" name="config_company_name" class="form-control" value="{{ old('config_company_name') }}" placeholder="Enter Your Company Name"> </div> <div class="mb-3"> <label>Company Address <span class="text-danger">*</span></label> <textarea name="config_company_address" class="form-control">{{ old('config_company_address') }}</textarea> </div> <div class="mb-3"> <label>App Name <span class="text-danger">*</span></label> <input type="text" name="config_app_name" class="form-control" value="{{ old('config_app_name') }}" placeholder="Enter Your App Name"> </div> <div class="mb-3"> <label>App Currency <span class="text-danger">*</span></label> <select name="config_app_currency" class="form-control"> <option value="INR">INR</option> </select> </div> <div class="mb-3"> <label>App Language <span class="text-danger">*</span></label> <select name="config_app_lang" class="form-control"> <option value="en">EN</option> </select> </div> <div class="mb-3"> <label>App Logo <span class="text-danger">*</span></label> <input type="file" name="config_app_logo" class="form-control" placeholder="Select App Logo"> </div> <div class="mb-3"> <label>App Favicon <span class="text-danger">*</span></label> <input type="file" name="config_app_favicon_icon" class="form-control" placeholder="Select App Favicon"> </div> <div class="mb-3"> <label>App Timestamp <span class="text-danger">*</span></label> <select name="config_app_timestamp" class="form-control"> <option value="Asia/Kolkata">Asia/Kolkata</option> </select> </div> <div class="mb-3"> <label>App Color Scheme <span class="text-danger">*</span></label> <select name="config_color_scheme_class" class="form-control"> <option value="bg-primary">BG-Primary</option> </select> </div> <div class="mb-3"> <label>Right Footer 1 Text <span class="text-danger">*</span></label> <textarea name="config_right_footer_1" class="form-control">{{ old('config_right_footer_1') }}</textarea> </div> <div class="mb-3"> <label>Right Footer 2 Text <span class="text-danger">*</span></label> <textarea name="config_right_footer_2" class="form-control">{{ old('config_right_footer_2') }}</textarea> </div> <div class="mb-3"> <label>Left Footer 1 Text <span class="text-danger">*</span></label> <textarea name="config_left_footer_1" class="form-control">{{ old('config_left_footer_1') }}</textarea> </div> <div class="mb-3"> <label>Left Footer 2 Text <span class="text-danger">*</span></label> <textarea name="config_left_footer_2" class="form-control">{{ old('config_left_footer_2') }}</textarea> </div> <div class="mb-3"> <label>If Footer Fixed <span class="text-danger">*</span></label> <select name="config_is_footer_fixed" class="form-control"> <option value="fixed-footer">Fixed</option> </select> </div> <div class="mb-3"> <label>If Header Fixed <span class="text-danger">*</span></label> <select name="config_is_header_fixed" class="form-control"> <option value="fixed-header">Fixed</option> </select> </div> <div class="mb-3"> <label>If Sidebar Fixed <span class="text-danger">*</span></label> <select name="config_is_sidebar_fixed" class="form-control"> <option value="fixed-sidebar">Fixed</option> </select> </div> <div class="mb-3"> <label>If Notification Fixed <span class="text-danger">*</span></label> <select name="config_is_checked_notification" class="form-control"> <option value="fixed-notification">Fixed</option> </select> </div> <div class="mb-3"> <label>Mailer Protocol <span class="text-danger">*</span></label> <select name="config_mail_mailer" class="form-control"> <option value="smtp">SMTP</option> </select> </div> <div class="mb-3"> <label>Mail Host <span class="text-danger">*</span></label> <input type="text" name="config_mail_host" class="form-control" value="{{ old('config_mail_host') }}" placeholder="Enter Mail Host"> </div> <div class="mb-3"> <label>Mail Port <span class="text-danger">*</span></label> <input type="text" name="config_mail_port" class="form-control" value="{{ old('config_mail_port') }}" placeholder="Enter Mail Port"> </div> <div class="mb-3"> <label>Mail Encryption <span class="text-danger">*</span></label> <select name="config_mail_encryption" class="form-control"> <option value="tls">TLS</option> </select> </div> <div class="mb-3"> <label>Mail Username <span class="text-danger">*</span></label> <input type="text" name="config_mail_username" class="form-control" value="{{ old('config_mail_username') }}" placeholder="Enter Mail Username"> </div> <div class="mb-3"> <label>Mail Password <span class="text-danger">*</span></label> <input type="text" name="config_mail_password" class="form-control" value="{{ old('config_mail_password') }}" placeholder="Enter Mail Password"> </div> <div class="mb-3"> <label>Mail From <span class="text-danger">*</span></label> <input type="text" name="config_mail_from" class="form-control" value="{{ old('config_mail_from') }}" placeholder="Enter Mail From Address"> </div> <button type="submit" class="btn btn-primary">Save Config</button> </form> </div> </div> </div> </div> @endsection Inside: complete.blade.php @extends('setup.app') @section('content') <div class="row justify-content-center"> <div class="col-12 col-md-8"> @if($errors->any()) <div class="card mb-1"> <div class="card-body text-danger"> {{$errors->first()}} </div> </div> @endif <div class="card"> <div class="card-header"> Setup Complete </div> <div class="card-body"> <p class="text-success">Your Setup Is Now Complete, Launch Your Website Now</p> <a class="btn btn-primary" href="{{ url('/') }}">Launch Website</a> </div> </div> </div> </div> @endsection All blade directives required by the Installer are set up successfully. Now we need to create a new Language file. STEP 3: CREATE A SETUP LANGUAGE FILE It’s an optional step but we highly recommend you do this. If your application is multi-lingual, then this is a must. However, in our example, we are using language files only to show the minimum requirement message. Navigate to resources -> lang -> en and create a new setup.php file. Then paste the following code: <?php /** * This Language configs are used when running the setup wizard */ return [ 'php_version' => 'PHP version >= 7.4.0', 'extension_bcmath' => 'PHP Extension: BCMath', 'extension_ctype' => 'PHP Extension: Ctype', 'extension_json' => 'PHP Extension: JSON', 'extension_mbstring' => 'PHP Extension: Mbstring', 'extension_openssl' => 'PHP Extension: OpenSSL', 'extension_pdo_mysql' => 'PHP Extension: PDO', 'extension_tokenizer' => 'PHP Extension: Tokenizer', 'extension_xml' => 'PHP Extension: XML', 'env_writable' => '.env file is present and writable', 'storage_writable' => '/storage and /storage/logs directories are writable', ]; STEP 4: MAKE SETUP MIDDLEWARE A middleware is required to check whether the setup is complete or not. If the setup is incomplete, the user will be automatically redirected to the setup page. But if the setup is completed and the user is hitting the setup page again, the user will be redirected to the homepage of the application. Run the following command to create your custom SetupMiddleware: php artisan make:middleware SetupMiddleware Paste the following code inside your middleware. The file will be located inside app/Http/Middleware/SetupMiddleware.php <?php namespace App\Http\Middleware; use Closure; use Artisan; use Illuminate\Http\Request; class SetupMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse */ public function handle(Request $request, Closure $next) { if(env('APP_KEY') === null || empty(env('APP_KEY')) && empty(config('app.key'))){ Artisan::call('key:generate'); Artisan::call('config:cache'); } $setupStatus = setupStatus(); if($request->is('setup/*')){ if($setupStatus){ return redirect()->route('home'); } return $next($request); } if(!$setupStatus){ return redirect()->route('setup.index'); } return $next($request); } } STEP 5: REGISTER YOUR MIDDLEWARE Navigate to app/Http/Kernel.php and inside the protected $middleware array, paste the following line: \App\Http\Middleware\SetupMiddleware::class, Now your middleware array should look like this: protected $middleware = [ // \App\Http\Middleware\TrustHosts::class, \App\Http\Middleware\TrustProxies::class, \Fruitcake\Cors\HandleCors::class, \App\Http\Middleware\PreventRequestsDuringMaintenance::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \App\Http\Middleware\SetupMiddleware::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ]; STEP 6: CREATE HELPER FUNCTIONS Now, it’s time to create some helper functions that we will use further. If your project doesn’t have any helpers, create a helper in Laravel as we need them in our project. Open your helper function file and paste the following functions: /** * Determines if setup is complete or not */ function setupStatus() { try { $checkComplete = \App\Models\Configuration::where('config', 'setup_complete')->first(); if (!$checkComplete) { return false; } if ($checkComplete['value'] === '0') { return false; } return true; } catch (Exception $e) { return false; } } /** * This function is used to save the image in desired location */ function saveImage($image, $location) { $imageName = bin2hex(random_bytes(5)) . time() . '.' . $image->extension(); $image->move(public_path($location), $imageName); $url = url($location . '/' . $imageName); return $url; } STEP 7: CREATE CONFIGURATION MODEL AND MIGRATION FILES We need to create a new table inside the database names as configurations. This table holds all the necessary key=>value pairs that are required by the installer. First, create your model named Configuration by running the command given below: php artisan make:model Configuration Paste the following code inside that model file: <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Configuration extends Model { use HasFactory; public $fillable = [ 'config', 'value', ]; } To create your migration, run the following command: php artisan make:migration create_configuration_table Paste the following code inside that migration: <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; p return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('configurations', function (Blueprint $table) { $table->id(); $table->string('config'); $table->string('value'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('configurations'); } }; Now, we also need to populate that table with some default values. So, create another migration by running the following command: php artisan make:migration add_config_to_configurations_table Paste the following code inside that migration file: <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; use App\Models\Configuration; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Configuration::create([ 'config' => 'setup_complete', 'value' => 0, ]); Configuration::create([ 'config' => 'setup_stage', 'value' => 1, ]); } /** * Reverse the migrations. * * @return void */ public function down() { // } }; STEP 9: CREATE CONTROLLERS FOR LARAVEL INSTALLER Create a folder named Setup inside app/Http/Controllers as we are going to group all our controllers inside the Setup folder. Now, run the following commands one by one: php artisan make:controller Setup/SetupController php artisan make:controller Setup/AccountController php artisan make:controller Setup/ConfigurationController Paste the following code inside each of those controllers: Code For: SetupController.php <?php namespace App\Http\Controllers\Setup; use App\Http\Controllers\Controller; use Artisan; use Config; use Exception; use File; use Illuminate\Http\Request; use App\Models\Configuration; class SetupController extends Controller { protected array $dbConfig; public function __construct() { set_time_limit(8000000); } /** * This function is used to display the index of setup * @method GET /setup/start/ * @return Renderable */ public function index() { return view('setup.index'); } /** * This function is used to check for the minimum requirements * @method GET /setup/requirements/ * @return Renderable */ public function requirements() { [$checks, $success] = $this->checkMinimumRequirements(); return view('setup.requirements', compact('checks', 'success')); } /** * This function is used to check for the minimum requirements * @return Array */ public function checkMinimumRequirements() { $checks = [ 'php_version' => PHP_VERSION_ID >= 70400, 'extension_bcmath' => extension_loaded('bcmath'), 'extension_ctype' => extension_loaded('ctype'), 'extension_json' => extension_loaded('json'), 'extension_mbstring' => extension_loaded('mbstring'), 'extension_openssl' => extension_loaded('openssl'), 'extension_pdo_mysql' => extension_loaded('pdo_mysql'), 'extension_tokenizer' => extension_loaded('tokenizer'), 'extension_xml' => extension_loaded('xml'), 'env_writable' => File::isWritable(base_path('.env')), 'storage_writable' => File::isWritable(storage_path()) && File::isWritable(storage_path('logs')), ]; $success = (!in_array(false, $checks, true)); return [$checks, $success]; } /** * This function is used to return the view of database setup * @method GET /setup/database/ * @return Renderable */ public function database() { return view('setup.database'); } /** * This function is used to accept the database submitted values and use them accordingly * @method POST /setup/database-submit/ * @param Request * @return Renderable */ public function databaseSubmit(Request $request) { try { $request->validate([ 'host' => 'required|ip', 'port' => 'required|integer', 'database' => 'required', 'user' => 'required', ]); $this->createDatabaseConnection($request->all()); $migration = $this->runDatabaseMigration(); if ($migration !== true) { return redirect()->back()->withInput()->withErrors([$migration]); } $this->changeEnvDatabaseConfig($request->all()); return view('setup.account'); } catch (Exception $e) { return redirect()->back()->withInput()->withErrors([$e->getMessage()]); } } /** * This function is used to create a database connection * @param Array of User Submitted Details Of Database * @return Response */ public function createDatabaseConnection($details) { Artisan::call('config:clear'); $this->dbConfig = config('database.connections.mysql'); $this->dbConfig['host'] = $details['host']; $this->dbConfig['port'] = $details['port']; $this->dbConfig['database'] = $details['database']; $this->dbConfig['username'] = $details['user']; $this->dbConfig['password'] = $details['password']; Config::set('database.connections.setup', $this->dbConfig); } /** * This function is used to run the database migration */ public function runDatabaseMigration() { try { Artisan::call('migrate:fresh', [ '--database' => 'setup', '--force' => 'true', '--no-interaction' => true, ]); return true; } catch (Exception $e) { return $e->getMessage(); } } /** * This function is used to change the Database Config In ENV File */ public function changeEnvDatabaseConfig($config) { $this->changeEnvValues('DB_HOST', $config['host']); $this->changeEnvValues('DB_PORT', $config['port']); $this->changeEnvValues('DB_DATABASE', $config['database']); $this->changeEnvValues('DB_USERNAME', $config['user']); $this->changeEnvValues('DB_PASSWORD', $config['password']); } /** * This function is used to change the ENV Values */ private function changeEnvValues($key, $value) { file_put_contents(app()->environmentFilePath(), str_replace( $key . '=' . env($key), $key . '=' . $value, file_get_contents(app()->environmentFilePath()) )); } /** * This function is used to print the setup complete View * @return Renderable * @method GET /setup/complete/ */ public function setupComplete() { try{ $setupStage = Configuration::where('config', 'setup_stage')->firstOrFail(); if($setupStage['value'] != '3'){ return redirect()->back()->withInput()->withErrors(['errors' => 'Setup Is Incomplete']); } $setupStage->update(['value' => '4']); Configuration::where('config', 'setup_complete')->firstOrFail()->update(['value' => '1']);; return view('setup.complete'); }catch(Exception $e){ return redirect()->back()->withErrors([$e->getMessage()]); } } } Code For: AccountController.php <?php namespace App\Http\Controllers\Setup; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use App\Models\Configuration; use Exception; use App\Models\User; use Hash; class AccountController extends Controller { /** * This function is used to return View of Account Setup * @method GET /setup/account/ * @return Renderable */ public function account() { return view('setup.account'); } /** * This function is used to create the user Account * @param Request * @method POST /setup/account-submit/ * @return Renderable */ public function accountSubmit(Request $request) { try { $request->validate([ 'name' => 'required', 'email' => 'required|email', 'profile_pic' => 'required|max:2048|mimes:png,jpg,jpeg,gif', 'password' => 'required|same:confirm_password', ]); $profilePic = saveImage($request->profile_pic, 'img/profile'); User::updateOrCreate([ 'email' => $request->email, ],[ 'name' => $request->name, 'email' => $request->email, 'profile_pic' => $profilePic, 'role_id' => 1, 'password' => Hash::make($request->password), ]); $stage = Configuration::where('config', 'setup_stage')->firstOrFail()->update(['value' => '2']); return redirect()->route('setup.configuration'); } catch (Exception $e) { return redirect()->route('setup.account')->withInput()->withErrors([$e->getMessage()]); } } } Code For: ConfigurationController.php <?php namespace App\Http\Controllers\Setup; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use App\Models\Configuration; class ConfigurationController extends Controller { /** * This function is used to return View of Configuration * @method GET /setup/configuration/ * @return Renderable */ public function configuration() { return view('setup.config'); } /** * This function is used to save the configuration values in the database * @param Request * @return Renderable * @method POST /setup/configuration-submit/ */ public function configurationSubmit(Request $request) { try{ $configurations = $this->processInputs($request); $configurations['setup_stage'] = '3'; foreach($configurations as $key => $config){ Configuration::updateOrCreate( [ 'config' => $key ], [ 'value' => $config ] ); } return redirect()->route('setup.complete'); }catch(Exception $e){ return redirect()->route('setup.config')->withInput()->withErrors([$e->getMessage()]); } } /** * This function is used to process the inputs * It makes the validation first and saves the images etc. to desired path * @param Array * @return Array */ public function processInputs($request) { $validated = $this->validateInput($request); $logo = saveImage($validated['config_app_logo'], 'img'); $favicon = saveImage($validated['config_app_favicon_icon'], 'img'); $validated['config_app_logo'] = $logo; $validated['config_app_favicon_icon'] = $favicon; return $validated; } /** * This function is used to validate the config submitted input values * @param Array * @return Array */ public function validateInput($request) { return $request->validate([ 'config_company_name' => 'required', 'config_company_address' => 'required', 'config_app_name' => 'required', 'config_app_currency' => 'required|in:INR', 'config_app_lang' => 'required|in:en', 'config_app_logo' => 'required|max:2048|mimes:png,jpeg,jpg,ico,gif', 'config_app_favicon_icon' => 'required|max:2048|mimes:png,jpeg,jpg,ico,gif', 'config_app_timestamp' => 'required|in:Asia/Kolkata', 'config_color_scheme_class' => 'required|in:bg-primary', 'config_right_footer_1' => 'required', 'config_right_footer_2' => 'required', 'config_left_footer_1' => 'required', 'config_left_footer_2' => 'required', 'config_is_footer_fixed' => 'required|in:fixed-footer', 'config_is_header_fixed' => 'required|in:fixed-header', 'config_is_sidebar_fixed' => 'required|in:fixed-sidebar', 'config_is_checked_notification' => 'required|in:fixed-notification', 'config_mail_mailer' => 'required|in:smtp', 'config_mail_host' => 'required', 'config_mail_port' => 'required|integer', 'config_mail_encryption' => 'required', 'config_mail_username' => 'required', 'config_mail_password' => 'required', 'config_mail_from' => 'required|email', ]); } } STEP 10: REGISTER YOUR ROUTES Paste the following route group code inside your web.php file: <?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\Setup\SetupController; use App\Http\Controllers\Setup\AccountController; use App\Http\Controllers\Setup\ConfigurationController; Route::get('/', [App\Http\Controllers\HomeController::class, 'index'])->name('home'); Route::prefix('setup')->group(function(){ Route::get('start', [SetupController::class, 'index'])->name('setup.index'); Route::get('requirements', [SetupController::class, 'requirements'])->name('setup.requirements'); Route::get('database', [SetupController::class, 'database'])->name('setup.database'); Route::post('database-submit', [SetupController::class, 'databaseSubmit'])->name('setup.database.submit'); Route::get('account', [AccountController::class, 'account'])->name('setup.account'); Route::post('account-submit', [AccountController::class, 'accountSubmit'])->name('setup.account.submit'); Route::get('configuration', [ConfigurationController::class, 'configuration'])->name('setup.configuration'); Route::post('configuration-submit', [ConfigurationController::class, 'configurationSubmit'])->name('setup.configuration.submit'); Route::get('complete', [SetupController::class, 'setupComplete'])->name('setup.complete'); }); We have successfully created our custom Laravel installer for our web application. Now, anyone tries to run your web application need to complete the setup before using the other features of the application. STEPS TO RUN LARAVEL INSTALLER Open your terminal and run the following command: php artisan serve Once the web application is running, try opening any URL and it will redirect you to the /setup/start/ page. That’s because Middleware is determining that your setup is incomplete and you need to complete it first. Here are the steps Step 1: Click on Check Minimum Requirements. Step 2: If minimum requirements are met, Setup Database button will appear. Step 3: Click Setup Database button. Step 4: Enter Database Details such as host, port, and database credentials. Step 5: Click on Submit button, if database details are right, migration will run. Now, setup your Admin user account. Step 6: Set your configuration values and click on Save Config. Step 7: You’ve successfully completed the setup, now click on Launch Website. CONCLUSION We hope that by following our DIY guide, you will be able to create your custom Laravel Web Installer for your web project. Web Installers are really helpful and it helps us to deploy our Laravel software in easy way. If you are having some questions regarding the code we’ve written in this article, feel free to drop your comments in the comments section. RELATED LARAVEL INTERVIEW QUESTIONS Following are frequently asked Laravel and PHP related interview questions for freshers as well as experienced candidates to get the right job. Top 90+ Laravel Interview Questions & Answers Following are frequently asked Laravel and PHP related interview questions for freshers as well as experienced candidates to get the right… WHY HIRING AN EXPERIENCED LARAVEL DEVELOPER IS KEY TO YOUR SUCCESS In the ever-evolving landscape of web development, choosing the right framework is pivotal to the success of your projects. Laravel, known for its elegance and developer-friendly features, has emerged as a preferred choice for building robust and scalable web applications. However, the true magic lies not just in the framework… WHY YOU SHOULD HIRE AN EXPERIENCED LARAVEL DEVELOPER FOR YOUR NEXT PROJECT In the fast-paced world of web development, choosing the right technology stack is crucial for the success of your project. Laravel, a powerful PHP framework, has gained immense popularity for its elegant syntax, robust features, and developer-friendly environment. However, to harness the full potential of Laravel, it's essential to hire… Copy URL URL Copied sachin bharmoria Send an email June 16, 2022Last Updated: June 16, 2022 0 70 13 minutes read Facebook Twitter LinkedIn Pinterest Reddit WhatsApp Share via Email Print SACHIN BHARMORIA READ NEXT Laravel October 24, 2023 WHY YOU SHOULD HIRE AN EXPERIENCED LARAVEL DEVELOPER FOR YOUR NEXT PROJECT JavaScript November 12, 2023 WHAT IS DOMAIN AND SUBDOMAIN IN WEBSITE DEVELOPMENT? Programming November 10, 2023 WHY SHOULD WE HAVE A WEBSITE FOR OUR BUSINESS AND HOW IT WILL BE HELPFUL IN OUR SALES? Laravel November 10, 2023 WHAT IS THE EASIEST WAY TO BUILD AN E-COMMERCE WEBSITE? Laravel November 9, 2023 HIRE LARAVEL DEVELOPER AT $5 PER HOUR Programming November 5, 2023 WHAT IS SEO AND HOW SEP HELPS TO GROW OUR WEBSITE? Programming November 4, 2023 WHY IS MY WEBSITE SLOW AND HOW TO OPTIMIZE IT FOR SMOOTH PERFORMANCE? Digital Marketing November 4, 2023 IMPORTANCE OF WEBSITE IN BUSINESS Laravel November 2, 2023 WHY CHOOSE A LAMP STACK WITH EXAMPLES Programming November 2, 2023 BENEFITS OF CONTRACTING OUT SOFTWARE DEVELOPMENT WORK TO INDIA Laravel October 24, 2023 WHY YOU SHOULD HIRE AN EXPERIENCED LARAVEL DEVELOPER FOR YOUR NEXT PROJECT JavaScript November 12, 2023 WHAT IS DOMAIN AND SUBDOMAIN IN WEBSITE DEVELOPMENT? * * November 4, 2023 IMPORTANCE OF WEBSITE IN BUSINESS November 2, 2023 WHY CHOOSE A LAMP STACK WITH EXAMPLES November 2, 2023 BENEFITS OF CONTRACTING OUT SOFTWARE DEVELOPMENT WORK TO INDIA October 24, 2023 WHY YOU SHOULD HIRE AN EXPERIENCED LARAVEL DEVELOPER FOR YOUR NEXT PROJECT November 12, 2023 WHAT IS DOMAIN AND SUBDOMAIN IN WEBSITE DEVELOPMENT? November 10, 2023 WHY SHOULD WE HAVE A WEBSITE FOR OUR BUSINESS AND HOW IT WILL BE HELPFUL IN OUR SALES? November 10, 2023 WHAT IS THE EASIEST WAY TO BUILD AN E-COMMERCE WEBSITE? November 9, 2023 HIRE LARAVEL DEVELOPER AT $5 PER HOUR November 5, 2023 WHAT IS SEO AND HOW SEP HELPS TO GROW OUR WEBSITE? November 4, 2023 WHY IS MY WEBSITE SLOW AND HOW TO OPTIMIZE IT FOR SMOOTH PERFORMANCE? November 4, 2023 IMPORTANCE OF WEBSITE IN BUSINESS November 2, 2023 WHY CHOOSE A LAMP STACK WITH EXAMPLES November 2, 2023 BENEFITS OF CONTRACTING OUT SOFTWARE DEVELOPMENT WORK TO INDIA October 24, 2023 WHY YOU SHOULD HIRE AN EXPERIENCED LARAVEL DEVELOPER FOR YOUR NEXT PROJECT November 12, 2023 WHAT IS DOMAIN AND SUBDOMAIN IN WEBSITE DEVELOPMENT? November 10, 2023 WHY SHOULD WE HAVE A WEBSITE FOR OUR BUSINESS AND HOW IT WILL BE HELPFUL IN OUR SALES? November 10, 2023 WHAT IS THE EASIEST WAY TO BUILD AN E-COMMERCE WEBSITE? November 9, 2023 HIRE LARAVEL DEVELOPER AT $5 PER HOUR Thanks For Reading Our Blog Post ARE YOU LOOKING FOR WEBSITE/APP DEVELOPMENT WILL DO IT FOR $5 PER HOUR Don't think too much let's begin. DETECT MOBILE OR DESKTOP IN LARAVEL REVERSE STRING IN PYTHON (6 DIFFERENT WAYS) RELATED ARTICLES WHAT’S NEW IN LARAVEL 7.12 May 23, 2020 LARAVEL-HOW TO USE INSTAGRAM FEED IN LARAVEL WITH EXAMPLE November 6, 2021 HOW TO ADD COLUMNS TO THE EXISTING TABLE IN LARAVEL THROUGH MIGRATION May 30, 2020 PAYTM PAYMENT GATEWAY INTEGRATION WITH LARAVEL 7 March 11, 2020 LEAVE A REPLY CANCEL REPLY Your email address will not be published. Required fields are marked * Comment * Name * Email * Website Save my name, email, and website in this browser for the next time I comment. Notify me of follow-up comments by email. Notify me of new posts by email. Δ Check Also Close * Laravel Run laravel project on different port March 19, 2022 Advertisement What Our Customer Speaks CodeHunger Private Limited 5.0 Based on 43 reviews review us on harsh singh 2 months ago I've been working with Codehunger for the past two years, and I'm consistently impressed with their level of expertise and commitment to client satisfaction. Their team is knowledgeable, professional, and always willing to go the extra mile.The software solutions they've provided have greatly improved our operational efficiency. Their products are robust, user-friendly, and they regularly roll out updates that enhance functionality.Moreover, their customer support is top-notch. Whenever we encounter an issue, their response time is remarkably quick, and they work diligently to find a solution. It's clear they genuinely care about their clients.Overall, I highly recommend Codehunger to any business in need of reliable, innovative IT solutions and exceptional customer service. swapnil krishna 2 months ago Code hunger is highly recommendable when it comes to timely delivery and hassle free diployment of the brief. They have the zeal to deliver as if it was all theirs only Nikita Mishra 2 months ago ramashish tomar 2 months ago I recently worked with codehunger team and they deliver a amazing website. swati kumari 2 months ago This evaluates the effectiveness, reliability, and performance of the software products developed by the codehunger.ThanksSwati Corebhr Technologies Pvt. Ltd. 2 months ago They have developed call managing software for our business, the software really help us to automate many of the task,Really love the task done by codehunger team Riddhi Roy 2 months ago I think codehunger is one of the best company to outsource project with them, unprecedented services provided by the team to deliver the work on time. Sumit kumar 2 months ago Best android app development company in patna, do the work at very reasonable cost. Shaiv Roy 2 months ago Working in codehunger since inception, I love the work life balance managed by the organization. Recent Posts * How to Boost Website SEO * As a React Native Developer, How can I Increase the Performance of an React Native App * Unleashing Success: The Power of Ecommerce Development Companies * What Developer Need To Do To Make the Website Run Smoothly? * How to Hire Experienced App Developer at Low Cost Our latest Works * * * * * * * * * Are you thinking of app development ? * Recent * Popular * Comments * How to Boost Website SEO 4 weeks ago * As a React Native Developer, How can I Increase the Performance of an React Native App 4 weeks ago * Unleashing Success: The Power of Ecommerce Development Companies November 16, 2023 * What Developer Need To Do To Make the Website Run Smoothly? November 14, 2023 * How to Hire Experienced App Developer at Low Cost November 14, 2023 * Learn Odia Language From Hindi January 14, 2021 * Benefits and application of OOP February 25, 2021 * Laravel-How to use Instagram feed in laravel with example November 6, 2021 * Convert numbers to words in laravel September 18, 2022 * Why PHP is known as a scripting language? October 13, 2021 * Mukesh Khatri I am getting this error on this line : $account = $instagram... * Himanshi Still facing same issue when followed the suggested steps to... * Himanshi Symfony \Component \Mailer \Exception \TransportException PH... * Jim Is there a way to get this to work for multiple forms?... * Naren Great. Thanks, it helped my project. Thank you again.... Subscribe to our channel Find us on Facebook Follow Us codehunger2 Social * Facebook * Twitter * LinkedIn * YouTube * GitHub * Instagram © Copyright 2023, All Rights Reserved | CodeHunger Blog * Facebook * Twitter * LinkedIn * YouTube * GitHub * Instagram Facebook Twitter LinkedIn Pinterest Share via Email Back to top button Close Search for: * Facebook * Twitter * LinkedIn * YouTube * GitHub * Instagram About Our Organizations CodeHunger is the website and App development Company on the other side we also give solution of programming problem step by step, even we provide video tutorial for complex program throug our youtube channel for the easy understanding. We post on Instagram and Facebook to help developers stay up to date with the latest technologies. Recent Posts * How to Boost Website SEO * As a React Native Developer, How can I Increase the Performance of an React Native App * Unleashing Success: The Power of Ecommerce Development Companies * What Developer Need To Do To Make the Website Run Smoothly? * How to Hire Experienced App Developer at Low Cost Close Search for WhatsApp us