Skip to content

Building a new command(internal program)

felipenmoura edited this page Jul 26, 2012 · 3 revisions

Add a new command to be used inside mind3rd’s command line

Creating a program within mind3rd

It may look complicated in the first sight, but is simple.

First of all, create a .php file with the name of your command, inside the mind3rd/API/programs. Let's say the program we are creating is the Tutorial. Inside this file, your class(with the same name as the file) must extend MindCommand and implement program.

The program basics

You must set some basic attributes for your program to be valid. Create the method that will be called when your program is executed, let's call our method executableFunction. Let's just write an "echo" command into it, with a masseage of our will.

public function executableFunction(){
    echo "\n\nEXECUTED\n\n";
}

In your constructor, you should define the following attributes:

       $this->setCommandName('tutorial')
           // a short description of your command
           ->setDescription("This is a cool tutorial command")
           // use this if your class has NOT the same name as its file
           //->setFileName('theFileName')
           ->setHelp("A longer text, explaining the command")
           // the user must be autenticated to run this command?
           ->setRestrict(false)
           // the function that will be called when the command is executed
           // you can use the name of your public method, as well
           ->setAction(function($class){
               $class->executableFunction();
           });

All those methods are from the MindProgram, the extended class. The setAction may be defined like this:

->setAction('executableFunction'); // in this case, the method MUST be public

After setting those attributes to your program, you should initiate it by executing this:

$this->init();

By this time, if you just execute the mind on your console, and call the command tutorial you will see the output from your executableFunction.

Parameters

For each parameter your command will receive, you must create a public property. The reserved names for parameters are: command, name and answers. There are 3 types of arguments: argument, option and flag.

Arguments Arguments are mere strings or numbers passed to your program, separated by space(spaced strings can be passed between quote characters). Let's say our command should be called like this: _tutorial [name] [section] For example:

$ mind> _tutorial install 6

Let's imagine that the first parameter MUST be one of "install", "open" or "save", for example. Then we can define the first parameter like this:

$this->addRequiredArgument('name', // the argument name
                            // a description for the parameter
                            'first, and required argument',
                            // an optional list of options for it
                            Array('install', 'open', 'save'));

The third parameter is option, and is used to represent the list of possible options for that parameter. When not passed, the user can enter any data to this parameter.

Let's imagine the second argument is not required, so, we can define it like this:

$this->addOptionalArgument('section',
                           'This is the second and optional argument');

** Opptions ** Opptions are those parameters with which the user can send a specific value. Imagine our command was, instead, like this:

$ mind> tutorial -u felipe -p 19

We expect a user, and the page, for example, but let's say that the page is not required. So our instructions should be this way:

$this->addRequiredOption('user', // the parameter
                         '-u', // the shortcut
                         // a description for the parameter
                         'The user who will be passed for any reason',
                         // the default value for it
                         'anonymous');

That last parameter is the default value, in case the user did not send this option...that is not required, though. Just like for arguments, you can add an optional Option:

$this->addOptionalOption('page',
                         '-p',
                         'Should perform its action detailed?',
                         null);

Anytime, the user can both use the commando with --user or -u, as well as --page or -p.

** Flags ** Flags are parameters that just indicate if an option is true or false. Let's imagine our tutorial with the flag detailed. When passed, the tutorial shows extra details, otherwise, no.

$this->addFlag('detail', '-d', 'Shows details');

With that, the user will now be able to call the program like this:

$ mind> tutorial -d

Obviously, you can combine the arguments, options and flags to define exactly how you want your command to be.

Accessing the parameter values

Remember when I said that you had to have a public property for each parameter you would use? That's why. Inside our executableFunction, we can simply use the $this to access the specified parameters.

eg.:
$this->user;
$this->page; // true or false

Prompting

You can ask things to the user.

For HTTP request, the answers for the questions must be passed in the same requisition, along with the rest of arguments.

Prompting the user is pretty simple. You can just call it this way:

$this->prompt('name', "What's your name?");

And then, you can access the answer in the answers property.

$this->answers('name');

The prompt will keep asking the user for an answer until he types something. For secret values, like passwords, you can send the third parameter as boolean:

$this->prompt('pwd', 'Say the magic word!', true);

If you want to validate the entry with a list of available options, you can send and array with the list of valid options, as the third parameter:

$this->prompt('genre',
              "\nwhat is your genre?",
              Array('F'=>'Female',
                    'M'=>'Male'));

The descriptions and details for each parameter is automatically shown when the user calls your command using --help. Also, your command will be auto-completed as the user type it and use the TAB key.

Here, look at an example of this program we were working on until now:

class Tutorial extends MindCommand implements program
{
    public $article= null;
    public $user= null;
    public $detail= 0;

    public function executableFunction(){
        echo $this->article.": ";
        echo $this->user."\n";
        if($this->detail)
            echo "DETAILS\n";
        echo "EXECUTED\n\n";
    }

    public function __construct(){
        $this->setCommandName('tutorial')
            // a short description of your command
            ->setDescription("This is a cool tutorial command")
            // use this if your class has NOT the same name as its file
            //->setFileName('theFileName')
            ->setHelp("A longer text, explaining the command")
            // the user must be autenticated to run this command?
            ->setRestrict(false)
            // the function that will be called when the command is executed
            // you can use the name of your public method, as well
            ->setAction(function($class){
                $class->executableFunction();
            });

        $this->addRequiredArgument('article', // the argument name
                                   // a description for the parameter
                                   'first, and required argument',
                                   // an optional list of options for it
                                   Array('install', 'open', 'save'));

       $this->addOptionalOption('user', // the parameter
                                '-u', // the shortcut
                                // a description for the parameter
                                'The user who will be passed for any reason',
                                // the default value for it
                                'anonymous');

        // when the -d is passed, should show details
        $this->addFlag('detail', '-d', 'Shows details');

        $this->init();
    }
}

With this program, the user can call it, for example, in these ways:

$ mind> tutorial install
$ mind> tutorial install -d
$ mind> tutorial open -u felipe
$ mind> tutorial save -u felipe -d
$ mind> tutorial install --user felipe -d