diff --git a/module/bug/model.php b/module/bug/model.php index 40f7672c95..5adc9e0c4a 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -1888,19 +1888,19 @@ class bugModel extends model /** * Get bugs of a execution. * - * @param int $executionID - * @param int $productID - * @param int $branchID - * @param int $build - * @param string $type - * @param int $param - * @param string $orderBy - * @param string $excludeBugs - * @param object $pager + * @param int $executionID + * @param int $productID + * @param int $branchID + * @param string|array $builds + * @param string $type + * @param int $param + * @param string $orderBy + * @param string $excludeBugs + * @param object $pager * @access public * @return array */ - public function getExecutionBugs($executionID, $productID = 0, $branchID = 'all', $build = 0, $type = '', $param = 0, $orderBy = 'id_desc', $excludeBugs = '', $pager = null) + public function getExecutionBugs($executionID, $productID = 0, $branchID = 'all', $builds = 0, $type = '', $param = 0, $orderBy = 'id_desc', $excludeBugs = '', $pager = null) { $type = strtolower($type); if(strpos($orderBy, 'pri_') !== false) $orderBy = str_replace('pri_', 'priOrder_', $orderBy); @@ -1935,15 +1935,28 @@ class bugModel extends model } else { + $condition = ''; + if($builds) + { + if(!is_array($builds)) $builds = explode(',', $builds); + + $conditions = array(); + foreach($builds as $build) + { + if($build) $conditions[] = "FIND_IN_SET('$build', t1.openedBuild)"; + } + $condition = join(' 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') ->leftJoin(TABLE_MODULE)->alias('t2')->on('t1.module=t2.id') ->where('t1.deleted')->eq(0) ->beginIF(!empty($productID) and $branchID !== 'all')->andWhere('t1.branch')->eq($branchID)->fi() - ->beginIF(empty($build))->andWhere('t1.execution')->eq($executionID)->fi() + ->beginIF(empty($builds))->andWhere('t1.execution')->eq($executionID)->fi() ->beginIF(!empty($productID))->andWhere('t1.product')->eq($productID)->fi() ->beginIF($type == 'unresolved')->andWhere('t1.status')->eq('active')->fi() ->beginIF($type == 'noclosed')->andWhere('t1.status')->ne('closed')->fi() - ->beginIF($build)->andWhere("CONCAT(',', t1.openedBuild, ',') like '%,$build,%'")->fi() + ->beginIF($condition)->andWhere("$condition")->fi() ->beginIF(!empty($param))->andWhere('t2.path')->like("%,$param,%")->andWhere('t2.deleted')->eq(0)->fi() ->beginIF($excludeBugs)->andWhere('t1.id')->notIN($excludeBugs)->fi() ->orderBy($orderBy) diff --git a/module/build/control.php b/module/build/control.php index 563238aeb8..91353e2f9d 100644 --- a/module/build/control.php +++ b/module/build/control.php @@ -292,7 +292,7 @@ class build extends control $this->view->storyPager = $storyPager; $generatedBugPager = new pager($type == 'generatedBug' ? $recTotal : 0, $recPerPage, $type == 'generatedBug' ? $pageID : 1); - $this->view->generatedBugs = $this->bug->getExecutionBugs($build->execution, $build->product, 'all', $build->id, $type, $param, $type == 'generatedBug' ? $sort : 'status_desc,id_desc', '', $generatedBugPager); + $this->view->generatedBugs = $this->bug->getExecutionBugs($build->execution, $build->product, 'all', "$build->id,{$build->builds}", $type, $param, $type == 'generatedBug' ? $sort : 'status_desc,id_desc', '', $generatedBugPager); $this->view->generatedBugPager = $generatedBugPager; $this->executeHooks($buildID); diff --git a/module/build/lang/de.php b/module/build/lang/de.php index 102f2a399f..39f5f213c7 100644 --- a/module/build/lang/de.php +++ b/module/build/lang/de.php @@ -57,6 +57,7 @@ $lang->build->notice = new stdclass(); $lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified"; $lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}"; $lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds"; +$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version"; $lang->build->finishStories = " %s {$lang->SRCommon} sind abgeschlossen."; $lang->build->resolvedBugs = ' %s Bugs sind gelöst.'; diff --git a/module/build/lang/en.php b/module/build/lang/en.php index 2cad705a92..df6d81e8d1 100644 --- a/module/build/lang/en.php +++ b/module/build/lang/en.php @@ -57,6 +57,7 @@ $lang->build->notice = new stdclass(); $lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified"; $lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}"; $lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds"; +$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version"; $lang->build->finishStories = " Finished {$lang->SRCommon} %s"; $lang->build->resolvedBugs = ' Resolved Bug %s'; diff --git a/module/build/lang/fr.php b/module/build/lang/fr.php index 5bf136f09b..30ed628f70 100644 --- a/module/build/lang/fr.php +++ b/module/build/lang/fr.php @@ -57,6 +57,7 @@ $lang->build->notice = new stdclass(); $lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified"; $lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}"; $lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds"; +$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version"; $lang->build->finishStories = " {$lang->SRCommon} Terminées %s"; $lang->build->resolvedBugs = ' Bugs Résolus %s'; diff --git a/module/build/lang/vi.php b/module/build/lang/vi.php index c5a6f474d1..830fb9234d 100644 --- a/module/build/lang/vi.php +++ b/module/build/lang/vi.php @@ -53,6 +53,7 @@ $lang->build->notice = new stdclass(); $lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified"; $lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}"; $lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds"; +$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version"; $lang->build->finishStories = " {$lang->SRCommon} đã kết thúc %s"; $lang->build->resolvedBugs = ' Bug đã giải quyết %s'; diff --git a/module/build/lang/zh-cn.php b/module/build/lang/zh-cn.php index b1bbf9d7ca..0be8d8c8b5 100644 --- a/module/build/lang/zh-cn.php +++ b/module/build/lang/zh-cn.php @@ -57,6 +57,7 @@ $lang->build->notice = new stdclass(); $lang->build->notice->changeProduct = "已经关联{$lang->SRCommon}、Bug或提交测试单的版本,不能修改其所属{$lang->productCommon}"; $lang->build->notice->changeExecution = "提交测试单的版本,不能修改其所属{$lang->executionCommon}"; $lang->build->notice->changeBuilds = "提交测试单的版本,不能修改关联版本"; +$lang->build->notice->autoRelation = "相关版本下完成的需求、解决的Bug、产生的Bug将会自动关联到项目版本中"; $lang->build->finishStories = " 本次共完成 %s 个{$lang->SRCommon}"; $lang->build->resolvedBugs = ' 本次共解决 %s 个Bug'; diff --git a/module/build/model.php b/module/build/model.php index 6a49cfb637..0f98597790 100644 --- a/module/build/model.php +++ b/module/build/model.php @@ -347,6 +347,7 @@ class buildModel extends model if(!dao::isError()) { $buildID = $this->dao->lastInsertID(); + $this->linkChildBuilds($buildID, $build->builds); $this->file->updateObjectID($this->post->uid, $buildID, 'build'); $this->file->saveUpload('build', $buildID); $this->loadModel('score')->create('build', 'create', $buildID); @@ -386,6 +387,8 @@ class buildModel extends model if(isset($build->branch) and $oldBuild->branch != $build->branch) $this->dao->update(TABLE_RELEASE)->set('branch')->eq($build->branch)->where('build')->eq($buildID)->exec(); if(!dao::isError()) { + $addBuilds = array_diff(explode(',', $build->builds), explode(',', $oldBuild->builds)); + if($addBuilds) $this->linkChildBuilds($buildID, $addBuilds); $this->file->updateObjectID($this->post->uid, $buildID, 'build'); return common::createChanges($oldBuild, $build); } @@ -561,6 +564,33 @@ class buildModel extends model foreach($this->post->unlinkBugs as $unlinkBugID) $this->action->create('bug', $unlinkBugID, 'unlinkedfrombuild', '', $buildID); } + /** + * Bugs and stories associated with child builds. + * + * @param int $buildID + * @param string $childBuilds + * @access public + * @return void + */ + public function linkChildBuilds($buildID, $childBuilds) + { + $build = $this->dao->select('bugs, stories')->from(TABLE_BUILD)->where('id')->eq($buildID)->fetch(); + $buildList = $this->dao->select('bugs, stories')->from(TABLE_BUILD)->where('id')->in($childBuilds)->fetchAll(); + + foreach($buildList as $buildInfo) + { + if($buildInfo->bugs) $build->bugs .= ",{$buildInfo->bugs}"; + if($buildInfo->stories) $build->stories .= ",{$buildInfo->stories}"; + } + + $build->bugs = explode(',', $build->bugs); + $build->bugs = join(',', array_filter($build->bugs)); + $build->stories = explode(',', $build->stories); + $build->stories = join(',', array_filter($build->stories)); + + $this->dao->update(TABLE_BUILD)->data($build)->where('id')->eq($buildID)->exec(); + } + /** * Build action menu. * diff --git a/module/build/view/create.html.php b/module/build/view/create.html.php index 3297178af4..6a26488df3 100644 --- a/module/build/view/create.html.php +++ b/module/build/view/create.html.php @@ -45,7 +45,8 @@ tab == 'project' && !empty($multipleProject)):?> build->builds;?> - + + build->notice->autoRelation;?> diff --git a/module/build/view/edit.html.php b/module/build/view/edit.html.php index 8fc810e5aa..59e3009c6a 100644 --- a/module/build/view/edit.html.php +++ b/module/build/view/edit.html.php @@ -47,7 +47,13 @@ build->builds;?> builds, "class='form-control chosen' multiple $disabled");?> - build->notice->changeBuilds;?> + + + build->notice->changeBuilds;?> + + build->notice->autoRelation;?> + + build->execution;?> diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php index fc9aae6e29..de9280d5d1 100644 --- a/module/common/lang/menu.php +++ b/module/common/lang/menu.php @@ -791,6 +791,7 @@ if(!helper::hasFeature('devops')) unset($lang->mainNav->devops, $lang->mainNav->menuOrder[35]); unset($lang->scrum->menu->devops, $lang->scrum->menuOrder[25]); unset($lang->waterfall->menu->devops, $lang->waterfall->menuOrder[35]); + unset($lang->execution->menu->devops, $lang->execution->menuOrder[45]); } if(!helper::hasFeature('kanban')) diff --git a/module/execution/view/story.html.php b/module/execution/view/story.html.php index a43f1cba34..4d4d80de04 100644 --- a/module/execution/view/story.html.php +++ b/module/execution/view/story.html.php @@ -221,7 +221,7 @@ moduleName . ucfirst($this->methodName); $useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'); - $vars = "executionID={$execution->id}&orderBy=%s&type=$type¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; + $vars = "executionID={$execution->id}&storyType=$storyType&orderBy=%s&type=$type¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; if($useDatatable) include '../../common/view/datatable.html.php'; if(!$execution->hasProduct and !$execution->multiple) diff --git a/module/projectrelease/control.php b/module/projectrelease/control.php index 64a5d6b9e9..f2d8398c9b 100644 --- a/module/projectrelease/control.php +++ b/module/projectrelease/control.php @@ -693,7 +693,7 @@ class projectrelease extends control $this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values']; $searchModules = array(); - $moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'story', 0, explode(',', $release->branch)); + $moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'bug', 0, explode(',', $release->branch)); foreach($moduleGroups as $modules) $searchModules += $modules; $this->config->bug->search['params']['module']['values'] = $searchModules; diff --git a/module/release/control.php b/module/release/control.php index 6327b37398..c1fc6a7af6 100644 --- a/module/release/control.php +++ b/module/release/control.php @@ -464,7 +464,6 @@ class release extends control $this->session->set('storyList', inlink('view', "releaseID=$releaseID&type=story&link=true¶m=" . helper::safe64Encode("&browseType=$browseType&queryID=$param")), 'product'); $release = $this->release->getById($releaseID); - $build = $this->loadModel('build')->getByID($release->build); $this->commonAction($release->product); $this->loadModel('story'); $this->loadModel('tree'); @@ -475,15 +474,21 @@ class release extends control $pager = new pager($recTotal, $recPerPage, $pageID); /* Build search form. */ - $queryID = ($browseType == 'bySearch') ? (int)$param : 0; unset($this->config->product->search['fields']['product']); unset($this->config->product->search['fields']['project']); + + $queryID = ($browseType == 'bySearch') ? (int)$param : 0; $this->config->product->search['actionURL'] = $this->createLink('release', 'view', "releaseID=$releaseID&type=story&link=true¶m=" . helper::safe64Encode('&browseType=bySearch&queryID=myQueryID')); $this->config->product->search['queryID'] = $queryID; $this->config->product->search['style'] = 'simple'; $this->config->product->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($release->product, $release->branch, 'skipParent|withMainPlan'); $this->config->product->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $this->lang->story->statusList); - $this->config->product->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($release->product, 'story', 0, $release->branch);; + + $searchModules = array(); + $moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'story', 0, explode(',', $release->branch));; + foreach($moduleGroups as $modules) $searchModules += $modules; + $this->config->product->search['params']['module']['values'] = $searchModules; + if($this->session->currentProductType == 'normal') { unset($this->config->product->search['fields']['branch']); @@ -491,20 +496,30 @@ class release extends control } else { - $this->config->product->search['fields']['branch'] = $this->lang->product->branch; - $branchName = $this->loadModel('branch')->getById($release->branch); - $branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main, $release->branch => $branchName); + $allBranchs = $this->loadModel('branch')->getPairs($release->product); + $branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main); + foreach(explode(',', trim($release->branch, ',')) as $branchID) $branches[$branchID] = zget($allBranchs, $branchID); + + $this->config->product->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$release->productType]); $this->config->product->search['params']['branch']['values'] = $branches; } $this->loadModel('search')->setSearchParams($this->config->product->search); - if($browseType == 'bySearch' or $build->execution == 0) + $builds = $this->loadModel('build')->getByList($release->build); + $executionIdList = array(); + foreach($builds as $build) { - $allStories = $this->story->getBySearch($release->product, "0,{$release->branch}", $queryID, 'id', $build->execution ? $build->execution : '', 'story', $release->stories, $pager); + if(empty($build->execution)) continue; + $executionIdList[$build->execution] = $build->execution; + } + + if($browseType == 'bySearch') + { + $allStories = $this->story->getBySearch($release->product, $release->branch, $queryID, 'id', $executionIdList, 'story', $release->stories, $pager); } else { - $allStories = $this->story->getExecutionStories($build->execution, $build->product, 0, 't1.`order`_desc', 'byBranch', $release->branch, 'story', $release->stories, $pager); + $allStories = $this->story->getExecutionStories($executionIdList, $build->product, 0, 't1.`order`_desc', 'byBranch', $release->branch, 'story', $release->stories, $pager); } $this->view->allStories = $allStories; @@ -584,7 +599,6 @@ class release extends control $this->session->set('bugList', inlink('view', "releaseID=$releaseID&type=$type&link=true¶m=" . helper::safe64Encode("&browseType=$browseType&queryID=$param")), 'qa'); /* Set menu. */ $release = $this->release->getByID($releaseID); - $build = $this->loadModel('build')->getByID($release->build); $this->commonAction($release->product); /* Load pager. */ @@ -593,17 +607,24 @@ class release extends control /* Build the search form. */ $this->loadModel('bug'); - $queryID = ($browseType == 'bysearch') ? (int)$param : 0; unset($this->config->bug->search['fields']['product']); unset($this->config->bug->search['fields']['project']); + + $queryID = ($browseType == 'bysearch') ? (int)$param : 0; $this->config->bug->search['actionURL'] = $this->createLink('release', 'view', "releaseID=$releaseID&type=$type&link=true¶m=" . helper::safe64Encode('&browseType=bySearch&queryID=myQueryID')); $this->config->bug->search['queryID'] = $queryID; $this->config->bug->search['style'] = 'simple'; + $this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($release->product, $release->branch, 'skipParent|withMainPlan'); $this->config->bug->search['params']['execution']['values'] = $this->loadModel('product')->getExecutionPairsByProduct($release->product, $release->branch); $this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($release->product, $branch = 'all', $params = ''); $this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values']; - $this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($release->product, 'bug', 0, $release->branch); + + $searchModules = array(); + $moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'bug', 0, explode(',', $release->branch)); + foreach($moduleGroups as $modules) $searchModules += $modules; + $this->config->bug->search['params']['module']['values'] = $searchModules; + if($this->session->currentProductType == 'normal') { unset($this->config->bug->search['fields']['branch']); @@ -611,28 +632,31 @@ class release extends control } else { - $this->config->bug->search['fields']['branch'] = $this->lang->product->branch; - $branchName = $this->loadModel('branch')->getById($release->branch); - $branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main, $release->branch => $branchName); + $allBranchs = $this->loadModel('branch')->getPairs($release->product); + $branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main); + foreach(explode(',', trim($release->branch, ',')) as $branchID) $branches[$branchID] = zget($allBranchs, $branchID); + + $this->config->bug->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$release->productType]); $this->config->bug->search['params']['branch']['values'] = $branches; } $this->loadModel('search')->setSearchParams($this->config->bug->search); + $builds = $this->loadModel('build')->getByList($release->build); $allBugs = array(); $releaseBugs = $type == 'bug' ? $release->bugs : $release->leftBugs; - if($browseType == 'bySearch' or $build->execution == 0) + if($browseType == 'bySearch') { $allBugs = $this->bug->getBySearch($release->product, $release->branch, $queryID, 'id_desc', $releaseBugs, $pager); } - elseif($build->execution) + else { if($type == 'bug') { - $allBugs = $this->bug->getReleaseBugs($build->id, $release->product, $release->branch, $releaseBugs, $pager); + $allBugs = $this->bug->getReleaseBugs(array_keys($builds), $release->product, $release->branch, $releaseBugs, $pager); } elseif($type == 'leftBug') { - $allBugs = $this->bug->getProductLeftBugs($build->id, $release->product, $release->branch, $releaseBugs, $pager); + $allBugs = $this->bug->getProductLeftBugs(array_keys($builds), $release->product, $release->branch, $releaseBugs, $pager); } } diff --git a/module/release/css/browse.css b/module/release/css/browse.css index 8c33b9fd78..dd6d856b51 100644 --- a/module/release/css/browse.css +++ b/module/release/css/browse.css @@ -1,5 +1,6 @@ #releaseList {font-size: 13px;} td {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} +#releaseList tbody>tr:hover{background-color: unset!important;} .main-table tbody>tr>td:first-child{padding: 2px 8px!important;} .c-id {width: 60px} diff --git a/module/release/model.php b/module/release/model.php index 92d8aaa8d4..db12c0f417 100644 --- a/module/release/model.php +++ b/module/release/model.php @@ -31,7 +31,7 @@ class releaseModel extends model ->fetch(); if(!$release) return false; - $release->builds = $this->dao->select('id, filePath, scmPath, name, project')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll(); + $release->builds = $this->dao->select('id, filePath, scmPath, name, execution, project')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll(); $this->loadModel('file'); $release = $this->file->replaceImgURL($release, 'desc'); @@ -66,7 +66,7 @@ class releaseModel extends model ->page($pager) ->fetchAll(); - $builds = $this->dao->select("t1.id, t1.name, IF(t2.name IS NOT NULL, t2.name, '') AS projectName, IF(t3.name IS NOT NULL, t3.name, '{$this->lang->trunk}') AS branchName") + $builds = $this->dao->select("t1.id, t1.name, t1.execution, IF(t2.name IS NOT NULL, t2.name, '') AS projectName, IF(t3.name IS NOT NULL, t3.name, '{$this->lang->trunk}') AS branchName") ->from(TABLE_BUILD)->alias('t1') ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') ->leftJoin(TABLE_BRANCH)->alias('t3')->on('t1.branch = t3.id') diff --git a/module/release/view/browse.html.php b/module/release/view/browse.html.php index 5552c7eb28..3162da013b 100644 --- a/module/release/view/browse.html.php +++ b/module/release/view/browse.html.php @@ -52,7 +52,7 @@ release->id;?> release->name;?> release->build;?> - release->project;?> + release->project;?> release->status;?> release->date;?> type != 'normal'):?> branchName;?> - createLink('build', 'view', "buildID=$build->id"), $build->name);?> + createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$build->id"), $build->name);?> projectName;?> diff --git a/module/release/view/view.html.php b/module/release/view/view.html.php index dbb2394344..67054a46e2 100644 --- a/module/release/view/view.html.php +++ b/module/release/view/view.html.php @@ -357,7 +357,7 @@ foreach($release->builds as $build) { $buildDivision = $i == count($release->builds) ? '' : $lang->comma; - echo (($build->project) ? html::a($this->createLink('build', 'view', "buildID=$build->id"), $build->name, '_blank') : $build->name) . $buildDivision; + echo (($build->project) ? html::a($this->createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$build->id"), $build->name, '_blank') : $build->name) . $buildDivision; $i++; } ?>