Merge branch 'master' into 'master_271_78665'

# Conflicts:
#   module/build/control.php
This commit is contained in:
孙广明
2022-12-09 08:58:55 +00:00
77 changed files with 612 additions and 281 deletions
+26 -1
View File
@@ -20,7 +20,32 @@ class tasksEntry extends entry
*/
public function get($executionID = 0)
{
if(!$executionID)
/* Get tasks by search, search arguments available: pri, assignedTo, status, id, name. Pager arguments will be utilized as well. */
if($this->param('search', 0) == 1) // TODO: document this api.
{
$this->loadModel('task');
$searchParams = array();
foreach(array('pri' => 'priList', 'assignedTo' => 'assignedToList', 'status' => 'statusList', 'id' => 'idList', 'name' => 'taskName') as $field => $condName)
{
if($this->param($field, false))
{
$searchParams[$condName] = $this->param($field);
continue;
}
if($this->param($condName, false)) $searchParams[$condName] = $this->param($condName);
}
$this->app->loadClass('pager', $static = true);
$pager = pager::init($this->param('total', 0), $this->param('limit', 20), $this->param('page', 1));
$tasks = $this->task->getListByConds((object)$searchParams, $this->param('order', 'id_desc'), $pager);
$data = new stdclass();
$data->status = 'success';
$data->data = new stdclass();
$data->data->tasks = array_values($tasks);
$data->data->pager = (object)$pager;
}
elseif(!$executionID)
{
/* Get my tasks defaultly. */
$control = $this->loadController('my', 'task');
+10 -5
View File
@@ -98,7 +98,7 @@ class baseEntry
* Get request params.
*
* @param string $key
* @param string $defaultValue
* @param mixed $defaultValue
* @access public
* @return mixed
*/
@@ -112,13 +112,18 @@ class baseEntry
* 设置请求参数
* Set request param.
*
* @param string $key
* @param mixed $value
* @param string|array $key if is array, set params by its key-value pairs.
* @param mixed $value
* @access public
* @return mixed
* @return void
*/
public function setParam($key, $value)
public function setParam($key, $value = null)
{
if(is_array($key))
{
foreach($key as $k => $v) $_GET[$k] = $v;
return;
}
$_GET[$key] = $value;
}
+5 -1
View File
@@ -130,7 +130,11 @@ class pager extends basePager
}
}
echo "<ul class='pager' $pageSizeOptions data-page-cookie='{$this->pageCookie}' data-ride='pager' data-rec-total='{$this->recTotal}' data-rec-per-page='{$this->recPerPage}' data-page='{$this->pageID}' data-link-creator='" . helper::createLink($this->moduleName, $this->methodName, $params) . "'></ul>";
global $app, $lang;
$appendApp = '';
$moduleName = $this->moduleName;
if(isset($lang->navGroup->{$moduleName}) and $lang->navGroup->{$moduleName} != $app->tab) $appendApp = "#app={$app->tab}";
echo "<ul class='pager' $pageSizeOptions data-page-cookie='{$this->pageCookie}' data-ride='pager' data-rec-total='{$this->recTotal}' data-rec-per-page='{$this->recPerPage}' data-page='{$this->pageID}' data-link-creator='" . helper::createLink($this->moduleName, $this->methodName, $params) . $appendApp . "'></ul>";
}
}
else
+5
View File
@@ -1951,6 +1951,11 @@ class block extends control
$hasViewPriv['review'] = true;
$count['review'] = count($reviews);
$this->view->reviews = $reviews;
if($this->config->edition == 'max')
{
$this->app->loadLang('approval');
$this->view->flows = $this->dao->select('module,name')->from(TABLE_WORKFLOW)->where('buildin')->eq(0)->fetchPairs('module', 'name');
}
}
$this->view->selfCall = $this->selfCall;
+15 -3
View File
@@ -29,13 +29,21 @@
<?php foreach($reviews as $review):?>
<?php
$type = $review->type;
if($type == 'project') $type = 'review';
if($type == 'projectreview') $type = 'review';
$typeName = $lang->$type->common;
$typeName = '';
if(isset($lang->{$review->type}->common)) $typeName = $lang->{$review->type}->common;
if($type == 'story') $typeName = $lang->my->auditMenu->audit->story;
if($review->type == 'projectreview') $typeName = $lang->project->common;
if(isset($flows[$review->type])) $typeName = $flows[$review->type];
$statusList = $lang->$type->statusList;
$statusList = array();
if(isset($lang->$type->statusList)) $statusList = $lang->$type->statusList;
if($type == 'attend') $statusList = $lang->attend->reviewStatusList;
if(!in_array($type, array('story', 'testcase', 'feedback', 'review')) and strpos(",{$config->my->oaObjectType},", ",$type,") === false)
{
$statusList = $lang->approval->nodeList;
}
?>
<tr>
<td class='c-id'><?php echo $review->id?></td>
@@ -82,6 +90,10 @@
{
common::printLink($module, 'view', $params, $reviewIcon, '', "class='btn' data-toggle='modal' title='{$lang->review->common}'", true, true);
}
elseif(!in_array($module, array('story', 'testcase', 'feedback')))
{
common::printLink($module, 'approvalreview', $params, $reviewIcon, '', "class='btn' data-toggle='modal' title='{$lang->review->common}'", true, true);
}
else
{
common::printLink($module, $method, $params, $reviewIcon, '', "class='btn iframe' title='{$lang->review->common}'", true, true);
+25 -13
View File
@@ -24,9 +24,16 @@ if($('#openedBuild').length || $('#resolvedBuild').length || $('[name^=openedBui
{
$.get(createLink('bug', 'ajaxGetReleasedBuilds', 'productID=' + productID), function(data){releasedBuilds = data;}, 'json');
$('#openedBuild, #resolvedBuild, [name^=openedBuilds]').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
$('#openedBuild, #resolvedBuild, [name^=openedBuilds]').picker({optionRender: markReleasedBuilds});
}
/**
* Mark released builds.
*
* @param object $option
* @access public
* @return void
*/
function markReleasedBuilds($option)
{
var build = $option.attr('data-value');
@@ -173,7 +180,7 @@ function loadAllBuilds(object)
{
oldResolvedBuild = $('#resolvedBuild').val() ? $('#resolvedBuild').val() : 0;
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=0&index=0&type=all');
$('#resolvedBuildBox').load(link, function(){$(this).find('select').chosen()});
$('#resolvedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
}
else
{
@@ -212,7 +219,7 @@ function loadAllExecutionBuilds(executionID, productID, buildBox)
$('#pickerDropMenu-pk_openedBuild').remove();
$('#openedBuild').next('.picker').remove();
notice();
$("#openedBuild").picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
$("#openedBuild").picker({optionRender: markReleasedBuilds});
})
}
if(page == 'edit')
@@ -220,7 +227,7 @@ function loadAllExecutionBuilds(executionID, productID, buildBox)
if(buildBox == 'openedBuildBox')
{
link = createLink('build', 'ajaxGetExecutionBuilds', 'executionID=' + executionID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch + '&index=0&needCreate=true&type=all');
$('#openedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
$('#openedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds})});
}
if(buildBox == 'resolvedBuildBox')
{
@@ -255,7 +262,7 @@ function loadAllProductBuilds(productID, buildBox)
$('#pickerDropMenu-pk_openedBuild').remove();
$('#openedBuild').next('.picker').remove();
notice();
$("#openedBuild").picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
$("#openedBuild").picker({optionRender: markReleasedBuilds});
})
}
if(page == 'edit')
@@ -263,12 +270,17 @@ function loadAllProductBuilds(productID, buildBox)
if(buildBox == 'openedBuildBox')
{
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch + '&index=0&type=all');
$('#openedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
$('#openedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds})});
}
if(buildBox == 'resolvedBuildBox')
{
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch + '&index=0&type=all');
$('#resolvedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
$('#resolvedBuildBox').load(link, function()
{
$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})
var $pkResolvedBuild = $('#pk_resolvedBuild-search');
$pkResolvedBuild.closest('.picker').css('width', $pkResolvedBuild.closest('td').width());
});
}
}
}
@@ -474,12 +486,12 @@ function loadProductBuilds(productID)
$('#pickerDropMenu-pk_openedBuild').remove();
$('#openedBuild').next('.picker').remove();
notice();
$("#openedBuild").picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
$("#openedBuild").picker({optionRender: markReleasedBuilds});
})
}
else
{
$('#openedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
$('#openedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds})});
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch);
$('#resolvedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
}
@@ -632,13 +644,13 @@ function loadProjectBuilds(projectID)
$('#pickerDropMenu-pk_openedBuild').remove();
$('#openedBuild').next('.picker').remove();
notice();
$("#openedBuild").picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
$("#openedBuild").picker({optionRender: markReleasedBuilds});
})
}
else
{
var link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch);
$('#openedBuildBox').load(link, function(){$(this).find('select').val(oldOpenedBuild).picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
$('#openedBuildBox').load(link, function(){$(this).find('select').val(oldOpenedBuild).picker({optionRender: markReleasedBuilds})});
var oldResolvedBuild = $('#resolvedBuild').val() ? $('#resolvedBuild').val() : 0;
var link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch);
@@ -677,13 +689,13 @@ function loadExecutionBuilds(executionID, num)
$('#pickerDropMenu-pk_openedBuild').remove();
$('#openedBuild').next('.picker').remove();
notice();
$("#openedBuild").picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
$("#openedBuild").picker({optionRender: markReleasedBuilds});
})
}
else
{
link = createLink('build', 'ajaxGetExecutionBuilds', 'executionID=' + executionID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch + '&index=0&needCreate=false&type=normal&number=' + num);
$('#openedBuildBox' + num).load(link, function(){$(this).find('select').val(oldOpenedBuild).picker({optionRender: markReleaseBuilds, dropWidth: 'auto'})});
$('#openedBuildBox' + num).load(link, function(){$(this).find('select').val(oldOpenedBuild).picker({optionRender: markReleaseBuilds})});
oldResolvedBuild = $('#resolvedBuild').val() ? $('#resolvedBuild').val() : 0;
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch);
+5 -3
View File
@@ -12,9 +12,8 @@ $(function()
confirmResult = confirm(confirmUnlinkBuild);
if(!confirmResult)
{
$('#resolvedBuild').val(oldResolvedBuild);
$('#resolvedBuild').trigger("chosen:updated");
$('#resolvedBuild').chosen();
var resolvedBuildPicker = $('#resolvedBuild').data('zui.picker');
resolvedBuildPicker.setValue(oldResolvedBuild);
}
}
});
@@ -40,6 +39,9 @@ $(function()
var modalTrigger = new $.zui.ModalTrigger({type: 'iframe', width: '95%', url: link});
modalTrigger.show();
});
var $pkResolvedBuild = $('#pk_resolvedBuild-search');
$pkResolvedBuild.closest('.picker').css('width', $pkResolvedBuild.closest('td').width() - $pkResolvedBuild.closest('td').find('.input-group-btn').width());
});
/**
+2 -2
View File
@@ -1855,7 +1855,7 @@ class bugModel extends model
->andWhere('deleted')->eq(0)
->beginIF($excludeBugs)->andWhere('id')->notIN($excludeBugs)->fi()
->beginIF(!empty($productID) and strpos($bugQuery, 'product') === false and strpos($bugQuery, '`product` IN') === false)->andWhere('product')->eq($productID)->fi()
->beginIF(!empty($productID) and strpos($bugQuery, 'product') === false and strpos($bugQuery, '`product` IN') === false)->andWhere('branch')->eq($branchID)->fi()
->beginIF(!empty($productID) and strpos($bugQuery, 'product') === false and strpos($bugQuery, '`product` IN') === false and $branchID != 'all')->andWhere('branch')->eq($branchID)->fi()
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
@@ -2319,7 +2319,7 @@ class bugModel extends model
$products = $this->session->product;
preg_match('/`product` IN \((?P<productIdList>.+)\)/', $this->reportCondition(), $matchs);
if(!empty($matchs) and isset($matchs['productIdList'])) $products = str_replace('\'', '', $matchs['productIdList']);
$builds = $this->loadModel('build')->getBuildPairs($products, $branch = 0, $params = 'hasDeleted');
$builds = $this->loadModel('build')->getBuildPairs($products, $branch = 0, $params = 'hasdeleted');
/* Deal with the situation that a bug maybe associate more than one openedBuild. */
foreach($datas as $buildIDList => $data)
+3 -1
View File
@@ -287,6 +287,8 @@ class build extends control
foreach($stages as $storyID => $stage) $stories[$storyID]->stage = $stage;
/* Set menu. */
$objectType = 'execution';
$objectID = $build->execution;
if($this->app->tab == 'project')
{
$this->loadModel('project')->setMenu($build->project);
@@ -432,7 +434,7 @@ class build extends control
return print(html::select($varName, $builds, $build, "class='form-control'"));
}
$builds = $this->build->getBuildPairs($productID, $branch, $type, 0, 'project', $build);
$builds = $this->build->getBuildPairs($productID, $branch, $type, 0, 'project', $build, false);
if(strpos($extra, 'multiple') !== false) $varName .= '[]';
if($isJsonView) return print(json_encode($builds));
return print(html::select($varName, $builds, $build, "class='form-control chosen' $extra"));
+1
View File
@@ -6,3 +6,4 @@
.body-modal #mainContent {min-height: 200px;}
td.article-content{overflow:auto !important;}
td.c-build{white-space: nowrap; overflow:hidden;}
+17 -6
View File
@@ -25,6 +25,7 @@ $().ready(function()
{
var projectID = $('#project').val();
var executionID = $('#execution').val();
if($(this).val() == 'no')
{
$('#execution').closest('tr').show();
@@ -35,7 +36,16 @@ $().ready(function()
{
$('#execution').closest('tr').hide();
$('#buildBox').closest('tr').show();
$.ajaxSettings.async = false;
loadProducts(projectID);
var productID = $('#product').val();
$.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();
});
$.ajaxSettings.async = true;
}
});
$('#product').change();
@@ -71,15 +81,16 @@ function loadProducts(executionID)
$('#productBox').append(data);
$('#product').chosen();
$.get(createLink('product', 'ajaxGetProductById', 'produtID=' + $("#product").val()), function(data)
{
$('#branchBox').closest('tr').find('th').text(data.branchName);
}, 'json');
loadBranches($("#product").val());
}
});
$.get(createLink('product', 'ajaxGetProductById', 'produtID=' + $("#product").val()), function(data)
{
$('#branchBox').closest('tr').find('th').text(data.branchName);
}, 'json');
loadLastBuild();
}
@@ -94,7 +105,7 @@ function loadLastBuild()
var isIntegrated = $('input[name=isIntegrated]:checked').val();
var projectID = $('#project').val();
var executionID = $('#execution').val();
if(isIntegrated == 'yes') executionID = 0;
if(isIntegrated == 'yes') executionID = 0;
$.get(createLink('build', 'ajaxGetLastBuild', 'projectID=' + projectID + '&executionID=' + executionID), function(data)
{
$('#lastBuildBox').html(data);
+7 -4
View File
@@ -63,7 +63,7 @@ class buildModel extends model
*/
public function getProjectBuilds($projectID = 0, $type = 'all', $param = 0, $orderBy = 't1.date_desc,t1.id_desc', $pager = null)
{
return $this->dao->select('t1.*, t2.name as executionName, t2.id as executionID, t3.name as productName')
return $this->dao->select('t1.*, t2.name as executionName, t2.id as executionID, t2.deleted as executionDeleted, t3.name as productName')
->from(TABLE_BUILD)->alias('t1')
->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.execution = t2.id')
->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t1.product = t3.id')
@@ -253,9 +253,11 @@ class buildModel extends model
->beginIF($products)->andWhere('product')->in($products)->fi()
->beginIF($objectType === 'execution' and $objectID)->andWhere('execution')->eq($objectID)->fi()
->beginIF($objectType === 'project' and $objectID)->andWhere('project')->eq($objectID)->fi()
->beginIF(strpos($params, 'hasdeleted') === false)->andWhere('deleted')->eq(0)->fi()
->fetchPairs();
}
$shadows = $this->dao->select('shadow')->from(TABLE_RELEASE)->where('product')->in($products)->fetchPairs('shadow', 'shadow');
$branchs = strpos($params, 'separate') === false ? "0,$branch" : $branch;
$allBuilds = $this->dao->select('t1.id, t1.name, t1.execution, t1.date, t1.deleted, t2.status as objectStatus, t3.id as releaseID, t3.status as releaseStatus, t4.name as branchName, t5.type as productType')->from(TABLE_BUILD)->alias('t1')
->beginIF($objectType === 'execution')->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.execution = t2.id')->fi()
@@ -264,7 +266,8 @@ class buildModel extends model
->leftJoin(TABLE_BRANCH)->alias('t4')->on('t1.branch = t4.id')
->leftJoin(TABLE_PRODUCT)->alias('t5')->on('t1.product = t5.id')
->where('1=1')
->beginIF(strpos($params, 'hasDeleted') === false)->andWhere('t1.deleted')->eq(0)->fi()
->andWhere('t1.id')->notIN($shadows)
->beginIF(strpos($params, 'hasdeleted') === false)->andWhere('t1.deleted')->eq(0)->fi()
->beginIF(strpos($params, 'hasproject') !== false)->andWhere('t1.project')->ne(0)->fi()
->beginIF(strpos($params, 'singled') !== false)->andWhere('t1.execution')->ne(0)->fi()
->beginIF($products)->andWhere('t1.product')->in($products)->fi()
@@ -405,7 +408,7 @@ class buildModel extends model
}
$product = $this->loadModel('product')->getByID($build->product);
if($product->type != 'normal' and $this->post->isIntegrated == 'no' and !isset($_POST['branch']))
if(!empty($product) and $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);
@@ -454,7 +457,7 @@ class buildModel extends model
->get();
$product = $this->loadModel('product')->getByID($build->product);
if($product->type != 'normal' and $this->post->isIntegrated == 'no' and !isset($_POST['branch']))
if(!empty($product) and $product->type != 'normal' and !isset($_POST['branch']) and isset($_POST['product']))
{
$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);
+8 -3
View File
@@ -44,11 +44,16 @@
<?php endif;?>
<td></td>
</tr>
<tr class='<?php if(!empty($product) and $product->type == 'normal') echo 'hidden'?>'>
<th class='w-120px'><?php echo $product->type == 'normal' ? '' : $lang->product->branchName[$product->type]?></th>
<tr class='<?php if((!empty($product) and $product->type == 'normal') or empty($product)) echo 'hidden'?>'>
<?php
if(empty($product)) $product = new stdclass();
$productType = zget($product, 'type', 'normal');
$productBranches = zget($product, 'branches', array());
?>
<th class='w-120px'><?php echo $productType == 'normal' ? '' : $lang->product->branchName[$productType]?></th>
<td>
<div class='input-group' id='branchBox'>
<?php echo html::select('branch[]', $branches, key($product->branches), "class='form-control chosen' multiple required"); ?>
<?php echo html::select('branch[]', $branches, key($productBranches), "class='form-control chosen' multiple required"); ?>
</div>
</td>
</tr>
+6 -1
View File
@@ -37,7 +37,12 @@
<td><?php if($disabled) echo $lang->build->notice->changeProduct;?></td>
</tr>
<tr>
<tr class='<?php if(!empty($product) and $product->type == 'normal') echo 'hidden'?>'>
<tr class='<?php if((!empty($product) and $product->type == 'normal') or empty($product) or empty($build->execution)) echo 'hidden'?>'>
<?php
if(empty($product)) $product = new stdclass();
$productType = zget($product, 'type', 'normal');
$productBranches = zget($product, 'branches', array());
?>
<th class='w-120px'><?php echo $product->type == 'normal' ? '' : $lang->product->branchName[$product->type]?></th>
<td>
<div class='input-group' id='branchBox'>
+3 -3
View File
@@ -148,7 +148,7 @@ tbody tr td:first-child input {display: none;}
?>
</td>
<?php if($childBuilds):?>
<td class='text-left' title='<?php echo $buildName?>'><?php echo $buildName;?></td>
<td class='c-build text-left' title='<?php echo $buildName?>'><?php echo $buildName;?></td>
<?php endif;?>
<td><?php echo zget($users, $story->openedBy);?></td>
<td class='text-right' title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit;?></td>
@@ -254,7 +254,7 @@ tbody tr td:first-child input {display: none;}
</span>
</td>
<?php if($childBuilds):?>
<td class='text-left' title='<?php echo $buildName?>'><?php echo $buildName;?></td>
<td class='c-build text-left' title='<?php echo $buildName?>'><?php echo $buildName;?></td>
<?php endif;?>
<td><?php echo zget($users, $bug->openedBy);?></td>
<td><?php echo helper::isZeroDate($bug->openedDate) ? '' : substr($bug->openedDate, 5, 11);?></td>
@@ -343,7 +343,7 @@ tbody tr td:first-child input {display: none;}
$openedBuilds = '';
foreach(explode(',', $bug->openedBuild) as $buildID) $openedBuilds .= ($buildID == 'trunk' ? 'Trunk' : zget($buildPairs, $buildID, '')) . ' ';
?>
<td class='text-left' title='<?php echo $openedBuilds;?>'><?php echo $openedBuilds;?></td>
<td class='c-build text-left' title='<?php echo $openedBuilds;?>'><?php echo $openedBuilds;?></td>
<td><?php echo zget($users, $bug->openedBy);?></td>
<td><?php echo helper::isZeroDate($bug->openedDate) ? '' : substr($bug->openedDate, 5, 11);?></td>
<td><?php echo zget($users, $bug->resolvedBy);?></td>
+37 -3
View File
@@ -395,9 +395,9 @@ class commonModel extends model
/**
* Deny access.
*
* @param varchar $module
* @param varchar $method
* @param bool $reload
* @param string $module
* @param string $method
* @param bool $reload
* @access public
* @return mixed
*/
@@ -939,6 +939,38 @@ class commonModel extends model
echo "<div class='btn-group header-btn'>" . $html . '</div>';
}
/**
* Format the date to YYYY-mm-dd, format the datetime to YYYY-mm-dd HH:ii:ss.
*
* @param int $date
* @param string $type date|datetime|''
* @access public
* @return string
*/
public function formatDate($date, $type = '')
{
$datePattern = '\w{4}(\/|-)\w{1,2}(\/|-)\w{1,2}';
$datetimePattern = $datePattern . ' \w{1,2}\:\w{1,2}\:\w{1,2}';
if(empty($type))
{
if(!preg_match("/$datePattern/", $date) and !preg_match("/$datetimePattern/", $date)) return $date;
if(preg_match("/$datePattern/", $date) === 1) $type = 'date';
if(preg_match("/$datetimePattern/", $date) === 1) $type = 'datetime';
}
if(helper::isZeroDate($date))
{
if($type == 'date') return '0000-00-00';
if($type == 'datetime') return '0000-00-00 00:00:00';
}
if($type == 'date') $format = 'Y-m-d';
if($type == 'datetime') $format = 'Y-m-d H:i:s';
return date($format, strtotime($date));
}
/**
* Get main nav items list
*
@@ -2454,6 +2486,8 @@ EOD;
}
catch(EndResponseException $endResponseException)
{
if($this->app->getViewType() == 'json' || (defined('RUN_MODE') && RUN_MODE == 'api')) die($endResponseException->getContent());
echo $endResponseException->getContent();
}
}
+5 -2
View File
@@ -898,7 +898,7 @@ class execution extends control
$storyBugs = $this->loadModel('bug')->getStoryBugCounts($storyIdList, $executionID);
$storyCases = $this->loadModel('testcase')->getStoryCaseCounts($storyIdList);
$plans = $this->execution->getPlans($products, 'skipParent|withMainPlan', $executionID);
$plans = $this->execution->getPlans($products, 'skipParent|withMainPlan|unexpired|noclosed', $executionID);
$allPlans = array('' => '');
if(!empty($plans))
{
@@ -1312,7 +1312,10 @@ class execution extends control
{
$showBranch = true;
$branchPairs = $branchGroups[$build->product];
foreach(explode(',', trim($build->branch, ',')) as $branchID) $build->branchName .= "{$branchPairs[$branchID]},";
foreach(explode(',', trim($build->branch, ',')) as $branchID)
{
if(isset($branchPairs[$branchID])) $build->branchName .= "{$branchPairs[$branchID]},";
}
$build->branchName = trim($build->branchName, ',');
}
}
+1 -1
View File
@@ -31,7 +31,7 @@
#endLabel {white-space: nowrap;}
#copyProjectModal .projectSelect {display: inline-block; margin-left: 10px; width: 20%;}
#copyProjectModal .titleBox{position: relative; bottom: 3px; display: inline-block;}
a.chosen-single > div > b {top: -4px !important;}
#copyProjectModal .projectSelect a.chosen-single > div > b {top: -4px !important;}
.productsBox a {border-radius: 2px !important;}
.productsBox .required:after {right: -9.5px !important;}
+8 -6
View File
@@ -1582,17 +1582,14 @@ class executionModel extends model
->andWhere('type')->eq('execution')
->fetchPairs();
}
$project = $this->loadModel('project')->getByID($projectID);
$executions = $this->dao->select('t1.*,t2.name projectName, t2.model as projectModel')->from(TABLE_EXECUTION)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t3')->on('t1.id=t3.project')
->beginIF(!empty($project->division))->leftJoin(TABLE_PRODUCT)->alias('t4')->on('t4.id=t3.product')->fi()
->beginIF($productID)->leftJoin(TABLE_PROJECTPRODUCT)->alias('t3')->on('t1.id=t3.project')->fi()
->where('t1.type')->in('sprint,stage,kanban')
->andWhere('t1.deleted')->eq('0')
->andWhere('t1.vision')->eq($this->config->vision)
->andWhere('t1.multiple')->eq('1')
->beginIF(!empty($project->division))->andWhere('t4.deleted')->eq('0')->fi()
->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->sprints)->fi()
->beginIF(!empty($executionQuery))->andWhere($executionQuery)->fi()
->beginIF($productID)->andWhere('t3.product')->eq($productID)->fi()
@@ -2319,7 +2316,7 @@ class executionModel extends model
$planPairs = array('' => '');
foreach($products as $productID => $product)
{
$plans = $this->productplan->getBranchPlanPairs($productID, array(BRANCH_MAIN) + $product->branches, true);
$plans = $this->productplan->getBranchPlanPairs($productID, array(BRANCH_MAIN) + $product->branches, 'unexpired', true);
foreach($plans as $plan) $planPairs += $plan;
}
$this->config->product->search['params']['plan']['values'] = $planPairs;
@@ -4656,6 +4653,8 @@ class executionModel extends model
{
$this->loadModel('productplan');
$date = date('Y-m-d');
$param = strtolower($param);
$branchIdList = strpos($param, 'withmainplan') !== false ? array(BRANCH_MAIN => BRANCH_MAIN) : array();
$branchGroups = $this->getBranchByProduct(array_keys($products), $executionID, 'noclosed');
@@ -4686,6 +4685,8 @@ class executionModel extends model
->where('t1.product')->in(array_keys($products))
->andWhere('t1.deleted')->eq(0)
->andWhere($branchQuery)
->beginIF(strpos($param, 'unexpired') !== false)->andWhere('t1.end')->ge($date)->fi()
->beginIF(strpos($param, 'noclosed') !== false)->andWhere('t1.status')->ne('closed')->fi()
->orderBy('t1.begin desc')
->fetchAll('id');
@@ -5247,7 +5248,6 @@ class executionModel extends model
$_POST = array();
$_POST['project'] = $projectID;
$_POST['name'] = $project->name;
$_POST['code'] = $project->code;
$_POST['begin'] = $project->begin;
$_POST['end'] = $project->end;
$_POST['realBegan'] = $project->realBegan;
@@ -5261,6 +5261,8 @@ class executionModel extends model
$_POST['status'] = $project->status;
$_POST['acl'] = 'open';
if(!isset($this->config->setCode) or $this->config->setCode == 1) $_POST['code'] = $project->code;
$projectProducts = $this->dao->select('*')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchAll();
foreach($projectProducts as $projectProduct)
{
+16 -2
View File
@@ -72,8 +72,22 @@
<td class="c-name"><?php echo html::a($this->createLink('build', 'view', "build=$build->id"), $build->name);?></td>
<td class="c-url text-left">
<?php
if($build->scmPath) echo "<div><i class='icon icon-file-code' title='{$lang->build->scmPath}'></i> <span title='{$build->scmPath}'>" . (strpos($build->scmPath, 'http') === 0 ? html::a($build->scmPath, $build->scmPath, '_blank') : $build->scmPath) . '</span></div>';
if($build->filePath) echo "<div><i class='icon icon-file-archive' title='{$lang->build->filePath}'></i> <span title='{$build->filePath}'>" . (strpos($build->filePath, 'http') === 0 ? html::a($build->filePath, $build->filePath, '_blank') : $build->filePath) . '</span></div>';
if($build->scmPath)
{
$colorStyle = strpos($build->scmPath, 'http') === 0 ? "style='color:#2463c7;'" : '';
echo "<div><i class='icon icon-file-code' $colorStyle title='{$lang->build->scmPath}'></i> ";
echo "<span title='{$build->scmPath}'>";
echo $colorStyle ? html::a($build->scmPath, $build->scmPath, '_blank', $colorStyle) : $build->scmPath;
echo '</span></div>';
}
if($build->filePath)
{
$colorStyle = strpos($build->filePath, 'http') === 0 ? "style='color:#2463c7;'" : '';
echo "<div><i class='icon icon-download' $colorStyle title='{$lang->build->filePath}'></i> ";
echo "<span title='{$build->filePath}'>";
echo $colorStyle ? html::a($build->filePath, $build->filePath, '_blank', $colorStyle) : $build->filePath;
echo '</span></div>';
}
?>
</td>
<td class="c-date"><?php echo $build->date?></td>
+2 -1
View File
@@ -408,7 +408,8 @@
<div class="modal-body">
<div class='input-group'>
<?php echo html::select('plan', $allPlans, '', "class='form-control chosen' id='plan'");?>
<span class='input-group-btn'><?php echo html::commonButton($lang->execution->linkStory, "id='toTaskButton'", 'btn btn-primary');?></span>
<?php $disabled = empty(array_filter($allPlans)) ? 'disabled' : ''?>
<span class='input-group-btn'><?php echo html::commonButton($lang->execution->linkStory, "id='toTaskButton'", 'btn btn-primary ' . $disabled);?></span>
</div>
</div>
</div>
+1 -1
View File
@@ -131,7 +131,7 @@ class file extends control
{
echo(js::alert($this->lang->file->accessDenied));
if(isonlybody()) return print(js::reload('parent.parent'));
return print(js::locate(helper::createLink('my', 'index')));
return print(js::locate(helper::createLink('my', 'index'), 'parent.parent'));
}
/* Judge the mode, down or open. */
+4 -1
View File
@@ -962,7 +962,10 @@ EOF;
}
else
{
$this->lang->my->auditMenu->audit = $this->my->getReviewingTypeList();
$typeList = $this->my->getReviewingTypeList();
if(!isset($typeList->$browseType)) $browseType = 'all';
$this->lang->my->auditMenu->audit = $typeList;
$reviewList = $this->my->getReviewingList($browseType, $orderBy, $pager);
}
+6 -8
View File
@@ -1006,7 +1006,7 @@ class myModel extends model
if($this->getReviewingCases('id_desc', true)) $typeList[] = 'testcase';
if($this->getReviewingApprovals('id_desc', true)) $typeList[] = 'project';
if($this->getReviewingFeedbacks('id_desc', true)) $typeList[] = 'feedback';
$typeList = array_merge($typeList, $this->getReviewingOA('status', true));
if($this->getReviewingOA('status', true)) $typeList[] = 'oa';
$typeList = array_merge($typeList, $this->getReviewingFlows('all', 'id_desc', true));
$flows = ($this->config->edition == 'open') ? array() : $this->dao->select('module,name')->from(TABLE_WORKFLOW)->where('module')->in($typeList)->andWhere('buildin')->eq(0)->fetchPairs('module', 'name');
@@ -1038,7 +1038,7 @@ class myModel extends model
if($browseType == 'all' or $browseType == 'project') $reviewList = array_merge($reviewList, $this->getReviewingApprovals());
if($browseType == 'all' or $browseType == 'feedback') $reviewList = array_merge($reviewList, $this->getReviewingFeedbacks());
if($browseType == 'all' or $browseType == 'oa') $reviewList = array_merge($reviewList, $this->getReviewingOA());
if($browseType == 'all' or !in_array($browseType, array('story', 'testcase', 'project', 'feedback', 'oa'))) $reviewList = array_merge($reviewList, $this->getReviewingFlows($browseType));
if($browseType == 'all' or !in_array($browseType, array('story', 'testcase', 'feedback', 'oa'))) $reviewList = array_merge($reviewList, $this->getReviewingFlows($browseType));
if(empty($reviewList)) return array();
@@ -1175,7 +1175,7 @@ class myModel extends model
$data = new stdclass();
$data->id = $review->id;
$data->title = $review->title;
$data->type = 'project';
$data->type = 'projectreview';
$data->time = $review->createdDate;
$data->status = $review->status;
$reviewList[] = $data;
@@ -1242,7 +1242,7 @@ class myModel extends model
$data->title = (empty($titleFieldName) or !isset($object->$titleFieldName)) ? $title . " #{$object->id}" : $object->$titleFieldName;
$data->type = $objectType;
$data->time = $object->$openedDateField;
$data->status = (isset($object->status) and !isset($flows[$objectType])) ? $object->status : 'doing';
$data->status = 'doing';
$approvalList[] = $data;
}
}
@@ -1310,12 +1310,10 @@ class myModel extends model
if($checkExists)
{
$typeList = array();
foreach($oa as $type => $reviewings)
{
if(!empty($reviewings)) $typeList[$type] = true;
if(!empty($reviewings)) return true;
}
return array_keys($typeList);
}
$reviewList = array();
@@ -1423,7 +1421,7 @@ class myModel extends model
$review->status = $objectType == 'attend' ? $object->reviewStatus : ((isset($object->status) and !isset($flows[$objectType])) ? $object->status : 'done');
if(strpos($review->result, ',') !== false) list($review->result) = explode(',', $review->result);
if($review->type == 'review') $review->type = 'project';
if($review->type == 'review') $review->type = 'projectreview';
if($review->type == 'case') $review->type = 'testcase';
$review->title = '';
if(isset($object->title))
+7 -2
View File
@@ -53,17 +53,22 @@
<?php foreach($reviewList as $review):?>
<?php
$type = $review->type;
if($type == 'project') $type = 'review';
if($type == 'projectreview') $type = 'review';
$typeName = '';
if(isset($lang->{$review->type}->common)) $typeName = $lang->{$review->type}->common;
if($type == 'story') $typeName = $lang->my->auditMenu->audit->story;
if($review->type == 'projectreview') $typeName = $lang->project->common;
if(isset($flows[$review->type])) $typeName = $flows[$review->type];
$statusList = array();
if(isset($lang->$type->statusList)) $statusList = $lang->$type->statusList;
if($type == 'attend') $statusList = $lang->attend->reviewStatusList;
if(isset($flows[$review->type])) $statusList = $lang->approval->statusList;
if(!in_array($type, array('story', 'testcase', 'feedback', 'review')) and strpos(",{$config->my->oaObjectType},", ",$type,") === false)
{
if($rawMethod == 'audit') $statusList = $lang->approval->nodeList;
if(isset($flows[$review->type])) $statusList = $rawMethod == 'audit' ? $lang->approval->nodeList : $lang->approval->statusList;
}
?>
<tr>
<td class='c-id'><?php echo $review->id?></td>
+3 -3
View File
@@ -257,7 +257,7 @@ class product extends control
$this->products = $this->product->getProducts($projectID, 'all', '', false);
$projectProducts = $this->product->getProducts($projectID);
$productPlans = $this->execution->getPlans($projectProducts, 'skipParent', $projectID);
$productPlans = $this->execution->getPlans($projectProducts, 'skipParent,unexpired,noclosed', $projectID);
if($browseType == 'bybranch') $param = $branchID;
$stories = $this->story->getExecutionStories($projectID, $productID, $branchID, $sort, $browseType, $param, $storyType, '', $pager);
@@ -356,7 +356,7 @@ class product extends control
$this->view->productName = $productName;
$this->view->moduleID = $moduleID;
$this->view->stories = $stories;
$this->view->plans = $this->loadModel('productplan')->getPairs($productID, ($branch === 'all' or empty($branch)) ? '' : $branch, 'unexpired', true);
$this->view->plans = $this->loadModel('productplan')->getPairs($productID, ($branch === 'all' or empty($branch)) ? '' : $branch, 'unexpired,noclosed', true);
$this->view->productPlans = isset($productPlans) ? array(0 => '') + $productPlans : array();
$this->view->summary = $this->product->summary($stories, $storyType);
$this->view->moduleTree = $moduleTree;
@@ -1056,7 +1056,7 @@ class product extends control
$param = strtolower($param);
if(strpos($param, 'forstory') === false)
{
$plans = $this->loadModel('productplan')->getPairs($productID, $branch, $expired, strpos($param, 'skipparent') !== false);
$plans = $this->loadModel('productplan')->getPairs($productID, empty($branch) ? 'all' : $branch, $expired, strpos($param, 'skipparent') !== false);
}
else
{
+14 -2
View File
@@ -1578,7 +1578,13 @@ class productModel extends model
if($plan->parent > 0 and isset($parents[$plan->parent])) $plan->title = $parents[$plan->parent] . ' / ' . $plan->title;
$year = substr($plan->end, 0, 4);
$roadmap[$year][$plan->branch][] = $plan;
$branchIdList = explode(',', trim($plan->branch, ','));
$branchIdList = array_unique($branchIdList);
foreach($branchIdList as $branchID)
{
if($branchID === '') continue;
$roadmap[$year][$branchID][] = $plan;
}
$total++;
if($count > 0 and $total >= $count) return $this->processRoadmap($roadmap);
@@ -1595,7 +1601,13 @@ class productModel extends model
foreach($releases as $release)
{
$year = substr($release->date, 0, 4);
$roadmap[$year][$release->branch][] = $release;
$branchIdList = explode(',', trim($release->branch, ','));
$branchIdList = array_unique($branchIdList);
foreach($branchIdList as $branchID)
{
if($branchID === '') continue;
$roadmap[$year][$branchID][] = $release;
}
$total++;
if($count > 0 and $total >= $count) return $this->processRoadmap($roadmap);
+3 -2
View File
@@ -605,7 +605,7 @@ class productplan extends control
*/
public function ajaxGetProductplans($productID, $branch = 0, $number = '', $expired = '')
{
$plans = $this->productplan->getPairs($productID, $branch, $expired, true);
$plans = $this->productplan->getPairs($productID, empty($branch) ? '' : $branch, $expired, true);
$planName = $number === '' ? 'plan' : "plan[$number]";
$plans = empty($plans) ? array('' => '') : $plans;
echo html::select($planName, $plans, '', "class='form-control'");
@@ -1030,11 +1030,12 @@ class productplan extends control
$parentPlan = $this->productplan->getByID($parentID);
foreach(explode(',', $parentPlan->branch) as $parentBranchID)
{
if(!isset($branchPairs[$parentBranchID])) continue;
$parentBranches[$parentBranchID] = $branchPairs[$parentBranchID];
if(!empty($currentBranches) and strpos(",$currentBranches,", ",$parentBranchID,") === false) $currentBranches = str_replace(",$parentBranchID,", ',', $currentBranches);
}
}
return print(html::select('branch[]', empty($parentID) ? $branchPairs : $parentBranches, trim($currentBranches, ','), "class='form-control chosen' multiple required"));
return print(html::select('branch[]', empty($parentID) ? $branchPairs : $parentBranches, trim($currentBranches, ','), "class='form-control chosen' multiple"));
}
/**
+3 -2
View File
@@ -17,11 +17,12 @@ td.c-branch {overflow: hidden; text-align: left !important; white-space: nowrap;
@-moz-document url-prefix() {.main-table tbody > tr.table-children > td:first-child::before {width: 4px;};}
.c-title {width: 160px;}
.c-branch {width: 100px;}
.c-branch {width: 130px;}
.c-story, .c-status {width: 80px;}
.c-execution {width: 60px !important;}
.c-bug, .c-hour {width: 60px;}
.c-desc {width: 160px;}
.c-desc {width: 140px;}
.c-date {width: 90px;}
.plan-name {position: relative; display: flex; align-items: center;}
.plan-name > span {flex: none;}
-1
View File
@@ -100,7 +100,6 @@ $lang->productplan->childrenAB = "C";
$lang->productplan->order = "Rank";
$lang->productplan->deleted = "Deleted";
$lang->productplan->mailto = "Mailto";
$lang->productplan->status = 'Status';
$lang->productplan->planStatus = "Status";
$lang->productplan->statusList['wait'] = 'Wait';
-1
View File
@@ -100,7 +100,6 @@ $lang->productplan->childrenAB = "C";
$lang->productplan->order = "Order";
$lang->productplan->deleted = "Deleted";
$lang->productplan->mailto = "Mailto";
$lang->productplan->status = "Plan Status";
$lang->productplan->planStatus = "Status";
$lang->productplan->statusList['wait'] = 'Wait';
-1
View File
@@ -100,7 +100,6 @@ $lang->productplan->childrenAB = "C";
$lang->productplan->order = "Order";
$lang->productplan->deleted = "Deleted";
$lang->productplan->mailto = "Mailto";
$lang->productplan->status = 'Status';
$lang->productplan->planStatus = "Status";
$lang->productplan->statusList['wait'] = 'Wait';
+1 -2
View File
@@ -86,7 +86,7 @@ $lang->productplan->title = '名称';
$lang->productplan->desc = '描述';
$lang->productplan->begin = '开始日期';
$lang->productplan->end = '结束日期';
$lang->productplan->status = '计划状态';
$lang->productplan->status = '状态';
$lang->productplan->last = "上次计划";
$lang->productplan->future = '待定';
$lang->productplan->stories = "{$lang->SRCommon}数";
@@ -100,7 +100,6 @@ $lang->productplan->childrenAB = "子";
$lang->productplan->order = "排序";
$lang->productplan->deleted = "已删除";
$lang->productplan->mailto = "抄送给";
$lang->productplan->status = "计划状态";
$lang->productplan->planStatus = "状态";
$lang->productplan->statusList['wait'] = '未开始';
+40 -1
View File
@@ -460,16 +460,34 @@ class productplanModel extends model
*
* @param int $productID
* @param array $branches
* @param string $param
* @param bool $skipParent
* @access public
* @return array
*/
public function getBranchPlanPairs($productID, $branches = '', $skipParent = false)
public function getBranchPlanPairs($productID, $branches = '', $param = '', $skipParent = false)
{
$branchQuery = '';
if($branches !== '' and $branches !== 'all')
{
$branchQuery .= '(';
if(!is_array($branches)) $branches = explode(',', $branches);
foreach($branches as $branchID)
{
$branchQuery .= "CONCAT(',', branch, ',') LIKE '%,$branchID,%'";
if($branchID != end($branches)) $branchQuery .= ' OR ';
}
$branchQuery .= ')';
}
$date = date('Y-m-d');
$param = strtolower($param);
$plans = $this->dao->select('parent,branch,id,title,begin,end')->from(TABLE_PRODUCTPLAN)
->where('product')->eq($productID)
->andWhere('deleted')->eq(0)
->beginIF(!empty($branchQuery))->andWhere($branchQuery)->fi()
->beginIF($branches != '')->andWhere('branch')->in($branches)->fi()
->beginIF(strpos($param, 'unexpired') !== false)->andWhere('end')->ge($date)->fi()
->orderBy('begin desc')
->fetchAll('id');
@@ -482,6 +500,7 @@ class productplanModel extends model
if($plan->parent > 0 and isset($plans[$plan->parent])) $plan->title = $plans[$plan->parent]->title . ' /' . $plan->title;
$planPairs[$branch][$planID] = $plan->title . ' [' . $plan->begin . '~' . $plan->end . ']';
if($branch !== BRANCH_MAIN) $planPairs[BRANCH_MAIN][$planID] = $plan->title . ' [' . $plan->begin . '~' . $plan->end . ']';
}
}
return $planPairs;
@@ -1355,4 +1374,24 @@ class productplanModel extends model
if(!empty($unlinkBugs)) $this->dao->update(TABLE_BUG)->set('plan')->eq(0)->where('plan')->eq($plan->parent)->andWhere('id')->in($unlinkBugs)->exec();
$this->dao->update(TABLE_BUG)->set('plan')->eq($plan->id)->where('plan')->eq($plan->parent)->exec();
}
/**
* Get plan list by ids.
*
* @param array $planIds
* @param boo $order
* @access public
* @return array
*/
public function getListByIds($planIds, $order = false)
{
$plans = $this->dao->select('*')->from(TABLE_PRODUCTPLAN)
->where('id')->in($planIds)
->orderBy('begin desc')
->fetchAll('id');
if($order) $plans = $this->relationBranch($plans);
return $plans;
}
}
+1 -1
View File
@@ -23,7 +23,7 @@
<tr class='text-center'>
<th class='c-id'><?php echo $lang->productplan->id?></th>
<?php if($product->type != 'normal'):?>
<th class='c-branch'><?php echo $lang->product->branch;?></th>
<th class='required c-branch'><?php echo $lang->product->branch;?></th>
<?php endif;?>
<th class='required'><?php echo $lang->productplan->title?></th>
<th class='c-status'><?php echo $lang->productplan->status?></th>
+1 -1
View File
@@ -55,7 +55,7 @@
}
}
?>
<td><?php echo html::select('branch[]', $branches, '', "class='form-control chosen' multiple required");?></td><td></td><td></td>
<td class='required'><?php echo html::select('branch[]', $branches, '', "class='form-control chosen' multiple");?></td><td></td><td></td>
</tr>
<?php endif;?>
<tr>
+1 -1
View File
@@ -43,7 +43,7 @@
<?php if(!$product->shadow and $product->type != 'normal' and $plan->parent != '-1'):?>
<tr>
<th><?php echo $lang->product->branch;?></th>
<td><?php echo html::select('branch[]', $branchTagOption, $plan->branch, "class='form-control chosen' multiple");?></td><td></td><td></td>
<td class='required'><?php echo html::select('branch[]', $branchTagOption, $plan->branch, "class='form-control chosen' multiple");?></td><td></td><td></td>
</tr>
<?php endif;?>
<tr>
-3
View File
@@ -31,9 +31,6 @@
<div class='page-title'>
<span class='label label-id'><?php echo $plan->id;?></span>
<span title='<?php echo $plan->title;?>' class='text'><?php echo $plan->title;?></span>
<?php foreach(explode(',', $branch) as $branchID):?>
<?php if($product->type !== 'normal') echo "<span title='{$lang->product->branchName[$product->type]}' class='label label-branch label-badge'>" . $branchOption[$branchID] . '</span>';?>
<?php endforeach;?>
<span class='label label-info label-badge'>
<?php echo ($plan->begin == $config->productplan->future || $plan->end == $config->productplan->future) ? $lang->productplan->future : $plan->begin . '~' . $plan->end;?>
</span>
+19 -3
View File
@@ -739,7 +739,7 @@ class project extends control
{
$linkedBranchList[$branchID] = $branchID;
if($branch != BRANCH_MAIN) $productPlans[$productID] = isset($plans[$productID][BRANCH_MAIN]) ? $plans[$productID][BRANCH_MAIN] : array();
if(!isset($productPlans[$productID])) $productPlans[$productID] = isset($plans[$productID][BRANCH_MAIN]) ? $plans[$productID][BRANCH_MAIN] : array();
$productPlans[$productID] += isset($plans[$productID][$branchID]) ? $plans[$productID][$branchID] : array();
if(!empty($projectStories[$productID][$branchID]) or !empty($projectBranches[$productID][$branchID]))
@@ -751,6 +751,17 @@ class project extends control
}
}
$productPlansOrder = array();
foreach($productPlans as $productID => $plan)
{
$orderPlans = $this->loadModel('productPlan')->getListByIds(array_keys($plan), true);
$orderPlansMap = array_keys($orderPlans);
foreach($orderPlansMap as $planMapID)
{
$productPlansOrder[$productID][$planMapID] = $productPlans[$productID][$planMapID];
}
}
if($project->model != 'kanban') $canChangeModel = $this->project->checkCanChangeModel($projectID, $project->model);
$this->view->title = $this->lang->project->edit;
@@ -764,7 +775,7 @@ class project extends control
$this->view->projectID = $projectID;
$this->view->allProducts = array('0' => '') + $allProducts;
$this->view->multiBranchProducts = $this->loadModel('product')->getMultiBranchPairs();
$this->view->productPlans = array_filter($productPlans);
$this->view->productPlans = array_filter($productPlansOrder);
$this->view->linkedProducts = $linkedProducts;
$this->view->branches = $branches;
$this->view->executions = $this->execution->getPairs($projectID);
@@ -1466,8 +1477,13 @@ class project extends control
{
$showBranch = true;
$branchPairs = $branchGroups[$build->product];
foreach(explode(',', trim($build->branch, ',')) as $branchID) $build->branchName .= "{$branchPairs[$branchID]},";
foreach(explode(',', trim($build->branch, ',')) as $branchID)
{
if(isset($branchPairs[$branchID])) $build->branchName .= "{$branchPairs[$branchID]},";
}
$build->branchName = trim($build->branchName, ',');
if(empty($build->branchName) and empty($build->builds)) $build->branchName = $this->lang->branch->main;
}
}
}
-11
View File
@@ -189,17 +189,6 @@ function setParentProgram(parentProgram)
});
$('#parent').attr('data-lastSelected', parentProgram);
if(parentProgram != '0')
{
$('.productsBox .addProduct .input-group:first').addClass('required');
$('.productsBox .row .input-group:first').addClass('required');
}
else
{
$('.productsBox .addProduct .input-group').removeClass('required');
$('.productsBox .row .input-group').removeClass('required');
}
}
/**
+23 -4
View File
@@ -52,7 +52,7 @@
<?php if($project->hasProduct):?>
<th class="c-name w-150px text-left"><?php echo $lang->build->product;?></th>
<?php if($showBranch):?>
<th class="c-name w-150px text-left"><?php echo $lang->build->branch;?></th>
<th class="c-name w-200px text-left"><?php echo $lang->build->branch;?></th>
<?php endif;?>
<?php endif;?>
<?php if($project->multiple):?>
@@ -84,7 +84,12 @@
<?php endif;?>
<?php if($project->multiple):?>
<?php if($build->execution):?>
<td class="c-name text-left" title='<?php echo $build->executionName;?>'><?php echo $build->executionName;?></td>
<td class="c-name text-left" title='<?php echo $build->executionName;?>'>
<?php echo $build->executionName;?>
<?php if($build->executionDeleted):?>
<span class='label label-danger'><?php echo $lang->build->deleted;?></span>
<?php endif; ?>
</td>
<?php else:?>
<td class="c-name text-left">
<?php $childExecutions = array();?>
@@ -103,8 +108,22 @@
<?php endif;?>
<td class="c-url text-left">
<?php
if($build->scmPath) echo "<div><i class='icon icon-file-code' title='{$lang->build->scmPath}'></i> <span title='{$build->scmPath}'>" . (strpos($build->scmPath, 'http') === 0 ? html::a($build->scmPath, $build->scmPath, '_blank') : $build->scmPath) . '</span></div>';
if($build->filePath) echo "<div><i class='icon icon-file-archive' title='{$lang->build->filePath}'></i> <span title='{$build->filePath}'>" . (strpos($build->filePath, 'http') === 0 ? html::a($build->filePath, $build->filePath, '_blank') : $build->filePath) . '</span></div>';
if($build->scmPath)
{
$colorStyle = strpos($build->scmPath, 'http') === 0 ? "style='color:#2463c7;'" : '';
echo "<div><i class='icon icon-file-code' $colorStyle title='{$lang->build->scmPath}'></i> ";
echo "<span title='{$build->scmPath}'>";
echo $colorStyle ? html::a($build->scmPath, $build->scmPath, '_blank', $colorStyle) : $build->scmPath;
echo '</span></div>';
}
if($build->filePath)
{
$colorStyle = strpos($build->filePath, 'http') === 0 ? "style='color:#2463c7;'" : '';
echo "<div><i class='icon icon-download' $colorStyle title='{$lang->build->filePath}'></i> ";
echo "<span title='{$build->filePath}'>";
echo $colorStyle ? html::a($build->filePath, $build->filePath, '_blank', $colorStyle) : $build->filePath;
echo '</span></div>';
}
?>
</td>
<td class="c-date"><?php echo $build->date?></td>
+16 -3
View File
@@ -87,6 +87,16 @@ class projectrelease extends control
$releases = $this->projectrelease->getList($projectID, $type, $orderBy, $pager);
$showBranch = false;
foreach($releases as $release)
{
if($release->productType != 'normal')
{
$showBranch = true;
break;
}
}
$this->view->title = $objectName . $this->lang->colon . $this->lang->release->browse;
$this->view->execution = $execution;
$this->view->project = $project;
@@ -97,6 +107,7 @@ class projectrelease extends control
$this->view->type = $type;
$this->view->from = $this->app->tab;
$this->view->pager = $pager;
$this->view->showBranch = $showBranch;
$this->display();
}
@@ -133,10 +144,10 @@ class projectrelease extends control
$this->commonAction($projectID);
/* Get the builds that can select. */
$builds = $this->build->getBuildPairs($this->view->product->id, $this->view->branch, 'notrunk|withbranch|hasproject', $projectID, 'project', '', false);
$builds = $this->build->getBuildPairs($this->view->product->id, 'all', 'notrunk|withbranch|hasproject', $projectID, 'project', '', false);
$releasedBuilds = $this->projectrelease->getReleasedBuilds($projectID);
foreach($releasedBuilds as $build) unset($builds[$build]);
$this->view->title = $this->view->project->name . $this->lang->colon . $this->lang->release->create;
$this->view->projectID = $projectID;
$this->view->builds = $builds;
@@ -263,6 +274,7 @@ class projectrelease extends control
foreach($stages as $storyID => $stage) $stories[$storyID]->stage = $stage;
$bugPager = new pager($type == 'bug' ? $recTotal : 0, $recPerPage, $type == 'bug' ? $pageID : 1);
$sort = common::appendOrder($orderBy);
$bugs = $this->dao->select('*')->from(TABLE_BUG)
->where('id')->in($release->bugs)
->andWhere('deleted')->eq(0)
@@ -271,8 +283,9 @@ class projectrelease extends control
->fetchAll();
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'linkedBug');
$leftBugPager = new pager($type == 'leftBug' ? $recTotal : 0, $recPerPage, $type == 'leftBug' ? $pageID : 1);
$sort = common::appendOrder($orderBy);
if($type == 'leftBug' and strpos($orderBy, 'severity_') !== false) $sort = str_replace('severity_', 'severityOrder_', $sort);
$leftBugPager = new pager($type == 'leftBug' ? $recTotal : 0, $recPerPage, $type == 'leftBug' ? $pageID : 1);
$leftBugs = $this->dao->select("*, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)
->where('id')->in($release->leftBugs)
+1
View File
@@ -9,3 +9,4 @@
#tabsNav .nav-tabs > li.active + li.pull-right {margin-right: 0;}
ol, ul {padding-left: 20px;}
.c-id {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
td.c-build{white-space: nowrap; overflow:hidden;}
+4 -15
View File
@@ -35,20 +35,9 @@ class projectreleaseModel extends model
$release->branch = trim($release->branch, ',');
$release->build = trim($release->build, ',');
$builds = $this->dao->select('id, branch, filePath, scmPath, name, execution, project')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll();
/* Get release's branches by build. */
$branches = array();
if($release->productType != 'normal')
{
foreach($builds as $build)
{
$branchIdList = explode(',', $build->branch);
foreach($branchIdList as $branchID) $branches[$branchID] = $branchID;
}
}
$release->branches = $branches;
$release->branches = array();
$branchIdList = explode(',', $release->branch);
foreach($branchIdList as $branchID) $release->branches[$branchID] = $branchID;
$this->loadModel('file');
$release = $this->file->replaceImgURL($release, 'desc');
@@ -70,7 +59,7 @@ class projectreleaseModel extends model
*/
public function getList($projectID, $type = 'all', $orderBy = 't1.date_desc', $pager = null)
{
$releases = $this->dao->select('t1.*, t2.name as productName')->from(TABLE_RELEASE)->alias('t1')
$releases = $this->dao->select('t1.*, t2.name as productName, t2.type as productType')->from(TABLE_RELEASE)->alias('t1')
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id')
->where('t1.deleted')->eq(0)
->andWhere("FIND_IN_SET($projectID, t1.project)")
@@ -53,7 +53,9 @@
<th class='c-product'><?php echo $lang->projectrelease->product;?></th>
<?php endif;?>
<th class='c-build'><?php echo $lang->release->includedBuild;?></th>
<?php if($showBranch):?>
<th class='c-branch text-center'><?php echo $lang->release->branch;?></th>
<?php endif;?>
<th class='c-status text-center'><?php echo $lang->release->status;?></th>
<th class='c-date text-center'><?php echo $lang->release->date;?></th>
<?php
@@ -88,7 +90,9 @@
<td class='c-build'><?php if($buildCount) echo html::a($this->createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$buildID"), $build->name, '', "data-app='project' title='{$build->name}'");?></td>
<?php if($i == 0):?>
<?php $status = $this->processStatus('release', $release);?>
<?php if($showBranch):?>
<td <?php echo $rowspan?> class='c-branch text-center'><?php echo $release->branchName; ?></td>
<?php endif;?>
<td <?php echo $rowspan?> class='c-status text-center' title='<?php echo $status;?>'>
<span class="status-release status-<?php echo $release->status?>"><?php echo $status;?></span>
</td>
+10 -10
View File
@@ -99,7 +99,7 @@
echo html::a($storyLink,$story->title, '', "class='preview'");
?>
</td>
<td class='text-left' title='<?php echo $story->buildName?>'><?php echo $story->buildName?></td>
<td class='c-build text-left' title='<?php echo $story->buildName?>'><?php echo $story->buildName?></td>
<td><?php echo zget($users, $story->openedBy);?></td>
<td class='text-right' style='padding-right:25px' title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit;?></td>
<td>
@@ -195,7 +195,7 @@
<span class='status-bug status-<?php echo $bug->status?>'><?php echo $this->processStatus('bug', $bug);?></span>
</td>
<?php $resolvedBuildName = zget($builds, $bug->resolvedBuild, '');?>
<td class='text-left' title='<?php echo $resolvedBuildName?>'><?php echo $resolvedBuildName;?></td>
<td class='c-build text-left' title='<?php echo $resolvedBuildName?>'><?php echo $resolvedBuildName;?></td>
<td><?php echo zget($users, $bug->openedBy);?></td>
<td><?php echo helper::isZeroDate($bug->openedDate) ? '' : substr($bug->openedDate, 5, 11);?></td>
<td><?php echo zget($users, $bug->resolvedBy);?></td>
@@ -305,7 +305,7 @@
$openedBuildName = '';
foreach(explode(',', $bug->openedBuild) as $buildID) $openedBuildName .= zget($builds, $buildID, '') . ' ';
?>
<td class='text-left' title='<?php echo $openedBuildName?>'><?php echo $openedBuildName;?></td>
<td class='c-build text-left' title='<?php echo $openedBuildName?>'><?php echo $openedBuildName;?></td>
<td><?php echo zget($users, $bug->openedBy);?></td>
<td><?php echo $bug->openedDate?></td>
<td class='c-actions'>
@@ -349,12 +349,6 @@
<th class='w-100px'><?php echo $lang->release->product;?></th>
<td><?php echo $release->productName;?></td>
</tr>
<?php if($release->productType != 'normal'):?>
<tr>
<th><?php echo sprintf($lang->product->branch, $lang->product->branchName[$product->type]);?></th>
<td><?php echo $branchName;?></td>
</tr>
<?php endif;?>
<?php endif;?>
<tr>
<th class='w-90px'><?php echo $lang->release->name;?></th>
@@ -377,7 +371,13 @@
<tr>
<th><?php echo $lang->release->branch;?></th>
<td>
<?php foreach($release->branches as $branchID) echo zget($branches, $branchID, '') . ' ';?>
<?php
foreach($release->branches as $branchID)
{
echo zget($branches, $branchID, '');
if($branchID != end($release->branches)) echo ', ';
}
?>
</td>
</tr>
<?php endif;?>
+15 -2
View File
@@ -50,12 +50,23 @@ class release extends control
$uri = $this->app->getURI(true);
$this->session->set('releaseList', $uri, 'product');
$this->session->set('buildList', $uri);
$releases = $this->release->getList($productID, $branch, $type, $orderBy, $pager);
$showBranch = false;
foreach($releases as $release)
{
if($release->productType != 'normal')
{
$showBranch = true;
break;
}
}
$this->view->title = $this->view->product->name . $this->lang->colon . $this->lang->release->browse;
$this->view->position[] = $this->lang->release->browse;
$this->view->releases = $this->release->getList($productID, $branch, $type, $orderBy, $pager);
$this->view->releases = $releases;
$this->view->type = $type;
$this->view->pager = $pager;
$this->view->showBranch = $showBranch;
$this->display();
}
@@ -199,6 +210,7 @@ class release extends control
foreach($stages as $storyID => $stage) $stories[$storyID]->stage = $stage;
$bugPager = new pager($type == 'bug' ? $recTotal : 0, $recPerPage, $type == 'bug' ? $pageID : 1);
$sort = common::appendOrder($orderBy);
$bugs = $this->dao->select('*')->from(TABLE_BUG)
->where('id')->in($release->bugs)
->andWhere('deleted')->eq(0)
@@ -207,8 +219,9 @@ class release extends control
->fetchAll();
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'linkedBug');
$leftBugPager = new pager($type == 'leftBug' ? $recTotal : 0, $recPerPage, $type == 'leftBug' ? $pageID : 1);
$sort = common::appendOrder($orderBy);
if($type == 'leftBug' and strpos($orderBy, 'severity_') !== false) $sort = str_replace('severity_', 'severityOrder_', $sort);
$leftBugPager = new pager($type == 'leftBug' ? $recTotal : 0, $recPerPage, $type == 'leftBug' ? $pageID : 1);
$leftBugs = $this->dao->select("*, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)
->where('id')->in($release->leftBugs)
+1
View File
@@ -10,3 +10,4 @@
ol, ul {padding-left: 20px;}
.body-modal #mainContent {min-height: 240px;}
.c-id {width: 110px;}
td.c-build{white-space: nowrap; overflow:hidden;}
+24 -18
View File
@@ -31,21 +31,11 @@ class releaseModel extends model
->fetch();
if(!$release) return false;
$builds = $this->dao->select('id, branch, filePath, scmPath, name, execution, project')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll();
$release->builds = $this->dao->select('id, branch, filePath, scmPath, name, execution, project')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll();
/* Get release's branches by build. */
$branches = array();
if($release->productType != 'normal')
{
foreach($builds as $build)
{
$branchIdList = explode(',', $build->branch);
foreach($branchIdList as $branchID) $branches[$branchID] = $branchID;
}
}
$release->builds = $builds;
$release->branches = $branches;
$release->branches = array();
$branchIdList = explode(',', trim($release->branch, ','));
foreach($branchIdList as $branchID) $release->branches[$branchID] = $branchID;
$this->loadModel('file');
$release = $this->file->replaceImgURL($release, 'desc');
@@ -68,7 +58,7 @@ class releaseModel extends model
*/
public function getList($productID, $branch = 'all', $type = 'all', $orderBy = 't1.date_desc', $pager = null)
{
$releases = $this->dao->select('t1.*, t2.name as productName')->from(TABLE_RELEASE)->alias('t1')
$releases = $this->dao->select('t1.*, t2.name as productName, t2.type as productType')->from(TABLE_RELEASE)->alias('t1')
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id')
->where('t1.deleted')->eq(0)
->beginIF($productID)->andWhere('t1.product')->eq((int)$productID)->fi()
@@ -94,8 +84,19 @@ class releaseModel extends model
$releaseBuilds[] = $builds[$buildID];
}
$release->builds = $releaseBuilds;
$branchName = '';
if($release->branch != 'normal')
{
foreach(explode(',', $release->branch) as $releaseBranch)
{
$branchName .= $this->loadModel('branch')->getById($releaseBranch);
$branchName .= ',';
}
$branchName = trim($branchName, ',');
}
$release->branchName = empty($branchName) ? $this->lang->branch->main : $branchName;
}
return $releases;
@@ -234,6 +235,7 @@ class releaseModel extends model
$linkedBuilds = array_merge($linkedBuilds, explode(',', $build->builds));
}
if($linkedBuilds) $builds += $this->dao->select('id,project,branch,builds,stories,bugs')->from(TABLE_BUILD)->where('id')->in($linkedBuilds)->fetchAll('id');
$branches = array();
foreach($builds as $build)
{
foreach(explode(',', $build->branch) as $buildBranch)
@@ -338,10 +340,14 @@ class releaseModel extends model
/* update release project and branch */
if($release->build)
{
$builds = $this->dao->select('project, branch')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll();
$builds = $this->dao->select('project, branch')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll();
$branches = array();
foreach($builds as $build)
{
$branches[$build->branch] = $build->branch;
foreach(explode(',', $build->branch) as $buildBranch)
{
if(!isset($branches[$buildBranch])) $branches[$buildBranch] = $buildBranch;
}
$projects[$build->project] = $build->project;
}
$release->build = ',' . trim($release->build, ',') . ',';
+8
View File
@@ -52,6 +52,9 @@
<th class='c-id'><?php echo $lang->release->id;?></th>
<th class="c-name"><?php echo $lang->release->name;?></th>
<th class='c-build'><?php echo $lang->release->includedBuild;?></th>
<?php if($showBranch):?>
<th class="c-name w-200px"><?php echo $lang->release->branch;?></th>
<?php endif;?>
<th class='c-project'><?php echo $lang->release->relatedProject;?></th>
<th class='text-center c-status'><?php echo $lang->release->status;?></th>
<th class='c-date text-center'><?php echo $lang->release->date;?></th>
@@ -98,6 +101,11 @@
?>
<?php endif;?>
</td>
<?php if($i == 1):?>
<?php if($showBranch):?>
<td <?php echo $rowspan?> class='c-branch text-center'><?php echo $release->branchName; ?></td>
<?php endif;?>
<?php endif;?>
<td><?php if($buildCount) echo $build->projectName;?></td>
<?php if($i == 1):?>
<?php $status = $this->processStatus('release', $release);?>
+10 -10
View File
@@ -101,7 +101,7 @@
echo html::a($storyLink,$story->title, '', "class='preview'");
?>
</td>
<td class='text-left' title='<?php echo $story->buildName?>'><?php echo $story->buildName?></td>
<td class='c-build text-left' title='<?php echo $story->buildName?>'><?php echo $story->buildName?></td>
<td><?php echo zget($users, $story->openedBy);?></td>
<td class='text-right' title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit;?></td>
<td class='text-center'>
@@ -197,7 +197,7 @@
<span class='status-bug status-<?php echo $bug->status?>'><?php echo $this->processStatus('bug', $bug);?></span>
</td>
<?php $resolvedBuildName = zget($builds, $bug->resolvedBuild, '');?>
<td class='text-left' title='<?php echo $resolvedBuildName?>'><?php echo $resolvedBuildName;?></td>
<td class='c-build text-left' title='<?php echo $resolvedBuildName?>'><?php echo $resolvedBuildName;?></td>
<td><?php echo zget($users, $bug->openedBy);?></td>
<td><?php echo substr($bug->openedDate, 5, 11)?></td>
<td><?php echo zget($users, $bug->resolvedBy);?></td>
@@ -307,7 +307,7 @@
$openedBuildName = '';
foreach(explode(',', $bug->openedBuild) as $buildID) $openedBuildName .= zget($builds, $buildID, '') . ' ';
?>
<td class='text-left' title='<?php echo $openedBuildName?>'><?php echo $openedBuildName;?></td>
<td class='c-build text-left' title='<?php echo $openedBuildName?>'><?php echo $openedBuildName;?></td>
<td><?php echo zget($users, $bug->openedBy);?></td>
<td><?php echo $bug->openedDate?></td>
<td class='c-actions'>
@@ -350,12 +350,6 @@
<th class='w-100px'><?php echo $lang->release->product;?></th>
<td><?php echo $release->productName;?></td>
</tr>
<?php if($release->productType != 'normal'):?>
<tr>
<th><?php echo $lang->product->branch;?></th>
<td><?php echo $branchName;?></td>
</tr>
<?php endif;?>
<tr>
<th><?php echo $lang->release->name;?></th>
<td><?php echo $release->name;?></td>
@@ -382,7 +376,13 @@
<tr>
<th><?php echo $lang->release->branch;?></th>
<td>
<?php foreach($release->branches as $branchID) echo zget($branches, $branchID, '') . ' ';?>
<?php
foreach($release->branches as $branchID)
{
echo zget($branches, $branchID, '');
if($branchID != end($release->branches)) echo ', ';
}
?>
</td>
</tr>
<?php endif;?>
+7 -4
View File
@@ -263,7 +263,9 @@ class story extends control
}
else
{
$response['locate'] = $this->session->storyList;
$sessionStoryList = $this->session->storyList;
if(count($_POST['branches']) > 1) $sessionStoryList = preg_replace('/branch=(\d+|[A-Za-z]+)/', 'branch=all', $this->session->storyList);
$response['locate'] = $sessionStoryList;
}
}
}
@@ -691,7 +693,7 @@ class story extends control
}
$this->view->titles = $titles;
}
$plans = $this->loadModel('productplan')->getPairsForStory($productID, ($branch === 'all' or !in_array($branch, array_keys($branches))) ? 0 : $branch, 'skipParent|unexpired|noclosed');
$plans = $this->loadModel('productplan')->getPairsForStory($productID, ($branch === 'all' or empty($branch)) ? '' : $branch, 'skipParent|unexpired|noclosed');
$plans['ditto'] = $this->lang->story->ditto;
$priList = (array)$this->lang->story->priList;
@@ -1064,7 +1066,7 @@ class story extends control
$moduleList = $branchProduct ? $modulePairs : array(0 => $modulePairs);
$modules = array($productID => $moduleList);
$plans = array($productID => $this->productplan->getBranchPlanPairs($productID, '', true));
$plans = array($productID => $this->productplan->getBranchPlanPairs($productID, '', 'unexpired', true));
$products = array($productID => $product);
$branchTagOption = array($productID => $branchTagOption);
}
@@ -1074,6 +1076,7 @@ class story extends control
$modules = array();
$branchTagOption = array();
$products = array();
$plans = array();
/* Get product id list by the stories. */
$productIdList = array();
@@ -1095,7 +1098,7 @@ class story extends control
$modulePairs = $this->tree->getOptionMenu($storyProduct->id, 'story', 0, $branches);
$modules[$storyProduct->id] = $storyProduct->type != 'normal' ? $modulePairs : array(0 => $modulePairs);
$plans[$storyProduct->id] = $this->productplan->getBranchPlanPairs($storyProduct->id, $branches, true);
$plans[$storyProduct->id] = $this->productplan->getBranchPlanPairs($storyProduct->id, $branches, 'unexpired', true);
if(empty($plans[$storyProduct->id])) $plans[$storyProduct->id][0] = $plans[$storyProduct->id];
if($storyProduct->type != 'normal') $branchProduct = true;
+2 -2
View File
@@ -77,11 +77,11 @@ function getStatus(method, params)
* @access public
* @return void
*/
function loadURS()
function loadURS(allURS)
{
var productID = $('#product').val();
var branchID = $('#branch').val();
var moduleID = $('#module').val();
var moduleID = typeof(allURS) == 'undefined' ? $('#module').val() : 0;
var requirementList = $('#URS').val();
requirementList = requirementList ? requirementList.join(',') : '';
+3 -1
View File
@@ -59,7 +59,9 @@ $(function()
return false;
});
$(document).on('change', '#module', loadURS);
$('#module').on('change', function(){
loadURS();
});
if($(".table-form select[id^='branches']").length == $('.switchBranch #branchBox option').length)
{
+2 -1
View File
@@ -80,6 +80,7 @@ $lang->story->currentBranch = 'Current Branch';
$lang->story->siblings = 'Siblings story';
$lang->story->relieved = 'Relieved';
$lang->story->relievedSiblings = 'Relieved Siblings';
$lang->story->loadAllStories = 'Load all stories';
$lang->story->editAction = "Edit {$lang->SRCommon}";
$lang->story->changeAction = "Change Story";
@@ -520,4 +521,4 @@ $lang->requirement->linkStory = 'Link Story';
$lang->story->addBranch = 'Add %s';
$lang->story->deleteBranch = 'Delete %s';
$lang->story->notice->branch = 'Each branch will establish a requirement, and the requirements are twins. The twins requirements are synchronized except for the product, branch, module, plan, and stage fields. You can manually remove the twins relationship later';
$lang->story->notice->branch = 'Each branch will establish a requirement. The requirements are twins. The twins requirements are synchronized except for the product, branch, module, plan, and stage fields. You can manually remove the twins relationship later';
+2 -1
View File
@@ -80,6 +80,7 @@ $lang->story->currentBranch = 'Current Branch';
$lang->story->siblings = 'Siblings story';
$lang->story->relieved = 'Relieved';
$lang->story->relievedSiblings = 'Relieved Siblings';
$lang->story->loadAllStories = 'Load all stories';
$lang->story->editAction = "Edit {$lang->SRCommon}";
$lang->story->changeAction = "Change {$lang->SRCommon}";
@@ -520,4 +521,4 @@ $lang->requirement->linkStory = 'Link Story';
$lang->story->addBranch = 'Add %s';
$lang->story->deleteBranch = 'Delete %s';
$lang->story->notice->branch = 'Each branch will establish a requirement, and the requirements are twins. The twins requirements are synchronized except for the product, branch, module, plan, and stage fields. You can manually remove the twins relationship later';
$lang->story->notice->branch = 'Each branch will establish a requirement. The requirements are twins. The twins requirements are synchronized except for the product, branch, module, plan, and stage fields. You can manually remove the twins relationship later';
+2 -1
View File
@@ -80,6 +80,7 @@ $lang->story->currentBranch = 'Current Branch';
$lang->story->siblings = 'Siblings story';
$lang->story->relieved = 'Relieved';
$lang->story->relievedSiblings = 'Relieved Siblings';
$lang->story->loadAllStories = 'Load all stories';
$lang->story->editAction = "Edit {$lang->SRCommon}";
$lang->story->changeAction = "Changer Story";
@@ -520,4 +521,4 @@ $lang->requirement->linkStory = 'Lier Story';
$lang->story->addBranch = 'Add %s';
$lang->story->deleteBranch = 'Delete %s';
$lang->story->notice->branch = 'Each branch will establish a requirement, and the requirements are twins. The twins requirements are synchronized except for the product, branch, module, plan, and stage fields. You can manually remove the twins relationship later';
$lang->story->notice->branch = 'Each branch will establish a requirement. The requirements are twins. The twins requirements are synchronized except for the product, branch, module, plan, and stage fields. You can manually remove the twins relationship later';
+2 -1
View File
@@ -80,6 +80,7 @@ $lang->story->currentBranch = '当前%s';
$lang->story->siblings = '孪生需求';
$lang->story->relieved = '解除';
$lang->story->relievedSiblings = '解除孪生需求';
$lang->story->loadAllStories = '加载所有需求';
$lang->story->editAction = "编辑{$lang->SRCommon}";
$lang->story->changeAction = "变更{$lang->SRCommon}";
@@ -520,4 +521,4 @@ $lang->requirement->linkStory = "关联{$lang->SRCommon}";
$lang->story->addBranch = '添加%s';
$lang->story->deleteBranch = '删除%s';
$lang->story->notice->branch = '每个分支会建立一个需求,需求间互为孪生关系,孪生需求间除产品、分支、模块、计划、阶段字段外均同步,后期您可以手动解除孪生关系';
$lang->story->notice->branch = '每个分支会建立一个需求,需求间互为孪生关系。孪生需求间除产品、分支、模块、计划、阶段字段外均保持同步,后期您可以手动解除孪生关系。';
+6 -1
View File
@@ -1256,7 +1256,7 @@ class storyModel extends model
if(empty($childrenStatus)) return $this->dao->update(TABLE_STORY)->set('parent')->eq('0')->where('id')->eq($parentID)->exec();
$status = $oldParentStory->status;
if(count($childrenStatus) == 1 and $oldParentStory->status != 'changing')
if(count($childrenStatus) == 1 and $oldParentStory->status != 'changing' and $oldParentStory->status != 'reviewing')
{
$status = current($childrenStatus);
if($status == 'draft' or $status == 'changing') $status = 'active';
@@ -5068,6 +5068,11 @@ class storyModel extends model
$title = isset($story->planTitle) ? $story->planTitle : '';
$class .= ' text-ellipsis';
}
elseif($id == 'branch')
{
$title = zget($branches, $story->branch, '');
$class .= ' text-ellipsis';
}
elseif($id == 'sourceNote')
{
$title = $story->sourceNote;
+6 -1
View File
@@ -204,7 +204,12 @@ foreach(explode(',', $config->story->create->requiredFields) as $field)
<?php if($this->config->URAndSR):?>
<tr>
<th><?php echo $hiddenURS ? $lang->story->parent : $lang->story->requirement;?></th>
<td colspan="2" class="<?php if($hiddenURS) echo 'hidden';?>"><?php echo html::select('URS[]', $URS, '', "class='form-control chosen' multiple");?></td>
<td colspan="2" class="<?php if($hiddenURS) echo 'hidden';?>">
<div class='input-group'>
<?php echo html::select('URS[]', $URS, '', "class='form-control chosen' multiple");?>
<span class='input-group-btn'><?php echo html::commonButton($lang->story->loadAllStories, "class='btn btn-default' onclick='loadURS(true)' data-toggle='tooltip'");?></span>
</div>
</td>
<td colspan="2" <?php if($hiddenParent) echo 'hidden';?>>
<div class='input-group' id='moduleIdBox'>
<?php if(!$hiddenURS):?>
+34
View File
@@ -4357,6 +4357,40 @@ class taskModel extends model
}
}
/**
* Get task list by conditions.
*
* @param object $conds
* @param string $orderBy
* @param object $pager
* @access public
* @return array
*/
public function getListByConds($conds, $orderBy = 'id_desc', $pager = null)
{
foreach(array('priList' => array(), 'assignedToList' => array(), 'statusList' => array(), 'idList' => array(), 'taskName' => '') as $condKey => $defaultValue)
{
if(!isset($conds->$condKey))
{
$conds->$condKey = $defaultValue;
continue;
}
if(strripos($condKey, 'list') === strlen($condKey) - 4 && !is_array($conds->$condKey)) $conds->$condKey = array_filter(explode(',', $conds->$condKey));
}
return $this->dao->select('*')->from(TABLE_TASK)
->where('deleted')->eq(0)
->beginIF(!empty($conds->priList))->andWhere('pri')->in($conds->priList)->fi()
->beginIF(!empty($conds->assignedToList))->andWhere('assignedTo')->in($conds->assignedToList)->fi()
->beginIF(!empty($conds->statusList))->andWhere('status')->in($conds->statusList)->fi()
->beginIF(!empty($conds->idList))->andWhere('id')->in($conds->idList)->fi()
->beginIF(!empty($conds->taskName))->andWhere('name')->like("%{$conds->taskName}%")
->beginIF(!$this->app->user->admin)->andWhere('execution')->in($this->app->user->view->sprints)->fi()
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
}
/**
* Get teamTask members.
*
+3 -3
View File
@@ -1564,9 +1564,9 @@ class testcaseModel extends model
{
$caseID = $this->dao->lastInsertID();
$parentStepID = 0;
if($this->post->desc)
if($data->desc)
{
foreach($this->post->desc[$key] as $id => $desc)
foreach($data->desc[$key] as $id => $desc)
{
$desc = trim($desc);
if(empty($desc)) continue;
@@ -1576,7 +1576,7 @@ class testcaseModel extends model
$stepData->case = $caseID;
$stepData->version = 1;
$stepData->desc = htmlSpecialString($desc);
$stepData->expect = htmlSpecialString($this->post->expect[$key][$id]);
$stepData->expect = htmlSpecialString($data->expect[$key][$id]);
$this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec();
if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID();
if($stepData->type == 'step') $parentStepID = 0;
+3 -3
View File
@@ -250,7 +250,7 @@ class testtask extends control
/* Create testtask from testtask of test.*/
$productID = $productID ? $productID : key($this->products);
$executions = empty($productID) ? array() : $this->loadModel('product')->getExecutionPairsByProduct($productID, '', 'id_desc', $projectID, 'stagefilter');
$builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 'all', 'notrunk,withexecution', $projectID, 'project');
$builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 'all', 'notrunk,withexecution', $projectID, 'project', '', false);
$execution = $this->loadModel('execution')->getByID($executionID);
if(!empty($execution) and $execution->type == 'kanban') $this->lang->testtask->execution = str_replace($this->lang->execution->common, $this->lang->kanban->common, $this->lang->testtask->execution);
@@ -816,11 +816,11 @@ class testtask extends control
$executions[$executionID] = $project->name . "({$this->lang->project->disableExecution})";
}
}
$builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,notrunk,withexecution', $executionID, 'execution');
$builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,notrunk,withexecution', $executionID, 'execution', $task->build, false);
}
else
{
$builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,notrunk,withexecution', $task->project, 'project');
$builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,notrunk,withexecution', $task->project, 'project', $task->build, false);
}
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->edit;
+1 -1
View File
@@ -91,7 +91,7 @@ class testtaskModel extends model
->beginIF($scopeAndStatus[0] == 'all')->andWhere('t1.product')->in($products)->fi()
->beginIF(strtolower($scopeAndStatus[1]) == 'totalstatus')->andWhere('t1.status')->in('blocked,doing,wait,done')->fi()
->beginIF(!in_array(strtolower($scopeAndStatus[1]), array('totalstatus', 'review'), true))->andWhere('t1.status')->eq($scopeAndStatus[1])->fi()
->beginIF($branch !== 'all')->andWhere('t4.branch')->eq($branch)->fi()
->beginIF($branch !== 'all')->andWhere("CONCAT(',', t4.branch, ',')")->like("%,$branch,%")->fi()
->beginIF($beginTime)->andWhere('t1.begin')->ge($beginTime)->fi()
->beginIF($endTime)->andWhere('t1.end')->le($endTime)->fi()
->beginIF($branch == BRANCH_MAIN)
+2 -2
View File
@@ -12,8 +12,8 @@ $config->transfer->fieldList['sort'] = '';
$config->transfer->fieldList['dataSource'] = array('module' => '', 'method' => '', 'params' => '', 'pairs' => '', 'lang' => '');
$config->transfer->initFunction = 'title,control,required,';
$config->transfer->dateFeilds = 'estStarted,realStarted,deadline,openedDate,assignedDate,finishedDate,canceledDate,closedDate,lastEditedDate,';
$config->transfer->datetimeFeilds = '';
$config->transfer->dateFields = 'estStarted,realStarted,deadline,openedDate,assignedDate,finishedDate,canceledDate,closedDate,lastEditedDate,';
$config->transfer->datetimeFields = '';
$config->transfer->listFields = '';
$config->transfer->sysLangFields = ',pri,status,type,mode,severity,os,browser,resolution,confirmed,source,reviewResult,stage,change,category';
$config->transfer->sysDataFields = 'execution,product,user';
+26 -4
View File
@@ -506,10 +506,32 @@ class transferModel extends model
{
$modelData = $this->getDatasByFile($tmpFile);
}
$modelData = $this->processDate($modelData);
if(isset($fields['id'])) unset($fields['id']);
return $modelData;
}
/**
* Process datas, convert date to YYYY-mm-dd, convert datetime to YYYY-mm-dd HH:ii:ss.
*
* @param array $datas
* @access public
* @return array
*/
public function processDate($datas)
{
foreach($datas as $index => $data)
{
foreach($data as $field => $value)
{
if(strpos($this->modelConfig->dateFields, $field) !== false or strpos($this->modelConfig->datetimeFields, $field) !== false) $data->$field = $this->loadModel('common')->formatDate($value);
}
$datas[$index] = $data;
}
return $datas;
}
/**
* Get rows from excel.
*
@@ -830,7 +852,7 @@ class transferModel extends model
$storyDatas = end($stories);
$lastBranch = $storyDatas->branch;
$lastType = $storyDatas->type;
$stories = $this->story->mergePlanTitle($productID , $stories, $lastBranch, $lastType);
$stories = $this->loadModel('story')->mergePlanTitle($productID , $stories, $lastBranch, $lastType);
return $stories;
}
@@ -940,7 +962,7 @@ class transferModel extends model
foreach($data as $field => $cellValue)
{
if(empty($cellValue)) continue;
if(strpos($this->transferConfig->dateFeilds, $field) !== false and helper::isZeroDate($cellValue)) $datas[$key]->$field = '';
if(strpos($this->transferConfig->dateFields, $field) !== false and helper::isZeroDate($cellValue)) $datas[$key]->$field = '';
if(is_array($cellValue)) continue;
if(!empty($fieldList[$field]['from']) and in_array($fieldList[$field]['control'], array('select', 'multiple')))
@@ -1325,8 +1347,8 @@ class transferModel extends model
if(!isset($modelConfig->export)) $modelConfig->export = new stdClass();
if(!isset($modelConfig->import)) $modelConfig->export = new stdClass();
$modelConfig->dateFeilds = isset($modelConfig->dateFeilds) ? $modelConfig->dateFeilds : $transferConfig->dateFeilds;
$modelConfig->datetimeFeilds = isset($modelConfig->datetimeFeilds) ? $modelConfig->datetimeFeilds : $transferConfig->datetimeFeilds;
$modelConfig->dateFields = isset($modelConfig->dateFields) ? $modelConfig->dateFields : $transferConfig->dateFields;
$modelConfig->datetimeFields = isset($modelConfig->datetimeFields) ? $modelConfig->datetimeFields : $transferConfig->datetimeFields;
$modelConfig->sysLangFields = isset($modelConfig->sysLangFields) ? $modelConfig->sysLangFields : $transferConfig->sysLangFields;
$modelConfig->sysDataFields = isset($modelConfig->sysDataFields) ? $modelConfig->sysDataFields : $transferConfig->sysDataFields;
$modelConfig->listFields = isset($modelConfig->listFields) ? $modelConfig->listFields : $transferConfig->listFields;
+11 -2
View File
@@ -390,7 +390,7 @@ class tree extends control
}
else
{
$this->view->optionMenu = $this->tree->getOptionMenu($module->root, $module->type, 0, $module->branch);
$this->view->optionMenu = $this->tree->getOptionMenu($module->root, $module->type, 0, $module->branch, 'noMainBranch');
}
if($type == 'doc') $this->view->libs = $this->loadModel('doc')->getLibs('all', $extra = 'withObject', '', 0, 'book');
@@ -534,8 +534,17 @@ class tree extends control
}
else
{
$optionMenu = $this->tree->getOptionMenu($rootID, $viewType, $rootModuleID, $branch);
$optionMenu = $this->tree->getOptionMenu($rootID, $viewType, $rootModuleID, $branch, $extra);
}
if(strpos($extra, 'excludeModuleID') !== false)
{
list($excludeModule, $noMainBranch) = explode(',', $extra);
parse_str($excludeModule, $output);
$excludeModuleID = $output['excludeModuleID'];
if(isset($optionMenu[$excludeModuleID])) unset($optionMenu[$excludeModuleID]);
}
if($returnType == 'html')
{
//Code for task #5081.
+5 -2
View File
@@ -109,11 +109,14 @@ class treeModel extends model
->andWhere('type')->in($type)
->beginIF($grade)->andWhere('grade')->le($grade)->fi()
->beginIF($startModulePath)->andWhere('path')->like($startModulePath)->fi()
->beginIF($branch !== 'all' and $branch !== '' and $branch !== false)
->beginIF($branch !== 'all' and $branch !== '' and $branch !== false and strpos($param, 'noMainBranch') === false)
->andWhere('(branch')->eq(0)
->orWhere('branch')->eq($branch)
->markRight(1)
->fi()
->beginIF($branch !== 'all' and $branch !== '' and $branch !== false and strpos($param, 'noMainBranch') !== false)
->andWhere('branch')->eq($branch)
->fi()
->beginIF(strpos($param, 'nodeleted') !== false)->andWhere('deleted')->eq(0)->fi()
->orderBy('grade desc, `order`')
->get();
@@ -175,7 +178,7 @@ class treeModel extends model
$treeMenu = array();
foreach($branches as $branchID => $branch)
{
{
$stmt = $this->dbh->query($this->buildMenuQuery($rootID, $type, $startModule, $branchID, $param));
$modules = array();
while($module = $stmt->fetch())
+1 -1
View File
@@ -189,7 +189,7 @@ function loadModules(branch)
if(typeof(branchID) == 'undefined') branchID = 0;
if(typeof(moduleID) == 'undefined') moduleID = 0;
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=story&branch=' + branchID + '&rootModuleID=0&returnType=html&fieldID=&needManage=true&extra=&currentModuleID=' + moduleID);
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=story&branch=' + branchID + '&rootModuleID=0&returnType=html&fieldID=&needManage=true&extra=excludeModuleID=' + <?php echo $module->id;?> + ',noMainBranch&currentModuleID=' + moduleID);
$(moduleBox).load(link, function()
{
$(this).children('select').attr('id', 'parent').attr('name', 'parent');
+1 -2
View File
@@ -1090,8 +1090,7 @@ class user extends control
}
/* Remove the real path for security reason. */
$pathPos = strrpos($this->app->getBasePath(), DIRECTORY_SEPARATOR, -2);
$resetFileName = substr($resetFileName, $pathPos + 1);
$resetFileName = str_replace($this->app->getBasePath(), '', $resetFileName);
$this->view->title = $this->lang->user->resetPassword;
$this->view->status = 'reset';
+1
View File
@@ -422,6 +422,7 @@ class webhookModel extends model
$viewLink = $this->getViewLink($objectType == 'kanbancard' ? 'kanban' : $objectType, $objectType == 'kanbancard' ? $object->kanban : $objectID);
$objectTypeName = ($objectType == 'story' and $object->type == 'requirement') ? $this->lang->action->objectTypes['requirement'] : $this->lang->action->objectTypes[$objectType];
$title = $this->app->user->realname . $this->lang->action->label->$actionType . $objectTypeName;
$host = (defined('RUN_MODE') and RUN_MODE == 'api') ? '' : $host;
$text = $title . ' ' . "[#{$objectID}::{$object->$field}](" . $host . $viewLink . ")";
$mobile = '';
@@ -344,27 +344,42 @@ class zentaoBot extends xuanBot
* @param object $user
* @param object $pager
* @access public
* @return object|string
* @return array
*/
public function viewTask($args = array(), $user = null, $pager = null)
{
$keys = array();
foreach(array('pri', 'id', 'status', 'assignTo', 'taskName') as $key) $keys[$key] = true;
if(empty($args))
{
$conds = new stdClass();
$conds->assignedToList = is_object($user) ? $user->account : false;
$conds->statusList = 'wait,doing,done,pause,cancel';
return $this->im->task->getListByConds($conds, 'status_asc', 0, $pager);
$keys['assignTo'] = is_object($user) ? $user->account : false;
$keys['status'] = 'wait,doing,done,pause,cancel';
}
$keys = array();
$keys['pri'] = true;
$keys['id'] = true;
$keys['status'] = true;
$keys['assignTo'] = true;
$keys['taskName'] = true;
$conds = $this->parseArguments($args, $keys);
return $this->im->task->getListByConds($conds, 'status_asc', 0, $pager);
$conds->search = 1;
$conds->order = 'status_asc';
$conds->limit = 10;
if(is_object($pager))
{
$conds->page = $pager->pageID;
$conds->limit = $pager->recPerPage;
}
$result = $this->loadEntry('tasks', 'get', array(), (array)$conds);
if(isset($result->tasks))
{
$pager->setRecTotal($result->total);
$pager->setRecPerPage($result->limit);
$pager->setPageID($result->page);
$pager->setPageTotal();
return $result->tasks;
}
return array();
}
/**
@@ -449,7 +464,7 @@ class zentaoBot extends xuanBot
if(empty($params))
{
$originCommand = rawurlencode($this->lang->finishTask . ' ' . implode(' ', $originArgs));
$originCommand = rawurlencode($this->lang->finishCommand . ' ' . implode(' ', $originArgs));
$json = (object)array
(
@@ -578,30 +593,28 @@ class zentaoBot extends xuanBot
public function renderTask($tasks, $originArgs, $pager)
{
$lang = $this->im->lang;
if(!$tasks || $pager->recTotal === 0) return $lang->task->noTask;
$sysURL = common::getSysURL();
$taskCount = $pager->recTotal ? $pager->recTotal : count($tasks);
if($pager->recTotal == 1)
if($taskCount === 0) return $lang->task->noTask;
if($taskCount == 1)
{
$task = current($tasks);
$link = str_replace('x.php', 'index.php', helper::createLink('task', 'view', "taskID=$task->id", 'html'));
$messages = new stdclass();
$messages->type = 'url';
$messages->url = $sysURL . $link;
return array(sprintf($this->lang->tasksFound, $pager->recTotal), $messages);
$messages->url = common::getSysURL() . $link;
return array(sprintf($this->lang->tasksFound, $taskCount), $messages);
}
$messages = array();
if($pager->pageID == 1)
{
$messages[] = sprintf($this->lang->tasksFound, $pager->recTotal);
}
if($pager->pageID == 1) $messages[] = sprintf($this->lang->tasksFound, $taskCount);
$taskTable = $this->renderTaskTable($tasks);
$originCommand = $this->lang->viewTask . ' ' . implode(' ', $originArgs);
$originCommand = $this->lang->viewCommand . ' ' . implode(' ', $originArgs);
$paging = "$pager->pageID / $pager->pageTotal";
if($pager->pageID != 1)
{
@@ -633,7 +646,6 @@ class zentaoBot extends xuanBot
public function renderTaskTable($tasks)
{
$lang = $this->im->lang;
$sysURL = common::getSysURL();
$headMap = array('id'=>'ID', 'pri' => $lang->task->pri, 'name' => $lang->task->name, 'assignedTo' => $lang->task->assignedTo, 'status' => $lang->task->status, 'estimate' => $lang->task->estimateAB, 'consumed' => $lang->task->consumedAB, 'left' => $lang->task->leftAB, 'actions' => $lang->actions);
$thead = '';
@@ -645,7 +657,7 @@ class zentaoBot extends xuanBot
{
$tr = '';
$link = str_replace('x.php', 'index.php', helper::createLink('task', 'view', "taskID=$task->id", 'html'));
$href = urlencode($sysURL . $link);
$href = urlencode(common::getSysURL() . $link);
$isParent = $task->parent == -1;
$isChild = $task->parent > 0;
$isMulti = !empty($task->mode);
@@ -675,13 +687,13 @@ class zentaoBot extends xuanBot
}
else
{
$tr .= "<td class='text-nowrap'>{$this->users[$task->$key]}</td>";
$tr .= "<td class='text-nowrap'>{$task->assignedTo->realname}</td>";
}
break;
case 'actions':
$startUrl = 'xxc://sendContentToServerBySendbox/' . "{$this->lang->startTask} #$task->id";
$finishUrl = 'xxc://sendContentToServerBySendbox/' . "{$this->lang->finishTask} #$task->id";
$closeUrl = 'xxc://sendContentToServerBySendbox/' . "{$this->lang->closeTask} #$task->id";
$startUrl = 'xxc://sendContentToServerBySendbox/' . "{$this->lang->startCommand} #$task->id";
$finishUrl = 'xxc://sendContentToServerBySendbox/' . "{$this->lang->finishCommand} #$task->id";
$closeUrl = 'xxc://sendContentToServerBySendbox/' . "{$this->lang->closeCommand} #$task->id";
$canStart = in_array($task->status, array('wait', 'pause'));
$canFinish = in_array($task->status, array('wait', 'pause', 'doing'));
@@ -770,7 +782,7 @@ class zentaoBot extends xuanBot
if(count($args) == 0)
{
$originCommand = rawurlencode($this->lang->startTask . ' ' . implode(' ', $originArgs));
$originCommand = rawurlencode($this->lang->startCommand . ' ' . implode(' ', $originArgs));
$realStarted = $this->formatDate($task, 'realStarted');
@@ -948,11 +960,12 @@ class zentaoBot extends xuanBot
* @param string $entry
* @param string $action
* @param array $params
* @param array $query
* @param string $version
* @access public
* @return object
*/
public function loadEntry($entry, $action, $params = array(), $version = 'v1')
public function loadEntry($entry, $action, $params = array(), $query = array(), $version = 'v1')
{
try
{
@@ -979,6 +992,10 @@ class zentaoBot extends xuanBot
{
$entry->requestBody = (object)$params;
}
elseif($action == 'get' && !empty($query))
{
$entry->setParam($query);
}
$content = call_user_func_array(array($entry, $action), $params);
return json_decode($content);
@@ -73,10 +73,10 @@ $lang->im->bot->zentaoBot->prevPage = 'Prev Page';
$lang->im->bot->zentaoBot->nextPage = 'Next Page';
$lang->im->bot->zentaoBot->effortRecorded = 'Effort recorded for task #%d.';
$lang->im->bot->zentaoBot->finishTask = 'finish';
$lang->im->bot->zentaoBot->closeTask = 'close';
$lang->im->bot->zentaoBot->startTask = 'start';
$lang->im->bot->zentaoBot->viewTask = 'view';
$lang->im->bot->zentaoBot->finishCommand = 'finish';
$lang->im->bot->zentaoBot->closeCommand = 'close';
$lang->im->bot->zentaoBot->startCommand = 'start';
$lang->im->bot->zentaoBot->viewCommand = 'view';
$lang->im->bot->zentaoBot->errors = new stdclass();
$lang->im->bot->zentaoBot->errors->emptyResult = 'No task found.';
@@ -73,10 +73,10 @@ $lang->im->bot->zentaoBot->prevPage = 'Prev Page';
$lang->im->bot->zentaoBot->nextPage = 'Next Page';
$lang->im->bot->zentaoBot->effortRecorded = 'Effort recorded for task #%d.';
$lang->im->bot->zentaoBot->finishTask = 'finish';
$lang->im->bot->zentaoBot->closeTask = 'close';
$lang->im->bot->zentaoBot->startTask = 'start';
$lang->im->bot->zentaoBot->viewTask = 'view';
$lang->im->bot->zentaoBot->finishCommand = 'finish';
$lang->im->bot->zentaoBot->closeCommand = 'close';
$lang->im->bot->zentaoBot->startCommand = 'start';
$lang->im->bot->zentaoBot->viewCommand = 'view';
$lang->im->bot->zentaoBot->errors = new stdclass();
$lang->im->bot->zentaoBot->errors->emptyResult = 'No task found.';
@@ -73,10 +73,10 @@ $lang->im->bot->zentaoBot->prevPage = 'Prev Page';
$lang->im->bot->zentaoBot->nextPage = 'Next Page';
$lang->im->bot->zentaoBot->effortRecorded = 'Effort recorded for task #%d.';
$lang->im->bot->zentaoBot->finishTask = 'finish';
$lang->im->bot->zentaoBot->closeTask = 'close';
$lang->im->bot->zentaoBot->startTask = 'start';
$lang->im->bot->zentaoBot->viewTask = 'view';
$lang->im->bot->zentaoBot->finishCommand = 'finish';
$lang->im->bot->zentaoBot->closeCommand = 'close';
$lang->im->bot->zentaoBot->startCommand = 'start';
$lang->im->bot->zentaoBot->viewCommand = 'view';
$lang->im->bot->zentaoBot->errors = new stdclass();
$lang->im->bot->zentaoBot->errors->emptyResult = 'No task found.';
@@ -81,10 +81,10 @@ $lang->im->bot->zentaoBot->prevPage = '上一页';
$lang->im->bot->zentaoBot->nextPage = '下一页';
$lang->im->bot->zentaoBot->effortRecorded = '任务 #%d 已完成工时信息填写';
$lang->im->bot->zentaoBot->finishTask = '完成任务';
$lang->im->bot->zentaoBot->closeTask = '关闭任务';
$lang->im->bot->zentaoBot->startTask = '开始任务';
$lang->im->bot->zentaoBot->viewTask = '查看任务';
$lang->im->bot->zentaoBot->finishCommand = '完成';
$lang->im->bot->zentaoBot->closeCommand = '关闭';
$lang->im->bot->zentaoBot->startCommand = '开始';
$lang->im->bot->zentaoBot->viewCommand = '查看';
$lang->im->bot->zentaoBot->errors = new stdclass();
$lang->im->bot->zentaoBot->errors->emptyResult = '未查询到相关匹配信息';
@@ -1,30 +0,0 @@
<?php
/**
* Get task list by conditions.
*
* @param object $conds
* @param string $orderBy
* @param int $limit
* @param object $pager
* @access public
* @return array
*/
public function getListByConds($conds, $orderBy = 'id_desc', $limit = 0, $pager = null)
{
foreach(array('priList' => array(), 'assignedToList' => array(), 'statusList' => array(), 'idList' => array(), 'taskName' => '') as $condKey => $defaultValue)
{
if(!isset($conds->$condKey)) $conds->$condKey = $defaultValue;
}
return $this->dao->select('*')->from(TABLE_TASK)
->where('deleted')->eq(0)
->beginIF(!empty($conds->priList))->andWhere('pri')->in($conds->priList)->fi()
->beginIF(!empty($conds->assignedToList))->andWhere('assignedTo')->in($conds->assignedToList)->fi()
->beginIF(!empty($conds->statusList))->andWhere('status')->in($conds->statusList)->fi()
->beginIF(!empty($conds->idList))->andWhere('id')->in($conds->idList)->fi()
->beginIF(!empty($conds->taskName))->andWhere('name')->like("%{$conds->taskName}%")
->orderBy($orderBy)
->beginIF($limit > 0)->limit($limit)->fi()
->page($pager)
->fetchAll('id');
}