Esempio n. 1
0
 /**
  * Bootstrap Phinx.
  *
  * @param array $args
  * @param array $options
  */
 public function bootstrap(array $args, array $options = [])
 {
     if (false === class_exists('\\Phinx\\Config\\Config')) {
         throw new \RuntimeException('please use `composer require linhecheng/cmlphp-ext-phinx` cmd to install phinx.');
     }
     if (!$this->getConfig()) {
         $this->loadConfig($options);
     }
     $this->loadManager($args, $options);
     // report the paths
     Output::writeln('using migration path ' . Colour::colour(str_replace(Cml::getApplicationDir('secure_src'), '{secure_src}', $this->getConfig()->getMigrationPath()), Colour::GREEN));
     Output::writeln('using seed path ' . Colour::colour(str_replace(Cml::getApplicationDir('secure_src'), '{secure_src}', $this->getConfig()->getSeedPath()), Colour::GREEN));
     $exportPath = false;
     if (isset($options['e'])) {
         $exportPath = $options['e'];
     } else {
         if (isset($options['export'])) {
             $exportPath = $options['export'];
         }
     }
     if ($exportPath) {
         is_dir($exportPath) || ($exportPath = $this->getConfig()->getExportPath());
         is_dir($exportPath) || mkdir($exportPath, 0700, true);
         Output::writeln('using export path:' . Colour::colour(str_replace(Cml::getApplicationDir('secure_src'), '{secure_src}', $exportPath), Colour::GREEN));
         $merge = isset($options['m']) || isset($options['merge']) ? 'merge_export_' . date('Y-m-d-H-i-s') . '.sql' : false;
         $this->getManager()->getEnvironment()->setExportPath($exportPath, $merge);
     }
     $this->getConfig()->echoAdapterInfo();
 }
Esempio n. 2
0
 /**
  * 自定义异常处理
  *
  * @param mixed $e 异常对象
  */
 public function appException(&$e)
 {
     $error = [];
     $exceptionClass = new \ReflectionClass($e);
     $error['exception'] = '\\' . $exceptionClass->name;
     $error['message'] = $e->getMessage();
     $trace = $e->getTrace();
     foreach ($trace as $key => $val) {
         $error['files'][$key] = $val;
     }
     if (substr($e->getFile(), -20) !== '\\Tools\\functions.php' || $e->getLine() !== 90) {
         array_unshift($error['files'], ['file' => $e->getFile(), 'line' => $e->getLine(), 'type' => 'throw']);
     }
     if (!Cml::$debug) {
         //正式环境 只显示‘系统错误’并将错误信息记录到日志
         Log::emergency($error['message'], [$error['files'][0]]);
         $error = [];
         $error['message'] = Lang::get('_CML_ERROR_');
     }
     if (Request::isCli()) {
         pd($error);
     } else {
         header('HTTP/1.1 500 Internal Server Error');
         View::getEngine('html')->reset()->assign('error', $error);
         Cml::showSystemTemplate(Config::get('html_exception'));
     }
 }
Esempio n. 3
0
 /**
  * 自定义异常处理
  *
  * @param mixed $e 异常对象
  */
 public function appException(&$e)
 {
     if (Cml::$debug) {
         $run = new Run();
         $run->pushHandler(Request::isCli() ? new PlainTextHandler() : new PrettyPageHandler());
         $run->handleException($e);
     } else {
         $error = [];
         $error['message'] = $e->getMessage();
         $trace = $e->getTrace();
         $error['files'][0] = $trace[0];
         if (substr($e->getFile(), -20) !== '\\Tools\\functions.php' || $e->getLine() !== 90) {
             array_unshift($error['files'], ['file' => $e->getFile(), 'line' => $e->getLine(), 'type' => 'throw']);
         }
         //正式环境 只显示‘系统错误’并将错误信息记录到日志
         Log::emergency($error['message'], [$error['files'][0]]);
         $error = [];
         $error['message'] = Lang::get('_CML_ERROR_');
         if (Request::isCli()) {
             \Cml\pd($error);
         } else {
             header('HTTP/1.1 500 Internal Server Error');
             View::getEngine('html')->reset()->assign('error', $error);
             Cml::showSystemTemplate(Config::get('html_exception'));
         }
     }
     exit;
 }
Esempio n. 4
0
 /**
  * 创建一个新的seeder
  *
  * @param array $args 参数
  * @param array $options 选项
  */
 public function execute(array $args, array $options = [])
 {
     $this->bootstrap($args, $options);
     // get the seed path from the config
     $path = $this->getConfig()->getSeedPath();
     if (!file_exists($path)) {
         $ask = new Dialog();
         if ($ask->confirm(Colour::colour('Create seeds directory?', [Colour::RED, Colour::HIGHLIGHT]))) {
             mkdir($path, 0755, true);
         }
     }
     $this->verifySeedDirectory($path);
     $path = realpath($path);
     $className = $args[0];
     if (!Util::isValidPhinxClassName($className)) {
         throw new \InvalidArgumentException(sprintf('The seed class name "%s" is invalid. Please use CamelCase format', $className));
     }
     // Compute the file path
     $filePath = $path . DIRECTORY_SEPARATOR . $className . '.php';
     if (is_file($filePath)) {
         throw new \InvalidArgumentException(sprintf('The file "%s" already exists', basename($filePath)));
     }
     // inject the class names appropriate to this seeder
     $contents = file_get_contents($this->getSeedTemplateFilename());
     $classes = ['$useClassName' => 'Phinx\\Seed\\AbstractSeed', '$className' => $className, '$baseClassName' => 'AbstractSeed'];
     $contents = strtr($contents, $classes);
     if (false === file_put_contents($filePath, $contents)) {
         throw new \RuntimeException(sprintf('The file "%s" could not be written to', $path));
     }
     Output::writeln('using seed base class ' . $classes['$useClassName']);
     Output::writeln('created ' . str_replace(Cml::getApplicationDir('secure_src'), '{secure_src}', $filePath));
 }
Esempio n. 5
0
 /**
  * 从注释解析生成文档
  *
  */
 public static function parse()
 {
     $result = [];
     $config = Config::load('api', Cml::getApplicationDir('app_controller_path') ? true : false);
     foreach ($config['version'] as $version => $apiList) {
         isset($result[$version]) || ($result[$version] = []);
         foreach ($apiList as $model => $api) {
             $pos = strrpos($api, '\\');
             $controller = substr($api, 0, $pos);
             $action = substr($api, $pos + 1);
             if (class_exists($controller) === false) {
                 continue;
             }
             $annotationParams = self::getAnnotationParams($controller, $action);
             empty($annotationParams) || ($result[$version][$model] = $annotationParams);
         }
     }
     foreach ($result as $key => $val) {
         if (count($val) < 1) {
             unset($result[$key]);
         }
     }
     $systemCode = Cml::requireFile(__DIR__ . DIRECTORY_SEPARATOR . 'resource' . DIRECTORY_SEPARATOR . 'code.php');
     Cml::requireFile(__DIR__ . DIRECTORY_SEPARATOR . 'resource' . DIRECTORY_SEPARATOR . 'doc.html', ['config' => $config, 'result' => $result, 'systemCode' => $systemCode]);
 }
Esempio n. 6
0
 /**
  * 创建控制器
  *
  * @param array $args 参数
  * @param array $options 选项
  */
 public function execute(array $args, array $options = [])
 {
     $template = isset($options['template']) ? $options['template'] : false;
     $template || ($template = __DIR__ . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . 'Controller.php.dist');
     $name = $args[0];
     $name = explode('-', $name);
     if (count($name) < 2) {
         throw new \InvalidArgumentException(sprintf('The arg name "%s" is invalid. eg: adminbase-Blog/Category', $name));
     }
     $namespace = trim(trim($name[0], '\\/'));
     $path = Cml::getApplicationDir('apps_path') . DIRECTORY_SEPARATOR . $namespace . DIRECTORY_SEPARATOR . Cml::getApplicationDir('app_controller_path_name') . DIRECTORY_SEPARATOR;
     $component = explode('/', trim(trim($name[1], '/')));
     if (count($component) > 1) {
         $className = ucfirst(array_pop($component)) . Config::get('controller_suffix');
         $component = implode(DIRECTORY_SEPARATOR, $component);
         $path .= $component . DIRECTORY_SEPARATOR;
         $component = '\\' . $component;
     } else {
         $className = ucfirst($component[0]) . Config::get('controller_suffix');
         $component = '';
     }
     if (!is_dir($path) && false == mkdir($path, 0700, true)) {
         throw new \RuntimeException(sprintf('The path "%s" could not be create', $path));
     }
     $contents = strtr(file_get_contents($template), ['$namespace' => $namespace, '$component' => $component, '$className' => $className]);
     if (false === file_put_contents($path . $className . '.php', $contents)) {
         throw new \RuntimeException(sprintf('The file "%s" could not be written to', $path));
     }
     Output::writeln(Colour::colour('Controller created successfully. ', Colour::GREEN));
 }
Esempio n. 7
0
 /**
  * 静态页面-获取静态页面
  *
  * @param  string  $key  静态页面标识符,可以用id代替
  *
  * @return  bool
  */
 public function get($key)
 {
     $filename = $this->getFilename($key);
     if (!$filename || !is_file($filename)) {
         return false;
     }
     Cml::requireFile($filename);
     return true;
 }
Esempio n. 8
0
 /**
  * 获取配置参数不区分大小写
  *
  * @param string $key 支持.获取多维数组
  * @param string $default 不存在的时候默认值
  *
  * @return mixed
  */
 public static function get($key = null, $default = null)
 {
     // 无参数时获取所有
     if (empty($key)) {
         return self::$_content;
     }
     $key = strtolower($key);
     return Cml::doteToArr($key, self::$_content['normal'], $default);
 }
Esempio n. 9
0
 /**
  * 运行对应的控制器
  *
  * @return void
  */
 public final function runAppController()
 {
     //检测csrf跨站攻击
     Secure::checkCsrf(Config::get('check_csrf'));
     // 关闭GPC过滤 防止数据的正确性受到影响 在db层防注入
     if (get_magic_quotes_gpc()) {
         Secure::stripslashes($_GET);
         Secure::stripslashes($_POST);
         Secure::stripslashes($_COOKIE);
         Secure::stripslashes($_REQUEST);
         //在程序中对get post cookie的改变不影响 request的值
     }
     //session保存方式自定义
     if (Config::get('session_user')) {
         Session::init();
     } else {
         ini_get('session.auto_start') || session_start();
         //自动开启session
     }
     header('Cache-control: ' . Config::get('http_cache_control'));
     // 页面缓存控制
     //如果有子类中有init()方法 执行Init() eg:做权限控制
     if (method_exists($this, "init")) {
         $this->init();
     }
     //根据动作去找对应的方法
     $method = Route::$urlParams['action'];
     if (method_exists($this, $method)) {
         $this->{$method}();
     } elseif ($GLOBALS['debug']) {
         Cml::montFor404Page();
         throwException(Lang::get('_ACTION_NOT_FOUND_', Route::$urlParams['action']));
     } else {
         Cml::montFor404Page();
         Response::show404Page();
     }
 }
Esempio n. 10
0
 /**
  * 获取Logger实例
  *
  * @return Base
  */
 private static function getLogger()
 {
     return Cml::getContainer()->make('cml_log');
 }
Esempio n. 11
0
 /**
  * 程序中并输出调试信息
  *
  */
 public static function cmlStop()
 {
     //输出Debug模式的信息
     if (self::$debug) {
         header('Content-Type:text/html; charset=' . Config::get('default_charset'));
         Debug::stop();
     } else {
         $deBugLogData = dump('', 1);
         if (!empty($deBugLogData)) {
             Config::get('dump_use_php_console') ? dumpUsePHPConsole($deBugLogData) : Cml::requireFile(CML_CORE_PATH . DIRECTORY_SEPARATOR . 'ConsoleLog.php', ['deBugLogData' => $deBugLogData]);
         }
         CML_OB_START && ob_end_flush();
     }
     exit;
 }
Esempio n. 12
0
 /**
  * 构造方法
  *
  */
 public function __construct()
 {
     $this->logDir = Cml::getApplicationDir('runtime_logs_path') . DIRECTORY_SEPARATOR . date('Y/m/d') . DIRECTORY_SEPARATOR;
     is_dir($this->logDir) || mkdir($this->logDir, 0755, true);
 }
Esempio n. 13
0
 /**
  * 获取要执行的控制器类名及方法
  *
  */
 public function getControllerAndAction()
 {
     //控制器所在路径
     $appName = self::getAppName();
     $className = $appName . ($appName ? '/' : '') . Cml::getApplicationDir('app_controller_path_name') . '/' . self::getControllerName() . Config::get('controller_suffix');
     $actionController = Cml::getApplicationDir('apps_path') . '/' . $className . '.php';
     if (is_file($actionController)) {
         return ['class' => str_replace('/', '\\', $className), 'action' => self::getActionName()];
     } else {
         return false;
     }
 }
Esempio n. 14
0
 /**
  * shell参数处理并启动守护进程
  *
  * @param string $cmd
  */
 public static function run($cmd)
 {
     self::$pidFile = Cml::getApplicationDir('global_store_path') . DIRECTORY_SEPARATOR . 'DaemonProcess_.pid';
     self::$log = Cml::getApplicationDir('global_store_path') . DIRECTORY_SEPARATOR . 'DaemonProcess_.log';
     self::$status = Cml::getApplicationDir('global_store_path') . DIRECTORY_SEPARATOR . 'DaemonProcessStatus.php';
     self::checkExtension();
     $param = is_array($cmd) && count($cmd) == 2 ? $cmd[1] : $cmd;
     switch ($param) {
         case 'start':
             self::start();
             break;
         case 'stop':
             posix_kill(self::getPid(), SIGINT);
             self::message('stop....');
             break;
         case 'reload':
             posix_kill(self::getPid(), SIGUSR1);
             self::message('reloading....');
             break;
         case 'status':
             self::getStatus(true);
             break;
         case 'addtask':
             if (func_num_args() < 1) {
                 self::message('please input task name');
                 break;
             }
             $args = func_get_args();
             $frequency = isset($args[2]) ? intval($args[2]) : 60;
             $frequency < 1 || ($frequency = 60);
             self::addTask($args[1], $frequency);
             break;
         case 'rmtask':
             if (func_num_args() < 1) {
                 self::message('please input task name');
                 break;
             }
             $args = func_get_args();
             self::rmTask($args[1]);
             break;
         default:
             self::message('Usage: xxx.php cml.cmd DaemonWorker::run {start|stop|status|addtask|rmtask}');
             break;
     }
 }
Esempio n. 15
0
 /**
  * URL组装 支持不同URL模式
  * eg: \Cml\Http\Response::url('Home/Blog/cate/id/1')
  *
  * @param string $url URL表达式 路径/控制器/操作/参数1/参数1值/.....
  * @param int $echo 是否输出  1输出 0 return
  *
  * @return string
  */
 public static function url($url = '', $echo = 1)
 {
     $return = '';
     // 解析URL
     if (empty($url)) {
         throw new \InvalidArgumentException(Lang::get('_NOT_ALLOW_EMPTY_', 'url'));
         //'U方法参数出错'
     }
     // URL组装
     $delimiter = Config::get('url_pathinfo_depr');
     $url = ltrim($url, '/');
     $url = implode($delimiter, explode('/', $url));
     if (Config::get('url_model') == 1) {
         $return = $_SERVER['SCRIPT_NAME'] . '/' . $url;
     } elseif (Config::get('url_model') == 2) {
         $return = Cml::getContainer()->make('cml_route')->getSubDirName() . $url;
     } elseif (Config::get('url_model') == 3) {
         $return = $_SERVER['SCRIPT_NAME'] . '?' . Config::get('var_pathinfo') . '=/' . $url;
     }
     $return .= Config::get('url_model') == 2 ? Config::get('url_html_suffix') : '';
     $return = Secure::filterScript($return);
     if ($echo === 1) {
         echo $return;
     } else {
         return $return;
     }
     return '';
 }
Esempio n. 16
0
 /**
  * 模板显示 调用内置的模板引擎显示方法,
  *
  * @param string $templateFile 指定要调用的模板文件 默认为空 由系统自动定位模板文件
  * @param bool $inOtherApp 是否为载入其它应用的模板
  *
  * @return void
  */
 public function display($templateFile = '', $inOtherApp = false)
 {
     // 网页字符编码
     header('Content-Type:text/html; charset=' . Config::get('default_charset'));
     echo $this->fetch($templateFile, $inOtherApp);
     Cml::cmlStop();
 }
Esempio n. 17
0
 /**
  * 获取缓存文件名
  *
  * @param  string $key 缓存名
  *
  * @return string
  */
 private function getFileName($key)
 {
     $md5Key = md5($this->getKey($key));
     $dir = Cml::getApplicationDir('runtime_cache_path') . DIRECTORY_SEPARATOR . 'LockFileCache' . DIRECTORY_SEPARATOR . substr($key, 0, strrpos($key, '/')) . DIRECTORY_SEPARATOR;
     $dir .= substr($md5Key, 0, 2) . DIRECTORY_SEPARATOR . substr($md5Key, 2, 2);
     is_dir($dir) || mkdir($dir, 0700, true);
     return $dir . DIRECTORY_SEPARATOR . $md5Key . '.php';
 }
