From 308bb3d1bef5eca596aea52a8a046722c166fa64 Mon Sep 17 00:00:00 2001 From: liugang Date: Mon, 8 Jul 2019 10:56:47 +0800 Subject: [PATCH] * If the module and method if defined in workflow, run workflow engine. --- framework/base/router.class.php | 2 +- framework/control.class.php | 61 +++++++++++++ framework/model.class.php | 43 ++++++++- framework/router.class.php | 156 ++++++++++++++++++++++++++++++-- 4 files changed, 250 insertions(+), 12 deletions(-) diff --git a/framework/base/router.class.php b/framework/base/router.class.php index 5e083621ed..214451ade0 100644 --- a/framework/base/router.class.php +++ b/framework/base/router.class.php @@ -1599,8 +1599,8 @@ class baseRouter $moduleName = isset($_GET[$this->config->moduleVar]) ? strtolower($_GET[$this->config->moduleVar]) : $this->config->default->module; $methodName = isset($_GET[$this->config->methodVar]) ? strtolower($_GET[$this->config->methodVar]) : $this->config->default->method; $this->setModuleName($moduleName); - $this->setControlFile(); $this->setMethodName($methodName); + $this->setControlFile(); } /** diff --git a/framework/control.class.php b/framework/control.class.php index 0415ebb1ab..e0cd41b5b8 100644 --- a/framework/control.class.php +++ b/framework/control.class.php @@ -20,6 +20,67 @@ include dirname(__FILE__) . '/base/control.class.php'; class control extends baseControl { + /** + * 加载指定模块的model文件。 + * Load the model file of one module. + * + * Extension: set appName as empty. + * + * @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name. + * @param string $appName The app name, if empty, use current app's name. + * @access public + * @return object|bool 如果没有model文件,返回false,否则返回model对象。If no model file, return false, else return the model object. + */ + public function loadModel($moduleName = '', $appName = '') + { + $appName = ''; + + if(empty($moduleName)) $moduleName = $this->moduleName; + if(empty($appName)) $appName = $this->appName; + + global $loadedModels; + if(isset($loadedModels[$appName][$moduleName])) + { + $this->$moduleName = $loadedModels[$appName][$moduleName]; + $this->dao = $this->$moduleName->dao; + return $this->$moduleName; + } + + $modelFile = $this->app->setModelFile($moduleName, $appName); + + /** + * 如果没有model文件,尝试加载config配置信息。 + * If no model file, try load config. + */ + if(!helper::import($modelFile)) + { + $this->app->loadModuleConfig($moduleName, $appName); + $this->app->loadLang($moduleName, $appName); + $this->dao = new dao(); + return false; + } + + /** + * 如果没有扩展文件,model类名是$moduleName + 'model',如果有扩展,还需要增加ext前缀。 + * If no extension file, model class name is $moduleName + 'model', else with 'ext' as the prefix. + */ + $modelClass = class_exists('ext' . $appName . $moduleName. 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model'; + if(!class_exists($modelClass)) + { + $modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model'; + if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true); + } + + /** + * 初始化model对象,在control对象中可以通过$this->$moduleName来引用。同时将dao对象赋为control对象的成员变量,方便引用。 + * Init the model object thus you can try $this->$moduleName to access it. Also assign the $dao object as a member of control object. + */ + $loadedModels[$appName][$moduleName] = new $modelClass($appName); + $this->$moduleName = $loadedModels[$appName][$moduleName]; + $this->dao = $this->$moduleName->dao; + return $this->$moduleName; + } + /** * 设置视图文件:主视图文件,扩展视图文件, 站点扩展视图文件,以及钩子脚本。 * Set view files: the main file, extension view file, site extension view file and hook files. diff --git a/framework/model.class.php b/framework/model.class.php index 2335d5dd18..f7fb367e93 100644 --- a/framework/model.class.php +++ b/framework/model.class.php @@ -20,10 +20,51 @@ include dirname(__FILE__) . '/base/model.class.php'; class model extends baseModel { + /** + * 加载一个模块的model。加载完成后,使用$this->$moduleName来访问这个model对象。 + * 比如:loadModel('user')引入user模块的model实例对象,可以通过$this->user来访问它。 + * + * Load the model of one module. After loaded, can use $this->$moduleName to visit the model object. + * + * Extension: set appName as empty. + * + * @param string $moduleName + * @access public + * @return object|bool the model object or false if model file not exists. + */ + public function loadModel($moduleName, $appName = '') + { + $appName = ''; + + if(empty($moduleName)) return false; + if(empty($appName)) $appName = $this->appName; + + global $loadedModels; + if(isset($loadedModels[$appName][$moduleName])) + { + $this->$moduleName = $loadedModels[$appName][$moduleName]; + return $this->$moduleName; + } + + $modelFile = $this->app->setModelFile($moduleName, $appName); + + if(!helper::import($modelFile)) return false; + $modelClass = class_exists('ext' . $appName . $moduleName. 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model'; + if(!class_exists($modelClass)) + { + $modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model'; + if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true); + } + + $loadedModels[$appName][$moduleName] = new $modelClass($appName); + $this->$moduleName = $loadedModels[$appName][$moduleName]; + return $this->$moduleName; + } + /** * 删除记录 * Delete one record. - * + * * @param string $table the table name * @param string $id the id value of the record to be deleted * @access public diff --git a/framework/router.class.php b/framework/router.class.php index dae5246afe..8bb5971aa1 100755 --- a/framework/router.class.php +++ b/framework/router.class.php @@ -20,6 +20,24 @@ include dirname(__FILE__) . '/base/router.class.php'; class router extends baseRouter { + /** + * 工作流模块名。 + * The module name of a flow. + * + * @var string + * @access public + */ + public $workflowModule; + + /** + * 工作流方法名。 + * The method name of a flow. + * + * @var string + * @access public + */ + public $workflowMethod; + /** * Add custom langs when set client lang. * @@ -38,7 +56,7 @@ class router extends baseRouter /** * 加载语言文件,返回全局$lang对象。 * Load lang and return it as the global lang object. - * + * * @param string $moduleName the module name * @param string $appName the app name * @access public @@ -49,6 +67,8 @@ class router extends baseRouter global $lang; if(!is_object($lang)) $lang = new language(); + $appName = ''; + /* Set productCommon and projectCommon for flow. */ if($moduleName == 'common') { @@ -123,11 +143,11 @@ class router extends baseRouter /** * Save error info. - * - * @param int $level - * @param string $message - * @param string $file - * @param int $line + * + * @param int $level + * @param string $message + * @param string $file + * @param int $line * @access public * @return void */ @@ -141,22 +161,83 @@ class router extends baseRouter parent::saveError($level, $message, $file, $line); } + /** + * 加载模块的config文件,返回全局$config对象。 + * 如果该模块是common,加载$configRoot的配置文件,其他模块则加载其模块的配置文件。 + * + * Load config and return it as the global config object. + * If the module is common, search in $configRoot, else in $modulePath. + * + * Extension: set appName as empty. + * + * @param string $moduleName module name + * @param string $appName app name + * @param bool $exitIfNone exit or not + * @access public + * @return object|bool the config object or false. + */ + public function loadModuleConfig($moduleName, $appName = '') + { + global $config; + + $appName = ''; + + if($config and (!isset($config->$moduleName) or !is_object($config->$moduleName))) $config->$moduleName = new stdclass(); + + /* 初始化数组。Init the variables. */ + $extConfigFiles = array(); + $commonExtConfigFiles = array(); + $siteExtConfigFiles = array(); + + /* 先获得模块的主配置文件。Get the main config file for current module first. */ + $mainConfigFile = $this->getModulePath($appName, $moduleName) . 'config.php'; + + /* 查找扩展配置文件。Get extension config files. */ + if($config->framework->extensionLevel > 0) $extConfigPath = $this->getModuleExtPath($appName, $moduleName, 'config'); + if($config->framework->extensionLevel >= 1 and !empty($extConfigPath['common'])) $commonExtConfigFiles = helper::ls($extConfigPath['common'], '.php'); + if($config->framework->extensionLevel == 2 and !empty($extConfigPath['site'])) $siteExtConfigFiles = helper::ls($extConfigPath['site'], '.php'); + $extConfigFiles = array_merge($commonExtConfigFiles, $siteExtConfigFiles); + + /* 将主配置文件和扩展配置文件合并在一起。Put the main config file and extension config files together. */ + $configFiles = array_merge(array($mainConfigFile), $extConfigFiles); + + /* 加载每一个配置文件。Load every config file. */ + static $loadedConfigs = array(); + foreach($configFiles as $configFile) + { + if(in_array($configFile, $loadedConfigs)) continue; + if(file_exists($configFile)) include $configFile; + $loadedConfigs[] = $configFile; + } + + /* 加载数据库中与本模块相关的配置项。Merge from the db configs. */ + if($moduleName != 'common') + { + if(isset($config->system->$moduleName)) $this->mergeConfig($config->system->$moduleName, $moduleName); + if(isset($config->personal->$moduleName)) $this->mergeConfig($config->personal->$moduleName, $moduleName); + } + } + /** * Alias load module config. - * - * @param string $moduleName - * @param string $appName + * + * Extension: set appName as empty. + * + * @param string $moduleName + * @param string $appName * @access public * @return void */ public function loadConfig($moduleName, $appName = '') { + $appName = ''; + return parent::loadModuleConfig($moduleName, $appName); } /** * Export config. - * + * * @access public * @return void */ @@ -173,6 +254,46 @@ class router extends baseRouter echo json_encode($view); } + /** + * 设置要被调用的控制器文件。 + * Set the control file of the module to be called. + * + * Extension: If the module and method is defined in workflow, run workflow engine. + * + * @param bool $exitIfNone 没有找到该控制器文件的情况:如果该参数为true,则终止程序;如果为false,则打印错误日志 + * If control file not foundde, how to do. True, die the whole app. false, log error. + * @access public + * @return bool + */ + public function setControlFile($exitIfNone = true) + { + /* If the module and method is defined in workflow, run workflow engine. */ + if(defined('TABLE_WORKFLOW')) + { + $flow = $this->dbh->query("SELECT * FROM " . TABLE_WORKFLOW . " WHERE `module` = '$this->moduleName'")->fetch(); + if($flow) + { + $action = $this->dbh->query("SELECT * FROM " . TABLE_WORKFLOWACTION . " WHERE `module` = '$this->moduleName' AND `action` = '$this->methodName'")->fetch(); + if($action) + { + $this->workflowModule = $this->moduleName; + $this->workflowMethod = $this->methodName; + + $this->loadModuleConfig('workflowaction'); + + $moduleName = 'flow'; + $methodName = in_array($this->methodName, $this->config->workflowaction->default->actions) ? $this->methodName : 'operate'; + + $this->setModuleName($moduleName); + $this->setMethodName($methodName); + } + } + } + + /* Call method of parent. */ + return parent::setControlFile($exitIfNone); + } + /** * PATH_INFO方式解析,获取$URI和$viewType。 * Parse PATH_INFO, get the $URI and $viewType. @@ -205,6 +326,8 @@ class router extends baseRouter * 合并请求的参数和默认参数,这样就可以省略已经有默认值的参数了。 * Merge the params passed in and the default params. Thus the params which have default values needn't pass value, just like a function. * + * Extension: If the workflowmodule and workflowmethod is not empty, reset the passed params. + * * @param array $defaultParams the default params defined by the method. * @param array $passedParams the params passed in through url. * @access public @@ -212,6 +335,19 @@ class router extends baseRouter */ public function mergeParams($defaultParams, $passedParams) { + /* If the workflowmodule and workflowmethod is not empty, reset the passed params. */ + if($this->workflowModule && $this->workflowMethod) + { + $passedParams = array_reverse($passedParams); + if(!in_array($this->workflowMethod, $this->config->workflowaction->default->actions)) + { + $passedParams['method'] = $this->workflowMethod; + } + $passedParams['module'] = $this->workflowModule; + + $passedParams = array_reverse($passedParams); + } + unset($passedParams['display']); return parent::mergeParams($defaultParams, $passedParams); }