Cli Prompts

Introduction

Prompts are needed in cli to obtain user information. The PHP STDIN makes it possible to obtain user inputs from the cli. After successfully retrieving an input, the input obtain can then be subjected to further validation. The cli class has two main methods for obtaining user inputs which are prompt() and q() methods.

Cli::prompt()
The prompt method is used when simple data is needed to be obtained from the cli. The first argument defines a list of options that must be matched by an input supplied while the second argument is a callback closure function that makes it possible to validate supplied inputs

Syntax: prompt
Cli::prompt($options, $callback, $terminate);

  where: 

    $options   : A list of options that must be matched 
    $callback  : A callback function that can be used to test values.
    $terminate : An optional argument to determines if invalid input should trigger a reprompt
    $new       : This is applied internally to determine a first use case of prompt.

                            


Example 1: prompt without arguments
    Cli::textView("Please input your name ", 0, 1);
  
    $name = Cli::prompt();
                              
In the above, the prompt method will wait to receive the user input once before terminating. Once the response is obtained, it will be stored inside the "$name" variable.

Example 2a: prompt with arguments
    $options= ['y', 'n'];
  
    Cli::textView("Will you like to continue? [Y/N] ", 0, 1);
  
    Cli::prompt($options, function($input, $options){
  
        $input = strtotlower($input);
  
        if(!in_array($input, $options)){
  
          Cli::textView("Will you like to continue? [Y/N] ", 0, 1);
  
        }
  
    });
                              

In the code above, the prompt will expect an input of "y" or "n". If an invalid input is supplied, the callback function will tell the prompt to re-ask the same question until a valid response is obtained. By default, prompt method is designed to continue prompting until a valid input is supplied. This behaviour is only applicable once arguments are defined on the method. However, this reprompt behaviour can be prevented by supplying a third argument of true on the prompt() method.

Example 2b: prompt with arguments
    $options= ['y', 'n'];
  
    Cli::textView("Will you like to continue? [Y/N] ", 0, 1);
  
    $response = Cli::prompt($options, function($input, $options){
  
        $input = strtotlower($input);
  
        if(!in_array($input, $options)){
  
          Cli::textView("Will you like to continue? [Y/N] ", 0, 1);
  
        }, true
  
    });
                              

In the example 2b above, the prompt will expect an input of "y" or "n". If an invalid input is supplied, the prompt will terminate and the last input entered will be forwarded to the "$response" variable. In certain situations, we might want to set the reprompt to a maximum number of trials. This is also possible by settin the third argument to a valid integer which tells the Cli that an invalid input is only allowed in the number of specified times.


Example 2c: specifying maximum number of failed trials.
    $options= ['y', 'n'];
  
    Cli::textView("Will you like to continue? [Y/N] ", 0, 1);
  
    $response = Cli::prompt($options, function($input, $options){
  
        $input = strtotlower($input);
  
        if(!in_array($input, $options)){
  
          Cli::textView("Will you like to continue? [Y/N] ", 0, 1);
  
        }, 3
  
    });
                              

In the example 2c above, the prompt will expect an input of "y" or "n". If an invalid input is supplied, the prompt continue to reprompt until the maximum number of trials is reached after which it will exit by returning the last response obtained.

Validating prompt responses

While the prompt method does some light validations, it also enables developers to perform advanced or custom validations on responses obtained using different relative methods such as Cli::promptIsMax() and Cli::promptInvalid().

The promptIsMax() returns true when the maximum number of trials is exhausted or reached while the promptIsValid() returns true when the last input supplied is not valid. Together, this methods can help developers to understand if a prompt was terminated and why it was terminated.