Esempio n. 18
0
 /**
  * 从文件载入Config
  *
  * @param string $file
  * @param bool $global 是否从全局加载
  *
  * @return array
  */
 public static function load($file, $global = true)
 {
     if (isset(static::$_content[$file])) {
         return static::$_content[$file];
     } else {
         $file = ($global ? Cml::getApplicationDir('global_config_path') : Cml::getApplicationDir('apps_path') . '/' . Cml::getContainer()->make('cml_route')->getAppName() . '/' . Cml::getApplicationDir('app_config_path_name')) . '/' . ($global ? self::$isLocal . DIRECTORY_SEPARATOR : '') . $file . '.php';
         if (!is_file($file)) {
             throw new ConfigNotFoundException(Lang::get('_NOT_FOUND_', $file));
         }
         static::$_content[$file] = Cml::requireFile($file);
         return static::$_content[$file];
     }
 }
Esempio n. 19
0
 /**
  * 使用的缓存配置 默认为使用default_cache配置的参数
  *
  * @param bool|array $conf
  */
 public function __construct($conf = false)
 {
     $this->conf = $conf ? $conf : Config::get('default_cache');
     $this->conf['CACHE_PATH'] = isset($this->conf['CACHE_PATH']) ? $this->conf['CACHE_PATH'] : Cml::getApplicationDir('runtime_cache_path') . DIRECTORY_SEPARATOR . 'FileCache' . DIRECTORY_SEPARATOR;
     is_dir($this->conf['CACHE_PATH']) || mkdir($this->conf['CACHE_PATH'], 0700, true);
 }
Esempio n. 20
0
 /**
  * 获取要执行的控制器类名及方法
  *
  */
 public function getControllerAndAction()
 {
     $isOld = Cml::getApplicationDir('app_controller_path');
     //控制器所在路径
     $actionController = ($isOld ? $isOld . self::getAppName() : Cml::getApplicationDir('apps_path') . '/' . self::getAppName() . '/' . Cml::getApplicationDir('app_controller_path_name')) . '/' . self::getControllerName() . 'Controller.php';
     if (is_file($actionController)) {
         $className = self::getControllerName() . 'Controller';
         $className = ($isOld ? '\\Controller\\' : '') . self::getAppName() . ($isOld ? '/' : '/Controller' . '/') . "{$className}";
         $className = str_replace('/', '\\', $className);
         return ['class' => $className, 'action' => self::getActionName()];
     } else {
         return false;
     }
 }
Esempio n. 21
0
 /**
  * 抽象display
  *
  * @param string $templateFile 模板文件
  *
  * @return mixed
  */
 public function display($templateFile = '')
 {
     $options = $this->initBaseDir($templateFile);
     $compiler = new BladeCompiler($options['cacheDir'], $options['layoutCacheRootPath']);
     $compiler->directive('datetime', function ($timestamp) {
         return preg_replace('/(\\(\\d+\\))/', '<?php echo date("Y-m-d H:i:s", $1); ?>', $timestamp);
     });
     $compiler->directive('hook', function ($hook) {
         return preg_replace('/\\((.*?)\\)/', '<?php \\Cml\\Plugin::hook("$1"); ?>', $hook);
     });
     $compiler->directive('urldeper', function () {
         return '<?php echo \\Cml\\Config::get("url_model") == 3 ? "&" : "?"; ?>';
     });
     $compiler->directive('get', function ($key) {
         return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Http\\Input::getString("${1}");?>', $key);
     });
     $compiler->directive('post', function ($key) {
         return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Http\\Input::postString("${1}");?>', $key);
     });
     $compiler->directive('request', function ($key) {
         return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Http\\Input::requestString("${1}");?>', $key);
     });
     $compiler->directive('url', function ($key) {
         return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Http\\Response::url("${1}"); ?>', $key);
     });
     $compiler->directive('public', function () {
         return '<?php echo \\Cml\\Config::get("static__path", \\Cml\\Cml::getContainer()->make("cml_route")->getSubDirName()."public/");?>';
     });
     $compiler->directive('token', function () {
         return '<input type="hidden" name="CML_TOKEN" value="<?php echo \\Cml\\Secure::getToken();?>" />';
     });
     $compiler->directive('lang', function ($lang) {
         return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Lang::get("${1}"); ?>', $lang);
     });
     $compiler->directive('config', function ($config) {
         return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Config::get("${1}"); ?>', $config);
     });
     $compiler->directive('assert', function ($url) {
         return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Tools\\StaticResource::parseResourceUrl("${1}"); ?>', $url);
     });
     $compiler->directive('acl', function ($url) {
         return preg_replace('/\\((.*?)\\)/', '<?php if (\\Cml\\Vendor\\Acl::checkAcl("${1}")) : ?>', $url);
     });
     $compiler->directive('endacl', function () {
         return '<?php endif; ?>';
     });
     foreach ($this->rule as $pattern => $func) {
         $compiler->directive($pattern, $func);
     }
     $finder = new FileViewFinder([$options['templateDir'], $options['layoutDir']]);
     $finder->addExtension(trim(Config::get('html_template_suffix'), '.'));
     $factory = new Factory($compiler, $finder);
     header('Content-Type:text/html; charset=' . Config::get('default_charset'));
     echo $factory->make($options['file'], $this->args)->render();
     Cml::cmlStop();
 }
