How to Make a Laravel Artisan Command to Install the Application
Today, we’ll look at how to make a custom artisan command that would install a Laravel application in one step. Wouldn’t it be great if you can share a Laravel project with your coworkers and they can set it up with a single command?
Laravel comes with Artisan, a sophisticated command-line interface that may help you develop your application. We will use Artisan to create a custom command for our application.
Let’s begin by creating a new Laravel application. If you have already installed Laravel installer, you can write in your terminal :
laravel new install-command
Or via Composer create-project:
composer create-project laravel/laravel install-command
Now, create an Artisan command inside your project directory:
php artisan make:command AppInstaller
This command will create an AppInstaller class in your App\Console\Commands namespace
your AppInstaller.php file will look like this:
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppInstaller extends Command |
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = ‘command:name’;
/**
* The console command description.
*
* @var string
*/
protected $description = ‘Command description’;
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
return 0;
}
}
We’ll now update the command signature:
protected $signature = ‘app:install
{–db-host=localhost : Database Host}
{–db-port=3306 : Port for the database}
{–db-database= : Name for the database}
{–db-username=root : Username for accessing the database}
{–db-password= : Password for accessing the database}’;
basically, we have created a command with some options for configuring the database.
The command description will now be changed into:
protected $description = ‘To install the application via CLI’;
we will add several functions that will be used in our handle method.
Because our operation is simple and we have used some default arguments above, the only option that is necessary is DB_DATABASE because DB_USERNAME is root, DB_HOST is localhost, DB_PORT is 3306 and DB_PASSWORD may be an empty string by default.
public function missingRequiredOptions()
{
return !$this->option(‘db-database’);
}
We’ll use this function to update our .env file, as the name implies.
public static function updateEnv($data)
{
$env = file_get_contents(base_path(‘.env’));
$env = explode(“\n”, $env);
foreach ($data as $dataKey => $dataValue) {
$alreadyExistInEnv = false;
foreach ($env as $envKey => $envValue) {
$entry = explode(‘=’, $envValue, 2);
// Check if exists or not in env file
if ($entry[0] == $dataKey) {
$env[$envKey] = $dataKey . ‘=’ . $dataValue;
$alreadyExistInEnv = true;
} else {
$env[$envKey] = $envValue;
}
}
// add the variable if not exists in env
if (!$alreadyExistInEnv) {
$env[] = $dataKey . ‘=’ . $dataValue;
}
}
$env = implode(“\n”, $env);
file_put_contents(base_path(‘.env’), $env);
return true;
}
This function will be used to copy the .env.example file to the .env file.
public static function copyEnvExampleToEnv()
{
if (!is_file(base_path(‘.env’)) &&
is_file(base_path(‘.env.example’))) {
File::copy(base_path(‘.env.example’), base_path(‘.env’));
}
}
to generate the APP_KEY.
public static function generateAppKey()
{
Artisan::call(‘key:generate’);
}
to run migrations and seeders.
public static function runMigrationsWithSeeders()
{
try {
Artisan::call(‘migrate:fresh’, [‘–force’ => true]);
Artisan::call(‘db:seed’, [‘–force’ => true]);
} catch (\Exception $e) {
return false;
}
return true;
}
Finally, from the given command options, change the .env file.
public function updateEnvVariablesFromOptions()
{
$this->updateEnv([
‘DB_HOST’ => $this->option(‘db-host’),
‘DB_PORT’ => $this->option(‘db-port’),
‘DB_DATABASE’ => $this->option(‘db-database’),
‘DB_USERNAME’ => $this->option(‘db-username’),
‘DB_PASSWORD’ => $this->option(‘db-password’),
]);
$conn = config(‘database.default’, ‘mysql’);
$dbConfig = Config::get(“database.connections.$conn”);
$dbConfig[‘host’] = $this->option(‘db-host’);
$dbConfig[‘port’] = $this->option(‘db-port’);
$dbConfig[‘database’] = $this->option(‘db-database’);
$dbConfig[‘username’] = $this->option(‘db-username’);
$dbConfig[‘password’] = $this->option(‘db-password’);
Config::set(“database.connections.$conn”, $dbConfig);
DB::purge($conn);
DB::reconnect($conn);
}
and in our handle method.
public function handle()
{
if ($this->missingRequiredOptions()) {
$this->error(‘Missing required options’);
$this->line(‘please run’);
$this->line(‘php artisan app:install –help’);
$this->line(‘to see the command usage.’);
return 0;
}
$this->alert(‘Application is installing…’);
static::copyEnvExampleToEnv();
$this->generateAppKey();
$this->updateEnvVariablesFromOptions();
$this->info(‘Env file created successfully.’);
$this->info(‘Runnning migrations and seeders…’);
if (!static::runMigrationsWithSeeders()) {
$this->error(‘Your database credentials are wrong!’);
return 0;
}
$this->alert(‘Application is installed successfully.’);
return 1
}
We begin by copying .env.example to the .env file, then generate APP_KEY, update the .env file using the options specified while running the command, and then run migrations and seeders.
This is how your AppInstaller.php file should now appear.
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
use Illuminate\Support\Facades\File; | |
use Illuminate\Support\Facades\Artisan; | |
use Illuminate\Support\Facades\Config; | |
use Illuminate\Support\Facades\DB; | |
class AppInstaller extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = ‘app:install | |
{–db-host=localhost : Database Host} | |
{–db-port=3306 : Port for the database} | |
{–db-database= : Name for the database} | |
{–db-username=root : Username for accessing the database} | |
{–db-password= : Password for accessing the database, it can be blank} | |
‘; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = ‘To install the application via CLI’; | |
/** | |
* Execute the console command. | |
* | |
* @return int | |
*/ | |
public function handle() | |
{ | |
if ($this->missingRequiredOptions()) { | |
$this->error(‘Missing required options’); | |
$this->line(‘please run’); | |
$this->line(‘php artisan app:install –help’); | |
$this->line(‘to see the command usage.’); | |
return 0; | |
} | |
$this->alert(‘Application is installing…’); | |
static::copyEnvExampleToEnv(); | |
$this->generateAppKey(); | |
$this->updateEnvVariablesFromOptions(); | |
$this->info(‘Env file created successfully.’); | |
$this->info(‘Runnning migrations and seeders…’); | |
if (!static::runMigrationsWithSeeders()) { | |
$this->error(‘Your database credentials are wrong!’); | |
return 0; | |
} | |
$this->alert(‘Application is installed successfully.’); | |
return 1; | |
} | |
public function missingRequiredOptions() | |
{ | |
return !$this->option(‘db-database’); | |
} | |
public static function copyEnvExampleToEnv() | |
{ | |
if (!is_file(base_path(‘.env’)) && is_file(base_path(‘.env.example’))) { | |
File::copy(base_path(‘.env.example’), base_path(‘.env’)); | |
} | |
} | |
public static function generateAppKey() | |
{ | |
Artisan::call(‘key:generate’); | |
} | |
public function updateEnvVariablesFromOptions() | |
{ | |
$this->updateEnv([ | |
‘DB_HOST’ => $this->option(‘db-host’), | |
‘DB_PORT’ => $this->option(‘db-port’), | |
‘DB_DATABASE’ => $this->option(‘db-database’), | |
‘DB_USERNAME’ => $this->option(‘db-username’), | |
‘DB_PASSWORD’ => $this->option(‘db-password’), | |
]); | |
$conn = config(‘database.default’, ‘mysql’); | |
$dbConfig = Config::get(“database.connections.$conn”); | |
$dbConfig[‘host’] = $this->option(‘db-host’); | |
$dbConfig[‘port’] = $this->option(‘db-port’); | |
$dbConfig[‘database’] = $this->option(‘db-database’); | |
$dbConfig[‘username’] = $this->option(‘db-username’); | |
$dbConfig[‘password’] = $this->option(‘db-password’); | |
Config::set(“database.connections.$conn”, $dbConfig); | |
DB::purge($conn); | |
DB::reconnect($conn); | |
} | |
public static function updateEnv($data) | |
{ | |
$env = file_get_contents(base_path(‘.env’)); | |
$env = explode(“\n”, $env); | |
foreach ($data as $dataKey => $dataValue) { | |
$alreadyExistInEnv = false; | |
foreach ($env as $envKey => $envValue) { | |
$entry = explode(‘=’, $envValue, 2); | |
// Check if exists or not in env file | |
if ($entry[0] == $dataKey) { | |
$env[$envKey] = $dataKey . ‘=’ . $dataValue; | |
$alreadyExistInEnv = true; | |
} else { | |
$env[$envKey] = $envValue; | |
} | |
} | |
// add the variable if not exists in env | |
if (!$alreadyExistInEnv) { | |
$env[] = $dataKey . ‘=’ . $dataValue; | |
} | |
} | |
$env = implode(“\n”, $env); | |
file_put_contents(base_path(‘.env’), $env); | |
return true; | |
} | |
public static function runMigrationsWithSeeders() | |
{ | |
try { | |
Artisan::call(‘migrate:fresh’, [‘–force’ => true]); | |
Artisan::call(‘db:seed’, [‘–force’ => true]); | |
} catch (\Exception $e) { | |
return false; | |
} | |
return true; | |
} | |
} |
now for running the Artisan Command in your terminal use the given command below:
php artisan app:install –db-database=YOUR_DB_NAME –db-username=YOUR_DB_USERNAME –db-password=YOUR_DB_PASSWORD
Below is the GitHub Repository: