diff --git a/module/bug/config/form.php b/module/bug/config/form.php index 4ededc48e6..1432aca3ba 100644 --- a/module/bug/config/form.php +++ b/module/bug/config/form.php @@ -41,40 +41,41 @@ $config->bug->form->create['issueKey'] = array('required' => false, 'type' => 's $config->bug->form->create['uid'] = array('required' => false, 'type' => 'string', 'default' => ''); $config->bug->form->edit = array(); -$config->bug->form->edit['title'] = array('required' => true, 'type' => 'string', 'filter' => 'trim'); -$config->bug->form->edit['openedBuild'] = array('required' => true, 'type' => 'array', 'filter' => 'join'); -$config->bug->form->edit['product'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['branch'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['project'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['execution'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['plan'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['module'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['story'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['task'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['case'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['testtask'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['duplicateBug'] = array('required' => false, 'type' => 'int', 'default' => 0); -$config->bug->form->edit['severity'] = array('required' => false, 'type' => 'int', 'default' => 3); -$config->bug->form->edit['pri'] = array('required' => false, 'type' => 'int', 'default' => 3); -$config->bug->form->edit['type'] = array('required' => false, 'type' => 'string', 'default' => ''); -$config->bug->form->edit['status'] = array('required' => false, 'type' => 'string', 'default' => 'active'); -$config->bug->form->edit['keywords'] = array('required' => false, 'type' => 'string', 'default' => ''); -$config->bug->form->edit['steps'] = array('required' => false, 'type' => 'string', 'default' => $lang->bug->tplStep . $lang->bug->tplResult . $lang->bug->tplExpect); -$config->bug->form->edit['resolution'] = array('required' => false, 'type' => 'string', 'default' => ''); -$config->bug->form->edit['resolvedBuild'] = array('required' => false, 'type' => 'string', 'default' => ''); -$config->bug->form->edit['assignedTo'] = array('required' => false, 'type' => 'string', 'default' => ''); -$config->bug->form->edit['feedbackBy'] = array('required' => false, 'type' => 'string', 'default' => ''); -$config->bug->form->edit['resolvedBy'] = array('required' => false, 'type' => 'string', 'default' => ''); -$config->bug->form->edit['closedBy'] = array('required' => false, 'type' => 'string', 'default' => ''); -$config->bug->form->edit['notifyEmail'] = array('required' => false, 'type' => 'string', 'default' => ''); -$config->bug->form->edit['uid'] = array('required' => false, 'type' => 'string', 'default' => ''); -$config->bug->form->edit['os'] = array('required' => false, 'type' => 'array', 'default' => array(''), 'filter' => 'join'); -$config->bug->form->edit['browser'] = array('required' => false, 'type' => 'array', 'default' => array(''), 'filter' => 'join'); -$config->bug->form->edit['linkBug'] = array('required' => false, 'type' => 'array', 'default' => array(''), 'filter' => 'join'); -$config->bug->form->edit['mailto'] = array('required' => false, 'type' => 'array', 'default' => array(''), 'filter' => 'join'); -$config->bug->form->edit['deadline'] = array('required' => false, 'type' => 'date', 'default' => NULL); -$config->bug->form->edit['resolvedDate'] = array('required' => false, 'type' => 'date', 'default' => NULL); -$config->bug->form->edit['closedDate'] = array('required' => false, 'type' => 'date', 'default' => NULL); +$config->bug->form->edit['title'] = array('required' => true, 'type' => 'string', 'filter' => 'trim'); +$config->bug->form->edit['openedBuild'] = array('required' => true, 'type' => 'array', 'filter' => 'join'); +$config->bug->form->edit['product'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['branch'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['project'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['execution'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['plan'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['module'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['story'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['task'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['case'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['testtask'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['duplicateBug'] = array('required' => false, 'type' => 'int', 'default' => 0); +$config->bug->form->edit['severity'] = array('required' => false, 'type' => 'int', 'default' => 3); +$config->bug->form->edit['pri'] = array('required' => false, 'type' => 'int', 'default' => 3); +$config->bug->form->edit['type'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->bug->form->edit['status'] = array('required' => false, 'type' => 'string', 'default' => 'active'); +$config->bug->form->edit['keywords'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->bug->form->edit['steps'] = array('required' => false, 'type' => 'string', 'default' => $lang->bug->tplStep . $lang->bug->tplResult . $lang->bug->tplExpect); +$config->bug->form->edit['resolution'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->bug->form->edit['resolvedBuild'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->bug->form->edit['assignedTo'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->bug->form->edit['feedbackBy'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->bug->form->edit['resolvedBy'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->bug->form->edit['closedBy'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->bug->form->edit['notifyEmail'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->bug->form->edit['uid'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->bug->form->edit['os'] = array('required' => false, 'type' => 'array', 'default' => array(''), 'filter' => 'join'); +$config->bug->form->edit['browser'] = array('required' => false, 'type' => 'array', 'default' => array(''), 'filter' => 'join'); +$config->bug->form->edit['linkBug'] = array('required' => false, 'type' => 'array', 'default' => array(''), 'filter' => 'join'); +$config->bug->form->edit['mailto'] = array('required' => false, 'type' => 'array', 'default' => array(''), 'filter' => 'join'); +$config->bug->form->edit['deadline'] = array('required' => false, 'type' => 'date', 'default' => NULL); +$config->bug->form->edit['resolvedDate'] = array('required' => false, 'type' => 'date', 'default' => NULL); +$config->bug->form->edit['closedDate'] = array('required' => false, 'type' => 'date', 'default' => NULL); +$config->bug->form->edit['lastEditedDate'] = array('required' => false, 'type' => 'date', 'default' => helper::now()); global $app; $config->bug->form->close = array(); @@ -85,4 +86,4 @@ $config->bug->form->close['lastEditedBy'] = array('required' => false, 'type' $config->bug->form->close['lastEditedDate'] = array('required' => false, 'type' => 'string', 'default' => helper::now()); $config->bug->form->close['closedBy'] = array('required' => false, 'type' => 'string', 'default' => $app->user->account); $config->bug->form->close['closedDate'] = array('required' => false, 'type' => 'string', 'default' => helper::now()); -$config->bug->form->close['comment'] = array('required' => false, 'type' => 'string', 'default' => '');; +$config->bug->form->close['comment'] = array('required' => false, 'type' => 'string', 'default' => ''); diff --git a/module/bug/control.php b/module/bug/control.php index f504fa5be2..28e17b20b4 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -660,7 +660,7 @@ class bug extends control * 更新bug信息。 * Edit a bug. * - * @param int $bugID + * @param string $bugID * @param bool $comment true|false * @param string $kanbanGroup * @access public @@ -670,28 +670,27 @@ class bug extends control { if(!empty($_POST)) { - $formData = form::data($this->config->bug->editform); - $bug = $this->bugZen->beforeUpdate($formData); + $oldBug = $this->bug->getByID($bugID); + + $formData = form::data($this->config->bug->form->edit); + $bug = $this->bugZen->prepareEditExtras($formData, $oldBug); + if(!$bug) return $this->send($this->bugZen->errorEdit()); $changes = array(); if(!$comment) { - $changes = $this->bug->update($bugID); - - if(dao::isError()) - { - if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'error', 'message' => dao::getError())); - - return print(js::error(dao::getError())); - } + $changes = $this->bug->update($bug, $oldBug); + if(!$changes) return $this->send($this->bugZen->errorEdit()); } - $result = $this->bugZen->afterUpdate($bugID, $changes); + $this->bugZen->processAfterEdit($bugID, $this->post->comment, $changes); - if(is_array($result)) return $result; + $this->executeHooks($bugID); + + return $this->send($this->bugZen->responseAfterEdit($bugID, $changes, $kanbanGroup)); } - $bug = $this->bug->getById($bugID); + $bug = $this->bug->getByID($bugID); $this->bug->checkBugExecutionPriv($bug); diff --git a/module/bug/model.php b/module/bug/model.php index b10ecc54ec..975cf0e1a8 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -174,7 +174,7 @@ class bugModel extends model foreach($extendFields as $extendField) { $bug->{$extendField->field} = $this->post->{$extendField->field}[$i]; - if(is_array($bug->{$extendField->field})) $bug->{$extendField->field} = join(',', $bug->{$extendField->field}); + if(is_array($bug->{$extendField->field})) $bug->{$extendField->field} = implode(',', $bug->{$extendField->field}); $bug->{$extendField->field} = htmlSpecialString($bug->{$extendField->field}); } @@ -397,7 +397,7 @@ class bugModel extends model * @access public * @return object|false */ - public function getByID(int $bugID, bool $setImgSize = false): object|false + public function getByID(string $bugID, bool $setImgSize = false): object|false { $bug = $this->bugTao->fetchBugInfo($bugID); if(!$bug) return false; @@ -532,121 +532,33 @@ class bugModel extends model } /** + * 更新bug信息。 * Update a bug. * - * @param int $bugID + * @param object $bug + * @param object $oldBug * @access public - * @return void + * @return array|false */ - public function update($bugID) + public function update(object $bug, object $oldBug): array|false { - $oldBug = $this->getById($bugID); - if(!empty($_POST['lastEditedDate']) and $oldBug->lastEditedDate != $this->post->lastEditedDate) - { - dao::$errors[] = $this->lang->error->editedByOther; - return false; - } - $now = helper::now(); - $bug = fixer::input('post') - ->add('id', $bugID) - ->cleanInt('product,module,severity,project,execution,story,task,branch') - ->stripTags($this->config->bug->editor->edit['id'], $this->config->allowedTags) - ->setDefault('module,execution,story,task,duplicateBug,branch', 0) - ->setDefault('product', $oldBug->product) - ->setDefault('openedBuild', '') - ->setDefault('os', '') - ->setDefault('browser', '') - ->setDefault('plan', 0) - ->setDefault('deadline', '0000-00-00') - ->setDefault('resolvedDate', '') - ->setDefault('lastEditedBy', $this->app->user->account) - ->setDefault('mailto', '') - ->setDefault('deleteFiles', array()) - ->add('lastEditedDate', $now) - ->setIF(strpos($this->config->bug->edit->requiredFields, 'deadline') !== false, 'deadline', $this->post->deadline) - ->join('openedBuild', ',') - ->join('mailto', ',') - ->join('linkBug', ',') - ->join('os', ',') - ->join('browser', ',') - ->setIF($this->post->assignedTo != $oldBug->assignedTo, 'assignedDate', $now) - ->setIF($this->post->resolvedBy != '' and $this->post->resolvedDate == '', 'resolvedDate', $now) - ->setIF($this->post->resolution != '' and $this->post->resolvedDate == '', 'resolvedDate', $now) - ->setIF($this->post->resolution != '' and $this->post->resolvedBy == '', 'resolvedBy', $this->app->user->account) - ->setIF($this->post->closedBy != '' and $this->post->closedDate == '', 'closedDate', $now) - ->setIF($this->post->closedDate != '' and $this->post->closedBy == '', 'closedBy', $this->app->user->account) - ->setIF($this->post->closedBy != '' or $this->post->closedDate != '', 'assignedTo', 'closed') - ->setIF($this->post->closedBy != '' or $this->post->closedDate != '', 'assignedDate', $now) - ->setIF($this->post->resolution != '' or $this->post->resolvedDate != '', 'status', 'resolved') - ->setIF($this->post->closedBy != '' or $this->post->closedDate != '', 'status', 'closed') - ->setIF(($this->post->resolution != '' or $this->post->resolvedDate != '') and $this->post->assignedTo == '', 'assignedTo', $oldBug->openedBy) - ->setIF(($this->post->resolution != '' or $this->post->resolvedDate != '') and $this->post->assignedTo == '', 'assignedDate', $now) - ->setIF($this->post->assignedTo == '' and $oldBug->status == 'closed', 'assignedTo', 'closed') - ->setIF($this->post->resolution == '' and $this->post->resolvedDate =='', 'status', 'active') - ->setIF($this->post->resolution != '', 'confirmed', 1) - ->setIF($this->post->resolution != '' and $this->post->resolution != 'duplicate', 'duplicateBug', 0) - ->setIF($this->post->story != false and $this->post->story != $oldBug->story, 'storyVersion', $this->loadModel('story')->getVersion($this->post->story)) - ->setIF(!$this->post->linkBug, 'linkBug', '') - ->setIF($this->post->case === '', 'case', 0) - ->remove('comment,files,labels,uid,contactListMenu') - ->get(); - - $bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->edit['id'], $this->post->uid); $this->dao->update(TABLE_BUG)->data($bug, 'deleteFiles') ->autoCheck() ->batchCheck($this->config->bug->edit->requiredFields, 'notempty') ->checkIF($bug->resolvedBy, 'resolution', 'notempty') ->checkIF($bug->closedBy, 'resolution', 'notempty') - ->checkIF($bug->notifyEmail, 'notifyEmail', 'email') + ->checkIF($bug->notifyEmail,'notifyEmail', 'email') ->checkIF($bug->resolution == 'duplicate', 'duplicateBug', 'notempty') ->checkIF($bug->resolution == 'fixed', 'resolvedBuild','notempty') ->checkFlow() - ->where('id')->eq((int)$bugID) + ->where('id')->eq($bug->id) ->exec(); - if(!dao::isError()) - { - /* Link bug to build and release. */ - if($bug->resolution == 'fixed' and !empty($bug->resolvedBuild) and $oldBug->resolvedBuild != $bug->resolvedBuild) - { - if(!empty($oldBug->resolvedBuild)) $this->loadModel('build')->unlinkBug($oldBug->resolvedBuild, (int)$bugID); - $this->linkBugToBuild($bugID, $bug->resolvedBuild); - } + if(dao::isError()) return false; - if($bug->plan != $oldBug->plan) - { - $this->loadModel('action'); - if(!empty($oldBug->plan)) $this->action->create('productplan', $oldBug->plan, 'unlinkbug', '', $bugID); - if(!empty($bug->plan)) $this->action->create('productplan', $bug->plan, 'linkbug', '', $bugID); - } + if(!$this->bugTao->afterUpdate($bug, $oldBug)) return false; - $linkBugs = explode(',', $bug->linkBug); - $oldLinkBugs = explode(',', $oldBug->linkBug); - $addBugs = array_diff($linkBugs, $oldLinkBugs); - $removeBugs = array_diff($oldLinkBugs, $linkBugs); - $changeBugs = array_merge($addBugs, $removeBugs); - $changeBugs = $this->dao->select('id,linkbug')->from(TABLE_BUG)->where('id')->in(array_filter($changeBugs))->fetchPairs(); - foreach($changeBugs as $changeBugID => $changeBug) - { - if(in_array($changeBugID, $addBugs) and empty($changeBug)) $this->dao->update(TABLE_BUG)->set('linkBug')->eq($bugID)->where('id')->eq((int)$changeBugID)->exec(); - if(in_array($changeBugID, $addBugs) and !empty($changeBug)) $this->dao->update(TABLE_BUG)->set('linkBug')->eq("$changeBug,$bugID")->where('id')->eq((int)$changeBugID)->exec(); - if(in_array($changeBugID, $removeBugs)) - { - $linkBugs = explode(',', $changeBug); - unset($linkBugs[array_search($bugID, $linkBugs)]); - $this->dao->update(TABLE_BUG)->set('linkBug')->eq(implode(',', $linkBugs))->where('id')->eq((int)$changeBugID)->exec(); - } - } - - if(!empty($bug->resolvedBy)) $this->loadModel('score')->create('bug', 'resolve', $bugID); - - if($bug->execution and $bug->status != $oldBug->status) $this->loadModel('kanban')->updateLane($bug->execution, 'bug'); - - if(($this->config->edition == 'biz' || $this->config->edition == 'max') && $oldBug->feedback) $this->loadModel('feedback')->updateStatus('bug', $oldBug->feedback, $bug->status, $oldBug->status); - - $this->file->processFile4Object('bug', $oldBug, $bug); - return common::createChanges($oldBug, $bug); - } + return common::createChanges($oldBug, $bug); } /** @@ -739,7 +651,7 @@ class bugModel extends model foreach($extendFields as $extendField) { $bug->{$extendField->field} = $this->post->{$extendField->field}[$bugID]; - if(is_array($bug->{$extendField->field})) $bug->{$extendField->field} = join(',', $bug->{$extendField->field}); + if(is_array($bug->{$extendField->field})) $bug->{$extendField->field} = implode(',', $bug->{$extendField->field}); $bug->{$extendField->field} = htmlSpecialString($bug->{$extendField->field}); } @@ -846,7 +758,7 @@ class bugModel extends model { $postFieldData = $this->post->{$extendField->field}; - if(is_array($postFieldData[$bugID])) $postFieldData[$bugID] = join(',', $postFieldData[$bugID]); + if(is_array($postFieldData[$bugID])) $postFieldData[$bugID] = implode(',', $postFieldData[$bugID]); $activateBugs[$bugID][$extendField->field] = htmlSpecialString($postFieldData[$bugID]); } @@ -1524,7 +1436,7 @@ class bugModel extends model $builds = $this->loadModel('build')->getBuildPairs(array_unique($productIdList), 'all', $params = ''); /* Process the openedBuild and resolvedBuild fields. */ - foreach($bugs as $key => $bug) + foreach($bugs as $bug) { $openBuildIdList = explode(',', $bug->openedBuild); $openedBuild = ''; @@ -1618,7 +1530,7 @@ class bugModel extends model } else { - if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1'); + if($this->session->$queryName === false) $this->session->set($queryName, ' 1 = 1'); } $query = $this->session->$queryName; $query = preg_replace('/`(\w+)`/', 't1.`$1`', $query); @@ -1711,7 +1623,7 @@ class bugModel extends model if($type == 'bysearch') { $queryID = (int)$param; - if($this->session->projectBugQuery == false) $this->session->set('projectBugQuery', ' 1 = 1'); + if($this->session->projectBugQuery === false) $this->session->set('projectBugQuery', ' 1 = 1'); if($queryID) { $query = $this->loadModel('search')->getQuery($queryID); @@ -1782,7 +1694,7 @@ class bugModel extends model if($type == 'bysearch') { $queryID = (int)$param; - if($this->session->executionBugQuery == false) $this->session->set('executionBugQuery', ' 1 = 1'); + if($this->session->executionBugQuery === false) $this->session->set('executionBugQuery', ' 1 = 1'); if($queryID) { $query = $this->loadModel('search')->getQuery($queryID); @@ -1818,7 +1730,7 @@ class bugModel extends model { if($build) $conditions[] = "FIND_IN_SET('$build', t1.openedBuild)"; } - $condition = join(' OR ', $conditions); + $condition = implode(' OR ', $conditions); $condition = "($condition)"; } $bugs = $this->dao->select("t1.*, 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') @@ -1876,7 +1788,7 @@ class bugModel extends model ->andWhere('t1.date')->lt($minBegin) ->fetchPairs('id', 'id'); - $bugs = $this->dao->select('*')->from(TABLE_BUG)->where('deleted')->eq(0) + return $this->dao->select('*')->from(TABLE_BUG)->where('deleted')->eq(0) ->andWhere('product')->eq($productID) ->andWhere('toStory')->eq(0) ->andWhere('openedDate')->ge($minBegin) @@ -1887,8 +1799,6 @@ class bugModel extends model ->beginIF($branch !== '')->andWhere('branch')->in("0,$branch")->fi() ->page($pager) ->fetchAll(); - - return $bugs; } /** @@ -1976,7 +1886,7 @@ class bugModel extends model $condition .= " OR (`execution` = '{$execution->id}' AND openedDate < '{$execution->begin}')"; } - $bugs = $this->dao->select('*')->from(TABLE_BUG) + return $this->dao->select('*')->from(TABLE_BUG) ->where('resolvedDate')->ge($minBegin) ->andWhere('resolution')->ne('postponed') ->andWhere('product')->eq($productID) @@ -1987,7 +1897,6 @@ class bugModel extends model ->orderBy('openedDate ASC') ->page($pager) ->fetchAll('id'); - return $bugs; } /** @@ -2394,7 +2303,7 @@ class bugModel extends model { $datas = $this->dao->select('pri AS name, COUNT(*) AS value')->from(TABLE_BUG)->where($this->reportCondition())->groupBy('name')->orderBy('value DESC')->fetchAll('name'); if(!$datas) return array(); - foreach($datas as $status => $data) $data->name = $this->lang->bug->report->bugsPerPri->graph->xAxisName . ':' . zget($this->lang->bug->priList, $data->name); + foreach($datas as $data) $data->name = $this->lang->bug->report->bugsPerPri->graph->xAxisName . ':' . zget($this->lang->bug->priList, $data->name); return $datas; } @@ -2528,7 +2437,7 @@ class bugModel extends model } else { - if($this->session->bugQuery == false) $this->session->set('bugQuery', ' 1 = 1'); + if($this->session->bugQuery === false) $this->session->set('bugQuery', ' 1 = 1'); } $bugQuery = $this->getBugQuery($this->session->bugQuery); @@ -2557,7 +2466,7 @@ class bugModel extends model if($branch !== 'all' and strpos($bugQuery, '`branch` =') === false) $bugQuery .= " AND `branch` in('0','$branch')"; if(strpos($bugQuery, $allBranch) !== false) $bugQuery = str_replace($allBranch, '1', $bugQuery); - $bugs = $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)->where($bugQuery) + return $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)->where($bugQuery) ->beginIF(!$this->app->user->admin)->andWhere('execution')->in('0,' . $this->app->user->view->sprints)->fi() ->beginIF($excludeBugs)->andWhere('id')->notIN($excludeBugs)->fi() @@ -2570,8 +2479,8 @@ class bugModel extends model ->andWhere('deleted')->eq(0) ->beginIF(!$this->app->user->admin)->andWhere('project')->in('0,' . $this->app->user->view->projects)->fi() - ->orderBy($orderBy)->page($pager)->fetchAll(); - return $bugs; + ->orderBy($orderBy)->page($pager) + ->fetchAll(); } /** @@ -2749,13 +2658,13 @@ class bugModel extends model public function linkBugToBuild($bugs, $resolvedBuild) { if(empty($resolvedBuild) or $resolvedBuild == 'trunk') return true; - if(is_array($bugs)) $bugs = join(',', $bugs); + if(is_array($bugs)) $bugs = implode(',', $bugs); $build = $this->dao->select('id,product,bugs')->from(TABLE_BUILD)->where('id')->eq($resolvedBuild)->fetch(); $buildBugs = $build->bugs . ',' . $bugs; $buildBugs = explode(',', trim($buildBugs, ',')); $buildBugs = array_unique($buildBugs); - $this->dao->update(TABLE_BUILD)->set('bugs')->eq(join(',', $buildBugs))->where('id')->eq($resolvedBuild)->exec(); + $this->dao->update(TABLE_BUILD)->set('bugs')->eq(implode(',', $buildBugs))->where('id')->eq($resolvedBuild)->exec(); $release = $this->dao->select('id,bugs')->from(TABLE_RELEASE)->where('product')->eq($build->product)->andWhere("(FIND_IN_SET('$resolvedBuild', build) or shadow = $resolvedBuild)")->andWhere('deleted')->eq('0')->fetch(); if($release) @@ -2763,7 +2672,7 @@ class bugModel extends model $releaseBugs = $release->bugs . ',' . $bugs; $releaseBugs = explode(',', trim($releaseBugs, ',')); $releaseBugs = array_unique($releaseBugs); - $this->dao->update(TABLE_RELEASE)->set('bugs')->eq(join(',', $releaseBugs))->where('id')->eq($release->id)->exec(); + $this->dao->update(TABLE_RELEASE)->set('bugs')->eq(implode(',', $releaseBugs))->where('id')->eq($release->id)->exec(); } return true; diff --git a/module/bug/tao.php b/module/bug/tao.php index 722ae958e2..4cccf81dc0 100644 --- a/module/bug/tao.php +++ b/module/bug/tao.php @@ -10,7 +10,7 @@ class bugTao extends bugModel * @access protected * @return object|false */ - protected function fetchBugInfo(int $bugID): object|false + protected function fetchBugInfo(string $bugID): object|false { 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') ->from(TABLE_BUG)->alias('t1') @@ -136,7 +136,7 @@ class bugTao extends bugModel * @access protected * @return array */ - protected function getCasesFromBug(int $bugID): array + protected function getCasesFromBug(string $bugID): array { return $this->dao->select('id, title')->from(TABLE_CASE)->where('`fromBug`')->eq($bugID)->fetchPairs(); } @@ -169,6 +169,97 @@ class bugTao extends bugModel return $this->dao->findById($objectID)->from($table)->fields($field)->fetch($field); } + /** + * 更新完bug后的相关处理。 + * Relevant processing after updating bug. + * + * @param object $bug + * @param object $oldBug + * @access protected + * @return void + */ + protected function afterUpdate(object $bug, object $oldBug) + { + /* 解除旧的版本关联关系,关联新的版本。*/ + /* Link bug to build and release. */ + if($bug->resolution == 'fixed' && !empty($bug->resolvedBuild) && $bug->resolvedBuild != $oldBug->resolvedBuild) + { + if(!empty($oldBug->resolvedBuild)) $this->loadModel('build')->unlinkBug($oldBug->resolvedBuild, $bug->id); + $this->linkBugToBuild($bug->id, $bug->resolvedBuild); + } + + /* 解除旧的计划关联关系,关联新的计划。*/ + /* Link new plan, unlink old plan. */ + if($bug->plan != $oldBug->plan) + { + $this->loadModel('action'); + if(!empty($oldBug->plan)) $this->action->create('productplan', $oldBug->plan, 'unlinkbug', '', $bug->id); + if(!empty($bug->plan)) $this->action->create('productplan', $bug->plan, 'linkbug', '', $bug->id); + } + + $this->updateLinkBug($bug->id, $bug->linkBug, $oldBug->linkBug); + + /* 给bug解决者积分奖励。*/ + /* Add score to resolvedby. */ + if(!empty($bug->resolvedBy)) $this->loadModel('score')->create('bug', 'resolve', $bug->id); + + /* 更新bug所属看板的泳道。*/ + /* Update the lane of the bug kanban. */ + if($bug->execution and $bug->status != $oldBug->status) $this->loadModel('kanban')->updateLane($bug->execution, 'bug'); + + /* 更新反馈的状态。*/ + /* Update the status of feedback. */ + if(($this->config->edition != 'open') && $oldBug->feedback) $this->loadModel('feedback')->updateStatus('bug', $oldBug->feedback, $bug->status, $oldBug->status); + + /* 更新bug的附件。*/ + /* Update the files of bug. */ + $this->loadModel('file')->processFile4Object('bug', $oldBug, $bug); + + return !dao::isError(); + } + + /** + * 更新相关bug。 + * Update the linked bug. + * + * @param int $bugID + * @param string $linkBug + * @param string $oldLinkBug + * @access private + * @return bool + */ + private function updateLinkBug(int $bugID, string $linkBug, string $oldLinkBug): bool + { + + return false; + + $linkBugs = explode(',', $linkBug); + $oldLinkBugs = explode(',', $oldLinkBug); + $addedLinkBugs = array_diff($linkBugs, $oldLinkBugs); + $removedLinkBugs = array_diff($oldLinkBugs, $linkBugs); + $changedLinkBugs = array_merge($addedLinkBugs, $removedLinkBugs); + $changedLinkBugs = $this->dao->select('id, linkbug')->from(TABLE_BUG)->where('id')->in(array_filter($changedLinkBugs))->fetchPairs(); + + foreach($changedLinkBugs as $changedBugID => $linkBugs) + { + if(in_array($changeBugID, $addedLinkBugs)) + { + $currentLinkBug = $bugID; + if(!empty($linkBugs)) $currentLinkBug = trim($linkBugs, ',') . ',' . $bugID; + } + else + { + $linkBugs = explode(',', $linkBugs); + unset($linkBugs[array_search($bugID, $linkBugs)]); + $currentLinkBug = implode(',', $linkBugs); + } + + $this->dao->update(TABLE_BUG)->set('linkBug')->eq($linkBug)->where('id')->eq($changeBugID)->exec(); + } + + return !dao::isError(); + } + /** * Call checkDelayBug in foreach to check if the bug is delay. * 循环调用checkDelayBug,检查bug是否延期 diff --git a/module/bug/test/bug.class.php b/module/bug/test/bug.class.php index 0be72507e8..4406979f52 100644 --- a/module/bug/test/bug.class.php +++ b/module/bug/test/bug.class.php @@ -795,10 +795,12 @@ class bugTest $_POST[$field] = $value; } } - $_POST['closedDate'] = ''; + //$_POST['closedDate'] = ''; + $_POST['deleteFiles'] = array(); + $object->files = array(); - $change = $this->objectModel->update($bugID); + $change = $this->objectModel->update((object)$_POST, $object); if($change == array()) $change = '没有数据更新'; unset($_POST); diff --git a/module/bug/test/model/getbyid.php b/module/bug/test/model/getbyid.php index a075854e94..940f221d48 100755 --- a/module/bug/test/model/getbyid.php +++ b/module/bug/test/model/getbyid.php @@ -45,7 +45,7 @@ $tester->loadModel('bug'); initData(); -r($tester->bug->getByID(2)) && p('pri,type') && e('1,codeerror'); //获取ID等于2的bug -r($tester->bug->getByID(3)) && p('title,status') && e('bug3,active'); //获取ID等于3的bug -r($tester->bug->getByID(4)) && p('severity,openedBuild') && e('3,trunk'); //获取ID等于4的bug -r($tester->bug->getByID(1)) && p('title') && e('0'); //获取不存在的bug +r($tester->bug->getByID(2)) && p('pri,type') && e('1,codeerror'); //获取ID等于2的bug +r($tester->bug->getByID(3)) && p('title,status') && e('bug3,active'); //获取ID等于3的bug +r($tester->bug->getByID(4)) && p('severity,openedBuild') && e('3,trunk'); //获取ID等于4的bug +r($tester->bug->getByID(1)) && p('title') && e('0'); //获取不存在的bug diff --git a/module/bug/test/model/update.php b/module/bug/test/model/update.php index 7ea4360a69..eb684be340 100755 --- a/module/bug/test/model/update.php +++ b/module/bug/test/model/update.php @@ -1,33 +1,62 @@ #!/usr/bin/env php id->range('1-5'); + $data->product->range('1-5'); + $data->branch->range('0-1'); + $data->project->range('0-5'); + $data->execution->range('0-5'); + $data->title->prefix("BUG")->range('1-5'); + $data->openedBuild->range('1-5'); + $data->type->range("[codeerror]"); + $data->status->range("[active]"); + $data->pri->range("[3]"); + $data->severity->range("[3]"); + + $data->gen(4); +} /** title=bugModel->update(); +timeout=0 cid=1 -pid=1 -测试更新bug名称 >> title,BUG1,john -测试更新bug类型 >> type,codeerror,config -测试更新bug名称和类型 >> title,john,jack;type,config,install -测试不更改bug名称 >> 没有数据更新 -测试不更改bug类型 >> 没有数据更新 +- 执行bug模块的updateObject方法,参数是$bugIdList[0], $t_uptitle + - 第0条的field属性 @title + - 第0条的old属性 @BUG1 + - 第0条的new属性 @john + +- 执行bug模块的updateObject方法,参数是$bugIdList[0], $t_uptype + - 第0条的field属性 @type + - 第0条的old属性 @codeerror + - 第0条的new属性 @config + +- 执行bug模块的updateObject方法,参数是$bugIdList[0], $t_untitle @没有数据更新 + +- 执行bug模块的updateObject方法,参数是$bugIdList[0], $t_untype @没有数据更新 + + */ -$projectIdList = array('1', '2'); +initData(); -$t_uptitle = array('title' => 'john'); -$t_uptype = array('type' => 'config'); -$t_typetitle = array('title' => 'jack', 'type' => 'install'); -$t_untitle = array('title' => 'jack'); -$t_untype = array('type' => 'install'); +$bugIdList = array('1', '2'); -$bug=new bugTest(); -r($bug->updateObject($projectIdList[0], $t_uptitle)) && p('0:field,old,new') && e('title,BUG1,john'); // 测试更新bug名称 -r($bug->updateObject($projectIdList[0], $t_uptype)) && p('0:field,old,new') && e('type,codeerror,config'); // 测试更新bug类型 -r($bug->updateObject($projectIdList[0], $t_typetitle)) && p('0:field,old,new;1:field,old,new') && e('title,john,jack;type,config,install'); // 测试更新bug名称和类型 -r($bug->updateObject($projectIdList[0], $t_untitle)) && p() && e('没有数据更新'); // 测试不更改bug名称 -r($bug->updateObject($projectIdList[0], $t_untype)) && p() && e('没有数据更新'); // 测试不更改bug类型 +$t_uptitle = array('title' => 'john'); +$t_uptype = array('type' => 'config'); +$t_untitle = array('title' => 'john'); +$t_untype = array('type' => 'config'); + +global $tester; +$tester->loadModel('bug'); +r($tester->bug->updateObject($bugIdList[0], $t_uptitle)) && p('0:field,old,new') && e('title,BUG1,john'); // 测试更新bug名称 +r($tester->bug->updateObject($bugIdList[0], $t_uptype)) && p('0:field,old,new') && e('type,codeerror,config'); // 测试更新bug类型 +r($tester->bug->updateObject($bugIdList[0], $t_untitle)) && p() && e('没有数据更新'); // 测试不更改bug名称 +r($tester->bug->updateObject($bugIdList[0], $t_untype)) && p() && e('没有数据更新'); // 测试不更改bug类型 diff --git a/module/bug/view/edit.html.php b/module/bug/view/edit.html.php index 4710a0e183..dcc5c70f39 100644 --- a/module/bug/view/edit.html.php +++ b/module/bug/view/edit.html.php @@ -37,7 +37,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project); ?>