Esempio n. 22
0
 /**
  * 从文件查找控制器
  *
  * @param array $pathInfo
  * @param string $path
  */
 private function findAction(&$pathInfo, &$path)
 {
     $controllerPath = $controllerName = '';
     $controllerAppPath = Cml::getApplicationDir('app_controller_path');
     //兼容旧版本
     while ($dir = array_shift($pathInfo)) {
         $controllerName = ucfirst($dir);
         if ($controllerAppPath) {
             $controller = $controllerAppPath . $path;
         } else {
             $controller = Cml::getApplicationDir('apps_path') . $path . Cml::getApplicationDir('app_controller_path_name') . '/';
         }
         $controller .= $controllerPath . $controllerName . 'Controller.php';
         if ($path != '/' && is_file($controller)) {
             self::$urlParams['controller'] = $controllerPath . $controllerName;
             break;
         } else {
             if ($path == '/') {
                 $path .= $dir . '/';
             } else {
                 $controllerPath .= $dir . '/';
             }
         }
     }
     empty(self::$urlParams['controller']) && (self::$urlParams['controller'] = $controllerName);
     //用于404的时候挂载插件用
     self::$urlParams['action'] = array_shift($pathInfo);
 }
Esempio n. 23
0
 /**
  *SQL语句条件组装
  *
  *@param array $arr; 要组装的数组
  *@param string $tableName 当前操作的数据表名
  *
  *@return string
  */
 protected function arrToCondition($arr, $tableName)
 {
     empty($tableName) && ($tableName = Cml::getContainer()->make('cml_route')->getControllerName());
     /*
     //这个应该开发人员自己判断。框架不做额外开销
     $dbFields = $this->getDbFields($tableName, $tablePrefix);
      foreach (array_keys($arr) as $key) {
          if (!isset($dbFields[$key]))  unset($arr[$key]); //过滤db表中不存在的字段
      }
     */
     $s = $p = '';
     $params = [];
     foreach ($arr as $k => $v) {
         if (is_array($v)) {
             //自增或自减
             switch (key($v)) {
                 case 'inc':
                     $p = "`{$k}`= `{$k}`+" . abs(intval(current($v)));
                     break;
                 case 'dec':
                     $p = "`{$k}`= `{$k}`-" . abs(intval(current($v)));
                     break;
                 case 'func':
                     $func = strtoupper(key(current($v)));
                     $funcParams = current(current($v));
                     foreach ($funcParams as $key => $val) {
                         if (!isset($dbFields[$val])) {
                             $funcParams[$key] = '%s';
                             $params[] = $val;
                         }
                     }
                     $p = "`{$k}`= {$func}(" . implode($funcParams, ',') . ')';
                     break;
                 default:
                     //计算类型
                     $conkey = key($v);
                     if (!isset($dbFields[$conkey])) {
                         $conkey = $k;
                     }
                     if (!in_array(key(current($v)), ['+', '-', '*', '/', '%', '^', '&', '|', '<<', '>>', '~'])) {
                         throw new \InvalidArgumentException(Lang::get('_PARSE_UPDATE_SQL_PARAMS_ERROR_'));
                     }
                     $p = "`{$k}`= `{$conkey}`" . key(current($v)) . abs(intval(current(current($v))));
                     break;
             }
         } else {
             $p = "`{$k}`= %s";
             $params[] = $v;
         }
         $s .= (empty($s) ? '' : ',') . $p;
     }
     $this->bindParams = array_merge($params, $this->bindParams);
     return $s;
 }
Esempio n. 24
0
 /**
  * 匹配路由
  *
  * @param $pathinfo
  *
  * @return mixed
  */
 public static function isRoute(&$pathinfo)
 {
     empty($pathinfo) && ($pathinfo[0] = '/');
     //网站根地址
     $issuccess = array();
     $route = self::$rules;
     switch ($_SERVER['REQUEST_METHOD']) {
         case 'GET':
             $rmethod = self::REQUEST_METHOD_GET;
             break;
         case 'POST':
             $rmethod = self::REQUEST_METHOD_POST;
             break;
         case 'PUT':
             $rmethod = self::REQUEST_METHOD_PUT;
             break;
         case 'PATCH':
             $rmethod = self::REQUEST_METHOD_PATCH;
             break;
         case 'DELETE':
             $rmethod = self::REQUEST_METHOD_DELETE;
             break;
         case 'OPTIONS':
             $rmethod = self::REQUEST_METHOD_OPTIONS;
             break;
         default:
             $rmethod = self::REQUEST_METHOD_ANY;
     }
     foreach ($route as $k => $v) {
         $rulesmethod = substr($k, 0, 1);
         if ($rulesmethod != $rmethod && $rulesmethod != self::REQUEST_METHOD_ANY && $rulesmethod != self::RESTROUTE) {
             //此条路由不符合当前请求方式
             continue;
         }
         unset($v);
         $singleRule = substr($k, 1);
         $arr = $singleRule === '/' ? array(0 => $singleRule) : explode('/', ltrim($singleRule, '/'));
         if ($arr[0] == $pathinfo[0]) {
             array_shift($arr);
             foreach ($arr as $key => $val) {
                 if (isset($pathinfo[$key + 1]) && $pathinfo[$key + 1] !== '') {
                     if (strpos($val, '\\d') && !is_numeric($pathinfo[$key + 1])) {
                         //数字变量
                         $route[$k] = false;
                         //匹配失败
                         break 1;
                     } elseif (strpos($val, ':') === false && $val != $pathinfo[$key + 1]) {
                         //字符串
                         $route[$k] = false;
                         //匹配失败
                         break 1;
                     }
                 } else {
                     $route[$k] = false;
                     //匹配失败
                     break 1;
                 }
             }
         } else {
             $route[$k] = false;
             //匹配失败
         }
         if ($route[$k] !== false) {
             //匹配成功的路由
             $issuccess[] = $k;
         }
     }
     if (empty($issuccess)) {
         $returnArr[0] = false;
     } else {
         //匹配到多条路由时 选择最长的一条(匹配更精确)
         usort($issuccess, function ($item1, $item2) {
             return strlen($item1) >= strlen($item2) ? 0 : 1;
         });
         if (is_callable($route[$issuccess[0]])) {
             call_user_func($route[$issuccess[0]]);
             Cml::cmlStop();
         }
         $route[$issuccess[0]] = trim($route[$issuccess[0]], '/');
         //判断路由的正确性
         count(explode('/', $route[$issuccess[0]])) >= 2 || throwException(Lang::get('_ROUTE_PARAM_ERROR_', substr($issuccess[0], 1)));
         $returnArr[0] = true;
         $successRoute = explode('/', $issuccess[0]);
         foreach ($successRoute as $key => $val) {
             $t = explode('\\d', $val);
             if (strpos($t[0], ':') !== false) {
                 $_GET[ltrim($t[0], ':')] = $pathinfo[$key];
             }
             unset($pathinfo[$key]);
         }
         if (substr($issuccess[0], 0, 1) == self::RESTROUTE) {
             $actions = explode('/', $route[$issuccess[0]]);
             $arrKey = count($actions) - 1;
             $actions[$arrKey] = strtolower($_SERVER['REQUEST_METHOD']) . ucfirst($actions[$arrKey]);
             $route[$issuccess[0]] = implode('/', $actions);
         }
         $returnArr['route'] = $route[$issuccess[0]];
     }
     return $returnArr;
 }
