<?php
namespace Tlf;
class Cli {
/**
* The current working directory
*/
public $pwd;
/** map of command name to callable
*/
public $command_map = [];
/**
* the array of commands (for environments that have sub-commands)
*/
// public $commands;
/**
* The command being executed
*/
public $command = 'main';
/**
* The args to pass to your command's callable (key=>value array)
*/
public $args = [];
public function __construct($pwd = null, $argv = null){
$this->pwd = $pwd ?? $_SERVER['PWD'];
$this->argv = $argv ?? $_SERVER['argv'];
}
/**
* load standard inputs from cli
* @param $stdin (optional) array of arguments like `['filename', 'subcommand', '-option', 'option_value', '--flag', 'etc']`
* @default $stdin to $_SERVER['argv']
*/
public function load_stdin($stdin=null){
$stdin = $stdin ?? $this->argv;
$this->script = basename($stdin[0]);
if (!isset($stdin[1])||substr($stdin[1],0,1)=='-'){
$this->command = $this->command;
$slice = 1;
} else {
$this->command = $stdin[1];
$slice = 2;
}
$args = $this->parse_args(array_slice($stdin,$slice), $this->args);
$this->args = array_merge($this->args, $args);
}
public function parse_args($stdin_args, $args=[]){
$last_key = null;
foreach ($stdin_args as $arg){
if ($arg[0]=='-'){
if ($arg[1]=='-'){
$last_key= substr($arg,2);
$args[$last_key] = true;
continue;
}
$last_key = substr($arg,1);
if (!isset($args[$last_key])){
$args[$last_key] = null;
}
} else if ($last_key==null){
$args['--'][] = $arg;
} else {
if ($arg==='true')$arg = true;
else if ($arg === 'false')$arg = false;
if (is_array($args[$last_key])){
$args[$last_key][] = $arg;
} else {
$args[$last_key] = $arg;
}
$last_key = null;
}
}
return $args;
}
public function load_command($command, $callable){
$this->command_map[$command] = $callable;
}
public function load_inputs($args){
$this->args = array_merge($this->args, $args);
}
/**
* @param $command the name of the command to execute
* @param $args args to execute
*/
public function call_command(string $command, array $args=[]){
if (!isset($this->command_map[$command])){
echo 'Command "'.$command.'" does not exist.'."\n";
return;
}
$call = $this->command_map[$command];
$ret = $call($this, $args);
echo "\n";
return $ret;
}
/**
* Run the cli based on loaded inputs
*/
public function execute(){
return $this->call_command($this->command, $this->args);
}
}