2016-04-13 01:19:22 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace NoccyLabs\Shell;
|
|
|
|
|
|
|
|
use NoccyLabs\Shell\LineRead;
|
|
|
|
|
|
|
|
abstract class Shell
|
|
|
|
{
|
2016-04-29 13:49:10 +00:00
|
|
|
protected $prompt;
|
2016-04-29 00:25:57 +00:00
|
|
|
|
|
|
|
protected $promptStyle;
|
|
|
|
|
|
|
|
protected $commandStyle;
|
|
|
|
|
2016-04-13 01:19:22 +00:00
|
|
|
public function __construct(array $config=[])
|
|
|
|
{
|
|
|
|
$this->configure($config);
|
|
|
|
}
|
|
|
|
|
|
|
|
abstract protected function configure(array $config);
|
|
|
|
|
2016-04-25 18:47:30 +00:00
|
|
|
public function addCommand($command, callable $handler=null)
|
2016-04-13 01:19:22 +00:00
|
|
|
{
|
2016-04-25 18:47:30 +00:00
|
|
|
if (!$handler) {
|
|
|
|
if (!($command instanceof Command)) {
|
|
|
|
throw new \RuntimeException("Handler is not callable nor a Command");
|
|
|
|
}
|
|
|
|
$command->setShell($this);
|
|
|
|
$this->commands[$command->getName()] = $command;
|
|
|
|
} else {
|
|
|
|
$this->commands[$command] = $handler;
|
|
|
|
}
|
2016-04-13 01:19:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function execute($command)
|
|
|
|
{
|
2016-04-25 18:47:30 +00:00
|
|
|
if (is_array($command)) {
|
|
|
|
foreach ($command as $cmd) {
|
|
|
|
$this->execute($cmd);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-13 01:19:22 +00:00
|
|
|
$buffer = str_getcsv($command, " ", "\"", "\\");
|
|
|
|
|
|
|
|
if (count($buffer)>0) {
|
2016-04-25 18:47:30 +00:00
|
|
|
$this->onCommand($buffer);
|
2016-04-13 01:19:22 +00:00
|
|
|
}
|
|
|
|
}
|
2016-04-25 18:47:30 +00:00
|
|
|
|
|
|
|
protected function onCommand($buffer)
|
|
|
|
{
|
|
|
|
$this->executeBuffer($buffer);
|
|
|
|
}
|
2016-04-13 01:19:22 +00:00
|
|
|
|
|
|
|
protected function executeBuffer(array $buffer)
|
|
|
|
{
|
|
|
|
$commandName = array_shift($buffer);
|
|
|
|
if (array_key_exists($commandName, $this->commands)) {
|
|
|
|
$command = $this->commands[$commandName];
|
2016-04-25 18:47:30 +00:00
|
|
|
if ($command instanceof Command) {
|
|
|
|
$command->run($buffer);
|
|
|
|
} else {
|
|
|
|
call_user_func_array($command,$buffer);
|
|
|
|
}
|
2016-04-13 01:19:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
$this->writeln("Bad command: ".$commandName);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function writeln($output)
|
|
|
|
{
|
|
|
|
echo "\r\e[K\e[0m".$output."\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function onUpdate()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-04-29 13:49:10 +00:00
|
|
|
public function setPrompt($prompt)
|
|
|
|
{
|
|
|
|
$this->prompt = $prompt;
|
|
|
|
}
|
|
|
|
|
2016-04-29 00:25:57 +00:00
|
|
|
public function setPromptStyle($style)
|
|
|
|
{
|
|
|
|
$this->promptStyle = $style;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setCommandStyle($style)
|
|
|
|
{
|
|
|
|
$this->commandStyle = $style;
|
|
|
|
}
|
|
|
|
|
2016-04-25 18:47:30 +00:00
|
|
|
public function run()
|
2016-04-13 01:19:22 +00:00
|
|
|
{
|
|
|
|
$lineRead = new LineRead();
|
2016-04-29 00:25:57 +00:00
|
|
|
|
|
|
|
$lineRead->setCommandStyle($this->commandStyle);
|
2016-04-13 01:19:22 +00:00
|
|
|
|
|
|
|
$this->running = true;
|
2016-04-25 18:47:30 +00:00
|
|
|
|
2016-04-13 01:19:22 +00:00
|
|
|
do {
|
2016-04-29 13:49:10 +00:00
|
|
|
$lineRead->setPrompt($this->prompt, $this->promptStyle);
|
2016-04-13 01:19:22 +00:00
|
|
|
$buffer = $lineRead->update();
|
2016-04-25 18:47:30 +00:00
|
|
|
if ($buffer == "\x03") {
|
|
|
|
$this->stop();
|
|
|
|
continue;
|
2016-04-13 01:19:22 +00:00
|
|
|
}
|
2016-04-25 18:47:30 +00:00
|
|
|
ob_start();
|
2016-04-13 01:19:22 +00:00
|
|
|
$this->onUpdate();
|
2016-04-25 18:47:30 +00:00
|
|
|
if ($buffer !== null) {
|
|
|
|
$this->execute($buffer);
|
|
|
|
}
|
2016-04-13 01:19:22 +00:00
|
|
|
$buf = ob_get_contents();
|
|
|
|
ob_end_clean();
|
|
|
|
if ($buf) {
|
|
|
|
$lineRead->erase();
|
2016-04-25 18:47:30 +00:00
|
|
|
echo str_replace("\n", "\r\n", rtrim($buf)."\n");
|
2016-04-13 01:19:22 +00:00
|
|
|
$lineRead->redraw();
|
|
|
|
}
|
2016-04-25 18:47:30 +00:00
|
|
|
usleep(10000);
|
2016-04-13 01:19:22 +00:00
|
|
|
} while ($this->running);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public function stop()
|
|
|
|
{
|
|
|
|
$this->running = false;
|
|
|
|
}
|
|
|
|
}
|