diff --git a/api/v1/entries/product.php b/api/v1/entries/product.php index 34089f3221..ae8f4e374b 100644 --- a/api/v1/entries/product.php +++ b/api/v1/entries/product.php @@ -58,7 +58,9 @@ class productEntry extends Entry $product->bugStatistic = $this->loadModel('bug')->getStatistic($productID); break; case 'moduleoptionmenu': - $product->moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($productID, 'story', 0, '0'); + $modules = $this->loadModel('tree')->getOptionMenu($productID, $this->param('moduleType', 'story')); + $product->moduleOptionMenu = array(); + foreach($modules as $id => $name) $product->moduleOptionMenu[] = array('id' => $id, 'name' => $name); break; case 'parentstories': $product->parentstories= $this->loadModel('story')->getParentStoryPairs($productID); diff --git a/lib/base/filter/filter.class.php b/lib/base/filter/filter.class.php index 8db2523369..fda784c2a2 100644 --- a/lib/base/filter/filter.class.php +++ b/lib/base/filter/filter.class.php @@ -661,11 +661,11 @@ class baseValidater global $config; if(empty($config->framework->filterXSS)) return $var; - if(stripos($var, 'post->uid) $this->file->updateObjectID($this->post->uid, $objectID, $objectType); /* Call the message notification function. */ - $this->loadModel('message')->send($objectType, $objectID, $actionType, $actionID, $actor); + $this->loadModel('message')->send(strtolower($objectType), $objectID, $actionType, $actionID, $actor); /* Add index for global search. */ $this->saveIndex($objectType, $objectID, $actionType); diff --git a/module/bug/lang/en.php b/module/bug/lang/en.php index fb26863be3..392c7ec082 100644 --- a/module/bug/lang/en.php +++ b/module/bug/lang/en.php @@ -418,6 +418,7 @@ $lang->bug->featureBar['browse']['unclosed'] = $lang->bug->unclosed; $lang->bug->featureBar['browse']['openedbyme'] = $lang->bug->openedByMe; $lang->bug->featureBar['browse']['assigntome'] = $lang->bug->assignToMe; $lang->bug->featureBar['browse']['resolvedbyme'] = $lang->bug->resolvedByMe; +$lang->bug->featureBar['browse']['assignedbyme'] = $lang->bug->assignedByMe; $lang->bug->featureBar['browse']['unresolved'] = $lang->bug->unResolved; $lang->bug->featureBar['browse']['more'] = $lang->more; diff --git a/module/bug/lang/zh-cn.php b/module/bug/lang/zh-cn.php index e8eec6b00e..25d19e7ed1 100644 --- a/module/bug/lang/zh-cn.php +++ b/module/bug/lang/zh-cn.php @@ -418,6 +418,7 @@ $lang->bug->featureBar['browse']['unclosed'] = $lang->bug->unclosed; $lang->bug->featureBar['browse']['openedbyme'] = $lang->bug->openedByMe; $lang->bug->featureBar['browse']['assigntome'] = $lang->bug->assignToMe; $lang->bug->featureBar['browse']['resolvedbyme'] = $lang->bug->resolvedByMe; +$lang->bug->featureBar['browse']['assignedbyme'] = $lang->bug->assignedByMe; $lang->bug->featureBar['browse']['toclosed'] = $lang->bug->toClosed; $lang->bug->featureBar['browse']['unresolved'] = $lang->bug->unResolved; $lang->bug->featureBar['browse']['more'] = $lang->more; diff --git a/module/bug/model.php b/module/bug/model.php index e4beb47890..d49fd2da3f 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -396,6 +396,7 @@ class bugModel extends model elseif($browseType == 'needconfirm') $bugs = $this->getByNeedconfirm($productIDList, $branch, $modules, $executions, $sort, $pager, $projectID); elseif($browseType == 'bysearch') $bugs = $this->getBySearch($productIDList, $branch, $queryID, $sort, '', $pager, $projectID); elseif($browseType == 'overduebugs') $bugs = $this->getOverdueBugs($productIDList, $branch, $modules, $executions, $sort, $pager, $projectID); + elseif($browseType == 'assignedbyme') $bugs = $this->getByAssignedbyme($productIDList, $branch, $modules, $executions, $sort, $pager, $projectID); return $this->checkDelayedBugs($bugs); } @@ -2646,6 +2647,36 @@ class bugModel extends model ->fetchAll(); } + /** + * Get by assigned by me. + * @param array $productIDList + * @param int|string $branch + * @param array $modules + * @param array $executions + * @param string $sort + * @param object $pager + * @param int $projectID + * + * @access public + * @return array + */ + public function getByAssignedbyme($productIDList, $branch, $modules, $executions, $sort, $pager, $projectID) + { + $actionIDList = $this->dao->select('objectID')->from(TABLE_ACTION)->where('objectType')->eq('bug')->andWhere('action')->eq('assigned')->andWhere('actor')->eq($this->app->user->account)->fetchPairs('objectID', 'objectID'); + return $this->dao->select('*')->from(TABLE_BUG) + ->where('product')->in($productIDList) + ->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi() + ->beginIF($modules)->andWhere('module')->in($modules)->fi() + ->beginIF($projectID)->andWhere('project')->eq($projectID)->fi() + ->andWhere('execution')->in(array_keys($executions)) + ->andWhere('deleted')->eq(0) + ->andWhere('status')->ne('closed') + ->andWhere('id')->in($actionIDList) + ->orderBy($sort) + ->page($pager) + ->fetchAll(); + } + /** * Get by Sonarqube id. * diff --git a/module/custom/control.php b/module/custom/control.php index d46597c491..6ed32f35e7 100644 --- a/module/custom/control.php +++ b/module/custom/control.php @@ -71,7 +71,18 @@ class custom extends control if(($module == 'story' or $module == 'testcase') and $field == 'review') { $this->app->loadConfig($module); - $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted'); + $this->loadModel('user'); + + if($module == 'story') + { + $this->view->depts = $this->loadModel('dept')->getDeptPairs(); + $this->view->forceReviewAll = zget($this->config->$module, 'forceReviewAll', 'false'); + $this->view->forceReview = zget($this->config->$module, 'forceReview', ''); + $this->view->forceReviewRoles = zget($this->config->$module, 'forceReviewRoles', ''); + $this->view->forceReviewDepts = zget($this->config->$module, 'forceReviewDepts', ''); + } + + $this->view->users = $module == 'story' ? $this->user->getCanCreateStoryUsers() : $this->user->getPairs('noclosed|nodeleted'); $this->view->needReview = zget($this->config->$module, 'needReview', 1); $this->view->forceReview = zget($this->config->$module, 'forceReview', ''); $this->view->forceNotReview = zget($this->config->$module, 'forceNotReview', ''); @@ -112,7 +123,16 @@ class custom extends control } elseif($module == 'story' and $field == 'review') { - $data = fixer::input('post')->join('forceReview', ',')->get(); + $data = fixer::input('post') + ->setDefault('forceReviewAll', 0) + ->setDefault('forceReviewDepts', '') + ->join('forceReview', ',') + ->join('forceReviewRoles', ',') + ->join('forceReviewDepts', ',') + ->join('forceReviewAll', ',') + ->setIF(isset($this->post->forceReviewAll), 'forceReviewAll', 1) + ->get(); + $this->loadModel('setting')->setItems("system.$module@{$this->config->vision}", $data); } elseif($module == 'story' and $field == 'reviewRules') diff --git a/module/custom/lang/en.php b/module/custom/lang/en.php index d2161714d5..257bbdc8b8 100644 --- a/module/custom/lang/en.php +++ b/module/custom/lang/en.php @@ -50,6 +50,10 @@ $lang->custom->oneUnit = "One {$lang->hourCommon}"; $lang->custom->convertRelationTitle = "Please firstly set the conversion factor from {$lang->hourCommon} to %s"; $lang->custom->superReviewers = "Super Reviewer"; $lang->custom->kanban = "Kanban"; +$lang->custom->allUsers = 'All Users'; +$lang->custom->account = 'Users'; +$lang->custom->role = 'Role'; +$lang->custom->dept = 'Dept'; if($config->systemMode == 'new') $lang->custom->execution = 'Execution'; if($config->systemMode == 'classic' || !$config->systemMode) $lang->custom->execution = $lang->executionCommon; @@ -181,6 +185,8 @@ $lang->custom->notice->readOnlyOfKanban = "If Change Forbidden, any change on $lang->custom->notice->URSREmpty = 'Custom requirement name can not be empty!'; $lang->custom->notice->confirmDelete = 'Are you sure you want to delete it?'; $lang->custom->notice->confirmReviewCase = 'Set the case in Wait to Normal?'; +$lang->custom->notice->storyReviewTip = 'After selecting by individual, position, and department, take the union of these three filters. '; +$lang->custom->notice->selectAllTip = 'After selecting all people, the reviewers will be emptied and grayed out while hiding their positions and departments.'; $lang->custom->notice->indexPage['product'] = "ZenTao 8.2+ has Product Home. Do you want to go to Product Home?"; $lang->custom->notice->indexPage['project'] = "ZenTao 8.2+ has Project Home. Do you want to go to Project Home?"; diff --git a/module/custom/lang/zh-cn.php b/module/custom/lang/zh-cn.php index 747d231c88..c4142d8e76 100644 --- a/module/custom/lang/zh-cn.php +++ b/module/custom/lang/zh-cn.php @@ -50,6 +50,10 @@ $lang->custom->oneUnit = "一个{$lang->hourCommon}"; $lang->custom->convertRelationTitle = "请先设置{$lang->hourCommon}转换为%s的换算系数"; $lang->custom->superReviewers = "超级评审人"; $lang->custom->kanban = "看板"; +$lang->custom->allUsers = '所有人员'; +$lang->custom->account = '人员'; +$lang->custom->role = '职位'; +$lang->custom->dept = '部门'; if($config->systemMode == 'new') $lang->custom->execution = '执行'; if($config->systemMode == 'classic' || !$config->systemMode) $lang->custom->execution = $lang->executionCommon; @@ -181,6 +185,8 @@ $lang->custom->notice->readOnlyOfKanban = "禁止修改后,已关闭{$lang- $lang->custom->notice->URSREmpty = '自定义需求名称不能为空!'; $lang->custom->notice->confirmDelete = '您确定要删除吗?'; $lang->custom->notice->confirmReviewCase = '是否将待评审的用例修改为正常状态?'; +$lang->custom->notice->storyReviewTip = '按人员、职位、部门勾选后,取所有人员的并集。'; +$lang->custom->notice->selectAllTip = '勾选所有人员后,会清空并置灰评审人员,同时隐藏职位、部门。'; $lang->custom->notice->indexPage['product'] = "从8.2版本起增加了产品主页视图,是否默认进入产品主页?"; $lang->custom->notice->indexPage['project'] = "从8.2版本起增加了项目主页视图,是否默认进入项目主页?"; diff --git a/module/custom/view/set.html.php b/module/custom/view/set.html.php index ef2f2ca94e..4e1a38ed76 100644 --- a/module/custom/view/set.html.php +++ b/module/custom/view/set.html.php @@ -36,6 +36,18 @@ EOT; + + +