dao->select('*')->from(TABLE_ACTION)->where('id')->eq($actionID)->fetch(); } /** * 获取一个基础对象的信息。 * Get object base info. * * @param string $table * @param array $queryParam * @param string $field * @param string $orderby * @access public * @return object|bool */ public function getObjectBaseInfo($table, $queryParam, $field = '*', $orderby = '') { $querys = array_map(function($key, $query){return "`{$key}` = '{$query}'";}, array_keys($queryParam), $queryParam); return $this->dao->select($field)->from($table)->where(implode(' and ', $querys))->orderby($orderby)->fetch(); } /** * 获取无需过滤的关联关系。 * Get no filter required relation. * * @param string $objectType * @param int $objectID * @access public * @return array */ public function getNoFilterRequiredRelation($objectType, $objectID) { $product = array(0); $project = $execution = 0; switch($objectType) { case 'product': $product = array($objectID); break; case 'project': case 'execution': $products = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($objectID)->fetchPairs(); if($products) $product = $products; ${$objectType} = $objectID; if($objectType == 'execution') { $project = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($objectID)->fetch('project'); if(!$project) $project = 0; } break; case 'marketresearch': $project = $objectID; break; } return array($product, $project, $execution); } /** * 获取对象的产品项目以及执行。 * Get product, project, execution of the object. * * @param string $objectType * @param int $objectID * @param string $actionType * @param string $extra * @access public * @return array */ public function getNeedRelatedFields($objectType, $objectID, $actionType = '', $extra = '') { $product = array(0); $project = $execution = 0; switch($objectType) { case 'story': list($product, $project, $execution) = $this->getStoryActionRelated($objectType, $actionType, $objectID, (int)$extra); break; case 'productplan': case 'branch': $product = $objectID == 0 ? $extra : $this->dao->select('product')->from($this->config->objectTables[$objectType])->where('id')->eq($objectID)->fetch('product'); break; case 'testcase': case 'case': list($product, $project, $execution) = $this->getCaseRelated($objectType, $actionType, $objectID, (int)$extra); break; case 'repo': case 'nc': case 'kanbanlane': $execution = $this->dao->select('execution')->from($this->config->objectTables[$objectType])->where('id')->eq($objectID)->fetch('execution'); break; case 'release': list($product, $project) = $this->getReleaseRelated($objectType, $objectID); break; case 'task': list($product, $project, $execution) = $this->getTaskRelated($objectType, $objectID); break; case 'kanbancolumn': $execution = $extra; break; case 'team': $type = $this->dao->select('type')->from(TABLE_PROJECT)->where('id')->eq($objectID)->fetch('type'); if($type != 'project') $type = 'execution'; ${$type} = $objectID; break; case 'whitelist': if($extra == 'product' || $extra == 'project') ${$extra} = $objectID; if($extra == 'sprint' || $extra == 'stage') $execution = $objectID; break; case 'module': $moduleID = $actionType != 'deleted' ? (int)$extra : (int)$objectID; $module = $this->dao->select('type,root')->from(TABLE_MODULE)->where('id')->eq($moduleID)->fetch(); if(!empty($module) && $module->type == 'story') $product = array($module->root); break; case 'review': case 'cm': case 'projectchange': list($product, $project) = $this->getReviewRelated($objectType, $objectID); break; default: list($product, $project, $execution) = $this->getGenerateRelated($objectType, $objectID); break; } return array($product, $project, $execution); } /** * 获取用户故事相关的产品、项目、阶段。 * Get story related product, project, stage. * * @param string $objectType * @param string $actionType * @param int $objectID * @param int $extra * @access public * @return array */ public function getStoryActionRelated($objectType, $actionType, $objectID, $extra) { list($product, $project, $execution) = $this->getGenerateRelated($objectType, $objectID); switch($actionType) { case 'linked2build': case 'unlinkedfrombuild': $build = $this->dao->select('project,execution')->from(TABLE_BUILD)->where('id')->eq($extra)->fetch(); if($build) { $project = $build->project; $execution = $build->execution; } break; case 'estimated': $project = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($extra)->fetch('project'); $execution = (int)$extra; break; default: $projectList = $this->dao->select('t2.id,t2.project,t2.type')->from(TABLE_PROJECTSTORY)->alias('t1') ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') ->where('t1.story')->eq($objectID) ->fetchAll(); foreach($projectList as $projectInfo) { if($projectInfo->type == 'project') { $project = $projectInfo->id; continue; } $project = $projectInfo->project; $execution = $projectInfo->id; } break; } return array($product, $project, $execution); } /** * 获取用例相关的产品、项目、阶段。 * Get case related product, project, stage. * * @param string $objectType * @param string $actionType * @param string $table * @param int $objectID * @param int $extra * @access public * @return array */ public function getCaseRelated($objectType, $actionType, $objectID, $extra) { list($product, $project, $execution) = $this->getGenerateRelated($objectType, $objectID); if(in_array($actionType, array('linked2testtask', 'unlinkedfromtesttask', 'run')) && $extra) { $testtask = $this->dao->select('project,execution')->from(TABLE_TESTTASK)->where('id')->eq($extra)->fetch(); $project = $testtask->project; $execution = $testtask->execution; } return array($product, $project, $execution); } /** * 常规获取相关的产品、项目、执行。 * Get general related product, project, execution. * * @param string $objectType * @param int $objectID * @access public * @return array */ public function getGenerateRelated($objectType, $objectID) { $product = $project = $execution = 0; if(!isset($this->config->objectTables[$objectType])) return array(array($product), $project, $execution); $result = $this->dao->select('*')->from($this->config->objectTables[$objectType])->where('id')->eq($objectID)->fetch(); if($result) { $product = zget($result, 'product', 0); $project = zget($result, 'project', 0); $execution = zget($result, 'execution', 0); } return array(array($product), $project, $execution); } /** * 获取分支相关的产品、项目、执行。 * Get case related product, project, execution. * * @param string $objectType * @param int $objectID * @access public * @return array */ public function getReleaseRelated($objectType, $objectID) { $product = 0; $project = 0; $result = $this->dao->select('product, build')->from($this->config->objectTables[$objectType])->where('id')->eq($objectID)->fetch(); if($result) { $product = $result->product; $project = $this->dao->select('project')->from(TABLE_BUILD)->where('id')->in($result->build)->fetch('project'); } return array(array($product), $project); } /** * 获取任务相关的产品、项目、执行。 * Get task related product, project, execution. * * @param string $objectType * @param int $objectID * @access public * @return array */ public function getTaskRelated($objectType, $objectID) { $product = array(0); $project = $execution = 0; $result = $this->dao->select('project,execution,story')->from($this->config->objectTables[$objectType])->where('id')->eq($objectID)->fetch(); if($result) { $table = $result->story != 0 ? TABLE_STORY : TABLE_PROJECTPRODUCT; $field = $result->story != 0 ? 'id' : 'project'; $value = $result->story != 0 ? $result->story : $result->execution; $products = $this->dao->select('product')->from($table)->where($field)->eq($value)->fetchPairs(); if($products) $product = array_values($products); $project = $result->project; $execution = $result->execution; } return array($product, $project, $execution); } /** * 获取需求相关的产品、项目、执行。 * Get story related product, project, execution. * * @param string $objectType * @param int $objectID * @access public * @return array */ public function getReviewRelated($objectType, $objectID) { $product = array(0); $project = 0; $result = $this->dao->select('*')->from($this->config->objectTables[$objectType])->where('id')->eq($objectID)->fetch(); if($result) { $products = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($result->project)->fetchPairs(); if($products) $product = $products; $project = zget($result, 'project', 0); } return array($product, $project); } /** * 根据类型和ID获取操作记录列表。 * Get action list by type and ID. * * @param string $objectType * @param int $objectID * @param array $modules * @access public * @return array */ public function getActionListByTypeAndID($objectType, $objectID, $modules) { $subTables = array(); if($this->config->edition != 'open') { $subTables = $this->dao->select('module')->from(TABLE_WORKFLOW) ->where('parent')->eq($objectType) ->andWhere('type')->eq('table') ->fetchPairs(); } return $this->dao->select('*')->from(TABLE_ACTION) ->beginIF($objectType == 'project') ->where("objectType IN('project', 'testtask', 'build')") ->andWhere('project')->in($objectID) ->fi() ->beginIF($objectType == 'story') ->where('objectType')->in('story,requirement') ->andWhere('objectID')->in($objectID) ->fi() ->beginIF($objectType == 'case' || $objectType == 'testcase') ->where('objectType')->in('case,testcase') ->andWhere('objectID')->in($objectID) ->fi() ->beginIF($objectType == 'module') ->where('objectType')->eq($objectType) ->andWhere('((action')->ne('deleted')->andWhere('objectID')->in($objectID)->markRight(1) ->orWhere('(action')->eq('deleted')->andWhere('objectID')->in($modules)->markRight(1)->markRight(1) ->fi() ->beginIF(!empty($subTables)) ->where('(objectType')->eq($objectType) ->andWhere('objectID')->in($objectID) ->markRight(1) ->orWhere('(objectType')->in($subTables) ->andWhere('extra')->in($objectID) ->markRight(1) ->fi() ->beginIF(empty($subTables) && !in_array($objectType, array('project', 'case', 'testcase', 'story', 'module'))) ->where('objectType')->eq($objectType) ->andWhere('objectID')->in($objectID) ->fi() ->orderBy('date, id') ->fetchAll('id', false); } /** * 获取 linked 和 unlinked 操作记录的附加信息。 * Get action extra info. * * @param object $action * @param string $type * @access public * @return bool */ public function getLinkedExtra($action, $type) { if($type == 'plan') $type = 'productplan'; if($type == 'revision') $type = 'repohistory'; if($type == 'bug') $type = 'build'; if($type == 'roadmap' && $action->objectType == 'story') $type = 'roadmap'; $table = zget($this->config->objectTables, $type, ''); if(empty($table)) return false; $method = 'view'; if(in_array($type, array('execution', 'kanban'))) { $execution = $this->fetchObjectInfoByID(TABLE_EXECUTION, (int)$action->extra, 'name, type, multiple'); if(!$execution) return false; if($execution->type != 'project' && empty($execution->multiple)) return false; $name = $execution->name; if($execution->type == 'kanban') $method = 'kanban'; if($name) { $isModalKanban = $method == 'kanban' && isonlybody(); $canShowLink = common::hasPriv('execution', $method) && !$isModalKanban && $this->config->vision != 'or'; $action->extra = $canShowLink ? html::a(helper::createLink('execution', $method, "executionID={$action->execution}"), $name, '', "data-app='execution'") : $name; } } elseif($type == 'project') { $project = $this->fetchObjectInfoByID($table, (int)$action->extra, 'name, model, multiple'); if(!$project) return false; $name = $project->name; if($project->model == 'kanban') $method = $project->multiple ? 'kanban' : 'index'; if($name) $action->extra = (common::hasPriv('project', $method) and $this->config->vision != 'or') ? html::a(helper::createLink('project', $method, "projectID=$action->project"), $name, '_self', in_array($method, array('view', 'index')) ? 'data-app="project"' : '') : $name; } elseif($type == 'plan' || $type == 'productplan') { $plan = $this->fetchObjectInfoByID($table, (int)$action->extra, 'title'); if($plan && $plan->title) $action->extra = common::hasPriv('productplan', 'view') && $this->config->vision != 'or' ? html::a(helper::createLink('productplan', $method, "planID={$action->extra}"), $plan->title) : $plan->title; } elseif(in_array($type, array('build', 'bug', 'release', 'testtask', 'roadmap'))) { $field = $type == 'build' ? 'name, execution' : 'name'; $object = $this->fetchObjectInfoByID($table, (int)$action->extra, $field); $buildTab = $type == 'build' && (in_array($this->app->tab, array('product', 'qa')) || empty($action->execution)) ? 'project' : $this->app->tab; if($this->app->tab == 'system') $buildTab = 'project'; if($object && $object->name) $action->extra = common::hasPriv($type, $method) ? html::a(helper::createLink($type, $method, $this->processParamString($action, $type)), $object->name, '', $type == 'build' ? "data-app='{$buildTab}'" : '') : $object->name; } elseif($type == 'revision') { $commit = $this->fetchObjectInfoByID($table, $action->extra, 'repo, revision'); if($commit) { $revision = substr($commit->revision, 0, 10); $action->extra = common::hasPriv('repo', 'revision') ? html::a(helper::createLink('repo', 'revision', "repoID={$commit->repo}&objectID=0&revision={$commit->revision}"), $revision) : $revision; } } return true; } /** * 通过ID获取对象信息。 * Get object info by ID. * * @param string $table * @param int $objectID * @access public * @return object|bool * @param string $field */ public function fetchObjectInfoByID($table, $objectID, $field = '*') { return $this->dao->select($field)->from($table)->where('id')->eq($objectID)->fetch(); } /** * 组建Action的extra信息。 * Build action extra info. * * @param string $table * @param object $action * @param string $fields * @param string $type * @param string $method * @param bool $onlyBody * @param bool $addlink * @access public * @return void * @param bool $addLink */ public function processActionExtra($table, $action, $fields, $type, $method = 'view', $onlyBody = false, $addLink = true) { $object = $this->fetchObjectInfoByID($table, (int)$action->extra, $fields); $condition = common::hasPriv($type, $method); if($onlyBody) $condition = $condition && !isonlybody(); if($object && $object->{$fields}) { $misc = ''; if($action->objectType == 'bug' && $action->action == 'converttotask' && $type == 'task' && $method == 'view') { $misc = "data-app='execution'"; $isMultipleProject = $this->dao->select('multiple')->from(TABLE_PROJECT)->where('id')->eq($action->project)->fetch('multiple'); if(!$isMultipleProject) $misc = "data-app='project'"; } $action->extra = $condition && $addLink ? html::a(helper::createLink($type, $method, $this->processParamString($action, $type)), "#{$action->extra} " . $object->{$fields}, '', $misc) : "#{$action->extra} " . $object->{$fields}; } } /** * 处理需求层级。 * Process story grade. * * @param object $action * @access public * @return object */ public function processStoryGradeActionExtra($action) { $action->extra = $this->dao->select('t1.name')->from(TABLE_STORYGRADE)->alias('t1') ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.grade = t2.grade AND t1.type = t2.type') ->where('t2.id')->eq($action->objectID) ->fetch('name'); return $action; } /** * 处理属性。 * Process attribute. * * @param string $type * @access public * @return string */ public function processAttribute($type) { if($type == 'testtask') $type = 'task'; return $type; } /** * 处理参数字符串。 * Process param string. * * @param object $action * @param string $type * @access public * @return string */ public function processParamString($action, $type) { $paramString = ''; switch($type) { case 'build': case 'bug': case 'release': $attribute = $this->processAttribute($type); $paramString = "{$attribute}ID={$action->extra}&type={$action->objectType}"; break; case 'testtask': $paramString = "taskID={$action->extra}"; break; case 'execution': case 'kanban': case 'story': $paramString = "{$type}ID={$action->extra}"; break; case 'task': case 'story': case 'charter': $paramString = "{$type}ID={$action->extra}"; break; case 'project': $productID = trim($action->product, ','); $paramString = "{$type}ID={$action->execution}&productID={$productID}"; break; case 'productplan': $paramString = "planID={$action->extra}"; break; case 'caselib': $paramString = "libID={$action->extra}"; break; case 'roadmap': $paramString = "roadmapID={$action->extra}"; break; case 'assetlib': $paramString = "libID={$action->extra}"; break; case 'demand': $paramString = "demandID={$action->extra}"; break; case 'epic': $paramString = "storyID={$action->extra}"; break; } return $paramString; } /** * 搭建创建子任务的Action的extra信息。 * Build create children action extra info. * * @param object $action * @access public * @return void */ public function processCreateChildrenActionExtra($action) { $names = $this->dao->select('id,name')->from(TABLE_TASK)->where('id')->in($action->extra)->fetchPairs(); $action->extra = ''; if($names) { foreach($names as $id => $name) $action->extra .= common::hasPriv('task', 'view') ? html::a(helper::createLink('task', 'view', "taskID={$id}"), "#{$id} " . $name) . ', ' : "#{$id} " . $name . ', '; } $action->extra = trim(trim($action->extra), ','); } /** * 搭建创建需求的Action的extra信息。 * Build create requirement action extra info. * * @param object $action * @access public * @return void */ public function processCreateRequirementsActionExtra($action) { $names = $this->dao->select('id,title')->from(TABLE_STORY)->where('id')->in($action->extra)->fetchPairs(); $action->extra = ''; if($names) { foreach($names as $id => $name) $action->extra .= common::hasPriv('requriement', 'view') ? html::a(helper::createLink('story', 'view', "storyID={$id}"), "#{$id} " . $name) . ', ' : "#{$id} " . $name . ', '; } $action->extra = trim(trim($action->extra), ','); } /** * 通过 extra 获取对象的 appendLink。 * Get object appendLink by extra. * * @param object $action * @access public * @return void */ public function processAppendLinkByExtra($action) { $action->appendLink = ''; if(strpos($action->extra, '|') !== false) $action->extra = substr($action->extra, 0, strpos($action->extra, '|')); if(strpos($action->extra, ':') !== false) { list($extra, $id) = explode(':', $action->extra); if($id) { $extra = strtolower($extra); $module = $action->objectType == 'todo' ? $extra : $action->objectType; $table = $this->config->objectTables[$module]; $field = $this->config->action->objectNameFields[$module]; $name = $this->dao->select($field)->from($table)->where('id')->eq($id)->fetch($field); $method = $module == 'story' ? 'storyView' : 'view'; if($name) $action->appendLink = html::a(helper::createLink($module, $method, "id={$id}"), "#{$id} " . $name); } $action->extra = $extra; } } /** * 搭建关联用户故事和bug的Action的extra信息。 * Build link story and bug action extra info. * * @param object $action * @param string $module * @param string $method * @access public * @return void */ public function processLinkStoryAndBugActionExtra($action, $module, $method) { $extra = ''; foreach(explode(',', $action->extra) as $id) $extra .= common::hasPriv($module, $method) ? html::a(helper::createLink($module, $method, "{$module}ID={$id}"), "#{$id} ", '', "data-size='lg' data-toggle='modal'") . ', ' : "#{$id}, "; $action->extra = trim(trim($extra), ','); } /** * 搭建与用户故事相关的Action的extra信息。 * Build story related action extra info. * * @param object $action * @access public * @return void */ public function processToStoryActionExtra($action) { $productShadow = $this->dao->select('shadow')->from(TABLE_PRODUCT)->where('id')->in(trim($action->product, ','))->fetch('shadow'); $title = $this->dao->select('title')->from(TABLE_STORY)->where('id')->eq($action->extra)->fetch('title'); $defaultExtra = "#{$action->extra} {$title}"; if($productShadow) { $projectID = $this->dao->select('project')->from(TABLE_PROJECTSTORY)->where('story')->eq($action->extra)->fetch('project'); if($title) $action->extra = common::hasPriv('projectstory', 'view') && $projectID ? html::a(helper::createLink('projectstory', 'view', "storyID={$action->extra}&projectID={$projectID}"), $defaultExtra) : $defaultExtra; } else { if($title) $action->extra = common::hasPriv('story', 'view') ? html::a(helper::createLink('story', 'view', "storyID={$action->extra}"), $defaultExtra) : $defaultExtra; } } /** * 通过条件获取操作记录列表。 * Get action list by condition. * * @param string $condition * @param string $begin * @param string $end * @param string $account * @param string|int $productID * @param string|int $projectID * @param string|int $executionID * @param string $actionCondition * @param string $orderBy * @param int $limit * @access public * @return array|bool */ public function getActionListByCondition($condition, $begin, $end, $account, $productID, $projectID, $executionID, $actionCondition, $orderBy, $limit = 50) { /* 获取最近一个月的动态用actionrecent表。 */ $lastMonth = date('Y-m-d', strtotime('-1 month')); $actionTable = ($begin >= $lastMonth && $end >= $lastMonth) ? TABLE_ACTIONRECENT : TABLE_ACTION; $actionCondition = str_replace(' `action`', ' action.`action`', $actionCondition); $hasProduct = preg_match('/t2\.(`?)product/', $condition); if(is_numeric($productID) && $productID) $hasProduct = true; if($productID === 'notzero') $hasProduct = true; return $this->dao->select('action.*')->from($actionTable)->alias('action') ->beginIF($hasProduct)->leftJoin(TABLE_ACTIONPRODUCT)->alias('t2')->on('action.id=t2.action')->fi() ->where('objectType')->notIN($this->config->action->ignoreObjectType4Dynamic) ->andWhere('action.action')->notIN($this->config->action->ignoreActions4Dynamic) ->andWhere('vision')->eq($this->config->vision) ->beginIF($begin != EPOCH_DATE)->andWhere('date')->ge($begin)->fi() ->beginIF($end != FUTURE_DATE)->andWhere('date')->le($end)->fi() ->beginIF($account != 'all')->andWhere('actor')->eq($account)->fi() ->beginIF(is_numeric($productID) && $productID)->andWhere('t2.product')->eq($productID)->fi() ->beginIF(is_numeric($projectID) && $projectID)->andWhere('project')->eq($projectID)->fi() ->beginIF(is_numeric($executionID) && $executionID)->andWhere('execution')->eq($executionID)->fi() /* lite模式下需要排除的一些类型。 */ /* Types excluded from Lite. */ ->beginIF($this->config->vision == 'lite')->andWhere('objectType')->notin('product')->fi() ->beginIF($this->config->systemMode == 'light')->andWhere('objectType')->notin('program')->fi() ->beginIF($productID === 'notzero')->andWhere('t2.product')->gt(0)->fi() ->beginIF($projectID === 'notzero')->andWhere('project')->gt(0)->fi() ->beginIF($executionID === 'notzero')->andWhere('execution')->gt(0)->fi() ->beginIF($condition && $condition != '1=1')->andWhere($condition)->fi() ->beginIF($actionCondition)->andWhere("($actionCondition)")->fi() ->orderBy($orderBy) ->limit($limit) ->fetchAll('', false); } /** * 根据条件获取动态表。 * Get action table by condition. * * @param string $period * @access public * @return string */ public function getActionTable($period) { return in_array($period, $this->config->action->latestDateList) ? TABLE_ACTIONRECENT : TABLE_ACTION; } /** * 检查Action是否合法。 * Check if action is legal. * * @param object $action * @param array $shadowProducts * @param array $docList * @param array $apiList * @param array $docLibList * @access public * @return bool */ public function checkIsActionLegal($action, $shadowProducts, $docList, $apiList, $docLibList) { if(($action->objectType == 'doc' || $action->objectType == 'doctemplate') && !isset($docList[$action->objectID])) return false; if($action->objectType == 'api' && !isset($apiList[$action->objectID])) return false; if($action->objectType == 'doclib' && !isset($docLibList[$action->objectID])) return false; if($action->objectType == 'product' && isset($shadowProducts[$action->objectID])) return false; return true; } /** * 为Action添加对象名称。 * Add object name for action. * * @param object $action * @param array $objectNames * @param string $objectType * @access public * @return void */ public function addObjectNameForAction($action, $objectNames, $objectType) { $action->objectName = isset($objectNames[$action->objectType][$action->objectID]) ? $objectNames[$action->objectType][$action->objectID] : ''; if($action->objectType == 'program' && strpos('syncexecution,syncproject,syncprogram', $action->action) !== false) { $action->objectName .= $this->lang->action->label->startProgram; } elseif($action->objectType == 'branch' && $action->action == 'mergedbranch') { if($action->objectID == 0) $action->objectName = $this->lang->branch->main; $action->objectName = '"' . $action->extra . ' "' . $this->lang->action->to . ' "' . $action->objectName . '"'; } elseif($action->objectType == 'user') { $user = $this->dao->select('id,realname')->from(TABLE_USER)->where('id')->eq($action->objectID)->fetch(); if($user) $action->objectName = $user->realname; } elseif($action->objectType == 'kanbancard' && strpos($action->action, 'imported') !== false && $action->action != 'importedcard') { $objectType = str_replace('imported', '', $action->action); $objectTable = zget($this->config->objectTables, $objectType, ''); $objectName = ($objectType == 'productplan' || $objectType == 'ticket') ? 'title' : 'name'; if($objectTable) $action->objectName = $this->dao->select($objectName)->from($objectTable)->where('id')->eq($action->extra)->fetch($objectName); } elseif(strpos(',module,chartgroup,', ",$action->objectType,") !== false && !empty($action->extra) && $action->action != 'deleted') { $modules = $this->dao->select('id,name')->from(TABLE_MODULE)->where('id')->in(explode(',', $action->extra))->fetchPairs('id'); $action->objectName = implode(',', $modules); } elseif($action->objectType == 'mr' && $action->action == 'deleted') { $action->objectName = $action->extra; } elseif($action->objectType == 'pivot') { $pivotNames = json_decode($action->objectName, true); $action->objectName = zget($pivotNames, $this->app->getClientLang(), ''); if(empty($action->objectName)) { $pivotNames = array_filter($pivotNames); $action->objectName = reset($pivotNames); } } elseif($action->objectType == 'aiassistant') { $action->objectName = $this->dao->select('name')->from(TABLE_AI_ASSISTANT)->where('id')->eq($action->objectID)->fetch('name'); } if (empty($action->objectName) && preg_match('/^(gitlab|gitea|gogs|mr)/', $objectType)) $action->objectName = $action->extra; } /** * 旗舰版处理资产库的链接。 * Process doc link for max. * * @param object $action * @param string $moduleName * @param string $methodName * @param string $vars * @access public * @return void */ public function processMaxDocObjectLink($action, $moduleName, $methodName, $vars) { if($action->objectType == 'doc') { $assetLibType = $this->dao->select('assetLibType')->from(TABLE_DOC)->where('id')->eq($action->objectID)->fetch('assetLibType'); if($assetLibType) $method = $assetLibType == 'practice' ? 'practiceView' : 'componentView'; } else { $method = $this->config->action->assetViewMethod[$action->objectType]; } if(isset($method)) { $moduleName = 'assetlib'; $methodName = $method; } $action->objectLink = common::hasPriv($moduleName, $methodName) ? helper::createLink($moduleName, $methodName, sprintf($vars, $action->objectID)) : ''; $action->hasLink = true; } /** * 获取文档库链接参数。 * Get doclib link params. * * @param object $action * @access public * @return array|bool */ public function getDocLibLinkParameters($action) { $libID = $action->objectID; $type = 'custom'; if(!empty($action->project)) $type = 'project'; if(!empty($action->execution)) $type = 'execution'; if(!empty($action->product)) $type = 'product'; $libObjectID = $type != 'custom' ? $action->{$type} : ''; $libObjectID = trim($libObjectID, ','); if(empty($libObjectID) && $type != 'custom') return false; return array($type, $libID, $libObjectID); } /** * 获取文档库类型参数。 * Get doclib type params. * * @param object $action * @access public * @return array */ public function getDoclibTypeParams($action) { $params = ''; $docLib = $this->dao->select('type,product,project,execution,deleted')->from(TABLE_DOCLIB)->where('id')->eq($action->objectID)->fetch(); $docLib->objectID = in_array($docLib->type, array('product', 'project', 'execution')) ? $docLib->{$docLib->type} : 0; $appendLib = $docLib->deleted == '1' ? $action->objectID : 0; if($docLib->type == 'api') { $moduleName = 'api'; $methodName = 'index'; $params = "libID={$action->objectID}&moduleID=0&apiID=0&version=0&release=0&appendLib={$appendLib}"; if(!empty($docLib->project) || !empty($docLib->product)) { $moduleName = 'doc'; if(!empty($docLib->product)) { $objectID = $docLib->product; $methodName = 'productspace'; } if(!empty($docLib->project)) { $objectID = $docLib->project; $methodName = 'projectspace'; } $params = "objectID={$objectID}&libID={$action->objectID}"; } } else { $moduleName = 'doc'; $methodName = zget($this->config->doc->spaceMethod, $docLib->type, 'tablecontents'); if($methodName == 'myspace') $params = "type=mine&libID={$action->objectID}"; if(!in_array($methodName, array('myspace', 'tablecontents'))) $params = "objectID={$docLib->objectID}&libID={$action->objectID}"; } return array($moduleName, $methodName, $params); } /** * 检查Action是否可点击。 * Check if action is clickable. * * @param object $action * @param array $deptUsers * @param string $moduleName * @param string $methodName * @access public * @return bool */ public function checkActionClickable($action, $deptUsers, $moduleName, $methodName) { if(empty($moduleName) || empty($methodName)) return false; if(!common::hasPriv($moduleName, $methodName)) return false; if(!helper::hasFeature($moduleName)) return false; if($action->objectType == 'user' && !isset($deptUsers[$action->objectID]) && !$this->app->user->admin) return false; if($action->objectType == 'user' && ($action->action == 'login' || $action->action == 'logout')) return false; if($action->objectType == 'user') { $user = $this->dao->select('deleted')->from(TABLE_USER)->where('id')->eq($action->objectID)->fetch(); if($user && $user->deleted == '1') return false; } if($action->objectType == 'todo') { $todo = $this->dao->select('*')->from(TABLE_TODO)->where('id')->eq($action->objectID)->fetch(); if($todo && $todo->private == 1 && $todo->account != $this->app->user->account) return false; } if($action->objectType == 'docTemplate' && !common::hasPriv('docTempalte', 'view')) return false; if($action->objectType == 'mr' && (empty($action->objectName) || $action->action == 'deleted')) return false; if($action->objectType == 'stakeholder' && $action->project == 0) return false; if($action->objectType == 'chartgroup') return false; if($action->objectType == 'branch' && $action->action == 'mergedbranch') return false; if($action->objectType == 'case') { $case = $this->dao->select('lib')->from(TABLE_CASE)->where('id')->eq($action->objectID)->fetch(); if($action->action == 'tolib' || !empty($case->lib)) return helper::hasFeature('caselib'); } return true; } /** * 获取对象链接参数。 * Get object link params. * * @param object $action * @param string $vars * @access public * @return string */ public function getObjectLinkParams($action, $vars) { if($action->objectType == 'api') { $api = $this->dao->select('id,lib,module')->from(TABLE_API)->where('id')->eq($action->objectID)->fetch(); $params = sprintf($vars, $api->lib, $api->id, $api->module); } elseif($action->objectType == 'branch' || ($action->objectType == 'module' && $action->action == 'deleted')) { $params = sprintf($vars, trim($action->product, ',')); } elseif($action->objectType == 'kanbanspace') { $kanbanSpace = $this->dao->select('type')->from(TABLE_KANBANSPACE)->where('id')->eq($action->objectID)->fetch(); $params = sprintf($vars, $kanbanSpace->type); } elseif($action->objectType == 'kanbancard') { $table = $this->config->objectTables[$action->objectType]; $kanbanID = $this->dao->select('kanban')->from($table)->where('id')->eq($action->objectID)->fetch('kanban'); $params = sprintf($vars, $kanbanID); } elseif($action->objectType == 'module' && $action->action == 'undeleted') { $table = $this->config->objectTables[$action->objectType]; $moduleID = $this->dao->select('root')->from($table)->where('id')->eq($action->objectID)->fetch('root'); $params = sprintf($vars, $moduleID); } else { $params = sprintf($vars, $action->objectID); } return $params; } /** * 根据对象类型获取恢复对象参数。 * Get object params by object type. * * @param string $objectType * @access public * @return array */ public function getUndeleteParamsByObjectType($objectType) { $table = $this->config->objectTables[$objectType]; $orderby = ''; $field = '*'; $queryKey = 'id'; switch($objectType) { case 'product': $field = 'id, name, code, acl'; break; case 'program': case 'project': $field = 'id, acl, name, hasProduct, multiple'; break; case 'doc': $table = TABLE_DOCCONTENT; $orderby = 'version desc'; $queryKey = 'doc'; default: break; } return array($table, $orderby, $field, $queryKey); } }