tao.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. <?php
  2. class bugTao extends bugModel
  3. {
  4. /**
  5. * Get bug details, including all contents of the TABLE_BUG, execution name, associated story name, associated story status, associated story version, associated task name, and associated plan name.
  6. * 获取bug的详情,包含bug表的所有内容、所属执行名称、关联需求名称、关联需求状态、关联需求版本、关联任务名称、关联计划名称
  7. *
  8. * @param int $bugID
  9. * @access protected
  10. * @return object|false
  11. */
  12. protected function fetchBugInfo($bugID)
  13. {
  14. return $this->dao->select('t1.*, t2.name AS executionName, t3.title AS storyTitle, t3.status AS storyStatus, t3.version AS latestStoryVersion, t4.name AS taskName, t5.title AS planName')
  15. ->from(TABLE_BUG)->alias('t1')
  16. ->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.execution = t2.id')
  17. ->leftJoin(TABLE_STORY)->alias('t3')->on('t1.story = t3.id')
  18. ->leftJoin(TABLE_TASK)->alias('t4')->on('t1.task = t4.id')
  19. ->leftJoin(TABLE_PRODUCTPLAN)->alias('t5')->on('t1.plan = t5.id')
  20. ->where('t1.id')->eq((int)$bugID)
  21. ->fetch();
  22. }
  23. /**
  24. * Get bug list by browse type.
  25. * 通过浏览类型获取 bug 列表。
  26. *
  27. * @param string $browseType
  28. * @param array $productIdList
  29. * @param int $projectID
  30. * @param int[] $executionIdList
  31. * @param int|string $branch
  32. * @param array $moduleIdList
  33. * @param int $queryID
  34. * @param string $orderBy
  35. * @param object $pager
  36. * @access protected
  37. * @return array
  38. */
  39. protected function getListByBrowseType($browseType, $productIdList, $projectID, $executionIdList, $branch, $moduleIdList, $queryID, $orderBy, $pager = null)
  40. {
  41. $browseType = strtolower($browseType);
  42. if($browseType == 'bysearch') return $this->getBySearch('bug', $productIdList, $branch, $projectID, 0, $queryID, '', $orderBy, $pager);
  43. if($browseType == 'needconfirm') return $this->getNeedConfirmList($productIdList, $projectID, $executionIdList, $branch, $moduleIdList, $orderBy, $pager);
  44. $lastEditedDate = '';
  45. if($browseType == 'longlifebugs') $lastEditedDate = date(DT_DATE1, time() - $this->config->bug->longlife * 24 * 3600);
  46. $bugIdListAssignedByMe = array();
  47. if($browseType == 'assignedbyme') $bugIdListAssignedByMe = $this->dao->select('objectID')->from(TABLE_ACTION)->where('objectType')->eq('bug')->andWhere('action')->eq('assigned')->andWhere('actor')->eq($this->app->user->account)->fetchPairs();
  48. $executionIdList[] = '0';
  49. $bugList = $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) AS priOrder, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) AS severityOrder")->from(TABLE_BUG)
  50. ->where('deleted')->eq('0')
  51. ->andWhere('product')->in($productIdList)
  52. ->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
  53. ->beginIF($this->app->tab !== 'doc')->andWhere('execution')->in($executionIdList)->fi()
  54. ->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
  55. ->beginIF($moduleIdList)->andWhere('module')->in($moduleIdList)->fi()
  56. ->beginIF(!$this->app->user->admin)->andWhere('project')->in('0,' . $this->app->user->view->projects)->fi()
  57. ->beginIF($browseType == 'assigntome')->andWhere('assignedTo')->eq($this->app->user->account)->fi()
  58. ->beginIF($browseType == 'openedbyme')->andWhere('openedBy')->eq($this->app->user->account)->fi()
  59. ->beginIF($browseType == 'resolvedbyme')->andWhere('resolvedBy')->eq($this->app->user->account)->fi()
  60. ->beginIF($browseType == 'assigntonull')->andWhere('assignedTo')->eq('')->fi()
  61. ->beginIF($browseType == 'unconfirmed')->andWhere('confirmed')->eq(0)->fi()
  62. ->beginIF($browseType == 'unclosed')->andWhere('status')->ne('closed')->fi()
  63. ->beginIF($browseType == 'unresolved')->andWhere('status')->eq('active')->fi()
  64. ->beginIF($browseType == 'toclosed')->andWhere('status')->eq('resolved')->fi()
  65. ->beginIF($browseType == 'postponedbugs')->andWhere('resolution')->eq('postponed')->fi()
  66. ->beginIF($browseType == 'review')->andWhere("FIND_IN_SET('{$this->app->user->account}', reviewers)")->fi()
  67. ->beginIF($browseType == 'feedback')->andWhere('feedback')->ne('0')->fi()
  68. ->beginIF($browseType == 'longlifebugs')
  69. ->andWhere('lastEditedDate')->lt($lastEditedDate)
  70. ->andWhere('openedDate')->lt($lastEditedDate)
  71. ->andWhere('status')->ne('closed')
  72. ->fi()
  73. ->beginIF($browseType == 'overduebugs')
  74. ->andWhere('status')->eq('active')
  75. ->andWhere('deadline')->lt(helper::today())
  76. ->fi()
  77. ->beginIF($browseType == 'assignedbyme')
  78. ->andWhere('status')->ne('closed')
  79. ->andWhere('id')->in($bugIdListAssignedByMe)
  80. ->fi()
  81. ->orderBy($orderBy)
  82. ->page($pager)
  83. ->fetchAll('id', false);
  84. $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'bug');
  85. return $bugList;
  86. }
  87. /**
  88. * 获取需要确认需求变动的 bug 列表。
  89. * Get bug list that related story need to be confirmed.
  90. *
  91. * @param array $productIdList
  92. * @param int $projectID
  93. * @param int[] $executionIdList
  94. * @param int|string $branch
  95. * @param array $moduleIdList
  96. * @param string $orderBy
  97. * @param object $pager
  98. * @access protected
  99. * @return array
  100. */
  101. protected function getNeedConfirmList($productIdList, $projectID, $executionIdList, $branch, $moduleIdList, $orderBy, $pager = null)
  102. {
  103. return $this->dao->select("t1.*, t2.title AS storyTitle, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) AS priOrder, IF(t1.`severity` = 0, {$this->config->maxPriValue}, t1.`severity`) AS severityOrder")->from(TABLE_BUG)->alias('t1')
  104. ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
  105. ->where('t1.deleted')->eq('0')
  106. ->andWhere('t2.status')->eq('active')
  107. ->andWhere('t2.version > t1.storyVersion')
  108. ->andWhere('t1.product')->in($productIdList)
  109. ->beginIF($projectID)->andWhere('t1.project')->eq($projectID)->fi()
  110. ->beginIF($this->app->tab !== 'qa')->andWhere('t1.execution')->in($executionIdList)->fi()
  111. ->beginIF($branch !== 'all')->andWhere('t1.branch')->in($branch)->fi()
  112. ->beginIF($moduleIdList)->andWhere('t1.module')->in($moduleIdList)->fi()
  113. ->beginIF(!$this->app->user->admin)->andWhere('t1.project')->in('0,' . $this->app->user->view->projects)->fi()
  114. ->orderBy($orderBy)
  115. ->page($pager)
  116. ->fetchAll('id', false);
  117. }
  118. /**
  119. * Get cases created by bug.
  120. * 获取bug建的用例。
  121. *
  122. * @param int $bugID
  123. * @access protected
  124. * @return array
  125. */
  126. protected function getCasesFromBug($bugID)
  127. {
  128. return $this->dao->select('id, title')->from(TABLE_CASE)->where('`fromBug`')->eq($bugID)->fetchPairs();
  129. }
  130. /**
  131. * Get an array of id and title pairs by buglist.
  132. * 传入一个buglist,获得bug的id和title键值对数组。
  133. *
  134. * @param string|array $bugList
  135. * @access protected
  136. * @return array
  137. */
  138. protected function getBugPairsByList($bugList)
  139. {
  140. return $this->dao->select('id,title')->from(TABLE_BUG)->where('id')->in($bugList)->fetchPairs();
  141. }
  142. /**
  143. * Get object title/name base on the params.
  144. * 根据传入的参数,获取对象名称。
  145. *
  146. * @param int $objectID
  147. * @param string $table
  148. * @param string $field
  149. * @access protected
  150. * @return string
  151. */
  152. protected function getNameFromTable($objectID, $table, $field)
  153. {
  154. return $this->dao->findById($objectID)->from($table)->fields($field)->fetch($field);
  155. }
  156. /**
  157. * Call checkDelayBug in foreach to check if the bug is delay.
  158. * 循环调用checkDelayBug,检查bug是否延期
  159. *
  160. * @param array $bugs
  161. * @access protected
  162. * @return object[]
  163. */
  164. protected function batchAppendDelayedDays($bugs)
  165. {
  166. foreach($bugs as $bug) $this->appendDelayedDays($bug);
  167. return $bugs;
  168. }
  169. /**
  170. * If the bug is delayed, add the bug->delay field to show the delay time (day).
  171. * 添加bug->delay字段,内容为延期的时长(天),不延期则为0
  172. *
  173. * @param object $bug
  174. * @access protected
  175. * @return object
  176. */
  177. protected function appendDelayedDays($bug)
  178. {
  179. if(helper::isZeroDate($bug->deadline)) return $bug;
  180. $delay = 0;
  181. if($bug->resolvedDate and !helper::isZeroDate($bug->resolvedDate))
  182. {
  183. $delay = helper::diffDate(substr($bug->resolvedDate, 0, 10), $bug->deadline);
  184. }
  185. elseif($bug->status == 'active')
  186. {
  187. $delay = helper::diffDate(helper::today(), $bug->deadline);
  188. }
  189. if($delay > 0) $bug->delay = $delay;
  190. return $bug;
  191. }
  192. /**
  193. * 处理搜索的查询语句。
  194. * Process search query.
  195. *
  196. * @param string $object bug|project
  197. * @param int $queryID
  198. * @param array|int $productIdList
  199. * @param int|string $branch
  200. * @access protected
  201. * @return string
  202. */
  203. protected function processSearchQuery($object, $queryID, $productIdList, $branch)
  204. {
  205. $queryName = $object != 'bug' ? $object . 'BugQuery' : 'bugQuery';
  206. $formName = $object != 'bug' ? $object . 'BugForm' : 'bugForm';
  207. /* 设置 bug 查询的 session。*/
  208. /* Set the session of bug query. */
  209. if($queryID)
  210. {
  211. $query = $this->loadModel('search')->getQuery($queryID);
  212. if($query)
  213. {
  214. $this->session->set($queryName, $query->sql);
  215. $this->session->set($formName, $query->form);
  216. }
  217. }
  218. if($this->session->$queryName === false) $this->session->set($queryName, ' 1 = 1');
  219. $bugQuery = $this->getBugQuery($this->session->$queryName);
  220. $bugQuery = str_replace('`project` in ()', '1 = 1', $bugQuery); // 系统中没有项目时,替换查询条件为1=1
  221. /* 如果搜索项目下的 bug 列表,在 bug 的查询中加上产品的限制。*/
  222. /* If search bug under project, append product condition in bug query. */
  223. if($object == 'project' || $object == 'execution') return $this->appendProductConditionForProject($bugQuery, $productIdList, $branch);
  224. return $this->appendProductConditionForBug($bugQuery, (array)$productIdList, (string)$branch);
  225. }
  226. /**
  227. * Append product condition for project.
  228. *
  229. * @param string $bugQuery
  230. * @param int $productID
  231. * @param string|int $branchID
  232. * @access protected
  233. * @return string
  234. */
  235. protected function appendProductConditionForProject($bugQuery, $productID, $branchID)
  236. {
  237. if(strpos($bugQuery, 'product') === false && strpos($bugQuery, '`product` IN') === false && $productID)
  238. {
  239. $bugQuery .= ' AND `product` = ' . $productID;
  240. if($branchID != 'all') $bugQuery .= ' AND `branch` = ' . $branchID;
  241. }
  242. return $bugQuery;
  243. }
  244. /**
  245. * Append product condition for bug.
  246. *
  247. * @param string $bugQuery
  248. * @param array $productIdList
  249. * @param string $branch
  250. * @access protected
  251. * @return string
  252. */
  253. protected function appendProductConditionForBug($bugQuery, $productIdList, $branch)
  254. {
  255. if(strpos($bugQuery, '`product`') !== false)
  256. {
  257. $productPairs = $this->loadModel('product')->getPairs('', 0, '', 'all');
  258. $productIdList = array_keys($productPairs);
  259. }
  260. $productIdList = implode(',', $productIdList);
  261. $bugQuery .= ' AND `product` IN (' . $productIdList . ')';
  262. /* 如果查询中没有分支条件,获取主干和当前分支下的 bug。*/
  263. /* If there is no branch condition in query, append it that is main and current . */
  264. $branch = $branch ? trim($branch, ',') : '0';
  265. if(strpos($branch, ',') !== false) $branch = str_replace(',', "','", $branch);
  266. if($branch !== 'all' && strpos($bugQuery, '`branch` =') === false) $bugQuery .= " AND `branch` = '$branch'";
  267. /* 将所有分支条件替换成 1。*/
  268. /* Replace the condition of all branch to 1. */
  269. $allBranch = "`branch` = 'all'";
  270. if(strpos($bugQuery, $allBranch) !== false) $bugQuery = str_replace($allBranch, '1', $bugQuery);
  271. return $bugQuery;
  272. }
  273. }