Esempio n. 25
0
 /**
  *输出分页
  */
 public function show()
 {
     if ($this->totalRows == 0) {
         return '';
     }
     $nowCoolPage = ceil($this->nowPage / $this->barShowPage);
     $delimiter = Config::get('url_pathinfo_depr');
     $params = array_merge($this->param, [$this->pageShowVarName => '__PAGE__']);
     $paramsString = '';
     foreach ($params as $key => $val) {
         $paramsString == '' || ($paramsString .= '/');
         $paramsString .= $key . '/' . $val;
     }
     if ($this->url) {
         $url = rtrim(Response::url($this->url . '/' . $paramsString, false), $delimiter);
     } else {
         $url = rtrim(Response::url(Cml::getContainer()->make('cml_route')->getFullPathNotContainSubDir() . '/' . $paramsString, false), $delimiter);
     }
     $upRow = $this->nowPage - 1;
     $downRow = $this->nowPage + 1;
     $upPage = $upRow > 0 ? '<li><a href = "' . str_replace('__PAGE__', $upRow, $url) . '">' . $this->config['prev'] . '</a></li>' : '';
     $downPage = $downRow <= $this->totalPages ? '<li><a href="' . str_replace('__PAGE__', $downRow, $url) . '">' . $this->config['next'] . '</a></li>' : '';
     // << < > >>
     if ($nowCoolPage == 1) {
         $theFirst = $prePage = '';
     } else {
         $preRow = $this->nowPage - $this->barShowPage;
         $prePage = '<li><a href="' . str_replace('__PAGE__', $preRow, $url) . '">上' . $this->barShowPage . '页</a></li>';
         $theFirst = '<li><a href="' . str_replace('__PAGE__', 1, $url) . '">' . $this->config['first'] . '</a></li>';
     }
     if ($nowCoolPage == $this->coolPages) {
         $nextPage = $theEnd = '';
     } else {
         $nextRow = $this->nowPage + $this->barShowPage;
         $theEndRow = $this->totalPages;
         $nextPage = '<li><a href="' . str_replace('__PAGE__', $nextRow, $url) . '">下' . $this->barShowPage . '页</a></li>';
         $theEnd = '<li><a href="' . str_replace('__PAGE__', $theEndRow, $url) . '">' . $this->config['last'] . '</a></li>';
     }
     //1 2 3 4 5
     $linkPage = '';
     for ($i = 1; $i <= $this->barShowPage; $i++) {
         $page = ($nowCoolPage - 1) * $this->barShowPage + $i;
         if ($page != $this->nowPage) {
             if ($page <= $this->totalPages) {
                 $linkPage .= '&nbsp;<li><a href="' . str_replace('__PAGE__', $page, $url) . '">&nbsp;' . $page . '&nbsp;</a></li>';
             } else {
                 break;
             }
         } else {
             if ($this->totalPages != 1) {
                 $linkPage .= '&nbsp;<li class="active"><a>' . $page . '</a></li>';
             }
         }
     }
     $pageStr = str_replace(['%header%', '%nowPage%', '%totalRow%', '%totalPage%', '%upPage%', '%downPage%', '%first%', '%prePage%', '%linkPage%', '%nextPage%', '%end%'], [$this->config['header'], $this->nowPage, $this->totalRows, $this->totalPages, $upPage, $downPage, $theFirst, $prePage, $linkPage, $nextPage, $theEnd], $this->config['theme']);
     return '<ul>' . $pageStr . '</ul>';
 }
