Skip to content

Writing Commands

Leaf MVC and Leaf API come with a built-in command line interface named Aloe. This CLI is used to run commands and perform tasks like creating controllers, models, migrations, seeds, etc.

In addition to the built-in commands, you can also create your own commands. This is useful if you want to create a command that performs a specific task in your application.

Generating a command

The easiest way to create a command is to use the g:command command. This command will create a new command class in your app/console directory.

php leaf g:command CachePurge

This will create a CachePurgeCommand in the app/console directory. Instead of using the class name, you can also create commands using the command you want to run in your console like this:

php leaf g:command cache:purge

This will create a CachePurgeCommand in the app/console directory.

Using the g:command command also registers the commands in Aloe. This means you can run the command immediately after creating it.

Manually writing a command

If you don't use the g:command command, you can create a command manually. To do this, create a new class in your app/console directory and extend the Aloe\Command class. The class should also have $defaultName and $description properties.

The $defaultName property is the name of the command that will be used to run the command in the console. The $description property is a short description of what the command does.

The class should have a handle(). This method is called when the command is run in the console. The handle method should return 0 if the command was successful and 1 if it failed.

<?php

namespace App\Console;

use Aloe\Command;

class ExampleCommand extends Command
{
  protected static $defaultName = 'example';
  public $description = 'example command\'s description';
  public $help = 'example command\'s help';

  protected function config()
  {
    $this
      ->setArgument('argument', 'optional', 'argument description')
      ->setOption('option', 'o', 'required', 'option description');
  }

  protected function handle()
  {
    $this->comment(
      "example command's output {$this->argument('argument')} {$this->option('option')}"
    );

    return 0;
  }
}

Both Leaf MVC and Leaf API ship with an example command. You can find it in the app/console directory.

Symfony Console

Aloe is built on top of Symfony Console. This means you can use all of the features of Symfony Console in your commands. You can read more about Symfony Console here.

Registering Commands

By default, aloe cli registers all generated commands, however, if you create a command manually, you'll have to register it manually. There are also situations where a package might need you to register a command, it can also be done using same method.

To add your commands, open up the app/console/Commands.php file and return whatever commands you want to register.

<?php 

namespace App\Console;

class Commands
{
    /**
     * Register commands
     * 
     * @param $console
     * @return void
     * 
     */
    public static function register($console): void
    {
        $console->register([
            ExampleCommand::class,
        ]);
    }
}

An example command has already been registered, so you can follow this example. You can add as many commands as you want to register.

$console->register([
  \App\Console\AppCommand::class,
  \App\Console\AppCommand2::class,
  CustomPackage::commands()
]);

Command Arguments

Command arguments are values that are passed to the command when it is run in the console. For example, if you have a command named example and you run it like this:

php leaf example argument

The argument value is an argument that is passed to the command. You can access the argument in the config() method using the setArgument() method. It typically follows the same convention as symfony console's addArgument except that instead of passing in InputArgument::state, you just pass in the state as a string. For example, instead of InputArgument::REQUIRED, you just pass in "required", any case is supported.

protected function config()
{
  $this->setArgument('argument', 'required', 'argument description');
}

You can access the argument in the handle() method using the argument() method.

protected function handle()
{
  $this->comment("example command's output {$this->argument('argument')}");
}

Command Options

Command options are values that are passed to the command when it is run in the console. For example, if you have a command named example and you run it like this:

php leaf example --option=value

To add an option to your command, you can use the setOption() method in the config() method. It typically follows the same convention as symfony console's addOption except that instead of passing in InputOption::state, you just pass in the state as a string. For example, instead of InputOption::VALUE_REQUIRED, you just pass in "required", any case is supported.

protected function config()
{
  $this->setOption('option', 'o', 'required', 'option description');
}

You can access the option in the handle() method using the option() method.

protected function handle()
{
  $this->comment("example command's output {$this->option('option')}");
}

Command Input

Aloe makes it easier to grab the Symfony input object from anywhere in your command. This means that you don't have to pass in the $input variable to the handle() method. Instead, you can use the input() method.

public function handle()
{
  $input = $this->input();
  $name = $input->getArgument('name');
}

Command Output

Aloe makes it easier to grab and output text to the console from anywhere in your command. Unlike with symfony console, you don't have to pass in the $output variable to the handle() method. Instead, you can use ouput(), write(), writeln(), comment(), info(), error(), question() and link() methods.

