Creating Installer of your Laravel Project

devquora
devquora

Posted On: Nov 17, 2022

Creating Installer of your Laravel Project

 

Creating Installer of Laravel Project to automate basic tasks of the project

In this article, I am going to show you how to create an installer of Laravel project to automate basic tasks.

When you are working on a Laravel project there is some basic setup that needs to be done for each install of the project.

  • Giving Permissions for "bootstrap/cache", "storage", "vendor" folder
  • composer install / composer update
  • Copying .env.example to .env
  • Key generation
  • Migration & Seeding
  • NPM install

Instead of asking your user to do these steps we can create an installer for doing this task. In this blog, we are going to learn to create the installer for Laravel projects. We will use a shell script to do this.

Step 1: Setting Permissions for different folders

The general permission for folders should be 775. The command for this will be:

sudo chmod -R 775 storage/ bootstrap/cache/ vendor/

Note: If there is any issue you can try with permission 777 [Not Recommended], or you can do this step manually to avoid any issues in the future.

Step 2: Installing Composer dependency

The command to do this is:

composer install

Step 3: Setting up .env

The commands that we need to do this are,

cp .env.example .env

# This line is here because we will update .env from command line

sudo chmod 777 .env

Step 4: Setting Up DB, Migrations & Seeding

For this, we will create a Laravel Console command. For more on Laravel Console please follow official documentation.

Let's look at the code below and then we will understand how each method is working

namespace App\Console\Commands;
 
use Illuminate\Console\Command;
use DB;
 
class InstallAppliction extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'application:install';
 
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'This will install the application & set up DB';
 
    /**
     * Create a new command instance.
     *
     * @return void|mixed
     */
    public function __construct()
    {
        parent::__construct();
    }
 
    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->line("You can use Ctrl+C to exit the installer any time.\n");
        $this->createDatabase();
        $this->migrate();
        $this->seed();
        $this->setUpKey();
    }
 
    /** 
     * This method creates the database by taking inputs from the user. 
     * 
     * @return void 
    */
    private function createDatabase(){
        if($this->testDbConnection()){
            return;
        }
 
        $this->line("You need to choose a database type.");
 
        install_database:
 
        $connection = null;
        $host = null;
        $port = null;
        $database = null;
        $username = null;
        $password = null;
 
        $available_connections = array_keys(config('database.connections'));
        $connection = $this->choice('Choose a connection type', $available_connections);
 
        if($connection == "sqlite"){
            $path = database_path('database.sqlite');
            touch($path);
            $this->info('Database file created at ' . $path);
        } else{
            $defaultPort = $connection == "mysql" ? 3306 
                               : ($connection == "pgsql" ? 5432 : null);
 
            $host = $this->ask('Database host', 'localhost');
            $port = $this->ask('Database port', $defaultPort);
            $database = $this->ask('Database name');
            $username = $this->ask('Database username');
            $password = $this->secret('Database password');
        }
 
        $settings = compact('connection', 'host', 'port', 'database', 'username', 'password');
        $this->updateEnvironmentFile($settings);
 
        if(!$this->testDbConnection()){
            $this->error('Could not connect to database.');
            goto install_database;
        }
    }
 
    /** 
     * This method is to test the DB connection. 
     * 
     * @return boolean 
    */
    private function testDbConnection(){
        $this->line('Checking DB connection.');
 
        try{
            DB::connection(DB::getDefaultConnection())->reconnect();
        }catch(\Exception $e){
            return false;
        }
 
        $this->info('Database connection working.');
        return true;
    }
 
    /**
     * Updates the environment file with the given database settings.
     *
     * @param  string  $settings
     * @return void
     */
    private function updateEnvironmentFile($settings)
    {
        $env_path = base_path('.env');
        DB::purge(DB::getDefaultConnection());
 
        foreach($settings as $key => $value){
            $key = 'DB_' . strtoupper($key);
            $line = $value ? ($key . '=' . $value) : $key;
            putenv($line);
            file_put_contents($env_path, preg_replace(
                '/^' . $key . '.*/m',
                $line,
                file_get_contents($env_path)
            ));
        }
 
        config()->offsetSet("database", include(config_path('database.php')));
 
    }
 
    /** 
     * Migrate the Database. 
     * 
     * @return void 
    */
    private function migrate(){
        $this->line("\nStarting DB Migration...");
        $this->call('migrate');
    }
 
    /** 
     * Seeds the Database. 
     * 
     * @return void 
    */
    private function seed(){
        $this->line("\nStarting DB Seeding...");
        $this->call('db:seed');
    }
 
    /** 
     * Sets up the application key. 
     * 
     * @return void 
    */
    private function setUpKey(){
        $this->call('key:generate');
        $this->info("\nApplication installation completed!");
    }
}

handle: This method is the starting point of this command. This method prints a line and then call other methods for installation.

createDatabase: This method is responsible for creating the database. This method checks the DB connection first if the connection is successful then it returns as DB is already set up. If DB connection is not set up then it asks for DB username password port etc and sets up the DB. This method uses ask and secret method provided by Laravel Console. Also if you see closely you will find “install_database;“, which is a goto label defining the section for installing the database. After getting input from the user we will try to connect to the DB again if it works we will return to the handle method else we will again come back to this section to start the DB install process all over again.

testDbConnection: This method tests the default DB connection and returns the result.

updateEnvironmentFile: This method takes a key value array and replace the values for all the keys in .env file using string pattern matching.

migrate: This method starts the DB migration process.

seed: This method starts the DB seeding process.

setUpKey: This method sets up the environment key.

This file needs to be called from the shell script. For this add the following to the script.

php artisan application:install

Step 5: Running NPM install

For installing node packages add this to the installation shell script.

npm install

So, the shell script will look like the following :

#!/bin/sh

#Update the folder permissions
sudo chmod -R 775 storage/ bootstrap/cache/ vendor/

# Install Composer Dependency
composer install

# Copy .env.example to .env
cp .env.example .env

# Update permission for .env
# This line is here because we will update .env from command line
sudo chmod 777 .env

#Start the installation process
php artisan application:install

# Install node dependency
npm install

Ok. So we have the installation script ready. Save it as installer.sh in the root directory of the project. We can commit this to SCM[GIT/SVN].

Now whenever someone downloads the project source code we will have this installer.sh present. We just need to execute the script and our project will be ready to use.

To execute this script we will have to run the following commands after downloading the project

sudo chmod +x installer.sh
sudo ./installer.sh

Now the rest will be taken care of by this script. You can modify the script / InstallApplication code as per your project needs.

Thank you!

 

    Please Login or Register to leave a response.

    Related Articles

    Laravel Tutorials

    Laravel 5.5 Middleware Complete Tutorial

    In Laravel, you can think middleware as a system or tool that are used to filter all HTTP requests entering your application. Middleware works between request and response of our application. It sits ..

    Laravel Tutorials

    Laravel Pagination Ajax

    Creating Ajax based pagination is Laravel 5.6. Ajax (Asynchronous JavaScript and XML) is a technique to update a specific part of webpage asynchronously without reloading the page. In this article, we..

    Laravel Tutorials

    Laravel Pagination

    According to Wikipedia Pagination is a process of separating or dividing a document or digital contents into discrete pages. In Core PHP and other frameworks, paginating record is a painful task. Lara..