Esempio n. 26
0
 /**
  * 检查对应的权限
  *
  * @param object|string $controller 传入控制器实例对象,用来判断当前访问的方法是不是要跳过权限检查。
  * 如当前访问的方法为web/User/list则传入new \web\Controller\User()获得的实例。最常用的是在基础控制器的init方法或构造方法里传入$this。
  * 传入字符串如web/User/list时会自动 new \web\Controller\User()获取实例用于判断
  *
  * @return int 返回1是通过检查,0是不能通过检查
  */
 public static function checkAcl($controller)
 {
     $authInfo = self::getLoginInfo();
     if (!$authInfo) {
         return false;
     }
     //登录超时
     //当前登录用户是否为超级管理员
     if (self::isSuperUser()) {
         return true;
     }
     $checkUrl = Cml::getContainer()->make('cml_route')->getFullPathNotContainSubDir();
     $checkAction = Cml::getContainer()->make('cml_route')->getActionName();
     if (is_string($controller)) {
         $checkUrl = trim($controller, '/\\');
         $controller = str_replace('/', '\\', $checkUrl);
         $actionPosition = strrpos($controller, '\\');
         $checkAction = substr($controller, $actionPosition + 1);
         $offset = $appPosition = 0;
         for ($i = 0; $i < Config::get('route_app_hierarchy', 1); $i++) {
             $appPosition = strpos($controller, '\\', $offset);
             $offset = $appPosition + 1;
         }
         $appPosition = $offset - 1;
         $subString = substr($controller, 0, $appPosition) . '\\' . Cml::getApplicationDir('app_controller_path_name') . substr($controller, $appPosition, $actionPosition - $appPosition);
         $controller = "\\{$subString}" . Config::get('controller_suffix');
         if (class_exists($controller)) {
             $controller = new $controller();
         } else {
             return false;
         }
     }
     $checkUrl = ltrim(str_replace('\\', '/', $checkUrl), '/');
     if (is_object($controller)) {
         //判断是否有标识 @noacl 不检查权限
         $reflection = new \ReflectionClass($controller);
         $methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
         foreach ($methods as $method) {
             if ($method->name == $checkAction) {
                 $annotation = $method->getDocComment();
                 if (strpos($annotation, '@noacl') !== false) {
                     return true;
                 }
                 $checkUrlArray = [];
                 if (preg_match('/@acljump([^\\n]+)/i', $annotation, $aclJump)) {
                     if (isset($aclJump[1]) && $aclJump[1]) {
                         $aclJump[1] = explode('|', $aclJump[1]);
                         foreach ($aclJump[1] as $val) {
                             trim($val) && ($checkUrlArray[] = ltrim(str_replace('\\', '/', trim($val)), '/'));
                         }
                     }
                     empty($checkUrlArray) || ($checkUrl = $checkUrlArray);
                 }
             }
         }
     }
     $acl = Model::getInstance()->db()->columns('m.id')->table(['access' => 'a'])->join(['menus' => 'm'], 'a.menuid=m.id')->lBrackets()->whereIn('a.groupid', $authInfo['groupid'])->_or()->where('a.userid', $authInfo['id'])->rBrackets();
     $acl = is_array($checkUrl) ? $acl->whereIn('m.url', $checkUrl) : $acl->where('m.url', $checkUrl);
     $acl = $acl->select();
     return count($acl) > 0;
 }
Esempio n. 27
0
/**
 * 快速文件数据读取和保存 针对简单类型数据 字符串、数组
 *
 * @param string $name 缓存名称
 * @param mixed $value 缓存值
 * @param string $path 缓存路径
 *
 * @return mixed
 */
function simpleFileCache($name, $value = '', $path = null)
{
    is_null($path) && ($path = Cml::getApplicationDir('global_store_path') . DIRECTORY_SEPARATOR . 'Data');
    static $_cache = [];
    $filename = $path . '/' . $name . '.php';
    if ($value !== '') {
        if (is_null($value)) {
            // 删除缓存
            return false !== @unlink($filename);
        } else {
            if (is_array($value)) {
                // 缓存数据
                $dir = dirname($filename);
                // 目录不存在则创建
                is_dir($dir) || mkdir($dir, 0700, true);
                $_cache[$name] = $value;
                return file_put_contents($filename, "<?php\treturn " . var_export($value, true) . ";?>", LOCK_EX);
            } else {
                return false;
            }
        }
    }
    if (isset($_cache[$name])) {
        return $_cache[$name];
    }
    // 获取缓存数据
    if (is_file($filename)) {
        $value = Cml::requireFile($filename);
        $_cache[$name] = $value;
    } else {
        $value = false;
    }
    return $value;
}
Esempio n. 28
0
 /**
  * 创建一个迁移
  *
  * @param array $args 参数
  * @param array $options 选项
  */
 public function execute(array $args, array $options = [])
 {
     $className = $args[0];
     $this->bootstrap($args, $options);
     if (!Util::isValidPhinxClassName($className)) {
         throw new \InvalidArgumentException(sprintf('The migration class name "%s" is invalid. Please use CamelCase format.', $className));
     }
     // get the migration path from the config
     $path = $this->getConfig()->getMigrationPath();
     if (!is_dir($path)) {
         $ask = new Dialog();
         if ($ask->confirm(Colour::colour('Create migrations directory?', [Colour::RED, Colour::HIGHLIGHT]))) {
             mkdir($path, 0755, true);
         }
     }
     $this->verifyMigrationDirectory($path);
     $path = realpath($path);
     if (!Util::isUniqueMigrationClassName($className, $path)) {
         throw new \InvalidArgumentException(sprintf('The migration class name "%s" already exists', $className));
     }
     // Compute the file path
     $fileName = Util::mapClassNameToFileName($className);
     $filePath = $path . DIRECTORY_SEPARATOR . $fileName;
     if (is_file($filePath)) {
         throw new \InvalidArgumentException(sprintf('The file "%s" already exists', $filePath));
     }
     // Get the alternative template and static class options from the command line, but only allow one of them.
     $altTemplate = $options['template'];
     $creationClassName = $options['class'];
     if ($altTemplate && $creationClassName) {
         throw new \InvalidArgumentException('Cannot use --template and --class at the same time');
     }
     // Verify the alternative template file's existence.
     if ($altTemplate && !is_file($altTemplate)) {
         throw new \InvalidArgumentException(sprintf('The alternative template file "%s" does not exist', $altTemplate));
     }
     if ($creationClassName) {
         // Supplied class does not exist, is it aliased?
         if (!class_exists($creationClassName)) {
             throw new \InvalidArgumentException(sprintf('The class "%s" does not exist', $creationClassName));
         }
         // Does the class implement the required interface?
         if (!is_subclass_of($creationClassName, self::CREATION_INTERFACE)) {
             throw new \InvalidArgumentException(sprintf('The class "%s" does not implement the required interface "%s"', $creationClassName, self::CREATION_INTERFACE));
         }
     }
     // Determine the appropriate mechanism to get the template
     if ($creationClassName) {
         // Get the template from the creation class
         $creationClass = new $creationClassName();
         $contents = $creationClass->getMigrationTemplate();
     } else {
         // Load the alternative template if it is defined.
         $contents = file_get_contents($altTemplate ?: $this->getMigrationTemplateFilename());
     }
     // inject the class names appropriate to this migration
     $classes = ['$useClassName' => $this->getConfig()->getMigrationBaseClassName(false), '$className' => $className, '$version' => Util::getVersionFromFileName($fileName), '$baseClassName' => $this->getConfig()->getMigrationBaseClassName(true)];
     $contents = strtr($contents, $classes);
     if (false === file_put_contents($filePath, $contents)) {
         throw new \RuntimeException(sprintf('The file "%s" could not be written to', $path));
     }
     // Do we need to do the post creation call to the creation class?
     if ($creationClassName) {
         $creationClass->postMigrationCreation($filePath, $className, $this->getConfig()->getMigrationBaseClassName());
     }
     Output::writeln('using migration base class ' . Colour::colour($classes['$useClassName'], Colour::GREEN));
     if (!empty($altTemplate)) {
         Output::writeln('using alternative template ' . Colour::colour($altTemplate, Colour::GREEN));
     } elseif (!empty($creationClassName)) {
         Output::writeln('using template creation class ' . Colour::colour($creationClassName, Colour::GREEN));
     } else {
         Output::writeln('using default template');
     }
     Output::writeln('created ' . str_replace(Cml::getApplicationDir('secure_src'), '{secure_src}', $filePath));
 }
