diff --git a/db/zentao.sql b/db/zentao.sql index f9f104ca7f..a3bd4f7843 100644 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -1557,6 +1557,9 @@ INSERT INTO `zt_groupPriv` (`company`, `group`, `module`, `method`) VALUES (1, 2, 'task', 'batchEdit'), (1, 3, 'task', 'batchEdit'), (1, 4, 'task', 'batchEdit'), -(1, 5, 'task', 'batchEdit'); - - +(1, 5, 'task', 'batchEdit'), +(1, 1, 'bug', 'batchEdit'), +(1, 2, 'bug', 'batchEdit'), +(1, 3, 'bug', 'batchEdit'), +(1, 4, 'bug', 'batchEdit'), +(1, 5, 'bug', 'batchEdit'); diff --git a/module/bug/control.php b/module/bug/control.php index abc8fd6843..0188e16ba2 100644 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -457,6 +457,79 @@ class bug extends control $this->display(); } + /** + * Batch edit bug. + * + * @param string $from example:bugBrowse, bugBatchEdit. + * @param int $productID + * @param string $orderBy + * @access public + * @return void + */ + public function batchEdit($from = '', $productID = 0, $orderBy = '') + { + if($from == 'bugBrowse') + { + /* Initialize vars.*/ + if(!$orderBy) $orderBy = $this->cookie->qaBugOrder ? $this->cookie->qaBugOrder : 'id_desc'; + $editedBugs = array(); + $allBugs = $this->dao->select('*')->from(TABLE_BUG)->alias('t1')->where($this->session->bugReportCondition)->orderBy($orderBy)->fetchAll('id'); + $bugIDList = $this->post->bugIDList ? $this->post->bugIDList : array(); + $product = $this->product->getByID($productID); + $columns = 9; + $showSuhosinInfo = false; + + /* Set product menu. */ + $this->bug->setMenu($this->products, $productID); + + /* Initialize the tasks whose need to edited. */ + foreach($allBugs as $bug) if(in_array($bug->id, $bugIDList)) $editedBugs[$bug->id] = $bug; + + /* Judge whether the editedTasks is too large. */ + $showSuhosinInfo = $this->loadModel('common')->judgeSuhosinSetting(count($editedBugs), $columns); + + /* Set the sessions. */ + $this->app->session->set('showSuhosinInfo', $showSuhosinInfo); + + /* Assign. */ + $this->view->header['title'] = $product->name . $this->lang->colon . $this->lang->bug->batchEdit; + $this->view->position[] = $this->lang->bug->batchEdit; + + if($showSuhosinInfo) $this->view->suhosinInfo = $this->lang->suhosinInfo; + $this->view->productID = $productID; + $this->view->editedBugs = $editedBugs; + $this->view->users = $this->user->getPairs('noletter'); + + $this->display(); + } + elseif($from == 'bugBatchEdit') + { + $allChanges = $this->bug->batchUpdate(); + + foreach($allChanges as $bugID => $changes) + { + $actionID = $this->action->create('bug', $bugID, 'Edited'); + $this->action->logHistory($actionID, $changes); + $this->sendmail($bugID, $actionID); + + $bug = $this->bug->getById($bugID); + if($bug->toTask != 0) + { + foreach($changes as $change) + { + if($change['field'] == 'status') + { + $confirmURL = $this->createLink('task', 'view', "taskID=$bug->toTask"); + $cancelURL = $this->server->HTTP_REFERER; + die(js::confirm(sprintf($this->lang->bug->remindTask, $bug->task), $confirmURL, $cancelURL, 'parent', 'parent')); + } + } + } + } + die(js::locate($this->session->bugList)); + } + } + /** * confirm a bug. * diff --git a/module/bug/js/batchedit.js b/module/bug/js/batchedit.js new file mode 100755 index 0000000000..0b26083423 --- /dev/null +++ b/module/bug/js/batchedit.js @@ -0,0 +1,18 @@ +/** + * Set duplicate field. + * + * @param string $resolution + * @access public + * @return void + */ +function setDuplicate(resolution, bugID) +{ + if(resolution == 'duplicate') + { + $('#duplicateBugBox' + bugID).show(); + } + else + { + $('#duplicateBugBox' + bugID).hide(); + } +} diff --git a/module/bug/lang/en.php b/module/bug/lang/en.php index 8b6b6a5174..b6018e090f 100644 --- a/module/bug/lang/en.php +++ b/module/bug/lang/en.php @@ -69,6 +69,7 @@ $lang->bug->index = 'Index'; $lang->bug->create = 'Create Bug'; $lang->bug->confirmBug = 'Confirm Bug'; $lang->bug->edit = 'Edit Bug'; +$lang->bug->batchEdit = 'Batch edit'; $lang->bug->browse = 'Browse Bug'; $lang->bug->view = 'Bug Info'; $lang->bug->resolve = 'Resolve Bug'; diff --git a/module/bug/lang/zh-cn.php b/module/bug/lang/zh-cn.php index 1b305efda9..0234e53ba4 100644 --- a/module/bug/lang/zh-cn.php +++ b/module/bug/lang/zh-cn.php @@ -54,7 +54,7 @@ $lang->bug->resolvedDate = '解决日期'; $lang->bug->resolvedDateAB = '解决日期'; $lang->bug->closedBy = '由谁关闭'; $lang->bug->closedDate = '关闭日期'; -$lang->bug->duplicateBug = '重复Bug'; +$lang->bug->duplicateBug = '重复ID'; $lang->bug->lastEditedBy = '最后修改者'; $lang->bug->lastEditedDate = '最后修改日期'; $lang->bug->linkBug = '相关Bug'; @@ -69,6 +69,7 @@ $lang->bug->index = '首页'; $lang->bug->create = '创建Bug'; $lang->bug->confirmBug = '确认'; $lang->bug->edit = '编辑Bug'; +$lang->bug->batchEdit = '批量编辑'; $lang->bug->browse = 'Bug列表'; $lang->bug->view = 'Bug详情'; $lang->bug->resolve = '解决Bug'; diff --git a/module/bug/model.php b/module/bug/model.php index f1947d9df0..97c2874b48 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -193,6 +193,86 @@ class bugModel extends model if(!dao::isError()) return common::createChanges($oldBug, $bug); } + /** + * Batch update bug. + * + * @access public + * @return void + */ + public function batchUpdate() + { + $bugs = array(); + $allChanges = array(); + $now = helper::now(); + $bugIDList = $this->post->bugIDList ? $this->post->bugIDList : array(); + + /* Adjust whether the post data is complete, if not, remove the last element of $bugIDList. */ + if($this->session->showSuhosinInfo) array_pop($bugIDList); + + if(!empty($bugIDList)) + { + /* Initialize bugs from the post data.*/ + foreach($bugIDList as $bugID) + { + $oldBug = $this->getByID($bugID); + + $bug->lastEditedBy = $this->app->user->account; + $bug->lastEditedDate = $now; + $bug->type = $this->post->types[$bugID]; + $bug->severity = $this->post->severities[$bugID]; + $bug->pri = $this->post->pris[$bugID]; + $bug->status = $this->post->statuses[$bugID]; + $bug->title = htmlspecialchars($this->post->titles[$bugID]); + $bug->assignedTo = $this->post->assignedTos[$bugID]; + $bug->resolvedBy = $this->post->resolvedBys[$bugID]; + $bug->resolution = $this->post->resolutions[$bugID]; + $bug->duplicateBug = $this->post->duplicateBugs[$bugID] ? $this->post->duplicateBugs[$bugID] : $oldBug->duplicateBug; + + if($bug->assignedTo != $oldBug->assignedTo) $bug->assignedDate = $now; + if($bug->resolvedBy != '' or $bug->resolution != '') $bug->resolvedDate = $now; + if($bug->resolution != '' and $bug->resolvedBy == '') $bug->resolvedBy = $this->app->user->account; + if($bug->resolution != '') + { + $bug->status = 'resolved'; + $bug->confirmed = 1; + } + if($bug->resolution != '' and $bug->assignedTo == '') + { + $bug->assignedTo = $oldBug->openedBy; + $bug->assignedDate = $now; + } + + $bugs[$bugID] = $bug; + unset($bug); + } + + /* Update bugs. */ + foreach($bugs as $bugID => $bug) + { + $oldBug = $this->getByID($bugID); + + $this->dao->update(TABLE_BUG)->data($bug) + ->autoCheck() + ->batchCheck($this->config->bug->edit->requiredFields, 'notempty') + ->checkIF($bug->resolvedBy, 'resolution', 'notempty') + ->checkIF($bug->resolution == 'duplicate', 'duplicateBug', 'notempty') + ->where('id')->eq((int)$bugID) + ->exec(); + + if(!dao::isError()) + { + $allChanges[$bugID] = common::createChanges($oldBug, $bug); + } + else + { + die(js::error('bug#' . $bugID . dao::getError(true))); + } + } + } + + return $allChanges; + } + /** * Confirm a bug. * diff --git a/module/bug/view/batchedit.html.php b/module/bug/view/batchedit.html.php new file mode 100755 index 0000000000..aff97dc25f --- /dev/null +++ b/module/bug/view/batchedit.html.php @@ -0,0 +1,50 @@ + + * @package bug + * @version $Id$ + * @link http://www.zentao.net + */ +?> + +
+ diff --git a/module/bug/view/browse.html.php b/module/bug/view/browse.html.php index 3112c544ab..2509b98aee 100644 --- a/module/bug/view/browse.html.php +++ b/module/bug/view/browse.html.php @@ -47,129 +47,136 @@ var customed = ; -|
-
-
-
-
- createLink('tree', 'browse', "productID=$productID&view=bug"), $lang->tree->manage);?>
+ |
+