From 9b51c138dc133cd0b0fcbd65a82b234cc707f248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=80=A1=E6=A0=8B?= Date: Tue, 9 Nov 2021 08:47:24 +0800 Subject: [PATCH] * adjust for multilingual api. --- api/v1/entries/groups.php | 49 ++++++++++++ api/v1/entries/views.php | 46 +++++++++++ config/routes.php | 2 + framework/base/control.class.php | 1 - framework/base/router.class.php | 129 +++++++++++++++++++++++++++++-- framework/control.class.php | 25 ++++++ framework/helper.class.php | 21 ++++- 7 files changed, 262 insertions(+), 11 deletions(-) create mode 100644 api/v1/entries/groups.php create mode 100644 api/v1/entries/views.php diff --git a/api/v1/entries/groups.php b/api/v1/entries/groups.php new file mode 100644 index 0000000000..48e5729431 --- /dev/null +++ b/api/v1/entries/groups.php @@ -0,0 +1,49 @@ + + * @package entries + * @version 1 + * @link http://www.zentao.net + */ +class groupsEntry extends entry +{ + /** + * GET method. + * + * @access public + * @return void + */ + public function get() + { + $groups = $this->loadModel('group')->getList(); + $privsGroup = $this->dao->select('`group`,module, method')->from(TABLE_GROUPPRIV)->orderBy('module')->fetchGroup('group'); + $usersGroup = $this->dao->select('t1.`group`,t1.account,t2.realname')->from(TABLE_USERGROUP)->alias('t1') + ->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account') + ->fetchGroup('group'); + + foreach($groups as $i => $group) + { + if($group->acl) + { + $acl = json_decode($group->acl, true); + $group->acl = array(); + $group->acl['views'] = $acl['views']; + } + $privs = zget($privsGroup, $group->id, array()); + $group->privs = array(); + foreach($privs as $priv) $group->privs[$priv->module][$priv->method] = true; + + $accounts = zget($usersGroup, $group->id, array()); + $group->accounts = array(); + foreach($accounts as $account) $group->accounts[$account->account] = $account->realname; + + $groups[$i] = $group; + } + + return $this->send(200, $groups); + } +} diff --git a/api/v1/entries/views.php b/api/v1/entries/views.php new file mode 100644 index 0000000000..f2b27bef9a --- /dev/null +++ b/api/v1/entries/views.php @@ -0,0 +1,46 @@ + + * @package entries + * @version 1 + * @link http://www.zentao.net + */ +class viewsEntry extends entry +{ + /** + * GET method. + * + * @access public + * @return void + */ + public function get() + { + $position = $this->param('position', ''); + $lite = $this->param('lite', ''); + + if(empty($position)) return $this->sendError(400, 'Need position param.'); + if($position != 'header' and $position != 'footer') return $this->sendError(400, 'Value of position param only is header or footer.'); + if(!empty($lite)) $lite .= 'lite.'; + + $viewFile = $this->app->moduleRoot . "common/view/{$position}.{$lite}html.php"; + if(!file_exists($viewFile)) return $this->sendError(400, 'This view file is not exists.'); + + $controller = new control(); + $viewHookFiles = glob($this->app->moduleRoot . "common/ext/view/{$position}.*.html.hook.php"); + + $output = ''; + if($position == 'header') $output .= $controller->printViewFile($viewFile); + foreach($viewHookFiles as $hookFile) $output .= $controller->printViewFile($hookFile); + if($position == 'footer') $output .= $controller->printViewFile($viewFile); + + $sysURL = common::getSysURL(); + $output = str_replace("href='{$this->config->webRoot}", "href='{$sysURL}{$this->config->webRoot}", $output); + $output = str_replace("src='{$this->config->webRoot}", "src='{$sysURL}{$this->config->webRoot}", $output); + + return $this->send(200, array('html' => $output)); + } +} diff --git a/config/routes.php b/config/routes.php index 312ad92c22..a2ab2f9b3a 100644 --- a/config/routes.php +++ b/config/routes.php @@ -6,6 +6,8 @@ $routes = array(); $routes['/tokens'] = 'tokens'; $routes['/langs'] = 'langs'; +$routes['/views'] = 'views'; +$routes['/groups'] = 'groups'; $routes['/tabs/:module'] = 'tabs'; diff --git a/framework/base/control.class.php b/framework/base/control.class.php index 761e30c573..2b44e11ad8 100644 --- a/framework/base/control.class.php +++ b/framework/base/control.class.php @@ -1,5 +1,4 @@ config->framework->extensionLevel == 2 and !empty( $moduleExtPaths['site'])) { + $locateFile = $moduleExtPaths['site'] . $this->methodName . '.302'; + if(file_exists($locateFile)) $this->sendAPI($locateFile); + $requestFile = $moduleExtPaths['site'] . $this->methodName . '.api'; + if(file_exists($requestFile)) $this->sendAPI($requestFile); + $this->extActionFile = $moduleExtPaths['site'] . $this->methodName . '.php'; if(file_exists($this->extActionFile)) return true; } /* 然后再尝试寻找公共扩展文件。Then try to find the common extension file. */ + $locateFile = $moduleExtPaths['common'] . $this->methodName . '.302'; + if(file_exists($locateFile)) $this->sendAPI($locateFile); + $requestFile = $moduleExtPaths['common'] . $this->methodName . '.api'; + if(file_exists($requestFile)) $this->sendAPI($requestFile); + $this->extActionFile = $moduleExtPaths['common'] . $this->methodName . '.php'; return file_exists($this->extActionFile); } @@ -1429,6 +1439,7 @@ class baseRouter /* 计算扩展的文件和hook文件。Compute the extension files and hook files. */ $hookFiles = array(); $extFiles = array(); + $apiFiles = array(); $siteExtended = false; $modelExtPaths = $this->getModuleExtPath($appName, $moduleName, 'model'); @@ -1438,14 +1449,16 @@ class baseRouter $tmpHookFiles = helper::ls($modelExtPath . 'hook/', '.php'); $tmpExtFiles = helper::ls($modelExtPath, '.php'); + $tmpAPIFiles = helper::ls($modelExtPath, '.api'); $hookFiles = array_merge($hookFiles, $tmpHookFiles); $extFiles = array_merge($extFiles, $tmpExtFiles); + $apiFiles = array_merge($apiFiles, $tmpAPIFiles); - if($extType == 'site' and (!empty($tmpHookFiles) or !empty($tmpExtFiles))) $siteExtended = true; + if($extType == 'site' and (!empty($tmpHookFiles) or !empty($tmpExtFiles) or !empty($tmpAPIFiles))) $siteExtended = true; } /* 如果没有扩展文件,返回主文件。 If no extension or hook files, return the main file directly. */ - if(empty($extFiles) and empty($hookFiles)) return $mainModelFile; + if(empty($extFiles) and empty($hookFiles) and empty($apiFiles)) return $mainModelFile; /* 计算合并之后的modelFile路径。Compute the merged model file path. */ $extModelPrefix = ($siteExtended and !empty($this->siteCode)) ? $this->siteCode[0] . DS . $this->siteCode : ''; @@ -1454,11 +1467,11 @@ class baseRouter if(!is_dir($mergedModelDir)) mkdir($mergedModelDir, 0755, true); /* 判断生成的缓存文件是否需要更新。 Judge whether the merged model file needed update or not. */ - if(!$this->needModelFileUpdate($mergedModelFile, $extFiles, $hookFiles, $modelExtPaths, $mainModelFile)) return $mergedModelFile; + if(!$this->needModelFileUpdate($mergedModelFile, $extFiles, $hookFiles, $apiFiles, $modelExtPaths, $mainModelFile)) return $mergedModelFile; /* 合并扩展和hook文件。Merge the extension and hook files. */ $modelLines = $this->mergeModelExtFiles($moduleName, $mainModelFile, $extFiles, $mergedModelDir); - $this->mergeModelHookFiles($moduleName, $mainModelFile, $modelLines, $hookFiles, $mergedModelDir, $mergedModelFile); + $this->mergeModelHookFiles($moduleName, $mainModelFile, $modelLines, $hookFiles, $mergedModelDir, $mergedModelFile, $apiFiles); return $mergedModelFile; } @@ -1466,20 +1479,22 @@ class baseRouter /** * 检查合并之后的model文件是否需要更新。Check whether the merged model file need update or not. * - * @param string $mainModelFile * @param string $mergedModelFile - * @param string $modelExtPaths * @param array $extFiles * @param array $hookFiles + * @param array $apiFiles + * @param string $modelExtPaths + * @param string $mainModelFile * @access public * @return bool */ - public function needModelFileUpdate($mergedModelFile, $extFiles, $hookFiles, $modelExtPaths, $mainModelFile) + public function needModelFileUpdate($mergedModelFile, $extFiles, $hookFiles, $apiFiles, $modelExtPaths, $mainModelFile) { $lastTime = file_exists($mergedModelFile) ? filemtime($mergedModelFile) : 0; foreach($extFiles as $extFile) if(filemtime($extFile) > $lastTime) return true; foreach($hookFiles as $hookFile) if(filemtime($hookFile) > $lastTime) return true; + foreach($apiFiles as $apiFile) if(filemtime($apiFile) > $lastTime) return true; $modelExtPath = $modelExtPaths['common']; $modelHookPath = $modelExtPaths['common'] . 'hook/'; @@ -1547,7 +1562,7 @@ class baseRouter * @access public * @return void */ - public function mergeModelHookFiles($moduleName, $mainModelFile, $modelLines, $hookFiles, $mergedModelDir, $mergedModelFile) + public function mergeModelHookFiles($moduleName, $mainModelFile, $modelLines, $hookFiles, $mergedModelDir, $mergedModelFile, $apiFiles) { /* 定义相关变量。Init vars. */ $modelClass = $moduleName . 'Model'; @@ -1558,6 +1573,15 @@ class baseRouter /* 读取hook文件。Get hook codes need to merge. */ $hookCodes = array(); + foreach($apiFiles as $apiFile) + { + /* 通过文件名获得其对应的方法名。Get methods according it's filename. */ + $fileName = baseName($apiFile); + list($method) = explode('.', $fileName); + + $url = self::extractAPIURL($apiFile); + if($url) $hookCodes[$method][] = "return helper::requestAPI('$url');"; + } foreach($hookFiles as $hookFile) { /* 通过文件名获得其对应的方法名。Get methods according it's filename. */ @@ -1611,6 +1635,95 @@ class baseRouter return trim($code); } + /** + * Extract API url from api file. + * + * @param string $fileName + * @static + * @access public + * @return string + */ + static public function extractAPIURL($fileName) + { + global $config; + + $url = ''; + $lines = file($fileName); + foreach($lines as $line) + { + $line = trim($line); + + if(empty($line)) continue; + if(preg_match('/^https?\:\/\//', $line)) + { + $url = $line; + break; + } + } + if(empty($url)) return false; + return $url; + } + + /** + * Send API. + * + * @param string $apiFile + * @access public + * @return void + */ + public function sendAPI($apiFile) + { + $extension = substr($apiFile, strrpos($apiFile, '.') + 1); + if($extension != '302' and $extension != 'api') return false; + + $lines = file($apiFile); + $url = ''; + foreach($lines as $line) + { + $line = trim($line); + + if(empty($line)) continue; + if(preg_match('/^https?\:\/\//', $line)) + { + $url = $line; + break; + } + } + if(empty($url)) return false; + + $url .= (strpos($url, '?') !== false ? '&' : '?') . $this->config->sessionVar . '=' . session_id() . '&account=' . $_SESSION['user']->account; + if($extension == '302') + { + header("location: $url"); + exit; + } + + if($extension == 'api') + { + $response = common::http($url); + $headFile = $this->moduleRoot . 'common/view/header.html.php'; + $footFile = $this->moduleRoot . 'common/view/footer.html.php'; + + $obLevel = ob_get_level(); + for($i = 0; $i < $obLevel; $i++) ob_end_clean(); + + $controller = new control(); + $viewFiles = $controller->setViewFile($this->moduleName, $this->methodName); + + $css = $controller->getCSS($this->moduleName, $this->methodName); + $js = $controller->getJS($this->moduleName, $this->methodName); + if($css) $controller->view->pageCSS = $css; + if($js) $controller->view->pageJS = $js; + + $output = ''; + $output .= $controller->printViewFile($headFile); + $output .= $response; + if(isset($viewFiles['hookFiles'])) foreach($viewFiles['hookFiles'] as $hookFile) $output .= $controller->printViewFile($hookFile); + $output .= $controller->printViewFile($footFile); + die($output); + } + } + //-------------------- 路由相关方法(Routing related methods) --------------------// /** diff --git a/framework/control.class.php b/framework/control.class.php index 3ee876480c..bb99722b61 100644 --- a/framework/control.class.php +++ b/framework/control.class.php @@ -420,4 +420,29 @@ class control extends baseControl } if($message) $this->send(array('result' => 'fail', 'message' => $message)); } + + /** + * Print view file. + * + * @param string $viewFile + * @access public + * @return void + */ + public function printViewFile($viewFile) + { + if(!file_exists($viewFile)) return false; + + $currentPWD = getcwd(); + chdir(dirname($viewFile)); + + extract((array)$this->view); + ob_start(); + include $viewFile; + $output = ob_get_contents(); + ob_end_clean(); + + chdir($currentPWD); + + return $output; + } } diff --git a/framework/helper.class.php b/framework/helper.class.php index fe2f3683c3..27c43274dc 100644 --- a/framework/helper.class.php +++ b/framework/helper.class.php @@ -228,6 +228,23 @@ class helper extends baseHelper $version ); } + + /** + * Request API. + * + * @param string $url + * @static + * @access public + * @return string + */ + static public function requestAPI($url) + { + global $config; + + $url .= (strpos($url, '?') !== false ? '&' : '?') . $config->sessionVar . '=' . session_id(); + if(isset($_SESSION['user'])) $url .= '&account=' . $_SESSION['user']->account; + return common::http($url); + } } /** @@ -261,8 +278,8 @@ function formatTime($time, $format = '') /** * Fix for session error. - * - * @param int $class + * + * @param int $class * @access protected * @return void */