diff --git a/db/update18.0.sql b/db/update18.0.sql new file mode 100644 index 0000000000..926795ad20 --- /dev/null +++ b/db/update18.0.sql @@ -0,0 +1,5 @@ +ALTER TABLE `zt_story` ADD COLUMN `siblings` varchar(255) NOT NULL AFTER `linkRequirements`; + +ALTER TABLE `zt_productplan` MODIFY COLUMN `branch` varchar(255) NOT NULL DEFAULT '0'; + +ALTER TABLE `zt_build` MODIFY COLUMN `branch` varchar(255) NOT NULL DEFAULT '0'; \ No newline at end of file diff --git a/db/zentao.sql b/db/zentao.sql index 0790cba43f..9fbac1cf39 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -321,7 +321,7 @@ CREATE TABLE IF NOT EXISTS `zt_build` ( `id` mediumint(8) unsigned NOT NULL auto_increment, `project` mediumint(8) unsigned NOT NULL, `product` mediumint(8) unsigned NOT NULL default '0', - `branch` mediumint(8) unsigned NOT NULL default '0', + `branch` varchar(255) NOT NULL DEFAULT '0', `execution` mediumint(8) unsigned NOT NULL default '0', `builds` varchar(255) NOT NULL, `name` char(150) NOT NULL, diff --git a/module/branch/control.php b/module/branch/control.php index f362b79248..93009d3205 100644 --- a/module/branch/control.php +++ b/module/branch/control.php @@ -257,20 +257,21 @@ class branch extends control * * @param int $productID * @param int $oldBranch - * @param string $param + * @param string $browseType * @param int $projectID * @param bool $withMainBranch * @param string $isSiblings * @param string $fieldID + * @param string $multiple * @access public * @return void */ - public function ajaxGetBranches($productID, $oldBranch = 0, $param = 'all', $projectID = 0, $withMainBranch = true, $isSiblings = 'no', $fieldID = '0') + public function ajaxGetBranches($productID, $oldBranch = 0, $browseType = 'all', $projectID = 0, $withMainBranch = true, $isSiblings = 'no', $fieldID = '0', $multiple = '') { $product = $this->loadModel('product')->getById($productID); if(empty($product) or $product->type == 'normal') return; - $branches = $this->loadModel('branch')->getList($productID, $projectID, $param, 'order', null, $withMainBranch); + $branches = $this->loadModel('branch')->getList($productID, $projectID, $browseType, 'order', null, $withMainBranch); $branchTagOption = array(); foreach($branches as $branchInfo) { @@ -282,8 +283,10 @@ class branch extends control $branchTagOption[$oldBranch] = $oldBranch == BRANCH_MAIN ? $branch : ($branch->name . ($branch->status == 'closed' ? ' (' . $this->lang->branch->statusList['closed'] . ')' : '')); } + $name = $multiple == 'multiple' ? 'branch[]' : 'branch'; + if($isSiblings == 'yes') return print(html::select("branches[$fieldID]", $branchTagOption, $oldBranch, "onchange='loadBranchRelation(this.value, $fieldID);' class='form-control chosen control-branch'")); - return print(html::select('branch', $branchTagOption, $oldBranch, "class='form-control' onchange='loadBranch(this)' data-last='{$oldBranch}'")); + return print(html::select($name, $branchTagOption, $oldBranch, "class='form-control' $multiple onchange='loadBranch(this)' data-last='{$oldBranch}'")); } /** diff --git a/module/build/control.php b/module/build/control.php index 05cc1ffef2..021f442967 100644 --- a/module/build/control.php +++ b/module/build/control.php @@ -199,7 +199,10 @@ class build extends control { $branchTagOption[$branchInfo->id] = $branchInfo->name . ($branchInfo->status == 'closed' ? ' (' . $this->lang->branch->statusList['closed'] . ')' : ''); } - if(!isset($branchTagOption[$build->branch])) $branchTagOption[$build->branch] = $this->branch->getById($build->branch, 0, 'name'); + foreach(explode(',', $build->branch) as $buildBranch) + { + if(!isset($branchTagOption[$buildBranch])) $branchTagOption[$buildBranch] = $this->branch->getById($buildBranch, 0, 'name'); + } foreach($productGroups as $product) $products[$product->id] = $product->name; @@ -306,6 +309,16 @@ class build extends control $this->view->generatedBugPager = $generatedBugPager; $this->executeHooks($buildID); + $branchName = ''; + if($build->productType != 'normal') + { + foreach(explode(',', $build->branch) as $buildBranch) + { + $branchName .= $this->loadModel('branch')->getById($buildBranch); + $branchName .= ','; + } + $branchName = trim($branchName, ','); + } /* Assign. */ $this->view->canBeChanged = common::canBeChanged('build', $build); // Determines whether an object is editable. @@ -321,7 +334,7 @@ class build extends control $this->view->bugs = $bugs; $this->view->type = $type; $this->view->bugPager = $bugPager; - $this->view->branchName = $build->productType == 'normal' ? '' : $this->loadModel('branch')->getById($build->branch); + $this->view->branchName = empty($branchName) ? $this->lang->branch->main : $branchName; $this->view->childBuilds = empty($build->builds) ? array() : $this->dao->select('id,name,bugs,stories')->from(TABLE_BUILD)->where('id')->in($build->builds)->fetchAll(); if($this->app->getViewType() == 'json') diff --git a/module/build/js/common.js b/module/build/js/common.js index 4dbf5d9cec..8f0538b32f 100644 --- a/module/build/js/common.js +++ b/module/build/js/common.js @@ -7,6 +7,11 @@ */ function loadBranches(productID) { + if($('input[name=isIntegrated]:checked').val() == 'yes') + { + $('#branchBox').closest('tr').addClass('hidden'); + return false; + } $('#branch').remove(); $('#branch_chosen').remove(); var oldBranch = 0; @@ -16,12 +21,17 @@ function loadBranches(productID) } projectID = currentTab == 'execution' ? executionID : projectID; - $.get(createLink('branch', 'ajaxGetBranches', 'productID=' + productID + '&oldBranch=0¶m=active&projectID=' + projectID), function(data) + $.get(createLink('branch', 'ajaxGetBranches', 'productID=' + productID + '&oldBranch=0¶m=active&projectID=' + projectID + '&withMainBranch=true&isSiblings=no&fieldID=0&multiple=multiple'), function(data) { if(data) { - $('#product').closest('.input-group').append(data); + $('#branchBox').append(data); $('#branch').chosen(); + $('#branchBox').closest('tr').removeClass('hidden'); + } + else + { + $('#branchBox').closest('tr').addClass('hidden'); } }); } diff --git a/module/build/js/create.js b/module/build/js/create.js index b84d711c00..f74d9ca74e 100644 --- a/module/build/js/create.js +++ b/module/build/js/create.js @@ -9,8 +9,7 @@ $().ready(function() { var projectID = $('#project').val(); var productID = $('#product').val(); - var branch = $('#branch').length > 0 ? $('#branch').val() : ''; - $.get(createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=builds&build=&branch=' + branch + '&index=&needCreate=&type=noempty,notrunk,separate,singled&extra=multiple'), function(data) + $.get(createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=builds&build=&branch=all&index=&needCreate=&type=noempty,notrunk,separate,singled&extra=multiple'), function(data) { if(data) $('#buildBox').html(data); $('#builds').attr('data-placeholder', multipleSelect).chosen(); diff --git a/module/build/js/edit.js b/module/build/js/edit.js index 7088791ec2..f5a81757a8 100644 --- a/module/build/js/edit.js +++ b/module/build/js/edit.js @@ -10,8 +10,7 @@ $().ready(function() else { var productID = $('#product').val(); - var branch = $('#branch').val(); - $.get(createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=builds&build=&branch=' + branch + '&index=&needCreate=&type=noempty,notrunk,separate,singled&extra=multiple'), function(data) + $.get(createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=builds&build=&branch=all&index=&needCreate=&type=noempty,notrunk,separate,singled&extra=multiple'), function(data) { if(data) $('#buildBox').html(data); $('#builds').attr('data-placeholder', multipleSelect).chosen(); diff --git a/module/build/model.php b/module/build/model.php index b53fd9507b..45d13f4296 100644 --- a/module/build/model.php +++ b/module/build/model.php @@ -382,21 +382,44 @@ class buildModel extends model ->setDefault('product', 0) ->setDefault('branch', 0) ->setDefault('builds', '') - ->cleanInt('product,branch') + ->cleanInt('product') ->add('createdBy', $this->app->user->account) ->add('createdDate', helper::now()) ->stripTags($this->config->build->editor->create['id'], $this->config->allowedTags) ->join('builds', ',') + ->join('branch', ',') ->remove('resolvedBy,allchecker,files,labels,isIntegrated,uid') ->get(); - if($this->post->isIntegrated == 'yes') $build->execution = 0; + if($this->post->isIntegrated == 'yes') + { + $build->execution = 0; + $branchPairs = $this->dao->select('branch')->from(TABLE_BUILD)->where('id')->in($build->builds)->fetchPairs(); + $relationBranch = array(); + foreach($branchPairs as $branches) + { + foreach(explode(',', $branches) as $branch) + { + if(!isset($relationBranch[$branch])) $relationBranch[$branch] = $branch; + } + } + $build->branch = implode(',', $relationBranch); + } + + $product = $this->loadModel('product')->getByID($build->product); + if($product->type != 'normal' and $this->post->isIntegrated == 'no' and !isset($_POST['branch'])) + { + $this->lang->product->branch = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]); + dao::$errors['branch'] = sprintf($this->lang->error->notempty, $this->lang->product->branch); + } + + if(dao::isError()) return false; $build = $this->loadModel('file')->processImgURL($build, $this->config->build->editor->create['id'], $this->post->uid); $this->dao->insert(TABLE_BUILD)->data($build) ->autoCheck() ->batchCheck($this->config->build->create->requiredFields, 'notempty') - ->check('name', 'unique', "product = {$build->product} AND branch = {$build->branch} AND deleted = '0'") + ->check('name', 'unique', "product = {$build->product} AND branch = '{$build->branch}' AND deleted = '0'") ->checkFlow() ->exec(); @@ -426,17 +449,27 @@ class buildModel extends model ->setIF(!isset($_POST['branch']), 'branch', $oldBuild->branch) ->setDefault('product', $oldBuild->product) ->setDefault('builds', '') - ->cleanInt('product,branch,execution') + ->cleanInt('product,execution') ->join('builds', ',') + ->join('branch', ',') ->remove('allchecker,resolvedBy,files,labels,uid') ->get(); + $product = $this->loadModel('product')->getByID($build->product); + if($product->type != 'normal' and $this->post->isIntegrated == 'no' and !isset($_POST['branch'])) + { + $this->lang->product->branch = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]); + dao::$errors['branch'] = sprintf($this->lang->error->notempty, $this->lang->product->branch); + } + + if(dao::isError()) return false; + $build = $this->loadModel('file')->processImgURL($build, $this->config->build->editor->edit['id'], $this->post->uid); $this->dao->update(TABLE_BUILD)->data($build) ->autoCheck() ->batchCheck($this->config->build->edit->requiredFields, 'notempty') ->where('id')->eq($buildID) - ->check('name', 'unique', "id != $buildID AND product = {$build->product} AND branch = {$build->branch} AND deleted = '0'") + ->check('name', 'unique', "id != $buildID AND product = {$build->product} AND branch = '{$build->branch}' AND deleted = '0'") ->checkFlow() ->exec(); if(isset($build->branch) and $oldBuild->branch != $build->branch) $this->dao->update(TABLE_RELEASE)->set('branch')->eq($build->branch)->where('build')->eq($buildID)->exec(); diff --git a/module/build/view/create.html.php b/module/build/view/create.html.php index 543af32def..d2b96aadc9 100644 --- a/module/build/view/create.html.php +++ b/module/build/view/create.html.php @@ -33,12 +33,6 @@