Merge branch 'apiext'

This commit is contained in:
王怡栋
2021-12-17 18:00:31 +08:00
7 changed files with 291 additions and 11 deletions
+49
View File
@@ -0,0 +1,49 @@
<?php
/**
* The groups entry point of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @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);
}
}
+53
View File
@@ -0,0 +1,53 @@
<?php
/**
* The views entry point of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @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', '');
$tab = $this->param('tab', '');
$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.';
if($tab)
{
$_COOKIE['tab'] = $tab;
$this->app->setOpenApp();
}
$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));
}
}
+2
View File
@@ -6,6 +6,8 @@ $routes = array();
$routes['/tokens'] = 'tokens';
$routes['/langs'] = 'langs';
$routes['/views'] = 'views';
$routes['/groups'] = 'groups';
$routes['/ping'] = 'ping';
$routes['/comments'] = 'comments';
-1
View File
@@ -1,5 +1,4 @@
<?php
/**
* ZenTaoPHP的baseControl类。
* The baseControl class file of ZenTaoPHP framework.
+140 -8
View File
@@ -1408,6 +1408,37 @@ class baseRouter
return file_exists($this->extActionFile);
}
/**
* Check for API extend.
*
* @access public
* @return bool
*/
public function checkAPIFile()
{
$moduleExtPaths = $this->getModuleExtPath('', $this->moduleName, 'control');
/* 如果扩展目录为空,不包含任何扩展文件。If there's no ext paths return false.*/
if(empty($moduleExtPaths)) return false;
/* 如果extensionLevel == 2,且扩展文件存在,返回该站点扩展文件。If extensionLevel == 2 and site extensionFile exists, return it. */
if($this->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);
}
/* 然后再尝试寻找公共扩展文件。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);
return false;
}
/**
* 设置一个模块的model文件,如果存在model扩展,一起合并。
* Set the model file of one module. If there's an extension file, merge it with the main model file.
@@ -1429,6 +1460,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 +1470,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 +1488,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 +1500,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 +1583,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 +1594,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 +1656,92 @@ 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();
$viewFiles = $this->control->setViewFile($this->moduleName, $this->methodName);
if($css) $this->control->view->pageCSS = $css;
if($js) $this->control->view->pageJS = $js;
$output = '';
$output .= $this->control->printViewFile($headFile);
$output .= $response;
if(isset($viewFiles['hookFiles'])) foreach($viewFiles['hookFiles'] as $hookFile) $output .= $this->control->printViewFile($hookFile);
$output .= $this->control->printViewFile($footFile);
die($output);
}
}
//-------------------- 路由相关方法(Routing related methods) --------------------//
/**
@@ -1780,6 +1911,7 @@ class baseRouter
/* 调用该方法 Call the method. */
call_user_func_array(array($module, $methodName), $this->params);
$this->checkAPIFile();
return $module;
}
+25
View File
@@ -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;
}
}
+22 -2
View File
@@ -228,6 +228,26 @@ 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;
$response = common::http($url);
$jsonDecode = json_decode($response);
if(empty($jsonDecode)) return $response;
return $jsonDecode;
}
}
/**
@@ -261,8 +281,8 @@ function formatTime($time, $format = '')
/**
* Fix for session error.
*
* @param int $class
*
* @param int $class
* @access protected
* @return void
*/