132 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace NoccyLabs\Shell;
 | 
						|
 | 
						|
use NoccyLabs\Shell\LineRead;
 | 
						|
 | 
						|
abstract class Shell
 | 
						|
{
 | 
						|
    protected $prompt;
 | 
						|
 | 
						|
    protected $promptStyle;
 | 
						|
    
 | 
						|
    protected $commandStyle;
 | 
						|
 | 
						|
    public function __construct(array $config=[])
 | 
						|
    {
 | 
						|
        $this->configure($config);
 | 
						|
    }
 | 
						|
 | 
						|
    abstract protected function configure(array $config);
 | 
						|
 | 
						|
    public function addCommand($command, callable $handler=null)
 | 
						|
    {
 | 
						|
        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;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function execute($command)
 | 
						|
    {
 | 
						|
        if (is_array($command)) {
 | 
						|
            foreach ($command as $cmd) {
 | 
						|
                $this->execute($cmd);
 | 
						|
            }
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        $buffer = str_getcsv($command, " ", "\"", "\\");
 | 
						|
 | 
						|
        if (count($buffer)>0) {
 | 
						|
            $this->onCommand($buffer);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    protected function onCommand($buffer)
 | 
						|
    {
 | 
						|
        $this->executeBuffer($buffer);
 | 
						|
    }
 | 
						|
 | 
						|
    protected function executeBuffer(array $buffer)
 | 
						|
    {
 | 
						|
        $commandName = array_shift($buffer);
 | 
						|
        if (array_key_exists($commandName, $this->commands)) {
 | 
						|
            $command = $this->commands[$commandName];
 | 
						|
            if ($command instanceof Command) {
 | 
						|
                $command->run($buffer);
 | 
						|
            } else {
 | 
						|
                call_user_func_array($command,$buffer);
 | 
						|
            }
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        $this->writeln("Bad command: ".$commandName);
 | 
						|
    }
 | 
						|
 | 
						|
    public function writeln($output)
 | 
						|
    {
 | 
						|
        echo "\r\e[K\e[0m".$output."\n";
 | 
						|
    }
 | 
						|
    
 | 
						|
    protected function onUpdate()
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    public function setPrompt($prompt)
 | 
						|
    {
 | 
						|
        $this->prompt = $prompt;
 | 
						|
    }
 | 
						|
 | 
						|
    public function setPromptStyle($style)
 | 
						|
    {
 | 
						|
        $this->promptStyle = $style;
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function setCommandStyle($style)
 | 
						|
    {
 | 
						|
        $this->commandStyle = $style;
 | 
						|
    }
 | 
						|
 | 
						|
    public function run()
 | 
						|
    {
 | 
						|
        $lineRead = new LineRead();
 | 
						|
        
 | 
						|
        $lineRead->setCommandStyle($this->commandStyle);
 | 
						|
 | 
						|
        $this->running = true;
 | 
						|
 | 
						|
        do {
 | 
						|
            $lineRead->setPrompt($this->prompt, $this->promptStyle);
 | 
						|
            $buffer = $lineRead->update();
 | 
						|
            if ($buffer == "\x03") {
 | 
						|
                $this->stop();
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
            ob_start();
 | 
						|
            $this->onUpdate();
 | 
						|
            if ($buffer !== null) {
 | 
						|
                $this->execute($buffer);
 | 
						|
            }
 | 
						|
            $buf = ob_get_contents();
 | 
						|
            ob_end_clean();
 | 
						|
            if ($buf) {
 | 
						|
                $lineRead->erase();
 | 
						|
                echo str_replace("\n", "\r\n", rtrim($buf)."\n");
 | 
						|
                $lineRead->redraw();
 | 
						|
            }
 | 
						|
            usleep(10000);
 | 
						|
        } while ($this->running);
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    public function stop()
 | 
						|
    {
 | 
						|
        $this->running = false;
 | 
						|
    }
 | 
						|
}
 |