| 
<?php/**
 * Copyright  (c) 2015, Till Wehowski
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of frdl/webfan nor the
 *    names of its contributors may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY frdl/webfan ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL frdl/webfan BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
 namespace frdl\ApplicationComposer;
 
 
 
 
 class Console extends \frdl\aSQL\Engines\Terminal\CLI
 {
 
 
 public $App;
 
 public $strip_frdl = true;
 
 protected $out = array();
 protected $p; //pointer
 protected $statusText;
 
 protected $dir_cmds;
 protected $state;
 
 private $HALT = false;
 
 
 function __construct($strip_frdl = true){
 $this->strip_frdl = $strip_frdl;
 parent::__construct();
 $this->dir_cmds = __DIR__. DIRECTORY_SEPARATOR . 'Command' . DIRECTORY_SEPARATOR;
 }
 
 
 public function applyApp(&$app){
 $this->App = $app;
 return $this;
 }
 
 
 public function dump(){
 $out = $this->App->OutData();
 $out->statusText = htmlentities($this->statusText);
 return $out;
 }
 
 protected function _list_commands(){
 $commands = array();
 
 $dir =  $this->dir_cmds;
 foreach (new \DirectoryIterator($dir) as $fileInfo) {
 if($fileInfo->isDot()) continue;
 if(preg_match("/([a-z][a-z0-9\-\_\.]+)\.php/", $fileInfo->getFilename(), $matches) ){
 $commands[] = $matches[1];
 }
 
 }
 
 foreach($this->shell['commands'] as $cmd => $p){
 $commands[] = $cmd;
 }
 
 return $commands;
 }
 
 protected function cmd_help(){
 $av = '';
 $av .= 'Available commands: '.PHP_EOL;
 $i = 0;
 foreach($this->_list_commands() as $num=> $cmd){
 $i++;
 $av .= $cmd ."\t\t";
 
 if($i % 3 === 0){
 $av.=PHP_EOL;
 }
 }
 
 $r = new AjaxResult;
 $r->type = 'print';
 $r->out = $av;
 return $r;
 }
 
 public function HALT(){
 $this->HALT = true;
 $this->force_state('HALT');
 $this->statusText = 'STOPPED DUE TO THE HALT COMMAND!';
 $r = new AjaxResult;
 $r->type = 'print';
 $r->out = $this->statusText;
 return $r;
 }
 
 protected function boot(){
 $this->statusText = 'Booting cli...';
 $this->out = array();
 $this->p = NIL;
 
 $this->add_command('help', array($this, 'cmd_help'));
 $this->add_command('HALT', array($this, 'HALT'));
 
 }
 
 public function exe($cml = ''){
 global $argv;
 if(false !== $this->strip_frdl && 'frdl' === substr($cml,0,strlen('frdl')))$cml = substr($cml, strlen('frdl'), strlen($cml));
 $this->IN = ($this->mode === self::MODE_CLI) ? implode(self::DELIM, $argv) : urldecode($cml);
 $this->parse();
 
 /*$this->App->OutData('out', print_r($this->batch, true));*/
 $this->statusText = 'Parsing query...';
 $this->parseQuery();
 $this->statusText = 'Validating query...';
 $this->validateQuery('before');
 $this->statusText = 'Process batch...';
 
 
 foreach($this->batch as $num => $args){
 if(false !== $this->HALT || 'HALT' ===  $this->state)break;
 $this->statusText = 'Process command:>'.$args['command']['cmd'];
 $this->_exec($args);
 $this->statusText .= htmlentities(' :>Complete.');
 }
 
 $this->statusText = 'Batch run complete';
 
 
 return $this;
 }
 
 
 public function get_cmd_file($cmd){
 $file = $this->dir_cmds . $cmd . '.php';
 return  (file_exists($file)) ?  $file : false;
 }
 
 
 protected function _exec($args){
 if(false !== $this->HALT || 'HALT' ===  $this->state)return;
 $command = $args['command']['cmd'];
 $cmd_file = $this->get_cmd_file($command);
 
 $this->statusText = 'Invoke frdl command...';
 if(isset($this->shell['commands'][$command])
 && is_callable($this->shell['commands'][$command])){
 return $this->App->OutData(call_user_func($this->shell['commands'][$command], $args));
 }elseif(false !== $cmd_file){
 require $cmd_file;
 $classname = '\frdl\ApplicationComposer\Command\\'.$command;
 try{
 if(!is_subclass_of($classname, '\frdl\ApplicationComposer\Command\CMD')){
 \webdof\wResponse::status('409');
 die('Invalid CMD class in '.__METHOD__.' '.__LINE__);
 }
 $CMD = new $classname;
 return $this->App->OutData($CMD($this, $args));
 }catch(\Exception $e){
 return $this->App->OutData('out', 'Error: '.$e->getMessage());
 }
 
 }
 
 
 
 $this->statusText = 'Command not found: '.strip_tags($command);
 
 }
 
 protected function force_state($state){
 $this->state = (false === $this->HALT && ('HALT' !==  $this->state || 'HALT' === $state)) ? $state :  $this->state;
 if('HALT' === $this->state)$this->HALT = true;
 return $this;
 }
 
 public function parseQuery(){
 $this->statusText .= htmlentities(' ->Pre-Parsing batch [GLOBAL]');
 
 }
 
 public function validateQuery(){
 $args = func_get_args();
 $this->statusText .=  htmlentities('->skipped(@ToDo) [GLOBAL]');
 }
 
 public function add_command($command, callable $callable){
 $this->shell['commands'][$command] = $callable;
 return $this;
 }
 
 
 public function test()
 {
 header("Content-Type: text/plain");
 $cmd = 'frdl test -c --test=console --foo=bar; install
 ';
 
 
 $batch = $this->parse($cmd);
 echo 'Test command line:'."\n\n".$cmd."\n\n".'Parsed:'."\n"
 .print_r($batch,true);
 echo "\n";
 echo 'Unparsed:'."\n\n";
 $u =  $this->unparse($batch);
 echo $u;
 echo "\n";
 $batch = $this->parse($u);
 echo 'Test-Re-Parsing:'."\n"
 .print_r($batch,true);
 }
 
 }
 |