Example 3: validating responses
    $options= ['y', 'n'];
  
    Cli::textView("Will you like to continue? [Y/N] ", 0, 1);
  
    $response = Cli::prompt($options, function($input, $options){
  
        $input = strtotlower($input);
  
        if(!in_array($input, $options)){
  
          Cli::textView("Will you like to continue? [Y/N] ", 0, 1);
  
        }, 3
  
    });


    if( Cli::promptIsMax() && Cli::promptInvalid() ) {

      Cli::textView( Cli::error('maximum number of trials was exeeded!') 0, "1|2");

    } elseif( Cli::promptInvalid() ) {

      Cli::textView( Cli::error('invalid response obtained') 0, "1|2");      

    }else{

      Cli::textView( Cli::success('valid response obtained') 0, "1|2");  

    }
                              

The code above will expect a response of "y" or "n". If the input is valid then the success message will be printed. However, if the input obtained is invalid the error message will be displayed based on the type of error that occured.

Cli::q()
The q otherwise called the the "query" method is an advanced method for obtaining, testing and validating user inputs. It is advanced in its structure because it provides an environment for checking data at every level when it is obtained. The major difference between the cli::q() and Cli::prompt() is that the Cli::q() manages prompts in a quite effective and articualate way. The callback supplied on this method is expected to return an array with index keys of init, test, success, failed and max. Each of these keys are in turn used to handle input validations.

Syntax: Cli::q()
  Cli::q($options, $callback, $trials);
  
    where: 

      $options   : A list of options on which a manual test will be performed. 
      $callback  : A callback function for performing advanced validation.
      $trials    : Number of acceptable trials.
  
                            


Example 4a: query options
    $options= ['y', 'n'];
    
  
    $input = Cli::q($options, fn() => 

      [
        'init' => fn() => Cli::textView("Will you like to continue? [Y/N] ", 0, 1),

        'test' => function($options, $input, $counter) {

            return in_array( strtolower($input), $options );

         },

         'failed' => function($options, $input, $counter) {

            Cli::textView(Cli::error('invalid option supplied!'));

            return true;

         },

         'success' => function($options, $input, $counter) {

            Cli::textView(Cli::success('valid option supplied!'));

         },   

         'max' => function() {

            Cli::textView( Cli::error('maximum reached!') );
          
         }

      ], 3
      
    )
    
                              

In the code above, the init is first called which prints a text to the Cli. This action is followed by calling the test which is expected to return a bool of true or false. If the test fails and false is returned, the failed will be triggered if it was defined. However, if the test returns true, then the success key will be called if defined. Also, if the test fails and the failed callback returns true, then a reprompt will be made will will ensure that init is first called before the test is called. The max key is also triggered if the maximum number of trials is reached. It should be noted that while init, failed, success and max keys are optional, the test key must be defined.

The Cli::q() also has its own validation methods just like the Cli::prompt() method. These validation methods are Cli::qValid(), Cli::qFailed() and Cli::qmax()


Example 4b: query with validation methods
    $options = ['y', 'n'];
   
  
    $response = Cli::q($options, fn() => 

      [

        'init' => fn() =>  Cli::textView("Will you like to continue? [Y/N] ", 0, 1),

        'test' => fn($input, $options) => in_array(strtolower($input), $options),

        'failed' => function($input, $options){
          
          if( !Cli::qmax() ) return !in_array(strtolower($input), $options);

        } 


      ], 3
  
    });

    if(Cli::qValid()){

      Cli::textView( Cli::success('input is valid') , 0, "|2"  );

    }else{

      if(Cli::qmax()){

        Cli::textView( Cli::error('maximum trials reached!') , 0, "|2"  );
        
      }else{ 
        
        Cli::textView( Cli::error('invalid options supplied!') , 0, "|2" );

      }

    }
                              

In the example 4b above, the Cli::q() will expect an input of "y" or "n". If an invalid input is supplied, a reprompt will be made until the maximum number of trials is reached. Once the query prompt is completed, the response will be saved into "$response". The Cli::qvalid() will return true if the input was valid. The Cli::qmax() returns true if the maximum acceptable number of trials is reached. Also, athough the Cli::qFailed() was not used above, but it will also return true if the input supplied was invalid.