output()

This method either outputs text in your console or returns the Symfony output object. If a value is passed into output(), it will write the value to the console.

public function handle()
{
  $this->output('Hello World');
}

If no value is passed into output(), it will return the Symfony output object.

public function handle()
{
  $output = $this->output();
  $output->writeln('This is output');
}

write()

This method writes text to the console. It is the same as the output()->write() method.

public function handle()
{
  $this->write('Hello World');
}

writeln()

This method writes text to the console and adds a new line. It is the same as the output()->writeln() method.

public function handle()
{
  $this->writeln('Hello World');
}

comment()

This method writes a comment styled message to the console and adds a new line. It is the same as the output()->writeln() method with the SymfonyStyle::COMMENT style.

public function handle()
{
  $this->comment('Hello World');
}

info()

This method writes an info styled message to the console and adds a new line. It is the same as the output()->writeln() method with the SymfonyStyle::INFO style.

public function handle()
{
  $this->info('Hello World');
}

error()

This method writes an error styled message to the console and adds a new line. It is the same as the output()->writeln() method with the SymfonyStyle::ERROR style.

public function handle()
{
  $this->error('Hello World');
}

question()

This method writes a question styled message to the console and adds a new line. It is the same as the output()->writeln() method with the SymfonyStyle::QUESTION style.

public function handle()
{
  $this->question('Hello World');
}

This method writes a link to the console and adds a new line.

public function handle()
{
  $this->link('https://leafphp.dev', 'Leaf PHP');
}

Command Questions

Aloe makes it easier to ask questions in your command. You can use the ask(), confirm(), askRaw(), autoComplete(), choice() and multiChoice() methods.

ask()

This method asks a question and returns the answer. It takes in 2 parameters:

  • the question to ask
  • the default answer (optional)
public function handle()
{
  $name = $this->ask('What is your name?', 'Leaf');
}

askRaw()

This is the same as the ask() method above, except that it does not trim the results that the user enters. Whatever the user enters is returned as is.

public function handle()
{
  $name = $this->askRaw('What is your name?', 'Leaf');
}

autoComplete()

This method allows you to ask a question and provide a list of values that the user can choose from. The user's answer will be auto-completed as they type if it matches one of the values in the list. It takes in 3 parameters:

  • the question to ask
  • the list of values to choose from
  • the default answer (optional)
public function handle()
{
  $name = $this->autoComplete('What is your name?', ['Leaf', 'PHP'], 'Leaf');
}

choice()

This method allows you to ask a question and provide a list of values that the user can choose from. The user must select one of the values in the list. It takes in 4 parameters:

  • the question to ask
  • the list of values to choose from
  • the error message to display if the user does not select one of the values in the list
  • the default answer (optional)
public function handle()
{
  $name = $this->choice('What is your name?', ['Leaf', 'PHP'], 'Please select a name');
}

multiChoice()

This method allows you to ask a question and provide a list of values that the user can choose from. The user must select one or more of the values in the list. It takes in 4 parameters:

  • the question to ask
  • the list of values to choose from
  • the error message to display if the user does not select one of the values in the list
  • the default answer (optional)
public function handle()
{
  $name = $this->multiChoice('What is your name?', ['Leaf', 'PHP'], 'Please select a name');
}

confirm()

This method asks a yes/no question and returns the answer. It takes in 2 parameters:

  • the question to ask
  • the default answer (optional)
public function handle()
{
  $name = $this->confirm('Are you sure?', 'yes');
}

secret()

This method asks a question but hides the keystrokes. It takes in 2 parameters:

  • the question to ask
  • use hidden fallback (optional)
$password = $this->secret('Confirm your password');

Aloe Installer

Aloe installer allows you to quickly install files and routes from your library into your Leaf MVC or Leaf API project's working directory.

Magic Copy

This method allows you to auto-magically copy all files and folders from a specified folder into Leaf workspace.

Aloe\Installer::magicCopy("package/to/install");

Consider the following directory structure:

C:.
└───Auth
    ├───controllers
    ├───routes
    └───views

To copy our controllers, routes and views, we simply need to point magicCopy to the auth directory.

\Aloe\Installer::magicCopy('package/Auth');

This will copy the sub directories in Auth to the app folder in the working directory. This is especially useful in team projects where you want to share resources with your team. You can simply create a package with the resources you want to share and then use magicCopy to copy them into the working directory.

Writing Commands has loaded