Esempio n. 29
0
    Cml::getContainer()->singleton('cml_debug', \Cml\Debug::class);
    //必须绑定。命令行组件
    Cml::getContainer()->singleton('cml_console', \Cml\Console\Console::class);
    //可选,队列服务 内置 \Cml\Queue\Redis::class.(内置的redis服务与缓存挂钩)参考 http://doc.cmlphp.com/devintro/quenue.html
    //自定义服务实现\Cml\Interfaces\Queue接口即可或继承\Cml\Queue\Base再按需重载
    Cml::getContainer()->singleton('cml_queue', \Cml\Queue\Redis::class);
    //可选,锁服务 内置\Cml\Lock\File::class|\Cml\Lock\Redis::class|\Cml\Lock\Memcache::class三种.
    //内置的redis锁跟/memcache锁 跟缓存服务挂钩。参考 http://doc.cmlphp.com/devintro/lock.html
    //自定义服务实现\Cml\Interfaces\Lock接口即可或继承\Cml\Lock\Base再按需重载
    Cml::getContainer()->singleton('cml_lock', \Cml\Lock\Redis::class);
    //可选。绑定要用到视图引擎内置以下5种 以view_为前缀,用的时候不用带前缀如使用view_html视图服务: \Cml\View::getEngine('html');
    //\Cml\View::getEngine();不传类型的时候,使用的引擎可在配置文件中配置 'view_render_engine' => 'Html'默认为view_html
    //自定义服务实现\Cml\Interfaces\View接口即可或继承\Cml\View\Base再按需重载
    Cml::getContainer()->singleton('view_html', \Cml\View\Html::class);
    Cml::getContainer()->singleton('view_json', \Cml\View\Json::class);
    Cml::getContainer()->singleton('view_blade', \Cml\Service\Blade::class);
    //blade模板引擎,使用前安装依赖。composer require linhecheng/cmlphp-ext-blade
    //Cml::getContainer()->singleton('view_excel', \Cml\View\Excel::class);
    //Cml::getContainer()->singleton('view_xml', \Cml\View\Xml::class);
    //可选,db 允许多种驱动同时使用。因同种数据库可能同时连多个.这边不使用单例绑定.内置 \Cml\Db\MySql\Pdo::class|\Cml\Db\MongoDB\MongoDB::class 两种数据库支持.
    //自定义数据库驱动实现\Cml\Interfaces\Db接口即可或继承\Cml\Db\Base再按需重载
    Cml::getContainer()->bind('db_mysql', \Cml\Db\MySql\Pdo::class);
    //Cml::getContainer()->bind('db_mongodb', \Cml\Db\MongoDB\MongoDB::class);
    //可选,cache  允许多种驱动同时使用。如即使用memcache又使用redis.有使用数据库时至少要启用一种缓存,因同种缓存可能同时连多个.这边不使用单例绑定。
    // 内置 \Cml\Cache\Redis::class|\Cml\Cache\File::class | \Cml\Cache\Memcache::class | \Cml\Cache\Apc::class 四种缓存支持.
    //自定义数据库驱动实现\Cml\Interfaces\Cache接口即可或继承\Cml\Cache\Base再按需重载
    Cml::getContainer()->bind('cache_redis', \Cml\Cache\Redis::class);
    Cml::getContainer()->bind('cache_file', \Cml\Cache\File::class);
    //Cml::getContainer()->bind('cache_memcache', \Cml\Cache\Memcache::class);
    //Cml::getContainer()->bind('cache_apc', \Cml\Cache\Memcache::class);
});
Esempio n. 30
0
 /**
  * 初始化环境
  *
  */
 private static function initEvn()
 {
     if (!self::$pidFile) {
         self::$pidFile = Cml::getApplicationDir('global_store_path') . DIRECTORY_SEPARATOR . 'DaemonProcess_.pid';
         self::$log = Cml::getApplicationDir('global_store_path') . DIRECTORY_SEPARATOR . 'DaemonProcess_.log';
         self::$status = Cml::getApplicationDir('global_store_path') . DIRECTORY_SEPARATOR . 'DaemonProcessStatus.php';
         self::checkExtension();
     }
 }