* @package my * @link https://www.zentao.net */ class myTao extends myModel { /** * 获取产品相关的由我指派的数据。 * Get the data related to the product assigned by me. * * @param array $objectIdList * @param string $objectType * @param string $orderBy * @param object $pager * @access protected * @return array * @param string $module */ protected function getProductRelatedAssignedByMe($objectIdList, $objectType, $module, $orderBy, $pager = null) { $nameField = $objectType == 'bug' ? 'productName' : 'productTitle'; $orderBy = strpos($orderBy, 'priOrder') !== false || strpos($orderBy, 'severityOrder') !== false || strpos($orderBy, $nameField) !== false ? $orderBy : "t1.{$orderBy}"; $select = "t1.*, t2.name AS {$nameField}, t2.shadow AS shadow, " . (strpos($orderBy, 'severity') !== false ? "IF(t1.`severity` = 0, {$this->config->maxPriValue}, t1.`severity`) AS severityOrder" : "IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) AS priOrder"); $objectList = $this->dao->select($select)->from($this->config->objectTables[$module])->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') ->where('t1.deleted')->eq(0) ->andWhere('t2.deleted')->eq(0) ->andWhere('t1.id')->in($objectIdList) ->beginIF($module == 'story')->andWhere('t1.type')->eq($objectType)->fi() ->beginIF($module == 'story')->andWhere("FIND_IN_SET('{$this->config->vision}', t1.vision)")->fi() ->orderBy($orderBy) ->page($pager) ->fetchAll('id', false); if($module == 'story') { $planList = array(); foreach($objectList as $story) $planList[$story->plan] = $story->plan; $planPairs = $this->dao->select('id,title')->from(TABLE_PRODUCTPLAN)->where('id')->in($planList)->fetchPairs('id'); foreach($objectList as $story) $story->planTitle = zget($planPairs, $story->plan, ''); } return $objectList; } /** * 通过搜索查找任务。 * Fetch tasks by search. * * @param string $query * @param string $moduleName * @param string $account * @param array $taskIdList * @param string $orderBy * @param int $limit * @param object $pager * @access protected * @return array */ protected function fetchTasksBySearch($query, $moduleName, $account, $taskIdList, $orderBy, $limit, $pager = null) { $query = preg_replace('/`(\w+)`/', 't1.`$1`', $query); $query = str_replace('t1.`project`', 't2.`project`', $query); $assignedToMatches = array(); $assignedToCondition = ''; $operatorAndAccount = ''; if(strpos($query, '`assignedTo`') !== false) { preg_match("/`assignedTo`\s+(([^']*) ('([^']*)'))/", $query, $assignedToMatches); if(!empty($assignedToMatches)) { $assignedToCondition = $assignedToMatches[0]; $operatorAndAccount = $assignedToMatches[1]; $query = str_replace("t1.{$assignedToMatches[0]}", "(t1.{$assignedToCondition} or (t1.mode = 'multi' and t5.`account` {$operatorAndAccount} and t1.status != 'closed' and t5.status != 'done') )", $query); } } if(strpos($query, "t2.`project` = 'all'") !== false) $query = str_replace("t2.`project` = 'all'", "t2.`project` != '0'", $query); if(strpos($query, "t2.`project` != 'all'") !== false) $query = str_replace("t2.`project` != 'all'", "t2.`project` = '0'", $query); if(strpos($query, "t1.`execution` = 'all'") !== false) $query = str_replace("t1.`execution` = 'all'", "t1.`execution` != '0'", $query); $orderBy = str_replace('pri_', 'priOrder_', $orderBy); return $this->dao->select("t1.*, t4.id as project, t2.id as executionID, t2.name as executionName, t2.multiple as executionMultiple, t4.name as projectName, t2.type as executionType, t3.id as storyID, t3.title as storyTitle, t3.status AS storyStatus, t3.version AS latestStoryVersion, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) as priOrder") ->from(TABLE_TASK)->alias('t1') ->leftJoin(TABLE_EXECUTION)->alias('t2')->on("t1.execution = t2.id") ->leftJoin(TABLE_STORY)->alias('t3')->on('t1.story = t3.id') ->leftJoin(TABLE_PROJECT)->alias('t4')->on("t2.project = t4.id") ->leftJoin(TABLE_TASKTEAM)->alias('t5')->on("t1.id = t5.task") ->where($query) ->andWhere('t1.deleted')->eq(0) ->andWhere('t2.deleted')->eq(0) ->andWhere('(t2.status')->ne('suspended')->orWhere('t4.status')->ne('suspended')->markRight(1) ->beginIF($moduleName == 'workTask') ->beginIF(!empty($assignedToMatches))->andWhere("(t1.{$assignedToCondition} or (t1.mode = 'multi' and t5.`account` {$operatorAndAccount} and t1.status != 'closed' and t5.status != 'done') )")->fi() ->beginIF(empty($assignedToMatches))->andWhere("(t1.assignedTo = '{$account}' or (t1.mode = 'multi' and t5.`account` = '{$account}' and t1.status != 'closed' and t5.status != 'done') )")->fi() ->andWhere('t1.status')->notin('closed,cancel') ->fi() ->beginIF($moduleName == 'contributeTask') ->andWhere('t1.openedBy', 1)->eq($account) ->orWhere('t1.closedBy')->eq($account) ->orWhere('t1.canceledBy')->eq($account) ->orWhere('t1.finishedby')->eq($account) ->orWhere('t1.assignedTo')->eq($account) ->orWhere('t5.account')->eq($account) ->orWhere('t1.id')->in($taskIdList) ->markRight(1) ->fi() ->beginIF($this->config->vision)->andWhere('t1.vision')->eq($this->config->vision)->fi() ->beginIF($this->config->vision)->andWhere('t2.vision')->eq($this->config->vision)->fi() ->beginIF(!$this->app->user->admin)->andWhere('t1.execution')->in($this->app->user->view->sprints)->fi() ->orderBy($orderBy) ->beginIF($limit > 0)->limit($limit)->fi() ->page($pager, 't1.id') ->fetchAll('id'); } /** * 通过搜索查找需求。 * Fetch stories by search. * * @param string $myStoryQuery * @param string $type * @param string $orderBy * @param object $pager * @param array $storiesAssignedByMe * @access protected * @return array */ protected function fetchStoriesBySearch($myStoryQuery, $type, $orderBy, $pager = null, $storiesAssignedByMe = array()) { if($type == 'contribute') { $storyIdList = !empty($storiesAssignedByMe) ? array_keys($storiesAssignedByMe) : array(); $stories = $this->dao->select("distinct t1.*, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) as priOrder, t2.name as productTitle, t2.shadow as shadow, t4.title as planTitle")->from(TABLE_STORY)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') ->leftJoin(TABLE_PLANSTORY)->alias('t3')->on('t1.id = t3.plan') ->leftJoin(TABLE_PRODUCTPLAN)->alias('t4')->on('t3.plan = t4.id') ->leftJoin(TABLE_STORYREVIEW)->alias('t5')->on('t1.id = t5.story') ->where($myStoryQuery) ->andWhere('t1.type')->eq('story') ->andWhere('t1.openedBy',1)->eq($this->app->user->account) ->orWhere('t5.reviewer')->eq($this->app->user->account) ->orWhere('t1.closedBy')->eq($this->app->user->account) ->orWhere('t1.id')->in($storyIdList) ->markRight(1) ->andWhere('t1.deleted')->eq(0) ->orderBy($orderBy) ->page($pager, 't1.id') ->fetchAll('id'); } else { $stories = $this->dao->select("distinct t1.*, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) as priOrder, t2.name as productTitle, t2.shadow as shadow, t4.title as planTitle")->from(TABLE_STORY)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') ->leftJoin(TABLE_PLANSTORY)->alias('t3')->on('t1.id = t3.plan') ->leftJoin(TABLE_PRODUCTPLAN)->alias('t4')->on('t3.plan = t4.id') ->leftJoin(TABLE_STORYREVIEW)->alias('t5')->on('t1.id = t5.story AND t1.version=t5.version') ->where($myStoryQuery) ->andWhere('t1.type')->eq('story') ->andWhere('t1.assignedTo',1)->eq($this->app->user->account) ->orWhere("(t5.reviewer = '{$this->app->user->account}' AND t5.result = '' AND t1.status = 'reviewing')") ->markRight(1) ->andWhere('t1.product')->ne('0') ->andWhere('t1.deleted')->eq(0) ->orderBy($orderBy) ->page($pager, 't1.id') ->fetchAll('id'); } return $stories; } /** * 通过搜索查找业务需求。 * Fetch epics by search. * * @param string $myEpicQuery * @param string $type * @param string $orderBy * @param object $pager * @param array $epicIDList * @access protected * @return array */ protected function fetchEpicsBySearch($myEpicQuery, $type, $orderBy, $pager = null, $epicIDList = array()) { if($type == 'contribute') { $epics = $this->dao->select("distinct t1.*, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) as priOrder, t2.name as productTitle")->from(TABLE_STORY)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') ->leftJoin(TABLE_STORYREVIEW)->alias('t3')->on('t1.id = t3.story') ->where($myEpicQuery) ->andWhere('t1.type')->eq('epic') ->andWhere('t1.openedBy',1)->eq($this->app->user->account) ->orWhere('t1.closedBy')->eq($this->app->user->account) ->orWhere('(t3.reviewer')->eq($this->app->user->account) ->andWhere('t3.result')->eq('') ->andWhere('t1.status')->eq('reviewing') ->markRight(1) ->orWhere('t1.id')->in($epicIDList) ->markRight(1) ->andWhere('t1.deleted')->eq(0) ->andWhere("FIND_IN_SET('{$this->config->vision}', t1.vision)") ->orderBy($orderBy) ->page($pager, 't1.id') ->fetchAll('id'); } else { $epics = $this->dao->select("distinct t1.*, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) as priOrder, t2.name as productTitle")->from(TABLE_STORY)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') ->leftJoin(TABLE_STORYREVIEW)->alias('t3')->on('t1.id = t3.story') ->where($myEpicQuery) ->andWhere('t1.type')->eq('epic') ->andWhere('t1.assignedTo',1)->eq($this->app->user->account) ->orWhere('(t3.reviewer')->eq($this->app->user->account) ->andWhere('t3.result')->eq('') ->andWhere('t1.status')->eq('reviewing') ->markRight(1) ->markRight(1) ->andWhere('t1.deleted')->eq(0) ->andWhere("FIND_IN_SET('{$this->config->vision}', t1.vision)") ->orderBy($orderBy) ->page($pager, 't1.id') ->fetchAll('id'); } return $epics; } /** * 通过搜索查找用户需求。 * Fetch requirements by search. * * @param string $myRequirementQuery * @param string $type * @param string $orderBy * @param object $pager * @param array $requirementIDList * @access protected * @return array */ protected function fetchRequirementsBySearch($myRequirementQuery, $type, $orderBy, $pager = null, $requirementIDList = array()) { if($type == 'contribute') { $requirements = $this->dao->select("distinct t1.*, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) as priOrder, t2.name as productTitle")->from(TABLE_STORY)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') ->leftJoin(TABLE_STORYREVIEW)->alias('t3')->on('t1.id = t3.story') ->where($myRequirementQuery) ->andWhere('t1.type')->eq('requirement') ->andWhere('t1.openedBy',1)->eq($this->app->user->account) ->orWhere('t1.closedBy')->eq($this->app->user->account) ->orWhere('t3.reviewer')->eq($this->app->user->account) ->orWhere('t1.id')->in($requirementIDList) ->markRight(1) ->andWhere('t1.deleted')->eq(0) ->andWhere("FIND_IN_SET('{$this->config->vision}', t1.vision)") ->orderBy($orderBy) ->page($pager, 't1.id') ->fetchAll('id'); } else { $requirements = $this->dao->select("distinct t1.*, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) as priOrder, t2.name as productTitle")->from(TABLE_STORY)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') ->leftJoin(TABLE_STORYREVIEW)->alias('t3')->on('t1.id = t3.story') ->where($myRequirementQuery) ->andWhere('t1.type')->eq('requirement') ->andWhere('t1.assignedTo',1)->eq($this->app->user->account) ->orWhere('t3.reviewer')->eq($this->app->user->account) ->markRight(1) ->andWhere('t1.deleted')->eq(0) ->andWhere("FIND_IN_SET('{$this->config->vision}', t1.vision)") ->orderBy($orderBy) ->page($pager, 't1.id') ->fetchAll('id'); } return $requirements; } /** * 构建待审批的审批数据。 * Build the data of the approval to be approved. * * @param array $objectGroup * @param array $flows * @param array $objectNameFields * @access protected * @return array */ protected function buildReviewingFlows($objectGroup, $flows, $objectNameFields) { $approvalList = array(); foreach($objectGroup as $objectType => $objects) { $title = ''; $titleFieldName = zget($objectNameFields, $objectType, ''); $openedDateField = zget($this->config->my->openedDateField, $objectType, 'openedDate'); if(empty($titleFieldName) && isset($flows[$objectType])) { if(!empty($flows[$objectType]->titleField)) $titleFieldName = $flows[$objectType]->titleField; if(empty($flows[$objectType]->titleField)) $title = $flows[$objectType]->name; $openedDateField = 'createdDate'; } foreach($objects as $object) { $data = new stdclass(); $data->id = $object->id; $data->title = empty($titleFieldName) || !isset($object->$titleFieldName) ? $title . " #{$object->id}" : $object->{$titleFieldName}; $data->type = $objectType; $data->time = $object->{$openedDateField}; $data->status = $objectType == 'charter' ? $object->reviewStatus : 'doing'; $data->app = isset($flows[$objectType]->app) ? $flows[$objectType]->app : zget($this->lang->navGroup, $objectType, ''); $data->product = isset($object->product) ? $object->product : 0; $data->project = isset($object->project) ? $object->project : 0; $approvalList[] = $data; } } return $approvalList; } }