Merge branch 'zentaopms_9.8' of https://github.com/easysoft/zentaopms into zentaopms_9.8

This commit is contained in:
daitingting
2018-03-20 15:02:00 +08:00
16 changed files with 69 additions and 34 deletions
+1
View File
@@ -32,6 +32,7 @@ class actionModel extends model
*/
public function create($objectType, $objectID, $actionType, $comment = '', $extra = '', $actor = '', $autoDelete = true)
{
if(empty($comment)) return false;
$actor = $actor ? $actor : $this->app->user->account;
$actionType = strtolower($actionType);
if($actor == 'guest' and $actionType == 'logout') return false;
+9 -1
View File
@@ -37,7 +37,15 @@ class api extends control
*/
public function getModel($moduleName, $methodName, $params = '')
{
parse_str(str_replace(',', '&', $params), $params);
$params = explode(',', $params);
$newParams = array_shift($params);
foreach($params as $param)
{
$sign = strpos($param, '=') !== false ? '&' : ',';
$newParams .= $sign . $param;
}
parse_str($newParams, $params);
$module = $this->loadModel($moduleName);
$result = call_user_func_array(array(&$module, $methodName), $params);
if(dao::isError()) die(json_encode(dao::getError()));
+11 -3
View File
@@ -82,12 +82,14 @@ class branchModel extends model
*
* @param array $products
* @param string $params
* @param array $appendBranch
* @access public
* @return array
*/
public function getByProducts($products, $params = '')
public function getByProducts($products, $params = '', $appendBranch = '')
{
$branches = $this->dao->select('*')->from(TABLE_BRANCH)->where('product')->in($products)->andWhere('deleted')->eq(0)->orderBy('`order`')->fetchAll();
$branches = $this->dao->select('*')->from(TABLE_BRANCH)->where('product')->in($products)->andWhere('deleted')->eq(0)->orderBy('`order`')->fetchAll('id');
if(!empty($appendBranch)) $branches += $this->dao->select('*')->from(TABLE_BRANCH)->where('id')->in($appendBranch)->orderBy('`order`')->fetchAll('id');
$products = $this->loadModel('product')->getByIdList($products);
$branchGroups = array();
@@ -154,6 +156,12 @@ class branchModel extends model
$case = $this->dao->select('id')->from(TABLE_CASE)->where('branch')->eq($branchID)->andWhere('deleted')->eq(0)->limit(1)->fetch();
$release = $this->dao->select('id')->from(TABLE_RELEASE)->where('branch')->eq($branchID)->andWhere('deleted')->eq(0)->limit(1)->fetch();
$build = $this->dao->select('id')->from(TABLE_BUILD)->where('branch')->eq($branchID)->andWhere('deleted')->eq(0)->limit(1)->fetch();
return empty($module) and empty($story) and empty($bug) and empty($case) and empty($release) and empty($build) and empty($plan);
$project = $this->dao->select('t1.id')->from(TABLE_PROJECT)->alias('t1')
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t2')->on('t1.id=t2.project')
->where('t2.branch')->eq($branchID)
->andWhere('t1.deleted')->eq(0)
->limit(1)
->fetch();
return empty($module) && empty($story) && empty($bug) && empty($case) && empty($release) && empty($build) && empty($plan) && empty($project);
}
}
+4 -4
View File
@@ -88,21 +88,21 @@ $currentBrowseType = isset($lang->bug->mySelects[$browseType]) && in_array($brow
<?php if(isset($menuItem->hidden)) continue;?>
<?php if($this->config->global->flow == 'onlyTest' and $menuItem->name == 'needconfirm') continue;?>
<?php $menuBrowseType = strpos($menuItem->name, 'QUERY') === 0 ? 'bySearch' : $menuItem->name;?>
<?php $param = strpos($menuItem->name, 'QUERY') === 0 ? (int)substr($menuItem->name, 5) : 0;?>
<?php $barParam = strpos($menuItem->name, 'QUERY') === 0 ? (int)substr($menuItem->name, 5) : 0;?>
<?php if($menuItem->name == 'my'):?>
<?php
echo "<li id='statusTab' class='dropdown " . (!empty($currentBrowseType) ? 'active' : '') . "'>";
echo html::a('javascript:;', $menuItem->text . " <span class='caret'></span>", '', "data-toggle='dropdown'");
echo "<ul class='dropdown-menu'>";
foreach ($lang->bug->mySelects as $key => $value)
foreach($lang->bug->mySelects as $key => $value)
{
echo '<li' . ($key == $currentBrowseType ? " class='active'" : '') . '>';
echo html::a($this->createLink('bug', 'browse', "productid=$productID&branch=$branch&browseType=$key&param=$param"), $value);
echo html::a($this->createLink('bug', 'browse', "productid=$productID&branch=$branch&browseType=$key&param=$barParam"), $value);
}
echo '</ul></li>';
?>
<?php else:?>
<li id='<?php echo $menuItem->name?>Tab'><?php echo html::a($this->createLink('bug', 'browse', "productid=$productID&branch=$branch&browseType=$menuBrowseType&param=$param"), $menuItem->text)?></li>
<li id='<?php echo $menuItem->name?>Tab'><?php echo html::a($this->createLink('bug', 'browse', "productid=$productID&branch=$branch&browseType=$menuBrowseType&param=$barParam"), $menuItem->text)?></li>
<?php endif;?>
<?php endforeach;?>
<li id='bysearchTab'><a href='#'><i class='icon-search icon'></i>&nbsp;<?php echo $lang->bug->byQuery;?></a></li>
+1 -1
View File
@@ -15,7 +15,7 @@ $(function()
return $(this).each(function()
{
var $this = $(this);
if($this.offset().top + 200 > $(document.body).height())
if(!$this.data('pickerPosition') && $this.offset().top + 200 > $(document.body).height())
{
$this.attr('data-picker-position', 'top-right');
}
+1 -1
View File
@@ -66,7 +66,7 @@ js::set('confirmDelete', $lang->user->confirmDelete);
</td>
<td><?php if(!common::printLink('user', 'view', "account=$user->account", $user->realname, '', "title='$user->realname'")) echo $user->realname;?></td>
<td><?php echo $user->account;?></td>
<td><?php echo $lang->user->roleList[$user->role];?></td>
<td><?php echo isset($user->role) ? $lang->user->roleList[$user->role] : '';?></td>
<td><?php echo html::mailto($user->email);?></td>
<td><?php if(isset($lang->user->genderList[$user->gender])) echo $lang->user->genderList[$user->gender];?></td>
<td><?php echo $user->phone;?></td>
+2 -1
View File
@@ -116,9 +116,10 @@ class custom extends control
foreach($_POST['keys'] as $index => $key)
{
/* Fix bug #942. */
if(!empty($key)) $key = trim($key);
if($field == 'priList' and !is_numeric($key)) die(js::alert($this->lang->custom->notice->priListKey));
if($module == 'bug' and $field == 'severityList' and !is_numeric($key)) die(js::alert($this->lang->custom->notice->severityListKey));
if(!empty($key) and $key != 'n/a' and !validater::checkREG($key, '/^[a-zA-Z_0-9]+$/')) die(js::alert($this->lang->custom->notice->keyList));
if(!empty($key) and $key != 'n/a' and !validater::checkREG($key, '/^[a-z_0-9]+$/')) die(js::alert($this->lang->custom->notice->keyList));
/* the length of role is 20, check it when save. */
if($module == 'user' and $field == 'roleList' and strlen($key) > 10) die(js::alert($this->lang->custom->notice->userRole));
+1 -1
View File
@@ -89,7 +89,7 @@ $lang->custom->notice->forceReview = '%s Review is required for certain
$lang->custom->notice->forceNotReview = "%s Review is NOT required for certain submitters.";
$lang->custom->notice->longlife = 'Define shelved bugs.';
$lang->custom->notice->priListKey = 'Priority list key should be numbers!';
$lang->custom->notice->keyList = 'key should be English or digital!';
$lang->custom->notice->keyList = 'The key should be a combination of lowercase English letters, numbers or underscores';
$lang->custom->notice->severityListKey = 'Bug severity list key should be numbers.';
$lang->custom->notice->indexPage['product'] = "ZenTao 8.2+ has Product Homepage. Do you want to go to Product Homepage?";
$lang->custom->notice->indexPage['project'] = "ZenTao 8.2+ has Project Homepage. Do you want to go to Project Homepage?";
+1 -1
View File
@@ -89,7 +89,7 @@ $lang->custom->notice->forceReview = "指定人提交的%s必须评审
$lang->custom->notice->forceNotReview = "指定人提交的%s不需要评审。";
$lang->custom->notice->longlife = 'Bug列表页面的久未处理标签中,列出设置天数之前未处理的Bug。';
$lang->custom->notice->priListKey = '优先级的键应当为数字!';
$lang->custom->notice->keyList = '键值应当为英文或数字';
$lang->custom->notice->keyList = '键值应当为小写英文字母、数字或下划线的组合';
$lang->custom->notice->severityListKey = 'Bug严重程度的键应当为数字!';
$lang->custom->notice->indexPage['product'] = "从8.2版本起增加了产品主页视图,是否默认进入产品主页?";
$lang->custom->notice->indexPage['project'] = "从8.2版本起增加了项目主页视图,是否默认进入项目主页?";
+1
View File
@@ -383,6 +383,7 @@ class productModel extends model
$products[$productID]->QD = $data->QDs[$productID];
$products[$productID]->RD = $data->RDs[$productID];
$products[$productID]->type = $data->types[$productID];
$products[$productID]->line = $data->line[$productID];
$products[$productID]->status = $data->statuses[$productID];
$products[$productID]->desc = strip_tags($this->post->descs[$productID], $this->config->allowedTags);
$products[$productID]->order = $data->orders[$productID];
+3 -3
View File
@@ -33,7 +33,7 @@
<?php foreach(customModel::getFeatureMenu($this->moduleName, $this->methodName) as $menuItem):?>
<?php if(isset($menuItem->hidden)) continue;?>
<?php $menuBrowseType = strpos($menuItem->name, 'QUERY') === 0 ? 'bySearch' : $menuItem->name;?>
<?php $param = strpos($menuItem->name, 'QUERY') === 0 ? '&param=' . (int)substr($menuItem->name, 5) : '';?>
<?php $barParam = strpos($menuItem->name, 'QUERY') === 0 ? '&param=' . (int)substr($menuItem->name, 5) : '';?>
<?php if($menuItem->name == 'my'):?>
<?php
echo "<li id='statusTab' class='dropdown " . (!empty($currentBrowseType) ? 'active' : '') . "'>";
@@ -42,12 +42,12 @@
foreach ($lang->product->mySelects as $key => $value)
{
echo '<li' . ($key == $currentBrowseType ? " class='active'" : '') . '>';
echo html::a($this->inlink('browse', "productID=$productID&branch=$branch&browseType=$key" . $param), $value);
echo html::a($this->inlink('browse', "productID=$productID&branch=$branch&browseType=$key" . $barParam), $value);
}
echo '</ul></li>';
?>
<?php else:?>
<li id='<?php echo $menuItem->name?>Tab'><?php echo html::a($this->inlink('browse', "productID=$productID&branch=$branch&browseType=$menuBrowseType" . $param), $menuItem->text);?></li>
<li id='<?php echo $menuItem->name?>Tab'><?php echo html::a($this->inlink('browse', "productID=$productID&branch=$branch&browseType=$menuBrowseType" . $barParam), $menuItem->text);?></li>
<?php endif;?>
<?php endforeach;?>
<li id='bysearchTab'><a href='javascript:;'><i class='icon-search icon'></i> <?php echo $lang->product->searchStory;?></a></li>
+12 -3
View File
@@ -1025,9 +1025,11 @@ class project extends control
$allProducts = array(0 => '') + $this->loadModel('product')->getPairs('noclosed|nocode');
$linkedProducts = $this->project->getProducts($project->id);
$linkedBranches = array();
foreach($linkedProducts as $product)
{
if(!isset($allProducts[$product->id])) $allProducts[$product->id] = $product->name;
if($product->branch) $linkedBranches[$product->branch] = $product->branch;
}
$this->view->title = $title;
@@ -1041,7 +1043,7 @@ class project extends control
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->allProducts = $allProducts;
$this->view->linkedProducts = $linkedProducts;
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($linkedProducts));
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($linkedProducts), '', $linkedBranches);
$this->display();
}
@@ -1291,6 +1293,11 @@ class project extends control
if(!$project) die(js::error($this->lang->notFound) . js::locate('back'));
$products = $this->project->getProducts($project->id);
$linkedBranches = array();
foreach($products as $product)
{
if($product->branch) $linkedBranches[$product->branch] = $product->branch;
}
/* Set menu. */
$this->project->setMenu($this->projects, $project->id);
@@ -1301,7 +1308,7 @@ class project extends control
$this->view->project = $project;
$this->view->products = $products;
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products));
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products), '', $linkedBranches);
$this->view->planGroups = $this->project->getPlans($products);
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->actions = $this->loadModel('action')->getList('project', $projectID);
@@ -1599,10 +1606,12 @@ class project extends control
$allProducts = $this->product->getPairs('noclosed|nocode');
$linkedProducts = $this->project->getProducts($project->id);
$linkedBranches = array();
// Merge allProducts and linkedProducts for closed product.
foreach($linkedProducts as $product)
{
if(!isset($allProducts[$product->id])) $allProducts[$product->id] = $product->name;
if(!empty($product->branch)) $linkedBranches[$product->branch] = $product->branch;
}
/* Assign. */
@@ -1610,7 +1619,7 @@ class project extends control
$this->view->position = $position;
$this->view->allProducts = $allProducts;
$this->view->linkedProducts = $linkedProducts;
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($allProducts));
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($allProducts), '', $linkedBranches);
$this->display();
}
+8 -1
View File
@@ -238,8 +238,15 @@ class searchModel extends model
$query->form = htmlspecialchars_decode($query->form, ENT_QUOTES);
$query->sql = htmlspecialchars_decode($query->sql, ENT_QUOTES);
$hasDynamic = strpos($query->form, '$') !== false;
$query->form = unserialize($query->form);
$query->sql = $this->replaceDynamic($query->sql);
if($hasDynamic)
{
$_POST = $query->form;
$this->buildQuery();
$querySessionName = $query->form['module'] . 'Query';
$query->sql = $this->session->$querySessionName;
}
return $query;
}
+12 -12
View File
@@ -39,17 +39,17 @@ if($this->story->checkForceReview()) unset($visibleFields['review']);
<thead>
<tr class='text-center'>
<th class='w-30px'><?php echo $lang->idAB;?></th>
<th class='w-120px<?php echo zget($visibleFields, $product->type, ' hidden')?>'><?php echo $lang->product->branch;?></th>
<th class='w-p15'><?php echo $lang->story->module;?> <span class='required'></span></th>
<th class='w-p15<?php echo zget($visibleFields, 'plan', ' hidden')?>'><?php echo $lang->story->plan;?></th>
<th <?php if(count($visibleFields) >= 9) echo "class='w-150px'"?>><?php echo $lang->story->title;?> <span class='required'></span></th>
<th class='w-p15<?php echo zget($visibleFields, 'spec', ' hidden')?>'><?php echo $lang->story->spec;?></th>
<th class='w-100px<?php echo zget($visibleFields, $product->type, ' hidden')?>'><?php echo $lang->product->branch;?></th>
<th class='w-p13'><?php echo $lang->story->module;?> <span class='required'></span></th>
<th class='w-p13<?php echo zget($visibleFields, 'plan', ' hidden')?>'><?php echo $lang->story->plan;?></th>
<th <?php if(count($visibleFields) >= 9) echo "class='w-200px'"?>><?php echo $lang->story->title;?> <span class='required'></span></th>
<th class='w-p13<?php echo zget($visibleFields, 'spec', ' hidden')?>'><?php echo $lang->story->spec;?></th>
<th class='w-80px<?php echo zget($visibleFields, 'source', ' hidden')?>'><?php echo $lang->story->source;?></th>
<th class='w-p15<?php echo zget($visibleFields, 'verify', ' hidden')?>'><?php echo $lang->story->verify;?></th>
<th class='w-p12<?php echo zget($visibleFields, 'verify', ' hidden')?>'><?php echo $lang->story->verify;?></th>
<th class='w-80px<?php echo zget($visibleFields, 'pri', ' hidden')?>'><?php echo $lang->story->pri;?></th>
<th class='w-100px<?php echo zget($visibleFields, 'estimate', ' hidden')?>'><?php echo $lang->story->estimate;?></th>
<th class='w-80px<?php echo zget($visibleFields, 'estimate', ' hidden')?>'><?php echo $lang->story->estimate;?></th>
<th class='w-70px<?php echo zget($visibleFields, 'review', ' hidden')?>'><?php echo $lang->story->review;?></th>
<th class='w-100px<?php echo zget($visibleFields, 'keywords', ' hidden')?>'><?php echo $lang->story->keywords;?></th>
<th class='w-80px<?php echo zget($visibleFields, 'keywords', ' hidden')?>'><?php echo $lang->story->keywords;?></th>
</tr>
</thead>
<?php $i = 0; ?>
@@ -62,7 +62,7 @@ if($this->story->checkForceReview()) unset($visibleFields['review']);
<tr class='text-center'>
<td><?php echo $i+1;?></td>
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?>'><?php echo html::select("branch[$i]", $branches, $branch, "class='form-control' onchange='setModuleAndPlan(this.value, $productID, $i)'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?>' style='overflow:visible'><?php echo html::select("module[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'module')?>' style='overflow:visible'><?php echo html::select("module[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'plan', ' hidden')?>' style='overflow:visible'><?php echo html::select("plan[$i]", $plans, $planID, "class='form-control chosen'");?></td>
<td style='overflow:visible'>
<div class='input-group'>
@@ -94,7 +94,7 @@ if($this->story->checkForceReview()) unset($visibleFields['review']);
<tr class='text-center'>
<td><?php echo $i+1;?></td>
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?>' style='overflow:visible'><?php echo html::select("branch[$i]", $branches, $branch, "class='form-control chosen' onchange='setModuleAndPlan(this.value, $productID, $i)'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?>' style='overflow:visible'><?php echo html::select("module[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'module')?>' style='overflow:visible'><?php echo html::select("module[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'plan', ' hidden')?>' style='overflow:visible'><?php echo html::select("plan[$i]", $plans, $planID, "class='form-control chosen'");?></td>
<td style='overflow:visible'>
<div class='input-group'>
@@ -114,7 +114,7 @@ if($this->story->checkForceReview()) unset($visibleFields['review']);
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input("keywords[$i]", '', "class='form-control' autocomplete='off'");?></td>
</tr>
<?php endfor;?>
<tr><td colspan='<?php echo count($visibleFields) + 2?>' class='text-center'><?php echo html::submitButton() . html::backButton();?></td></tr>
<tr><td colspan='<?php echo count($visibleFields) + 3?>' class='text-center'><?php echo html::submitButton() . html::backButton();?></td></tr>
</table>
</form>
<table class='hide' id='trTemp'>
@@ -122,7 +122,7 @@ if($this->story->checkForceReview()) unset($visibleFields['review']);
<tr class='text-center'>
<td>%s</td>
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?>' style='overflow:visible'><?php echo html::select("branch[%s]", $branches, $branch, "class='form-control' onchange='setModuleAndPlan(this.value, $productID, \"%s\")'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?>' style='overflow:visible'><?php echo html::select("module[%s]", $moduleOptionMenu, $moduleID, "class='form-control'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'module')?>' style='overflow:visible'><?php echo html::select("module[%s]", $moduleOptionMenu, $moduleID, "class='form-control'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'plan', ' hidden')?>' style='overflow:visible'><?php echo html::select("plan[%s]", $plans, $planID, "class='form-control'");?></td>
<td style='overflow:visible'>
<div class='input-group'>
+1 -1
View File
@@ -87,7 +87,7 @@ foreach(explode(',', $showFields) as $field)
<?php echo html::select("branches[$storyID]", $branches, $story->branch, "class='form-control chosen' onchange='loadBranches($branchProductID, this.value, $storyID);' $disabled");?>
</td>
<?php endif;?>
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?>' style='overflow:visible'>
<td class='text-left<?php echo zget($visibleFields, 'module')?>' style='overflow:visible'>
<?php echo html::select("modules[$storyID]", $modules, $story->module, "class='form-control chosen'");?>
</td>
<td class='text-left<?php echo zget($visibleFields, 'plan', ' hidden')?>' style='overflow:visible'>
+1 -1
View File
@@ -33,7 +33,7 @@
<table class='table table-form'>
<tr>
<th class='w-80px'><?php echo $lang->task->realStarted;?></th>
<td class='w-p25-f'><div class='datepicker-wrapper datepicker-date'><?php echo html::input('realStarted', $task->realStarted == '0000-00-00' ? helper::today() : $task->realStarted, "class='form-control form-date'");?></div></td><td></td>
<td class='w-p25-f'><div class='datepicker-wrapper datepicker-date'><?php echo html::input('realStarted', $task->realStarted == '0000-00-00' ? helper::today() : $task->realStarted, "class='form-control form-date' data-picker-position='bottom-right'");?></div></td><td></td>
</tr>
<tr>
<th><?php echo $lang->task->consumed;?></th>