diff --git a/lib/base/dao/dao.class.php b/lib/base/dao/dao.class.php index aabc2c9ce7..11512f4511 100644 --- a/lib/base/dao/dao.class.php +++ b/lib/base/dao/dao.class.php @@ -820,10 +820,11 @@ class baseDAO * 处理sql语句,替换表和字段。 * Process the sql, replace the table, fields. * + * @param string $filterTpl * @access public * @return string the sql string after process. */ - public function processSQL() + public function processSQL($filterTpl = true) { $sql = $this->sqlobj->get(); @@ -858,20 +859,50 @@ class baseDAO $sql .= '(`' . implode('`,`', array_keys($values)) . '`)' . ' VALUES(' . implode(',', $values) . ')'; } - elseif($this->method == 'select') + elseif($this->method == 'select' && $filterTpl) { /* 过滤模板类型的数据 */ foreach(array('project', 'task') as $table) { $table = $this->config->db->prefix . $table; if(strpos($sql, "`$table`") === false) continue; - if(preg_match("/isTpl\s*=\s*('1'|1)/", $sql)) continue; // 指定查询模板类型的数据则不过滤 + preg_match_all('/\(([^()]*SELECT\b.+?\bFROM\b[^()]*)\)/i', $sql, $matches); + if(!$matches[1]) + { + if(preg_match("/`isTpl`\s*=\s*('1'|1)/", $sql)) continue; // 指定查询模板类型的数据则不过滤 - $alias = preg_match("/`$table`\s+as\s+(\w+)/i", $sql, $matches) ? $matches[1] : ''; + $alias = preg_match("/`$table`\s+as\s+(\w+)/i", $sql, $matches) ? $matches[1] : ''; - $replace = $alias ? "wHeRe $alias.isTpl = '0' AND" : "wHeRe isTpl = '0' AND"; - $sql = str_ireplace("wHeRe", $replace, $sql); + $replace = $alias ? "wHeRe $alias.`isTpl` = '0' AND" : "wHeRe `isTpl` = '0' AND"; + $sql = str_ireplace("wHeRe", $replace, $sql); + } + else + { + if(preg_match("/`isTpl`\s*=\s*('1'|1)/", $sql)) continue; // 指定查询模板类型的数据则不过滤 + foreach($matches[1] as $index => $subSQL) + { + $sql = str_ireplace($subSQL, "$$index", $sql); + } + + if(strpos($sql, "`$table`") !== false) + { + $alias = preg_match("/`$table`\s+as\s+(\w+)/i", $sql, $mainMatches) ? $mainMatches[1] : ''; + $replace = $alias ? "wHeRe $alias.`isTpl` = '0' AND" : "wHeRe `isTpl` = '0' AND"; + $sql = str_ireplace("wHeRe", $replace, $sql); + } + + foreach($matches[1] as $index => $subSQL) + { + if(strpos($sql, "`$table`") !== false && !preg_match("/`isTpl`\s*=\s*('1'|1)/", $subSQL)) + { + $alias = preg_match("/`$table`\s+as\s+(\w+)/i", $subSQL, $subMatches) ? $subMatches[1] : ''; + $replace = $alias ? "wHeRe $alias.`isTpl` = '0' AND" : "wHeRe isTpl = '0' AND"; + $subSQL = str_ireplace("wHeRe", $replace, $subSQL); + } + $sql = str_ireplace("$$index", $subSQL, $sql); + } + } } } @@ -1240,7 +1271,7 @@ class baseDAO */ public function fetch($field = '') { - $sql = $this->processSQL(); + $sql = $this->processSQL(false); $key = $this->createCacheKey('fetch', md5($sql)); $result = $this->getCache($key); if($result === self::CACHE_MISS) diff --git a/module/execution/control.php b/module/execution/control.php index 4efd825551..b347f3f0c7 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -2967,13 +2967,9 @@ class execution extends control */ public function whitelist(int $executionID = 0, string $module='execution', string $objectType = 'sprint', string $orderBy = 'id_desc', int $recTotal = 0, int $recPerPage = 20, int $pageID = 1) { - /* use first execution if executionID does not exist. */ - if(!isset($this->executions[$executionID])) $executionID = key($this->executions); - /* Set the menu. If the executionID = 0, use the indexMenu instead. */ - $this->execution->setMenu($executionID); + $execution = $this->commonAction($executionID); - $execution = $this->execution->getByID($executionID); if(!empty($execution->acl) and $execution->acl != 'private') return $this->sendError($this->lang->whitelistNotNeed, $this->createLink('execution', 'task', "executionID=$executionID")); echo $this->fetch('personnel', 'whitelist', "objectID=$executionID&module=$module&browseType=$objectType&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"); @@ -3153,6 +3149,7 @@ class execution extends control */ public function doc(int $executionID = 0, int $libID = 0, int $moduleID = 0, string $browseType = 'all', string $orderBy = 'order_asc', int $param = 0, int $recTotal = 0, int $recPerPage = 20, int $pageID = 1, string $mode = 'list', int $docID = 0, string $search = '') { + $this->commonAction($executionID); echo $this->fetch('doc', 'app', "type=execution&spaceID=$executionID&libID=$libID&moduleID=$moduleID&docID=$docID&mode=$mode&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID&filterType=$browseType&search=$search&noSpace=true"); } diff --git a/module/execution/model.php b/module/execution/model.php index e8b46cde52..9abd363a7a 100755 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -107,8 +107,8 @@ class executionModel extends model $executions = $this->fetchPairs($execution->project, 'all'); if(!$executionID && $this->session->execution) $executionID = $this->session->execution; if(!$executionID) $executionID = key($executions); - if($execution->multiple and !isset($executions[$executionID])) $executionID = key($executions); - if($execution->multiple and $executions and (!isset($executions[$executionID]) or !$this->checkPriv($executionID))) return $this->accessDenied(); + if($execution->multiple && !$execution->isTpl && !isset($executions[$executionID])) $executionID = key($executions); + if($execution->multiple && !$execution->isTpl && $executions && (!isset($executions[$executionID]) || !$this->checkPriv($executionID))) return $this->accessDenied(); if(empty($executionID)) return; /* Replaces the iterated language with the stage. */ @@ -195,8 +195,10 @@ class executionModel extends model if(!$executionID && isset($this->config->execution->lastExecution)) $executionID = (int)$this->config->execution->lastExecution; } + /* 项目模板不校验访问权限。 */ + $isTpl = $this->dao->select('isTpl')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->fetch('isTpl'); /* If the execution doesn't exist in the list, use the first execution in the list. */ - if(!isset($executions[$executionID])) + if(!$isTpl && !isset($executions[$executionID])) { /* Check execution. */ if($executionID) @@ -1437,7 +1439,7 @@ class executionModel extends model { /* Construct the query SQL at search executions. */ $executionQuery = $browseType == 'bySearch' ? $this->getExecutionQuery($param) : ''; - $projectModel = $this->dao->select('model')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetch('model'); + $project = $this->dao->select('model,isTpl')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetch(); return $this->dao->select('t1.*,t2.name projectName, t2.model as projectModel')->from(TABLE_EXECUTION)->alias('t1') ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') @@ -1446,7 +1448,8 @@ class executionModel extends model ->andWhere('t1.deleted')->eq('0') ->andWhere('t1.vision')->eq($this->config->vision) ->andWhere('t1.multiple')->eq('1') - ->beginIF($projectModel == 'ipd')->andWhere('t1.enabled')->eq('on')->fi() + ->beginIF($project->model == 'ipd')->andWhere('t1.enabled')->eq('on')->fi() + ->beginIF($project->isTpl)->andWhere('t1.isTpl')->eq('1')->fi() ->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->sprints)->fi() ->beginIF(!empty($executionQuery))->andWhere($executionQuery)->fi() ->beginIF($productID)->andWhere('t3.product')->eq($productID)->fi() @@ -5017,6 +5020,7 @@ class executionModel extends model $executionData->openedBy = $this->app->user->account; $executionData->openedDate = helper::now(); $executionData->parent = $projectID; + $executionData->isTpl = $project->isTpl; if($project->code) $executionData->code = $project->code; $projectProducts = $this->dao->select('*')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchAll(); diff --git a/module/project/model.php b/module/project/model.php index 3cc597cc67..302d607324 100755 --- a/module/project/model.php +++ b/module/project/model.php @@ -76,8 +76,10 @@ class projectModel extends model return $this->dao->select($fields)->from(TABLE_PROJECT) ->where('type')->eq('project') ->beginIF($this->config->vision)->andWhere('vision')->eq($this->config->vision)->fi() - ->andWhere('deleted')->eq(0) + ->andWhere('(deleted')->eq(0) ->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi() + ->orWhere('isTpl')->eq('1') + ->markRight(1) ->orderBy('order_asc,id_desc') ->fetchAll('id'); } @@ -215,7 +217,9 @@ class projectModel extends model if(!$projectID) $projectID = $this->session->project ? $this->session->project : (int)key($projects); } - if(!isset($projects[$projectID])) + /* 项目模板不校验访问权限。 */ + $isTpl = $this->dao->select('isTpl')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetch('isTpl'); + if(!$isTpl && !isset($projects[$projectID])) { if($projectID && strpos(",{$this->app->user->view->projects},", ",{$projectID},") === false && !empty($projects)) {