This commit is contained in:
holan20180123
2020-10-10 16:57:05 +08:00
53 changed files with 260 additions and 193 deletions
+4 -4
View File
@@ -2,13 +2,13 @@ Z PUBLIC LICENSE 1.2
许可
Z PUBLIC LICENSE 由青岛易软天创网络科技有限公司(www.cnezsoft.com)起草,简称ZPL协议。
Z PUBLIC LICENSE 由青岛易软天创网络科技有限公司(www.easycorp.cn)起草,简称ZPL协议。
任何人均可使用该协议来发布开源软件,并可对下面协议正文中以下划线标注的空白部分做相应修改,
除此之外的任何内容不得做任何修改。青岛易软天创网络科技有限公司拥有对该协议条款的最终解释权。
前言:
禅道项目管理软件(以下简称该软件)由 青岛易软天创网络科技有限公司(www.cnezsoft.com)开发(以下简称我)。我依法拥有该软件的所有版权。
禅道项目管理软件(以下简称该软件)由 青岛易软天创网络科技有限公司(www.easycorp.cn)开发(以下简称我)。我依法拥有该软件的所有版权。
本着共享开放的角度,我以开放源代码的形式发布该软件。您可以在遵守该协议的前提下使用该软件。
自您安装该软件开始,您和我之间的合同关系自动成立。除非您停止使用该软件或与我有签署额外合同,
您须认真遵循该授权协议约定的每一条款。
@@ -16,9 +16,9 @@ Z PUBLIC LICENSE 由青岛易软天创网络科技有限公司(www.cnezsoft.co
我的联系方式:
联系人:徐先生
电话: 4006-8899-23
Email: co@cnezsoft.com
Email: co@zentao.net
QQ: 1492153927
地址: 青岛开发区武夷山路167号千禧龙花园 9-1-101室
地址: 青岛开发区长江路232号国贸中心C座2单元2902室
约定:
+3 -3
View File
@@ -2,20 +2,20 @@ Z PUBLIC LICENSE 1.2
Authorization
Z PUBLIC LICENSE, also known as ZPL Agreement, is drafted by EasyCorp(en.easycorp.ltd).
Z PUBLIC LICENSE, also known as ZPL Agreement, is drafted by EasyCorp(www.easycorp.ltd).
Anyone can use the agreement to publish open source software, and modify the blank in the following text of the agreement accordingly.
No other text of the agreement shall be changed. EasyCorp has the final interpretation of the terms in the agreement.
Preface
ZenTao ALM (Hereinafter referred to as "the software") developed by EasyCorp (en.easycorp.ltd) (hereinafter referred to I). I'm entitled to all copyright of the software.
ZenTao ALM (Hereinafter referred to as "the software") developed by EasyCorp (www.easycorp.ltd) (hereinafter referred to I). I'm entitled to all copyright of the software.
The software is released as open source software. You are authorized to use the software as long as you are in compliance with this agreement.
By installation of the software, you agree that a contractual relationship between you and me is automatically established.
You are obliged to fully comply with all the terms of this agreement unless you choose to stop using the software or you have signed additional agreement with me.
My Contact:
Email: renee@easysoft.ltd
Site: http://www.zentao.pm
Site: https://www.zentao.pm
We agree:
+12 -11
View File
@@ -712,8 +712,9 @@ class baseDAO
/**
* 将记录进行分页,自动设置limit语句。
* Page the records, set the limit part auto.
*
* @param object $pager
*
* @param object $pager
* @param string $distinctField
* @access public
* @return object the dao object self.
*/
@@ -722,15 +723,15 @@ class baseDAO
if(!is_object($pager)) return $this;
/*
* 如果$pager的总记录为0,需要计算总结果数。
* If the record total is 0, compute it.
**/
if($pager->recTotal == 0)
{
$recTotal = $this->count($distinctField);
$pager->setRecTotal($recTotal);
$pager->setPageTotal();
}
* 重新计算分页数据,并判断是否需要返回上一页。
* Calculate pagination to determine whether to return to the previous page.
*/
$originalPageID = $pager->pageID;
$recTotal = $this->count($distinctField);
$pager->setRecTotal($recTotal);
$pager->setPageTotal();
if($originalPageID > $pager->pageTotal) $pager->setPageID($pager->pageTotal);
$this->sqlobj->limit($pager->limit());
return $this;
}
+3 -3
View File
@@ -360,8 +360,8 @@ class basePager
/**
* 设置分页信息的样式。
* Get the pager html string.
*
* @param string $align
*
* @param string $align
* @param string $type the pager type, full|short|shortest
* @access public
* @return string
@@ -392,7 +392,7 @@ class basePager
$position = $this->pageTotal == 1 ? '' : $this->pageID . '/' . $this->pageTotal;
$pager = $pager . ' ' . $position;
}
else if($type != 'full')
else if($type != 'full')
{
$pager = $this->pageID . '/' . $this->pageTotal . ' ' . $pager;
}
+2 -2
View File
@@ -130,7 +130,7 @@ class dingapi
$url = $this->apiUrl . 'topapi/message/corpconversation/asyncsend_v2?access_token=' . $this->token;
$response = common::http($url, $postData);
$errors = commonModel::$errors;
$errors = commonModel::$requestErrors;
$response = json_decode($response);
if(isset($response->errcode) and $response->errcode == 0) return array('result' => 'success');
@@ -150,7 +150,7 @@ class dingapi
public function queryAPI($url)
{
$response = common::http($url);
$errors = commonModel::$errors;
$errors = commonModel::$requestErrors;
$response = json_decode($response);
if(isset($response->errcode) and $response->errcode == 0) return $response;
+2 -2
View File
@@ -114,7 +114,7 @@ class wechatapi
$url = $this->apiUrl . 'message/send?access_token=' . $this->token;
$response = common::http($url, json_encode($message), array(), array('Content-Type: text/plain'));
$errors = commonModel::$errors;
$errors = commonModel::$requestErrors;
$response = json_decode($response);
if(isset($response->errcode) and $response->errcode == 0) return array('result' => 'success');
@@ -134,7 +134,7 @@ class wechatapi
public function queryAPI($url)
{
$response = common::http($curl);
$errors = commonModel::$errors;
$errors = commonModel::$requestErrors;
$response = json_decode($response);
if(isset($response->errcode) and $response->errcode == 0) return $response;
+1 -1
View File
@@ -43,7 +43,7 @@ $lang->block->myBug = '我的BUG';
$lang->block->myProject = '未关闭的' . $lang->projectCommon;
$lang->block->myProduct = '未关闭的' . $lang->productCommon;
$lang->block->delayed = '已延期';
$lang->block->noData = '当前统计类型下暂无数据';
$lang->block->noData = '当前统计类型下暂无数据。';
$lang->block->emptyTip = '暂无信息';
$lang->block->params = new stdclass();
+1 -1
View File
@@ -43,7 +43,7 @@ $lang->block->myBug = '我的BUG';
$lang->block->myProject = '未關閉的' . $lang->projectCommon;
$lang->block->myProduct = '未關閉的' . $lang->productCommon;
$lang->block->delayed = '已延期';
$lang->block->noData = '當前統計類型下暫無數據';
$lang->block->noData = '當前統計類型下暫無數據。';
$lang->block->emptyTip = '暫無信息';
$lang->block->params = new stdclass();
+1 -1
View File
@@ -21,7 +21,7 @@ $useGuest = $this->app->user->account == 'guest';
<?php if(empty($longBlocks) and empty($shortBlocks)):?>
<div class="table-empty-tip">
<p>
<span class="text-muted"><?php echo $lang->block->noData. ',';?></span>
<span class="text-muted"><?php echo $lang->block->noData;?></span>
<?php echo html::a($this->createLink("block", "admin", "id=0&module=$module"), "<i class='icon icon-plus'></i> {$lang->block->createBlock}", '', "data-toggle='modal' data-type='ajax' data-width='700' data-title='{$lang->block->createBlock}' class='btn btn-info'")?>
<?php echo html::a($this->createLink("block", "ajaxReset", "module=$module"), "<i class='icon icon-refresh'></i> {$lang->block->reset}", 'hiddenwin', 'class="btn btn-info"')?>
</p>
+3 -7
View File
@@ -127,18 +127,13 @@ class bug extends control
/* Load pager. */
$this->app->loadClass('pager', $static = true);
if($this->app->getViewType() == 'mhtml') $recPerPage = 10;
$pager = pager::init(0, $recPerPage, $pageID);
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Get projects. */
$projects = $this->loadModel('project')->getPairs('empty|withdelete');
/* Get bugs. */
$bugs = $this->bug->getBugs($productID, $projects, $branch, $browseType, $moduleID, $queryID, $sort, $pager);
if(empty($bugs) and $pageID > 1)
{
$pager = pager::init(0, $recPerPage, 1);
$bugs = $this->bug->getBugs($productID, $projects, $branch, $browseType, $moduleID, $queryID, $sort, $pager);
}
/* Process the sql, get the conditon partion, save it to session. */
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'bug', $browseType == 'needconfirm' ? false : true);
@@ -371,7 +366,7 @@ class bug extends control
$pri = 3;
$color = '';
/* Parse the extras. extract fix php7.2*/
/* Parse the extras. extract fix php7.2. */
$extras = str_replace(array(',', ' '), array('&', ''), $extras);
parse_str($extras, $output);
extract($output);
@@ -487,6 +482,7 @@ class bug extends control
$this->view->branch = $branch;
$this->view->branches = $branches;
$this->view->color = $color;
$this->view->stepsRequired = strpos($this->config->bug->create->requiredFields, 'steps');
$this->display();
}
+8 -5
View File
@@ -112,16 +112,17 @@ function loadAllBuilds(object)
{
productID = $('#product').val();
projectID = $('#project').val();
if(page == 'edit') buildBox = $(object).closest('.input-group').attr('id');
var buildBox = '';
if(page == 'edit') buildBox = $(object).closest('.input-group').attr('id');
if(projectID)
{
loadAllProjectBuilds(projectID, productID);
loadAllProjectBuilds(projectID, productID, buildBox);
}
else
{
loadAllProductBuilds(productID);
loadAllProductBuilds(productID, buildBox);
}
}
}
@@ -131,10 +132,11 @@ function loadAllBuilds(object)
*
* @param int $projectID
* @param int $productID
* @param string $buildBox
* @access public
* @return void
*/
function loadAllProjectBuilds(projectID, productID)
function loadAllProjectBuilds(projectID, productID, buildBox)
{
branch = $('#branch').val();
if(typeof(branch) == 'undefined') branch = 0;
@@ -171,10 +173,11 @@ function loadAllProjectBuilds(projectID, productID)
* Load all builds of the product.
*
* @param int $productID
* @param string $buildBox
* @access public
* @return void
*/
function loadAllProductBuilds(productID)
function loadAllProductBuilds(productID, buildBox)
{
branch = $('#branch').val();
if(typeof(branch) == 'undefined') branch = 0;
+25 -4
View File
@@ -22,7 +22,7 @@ function loadAllUsers()
/**
* Load team members of the latest project of a product as assignedTo list.
*
* @param $productID
* @param int $productID
* @access public
* @return void
*/
@@ -33,7 +33,7 @@ function loadProjectTeamMembers(productID)
}
/**
* load assignedTo and stories of module.
* Load assignedTo and stories of module.
*
* @access public
* @return void
@@ -50,6 +50,8 @@ function loadModuleRelated()
/**
* Set the assignedTo field.
*
* @param int $moduleID
* @param int $productID
* @access public
* @return void
*/
@@ -83,13 +85,14 @@ function setAssignedTo(moduleID, productID)
});
}
var stepsTemplate;
$(function()
{
if($('#project').val()) loadProjectRelated($('#project').val());
$('[data-toggle=tooltip]').tooltip();
// adjust size of bug type input group
/* Adjust size of bug type input group. */
var adjustBugTypeGroup = function()
{
var $group = $('#bugTypeInputGroup');
@@ -107,7 +110,7 @@ $(function()
adjustBugTypeGroup();
$(window).on('resize', adjustBugTypeGroup);
// init pri and severity selector
/* Init pri and severity selector. */
$('#severity, #pri').on('change', function()
{
var $select = $(this);
@@ -115,4 +118,22 @@ $(function()
var value = $select.val();
$selector.find('.pri-text').html($selector.data('type') === 'severity' ? '<span class="label-severity" data-severity="' + value + '" title="' + value + '"></span>' : '<span class="label-pri label-pri-' + value + '" title="' + value + '">' + value + '</span>');
});
/* Get steps template. */
stepsTemplate = editor['steps'].html();
$("a[id^='tplTitleBox']").on('click', function()
{
setTimeout("stepsTemplate = editor['steps'].html()", 100);
});
/* Judgment of required items for steps. */
$('#submit').on('click', function()
{
var steps = editor['steps'].html();
if(stepsRequired !== false && stepsTemplate == steps)
{
bootbox.alert(stepsNotEmpty);
return false;
}
});
});
+7 -6
View File
@@ -172,12 +172,13 @@ $lang->bug->legendRelated = 'Sonstige Infos';
$lang->bug->buttonConfirm = 'Confirm';
/* 交互提示。*/
$lang->bug->summary = "Bugs on this page : <strong>%s</strong> Total, <strong>%s</strong> Unresolved.";
$lang->bug->confirmChangeProduct = "Change {$lang->productCommon} will cause linked {$lang->projectCommon},Story and Task change. Do you want to do this?";
$lang->bug->confirmDelete = 'Do you want to delete this bug?';
$lang->bug->remindTask = 'This Bug has been converted to Task. Do you want to update Status of Task(ID %s)?';
$lang->bug->skipClose = 'Bug %s is not resolved. You cannot close it.';
$lang->bug->projectAccessDenied = "You access to the {$lang->projectCommon} to which this bug belongs is denied!";
$lang->bug->summary = "Bugs on this page : <strong>%s</strong> Total, <strong>%s</strong> Unresolved.";
$lang->bug->confirmChangeProduct = "Change {$lang->productCommon} will cause linked {$lang->projectCommon},Story and Task change. Do you want to do this?";
$lang->bug->confirmDelete = 'Do you want to delete this bug?';
$lang->bug->remindTask = 'This Bug has been converted to Task. Do you want to update Status of Task(ID %s)?';
$lang->bug->skipClose = 'Bug %s is not resolved. You cannot close it.';
$lang->bug->projectAccessDenied = "You access to the {$lang->projectCommon} to which this bug belongs is denied!";
$lang->bug->stepsNotEmpty = "The reproduction step cannot be empty.";
/* 模板。*/
$lang->bug->tplStep = "<p>[Steps]</p><br/>";
+7 -6
View File
@@ -172,12 +172,13 @@ $lang->bug->legendRelated = 'Related Info';
$lang->bug->buttonConfirm = 'Confirm';
/* Interactive prompt. */
$lang->bug->summary = "Total <strong>%s</strong> bugs on this page, and <strong>%s</strong> Active.";
$lang->bug->confirmChangeProduct = "Any change to {$lang->productCommon} will cause linked {$lang->projectCommon}s, stories and tasks change. Do you want to do this?";
$lang->bug->confirmDelete = 'Do you want to delete this bug?';
$lang->bug->remindTask = 'This bug has been converted to a task. Do you want to update the status of Task(ID %s)?';
$lang->bug->skipClose = 'Bug %s is active. You cannot close it.';
$lang->bug->projectAccessDenied = "You access to the {$lang->projectCommon} to which this bug belongs is denied!";
$lang->bug->summary = "Total <strong>%s</strong> bugs on this page, and <strong>%s</strong> Active.";
$lang->bug->confirmChangeProduct = "Any change to {$lang->productCommon} will cause linked {$lang->projectCommon}s, stories and tasks change. Do you want to do this?";
$lang->bug->confirmDelete = 'Do you want to delete this bug?';
$lang->bug->remindTask = 'This bug has been converted to a task. Do you want to update the status of Task(ID %s)?';
$lang->bug->skipClose = 'Bug %s is active. You cannot close it.';
$lang->bug->projectAccessDenied = "You access to the {$lang->projectCommon} to which this bug belongs is denied!";
$lang->bug->stepsNotEmpty = "The reproduction step cannot be empty.";
/* Template. */
$lang->bug->tplStep = "<p>[Steps]</p><br/>";
+7 -6
View File
@@ -172,12 +172,13 @@ $lang->bug->legendRelated = 'Infos connexes';
$lang->bug->buttonConfirm = 'Confirmer';
/* 交互提示。*/
$lang->bug->summary = "Total de <strong>%s</strong> bugs sur cette page, et <strong>%s</strong> sont Actifs.";
$lang->bug->confirmChangeProduct = "Tout changement aux {$lang->productCommon} fera que les {$lang->projectCommon}s, stories et tâches associées vont changer. Voulez-vous faire cela ?";
$lang->bug->confirmDelete = 'Voulez-vous supprimer ce bug ?';
$lang->bug->remindTask = 'Ce bug a été converti en tâche. Voulez-vous mettre à jour le statut de la Tâche(ID %s) ?';
$lang->bug->skipClose = 'Bug %s est actif. Vous ne pouvez pas le fermer.';
$lang->bug->projectAccessDenied = "Votre accès à {$lang->projectCommon} auquel ce bug appartient est refusé !";
$lang->bug->summary = "Total de <strong>%s</strong> bugs sur cette page, et <strong>%s</strong> sont Actifs.";
$lang->bug->confirmChangeProduct = "Tout changement aux {$lang->productCommon} fera que les {$lang->projectCommon}s, stories et tâches associées vont changer. Voulez-vous faire cela ?";
$lang->bug->confirmDelete = 'Voulez-vous supprimer ce bug ?';
$lang->bug->remindTask = 'Ce bug a été converti en tâche. Voulez-vous mettre à jour le statut de la Tâche(ID %s) ?';
$lang->bug->skipClose = 'Bug %s est actif. Vous ne pouvez pas le fermer.';
$lang->bug->projectAccessDenied = "Votre accès à {$lang->projectCommon} auquel ce bug appartient est refusé !";
$lang->bug->stepsNotEmpty = "The reproduction step cannot be empty.";
/* 模板。*/
$lang->bug->tplStep = "<p>[Etape]</p><br/>";
+7 -6
View File
@@ -172,12 +172,13 @@ $lang->bug->legendRelated = 'Thông tin liên quan';
$lang->bug->buttonConfirm = 'Xác nhận';
/* Interactive prompt. */
$lang->bug->summary = "Tổng <strong>%s</strong> bugs, và <strong>%s</strong> kích hoạt.";
$lang->bug->confirmChangeProduct = "Mọi sự thay đổi tới {$lang->productCommon} sẽ là nguyên nhân liên kết {$lang->projectCommon}, câu chuyện và nhiệm vụ thay đổi. Bạn có muốn làm điều này?";
$lang->bug->confirmDelete = 'Bạn có muốn xóa bug này?';
$lang->bug->remindTask = 'Bug này đã chuyển thành một nhiệm vụ. Bạn có muốn cập nhật tình trạng của nhiệm vụ(ID %s)?';
$lang->bug->skipClose = 'Bug %s được kích hoạt. Bạn không thể đóng nó.';
$lang->bug->projectAccessDenied = "Truy cập của bạn tới {$lang->projectCommon} mà Bug này sở hữu bị từ chối!";
$lang->bug->summary = "Tổng <strong>%s</strong> bugs, và <strong>%s</strong> kích hoạt.";
$lang->bug->confirmChangeProduct = "Mọi sự thay đổi tới {$lang->productCommon} sẽ là nguyên nhân liên kết {$lang->projectCommon}, câu chuyện và nhiệm vụ thay đổi. Bạn có muốn làm điều này?";
$lang->bug->confirmDelete = 'Bạn có muốn xóa bug này?';
$lang->bug->remindTask = 'Bug này đã chuyển thành một nhiệm vụ. Bạn có muốn cập nhật tình trạng của nhiệm vụ(ID %s)?';
$lang->bug->skipClose = 'Bug %s được kích hoạt. Bạn không thể đóng nó.';
$lang->bug->projectAccessDenied = "Truy cập của bạn tới {$lang->projectCommon} mà Bug này sở hữu bị từ chối!";
$lang->bug->stepsNotEmpty = "The reproduction step cannot be empty.";
/* Template. */
$lang->bug->tplStep = "<p>[Các bước]</p><br/>";
+7 -6
View File
@@ -172,12 +172,13 @@ $lang->bug->legendRelated = '其他信息';
$lang->bug->buttonConfirm = '确认';
/* 交互提示。*/
$lang->bug->summary = "本页共 <strong>%s</strong> 个Bug,未解决 <strong>%s</strong>。";
$lang->bug->confirmChangeProduct = "修改{$lang->productCommon}会导致相应的{$lang->projectCommon}、{$lang->storyCommon}和任务发生变化,确定吗?";
$lang->bug->confirmDelete = '您确认要删除该Bug吗?';
$lang->bug->remindTask = '该Bug已经转化为任务,是否更新任务(编号:%s)状态 ?';
$lang->bug->skipClose = 'Bug %s 不是已解决状态,不能关闭。';
$lang->bug->projectAccessDenied = "您无权访问该Bug所属的{$lang->projectCommon}!";
$lang->bug->summary = "本页共 <strong>%s</strong> 个Bug,未解决 <strong>%s</strong>。";
$lang->bug->confirmChangeProduct = "修改{$lang->productCommon}会导致相应的{$lang->projectCommon}、{$lang->storyCommon}和任务发生变化,确定吗?";
$lang->bug->confirmDelete = '您确认要删除该Bug吗?';
$lang->bug->remindTask = '该Bug已经转化为任务,是否更新任务(编号:%s)状态 ?';
$lang->bug->skipClose = 'Bug %s 不是已解决状态,不能关闭。';
$lang->bug->projectAccessDenied = "您无权访问该Bug所属的{$lang->projectCommon}!";
$lang->bug->stepsNotEmpty = "重现步骤不能为空。";
/* 模板。*/
$lang->bug->tplStep = "<p>[步骤]</p><br/>";
+15 -21
View File
@@ -129,23 +129,10 @@ class bugModel extends model
*
* @param string $from object that is transfered to bug.
* @access public
* @return int|bool
* @return array|bool
*/
public function create($from = '')
{
/* Delete HTML tags, line breaks, and spaces in templates and steps. */
if($this->post->templateID)
{
$stepsTemplate = strip_tags($this->dao->select('content')->from(TABLE_USERTPL)->where('id')->eq($this->post->templateID)->fetch('content'));
$stepsTemplate = preg_replace("/\s/", "", $stepsTemplate);
}
else
{
$stepsTemplate = strip_tags($this->lang->bug->tplStep . $this->lang->bug->tplResult . $this->lang->bug->tplExpect);
}
$steps = strip_tags(preg_replace("/\s/", "", $this->post->steps));
$steps = str_replace("&nbsp;", "", $steps);
$now = helper::now();
$bug = fixer::input('post')
->setDefault('openedBy', $this->app->user->account)
@@ -157,12 +144,11 @@ class bugModel extends model
->setIF($this->post->assignedTo != '', 'assignedDate', $now)
->setIF($this->post->story != false, 'storyVersion', $this->loadModel('story')->getVersion($this->post->story))
->setIF(strpos($this->config->bug->create->requiredFields, 'project') !== false, 'project', $this->post->project)
->setIF($steps == $stepsTemplate, 'steps', '')
->stripTags($this->config->bug->editor->create['id'], $this->config->allowedTags)
->cleanInt('product,project,module,severity')
->join('openedBuild', ',')
->join('mailto', ',')
->remove('files, labels,uid,oldTaskID,contactListMenu,templateID')
->remove('files, labels,uid,oldTaskID,contactListMenu')
->get();
/* Check repeat bug. */
@@ -191,17 +177,19 @@ class bugModel extends model
* Batch create
*
* @param int $productID
* @param int $branch
* @access public
* @return void
*/
public function batchCreate($productID, $branch = 0)
{
/* Load module and init vars. */
$this->loadModel('action');
$branch = (int)$branch;
$productID = (int)$productID;
$now = helper::now();
$actions = array();
$data = fixer::input('post')->get();
$branch = (int)$branch;
$productID = (int)$productID;
$now = helper::now();
$actions = array();
$data = fixer::input('post')->get();
$result = $this->loadModel('common')->removeDuplicate('bug', $data, "product={$productID}");
$data = $result['data'];
@@ -234,8 +222,10 @@ class bugModel extends model
$data->browsers[$i] = $browser;
}
/* If there are images to upload, load the file module. */
if(isset($data->uploadImage)) $this->loadModel('file');
$extendFields = $this->getFlowExtendFields();
$bugs = array();
foreach($data->title as $i => $title)
{
@@ -260,6 +250,7 @@ class bugModel extends model
$bug->browser = $data->browsers[$i];
$bug->keywords = $data->keywords[$i];
/* Assign the bug to the person in charge of the module. */
if(!empty($moduleOwners[$bug->module]))
{
$bug->assignedTo = $moduleOwners[$bug->module];
@@ -273,6 +264,7 @@ class bugModel extends model
if($message) die(js::alert($message));
}
/* Required field check. */
foreach(explode(',', $this->config->bug->create->requiredFields) as $field)
{
$field = trim($field);
@@ -282,6 +274,7 @@ class bugModel extends model
$bugs[$i] = $bug;
}
/* When the bug is created by uploading an image, add the image to the step of the bug. */
foreach($bugs as $i => $bug)
{
if(!empty($data->uploadImage[$i]))
@@ -319,6 +312,7 @@ class bugModel extends model
$this->executeHooks($bugID);
/* When the bug is created by uploading the image, add the image to the file of the bug. */
$this->loadModel('score')->create('bug', 'create', $bugID);
if(!empty($data->uploadImage[$i]) and !empty($file))
{
+3 -2
View File
@@ -20,6 +20,8 @@ js::set('createRelease', $lang->release->create);
js::set('createBuild', $lang->build->create);
js::set('refresh', $lang->refresh);
js::set('flow', $config->global->flow);
js::set('stepsRequired', $stepsRequired);
js::set('stepsNotEmpty', $lang->bug->stepsNotEmpty);
?>
<div id="mainContent" class="main-content fade">
<div class="center-block">
@@ -219,10 +221,9 @@ js::set('flow', $config->global->flow);
</tr>
<tr>
<th><?php echo $lang->bug->steps;?></th>
<td colspan='2' class='steps'>
<td colspan='2'>
<?php echo $this->fetch('user', 'ajaxPrintTemplates', 'type=bug&link=steps');?>
<?php echo html::textarea('steps', $steps, "rows='10' class='form-control'");?>
<?php echo html::hidden('templateID', '');?>
</td>
</tr>
<?php
-5
View File
@@ -200,11 +200,6 @@ class caselib extends control
/* save session .*/
$cases = $this->caselib->getLibCases($libID, $browseType, $queryID, $moduleID, $sort, $pager);
if(empty($cases) and $pageID > 1)
{
$pager = pager::init(0, $recPerPage, 1);
$cases = $this->caselib->getLibCases($libID, $browseType, $queryID, $moduleID, $sort, $pager);
}
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', true);
+6 -6
View File
@@ -66,13 +66,13 @@ class ciModel extends model
$userPWD = "$jenkinsUser:$jenkinsPassword";
$queueUrl = sprintf('%s/queue/item/%s/api/json', $jenkinsServer, $compile->queue);
$response = common::http($queueUrl, '', array('CURLOPT_USERPWD' => $userPWD));
$response = common::http($queueUrl, '', array(CURLOPT_USERPWD => $userPWD));
$this->dao->update(TABLE_COMPILE)->set('times = times + 1')->where('id')->eq($compile->id)->exec();
if(strripos($response, "404") > -1)
{
$infoUrl = sprintf("%s/job/%s/api/xml?tree=builds[id,number,result,queueId]&xpath=//build[queueId=%s]", $jenkinsServer, $compile->jkJob, $compile->queue);
$response = common::http($infoUrl, '', array('CURLOPT_USERPWD' => $userPWD));
$response = common::http($infoUrl, '', array(CURLOPT_USERPWD => $userPWD));
if($response)
{
$buildInfo = simplexml_load_string($response);
@@ -83,7 +83,7 @@ class ciModel extends model
$this->updateBuildStatus($compile, $result);
$logUrl = sprintf('%s/job/%s/%s/consoleText', $jenkinsServer, $compile->jkJob, $buildNumber);
$response = common::http($logUrl, '', array('CURLOPT_USERPWD' => $userPWD));
$response = common::http($logUrl, '', array(CURLOPT_USERPWD => $userPWD));
$this->dao->update(TABLE_COMPILE)->set('logs')->eq($response)->where('id')->eq($compile->id)->exec();
}
}
@@ -93,7 +93,7 @@ class ciModel extends model
if(!empty($queueInfo->executable))
{
$buildUrl = $queueInfo->executable->url . 'api/json?pretty=true';
$response = common::http($buildUrl, '', array('CURLOPT_USERPWD' => $userPWD));
$response = common::http($buildUrl, '', array(CURLOPT_USERPWD => $userPWD));
$buildInfo = json_decode($response);
if($buildInfo->building)
@@ -106,7 +106,7 @@ class ciModel extends model
$this->updateBuildStatus($compile, $result);
$logUrl = $buildInfo->url . 'logText/progressiveText/api/json';
$response = common::http($logUrl, '', array('CURLOPT_USERPWD' => $userPWD));
$response = common::http($logUrl, '', array(CURLOPT_USERPWD => $userPWD));
$this->dao->update(TABLE_COMPILE)->set('logs')->eq($response)->where('id')->eq($compile->id)->exec();
}
}
@@ -139,7 +139,7 @@ class ciModel extends model
public function sendRequest($url, $data, $userPWD = '')
{
if(!empty($data->PARAM_TAG)) $data->PARAM_REVISION = '';
$response = common::http($url, $data, array('CURLOPT_HEADER' => true, 'CURLOPT_USERPWD' => $userPWD));
$response = common::http($url, $data, array(CURLOPT_HEADER => true, CURLOPT_USERPWD => $userPWD));
if(preg_match("!Location: .*item/(.*)/!", $response, $matches)) return $matches[1];
return 0;
}
+10 -8
View File
@@ -11,7 +11,7 @@
*/
class commonModel extends model
{
static public $errors = array();
static public $requestErrors = array();
/**
* The construc method, to do some auto things.
@@ -1859,8 +1859,8 @@ EOD;
*
* @param string $url
* @param string|array $data
* @param bool $optHeader
* @param string $userPWD
* @param array $options This is option and value pair, like CURLOPT_HEADER => true. Use curl_setopt function to set options.
* @param array $headers Set request headers.
* @static
* @access public
* @return string
@@ -1870,7 +1870,10 @@ EOD;
global $lang, $app;
if(!extension_loaded('curl')) return json_encode(array('result' => 'fail', 'message' => $lang->error->noCurlExt));
commonModel::$errors = array();
commonModel::$requestErrors = array();
if(!is_array($headers)) $headers = (array)$headers;
$headers[] = "API-RemoteIP: " . zget($_SERVER, 'REMOTE_ADDR', '');
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
@@ -1884,17 +1887,16 @@ EOD;
curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($curl, CURLOPT_HEADER, FALSE);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
$headers[] = "API-RemoteIP: " . $_SERVER['REMOTE_ADDR'];
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_URL, $url);
if(!empty($data))
{
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
foreach($options as $option => $value) curl_setopt($curl, $option, $value);
if($options) curl_setopt_array($curl, $options);
$response = curl_exec($curl);
$errors = curl_error($curl);
@@ -1914,7 +1916,7 @@ EOD;
fclose($fh);
}
if($errors) commonModel::$errors[] = $errors;
if($errors) commonModel::$requestErrors[] = $errors;
return $response;
}
+3 -3
View File
@@ -513,15 +513,15 @@ class docModel extends model
*
* @param int $libID
* @param int $module
* @param string $mode undeleted|all
* @param string $mode normal|all
* @access public
* @return void
*/
public function getPrivDocs($libID = 0, $module = 0, $mode = 'undeleted')
public function getPrivDocs($libID = 0, $module = 0, $mode = 'normal')
{
$stmt = $this->dao->select('*')->from(TABLE_DOC)
->where('1=1')
->beginIF($mode == 'undeleted')->andWhere('deleted')->eq(0)->fi()
->beginIF($mode == 'normal')->andWhere('deleted')->eq(0)->fi()
->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi()
->beginIF($libID)->andWhere('lib')->in($libID)->fi()
->beginIF(strpos($this->config->doc->custom->showLibs, 'children') === false)->andWhere('module')->in($module)->fi()
+1 -1
View File
@@ -195,7 +195,7 @@ $lang->install->chanzhi->desc = <<<EOD
EOD;
$lang->install->zdoo = new stdclass();
$lang->install->zdoo->name = 'ZDOO';
$lang->install->zdoo->name = 'ZDOO协同';
$lang->install->zdoo->logo = 'images/main/zdoo.ico';
$lang->install->zdoo->url = 'https://www.zdoo.com';
$lang->install->zdoo->desc = <<<EOD
+1 -1
View File
@@ -72,7 +72,7 @@ class jenkinsModel extends model
$jenkinsPassword = $jenkins->token ? $jenkins->token : $jenkins->password;
$userPWD = "$jenkinsUser:$jenkinsPassword";
$response = common::http($jenkinsServer . '/api/json/items/list', '', array('CURLOPT_USERPWD' => $userPWD));
$response = common::http($jenkinsServer . '/api/json/items/list', '', array(CURLOPT_USERPWD => $userPWD));
$response = json_decode($response);
$tasks = array();
+1 -3
View File
@@ -100,13 +100,11 @@ $('#jkHost').change(function()
$('#jkJobBox .loading').remove();
$('#jkJobBox .input-group').append(html);
var dropDirection = $('#jkJobBox #jkJob option').length > 2 ? 'up' : 'auto';
$('#jkJobBox #jkJob').chosen({drop_direction: dropDirection});
$('#jkJobBox #jkJob').chosen({drop_direction: 'auto'});
})
})
$(function()
{
$('#jkHost').chosen({drop_direction: $('#jkHost option').length > 3 ? 'up' : 'auto'});
$('#triggerType').change();
});
+1 -3
View File
@@ -104,14 +104,12 @@ $('#jkHost').change(function()
$('#jkJobBox .loading').remove();
$('#jkJobBox .input-group').append(html);
var dropDirection = $('#jkJobBox #jkJob option').length > 2 ? 'up' : 'auto';
$('#jkJobBox #jkJob').val(jkJob).chosen({drop_direction: dropDirection});
$('#jkJobBox #jkJob').val(jkJob).chosen({drop_direction: 'auto'});
})
})
$(function()
{
$('#jkHost').chosen({drop_direction: $('#jkHost option').length > 3 ? 'up' : 'auto'});
$('#jkHost').change();
$('#triggerType').change();
});
+1 -1
View File
@@ -76,7 +76,7 @@
<th><?php echo $lang->job->jkHost; ?></th>
<td colspan='2'>
<div class='table-row'>
<div class='table-col'><?php echo html::select('jkHost', $jkHostList, '', "class='form-control'"); ?></div>
<div class='table-col'><?php echo html::select('jkHost', $jkHostList, '', "class='form-control chosen'"); ?></div>
<div id='jkJobBox' class='table-col'>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->job->jkJob; ?></span>
+1 -1
View File
@@ -99,7 +99,7 @@
<th><?php echo $lang->job->jkHost; ?></th>
<td colspan='2'>
<div class='table-row'>
<div class='table-col'><?php echo html::select('jkHost', $jkHostList, $job->jkHost, "class='form-control'");?></div>
<div class='table-col'><?php echo html::select('jkHost', $jkHostList, $job->jkHost, "class='form-control chosen'");?></div>
<div id='jkJobBox' class='table-col'>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->job->jkJob; ?></span>
+1 -1
View File
@@ -54,7 +54,7 @@ $lang->misc->zentao->service['servicemore']= '更多服务...';
global $config;
$lang->misc->zentao->others['chanzhi'] = "<img src='{$config->webRoot}theme/default/images/main/chanzhi.ico' /> 蝉知门户";
$lang->misc->zentao->others['zdoo'] = "<img src='{$config->webRoot}theme/default/images/main/zdoo.ico' /> ZDOO";
$lang->misc->zentao->others['zdoo'] = "<img src='{$config->webRoot}theme/default/images/main/zdoo.ico' /> ZDOO协同";
$lang->misc->zentao->others['xuanxuan'] = "<img src='{$config->webRoot}theme/default/images/main/xuanxuan.ico' /> 喧喧聊天";
$lang->misc->zentao->others['ydisk'] = "<img src='{$config->webRoot}theme/default/images/main/ydisk.ico' /> 悦库网盘";
$lang->misc->zentao->others['meshiot' ] = "<img src='{$config->webRoot}theme/default/images/main/meshiot.ico' /> 易天物联";
-6
View File
@@ -165,16 +165,10 @@ class product extends control
/* Load pager. */
$this->app->loadClass('pager', $static = true);
if($this->app->getViewType() == 'mhtml') $recPerPage = 10;
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Get stories. */
$stories = $this->product->getStories($productID, $branch, $browseType, $queryID, $moduleID, $storyType, $sort, $pager);
if(empty($stories) and $pageID > 1)
{
$pager = pager::init(0, $recPerPage, 1);
$stories = $this->product->getStories($productID, $branch, $browseType, $queryID, $moduleID, $storyType, $sort, $pager);
}
/* Process the sql, get the conditon partion, save it to session. */
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story', $browseType != 'bysearch');
+1 -1
View File
@@ -24,7 +24,7 @@
<p>
<span class="text-muted"><?php echo $lang->project->noProject;?></span>
<?php if(common::hasPriv('project', 'create')):?>
<?php echo html::a($this->createLink('project', 'create', "projectID=&copyProjectID=&planID=&confirm=&productID=$productID"), "<i class='icon icon-plus'></i> " . $lang->project->create, '', "class='btn btn-info'");?>
<?php echo html::a($this->createLink('project', 'create', "productID=$productID"), "<i class='icon icon-plus'></i> " . $lang->project->create, '', "class='btn btn-info'");?>
<?php endif;?>
</p>
</div>
+1 -1
View File
@@ -122,7 +122,7 @@
<?php foreach($extendFields as $extendField) echo "<td>" . $this->loadModel('flow')->getFieldValue($extendField, $plan) . "</td>";?>
<td class='c-actions'>
<?php
if(common::hasPriv('project', 'create')) echo html::a(helper::createLink('project', 'create', "projectID=&copyProjectID=&planID=$plan->id"), '<i class="icon-plus"></i>', '', "class='btn' title='{$lang->project->create}'");
if(common::hasPriv('project', 'create')) echo html::a(helper::createLink('project', 'create', "productID=&projectID=&copyProjectID=&planID=$plan->id"), '<i class="icon-plus"></i>', '', "class='btn' title='{$lang->project->create}'");
if(common::hasPriv('productplan', 'linkStory')) echo html::a(inlink('view', "planID=$plan->id&type=story&orderBy=id_desc&link=true"), '<i class="icon-link"></i>', '', "class='btn' title='{$lang->productplan->linkStory}'");
if(common::hasPriv('productplan', 'linkBug') and $config->global->flow != 'onlyStory') echo html::a(inlink('view', "planID=$plan->id&type=bug&orderBy=id_desc&link=true"), '<i class="icon-bug"></i>', '', "class='btn' title='{$lang->productplan->linkBug}'");
common::printIcon('productplan', 'edit', "planID=$plan->id", $plan, 'list');
+6 -14
View File
@@ -181,11 +181,6 @@ class project extends control
/* Get tasks. */
$tasks = $this->project->getTasks($productID, $projectID, $this->projects, $browseType, $queryID, $moduleID, $sort, $pager);
if(empty($tasks) and $pageID > 1)
{
$pager = pager::init(0, $recPerPage, 1);
$tasks = $this->project->getTasks($productID, $projectID, $this->projects, $browseType, $queryID, $moduleID, $sort, $pager);
}
/* Build the search form. */
$actionURL = $this->createLink('project', 'task', "projectID=$projectID&status=bySearch&param=myQueryID");
@@ -706,11 +701,6 @@ class project extends control
$pager = new pager($recTotal, $recPerPage, $pageID);
$stories = $this->story->getProjectStories($projectID, $sort, $type, $param, 'story', '', $pager);
if(empty($stories) and $pageID > 1)
{
$pager = pager::init(0, $recPerPage, 1);
$stories = $this->story->getProjectStories($projectID, $sort, $type, $param, 'story', '', $pager);
}
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story', false);
$users = $this->user->getPairs('noletter');
@@ -1044,14 +1034,16 @@ class project extends control
/**
* Create a project.
*
* @param string $productID
* @param string $projectID
* @param string $copyProjectID
* @param int $planID
* @param string $confirm
*
* @access public
* @return void
*/
public function create($projectID = '', $copyProjectID = '', $planID = 0, $confirm = 'no', $productID = '')
public function create($productID = '', $projectID = '', $copyProjectID = '', $planID = 0, $confirm = 'no')
{
if($projectID)
{
@@ -1063,7 +1055,7 @@ class project extends control
}
else
{
die(js::confirm($this->lang->project->importPlanStory, inlink('create', "projectID=$projectID&copyProjectID=&planID=$planID&confirm=yes"), inlink('create', "projectID=$projectID"), 'parent', 'parent'));
die(js::confirm($this->lang->project->importPlanStory, inlink('create', "productID=&projectID=$projectID&copyProjectID=&planID=$planID&confirm=yes"), inlink('create', "productID=&projectID=$projectID"), 'parent', 'parent'));
}
}
$this->view->title = $this->lang->project->tips;
@@ -1129,11 +1121,11 @@ class project extends control
}
if(!empty($planID))
{
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('create', "projectID=$projectID&copyProjectID=&planID=$planID&confirm=no")));
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('create', "productID=&projectID=$projectID&copyProjectID=&planID=$planID&confirm=no")));
}
else
{
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('create', "projectID=$projectID")));
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('create', "productID=&projectID=$projectID")));
}
}
+20
View File
@@ -239,6 +239,26 @@ $(function()
e.preventDefault();
});
/*Assign value to the manage products by the different request type.*/
var url = window.location.href;
if(window.config.requestType == 'GET')
{
var paramStr = url.split('?')[1];
var paramArr = paramString.split('&');
var productID = paramArr[2].split('=')[1];
}
else
{
var urlArr = url.split('/');
var paramStr = urlArr[urlArr.length-1];
var paramArr = paramStr.split('-');
var productID = paramArr[2].split('.')[0];
}
var product = $('#productsBox .input-group:last select:first');
$(product).val(productID);
$(product).trigger("chosen:updated");
loadBranches($(product));
adjustProductBoxMargin();
adjustPlanBoxMargin();
});
+1 -1
View File
@@ -1,6 +1,6 @@
function setCopyProject(projectID)
{
location.href = createLink('project', 'create', 'projectID=0&copyProjectID=' + projectID);
location.href = createLink('project', 'create', 'productID=&projectID=0&copyProjectID=' + projectID);
}
$(function()
+1 -1
View File
@@ -1704,7 +1704,7 @@ class projectModel extends model
}
}
$this->linkStory($projectID, $planStories, $planProducts);
if($count != 0) echo js::alert(sprintf($this->lang->project->haveDraft, $count)) . js::locate(helper::createLink('project', 'create', "projectID=$projectID"));
if($count != 0) echo js::alert(sprintf($this->lang->project->haveDraft, $count)) . js::locate(helper::createLink('project', 'create', "productID=&projectID=$projectID"));
}
/**
+1 -1
View File
@@ -109,7 +109,7 @@
<?php endforeach;?>
<div class='col-sm-4'>
<div class='input-group'>
<?php echo html::select("products[$i]", $allProducts, $productID, "class='form-control chosen' onchange='loadBranches(this)'");?>
<?php echo html::select("products[$i]", $allProducts, '', "class='form-control chosen' onchange='loadBranches(this)'");?>
<span class='input-group-addon fix-border'></span>
</div>
</div>
-1
View File
@@ -1463,7 +1463,6 @@ class story extends control
$storyInfo['estimate'] = $story->estimate;
$storyInfo['pri'] = $story->pri;
$storyInfo['spec'] = html_entity_decode($story->spec);
echo json_encode($storyInfo);
}
+5 -2
View File
@@ -562,7 +562,6 @@ class storyModel extends model
->remove('files,labels,comment,contactListMenu,stages')
->get();
if(isset($story->plan) and is_array($story->plan)) $story->plan = trim(join(',', $story->plan), ',');
if(empty($_POST['product'])) $story->branch = $oldStory->branch;
if(isset($_POST['branch']) and $_POST['branch'] == 0) $story->branch = 0;
if(!empty($_POST['stages']))
{
@@ -1758,6 +1757,7 @@ class storyModel extends model
$branch = join(',', $branch);
if($branch) $branch = "0,$branch";
}
$stories = $this->dao->select('*')->from(TABLE_STORY)
->where('product')->in($productID)
->beginIF(!$hasParent)->andWhere("parent")->ge(0)->fi()
@@ -1767,7 +1767,10 @@ class storyModel extends model
->beginIF($status and $status != 'all')->andWhere('status')->in($status)->fi()
->andWhere('deleted')->eq(0)
->andWhere('type')->eq($type)
->orderBy($orderBy)->page($pager)->fetchAll('id');
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
return $this->mergePlanTitle($productID, $stories, $branch, $type);
}
+7
View File
@@ -80,6 +80,13 @@
</div>
</td>
</tr>
<?php else:?>
<tr>
<th class='thWidth'><?php echo $lang->product->branch;?></th>
<td>
<div class='input-group'><?php if($product->type != 'normal') echo html::select('branch', $branches, $story->branch, "onchange='loadBranch();' class='form-control chosen control-branch'");?></div>
</td>
</tr>
<?php endif;?>
<tr>
<th class='thWidth'><?php echo $lang->story->module;?></th>
+2 -2
View File
@@ -1631,7 +1631,7 @@ class taskModel extends model
$this->dao->update(TABLE_TASK)->data($task)->autoCheck()->where('id')->eq((int)$taskID)->exec();
if($oldTask->fromBug) $this->dao->update(TABLE_BUG)->set('toTask')->eq(0)->where('id')->eq($oldTask->fromBug)->exec();
if($oldTask->parent > 0) $this->updateParentStatus($taskID);
if($oldTask->parent == '-1')
if($oldTask->parent == '-1')
{
unset($task->assignedTo);
$this->dao->update(TABLE_TASK)->data($task)->autoCheck()->where('parent')->eq((int)$taskID)->exec();
@@ -1695,7 +1695,7 @@ class taskModel extends model
->exec();
if($oldTask->parent > 0) $this->updateParentStatus($taskID);
if($oldTask->parent == '-1')
if($oldTask->parent == '-1')
{
unset($task->left);
$this->dao->update(TABLE_TASK)->data($task)->autoCheck()->where('parent')->eq((int)$taskID)->exec();
-1
View File
@@ -23,7 +23,6 @@
<?php endif;?>
</h2>
</div>
<form method='post' target='hiddenwin'>
<table class='table table-form'>
<tr class='hide'>
+2 -7
View File
@@ -92,16 +92,11 @@ class testcase extends control
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = pager::init($recTotal, $recPerPage, $pageID);
$pager = new pager($recTotal, $recPerPage, $pageID);
$sort = $this->loadModel('common')->appendOrder($orderBy);
/* Get test cases. */
$cases = $this->testcase->getTestCases($productID, $branch, $browseType, $browseType == 'bysearch' ? $queryID : $suiteID, $moduleID, $sort, $pager);
if(empty($cases) and $pageID > 1)
{
$pager = pager::init(0, $recPerPage, 1);
$cases = $this->testcase->getTestCases($productID, $branch, $browseType, $browseType == 'bysearch' ? $queryID : $suiteID, $moduleID, $sort, $pager);
}
/* save session .*/
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', $browseType != 'bysearch' ? false : true);
@@ -1504,7 +1499,7 @@ class testcase extends control
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = pager::init(0, $recPerPage, $pageID);
$pager = new pager($recTotal, $recPerPage, $pageID);
$this->view->title = $this->lang->testcase->common . $this->lang->colon . $this->lang->testcase->importFromLib;
$this->view->position[] = $this->lang->testcase->importFromLib;
+4 -9
View File
@@ -63,11 +63,6 @@ class testreport extends control
$pager = pager::init($recTotal, $recPerPage, $pageID);
$reports = $this->testreport->getList($objectID, $objectType, $extra, $orderBy, $pager);
if(empty($reports) and $pageID > 1)
{
$pager = pager::init(0, $recPerPage, 1);
$reports = $this->testreport->getList($objectID, $objectType, $extra, $orderBy, $pager);
}
if($objectType == 'project' and isset($_POST['taskIdList']))
{
@@ -450,7 +445,7 @@ class testreport extends control
$tasks = $report->tasks ? $this->testtask->getByList($report->tasks) : array();;
$builds = $report->builds ? $this->build->getByList($report->builds) : array();
$cases = $this->testreport->getTaskCases($tasks, $report->begin, $report->end, $report->cases, $pager);
$totalCases = $this->testreport->getTaskCases($tasks, $report->begin, $report->end, $report->cases);
$caseIdList = $this->testreport->getCaseIdList($reportID);
$bugInfo = $this->testreport->getBugInfo($tasks, $report->product, $report->begin, $report->end, $builds);
if($report->objectType == 'testtask')
@@ -478,10 +473,10 @@ class testreport extends control
$this->view->actions = $this->loadModel('action')->getList('testreport', $reportID);
$this->view->storySummary = $this->product->summary($stories);
$this->view->caseSummary = $this->testreport->getResultSummary($tasks, $totalCases, $report->begin, $report->end);
$this->view->caseSummary = $this->testreport->getResultSummary($tasks, $caseIdList, $report->begin, $report->end);
$perCaseResult = $this->testreport->getPerCaseResult4Report($tasks, $totalCases, $report->begin, $report->end);
$perCaseRunner = $this->testreport->getPerCaseRunner4Report($tasks, $totalCases, $report->begin, $report->end);
$perCaseResult = $this->testreport->getPerCaseResult4Report($tasks, $caseIdList, $report->begin, $report->end);
$perCaseRunner = $this->testreport->getPerCaseRunner4Report($tasks, $caseIdList, $report->begin, $report->end);
$this->view->datas['testTaskPerRunResult'] = $this->loadModel('report')->computePercent($perCaseResult);
$this->view->datas['testTaskPerRunner'] = $this->report->computePercent($perCaseRunner);
+20
View File
@@ -362,6 +362,24 @@ class testreportModel extends model
return $cases;
}
/**
* Get caseID list.
*
* @param int $reportID
* @access public
* @return void
*/
public function getCaseIdList($reportID)
{
$caseIdList = $this->dao->select('`case`')->from(TABLE_TESTREPORT)->alias('t1')
->leftJoin(TABLE_TESTRUN)->alias('t2')->on('t1.tasks=t2.task')
->where('t1.id')->eq($reportID)
->andWhere('t1.deleted')->eq(0)
->fetchPairs('case');
return $caseIdList;
}
/**
* Get result summary.
*
@@ -409,6 +427,7 @@ class testreportModel extends model
->leftJoin(TABLE_TESTRUN)->alias('t2')
->on('t1.run= t2.id')
->where('t2.task')->in(array_keys($tasks))
->andwhere('t1.date = t2.lastRunDate')
->andWhere('t1.`case`')->in(array_keys($cases))
->andWhere('t1.date')->ge($begin)
->andWhere('t1.date')->le($end . " 23:59:59")
@@ -440,6 +459,7 @@ class testreportModel extends model
->leftJoin(TABLE_TESTRUN)->alias('t2')
->on('t1.run= t2.id')
->where('t2.task')->in(array_keys($tasks))
->andwhere('t1.date = t2.lastRunDate')
->andWhere('t1.`case`')->in(array_keys($cases))
->andWhere('t1.date')->ge($begin)
->andWhere('t1.date')->le($end . " 23:59:59")
-5
View File
@@ -54,11 +54,6 @@ class testsuite extends control
$productName = isset($this->products[$productID]) ? $this->products[$productID] : '';
$suites = $this->testsuite->getSuites($productID, $sort, $pager);
if(empty($suites) and $pageID > 1)
{
$pager = pager::init(0, $recPerPage, 1);
$suites = $this->testsuite->getSuites($productID, $sort, $pager);
}
$this->view->title = $productName . $this->lang->testsuite->common;
$this->view->position[] = html::a($this->createLink('testsuite', 'browse', "productID=$productID"), $productName);
-5
View File
@@ -77,11 +77,6 @@ class testtask extends control
/* Get tasks. */
$tasks = $this->testtask->getProductTasks($productID, $branch, $sort, $pager, $scopeAndStatus, $beginTime, $endTime);
if(empty($tasks) and $pageID > 1)
{
$pager = pager::init(0, $recPerPage, 1);
$tasks = $this->testtask->getProductTasks($productID, $branch, $sort, $pager, $scopeAndStatus, $beginTime, $endTime);
}
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->common;
$this->view->position[] = html::a($this->createLink('testtask', 'browse', "productID=$productID"), $this->products[$productID]);
+1 -1
View File
@@ -123,7 +123,7 @@ $lang->testtask->showFail = '失败<span class="text-danger">%s</span>次';
$lang->testtask->confirmDelete = '您确认要删除该测试单吗?';
$lang->testtask->confirmUnlinkCase = '您确认要移除该用例吗?';
$lang->testtask->noticeNoOther = '该产品还没有其他测试单';
$lang->testtask->noTesttask = '暂时没有测试单';
$lang->testtask->noTesttask = '暂时没有测试单。';
$lang->testtask->checkLinked = '请检查测试单的产品是否与项目相关联';
$lang->testtask->noImportData = '导入的XML没有解析出数据。';
$lang->testtask->unitXMLFormat = '请选择Junit XML 格式的文件。';
@@ -77,7 +77,6 @@ function setTemplate(templateID)
var cmd = editor['<?php echo $link;?>'].edit.cmd;
editor['<?php echo $link;?>'].html('');
cmd.inserthtml(content);
$("#mainContent #dataform .table.table-form .steps #templateID").val(templateID);
}
function deleteTemplate(templateID)
+2 -4
View File
@@ -1,4 +1,2 @@
alert('日语是收费功能,需要购买插件安装');
$.cookie('lang', 'zh-cn', {expires:config.cookieLife, path:config.webRoot});
location.href = location.href;
var locateLink = config.webRoot + 'tip4japanese.html';
if(location.href.indexOf(locateLink) < 0) location.href = locateLink;
+2
View File
@@ -58,3 +58,5 @@ a.showMoreImage:hover{opacity: 1;}
.color-darkblue:hover{background:rgb(0,0,139)}
.color-darkblue:focus{background:rgb(0,0,139)}
.margin-l-50px{margin-left:50px;}
.chosen-container .chosen-drop{z-index: 1100;}
+40
View File
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang='zh-cn'>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="renderer" content="webkit">
<title>グリッド・リサーチ株式会社に完全日本語使用権を取得ください</title>
<style>
body{margin:0px;}
p{margin:0px; margin-bottom:3px;}
</style>
</head>
<body>
<div style='width:500px;margin:100px auto; border:1px solid #000; padding:10px;'>
<h5 style='margin-top:0px;'>グリッド・リサーチ株式会社に完全日本語使用権を取得ください</h5>
<div style='font-size:12px;'>
<p>〒104-0041 東京都中央区新富1-15-11 マキプラザ 3階</p>
<p>電話:03-3537-9700(代表)</p>
<p>MailTo:sales1@grids.co.jp</p>
</div>
<div style='margin-top:20px; font-size:13px;'>
Language :
<a style='padding-right:5px;' href="javascript:switchLang('zh-cn')">简体</a>
<a style='padding-right:5px;' href="javascript:switchLang('zh-tw')">繁體</a>
<a style='padding-right:5px;' href="javascript:switchLang('en')">English</a>
<a style='padding-right:5px;' href="javascript:switchLang('de')">Deutsch</a>
<a style='padding-right:5px;' href="javascript:switchLang('fr')">Français</a>
<a style='padding-right:5px;' href="javascript:switchLang('vi')">Tiếng Việt</a>
</div>
</div>
<script>
function switchLang(lang)
{
document.cookie = "lang=" + lang;
location.href = window.location.protocol+"//"+window.location.host;
}
</script>
</body>
</html>