* @package common * @link https://www.zentao.net */ class commonTao extends commonModel { /** * Get SQL for preAndNext. * * @param string $type * @access protected * @return string */ protected function getPreAndNextSQL($type) { $queryCondition = $type . 'QueryCondition'; $typeOnlyCondition = $type . 'OnlyCondition'; $queryCondition = $this->session->$queryCondition; $table = zget($this->config->objectTables, $type, ''); if($this->config->edition != 'open' && empty($table)) { $flow = $this->loadModel('workflow')->getByModule($type); if(empty($flow->table)) return ''; $table = $flow->table; } $orderBy = $type . 'OrderBy'; $orderBy = $this->session->$orderBy; $select = ''; if($this->session->$typeOnlyCondition) { if($orderBy and strpos($orderBy, 'priOrder') !== false) $select .= ", IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder"; if($orderBy and strpos($orderBy, 'severityOrder') !== false) $select .= ", IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder"; if($type == 'task' && strpos($orderBy, 'statusOrder') !== false) $select .= ", INSTR('wait,doing,done,pause,cancel,closed,', status) as statusOrder"; $queryCondition = str_replace('t4.status', 'status', $queryCondition); $sql = $this->dao->select("*$select")->from($table) ->where($queryCondition) ->beginIF($orderBy != false)->orderBy($orderBy)->fi() ->get(); } else { $sql = $queryCondition . (empty($orderBy) ? '' : " ORDER BY $orderBy"); } return $sql; } /** * Query list for preAndNext. * * @param string $type * @param string $sql * @access protected * @return array */ protected function queryListForPreAndNext($type, $sql) { $objectIdListKey = $type . 'BrowseList'; $existsObjectList = $this->session->$objectIdListKey; $typeOnlyCondition = $type . 'OnlyCondition'; if(empty($existsObjectList) or trim($existsObjectList['sql']) != trim($sql)) { $queryObjects = $this->dao->query($sql); $objectList = array(); $key = 'id'; if($queryObjects) { while($object = $queryObjects->fetch()) { if(!$this->session->$typeOnlyCondition and $type == 'testcase' and isset($object->case)) $key = 'case'; $id = $object->$key; $objectList[$id] = $id; } } $this->session->set($objectIdListKey, array('sql' => $sql, 'idkey' => $key, 'objectList' => $objectList), $this->app->tab); $existsObjectList = $this->session->$objectIdListKey; } return $existsObjectList; } /** * Search preAndNext from list. * * @param int $objectID * @param array $objectList * @access protected * @return object */ protected function searchPreAndNextFromList($objectID, $objectList) { $preAndNextObject = new stdClass(); $preAndNextObject->pre = ''; $preAndNextObject->next = ''; if(!isset($objectList['objectList'])) return $preAndNextObject; $preObj = false; foreach($objectList['objectList'] as $id) { /* Get next object. */ if($preObj === true) { $preAndNextObject->next = $id; break; } /* Get pre object. */ if($id == $objectID) { if($preObj) $preAndNextObject->pre = $preObj; $preObj = true; } if($preObj !== true) $preObj = $id; } return $preAndNextObject; } /** * Fetch preAndNextObject. * * @param string $type * @param int $objectID * @param object $preAndNextObject * @access protected * @return object */ protected function fetchPreAndNextObject($type, $objectID, $preAndNextObject) { $queryCondition = $type . 'QueryCondition'; $typeOnlyCondition = $type . 'OnlyCondition'; $objectIdListKey = $type . 'BrowseList'; $queryCondition = $this->session->$queryCondition; $existsObjectList = $this->session->$objectIdListKey; $table = zget($this->config->objectTables, $type, ''); if($this->config->edition != 'open' && empty($table)) { $flow = $this->loadModel('workflow')->getByModule($type); if(empty($flow->table)) return $preAndNextObject; $table = $flow->table; } if(empty($preAndNextObject->pre) and empty($preAndNextObject->next)) return $preAndNextObject; if(empty($queryCondition) or $this->session->$typeOnlyCondition) { if(!empty($preAndNextObject->pre)) $preAndNextObject->pre = $this->dao->select('*')->from($table)->where('id')->eq($preAndNextObject->pre)->fetch(); if(!empty($preAndNextObject->next)) $preAndNextObject->next = $this->dao->select('*')->from($table)->where('id')->eq($preAndNextObject->next)->fetch(); return $preAndNextObject; } $searched = false; $objects = array(); $key = $existsObjectList['idkey']; $queryObjects = $this->dao->query($existsObjectList['sql']); while($object = $queryObjects->fetch()) { $objects[$object->$key] = $object; if(!empty($preAndNextObject->pre) and is_numeric($preAndNextObject->pre) and $object->$key == $preAndNextObject->pre) $preAndNextObject->pre = $object; if(!empty($preAndNextObject->next) and is_numeric($preAndNextObject->next) and $object->$key == $preAndNextObject->next) $preAndNextObject->next = $object; if((empty($preAndNextObject->pre) or is_object($preAndNextObject->pre)) and (empty($preAndNextObject->next) or is_object($preAndNextObject->next))) { $searched = true; break; } } /* If the pre object or next object is number type, then continue to find the pre or next. */ if(!$searched) { $objectIdList = array_keys($objects); $objectIdIndex = (int)array_search($objectID, $objectIdList); if(is_numeric($preAndNextObject->pre)) $preAndNextObject->pre = $objectIdIndex - 1 >= 0 ? $objects[$objectIdList[$objectIdIndex - 1]] : ''; if(is_numeric($preAndNextObject->next)) $preAndNextObject->next = $objectIdIndex + 1 < count($objectIdList) ? $objects[$objectIdList[$objectIdIndex + 1]] : ''; } $preAndNextObject->idKey = $key; return $preAndNextObject; } /** * 查看当前用户是否有资产库下其他方法的权限。 * Check if current user has other methods permissions under the asset library. * * @param bool $display * @param string $currentModule * @param string $currentMethod * @access protected * @return array */ protected static function setAssetLibMenu($display, $currentModule, $currentMethod) { $methodList = array('caselib', 'issuelib', 'risklib', 'opportunitylib', 'practicelib', 'componentlib'); foreach($methodList as $method) { if(common::hasPriv($currentModule, $method)) { $display = true; $currentMethod = $method; break; } } return array($display, $currentMethod); } /** * 根据后台维护分组的视图设置,判断用户是否有权限。 * According to the view maintained by the background, determine whether the user has permission. * * @param string $module * @param string $method * @param array $acls * @param mixed $object * @access protected * @return bool */ protected static function checkPrivByRights($module, $method, $acls, $object) { global $lang, $app; if(!commonModel::hasDBPriv($object, $module, $method)) return false; if(empty($acls['views'])) return true; $menu = isset($lang->navGroup->$module) ? $lang->navGroup->$module : $module; if($module == 'my' and $method == 'team') $menu = 'system'; // Fix bug #18642. $menu = strtolower($menu); if($menu == 'product' && $app->tab != 'product' && in_array($module, array('story', 'requirement', 'epic'))) return true; if($menu != 'qa' and $menu != 'project' and !isset($lang->$menu->menu)) return true; if(($menu == 'my' and $method != 'team') or $menu == 'index' or $module == 'tree') return true; if($module == 'company' and $method == 'dynamic') return true; if($module == 'action' and $method == 'editcomment') return true; if($module == 'action' and $method == 'comment') return true; if($module == 'report' and $method == 'export') return true; if(!isset($acls['views'][$menu])) return false; return true; } /** * 查看当前用户是否有其他个性化设置导航的权限。 * Check if current user has other methods permissions under the preference menu. * * @param bool $display * @param string $currentModule * @param string $currentMethod * @access protected * @return array */ protected static function setPreferenceMenu($display, $currentModule, $currentMethod) { global $app; global $lang; $app->loadLang('my'); $moduleLinkList = $currentModule . 'LinkList'; foreach($lang->my->$moduleLinkList as $key => $linkList) { $moduleMethodList = explode('-', $key); $method = $moduleMethodList[1]; if(common::hasPriv($currentModule, $method)) { $display = true; $currentMethod = $method; break; } } return array($display, $currentMethod); } /** * 非个性化设置的导航,查看当前用户是否有该应用下其他方法的权限。 * For non-personalized settings navigation, check if current user has other methods permissions under the application. * * @param bool $display * @param string $currentModule * @param string $currentMethod * @access protected * @return array */ protected static function setOtherMenu($display, $currentModule, $currentMethod) { global $lang; foreach($lang->$currentModule->menu as $menu) { if(!isset($menu['link'])) continue; $linkPart = explode('|', $menu['link']); if(!isset($linkPart[2])) continue; $method = $linkPart[2]; /* Skip some pages that do not require permissions.*/ if($currentModule == 'report' and $method == 'annualData') continue; if($currentModule == 'my' and $currentMethod == 'team') continue; if(common::hasPriv($currentModule, $method)) { $display = true; $currentMethod = $method; if(!isset($menu['target'])) break; // Try to jump to the method without opening a new window. } } return array($display, $currentMethod); } /** * 基于导航的所属应用,查看当前用户是否有该应用下其他方法的权限。 * Based on the navigation of the application, check if current user has other methods permissions under the application. * * @param string $group * @param bool $display * @param string $currentModule * @param string $currentMethod * @access protected * @return array */ protected static function setMenuByGroup($group, $display, $currentModule, $currentMethod) { global $lang; foreach($lang->$group->menu as $menu) { if(!isset($menu['link'])) continue; $linkPart = explode('|', $menu['link']); if(count($linkPart) < 3) continue; list(, $module, $method) = $linkPart; if(common::hasPriv($module, $method)) { $display = true; $currentModule = $module; $currentMethod = $method; if(!isset($menu['target'])) break; // Try to jump to the method without opening a new window. } } return array($display, $currentModule, $currentMethod); } /** * 判断用户是否在项目、产品、计划、执行的管理员中。 * Check if the user is in the administrator of the project, product, plan, and execution. * * @param string $module * @param mixed $object * @access protected * @return bool */ protected static function isProjectAdmin($module, $object) { global $app, $lang; $inProject = ((isset($lang->navGroup->$module) and $lang->navGroup->$module == 'project') || (!empty($object->type) and $object->type == 'project')); $projectID = $app->session->project; if(!empty($object->type) && $object->type == 'project') $projectID = $object->id; if($inProject and $projectID and (strpos(",{$app->user->rights['projects']},", ",{$projectID},") !== false or strpos(",{$app->user->rights['projects']},", ',all,') !== false)) return true; $inProduct = (isset($lang->navGroup->$module) and $lang->navGroup->$module == 'product'); $productID = empty($object->id) ? $app->session->product : $object->id; if($inProduct and $productID and (strpos(",{$app->user->rights['products']},", ",{$productID},") !== false or strpos(",{$app->user->rights['products']},", ',all,') !== false)) return true; $inProgram = (isset($lang->navGroup->$module) and $lang->navGroup->$module == 'program'); $programID = empty($object->id) ? $app->session->program : $object->id; if($inProgram and $programID and (strpos(",{$app->user->rights['programs']},", ",{$programID},") !== false or strpos(",{$app->user->rights['programs']},", ',all,') !== false)) return true; $inExecution = (isset($lang->navGroup->$module) and $lang->navGroup->$module == 'execution'); $executionID = empty($object->id) ? $app->session->execution : $object->id; if($inExecution and $executionID and (strpos(",{$app->user->rights['executions']},", ",{$executionID},") !== false or strpos(",{$app->user->rights['executions']},", ',all,') !== false)) return true; return false; } /** * 获取需求模块下,真实请求的模块和方法。 * Get the real module and method of the request under the requirement module. * * @param string $module * @param string $method * @param array $params * @access protected * @return array */ protected static function getStoryModuleAndMethod($module, $method, $params) { if($module == 'story' && $method == 'processstorychange') return array($module, $method); global $app; if(empty($params['storyType']) and $module == 'story' and !empty($app->params['storyType']) and strpos(",story,requirement,", ",{$app->params['storyType']},") !== false) $module = $app->params['storyType']; if($module == 'story' and !empty($params['storyType']) and strpos(",story,requirement,", ",{$params['storyType']},") !== false) $module = $params['storyType']; if($module == 'product' and $method == 'browse' and !empty($app->params['storyType']) and $app->params['storyType'] == 'requirement') $method = 'requirement'; if($module == 'product' and $method == 'browse' and !empty($params['storyType']) and $params['storyType'] == 'requirement') $method = 'requirement'; if($module == 'story' and $method == 'linkrequirements') $module = 'requirement'; return array($module, $method); } /** * 获取白板模块下,真实请求的模块和方法。 * Get the real module and method of the request under the board module. * * @param string $module * @param string $method * @param array $params * @access protected * @return string[] */ protected static function getBoardModuleAndMethod($module, $method, $params) { if($module != 'board') return array($module, $method); if(strpos(',view,open,bind,canvas,autoupdate,quit,importstory,', ",{$method},") !== false) $method = 'creation'; if($method == 'createbytemplate') $method = 'createboard'; return array($module, $method); } /** * Check and update webRoot config in DB. * * @param object $dbConfig * @access public * @return void */ public function updateDBWebRoot($dbConfig) { if(PHP_SAPI == 'cli') return; if(!empty($this->app->installing) || !empty($this->app->upgrading)) return; global $config; /* Check config webRoot right or not. */ if($config->webRoot[0] != '/') return; if($config->webRoot[strlen($config->webRoot) - 1] != '/') return; /* Get webRoot config in db. */ $webRootConfig = null; foreach($dbConfig->common as $commonConfig) { if($commonConfig->key == 'webRoot') { $webRootConfig = $commonConfig; break; } } /* Init db webRoot config. */ if(empty($webRootConfig)) return $this->loadModel('setting')->setItem('system.common.webRoot', $config->webRoot); if($config->webRoot == $webRootConfig->value) return; /* Update db webRoot. */ $webRootConfig->value = $config->webRoot; $this->loadModel('setting')->updateItem('system.common.webRoot', $config->webRoot); } }