bashfile=$bashfile; $this->config = (object)$config; $this->root = $root; $this->path = $path; $this->path = str_replace('${HOME}', getenv('HOME'), $this->path); if($this->path !== getcwd()){ chdir($this->path); } } // public function __destruct() { // $_SESSION[self::SESSIONKEY]['cwd'] = getcwd(); // } private static function session_started(){ // return $this->Shield->session_started(); if ( \php_sapi_name() !== 'cli' ) { if ( version_compare(phpversion(), '5.4.0', '>=') ) { return session_status() === \PHP_SESSION_ACTIVE ? true : false; } else { return session_id() === '' ? false : true; } } return false; } private function shell_exec($code) { return shell_exec($code); } // ------------------------------------------------------------------------ private function exec($code) { exec($code, $result); return implode("\n", $result); } // ------------------------------------------------------------------------ public function uniq_id() { return md5(array_sum(explode(" ", microtime())) * time()); } // ------------------------------------------------------------------------ public function system($code) { ob_start(); system($code); $result = ob_get_contents(); ob_end_clean(); return $result; } // ------------------------------------------------------------------------ public function mysql_close($id) { if (isset($_SESSION[self::SESSIONKEY]['mysql']) && isset($_SESSION[self::SESSIONKEY]['mysql'][$id])) { unset($_SESSION[self::SESSIONKEY]['mysql'][$id]); return true; } return false; } // ------------------------------------------------------------------------ public function mysql_connect($username, $password, $db_name, $host = 'localhost') { $db = $this->_mysql_connect($username, $password, $db_name, $host); if (!isset($_SESSION[self::SESSIONKEY]['mysql'])) { $_SESSION[self::SESSIONKEY]['mysql'] = array(); } $resource_id = $this->uniq_id(); $_SESSION[self::SESSIONKEY]['mysql'][$resource_id] = array( 'username' => $username, 'password' => $password, 'host' => $host, 'db' => $db_name ); return $resource_id; } // ------------------------------------------------------------------------ public function sqlite_query($filename, $query) { $db = new PDO('sqlite:' . $filename); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $res = $db->query($query); if ($res) { if (preg_match("/^\s*INSERT|UPDATE|DELETE|ALTER|CREATE|DROP/i", $query)) { return $res->rowCount(); } else { return $res->fetchAll(PDO::FETCH_ASSOC); } } else { throw new Exception("Coudn't open file"); } } // ------------------------------------------------------------------------ public function mysql_query($resource_id, $query) { if (!isset($_SESSION[self::SESSIONKEY]['mysql'])) { throw new Exception("Not mysql sessions found"); } if (!isset($_SESSION[self::SESSIONKEY]['mysql'][$resource_id])) { throw new Exception("Invalid resource id"); } $data = $_SESSION[self::SESSIONKEY]['mysql'][$resource_id]; $db = $this->_mysql_connect($data['username'], $data['password'], $data['db'], $data['host']); $res = $db->query($query); if ($res) { if (preg_match("/^\s*INSERT|UPDATE|DELETE|ALTER|CREATE|DROP/i", $query)) { return $res->rowCount(); } else { return $res->fetchAll(PDO::FETCH_ASSOC); } } else { throw new Exception("Query Error"); } } // ------------------------------------------------------------------------ private function _mysql_connect($username, $password, $db, $host = 'localhost') { $opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); $db = new PDO("mysql:host={$host};dbname={$db};charset=utf8mb4", $username, $password, $opts); return $db; } // ------------------------------------------------------------------------ private function unbuffer($command, $shell_fn) { if (preg_match("/which unbuffer/", $command)) { return $command; } else { $path = preg_replace("/\s$/", "", $this->$shell_fn("which unbuffer")); if (empty($path)) { return $command; } else { return $path . " " . $command; } } } // ------------------------------------------------------------------------ public function command(string $command,string $path, $shell_fn) :?array { if (!method_exists($this, $shell_fn)) { throw new Exception("Invalid shell '$shell_fn'"); } $marker = 'XXXX' . md5(time()); if ($this->config->is_windows) { $pre = "@echo off\ncd /D $path\n"; $post = "\necho '$marker'%cd%"; $command = $pre . $command . $post; $file_name = "tmp.bat"; $file = fopen($file_name, "w"); fwrite($file, $command); fclose($file); $result = preg_replace("/\r/", "", $this->$shell_fn($file_name)); unlink($file_name); $result = \sapi_windows_cp_conv(\sapi_windows_cp_get('oem'), 65001, $result); $output = preg_split("/\n?'".$marker."'/", $result); if (count($output) == 2) { $cwd = preg_replace("/\n$/", '', $output[1]); } else { $cwd = $path; } return array( 'output' => preg_replace("/\n$/", "", $output[0]), 'cwd' => $cwd ); } $command = preg_replace("/&\s*$/", ' >/dev/null & echo $!', $command); $home = $this->root; // $cmd_path = __DIR__; $bashDir = dirname($this->bashfile); $bashFile = basename($this->bashfile); $pre = "$bashDir $bashFile\nexport HOME=\"$home\"\ncd $path;\n"; //$post = ";echo -n \"$marker\";pwd"; $post = (''===$command) ? "echo -n \"$marker\";pwd" : ";echo -n \"$marker\";pwd"; $command = escapeshellarg($pre . $command . $post); $command = $this->unbuffer('/bin/bash -c ' . $command . ' 2>&1', $shell_fn); $result = $this->$shell_fn($command); /* return array( 'output' => $command, 'cwd' => $this->path ); */ if (preg_match("%>/dev/null & echo $!$%", $command)) { return array( 'output' => '[1] ' . $result, 'cwd' => $path ); } else if ($result) { // work wth `set` that return BASH_EXECUTION_STRING $output = preg_split('/'.$marker.'(?!")/', $result); if (count($output) == 2) { $cwd = preg_replace("/\n$/", '', $output[1]); } else { $cwd = $path; } $output[0] = preg_replace("/\n$/", "", $output[0]); return array( 'output' => preg_replace("/" . preg_quote($post) . "/", "", $output[0]), 'cwd' => $cwd ); } else { throw new Exception("Internal error, shell function give no result"); } } // ------------------------------------------------------------------------ public function cd($path): array { $this->path = $path; ////chdir($this->path); // $command = sprintf('cd %s', $this->path); // $result = $this->shell($command); $oldPath = getcwd(); if(file_exists($this->path) && is_dir($this->path) && !chdir($this->path)){ $_path = rtrim($oldPath, '\\/').\DIRECTORY_SEPARATOR. ltrim($this->path, '\\/'); if(file_exists($_path) && is_dir($_path) && !chdir($_path)){ throw new \Exception('Cannot cd '.$this->path); } // throw new \Exception('Cannot cd '.$this->path); } $this->path = getcwd(); //if(is_dir($this->path) && (is_readable($this->path) || is_writeable($this->path)) ){ $_SESSION[self::SESSIONKEY]['cwd'] = $this->path; //}else{ // chdir($oldPath); //} /* return array( 'cwd' => $this->path, 'result' => $result, ); */ return array( 'cwd' => $this->path, //'output' => $result['output'], 'output' => $this->path, ); } // ------------------------------------------------------------------------ public function dir($path): array { // using shell since php can restric to read files from specific directories $EXEC = 'X'; $DIR = 'D'; $FILE = 'F'; // depend on GNU version of find (not tested on different versions) $cmd = "find . -mindepth 1 -maxdepth 1 \\( -type f -executable -printf ". "'$EXEC%p\\0' \\) -o -type d -printf '$DIR%p\\0' -o \\( -type l -x". "type d -printf '$DIR%p\\0' \\) -o -not -type d -printf '$FILE%p\\0'"; $this->path = $path; $result = $this->shell($cmd); $files = array(); $dirs = array(); $execs = array(); foreach (explode("\x0", $result['output']) as $item) { if ($item != "") { $mnemonic = substr($item, 0, 1); $item = substr($item, 3); // remove `./' switch ($mnemonic) { case $EXEC: $execs[] = $item; // executables are also files case $FILE: $files[] = $item; break; case $DIR: $dirs[] = $item; } } } $_SESSION[self::SESSIONKEY]['cwd'] = $this->path; return array( 'cwd' => str_replace( getenv('HOME'), '${HOME}',$this->path), 'files' => $files, 'dirs' => $dirs, 'execs' => $execs ); } // ------------------------------------------------------------------------ public function executables() : array { if (!$this->config->is_windows) { $command = 'IFS=":";for i in $PATH; do test -d "$i" && find "$i" ' . '-maxdepth 1 -executable -type f -exec basename {} \;;' . 'done | sort | uniq'; $result = $this->shell($command); $commands = explode("\n", trim($result['output'])); return array_values(array_filter($commands, function($command) { return strlen($command) > 1; // filter out . : [ })); } return array(); } // ------------------------------------------------------------------------ public function shell($code) { $shells = array('system', 'exec', 'shell_exec'); foreach ($shells as $shell) { if (function_exists($shell)) { return $this->command($code, $this->path, $shell); } } throw new Exception("No valid shell found"); } // $f = __DIR__.\DIRECTORY_SEPARATOR.'index.php'; //$f = __DIR__.\DIRECTORY_SEPARATOR.'../../frdlweb/frdl-projects/testground/modules/frdl.console/bin/frdlweb'; //exec(sprintf('%s %s %s 2>&1 ', (new \webfan\hps\patch\PhpBinFinder())->find(), $f, 'frdl:test'), $out, $status); //$cmd = sprintf('%s install --working-dir=%s --no-progress', (new \webfan\hps\patch\PhpBinFinder())->find().' -d memory_limit=-1 '.$config['COMPOSER_PATH'], $path); /* const SESSIONKEY = 'apc'; const CONFIG_FILENAME = 'frdl.stub.config.php'; const WORKSPACES_FILENAME = 'frdl.workspaces.php'; const VERSION_FILENAME = 'frdl.version.config.php'; const BASH_FILENAME = '.bashrc_profile'; //const BASH_FILENAME = '.bashrc-frdl'; const PROJECT_FILENAME = 'frdl.project.json'; const DEPLOYMENT_FILENAME = 'frdl.deployment.json'; const STAGES_FILENAME = 'frdl.stages.json'; const CONFIG_PROJECT_FILENAME = 'frdl.project.config.php'; */ public function whatsin($dir){ return [ 'project:frdl' => (file_exists($dir.\DIRECTORY_SEPARATOR.'frdl.project.json') ), 'composer:package' => (file_exists($dir.\DIRECTORY_SEPARATOR.'composer.json') ), 'project:npm' => (file_exists($dir.\DIRECTORY_SEPARATOR.'package.json') ), 'console:frdl' => (0 (file_exists($dir.\DIRECTORY_SEPARATOR.Shield::CONFIG_FILENAME) || file_exists($dir.\DIRECTORY_SEPARATOR.Shield::BASH_FILENAME) ), 'project:deployment' => (file_exists($dir.\DIRECTORY_SEPARATOR.Shield::STAGES_FILENAME) || file_exists($dir.\DIRECTORY_SEPARATOR.Shield::DEPLOYMENT_FILENAME) ), ]; } private function withFrdl($command, $args){ $whatsInHere = $this->whatsin($this->path); $cmd = implode(' ', $args); $frdl_project_file=$this->path.\DIRECTORY_SEPARATOR.'frdl.project.json'; if(file_exists($frdl_project_file)){ $project = json_decode(file_get_contents($frdl_project_file)); }else{ $project = new \stdclass; $project->modules_dirname = 'modules'; } $s = array_merge( glob($this->path."/*/frdl.console/bin/frdlweb"),glob($this->path."/*/frdl.console/bin/frdl"),glob($this->path."/bin/frdlweb"),glob($this->path."/vendor/bin/frdlweb") ); $f = $s[0]; //$f = $this->path.\DIRECTORY_SEPARATOR.$project->modules_dirname.\DIRECTORY_SEPARATOR.'frdl.console'.\DIRECTORY_SEPARATOR.'bin'.\DIRECTORY_SEPARATOR.'frdlweb'; if(!file_exists($f)){ $f = $this->path.\DIRECTORY_SEPARATOR.'index.php'; } if(!file_exists($f)){ $f = $this->path.\DIRECTORY_SEPARATOR.$project->modules_dirname.\DIRECTORY_SEPARATOR.'frdl.console'.\DIRECTORY_SEPARATOR.'bin'.\DIRECTORY_SEPARATOR.'frdlweb'; } $cmd=trim($cmd); if(!file_exists($f) && ($cmd === 'help' || 0===count($args))){ return [ 'result' => implode("\n", [ '* First step: Download https://webfan.de/install/php/ and install the Webfan PHP-Installer and its dependencies on an php enabled vHost', ' - During the installation you are enforced to install composer, Node.js, frdl.js, ... if it is not allready supported by your host', '* Next create a project and add the dependencies to the composer.json (you SHOULD use the web-UI of the Webfan PHP-Installer)', '* Compile the project by clicking the buttons in the web-UI:', ' `frdl-module` and other `frdl-*` packages and the javascripts for frdl.js', '* Deploy the project to diffrent test or production stages and enable the update-alerts', ]), 'cwd' => str_replace( getenv('HOME'), '${HOME}',$this->path) ]; } if(file_exists($f) // && false !== strpos(file_get_contents($f), 'Thi file was auto-generated by frdl') ){ exec(sprintf('%s %s %s 2>&1', (new \webfan\hps\patch\PhpBinFinder())->find(), $f, escapeshellarg($cmd)), $out, $status); if($status){ throw new Exception(implode("\n", $out)); } return [ 'result' => $out, 'cwd' => str_replace( getenv('HOME'), '${HOME}',$this->path) ]; }elseif('frdlweb' === $command){ return $this->shell($command.' '.implode(' ', $args)); } //else{ throw new Exception(sprintf("You must run the `%s%s` command within a frdl project working directory! cwd: %s | %s | %s", $command, (isset($args[0])) ? ' '.$args[0] : $cmd, $f, $this->path, $_SESSION[self::SESSIONKEY]['cwd'])); //} //return $this->shell($command.' '.implode(' ', $args)); } private function withComposer($command, $args){ $cmd = $command.' '.implode(' ', $args); if(!isset($this->config->COMPOSER_PATH)){ return $this->shell($cmd); } /* return $this->shell($cmd); */ $cmd = implode(' ', $args); $cmd = sprintf('%s %s --working-dir=%s 2>&1', (new \webfan\hps\patch\PhpBinFinder())->find().' -d memory_limit=-1 '.$this->config->COMPOSER_PATH, escapeshellarg($cmd), $this->path); exec($cmd, $out, $status); if($status){ throw new Exception(implode("\n", $out)); } return [ 'result' => $out, 'cwd' => str_replace( getenv('HOME'), '${HOME}',$this->path) ]; } public function __call($command, $args){ if('rpc' === substr($command, 0, strlen('rpc'))){ return Shield::getInstance()->pc(trim(substr($command, strlen('rpc'), strlen($command))), json_decode($args[0])); }elseif('frdl' === substr($command, 0, strlen('frdl'))){ return $this->withFrdl($command, $args); }elseif('composer' === substr($command, 0, strlen('composer'))){ return $this->withComposer($command, $args); } return [ 'result' => $command.' was called with '.count($args).' arguments but it was not resoveld yet!', 'cwd' => str_replace( getenv('HOME'), '${HOME}',$this->path) ]; } }__halt_compiler();----SIGNATURE:----eb7O9kT+X130zJXrqoR08BMlEPM0g7ZmcWWKtCqXdd1KAt3QUM9hO4i2qd5DK0m0kTimqmRUOzusJ9TgRhn/Fj5n4IRkB4jlnBbqdklb5qV/WjaZkIRtpOxHuL0jt5eXCj/xfIDSVKOLCl3ITcGTPmhy75MCdaSQqRlSlsXFLfjnBOpq+QjbUbCgHh7gMkMBPIvfdYXsc5V0bVC/AYUZCzHgep41dS9iR6bT8Agolw6hdPbDGNjTQVe+bXRxC284my4eA8+ndhpKdhx4SbXBx9fckhHWiOyua3xLT/WW9DYDaWvpiOVAqdJ+T449+J4oTUZSqrijzXr/fZ2e01rEN4LumNFJajy7MyO90jfHH8n2kGry/B3vy2JnDbN3Cg1049C+GO14sFzKd5+vvQU+0pifYv0K6FtbESSl6sCdCK70Dp3S9nzu7s1zERVlZ6zPXqFL/1mxIfIr1vKqfgiK+Ex1H85I0LiWI+lpu7vOQcrWZm4uHZk9GmDrtc02dI71ksjLE+vtfwy5lZ1WyjNh1JTFgUS/h8NHS8zVq5LgxXBvRrvEotPs+VJ02mvTEGLCeiQ6g/tDEJXg7MoM+4IUlXC536uCROv4IyZib7pIK2FQgXerkmSs2jTUuKxfyrXDjbcG4eVg+tt17AnMiAURlgVkvwTEfv3OJdUAB/NvwjA=----ATTACHMENT:----MjM1Mjg0NTAzMjYxNzMwNiA5NDkzMzI0MDAwMDA0MzY4IDI1OTE5MTEzMjEzMjA3NjM=