mirror of
https://gitee.com/ShopeX/OMS
synced 2026-03-22 18:35:35 +08:00
271 lines
9.2 KiB
PHP
271 lines
9.2 KiB
PHP
<?php
|
|
/**
|
|
* Copyright 2012-2026 ShopeX (https://www.shopex.cn)
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
|
|
class base_shell_loader{
|
|
|
|
var $commands_dir;
|
|
var $app_id;
|
|
var $trigger = array();
|
|
var $status = array();
|
|
var $input = array();
|
|
|
|
function __construct(){
|
|
set_time_limit(0);
|
|
cachemgr::init(false);
|
|
kernel::$console_output = true;
|
|
if(file_exists(ROOT_DIR.'/config/config.php')){
|
|
require(ROOT_DIR.'/config/config.php');
|
|
$this->status['config'] = ROOT_DIR.'/config/config.php';
|
|
}else{
|
|
$this->status['config'] = 'false';
|
|
}
|
|
include(APP_DIR.'/base/defined.php');
|
|
date_default_timezone_set(
|
|
defined('DEFAULT_TIMEZONE') ? ('Etc/GMT'.(DEFAULT_TIMEZONE>=0?(DEFAULT_TIMEZONE*-1):'+'.(DEFAULT_TIMEZONE*-1))):'UTC'
|
|
);
|
|
$this->buildin_commander = new base_shell_buildin($this);;
|
|
}
|
|
|
|
function run(){
|
|
ignore_user_abort(false);
|
|
ob_implicit_flush(1);
|
|
ini_set('implicit_flush',true);
|
|
cachemgr::init(false);
|
|
|
|
if(strpos(strtolower(PHP_OS), 'win') === 0){
|
|
if(function_exists('mb_internal_encoding')){
|
|
mb_internal_encoding("UTF-8");
|
|
mb_http_output("GBK");
|
|
ob_start("mb_output_handler",2);
|
|
}elseif(function_exists('iconv_set_encoding')){
|
|
iconv_set_encoding("internal_encoding", "UTF-8");
|
|
iconv_set_encoding("output_encoding", "GBK");
|
|
ob_start("ob_iconv_handler",2);
|
|
}
|
|
}
|
|
|
|
if(isset($_SERVER['argv'][1])){
|
|
$args = array_shift($_SERVER['argv']);
|
|
$rst = $this->exec_command(implode(' ',$_SERVER['argv']));
|
|
if($rst===false){
|
|
exit(-1);
|
|
}
|
|
}else{
|
|
$this->interactive();
|
|
}
|
|
}
|
|
|
|
function print_banner(){
|
|
$version = 1.3;
|
|
echo "Ecos shell V{$version} (abort with ^C), Root: ",ROOT_DIR;
|
|
}
|
|
|
|
/**
|
|
* 获取_width
|
|
* @return mixed 返回结果
|
|
*/
|
|
static public function get_width() {
|
|
$output = @strtolower(exec('stty -a |grep columns'));
|
|
if($output){
|
|
foreach(explode(';',$output) as $part){
|
|
if(strpos($part,'columns')!==false){
|
|
return intval(str_replace('columns', '', $part));
|
|
}
|
|
}
|
|
}
|
|
return 80;
|
|
}
|
|
|
|
function &get_commander($app_id,$shell_command){
|
|
$shell_command = strtolower($shell_command);
|
|
if(!$app_id && isset($this->cmdlibs[$shell_command])){
|
|
return $this->cmdlibs[$shell_command];
|
|
}
|
|
if(file_exists(APP_DIR.'/'.$app_id.'/lib/command/'.$shell_command.'.php')){
|
|
require_once(APP_DIR.'/'.$app_id.'/lib/command/'.$shell_command.'.php');
|
|
$class_name = $app_id.'_command_'.$shell_command;
|
|
$this->cmdlibs[$shell_command] = new $class_name($this);
|
|
$this->cmdlibs[$shell_command]->app = app::get($app_id);
|
|
return $this->cmdlibs[$shell_command];
|
|
}else{
|
|
$commander = false;
|
|
return $commander;
|
|
}
|
|
}
|
|
|
|
function interactive(){
|
|
$this->print_banner();
|
|
$i=1;
|
|
|
|
while (true) {
|
|
$line = readline("\n".($this->app_id?($i++).':'.$this->app_id:$i++).'> ');
|
|
readline_add_history($line);
|
|
|
|
foreach($this->trigger as $trigger_name => &$trigger){
|
|
$trigger->{'begin_'.$trigger_name}($line);
|
|
}
|
|
|
|
$this->exec($line);
|
|
|
|
foreach($this->trigger as $trigger_name => &$trigger){
|
|
$trigger->{'end_'.$trigger_name}($line);
|
|
}
|
|
//ob_flush();
|
|
|
|
}
|
|
}
|
|
|
|
function input_option($options,$part,$message=null){
|
|
if(PHP_SAPI!='cli'){
|
|
trigger_error('Can\'t start options editor',E_ERROR);
|
|
exit;
|
|
}
|
|
do{
|
|
echo "\n";
|
|
$output= array();
|
|
$i = 1;
|
|
foreach($options as $key=>$option){
|
|
$map[$i] = $key;
|
|
|
|
if(!array_key_exists($key,(array)$this->input[$part]) && array_key_exists('default',$option)){
|
|
$this->input[$part][$key] = $option['default'];
|
|
}
|
|
|
|
if($option['type']=='password'){
|
|
$current_value = $this->input[$part][$key]?str_repeat('*',strlen($current_value)):'(empty)';
|
|
}elseif($option['type']=='select'){
|
|
if(is_array($option['options_callback'])){
|
|
$option['options'] = app::get($option['options_callback']['app'])->runtask($option['options_callback']['method'], $this->input);
|
|
$options[$key]['options'] = $option['options'];
|
|
}
|
|
$current_value = $option['options'][$this->input[$part][$key]];
|
|
}elseif($this->input[$part][$key]==''){
|
|
$current_value = '(empty)';
|
|
}else{
|
|
$current_value = $this->input[$part][$key];
|
|
}
|
|
|
|
$output[] = array(
|
|
str_pad($i,3,' ',STR_PAD_LEFT).'. '.$option['title'],
|
|
$current_value
|
|
);
|
|
$i++;
|
|
}
|
|
$this->buildin_commander->output_table( $output );
|
|
$line = readline(str_repeat('_',40)."\n".app::get('base')->_('输入项目编号,或输入井号').'"#"'.app::get('')->_('确认').": ");
|
|
}while($this->save_input_option($options,$map,trim($line),$part));
|
|
}
|
|
|
|
function save_input_option($options,$map,$input,$part){
|
|
if($input=='#'){
|
|
return false;
|
|
}else{
|
|
$option = $options[$map[$input]];
|
|
switch($option['type']){
|
|
|
|
case 'password':
|
|
@system('stty -echo');
|
|
$this->input[$part][$map[$input]] = trim(readline("\n".app::get('base')->_('输入')."{$option['title']}: "));
|
|
@system('stty echo');
|
|
break;
|
|
|
|
case 'select':
|
|
$i=1;
|
|
$output = "\n".app::get('base')->_('选择合适的')."{$option['title']}:\n";
|
|
foreach($options[$map[$input]]['options'] as $k=>$v){
|
|
$optmap[$i] = $k;
|
|
$output.= str_pad($i,3,' ',STR_PAD_LEFT).'. '.$v."\n";
|
|
$i++;
|
|
}
|
|
$output.=app::get('base')->_("输入合适的")."{$option['title']}".app::get('base')->_('编号').": ";
|
|
$this->input[$part][$map[$input]] = $optmap[trim(readline($output))];
|
|
break;
|
|
|
|
default:
|
|
$this->input[$part][$map[$input]] = trim(readline("\n".app::get('base')->_('输入')."{$option['title']}: "));
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
function exec_command($line){
|
|
$this->exec($line);
|
|
}
|
|
|
|
function exec($line){
|
|
try{
|
|
$line = trim($line);
|
|
if(substr($line,-1,1)==';'){
|
|
return $this->buildin_commander->php_call($line);
|
|
}else{
|
|
$command_parts = preg_split ("/[\s]+/", $line);
|
|
$shell_command = array_shift($command_parts);
|
|
list($app_id,$commander) = explode(':',$shell_command);
|
|
if(!$commander){
|
|
$commander = $app_id;
|
|
if(method_exists($this->buildin_commander,'command_'.$commander)){
|
|
array_unshift($command_parts,$shell_command);
|
|
return $this->buildin_commander->exec($command_parts);
|
|
}else{
|
|
echo $shell_command.": Command not found.";
|
|
}
|
|
}else{
|
|
$commander = $this->get_commander($app_id,$commander);
|
|
if($commander){
|
|
return $commander->exec($command_parts);
|
|
}else{
|
|
echo $shell_command.": Command not found.";
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}catch (Exception $e){
|
|
echo 'Error: ', $e->getMessage(), "";
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if(!function_exists('readline')){
|
|
|
|
function readline($prompt){
|
|
echo $prompt;
|
|
//ob_flush();
|
|
$input = '';
|
|
while(1){
|
|
$key = fgetc(STDIN);
|
|
switch($key){
|
|
case "\n":
|
|
return $input;
|
|
|
|
default:
|
|
$input.=$key;
|
|
}
|
|
}
|
|
}
|
|
|
|
function readline_add_history($line){
|
|
//...
|
|
}
|
|
|
|
function readline_completion_function($callback){
|
|
|
|
}
|
|
}
|