Create Custom Laravel Artisan Commands : Getting Started

Create Custom Laravel Artisan Commands : Getting Started

Next Topic will go through more advanced level

As a Laravel developer you should be knowing what artisan is and how great addon it is to laravel, but if you are not very familiar with this then now worries, we have you covered

What is Artisan ?

ArtIsan is a Command line interface to interact with your laravel based Project, it’s shipped already with default laravel installation and you can also add it manually if not. Artisan comes with a lot of helpful and great command which helps generate and scaffold your project logic files as well as project control.

All artisan command can be executed simply through any command line like follows:

php artisan {command-name} {command-arguments} {command-attributes}

To get list of available Artisan Commands you can run this command :

php artisan list

Now you know the basic of Artisan Commands, so why not make your own custom artisan commands.

Create your Custom Command

Creating your custom commands will greatly help you automate and enhance your development experience, so lets image we want to make a command that will help us change users password through console interface, so we begin by create our command class file, once again we can do this using artisan command :

php artisan make:command SetUserPasswordCommand

Here we use command make:command and we passed the argument that identify the class name of our command

Voila, your custom command class created successfully and you can found it under path : /app/Console/Commands

Here is our Blank Command Class Content Looks Like

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class SetUserPasswordCommand 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';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        return Command::SUCCESS;
    }
}

Lets Deep dive

$signature Property :

This Property is what tells laravel how you command should look like when executed, it’s like a Pattern that describe your command, so for example if we want our command to be called reset-password then the signature should be like this :

protected $signature = 'reset-password';

$description Property :

Consider this is the Help or description for your command, so make it meaningful and descriptive, and it’s just a string, that doesn’t affect how your command executes

protected $description = 'A Very Powerful command that helps you reset any user password through console';

But wait… where this description will appear ?

well you can check that using the artisan “help” command like this :

php artisan help reset-password

__construct() method :

This is just a regular class constructor method that runs just before executing your command logic.

handle() method :

This is the beating heart of your command, this the place where you command logic should reside, which means all logic procedures should be implemented there.

Now we know how this command structured but its actually doing nothing, and to be useful we need to accept arguments or parameters from the console to be more dynamic and responsive

Arguments

We need our Command to accept 2 Arguments (user email and the new password), if we try to just pass it when calling or command like this :

php artisan reset-password email@codersam.online TheNewPassword

as you may notice it will throw an Error

no-arguments-expected.png

Defining Arguments

That’s means we need to tell laravel that our command can except 2 arguments, and this is done by modifying command $signature as follows :

protected $signature = 'reset-password {email} {password}';

Defining Arguments should be enclosed with curly braces ( { } ), to identify that this is an argument that our command can accept, and between the curly braces we give our arguments a name so we can retrieve the argument value later.

Retrieve Arguments Values

Retrieving Arguments Value is very simple by calling the method argument, it accepts argument name as a parameter, so in our handle method we can retrieve values as follows :

public function handle()
{
    $email = $this->argument('email');
    $password = $this->argument('password');
    return Command::SUCCESS;
}

Output to Console

Now we can create a command, define arguments and also retrieve its values, but it will be so mystery if we can’t return a feedback to console to tell if something went successful or failed, so we need to output some messages to the console as a feedback.

The Legacy Echo

Of course as this is just a php code then you can use a simple echo to output some messages to console

public function handle()
{
  $email = $this->argument('email');
  $password = $this->argument('password');
  echo 'Email : '.$email;
  return Command::SUCCESS;
}

Sure it works but it’s not the best and beneficial way to output to console. Laravel Artisan comes with so many helpers to help interact with the console during command execution, we will learn about some of them just right now.

Info Output

We can output a info message with the helper method of info

$this->info('We Receive your Email and new Password');

Error Output

Display errors to console can be done using helper method error

$this->error('We cannot find a user associated with this email address');

Warning Output

You can add warning to console using helper method warn

$this->warn('Changing Password cannot be reverted later');

Alert Output

Displaying Alert can be done using helper method of alert

$this->alert('Changing Password in Progress');

Note : Alerts may seems same like Warning but actually it has more decorated like to bring more attention

Empty Lines Output

You may need to add Empty Lines like line breaks to space your outputs away, this can be done using helper method newLine

$this->newLine();

Note if you need to add more than one empty line then you can pass number of lines to this method

$this->newLine(3);

Let’s Implement our Command

Now we have all knowledge need to create our command, so let’s sum it up and implement our command login to be like so

public function handle()
{
  $email = $this->argument('email');
  $password = $this->argument('password');

  $user = User::where('email', $email)->first();

  if($user == null)
  {
    $this->error('Cannot find user associated with this email address');
    return Command::INVALID;
  }

  $user->password= bcrypt($password);
  $user->save();

  $this->info('User '.$user->name.' Password has been changed successfully');

  return Command::SUCCESS;
}

Note About Return

Note that Laravel expects the handle method to return an Integer value which indicates the status of the command execution and we have 3 statuses that we can return as they are defined as a constants in the base Command class : Command::SUCCESS , Command::FAILURE and Command::INVALID .

Final Code

<?php

namespace App\Console\Commands;

use App\Models\User;
use Illuminate\Console\Command;

class SetUserPasswordCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'reset-password {email} {password}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'A Very Powerful command that helps you reset any user password through console';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $email = $this->argument('email');
        $password = $this->argument('password');

        $user = User::where('email', $email)->first();

        if($user == null)
        {
            $this->error('Cannot find user associated with this email address');
            return Command::INVALID;
        }

        $user->password= bcrypt($password);
        $user->save();

        $this->info('User '.$user->name.' Password has been changed successfully');

        return Command::SUCCESS;
    }
}

Summary

In this tutorial we learned how to create our first Artisan command, Defining Arguments, Get Values, Display Feedback and Real world example of implementation.

In Next Part we will go more advanced with custom Artisan Commands and we will learn much more advanced features and techniques.

So if you have any questions or requests, please don’t hesitate to add it to comments below.