Phalcon CLI Toolset


The Phalcon framework is absolutely amazing. If you dont know much about it already, go check it out here: phalconphp.com. The problem I found is that the CLI tools didn't do what I wanted them to do out the box, and thats Why I created this Tool set for the Phalcon CLI. Which again, can be found on github.

Basic usage

Firsly, install this using composer "danzabar/phalcon-cli": "1.x". Now it's installed lets build the application base, heres a quick example of that:

$app = new Danzabar\CLI\Application;

// Add your Tasks
$app->add(new MyTask);

try {

    $app->start($argv);

} catch(\Exception $e) {

    echo $e->getMessage();
    exit(255);
}

You can also pass a custom DI instance to the Application, but for ease it will create one if none is passed: new Danzabar\CLI\Application($di)

Writing Tasks

Tasks are classes that contain multiple commands, for example we could have a GitTask and that could have a push method with is the command. Take a look at this example task:

Class BasicTask extends \Danzabar\CLI\Tasks\Tasks
{
    // This will be the task name defined in the library.   
    protected $name = 'basic'; 

    protected $description = 'A basic task that does pretty much nothing';

    /**
     * Every task should have a main method, it will be the default
     * action that is called if no other is specified.
     *
     * We use the Annotation engine to specify which commands are actions. Make sure you include it on every action!
     *
     * @Action
     */
    public function main() 
    {
        $this->output->writeln("This is the main action");  
    }

    /**
     * @Action
     */
    public function other()
    {
        $this->output->writeln("This is the other action");
    }

}

If we wanted to call the main method of this task we could use:

php cli basic

But lets say we wanted to call the "other" method:

php cli basic:other

The annotation @Action lets the task prepper class know that this function is a command action and should be included on the helper tasks output.

Arguments and Options

You can add arguments and options to commands by using a setup function, there are two ways of doing this, lets have a look:

// This one will be used for the whole class unless a specific
// setup method is set.
public function setup() {
	
	$this->argument->addExpected('name', InputArgument::Required);
}
// This one will be specific to the "other" method as specified in the task class
public function setupOther() {
	
	$this->argument->addExpected('name', InputArgument::Required);
}

To use an argument or option in a task you can use $this->argument->key. Theres more documentation on using these in the github docs.

Helpers

The helper classes give you access to functionality like adding Questions, building Tables, Asking for Confirmation. You can also build your own helper classes and register them to be used within your tasks. Here is how you would do that:

class MyHelper extends Danzabar\CLI\Tasks\Helpers\Helper
{
    // Add your functionality.  
}

// When you are setting up the app, register your helper
$app = new Application;

$app->helpers()->registerHelper('myhelper', 'MyHelper');

// Now in your Task class you can load this to return an instance of your helper
$myHelper = $this->helpers->load('myhelper');

There are 3 helpers included in the CLI tools, they are, Questions, Tables, Confirmation, to use these you can use the helpers property like so:

Questions

$question = $this->helpers->load('question');

$answer = $question->ask("Do you like Questions?");

$answer = $question->choice("Pick one", Array('one', 'two'));

$answers = $question->multipleChoice('Pick two of these', Array('one', 'two', 'three'));

Tables

$table = $this->helpers->load('table');

$data = Array(
    0 => Array('Header' => 'value', 'Header2' => 'value2'),
    1 => Array('Header' => 'test', 'Header2' => 'value3')
);

$table->draw($data);

Confirmation

$confirmation = $this->helpers->load('confirm');

if($confirmation->confirm("Do you want to continue?"))
{
    // Confirmed
}

Testing Commands

I like being able to fully test a command, and it was something that I HAD to include in this toolset too, so there is a CommandTester class, which you can use to test all your commands.

$ct = new CommandTester;
$ct->add(new Task);
$ct->execute('task:action', $params);

You can get the output of the execution to analyse:

$ct->getOutput();

Heres an example of Mocking input for a task that expects user input.

$ct = new CommandTester;
$ct->setInput("Y\n");
$ct->execute('task:question');

$ct->getOutput();

If you have multiple questions you can also give multiple input

$ct->setInput("Y\nY\nY\n")

comments powered by Disqus