diff --git a/module/bug/control.php b/module/bug/control.php index 5828b04e5c..6b48550e2e 100644 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -878,6 +878,110 @@ class bug extends control $this->display(); } + /** + * Link related bugs. + * + * @param int $bugID + * @param string $bugs + * @param string $browseType + * @param int $param + * @access public + * @return void + */ + public function linkBugs($bugID, $bugs = '', $browseType = '', $param = 0) + { + /* Link bugs. */ + if(!empty($_POST)) + { + $bugs = $this->bug->linkBugs($bugID, $bugs); + if(isonlybody()) die(js::closeModal('parent.parent', '', "function(){parent.parent.loadLinkedBugs('$bugID', '$bugs')}")); + die(js::locate($this->createLink('bug', 'edit', "bugID=$bugID"), 'parent')); + } + + /* Get bug, productID and queryID. */ + $bug = $this->bug->getById($bugID); + $productID = $this->product->saveState($bug->product, $this->products); + $queryID = ($browseType == 'bysearch') ? (int)$param : 0; + + /* Set the menu. */ + $this->bug->setMenu($this->products, $productID, $bug->branch); + + /* Build the search form. */ + $actionURL = $this->createLink('bug', 'linkBugs', "bugID=$bugID&bugs=$bugs&browseType=bySearch&queryID=myQueryID", '', true); + $this->bug->buildSearchForm($productID, $this->products, $queryID, $actionURL); + $this->loadModel('search')->setSearchParams($this->config->bug->search); + + /* Get bugs to link. */ + $allBugs = array(); + if($browseType == 'bySearch') $allBugs = $this->bug->getBySearch($bug->product, $quueryID, 'id', null); + + /* Assign. */ + $this->view->title = $this->lang->bug->linkBugs . "BUG #$bug->id $bug->title - " . $this->products[$productID]; + $this->view->position[] = html::a($this->createLink('product', 'view', "productID=$productID"), $this->products[$productID]); + $this->view->position[] = html::a($this->createLink('bug', 'view', "bugID=$bugID"), $bug->title); + $this->view->position[] = $this->lang->bug->linkBugs; + $this->view->bug = $bug; + $this->view->allBugs = $allBugs; + $this->view->users = $this->loadModel('user')->getPairs('noletter'); + + $this->display(); + } + + /** + * AJAX: get linked bugs. + * + * @param int $bugID + * @param string $linkedBugs + * @access public + * @return string + */ + public function ajaxGetLinkedBugs($bugID, $linkedBugs = '') + { + /* Get bug and linked bugs. */ + $bug = $this->bug->getById($bugID); + $bugs = $this->bug->getLinkedBugs($linkedBugs); + + /* Build linkBug list.*/ + $output = "'; + + die($output); + } + + /** + * AJAX: delete a linked bug. + * + * @param int $bugID + * @param int $deleteBug + * @access public + * @return string + */ + public function ajaxDeleteLinkedBug($bugID, $deleteBug) + { + /* Get bug and bugs. */ + $bug = $this->bug->getById($bugID); + $bugs = $this->bug->deleteLinkedBug($bugID, $deleteBug); + + /* Build linkBug list. */ + $output = "'; + + die($output); + } + /** * Batch close bugs. * diff --git a/module/bug/css/edit.css b/module/bug/css/edit.css index e1b4438cce..57e4d4ef0a 100644 --- a/module/bug/css/edit.css +++ b/module/bug/css/edit.css @@ -2,3 +2,4 @@ .col-side .chosen-container {width: 218px!important} .col-side .chosen-container[id^="openedBuild"] {width: 172px!important} .col-side .chosen-container[id^="resolvedBuild"] {width: 172px!important} +#linkBugBox > .list-unstyled > li {margin-left:-56px} diff --git a/module/bug/js/edit.js b/module/bug/js/edit.js index 994831ae60..9893463fcd 100644 --- a/module/bug/js/edit.js +++ b/module/bug/js/edit.js @@ -54,3 +54,31 @@ function loadModuleRelated() productID = $('#product').val(); setStories(moduleID, productID); } + +/** + * Delete a linked bug. + * + * @param int $bugID + * @param int $deleteBug + * @access public + * @return void + */ +function deleteLinkedBug(bugID, deleteBug) +{ + deleteLink = createLink('bug', 'ajaxDeleteLinkedBug', 'bugID=' + bugID + '&deleteBug=' + deleteBug); + $('#linkBugBox').load(deleteLink); +} + +/** + * Load linked bugs. + * + * @param int $bugID + * @param string $linkedBugs + * @access public + * @return void + */ +function loadLinkedBugs(bugID, linkedBugs) +{ + bugLink = createLink('bug', 'ajaxGetLinkedBugs', 'bugID=' + bugID + '&linkedBugs=' + linkedBugs); + $('#linkBugBox').load(bugLink); +} diff --git a/module/bug/lang/en.php b/module/bug/lang/en.php index 41efb61a66..8382dc6a98 100644 --- a/module/bug/lang/en.php +++ b/module/bug/lang/en.php @@ -60,6 +60,7 @@ $lang->bug->duplicateBug = 'Duplicate'; $lang->bug->lastEditedBy = 'Last Edited By'; $lang->bug->lastEditedDate = 'Last Edited Date'; $lang->bug->linkBug = 'Related'; +$lang->bug->linkBugs = 'Link bugs'; $lang->bug->case = 'Case'; $lang->bug->files = 'Files'; $lang->bug->keywords = 'Keywords'; @@ -359,6 +360,8 @@ $lang->bug->action->tostory = array('main' => '$date, To story by bug->action->totask = array('main' => '$date, To task by $actor, ID is $extra.'); $lang->bug->action->linked2plan = array('main' => '$date, Link to plan by $actor,ID is $extra。'); $lang->bug->action->unlinkedfromplan = array('main' => '$date, Unlink from plan $extra by $actor.'); +$lang->bug->action->linked2bug = array('main' => '$date, linked related bugs $extra by $actor.'); +$lang->bug->action->unlinkedbug = array('main' => '$date, removed related bugs $extra by $actor.'); $lang->bug->placeholder = new stdclass(); $lang->bug->placeholder->chooseBuilds = 'Choose builds...'; diff --git a/module/bug/lang/zh-cn.php b/module/bug/lang/zh-cn.php index 12afba16a1..dae8bbb8e6 100644 --- a/module/bug/lang/zh-cn.php +++ b/module/bug/lang/zh-cn.php @@ -60,6 +60,7 @@ $lang->bug->duplicateBug = '重复ID'; $lang->bug->lastEditedBy = '最后修改者'; $lang->bug->lastEditedDate = '最后修改日期'; $lang->bug->linkBug = '相关Bug'; +$lang->bug->linkBugs = '关联Bug'; $lang->bug->case = '相关用例'; $lang->bug->files = '附件'; $lang->bug->keywords = '关键词'; @@ -359,6 +360,8 @@ $lang->bug->action->tostory = array('main' => '$date, 由 $acto $lang->bug->action->totask = array('main' => '$date, 由 $actor 导入为任务,编号为 $extra。'); $lang->bug->action->linked2plan = array('main' => '$date, 由 $actor 关联到计划 $extra。'); $lang->bug->action->unlinkedfromplan = array('main' => '$date, 由 $actor 从计划 $extra 移除。'); +$lang->bug->action->linked2bug = array('main' => '$date, 由 $actor 关联相关Bug $extra。'); +$lang->bug->action->unlinkedbug = array('main' => '$date, 由 $actor 移除相关Bug $extra。'); $lang->bug->placeholder = new stdclass(); $lang->bug->placeholder->chooseBuilds = '选择相关版本...'; diff --git a/module/bug/model.php b/module/bug/model.php index 1188424179..faab114289 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -794,6 +794,64 @@ class bugModel extends model $this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->where('id')->eq((int)$bugID)->exec(); } + /** + * Link bugs. + * + * @param int $bugID + * @param string $bugs + * @access public + * @return string + */ + public function linkBugs($bugID, $bugs = '') + { + if($this->post->bugs == false) return $bugs; + + $bugs = implode(',', $this->post->bugs) . ',' . trim($bugs, ','); + $this->dao->update(TABLE_BUG)->set('linkBug')->eq(trim($bugs, ','))->where('id')->eq($bugID)->exec(); + if(dao::isError()) die(js::error(dao::getError())); + $this->loadModel('action')->create('bug', $bugID, 'linked2Bug', '', implode(',', $this->post->bugs)); + + return $bugs; + } + + /** + * Delete a linked bug. + * + * @param int $bugID + * @param int $deleteBug + * @access public + * @return array + */ + public function deleteLinkedBug($bugID, $deleteBug = 0) + { + $bug = $this->getById($bugID); + + $bugs = explode(',', trim($bug->linkBug, ',')); + foreach($bugs as $key => $bugId) + { + if($bugId == $deleteBug) unset($bugs[$key]); + } + $bugs = implode(',', $bugs); + + $this->dao->update(TABLE_BUG)->set('linkBug')->eq($bugs)->where('id')->eq($bugID)->exec(); + if(dao::isError()) die(js::error(dao::getError())); + $this->loadModel('action')->create('bug', $bugID, 'unLinkedBug', '', $deleteBug); + + return $this->getLinkedBugs($bugs); + } + + /** + * Get linked bugs. + * + * @param string $bugs + * @access public + * @return array + */ + public function getLinkedBugs($bugs) + { + return $this->dao->select('id, title')->from(TABLE_BUG)->where('id')->in($bugs)->fetchPairs(); + } + /** * Build search form. * diff --git a/module/bug/view/edit.html.php b/module/bug/view/edit.html.php index 07b4fc5d8e..53838d3883 100644 --- a/module/bug/view/edit.html.php +++ b/module/bug/view/edit.html.php @@ -230,9 +230,25 @@ js::set('oldResolvedBuild' , $bug->resolvedBuild);
bug->legendMisc;?> - + - + case):?> diff --git a/module/bug/view/view.html.php b/module/bug/view/view.html.php index 0e85d09ec2..fc08e51f47 100644 --- a/module/bug/view/view.html.php +++ b/module/bug/view/view.html.php @@ -279,10 +279,13 @@
bug->linkBug;?>linkBug, 'class="form-control"');?> +
    + createLink('bug', 'linkBugs', "bugID=$bug->id&bugs=$bug->linkBug", '', true), $lang->bug->linkBugs, '', "class='iframe' data-width='85%'");?> + linkBugTitles)) + { + foreach($bug->linkBugTitles as $linkBugID => $linkBugTitle) + { + echo '
  • '; + echo html::a(inlink('view', "bugID=$linkBugID"), "#$linkBugID " . $linkBugTitle); + echo html::a("javascript:deleteLinkedBug($bug->id, $linkBugID)", '', '', "title='{$lang->unlink}' style='float:right'"); + echo '
  • '; + } + } + ?> +
+
+ case):?> - + + + toCases):?> - - + + + + toStory != 0):?> - + + + toTask != 0):?> - + +
bug->fromCase;?>case) echo html::a($this->createLink('testcase', 'view', "caseID=$bug->case"), "#$bug->case $bug->caseTitle", '_blank');?>createLink('testcase', 'view', "caseID=$bug->case"), "#$bug->case $bug->caseTitle", '_blank');?>
bug->toCase;?> @@ -294,8 +297,9 @@ ?>
bug->linkBug;?>
bug->linkBug;?> linkBugTitles)) @@ -308,14 +312,18 @@ ?>
bug->toStory;?>toStory != 0) echo html::a($this->createLink('story', 'view', "storyID=$bug->toStory"), "#$bug->toStory $bug->toStoryTitle", '_blank');?>createLink('story', 'view', "storyID=$bug->toStory"), "#$bug->toStory $bug->toStoryTitle", '_blank');?>
bug->toTask;?>toTask != 0) echo html::a($this->createLink('task', 'view', "taskID=$bug->toTask"), "#$bug->toTask $bug->toTaskTitle", '_blank');?>createLink('task', 'view', "taskID=$bug->toTask"), "#$bug->toTask $bug->toTaskTitle", '_blank');?>