* Finish task #43903.
This commit is contained in:
+1
-1
@@ -837,7 +837,7 @@ CREATE TABLE IF NOT EXISTS `zt_projectproduct` (
|
||||
`product` mediumint(8) unsigned NOT NULL,
|
||||
`branch` mediumint(8) unsigned NOT NULL,
|
||||
`plan` mediumint(8) unsigned NOT NULL,
|
||||
PRIMARY KEY (`project`,`product`)
|
||||
PRIMARY KEY (`project`,`product`, `branch`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_projectspec`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_projectspec` (
|
||||
|
||||
@@ -7,6 +7,7 @@ $lang->branch->add = 'Hinzufügen';
|
||||
|
||||
$lang->branch->manageTitle = '%s Management';
|
||||
$lang->branch->all = 'Alle ';
|
||||
$lang->branch->main = 'Trunk';
|
||||
|
||||
$lang->branch->id = 'ID';
|
||||
$lang->branch->product = 'Produkt';
|
||||
|
||||
@@ -7,6 +7,7 @@ $lang->branch->add = 'Add';
|
||||
|
||||
$lang->branch->manageTitle = '%s Management';
|
||||
$lang->branch->all = 'All ';
|
||||
$lang->branch->main = 'Trunk';
|
||||
|
||||
$lang->branch->id = 'ID';
|
||||
$lang->branch->product = 'Product';
|
||||
|
||||
@@ -7,6 +7,7 @@ $lang->branch->add = 'Ajout';
|
||||
|
||||
$lang->branch->manageTitle = 'Gestion %s';
|
||||
$lang->branch->all = 'Tous';
|
||||
$lang->branch->main = 'Trunk';
|
||||
|
||||
$lang->branch->id = 'ID';
|
||||
$lang->branch->product = 'Product';
|
||||
|
||||
@@ -7,6 +7,7 @@ $lang->branch->add = 'Thêm';
|
||||
|
||||
$lang->branch->manageTitle = 'Quản lý %s';
|
||||
$lang->branch->all = 'Tất cả ';
|
||||
$lang->branch->main = 'Trunk';
|
||||
|
||||
$lang->branch->id = 'ID';
|
||||
$lang->branch->product = 'Sản phẩm';
|
||||
|
||||
@@ -7,6 +7,7 @@ $lang->branch->add = '添加';
|
||||
|
||||
$lang->branch->manageTitle = '%s管理';
|
||||
$lang->branch->all = '所有';
|
||||
$lang->branch->main = '主干';
|
||||
|
||||
$lang->branch->id = '编号';
|
||||
$lang->branch->product = '所属产品';
|
||||
|
||||
@@ -25,7 +25,7 @@ class branchModel extends model
|
||||
if(empty($productID)) $productID = $this->session->product;
|
||||
$product = $this->loadModel('product')->getById($productID);
|
||||
if(empty($product) or !isset($this->lang->product->branchName[$product->type])) return false;
|
||||
return $this->lang->branch->all . $this->lang->product->branchName[$product->type];
|
||||
return $this->lang->branch->main;
|
||||
}
|
||||
return htmlspecialchars_decode($this->dao->select('*')->from(TABLE_BRANCH)->where('id')->eq($branchID)->fetch('name'));
|
||||
}
|
||||
@@ -52,7 +52,7 @@ class branchModel extends model
|
||||
$product = $this->loadModel('product')->getById($productID);
|
||||
if(!$product or $product->type == 'normal') return array();
|
||||
|
||||
$branches = array('0' => $this->lang->branch->all . $this->lang->product->branchName[$product->type]) + $branches;
|
||||
$branches = array('0' => $this->lang->branch->main) + $branches;
|
||||
}
|
||||
return $branches;
|
||||
}
|
||||
@@ -81,10 +81,7 @@ class branchModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
if(strpos($params, 'noempty') === false)
|
||||
{
|
||||
$branchPairs = array('0' => $this->lang->branch->all . $this->lang->product->branchName['branch']) + $branchPairs;
|
||||
}
|
||||
if(strpos($params, 'noempty') === false) $branchPairs = array('0' => $this->lang->branch->main) + $branchPairs;
|
||||
return $branchPairs;
|
||||
}
|
||||
|
||||
@@ -154,7 +151,7 @@ class branchModel extends model
|
||||
if($product->type == 'normal') continue;
|
||||
|
||||
if(!isset($branchGroups[$product->id])) $branchGroups[$product->id] = array();
|
||||
if(strpos($params, 'noempty') === false) $branchGroups[$product->id] = array('0' => $this->lang->branch->all . $this->lang->product->branchName[$product->type]) + $branchGroups[$product->id];
|
||||
if(strpos($params, 'noempty') === false) $branchGroups[$product->id] = array('0' => $this->lang->branch->main) + $branchGroups[$product->id];
|
||||
}
|
||||
|
||||
return $branchGroups;
|
||||
|
||||
@@ -1776,7 +1776,7 @@ class bug extends control
|
||||
$relatedTasks = $this->dao->select('id, name')->from(TABLE_TASK)->where('id')->in($relatedTaskIdList)->fetchPairs();
|
||||
$relatedBugs = $this->dao->select('id, title')->from(TABLE_BUG)->where('id')->in($relatedBugIdList)->fetchPairs();
|
||||
$relatedCases = $this->dao->select('id, title')->from(TABLE_CASE)->where('id')->in($relatedCaseIdList)->fetchPairs();
|
||||
$relatedBranch = array('0' => $this->lang->branch->all) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
|
||||
$relatedBranch = array('0' => $this->lang->branch->main) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
|
||||
$relatedBuilds = array('trunk' => $this->lang->trunk) + $this->dao->select('id, name')->from(TABLE_BUILD)->where('id')->in($relatedBuildIdList)->fetchPairs();
|
||||
$relatedFiles = $this->dao->select('id, objectID, pathname, title')->from(TABLE_FILE)->where('objectType')->eq('bug')->andWhere('objectID')->in(@array_keys($bugs))->andWhere('extra')->ne('editor')->fetchGroup('objectID');
|
||||
$relatedModules = $this->loadModel('tree')->getAllModulePairs('bug');
|
||||
|
||||
@@ -1320,7 +1320,7 @@ class bugModel extends model
|
||||
else
|
||||
{
|
||||
$this->config->bug->search['fields']['branch'] = $this->lang->product->branch;
|
||||
$this->config->bug->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
|
||||
$this->config->bug->search['params']['branch']['values'] = array('' => '', 0 => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
|
||||
}
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->bug->search);
|
||||
|
||||
+13
-12
@@ -402,18 +402,19 @@ $lang->pasteImgFail = "Failed to paste images. Try again later.";
|
||||
$lang->pasteImgUploading = "Uploading...";
|
||||
|
||||
/* Time formats settings. */
|
||||
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
|
||||
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
|
||||
if(!defined('DT_MONTHTIME1'))define('DT_MONTHTIME1', 'n/d H:i');
|
||||
if(!defined('DT_MONTHTIME2'))define('DT_MONTHTIME2', 'n/d H:i');
|
||||
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
|
||||
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
|
||||
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y/m/d');
|
||||
if(!defined('DT_DATE4')) define('DT_DATE4', 'M d');
|
||||
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
|
||||
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
|
||||
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
|
||||
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
|
||||
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
|
||||
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
|
||||
if(!defined('DT_MONTHTIME1')) define('DT_MONTHTIME1', 'n/d H:i');
|
||||
if(!defined('DT_MONTHTIME2')) define('DT_MONTHTIME2', 'n/d H:i');
|
||||
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
|
||||
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
|
||||
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y/m/d');
|
||||
if(!defined('DT_DATE4')) define('DT_DATE4', 'M d');
|
||||
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
|
||||
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
|
||||
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
|
||||
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
|
||||
if(!defined('MAIN')) define('MAIN', '0');
|
||||
|
||||
/* Datepicker. */
|
||||
$lang->datepicker = new stdclass();
|
||||
|
||||
@@ -402,18 +402,19 @@ $lang->pasteImgFail = "贴图失败,请稍后重试。";
|
||||
$lang->pasteImgUploading = "正在上传图片,请稍后...";
|
||||
|
||||
/* 时间格式设置。*/
|
||||
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
|
||||
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
|
||||
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
|
||||
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
|
||||
if(!defined('DT_MONTHTIME1')) define('DT_MONTHTIME1', 'n/d H:i');
|
||||
if(!defined('DT_MONTHTIME2')) define('DT_MONTHTIME2', 'n月d日 H:i');
|
||||
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
|
||||
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
|
||||
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y年m月d日');
|
||||
if(!defined('DT_DATE4')) define('DT_DATE4', 'n月j日');
|
||||
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
|
||||
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
|
||||
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
|
||||
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
|
||||
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
|
||||
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
|
||||
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y年m月d日');
|
||||
if(!defined('DT_DATE4')) define('DT_DATE4', 'n月j日');
|
||||
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
|
||||
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
|
||||
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
|
||||
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
|
||||
if(!defined('MAIN')) define('MAIN', '0');
|
||||
|
||||
/* datepicker 时间*/
|
||||
$lang->datepicker = new stdclass();
|
||||
|
||||
@@ -858,7 +858,7 @@ class productModel extends model
|
||||
else
|
||||
{
|
||||
$this->config->product->search['fields']['branch'] = $this->lang->product->branch;
|
||||
$this->config->product->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
|
||||
$this->config->product->search['params']['branch']['values'] = array('' => '', '0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
|
||||
}
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->product->search);
|
||||
|
||||
@@ -275,6 +275,24 @@ class productplanModel extends model
|
||||
return array('' => '') + $planPairs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plan list by story id list.
|
||||
*
|
||||
* @param string|array $storyIdList
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getListByStories($storyIdList)
|
||||
{
|
||||
if(empty($storyIdList)) return array();
|
||||
return $this->dao->select('t3.*, t1.id as storyID')->from(TABLE_STORY)->alias('t1')
|
||||
->leftJoin(TABLE_PLANSTORY)->alias('t2')->on('t1.id=t2.story')
|
||||
->leftJoin(TABLE_PRODUCTPLAN)->alias('t3')->on('t2.plan=t3.id')
|
||||
->where('t1.id')->in($storyIdList)
|
||||
->andWhere('t3.deleted')->eq(0)
|
||||
->fetchGroup('storyID', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plans for products
|
||||
*
|
||||
|
||||
@@ -1381,7 +1381,55 @@ class story extends control
|
||||
*/
|
||||
public function batchChangeBranch($branchID)
|
||||
{
|
||||
$storyIdList = !empty($_POST['storyIdList']) ? $this->post->storyIdList : die(js::locate($this->session->storyList, 'parent'));
|
||||
/* Get the storyIdList value from the post. */
|
||||
if(!empty($_POST['storyIdList'])) $storyIdList = $_POST['storyIdList'];
|
||||
$storyIdList = $storyIdList ? $storyIdList : die(js::locate($this->session->storyList, 'parent'));
|
||||
$plans = $this->loadModel('productplan')->getListByStories($storyIdList);
|
||||
if(empty($confirm))
|
||||
{
|
||||
$stories = $this->story->getByList($storyIdList);
|
||||
$conflictStotyIdList = '';
|
||||
$normalStotyIdList = '';
|
||||
/* Determine whether there are conflicting stories. */
|
||||
foreach($storyIdList as $storyID)
|
||||
{
|
||||
/* If the story of a non-trunk branch needs to be changed to a non-trunk branch, judge whether there is a conflict in the plan. */
|
||||
if($branchID and $stories[$storyID]->branch and $stories[$storyID]->branch != $branchID and isset($plans[$storyID]))
|
||||
{
|
||||
if(!empty($plan->branch) and $plan->branch != $branchID)
|
||||
{
|
||||
$conflictStotyIdList .= '[' . $storyID . ']';
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If a trunk story needs to be switched to a non-trunk branch to determine whether there is a conflicting plan. */
|
||||
elseif($branchID and empty($stories[$storyID]->branch) and $plans[$storyID])
|
||||
{
|
||||
foreach($plans[$storyID] as $plan)
|
||||
{
|
||||
if(!empty($plan->branch) and $plan->branch != $branchID)
|
||||
{
|
||||
$conflictStotyIdList .= '[' . $storyID . ']';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$normalStotyIdList .= $storyID . ',';
|
||||
}
|
||||
}
|
||||
|
||||
if($conflictStotyIdList)
|
||||
{
|
||||
$storyIdList = implode(',', $storyIdList);
|
||||
$confirmURL = $this->createLink('story', 'batchChangeBranch', "branchID=$branchID&confirm=yes&storyIdList=$storyIdList");
|
||||
$cancelURL = $this->createLink('story', 'batchChangeBranch', "branchID=$branchID&confirm=no&storyIdList=$normalStotyIdList");
|
||||
die(js::confirm(sprintf($this->lang->story->confirmChangeBranch, $conflictStotyIdList), $confirmURL, $cancelURL));
|
||||
}
|
||||
}
|
||||
|
||||
if(!is_array($storyIdList)) $storyIdList = explode(',', $storyIdList);
|
||||
$storyIdList = array_unique($storyIdList);
|
||||
$allChanges = $this->story->batchChangeBranch($storyIdList, $branchID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
@@ -2039,7 +2087,7 @@ class story extends control
|
||||
$relatedStories = $this->dao->select('id,title')->from(TABLE_STORY) ->where('id')->in($relatedStoryIdList)->fetchPairs();
|
||||
$relatedFiles = $this->dao->select('id, objectID, pathname, title')->from(TABLE_FILE)->where('objectType')->eq('story')->andWhere('objectID')->in($storyIdList)->andWhere('extra')->ne('editor')->fetchGroup('objectID');
|
||||
$relatedSpecs = $this->dao->select('*')->from(TABLE_STORYSPEC)->where('`story`')->in($storyIdList)->orderBy('version desc')->fetchGroup('story');
|
||||
$relatedBranch = array('0' => $this->lang->branch->all) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
|
||||
$relatedBranch = array('0' => $this->lang->branch->main) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
|
||||
$relatedModules = $this->loadModel('tree')->getAllModulePairs();
|
||||
|
||||
foreach($stories as $story)
|
||||
|
||||
+43
-3
@@ -1692,7 +1692,44 @@ class storyModel extends model
|
||||
$story->branch = $branchID;
|
||||
|
||||
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->where('id')->eq((int)$storyID)->exec();
|
||||
if(!dao::isError()) $allChanges[$storyID] = common::createChanges($oldStory, $story);
|
||||
if(!dao::isError())
|
||||
{
|
||||
/* If a trunk story to be switched to a non-trunk branch to cancel the association with other non-trunk branch plans. */
|
||||
$removeUnlinkPlan = '';
|
||||
$continueLinkPlan = '';
|
||||
if(empty($oldStory->branch) and $branchID and isset($plans[$storyID]))
|
||||
{
|
||||
foreach($plans[$storyID] as $planID => $plan)
|
||||
{
|
||||
if(!empty($plan->branch) and $plan->branch != $branchID)
|
||||
{
|
||||
$removeUnlinkPlan = $planID . ',';
|
||||
continue;
|
||||
}
|
||||
$continueLinkPlan = $planID . ',';
|
||||
}
|
||||
}
|
||||
/* If a non-trunk story wants to switch to a non-trunk branch, cancel the association with other non-trunk branch plans. */
|
||||
elseif($oldStory->branch and $branchID and isset($plans[$storyID]))
|
||||
{
|
||||
foreach($plans[$storyID] as $planID => $plan)
|
||||
{
|
||||
if(!empty($plan->branch) and $plan->branch != $branchID)
|
||||
{
|
||||
$removeUnlinkPlan = $planID . ',';
|
||||
continue;
|
||||
}
|
||||
$continueLinkPlan = $planID . ',';
|
||||
}
|
||||
}
|
||||
if($removeUnlinkPlan) $this->dao->delete()->from(TABLE_PLANSTORY)->where('story')->eq($storyID)->andWhere('plan')->in($removeUnlinkPlan)->exec();
|
||||
if($continueLinkPlan)
|
||||
{
|
||||
$story->plan = $continueLinkPlan;
|
||||
$this->dao->update(TABLE_STORY)->set('plan')->eq($continueLinkPlan)->where('id')->eq($storyID)->exec();
|
||||
}
|
||||
$allChanges[$storyID] = common::createChanges($oldStory, $story);
|
||||
}
|
||||
}
|
||||
return $allChanges;
|
||||
}
|
||||
@@ -2413,6 +2450,7 @@ class storyModel extends model
|
||||
$storyQuery = $storyQuery . ' AND `product` ' . helper::dbIN(array_keys($products));
|
||||
if($excludeStories) $storyQuery = $storyQuery . ' AND `id` NOT ' . helper::dbIN($excludeStories);
|
||||
if($this->app->moduleName == 'productplan') $storyQuery .= " AND `status` NOT IN ('closed') AND `parent` >= 0 ";
|
||||
$allBranch = "`branch` = 'all'";
|
||||
if($executionID != '')
|
||||
{
|
||||
foreach($products as $product) $branches[$product->branch] = $product->branch;
|
||||
@@ -2430,9 +2468,11 @@ class storyModel extends model
|
||||
}
|
||||
elseif($branch)
|
||||
{
|
||||
$allBranch = "`branch` = 'all'";
|
||||
if($branch and strpos($storyQuery, '`branch` =') === false) $storyQuery .= " AND `branch` in('0','$branch')";
|
||||
if(strpos($storyQuery, $allBranch) !== false) $storyQuery = str_replace($allBranch, '1', $storyQuery);
|
||||
}
|
||||
elseif(strpos($storyQuery, $allBranch) !== false)
|
||||
{
|
||||
$storyQuery = str_replace($allBranch, '1', $storyQuery);
|
||||
}
|
||||
$storyQuery = preg_replace("/`plan` +LIKE +'%([0-9]+)%'/i", "CONCAT(',', `plan`, ',') LIKE '%,$1,%'", $storyQuery);
|
||||
|
||||
|
||||
@@ -1439,7 +1439,7 @@ class testcaseModel extends model
|
||||
else
|
||||
{
|
||||
$this->config->testcase->search['fields']['branch'] = $this->lang->product->branch;
|
||||
$this->config->testcase->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
|
||||
$this->config->testcase->search['params']['branch']['values'] = array('' => '', '0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
|
||||
}
|
||||
if(!$this->config->testcase->needReview) unset($this->config->testcase->search['params']['status']['values']['wait']);
|
||||
$this->config->testcase->search['actionURL'] = $actionURL;
|
||||
|
||||
@@ -42,7 +42,7 @@ class testsuiteModel extends model
|
||||
if($currentProduct->type != 'normal')
|
||||
{
|
||||
$this->app->loadLang('branch');
|
||||
$branchName = $this->lang->branch->all . $this->lang->product->branchName[$currentProduct->type];
|
||||
$branchName = $this->lang->branch->main;
|
||||
$output .= "<div class='btn-group'><button id='currentBranch' type='button' class='btn btn-limit'>{$branchName} </button></div></div>";
|
||||
}
|
||||
$output .= '</div>';
|
||||
|
||||
Reference in New Issue
Block a user