Merge branch 'master' into 'sprint/174_tianshujie_45081'

# Conflicts:
#   module/product/control.php
#   module/story/view/batchedit.html.php
This commit is contained in:
李玉春
2021-11-29 08:03:38 +00:00
109 changed files with 1292 additions and 485 deletions
+68 -2
View File
@@ -9,7 +9,7 @@
* @version 1
* @link http://www.zentao.net
*/
class bugEntry extends entry
class bugEntry extends entry
{
/**
* GET method.
@@ -24,7 +24,73 @@ class bugEntry extends entry
$control->view($bugID);
$data = $this->getData();
$bug = $data->data->bug;
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$bug = $data->data->bug;
/* Set product name */
$bug->productName = $data->data->product->name;
/* Set module title */
$moduleTitle = '';
if(empty($bug->module)) $moduleTitle = '/';
if($bug->module)
{
$modulePath = $data->data->modulePath;
foreach($modulePath as $key => $module)
{
$moduleTitle .= $module->name;
if(isset($modulePath[$key + 1])) $moduleTitle .= '/';
}
}
$bug->moduleTitle = $moduleTitle;
if($bug->openedBy) $bug->openedBy = $this->formatUser($bug->openedBy, $data->data->users);
if($bug->resolvedBy) $bug->resolvedBy = $this->formatUser($bug->resolvedBy, $data->data->users);
if($bug->closedBy) $bug->closedBy = $this->formatUser($bug->closedBy, $data->data->users);
if($bug->lastEditedBy) $bug->lastEditedBy = $this->formatUser($bug->lastEditedBy, $data->data->users);
if($bug->assignedTo)
{
$usersWithAvatar = $this->loadModel('user')->getListByAccounts(array($bug->assignedTo), 'account');
$bug->assignedTo = zget($usersWithAvatar, $bug->assignedTo);
}
$mailto = array();
if($bug->mailto)
{
foreach(explode(',', $bug->mailto) as $account)
{
if(empty($account)) continue;
$mailto[] = $this->formatUser($account, $data->data->users);
}
}
$bug->mailto = $mailto;
$openedBuilds = array();
foreach(explode(',', $bug->openedBuild) as $buildID)
{
if(empty($buildID)) continue;
$openedBuild = new stdclass();
$openedBuild->id = $buildID;
$openedBuild->title = zget($data->data->builds, $buildID, '');
$openedBuilds[] = $openedBuild;
}
$bug->openedBuild = $openedBuilds;
if($bug->resolvedBuild)
{
$resolvedBuild = new stdclass();
$resolvedBuild->id = $bug->resolvedBuild;
$resolvedBuild->title = zget($data->data->builds, $bug->resolvedBuild, '');
$bug->resolvedBuild = $resolvedBuild;
}
$bug->actions = $this->loadModel('action')->processActionForAPI($data->data->actions, $data->data->users, $this->lang->bug);
$this->send(200, $this->format($bug, 'activatedDate:time,openedDate:time,assignedDate:time,resolvedDate:time,closedDate:time,lastEditedDate:time,deadline:date,deleted:bool'));
}
+28 -33
View File
@@ -9,42 +9,22 @@
* @version 1
* @link http://www.zentao.net
*/
class bugsEntry extends entry
class bugsEntry extends entry
{
/**
* GET method.
*
* @param int $productID
* @param int $projectID
* @param int $executionID
* @access public
* @return void
*/
public function get($productID = 0, $projectID = 0, $executionID = 0)
public function get($productID = 0)
{
if(!$productID) $productID = $this->param('product', 0);
if(!$projectID) $projectID = $this->param('project', 0);
if(!$executionID) $executionID = $this->param('execution', 0);
if(empty($productID)) $productID = $this->param('product', 0);
if(empty($productID)) return $this->sendError(400, 'Need product id.');
if($projectID)
{
$control = $this->loadController('project', 'bug');
$control->bug($projectID, $productID, $this->param('order', 'status,id_desc'), $this->param('build', 0), $this->param('status', 'all'), 0, $this->param('limit', 20), $this->param('page', 1));
}
elseif($executionID)
{
$control = $this->loadController('execution', 'bug');
$control->bug($executionID, $productID, $this->param('order', 'status,id_desc'), $this->param('build', 0), $this->param('status', 'all'), 0, $this->param('limit', 20), $this->param('page', 1));
}
elseif($productID)
{
$control = $this->loadController('bug', 'browse');
$control->browse($productID, $this->param('branch', ''), $this->param('status', ''), 0, $this->param('order', ''), 0, $this->param('limit', 20), $this->param('page', 1));
}
else
{
return $this->sendError(400, 'Need product or project or execution id.');
}
$control = $this->loadController('bug', 'browse');
$control->browse($productID, $this->param('branch', 'all'), $this->param('status', ''), 0, $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
@@ -55,16 +35,31 @@ class bugsEntry extends entry
$result = array();
foreach($bugs as $bug)
{
$result[] = $this->format($bug, 'activatedDate:time,openedDate:time,assignedDate:time,resolvedDate:time,closedDate:time,lastEditedDate:time,deadline:date,deleted:bool');
$status = array('code' => $bug->status, 'name' => $this->lang->bug->statusList[$bug->status]);
if($bug->status == 'active' and $bug->confirmed) $status = array('code' => 'confirmed', 'name' => $this->lang->bug->labelConfirmed);
if($bug->resolution == 'postponed') $status = array('code' => 'postponed', 'name' => $this->lang->bug->labelPostponed);
if(!empty($bug->delay)) $status = array('code' => 'delay', 'name' => $this->lang->bug->overdueBugs);
$bug->status = $status;
$result[$bug->id] = $this->format($bug, 'activatedDate:time,openedDate:time,assignedDate:time,resolvedDate:time,closedDate:time,lastEditedDate:time,deadline:date,deleted:bool');
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'bugs' => $result));
$storyChangeds = $this->dao->select('t1.id')->from(TABLE_BUG)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id')
->where('t1.id')->in(array_keys($result))
->andWhere('t1.story')->ne('0')
->andWhere('t1.storyVersion != t2.version')
->fetchPairs('id', 'id');
foreach($storyChangeds as $bugID)
{
$status = array('code' => 'storyChanged', 'name' => $this->lang->bug->changed);
$result[$bugID]->status = $status;
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'bugs' => array_values($result)));
}
if(isset($data->status) and $data->status == 'fail')
{
return $this->sendError(400, $data->message);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
@@ -91,7 +86,7 @@ class bugsEntry extends entry
$this->requireFields('title,pri,severity,type,openedBuild');
$control->create($productID);
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
if(isset($data->result) and !isset($data->id)) return $this->sendError(400, $data->message);
+1 -4
View File
@@ -27,10 +27,7 @@ class buildEntry extends Entry
if(isset($data->status) and $data->status == 'success') return $this->send(200, $this->format($data->data->build, 'stories:idList,bugs:idList,deleted:bool'));
/* Exception handling. */
if(isset($data->status) and $data->status == 'fail')
{
return isset($data->code) and $data->code == 404 ? $this->send404() : $this->sendError(400, $data->message);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$this->sendError(400, 'error');
}
+6 -8
View File
@@ -20,25 +20,23 @@ class buildsEntry extends entry
*/
public function get($projectID = 0)
{
if(!$projectID) $projectID = $this->param('project', 0);
if(empty($projectID)) $projectID = $this->param('project', 0);
if(empty($projectID)) return $this->sendError(400, "Need project id.");
$control = $this->loadController('project', 'build');
$control->build($projectID, $this->param('type', 'all'), $this->param('param', 0));
$control->build($projectID, $this->param('type', 'all'), $this->param('param', 0), $this->param('order', 't1.date_desc,t1.id_desc'));
$data = $this->getData();
if(!isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$result = array();
foreach($data->data->projectBuilds as $productID => $builds)
{
foreach($builds as $build)
{
$result[] = $this->format($build, 'bugs:idList,stories:idList,deleted:bool');
}
foreach($builds as $build) $result[] = $this->format($build, 'bugs:idList,stories:idList,deleted:bool');
}
return $this->send(200, $result);
return $this->send(200, array('total' => count($result), 'builds' => $result));
}
/**
+89
View File
@@ -0,0 +1,89 @@
<?php
/**
* The doc entry point of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package entries
* @version 1
* @link http://www.zentao.net
*/
class docEntry extends entry
{
/**
* GET method.
*
* @param int $docID
* @access public
* @return void
*/
public function get($docID)
{
$control = $this->loadController('doc', 'view');
$control->view($docID);
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$doc = $data->data->doc;
unset($doc->draft);
if(!empty($doc->files)) $doc->files = array_values((array)$doc->files);
/* Set lib name */
$doc->libName = $data->data->lib->name;
/* Format user for api. */
if($doc->editedBy) $doc->editedBy = $this->formatUser($doc->editedBy, $data->data->users);
if($doc->addedBy)
{
$usersWithAvatar = $this->loadModel('user')->getListByAccounts(array($doc->addedBy), 'account');
$doc->addedBy = zget($usersWithAvatar, $doc->addedBy);
}
$this->send(200, $this->format($doc, 'addedDate:time,assignedDate:date,editedDate:time'));
}
/**
* PUT method.
*
* @param int $storyID
* @access public
* @return void
*/
public function put($storyID)
{
$oldStory = $this->loadModel('story')->getByID($storyID);
/* Set $_POST variables. */
$fields = 'type';
$this->batchSetPost($fields, $oldStory);
$this->setPost('parent', 0);
$control = $this->loadController('story', 'edit');
$control->edit($storyID);
$this->getData();
$story = $this->story->getByID($storyID);
$this->sendSuccess(200, $this->format($story, 'openedDate:time,assignedDate:time,reviewedDate:time,lastEditedDate:time,closedDate:time,deleted:bool'));
}
/**
* DELETE method.
*
* @param int $storyID
* @access public
* @return void
*/
public function delete($storyID)
{
$control = $this->loadController('story', 'delete');
$control->delete($storyID, 'yes');
$this->getData();
$this->sendSuccess(200, 'success');
}
}
-5
View File
@@ -33,11 +33,6 @@ class doclibsEntry extends Entry
}
krsort($result);
$lib = new stdclass();
$lib->id = 'files';
$lib->name = $this->lang->doclib->files;
$result[] = $lib;
return $this->send(200, array('libs' => array_values($result)));
}
}
+42 -4
View File
@@ -27,18 +27,48 @@ class executionEntry extends Entry
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail')
{
return isset($data->code) and $data->code == 404 ? $this->send404() : $this->sendError(400, $data->message);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$execution = $this->format($data->data->execution, 'openedDate:time,lastEditedDate:time,closedDate:time,canceledDate:time,begin:date,end:date,realBegan:date,realEnd:date,deleted:bool');
$accounts = array();
$accounts[$execution->PO] = $execution->PO;
$accounts[$execution->PM] = $execution->PM;
$accounts[$execution->QD] = $execution->QD;
$accounts[$execution->RD] = $execution->RD;
$users = $this->loadModel('user')->getListByAccounts($accounts, 'account');
$execution->PO = zget($users, $execution->PO, '');
$execution->PM = zget($users, $execution->PM, '');
$execution->QD = zget($users, $execution->QD, '');
$execution->RD = zget($users, $execution->RD, '');
$execution->progress = ($execution->totalConsumed + $execution->totalLeft) ? round($execution->totalConsumed / ($execution->totalConsumed + $execution->totalLeft) * 100, 1) : 0;
$execution->teamMembers = array_values((array)$data->data->teamMembers);
$execution->products = array();
foreach($data->data->products as $productID => $executionProduct)
{
$product = new stdclass();
$product->id = $executionProduct->id;
$product->name = $executionProduct->name;
$product->plans = array();
foreach($executionProduct->plans as $planID)
{
$plan = new stdclass();
$plan->id = $planID;
$plan->name = $data->data->planGroups->{$productID}->{$planID};
$product->plans[] = $plan;
}
$execution->products[] = $product;
}
$this->loadModel('testcase');
$execution->caseReview = ($this->config->testcase->needReview or !empty($this->config->testcase->forceReview));
if(!$fields) $this->send(200, $execution);
$users = $data->data->users;
/* Set other fields. */
$fields = explode(',', strtolower($fields));
foreach($fields as $field)
@@ -67,6 +97,14 @@ class executionEntry extends Entry
$execution->stories = array_values($stories);
break;
case 'actions':
$actions = $data->data->actions;
$execution->actions = $this->loadModel('action')->processActionForAPI($actions, $users, $this->lang->execution);
break;
case "dynamics":
$dynamics = $data->data->dynamics;
$execution->dynamics = $this->loadModel('action')->processDynamicForAPI($dynamics);
break;
}
}
+1 -1
View File
@@ -59,7 +59,7 @@ class executionBugsEntry extends entry
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'bugs' => array_values($result)));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
+41
View File
@@ -0,0 +1,41 @@
<?php
/**
* The execution builds entry point of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package entries
* @version 1
* @link http://www.zentao.net
*/
class executionBuildsEntry extends entry
{
/**
* GET method.
*
* @param int $executionID
* @access public
* @return void
*/
public function get($executionID = 0)
{
if(empty($executionID)) $executionID = $this->param('execution', 0);
if(empty($executionID)) return $this->sendError(400, "Need execution id.");
$control = $this->loadController('execution', 'build');
$control->build($executionID, $this->param('status', 'all'), $this->param('param', 0), $this->param('order', 't1.date_desc,t1.id_desc'));
$data = $this->getData();
if(!isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$result = array();
foreach($data->data->executionBuilds as $builds)
{
foreach($builds as $build) $result[] = $this->format($build, 'bugs:idList,stories:idList,deleted:bool');
}
return $this->send(200, array('total' => count($result), 'builds' => $result));
}
}
+1 -1
View File
@@ -42,7 +42,7 @@ class executionCasesEntry extends entry
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'cases' => $result));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
+10 -8
View File
@@ -32,7 +32,7 @@ class executionsEntry extends entry
/* Response */
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$executions = $data->data->executionStats;
$pager = $data->data->pager;
@@ -84,15 +84,17 @@ class executionsEntry extends entry
$this->batchSetPost($fields);
$projectID = $this->param('project', $projectID);
$this->setPost('project', $projectID);
$this->setPost('acl', $this->request('acl', 'private'));
$this->setPost('project', $projectID);
$this->setPost('acl', $this->request('acl', 'private'));
$this->setPost('PO', $this->request('PO', ''));
$this->setPost('PM', $this->request('PM', ''));
$this->setPost('QD', $this->request('QD', ''));
$this->setPost('RD', $this->request('RD', ''));
$this->setPost('whitelist', $this->request('whitelist', array()));
$this->setPost('products', $this->request('products', array()));
$this->setPost('plans', $this->request('plans', array()));
$control = $this->loadController('execution', 'create');
$this->requireFields('name,code,begin,end,days');
$this->setPost('products', $this->request('products', array()));
$this->setPost('plans', $this->request('plans', array()));
$control = $this->loadController('execution', 'create'); $this->requireFields('name,code,begin,end,days');
$control->create($projectID);
$data = $this->getData();
+1 -1
View File
@@ -39,7 +39,7 @@ class executionStoriesEntry extends entry
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'stories' => $result));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
+17
View File
@@ -11,6 +11,23 @@
*/
class fileEntry extends Entry
{
/**
* GET method.
*
* @access public
* @return void
*/
public function get($fileID)
{
$control = $this->loadController('file', 'download');
$control->download($fileID);
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$this->send(200, $data);
}
/**
* PUT method.
*
+1 -4
View File
@@ -27,10 +27,7 @@ class filesEntry extends Entry
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'error')
{
return isset($data->code) and $data->code == 404 ? $this->send404() : $this->sendError(400, $data->message);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$this->send(200, array('id' => $data->id));
}
+1 -1
View File
@@ -30,7 +30,7 @@ class issueEntry extends Entry
$data = $this->getData();
if(!$data or (isset($data->message) and $data->message == '404 Not found')) return $this->send404();
if(isset($data->status) and $data->status == 'success') return $this->send(200, $this->format($data->data->issue, 'createdDate:time,editedDate:time,assignedDate:time'));
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$this->sendError(400, 'error');
}
+1 -1
View File
@@ -28,7 +28,7 @@ class issuesEntry extends entry
$data = $this->getData();
if(!isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$pager = $data->data->pager;
$result = array();
+80
View File
@@ -0,0 +1,80 @@
<?php
/**
* The meetings entry point of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package entries
* @version 1
* @link http://www.zentao.net
*/
class meetingsEntry extends entry
{
/**
* GET method.
*
* @param int $projectID
* @access public
* @return void
*/
public function get($projectID = 0)
{
if(empty($projectID)) $projectID = $this->param('project', 0);
if(empty($projectID)) return $this->sendError(400, 'Need project id.');
$project = $this->loadModel('project')->getByID($projectID);
if(!$project) return $this->send404();
/* Get meetings by project. */
$control = $this->loadController('meeting', 'browse');
$control->browse($projectID, $this->param('status', 'all'), '', $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
if(!isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$pager = $data->data->pager;
$result = array();
foreach($data->data->meetings as $risk)
{
$result[] = $this->format($risk, 'createdDate:time,editedDate:time');
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'meetings' => $result));
}
/**
* POST method.
*
* @param int $projectID
* @access public
* @return void
*/
public function post($projectID = 0)
{
$project = $this->loadModel('project')->getByID($projectID);
if(!$project) return $this->send404();
$fields = 'source,name,category,strategy,status,impact,probability,rate,identifiedDate,plannedClosedDate,actualClosedDate,resolvedBy,assignedTo,prevention,remedy,resolution';
$this->batchSetPost($fields);
$this->setPost('impact', $this->request('impact', 3));
$this->setPost('probability', $this->request('probability', 3));
$this->setPost('rate', $this->request('rate', 9));
$this->setPost('pri', 'middle');
$control = $this->loadController('risk', 'create');
$this->requireFields('name');
$control->create($projectID);
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
if(isset($data->result) and !isset($data->id)) return $this->sendError(400, $data->message);
$risk = $this->loadModel('risk')->getByID($data->id);
$this->send(201, $this->format($risk, 'createdDate:time,editedDate:time'));
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
/**
* The ping entry point of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package entries
* @version 1
* @link http://www.zentao.net
*/
class pingEntry extends entry
{
/**
* GET method.
*
* @access public
* @return void
*/
public function get()
{
$this->send(200, date('Y-m-d H:i:s'));
}
}
+5 -5
View File
@@ -27,13 +27,13 @@ class productEntry extends Entry
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail')
{
return isset($data->code) and $data->code == 404 ? $this->send404() : $this->sendError(400, $data->message);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$product = $this->format($data->data->product, 'createdDate:time');
$this->loadModel('testcase');
$product->caseReview = ($this->config->testcase->needReview or !empty($this->config->testcase->forceReview));
$users = $data->data->users;
$product->PO = $this->formatUser($product->PO, $users);
$product->QD = $this->formatUser($product->QD, $users);
@@ -108,7 +108,7 @@ class productEntry extends Entry
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
$product = $this->product->getByID($productID);
$this->send(200, array('product' => $this->format($product, 'createdDate:time')));
$this->send(200, $this->format($product, 'createdDate:time'));
}
/**
+1 -4
View File
@@ -27,10 +27,7 @@ class productplanEntry extends Entry
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail')
{
return isset($data->code) and $data->code == 404 ? $this->send404() : $this->sendError(400, $data->message);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$plan = $this->format($data->data->plan, 'begin:date,end:date,deleted:bool');
+17 -2
View File
@@ -33,12 +33,27 @@ class productplansEntry extends entry
$result = array();
$plans = $data->data->plans;
$pager = $data->data->pager;
foreach($plans as $plan) $result[] = $plan;
foreach($plans as $plan)
{
if($plan->parent > 0 and isset($result[$plan->parent]))
{
$parentPlan = $result[$plan->parent];
if(!isset($parentPlan->children) or !is_array($parentPlan->children)) $parentPlan->children = array();
$parentPlan->children[] = $plan;
$result[$plan->parent] = $parentPlan;
}
else
{
$result[$plan->id] = $plan;
}
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'plans' => array_values($result)));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
+128
View File
@@ -0,0 +1,128 @@
<?php
/**
* The product projects entry point of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package entries
* @version 1
* @link http://www.zentao.net
*/
class productProjectsEntry extends entry
{
/**
* GET method.
*
* @param int $productID
* @access public
* @return void
*/
public function get($productID = 0)
{
if(empty($productID)) $productID = $this->param('product', 0);
if(empty($productID)) return $this->sendError('400', "Need product id");
$appendFields = $this->param('fields', '');
$control = $this->loadController('product', 'project');
$control->project($this->param('status', 'all'), $productID, $this->param('branch', 0), $this->param('involved', 0), $this->param('order', 'order_desc'));
$data = $this->getData();
if(isset($data->status) and $data->status == 'success')
{
$result = array();
foreach($data->data->projectStats as $project)
{
foreach($project->hours as $field => $value) $project->$field = $value;
$project = $this->filterFields($project, 'id,name,code,model,type,budget,budgetUnit,parent,begin,end,status,openedBy,openedDate,PM,delay,progress,' . $appendFields);
$result[] = $this->format($project, 'openedDate:time,lastEditedDate:time,closedDate:time,canceledDate:time');
}
$data = array();
$data['total'] = count($result);
$data['projects'] = $result;
$withUser = $this->param('withUser', '');
if(!empty($withUser)) $data['users'] = $users;
return $this->send(200, $data);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
// TODO There is no handle for 401.
return $this->sendError(400, 'error');
}
/**
* POST method.
*
* @access public
* @return void
*/
public function post()
{
$fields = 'name,begin,end,products';
$this->batchSetPost($fields);
$this->setPost('code', $this->request('code', ''));
$this->setPost('acl', $this->request('acl', 'private'));
$this->setPost('parent', $this->request('program', 0));
$this->setPost('whitelist', $this->request('whitelist', array()));
$this->setPost('PM', $this->request('PM', ''));
$this->setPost('model', $this->request('model', 'scrum'));
$control = $this->loadController('project', 'create');
$this->requireFields('name,code,begin,end,products');
$control->create($this->request('model', 'scrum'));
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
if(!isset($data->result)) return $this->sendError(400, 'error');
$project = $this->loadModel('project')->getByID($data->id);
$this->send(201, $this->format($project, 'openedDate:time,lastEditedDate:time,closedDate:time,canceledDate:time'));
}
/**
* Get drop menu.
*
* @access public
* @return void
*/
public function getDropMenu()
{
$control = $this->loadController('project', 'ajaxGetDropMenu');
$control->ajaxGetDropMenu($this->request('projectID', 0), $this->request('module', 'project'), $this->request('method', 'browse'));
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
$dropMenu = array('owner' => array(), 'other' => array(), 'closed' => array());
foreach($data->data->projects as $programID => $projects)
{
foreach($projects as $project)
{
if(helper::diffDate(date('Y-m-d'), $project->end) > 0) $project->delay = true;
$project = $this->filterFields($project, 'id,model,type,name,code,parent,status,PM,delay');
if($project->status == 'closed')
{
$dropMenu['closed'][] = $project;
}
elseif($project->PM == $this->app->user->account)
{
$dropMenu['owner'][] = $project;
}
else
{
$dropMenu['other'][] = $project;
}
}
}
$this->send(200, $dropMenu);
}
}
+3 -3
View File
@@ -34,7 +34,7 @@ class productsEntry extends entry
/* Response */
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$products = $data->data->products;
@@ -113,7 +113,7 @@ class productsEntry extends entry
$control->create($this->request('program', 0));
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
/* Response */
$product = $this->loadModel('product')->getByID($data->id);
@@ -134,7 +134,7 @@ class productsEntry extends entry
$control->ajaxGetDropMenu($this->request('productID', 0), $this->request('module', 'product'), $this->request('method', 'browse'), $this->request('extra', ''), $this->request('from', ''));
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$dropMenu = array('owner' => array(), 'other' => array(), 'closed' => array());
foreach($data->data->products as $programID => $products)
+56
View File
@@ -11,4 +11,60 @@
*/
class programEntry extends Entry
{
/**
* GET method.
*
* @param int $programID
* @access public
* @return void
*/
public function get($programID)
{
$program = $this->loadModel('program')->getByID($programID);
if(!$program) return $this->send404();
$this->send(200, $this->format($program, 'openedDate:time,realBegan:date,realEnd:date,deleted:bool'));
}
/**
* PUT method.
*
* @param int $programID
* @access public
* @return void
*/
public function put($programID)
{
$oldProgram = $this->loadModel('program')->getByID($programID);
/* Set $_POST variables. */
$fields = 'name,PM,budget,budgetUnit,desc,parent,begin,end,realBegan,realEnd,acl,whitelist';
$this->batchSetPost($fields, $oldProgram);
$this->setPost('parent', $this->request('parent', 0));
$control = $this->loadController('program', 'edit');
$control->edit($programID);
$this->getData();
$program = $this->program->getByID($programID);
$this->send(200, $this->format($program, 'openedDate:time'));
}
/**
* DELETE method.
*
* @param int $programID
* @access public
* @return void
*/
public function delete($programID)
{
$control = $this->loadController('program', 'delete');
$control->delete(0, $programID, 'true');
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
$this->sendSuccess(200, 'success');
}
}
+31 -7
View File
@@ -30,15 +30,15 @@ class programsEntry extends Entry
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$programs = (array)$data->data->programs;
$progressList = (array)$data->data->progressList;
$programs = $data->data->programs;
$progressList = $data->data->progressList;
$users = $data->data->users;
$result = array();
foreach($programs as $program)
{
if(isset($progressList[$program->id])) $program->progress = $progressList[$program->id];
if(isset($progressList->{$program->id})) $program->progress = $progressList->{$program->id};
$param = $this->format($program, 'begin:date,end:date,realBegan:date,realEnd:date,openedDate:time,lastEditedDate:time,closedDate:time,canceledDate:time,deleted:bool');
if($mergeChildren)
@@ -57,9 +57,9 @@ class programsEntry extends Entry
$program->labelBudget = $program->budget != 0 ? zget($this->lang->project->currencySymbol, $program->budgetUnit) . ' ' . $programBudget : $this->lang->project->future;
if(empty($program->parent)) $result[$program->id] = $program;
if(isset($programs[$program->parent]))
if(isset($programs->{$program->parent}))
{
$parentProgram = $programs[$program->parent];
$parentProgram = $programs->{$program->parent};
if(!isset($parentProgram->children)) $parentProgram->children = array();
$parentProgram->children[] = $program;
}
@@ -72,6 +72,31 @@ class programsEntry extends Entry
return $this->send(200, array('programs' => array_values($result)));
}
/**
* POST method.
*
* @access public
* @return void
*/
public function post()
{
$fields = 'name,PM,budget,budgetUnit,desc,begin,end';
$this->batchSetPost($fields);
$this->setPost('acl', $this->request('acl', 'open'));
$this->setPost('whitelist', $this->request('whitelist', array()));
$control = $this->loadController('program', 'create');
$this->requireFields('name,begin,end');
$control->create($this->request('parent', 0));
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
$program = $this->loadModel('program')->getByID($data->id);
$this->send(201, $this->format($program, 'openedDate:time,whitelist:stringList'));
}
/**
* Get drop menu.
*
@@ -80,7 +105,6 @@ class programsEntry extends Entry
*/
public function getDropMenu()
{
$programs = $this->dao->select('id,name,parent,path,grade,`order`')->from(TABLE_PROJECT)
->where('deleted')->eq('0')
->andWhere('type')->eq('program')
+6 -2
View File
@@ -28,9 +28,13 @@ class projectEntry extends entry
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$project = $this->format($data->data->project, 'begin:date,end:date,realBegan:date,realEnd:date,openedDate:time,lastEditedDate:time,closedDate:time,canceledDate:time,deleted:bool');
$this->loadModel('testcase');
$project->caseReview = ($this->config->testcase->needReview or !empty($this->config->testcase->forceReview));
if(empty($fields)) return $this->send(200, $project);
/* Set other fields. */
@@ -110,7 +114,7 @@ class projectEntry extends entry
$control->edit($projectID);
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
if(!isset($data->result)) return $this->sendError(400, 'error');
$project = $this->project->getByID($projectID);
+2 -2
View File
@@ -20,7 +20,7 @@ class projectBugsEntry extends entry
*/
public function get($projectID = 0)
{
if(!$projectID) $projectID = $this->param('project', 0);
if(empty($projectID)) $projectID = $this->param('project', 0);
if(empty($projectID)) return $this->sendError(400, 'Need project id.');
$control = $this->loadController('project', 'bug');
@@ -59,7 +59,7 @@ class projectBugsEntry extends entry
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'bugs' => array_values($result)));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
+51
View File
@@ -0,0 +1,51 @@
<?php
/**
* The project cases entry point of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package entries
* @version 1
* @link http://www.zentao.net
*/
class projectCasesEntry extends entry
{
/**
* GET method.
*
* @param int $projectID
* @access public
* @return void
*/
public function get($projectID = 0)
{
if(!$projectID) $projectID = $this->param('project', 0);
if(empty($projectID)) return $this->sendError(400, 'Need project id.');
$this->app->tab = 'project';
$this->app->session->set('project', $projectID, $this->app->tab);
$control = $this->loadController('project', 'testcase');
$control->testcase($projectID, $this->param('product', 0), $this->param('branch', 0), $this->param('status', 'all'), 0, $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
if(isset($data->status) and $data->status == 'success')
{
$cases = $data->data->cases;
$pager = $data->data->pager;
$result = array();
foreach($cases as $case)
{
$case->status = array('code' => $case->status, 'name' => $this->lang->testcase->statusList[$case->status]);
$result[] = $this->format($case, 'openedDate:time,reviewedDate:date,lastEditedDate:time,lastRunDate:time');
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'cases' => $result));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
}
+20 -2
View File
@@ -9,7 +9,7 @@
* @version 1
* @link http://www.zentao.net
*/
class projectreleasesEntry extends entry
class projectReleasesEntry extends entry
{
/**
* GET method.
@@ -20,7 +20,25 @@ class projectreleasesEntry extends entry
*/
public function get($projectID = 0)
{
$this->fetch('releases', 'get', array('productID' => 0, 'projectID' => $projectID));
if(empty($projectID)) $projectID = $this->param('project');
if(empty($projectID)) return $this->sendError(400, 'Need project id.');
$control = $this->loadController('projectrelease', 'browse');
$control->browse($projectID, $this->param('execution', 0), $this->param('status', 'all'), $this->param('order', 't1.date_desc'));
/* Response */
$data = $this->getData();
if(isset($data->status) and $data->status == 'success')
{
$result = array();
$releases = $data->data->releases;
foreach($releases as $release) $result[] = $this->format($release, 'deleted:bool,date:date');
return $this->send(200, array('total' => count($result), 'releases' => $result));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
/**
+2 -4
View File
@@ -64,9 +64,7 @@ class projectsEntry extends entry
return $this->send(200, $data);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
// TODO There is no handle for 401.
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
@@ -99,7 +97,7 @@ class projectsEntry extends entry
$project = $this->loadModel('project')->getByID($data->id);
$this->send(201, $this->format($project, 'openedDate:time,lastEditedDate:time,closedDate:time,canceledDate:time'));
$this->send(201, $this->format($project, 'openedDate:time,lastEditedDate:time,closedDate:time,canceledDate:time,budget:int'));
}
/**
+1 -2
View File
@@ -39,8 +39,7 @@ class projectStoriesEntry extends entry
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'stories' => $result));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
}
+1 -4
View File
@@ -25,10 +25,7 @@ class releaseEntry extends Entry
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail')
{
return isset($data->code) and $data->code == 404 ? $this->send404() : $this->sendError(400, $data->message);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$release = $this->format($data->data->release, 'date:date,deleted:bool');
+7 -18
View File
@@ -15,26 +15,16 @@ class releasesEntry extends entry
* GET method.
*
* @param int $productID
* @param int $projectID
* @access public
* @return void
*/
public function get($productID = 0, $projectID = 0)
public function get($productID = 0)
{
if(!$productID) $productID = $this->param('product');
if(!$projectID) $projectID = $this->param('project');
if(!$productID and !$projectID) return $this->sendError(400, 'Need product or project id.');
if(empty($productID)) $productID = $this->param('product');
if(empty($productID)) return $this->sendError(400, 'Need product id.');
if($projectID)
{
$control = $this->loadController('projectrelease', 'browse');
$control->browse($projectID, 0, $this->param('status', 'all'));
}
else
{
$control = $this->loadController('release', 'browse');
$control->browse($productID, $this->param('branch', 0), $this->param('status', 'all'));
}
$control = $this->loadController('release', 'browse');
$control->browse($productID, $this->param('branch', 0), $this->param('status', 'all'), $this->param('order', 't1.date_desc'));
/* Response */
$data = $this->getData();
@@ -44,11 +34,10 @@ class releasesEntry extends entry
$releases = $data->data->releases;
foreach($releases as $release) $result[] = $this->format($release, 'deleted:bool,date:date');
return $this->send(200, array('releases' => $result));
return $this->send(200, array('total' => count($result), 'releases' => $result));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
}
+1 -1
View File
@@ -26,7 +26,7 @@ class riskEntry extends Entry
$data = $this->getData();
if(!$data or (isset($data->message) and $data->message == '404 Not found')) return $this->send404();
if(isset($data->status) and $data->status == 'success') return $this->send(200, $this->format($data->data->risk, 'createdDate:time,editedDate:time'));
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$this->sendError(400, 'error');
}
+1 -1
View File
@@ -39,7 +39,7 @@ class risksEntry extends entry
}
if(!isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$pager = $data->data->pager;
$result = array();
+1 -3
View File
@@ -55,9 +55,7 @@ class stakeholdersEntry extends entry
return $this->send(200, $data);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
// TODO There is no handle for 401.
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
+2 -2
View File
@@ -28,7 +28,7 @@ class storiesEntry extends entry
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$stories = $data->data->stories;
$pager = $data->data->pager;
@@ -68,7 +68,7 @@ class storiesEntry extends entry
$control->create($productID);
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
if(isset($data->result) and !isset($data->id)) return $this->sendError(400, $data->message);
$story = $this->loadModel('story')->getByID($data->id);
+82 -2
View File
@@ -23,8 +23,88 @@ class storyEntry extends Entry
$control = $this->loadController('story', 'view');
$control->view($storyID);
$data = $this->getData();
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$story = $data->data->story;
if(!empty($story->children)) $story->children = array_values((array)$story->children);
if(isset($story->planTitle)) $story->planTitle = array_values((array)$story->planTitle);
if($story->parent > 0) $story->parentPri = $this->dao->select('pri')->from(TABLE_STORY)->where('id')->eq($story->parent)->fetch('pri');
/* Set product name */
$story->productName = $data->data->product->name;
/* Set module title */
$moduleTitle = '';
if(empty($story->module)) $moduleTitle = '/';
if($story->module)
{
$modulePath = $data->data->modulePath;
foreach($modulePath as $key => $module)
{
$moduleTitle .= $module->name;
if(isset($modulePath[$key + 1])) $moduleTitle .= '/';
}
}
$story->moduleTitle = $moduleTitle;
/* Format user for api. */
if($story->assignedTo) $story->assignedTo = $this->formatUser($story->assignedTo, $data->data->users);
if($story->closedBy) $story->closedBy = $this->formatUser($story->closedBy, $data->data->users);
if($story->lastEditedBy) $story->lastEditedBy = $this->formatUser($story->lastEditedBy, $data->data->users);
if($story->openedBy)
{
$usersWithAvatar = $this->loadModel('user')->getListByAccounts(array($story->openedBy), 'account');
$story->openedBy = zget($usersWithAvatar, $story->openedBy);
}
$mailto = array();
if($story->mailto)
{
foreach(explode(',', $story->mailto) as $account)
{
if(empty($account)) continue;
$mailto[] = $this->formatUser($account, $data->data->users);
}
}
$story->mailto = $mailto;
$reviewedBy = array();
if($story->reviewer)
{
foreach($story->reviewer as $account)
{
if(empty($account)) continue;
$reviewedBy[] = $this->formatUser($account, $data->data->users);
}
}
$story->reviewedBy = $reviewedBy;
$storyTasks = array();
foreach($story->tasks as $executionTasks)
{
foreach($executionTasks as $task)
{
if(!isset($data->data->executions->{$task->execution})) continue;
$storyTasks[] = $this->filterFields($task, 'id,name,type');
}
}
$story->tasks = $storyTasks;
$story->bugs = array();
foreach($data->data->bugs as $bug) $story->bugs[] = $this->filterFields($bug, 'id,title');
$story->cases = array();
foreach($data->data->cases as $case) $story->cases[] = $this->filterFields($case, 'id,title');
$story->requirements = array();
foreach($data->data->relations as $relation) $story->requirements[] = $this->filterFields($relation, 'id,title');
$story->actions = $this->loadModel('action')->processActionForAPI($data->data->actions, $data->data->users, $this->lang->story);
$this->send(200, $this->format($story, 'openedDate:time,assignedDate:time,reviewedDate:time,lastEditedDate:time,closedDate:time'));
}
@@ -49,7 +129,7 @@ class storyEntry extends Entry
$this->getData();
$story = $this->story->getByID($storyID);
$this->sendSuccess(200, $this->format($story, 'openedDate:time,assignedDate:time,reviewedDate:time,lastEditedDate:time,closedDate:time,deleted:bool'));
$this->send(200, $this->format($story, 'openedDate:time,assignedDate:time,reviewedDate:time,lastEditedDate:time,closedDate:time,deleted:bool'));
}
/**
+4 -3
View File
@@ -35,12 +35,13 @@ class storyChangeEntry extends Entry
}
$control = $this->loadController('story', 'change');
$this->requireFields('title,spec');
$this->requireFields('title,spec,verify');
$control->change($storyID);
$data = $this->getData();
if($data->status == 'fail') return $this->sendError(400, $data->message);
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$story = $this->loadModel('story')->getByID($storyID);
+71 -4
View File
@@ -26,12 +26,79 @@ class taskEntry extends Entry
$data = $this->getData();
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail')
{
return isset($data->code) and $data->code == 404 ? $this->send404() : $this->sendError(400, $data->message);
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$task = $data->data->task;
if(!empty($task->children)) $task->children = array_values((array)$task->children);
if($task->parent > 0) $task->parentPri = $this->dao->select('pri')->from(TABLE_TASK)->where('id')->eq($task->parent)->fetch('pri');
/* Set execution name */
$task->executionName = $data->data->execution->name;
/* Set module title */
$moduleTitle = '';
if(empty($task->module)) $moduleTitle = '/';
if($task->module)
{
$modulePath = $data->data->modulePath;
foreach($modulePath as $key => $module)
{
$moduleTitle .= $module->name;
if(isset($modulePath[$key + 1])) $moduleTitle .= '/';
}
}
$task->moduleTitle = $moduleTitle;
/* Format user for api. */
if($task->openedBy) $task->openedBy = $this->formatUser($task->openedBy, $data->data->users);
if($task->finishedBy) $task->finishedBy = $this->formatUser($task->finishedBy, $data->data->users);
if($task->canceledBy) $task->canceledBy = $this->formatUser($task->canceledBy, $data->data->users);
if($task->closedBy) $task->closedBy = $this->formatUser($task->closedBy, $data->data->users);
if($task->lastEditedBy) $task->lastEditedBy = $this->formatUser($task->lastEditedBy, $data->data->users);
$mailto = array();
if($task->mailto)
{
foreach(explode(',', $task->mailto) as $account)
{
if(empty($account)) continue;
$mailto[] = $this->formatUser($account, $data->data->users);
}
}
$task->mailto = $mailto;
$queryAccounts = array();
if($task->assignedTo) $queryAccounts[$task->assignedTo] = $task->assignedTo;
if(!empty($task->team))
{
foreach($task->team as $account => $team) $queryAccounts[$account] = $account;
}
$usersWithAvatar = $this->loadModel('user')->getListByAccounts($queryAccounts, 'account');
$task->assignedTo = zget($usersWithAvatar, $task->assignedTo, '');
if(!empty($task->team))
{
$teams = array();
foreach($task->team as $account => $team)
{
$user = zget($usersWithAvatar, $account, '');
$team->realname = $user ? $user->realname : $account;
$team->avatar = $user ? $user->avatar : '';
$team->estimate = round($team->estimate, 1);
$team->consumed = round($team->consumed, 1);
$team->left = round($team->left, 1);
$allHours = $team->consumed + $team->left;
$team->progress = empty($allHours) ? 0 : round($team->consumed / $allHours * 100, 1);
$teams[] = $team;
}
$task->team = $teams;
}
$task->actions = $this->loadModel('action')->processActionForAPI($data->data->actions, $data->data->users, $this->lang->task);
$this->send(200, $this->format($task, 'openedDate:time,assignedDate:time,realStarted:time,finishedDate:time,canceledDate:time,closedDate:time,lastEditedDate:time,deleted:bool'));
}
+3 -2
View File
@@ -29,9 +29,10 @@ class taskAssignToEntry extends Entry
$this->requireFields('assignedTo');
$control->assignTo($task->execution, $taskID);
$data = $this->getData();
if($data->result == 'fail') return $this->sendError(400, $data->message);
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$task = $this->loadModel('task')->getByID($taskID);
+3 -2
View File
@@ -34,9 +34,10 @@ class taskFinishEntry extends Entry
$control = $this->loadController('task', 'finish');
$this->requireFields('assignedTo,currentConsumed,realStarted,finishedDate');
$control->finish($taskID);
$data = $this->getData();
if($data->result == 'fail') return $this->sendError(400, $data->message);
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$task = $this->loadModel('task')->getByID($taskID);
+2 -3
View File
@@ -43,13 +43,12 @@ class tasksEntry extends entry
foreach($tasks as $task)
{
if(isset($task->children)) $task->children = array_values((array)$task->children);
$result[] = $this->format($task, 'openedDate:time,assignedDate:time,realStarted:time,finishedDate:time,canceledDate:time,closedDate:time,lastEditedDate:time,deleted:bool');
$result[] = $this->format($task, 'deadline:date,openedDate:time,assignedDate:time,realStarted:time,finishedDate:time,canceledDate:time,closedDate:time,lastEditedDate:time,deleted:bool');
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'tasks' => $result));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
+3 -2
View File
@@ -28,9 +28,10 @@ class taskStartEntry extends Entry
$control = $this->loadController('task', 'start');
$this->requireFields('left');
$control->start($taskID);
$data = $this->getData();
if($data->result == 'fail') return $this->sendError(400, $data->message);
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$task = $this->loadModel('task')->getByID($taskID);
+2 -2
View File
@@ -9,7 +9,7 @@
* @version 1
* @link http://www.zentao.net
*/
class testcaseEntry extends entry
class testcaseEntry extends entry
{
/**
* GET method.
@@ -25,7 +25,7 @@ class testcaseEntry extends entry
$data = $this->getData();
if(!$data or (isset($data->message) and $data->message == '404 Not found')) return $this->send404();
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
if(!isset($data->case)) $this->sendError(400, 'error');
$case = $data->case;
+7 -19
View File
@@ -15,28 +15,16 @@ class testcasesEntry extends entry
* GET method.
*
* @param int $productID
* @param int $projectID
* @param int $executionID
* @access public
* @return void
*/
public function get($productID = 0, $projectID = 0, $executionID = 0)
public function get($productID = 0)
{
if(!$productID) $productID = $this->param('product', 0);
if(!$projectID) $projectID = $this->param('project', 0);
if(!$executionID) $executionID = $this->param('execution', 0);
if(!$productID and !$projectID and !$executionID) return $this->sendError(400, 'Need product or project or execution id.');
if(empty($productID)) $productID = $this->param('product', 0);
if(empty($productID)) return $this->sendError(400, 'Need product id.');
if($executionID)
{
$control = $this->loadController('execution', 'testcase');
$control->testcase($executionID, $this->param('status', 'all'), $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
}
else
{
$control = $this->loadController('testcase', 'browse');
$control->browse($productID, $this->param('branch', ''), $this->param('status', 'all'), 0, $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1), $projectID);
}
$control = $this->loadController('testcase', 'browse');
$control->browse($productID, $this->param('branch', ''), $this->param('status', 'all'), 0, $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
@@ -47,14 +35,14 @@ class testcasesEntry extends entry
$result = array();
foreach($cases as $case)
{
$case->status = array('code' => $case->status, 'name' => $this->lang->testcase->statusList[$case->status]);
$result[] = $this->format($case, 'openedDate:time,lastEditedDate:time,lastRunDate:time,scriptedDate:date,reviewedDate:date,deleted:bool');
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'testcases' => $result));
}
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
return $this->sendError(400, 'error');
}
+2 -2
View File
@@ -9,7 +9,7 @@
* @version 1
* @link http://www.zentao.net
*/
class testtaskEntry extends entry
class testtaskEntry extends entry
{
/**
* GET method.
@@ -24,7 +24,7 @@ class testtaskEntry extends entry
$control->view($testtaskID);
$data = $this->getData();
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
if(!isset($data->data->task)) $this->sendError(400, 'error');
$testtask = $data->data->task;
+1 -1
View File
@@ -29,7 +29,7 @@ class testtasksEntry extends entry
$data = $this->getData();
if(!isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$pager = $data->data->pager;
$result = array();
+5 -4
View File
@@ -9,7 +9,7 @@
* @version 1
* @link http://www.zentao.net
*/
class todoEntry extends entry
class todoEntry extends entry
{
/**
* GET method.
@@ -25,7 +25,8 @@ class todoEntry extends entry
$data = $this->getData();
if(!$data or (isset($data->message) and $data->message == '404 Not found')) return $this->send404();
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$todo = $data->data->todo;
$this->send(200, $this->format($todo, 'assignedDate:time,finishedDate:time,closedDate:time'));
@@ -45,7 +46,7 @@ class todoEntry extends entry
/* Set $_POST variables. */
$fields = 'date,type,name,pri,desc,status,begin,end,private';
$this->batchSetPost($fields, $oldTodo);
$this->setPost('idvalue', 0);
$this->setPost('date', $this->request('date', date("Y-m-d", strtotime($oldTodo->date))));
$this->setPost('begin', $this->request('begin') ? str_replace(':', '', $this->request('begin')) : $oldTodo->begin);
@@ -57,7 +58,7 @@ class todoEntry extends entry
$data = $this->getData();
if(!isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$todo = $this->todo->getByID($todoID);
$this->send(200, $this->format($todo, 'assignedDate:time,finishedDate:time,closedDate:time'));
+2 -1
View File
@@ -24,7 +24,8 @@ class todoActivateEntry extends Entry
$control->activate($todoID);
$data = $this->getData();
if($data->status == 'fail') return $this->sendError(400, $data->message);
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$todo = $this->loadModel('todo')->getByID($todoID);
$this->send(200, $this->format($todo, 'assignedDate:time,finishedDate:time,closedDate:time'));
+2 -1
View File
@@ -24,7 +24,8 @@ class todoFinishEntry extends Entry
$control->finish($todoID);
$data = $this->getData();
if($data->status == 'fail') return $this->sendError(400, $data->message);
if(!$data or !isset($data->status)) return $this->send400('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$todo = $this->loadModel('todo')->getByID($todoID);
$this->send(200, $this->format($todo, 'assignedDate:time,finishedDate:time,closedDate:time'));
+1 -1
View File
@@ -24,7 +24,7 @@ class todosEntry extends entry
$data = $this->getData();
if(!isset($data->status)) return $this->sendError(400, 'error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$pager = $data->data->pager;
$result = array();
+1 -1
View File
@@ -73,7 +73,7 @@ class usersEntry extends entry
$control->create();
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
if(isset($data->result) and !isset($data->id)) return $this->sendError(400, $data->message);
$user = $this->loadModel('user')->getByID($data->id, 'id');
-1
View File
@@ -207,7 +207,6 @@ $filter->api->edit->get['libID'] = 'int';
$filter->api->edit->get['module'] = 'int';
$filter->api->edit->get['apiID'] = 'int';
$filter->file->download->cookie[$config->sessionVar] = 'code';
$filter->mail->ztcloud->cookie['ztCloudLicense'] = 'equal::yes';
+27 -19
View File
@@ -6,6 +6,7 @@ $routes = array();
$routes['/tokens'] = 'tokens';
$routes['/langs'] = 'langs';
$routes['/ping'] = 'ping';
$routes['/comments'] = 'comments';
$routes['/tabs/:module'] = 'tabs';
@@ -28,8 +29,8 @@ $routes['/products/:id/plans'] = 'productPlans';
$routes['/productplans/:id'] = 'productPlan';
$routes['/releases'] = 'releases';
$routes['/product/:id/releases'] = 'releases';
$routes['/projects/:id/releases'] = 'projectreleases';
$routes['/products/:id/releases'] = 'releases';
$routes['/projects/:id/releases'] = 'projectReleases';
$routes['/releases/:id'] = 'release';
$routes['/stories'] = 'stories';
@@ -46,19 +47,20 @@ $routes['/bugs'] = 'bugs';
$routes['/bugs/:id'] = 'bug';
$routes['/programs/:id/projects'] = 'projects';
$routes['/products/:id/projects'] = 'productProjects';
$routes['/projects'] = 'projects';
$routes['/projects/:id'] = 'project';
$routes['/projects/:project/executions'] = 'executions';
$routes['/executions'] = 'executions';
$routes['/executions/:id'] = 'execution';
$routes['/projects/:id/executions'] = 'executions';
$routes['/executions'] = 'executions';
$routes['/executions/:id'] = 'execution';
$routes['/executions/:execution/tasks'] = 'tasks';
$routes['/tasks'] = 'tasks';
$routes['/tasks/:id'] = 'task';
$routes['/tasks/:id/assignto'] = 'taskAssignTo';
$routes['/tasks/:id/start'] = 'taskStart';
$routes['/tasks/:id/finish'] = 'taskFinish';
$routes['/executions/:id/tasks'] = 'tasks';
$routes['/tasks'] = 'tasks';
$routes['/tasks/:id'] = 'task';
$routes['/tasks/:id/assignto'] = 'taskAssignTo';
$routes['/tasks/:id/start'] = 'taskStart';
$routes['/tasks/:id/finish'] = 'taskFinish';
$routes['/users'] = 'users';
$routes['/users/:id'] = 'user';
@@ -69,22 +71,24 @@ $routes['/programs/:id'] = 'program';
$routes['/programs/:id/stakeholders'] = 'stakeholders';
$routes['/products/:productID/issues'] = 'productIssues';
$routes['/projects/:projectID/issues'] = 'issues';
$routes['/issues'] = 'issues';
$routes['/issues/:issueID'] = 'issue';
$routes['/products/:id/issues'] = 'productIssues';
$routes['/projects/:id/issues'] = 'issues';
$routes['/issues'] = 'issues';
$routes['/issues/:id'] = 'issue';
$routes['/todos'] = 'todos';
$routes['/todos/:id'] = 'todo';
$routes['/todos/:id/finish'] = 'todoFinish';
$routes['/todos/:id/activate'] = 'todoActivate';
$routes['/projects/:projectID/builds'] = 'builds';
$routes['/builds'] = 'builds';
$routes['/builds/:id'] = 'build';
$routes['/projects/:id/builds'] = 'builds';
$routes['/executions/:id/builds'] = 'executionBuilds';
$routes['/builds'] = 'builds';
$routes['/builds/:id'] = 'build';
$routes['/products/:id/testcases'] = 'testcases';
$routes['/executions/:id/testcases'] = 'executioncases';
$routes['/projects/:id/testcases'] = 'projectCases';
$routes['/executions/:id/testcases'] = 'executionCases';
$routes['/testcases'] = 'testcases';
$routes['/testcases/:id'] = 'testcase';
@@ -96,6 +100,10 @@ $routes['/projects/:projectID/risks'] = 'risks';
$routes['/risks'] = 'risks';
$routes['/risks/:id'] = 'risk';
$routes['/projects/:id/meetings'] = 'meetings';
$routes['/meetings'] = 'meetings';
$routes['/meetings/:id'] = 'meeting';
$routes['/departments'] = 'departments';
$routes['/departments/:id'] = 'department';
+12
View File
@@ -589,6 +589,8 @@ class baseEntry
return $value;
case 'bool':
return !empty($value);
case 'int':
return (int) $value;
case 'idList':
$values = explode(',', $value);
if(empty($values)) return array();
@@ -599,6 +601,16 @@ class baseEntry
if($val !== '') $idList[] = (int) $val;
}
return $idList;
case 'stringList':
$values = explode(',', $value);
if(empty($values)) return array();
$stringList = array();
foreach($values as $val)
{
if($val !== '') $stringList[] = $val;
}
return $stringList;
default:
return $value;
}
+6 -5
View File
@@ -82,12 +82,13 @@ class api extends router
$this->httpMethod = strtolower($_SERVER['REQUEST_METHOD']);
$dir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
$this->path = rtrim((strpos($_SERVER['REQUEST_URI'], '?') > 0 ? strstr($_SERVER['REQUEST_URI'], '?', true) : $_SERVER['REQUEST_URI']), '/');
if($dir != '' and strpos($this->path, $dir) === 0) $this->path = substr($this->path, strlen($dir));
$fileName = ltrim(substr($_SERVER['SCRIPT_FILENAME'], strlen($_SERVER['DOCUMENT_ROOT'])), '/');
$this->path = substr(ltrim($_SERVER['REQUEST_URI'], '/'), strlen($fileName) + 1);
if(strpos($this->path, '?') > 0) $this->path = strstr($this->path, '?', true);
$subPos = $dir ? strpos($dir, '/', 1) : 0;
$this->version = $subPos ? substr($dir, $subPos + 1) : '';
$subPos = $this->path ? strpos($this->path, '/') : false;
$this->version = $subPos !== false ? substr($this->path, 0, $subPos) : '';
$this->path = $subPos !== false ? substr($this->path, $subPos) : '';
$this->loadApiLang();
}
+6 -1
View File
@@ -117,7 +117,12 @@ class router extends baseRouter
unset($lang->{$moduleName}->{$section});
if(isset($nullKey))$lang->{$moduleName}->{$section}[$nullKey] = $nullValue;
foreach($fields as $key => $value) $lang->{$moduleName}->{$section}[$key] = $value;
foreach($fields as $key => $value)
{
if(!isset($lang->{$moduleName})) $lang->{$moduleName} = new stdclass();
if(!isset($lang->{$moduleName}->{$section})) $lang->{$moduleName}->{$section} = array();
$lang->{$moduleName}->{$section}[$key] = $value;
}
unset($nullKey);
unset($nullValue);
}
+3
View File
@@ -29,6 +29,9 @@ $lang->action->url = '网址';
$lang->action->contentType = '内容类型';
$lang->action->data = '数据';
$lang->action->result = '结果';
$lang->action->modified = '修改了';
$lang->action->old = '旧值为';
$lang->action->new = '新值为';
$lang->action->trash = '回收站';
$lang->action->undelete = '还原';
+1 -1
View File
@@ -1759,7 +1759,7 @@ class block extends control
$meetingCount = isset($params->meetingCount) ? isset($params->meetingCount) : 0;
$meetings = $this->dao->select('*')->from(TABLE_MEETING)
->Where('deleted')->eq('0')
->where('deleted')->eq('0')
->andWhere('(date')->gt($today)
->orWhere('(begin')->gt($now)
->andWhere('date')->eq($today)
+2 -1
View File
@@ -205,7 +205,8 @@ class branch extends control
*/
public function ajaxGetDropMenu($productID, $branch = 0, $module, $method, $extra = '')
{
$branches = $this->branch->getPairs($productID, 'all');
parse_str($extra, $output);
$branches = $this->branch->getPairs($productID, 'all', isset($output['projectID']) ? $output['projectID'] : 0);
$statusList = $this->dao->select('id,status')->from(TABLE_BRANCH)->where('product')->eq($productID)->fetchPairs();
$this->view->link = $this->loadModel('product')->getProductLink($module, $method, $extra, true);
+1 -1
View File
@@ -93,7 +93,7 @@ class branchModel extends model
$executionBranches = $this->dao->select('branch')->from(TABLE_PROJECTPRODUCT)
->where('project')->eq($executionID)
->andWhere('product')->eq($productID)
->fetchAll();
->fetchAll('branch');
if(empty($executionBranches)) return array();
}
+1 -1
View File
@@ -13,7 +13,7 @@ foreach($branches as $branchID => $branch)
if($branchID == 'all' or empty($branchID) or $statusList[$branchID] == 'active')
{
$activeBranchesHtml .= html::a($linkHtml, $branch, '', "class='$selected' data-key='{$branchesPinyin[$branch]}'");
$activeBranchesHtml .= html::a($linkHtml, $branch, '', "class='$selected' data-key='{$branchesPinyin[$branch]}' data-app='{$this->app->tab}'");
}
else
{
+2 -2
View File
@@ -1205,7 +1205,7 @@ class bugModel extends model
$this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->where('id')->eq((int)$bugID)->exec();
$this->dao->update(TABLE_BUG)->set('activatedCount = activatedCount + 1')->where('id')->eq((int)$bugID)->exec();
$openedBuilds = $this->post->openedBuild;
$openedBuilds = explode(',', $oldBug->openedBuild);
if($openedBuilds)
{
$this->loadModel('build');
@@ -2499,7 +2499,7 @@ class bugModel extends model
}
$allBranch = "`branch` = 'all'";
if($branch !== 'all' and strpos($bugQuery, '`branch` =') === false) $bugQuery .= " AND `branch` in('$branch')";
if($branch !== 'all' and strpos($bugQuery, '`branch` =') === false) $bugQuery .= " AND `branch` in('0','$branch')";
if(strpos($bugQuery, $allBranch) !== false) $bugQuery = str_replace($allBranch, '1', $bugQuery);
$allProject = "`project` = 'all'";
+15 -11
View File
@@ -492,8 +492,8 @@ class build extends control
$this->config->product->search['actionURL'] = $this->createLink('build', 'view', "buildID=$buildID&type=story&link=true&param=" . helper::safe64Encode("&browseType=bySearch&queryID=myQueryID"));
$this->config->product->search['queryID'] = $queryID;
$this->config->product->search['style'] = 'simple';
$this->config->product->search['params']['plan']['values'] = $this->loadModel('productplan')->getForProducts(array($build->product => $build->product));
$this->config->product->search['params']['module']['values'] = $this->tree->getOptionMenu($build->product, 'story', 0);
$this->config->product->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($build->product, $build->branch, 'skipParent');
$this->config->product->search['params']['module']['values'] = $this->tree->getOptionMenu($build->product, 'story', 0, $build->branch);
$this->config->product->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $this->lang->story->statusList);
if($product->type == 'normal')
@@ -503,9 +503,11 @@ class build extends control
}
else
{
$this->config->product->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]);
$branches = array('' => '') + $this->loadModel('branch')->getPairs($build->product, 'noempty');
if($build->branch) $branches = array('' => '', $build->branch => $branches[$build->branch]);
$branchPairs = $this->loadModel('branch')->getPairs($build->product, 'noempty');
$branches = array('' => '') + array(BRANCH_MAIN => $this->lang->branch->main);
if($build->branch) $branches += array($build->branch => $branchPairs[$build->branch]);
$this->config->product->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]);
$this->config->product->search['params']['branch']['values'] = $branches;
}
$this->loadModel('search')->setSearchParams($this->config->product->search);
@@ -516,7 +518,7 @@ class build extends control
}
else
{
$allStories = $this->story->getExecutionStories($build->execution, 0, 0, 't1.`order`_desc', 'byProduct', $build->product, 'story', $build->stories, $pager);
$allStories = $this->story->getExecutionStories($build->execution, $build->product, 0, 't1.`order`_desc', 'byBranch', $build->branch, 'story', $build->stories, $pager);
}
$this->view->allStories = $allStories;
@@ -609,8 +611,8 @@ class build extends control
$this->config->bug->search['actionURL'] = $this->createLink('build', 'view', "buildID=$buildID&type=bug&link=true&param=" . helper::safe64Encode("&browseType=bySearch&queryID=myQueryID"));
$this->config->bug->search['queryID'] = $queryID;
$this->config->bug->search['style'] = 'simple';
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getForProducts(array($build->product => $build->product));
$this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($build->product, $viewType = 'bug', $startModuleID = 0);
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($build->product, $build->branch, 'skipParent');
$this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($build->product, 'bug', 0, $build->branch);
$this->config->bug->search['params']['execution']['values'] = $this->loadModel('product')->getExecutionPairsByProduct($build->product, 0, 'id_desc', $this->session->project);
$this->config->bug->search['params']['openedBuild']['values'] = $this->build->getProductBuildPairs($build->product, $branch = 0, $params = '');
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
@@ -624,9 +626,11 @@ class build extends control
}
else
{
$this->config->bug->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]);
$branches = array('' => '') + $this->loadModel('branch')->getPairs($build->product, 'noempty');
if($build->branch) $branches = array('' => '', $build->branch => $branches[$build->branch]);
$branchPairs = $this->loadModel('branch')->getPairs($build->product, 'noempty');
$branches = array('' => '') + array(BRANCH_MAIN => $this->lang->branch->main);
if($build->branch) $branches += array($build->branch => $branchPairs[$build->branch]);
$this->config->bug->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]);
$this->config->bug->search['params']['branch']['values'] = $branches;
}
$this->loadModel('search')->setSearchParams($this->config->bug->search);
+1 -1
View File
@@ -15,7 +15,7 @@ function loadBranches(productID)
oldBranch = productGroups[productID]['branches'];
}
executionID = $('#execution').val();
executionID = currentTab == 'execution' ? executionID : $('#execution').val();
$.get(createLink('branch', 'ajaxGetBranches', 'productID=' + productID + '&oldBranch=0&param=active&projectID=' + executionID), function(data)
{
if(data)
+6 -4
View File
@@ -55,10 +55,11 @@ class buildModel extends model
* @param int $projectID
* @param string $type
* @param int $param
* @param string $orderBy
* @access public
* @return array
*/
public function getProjectBuilds($projectID = 0, $type = 'all', $param = 0)
public function getProjectBuilds($projectID = 0, $type = 'all', $param = 0, $orderBy = 't1.date_desc,t1.id_desc')
{
return $this->dao->select('t1.*, t2.name as executionName, t2.id as executionID, t3.name as productName, t4.name as branchName')
->from(TABLE_BUILD)->alias('t1')
@@ -70,7 +71,7 @@ class buildModel extends model
->andWhere('t1.project')->ne(0)
->beginIF($type == 'product' and $param)->andWhere('t1.product')->eq($param)->fi()
->beginIF($type == 'bysearch')->andWhere($param)->fi()
->orderBy('t1.date DESC, t1.id desc')
->orderBy($orderBy)
->fetchAll('id');
}
@@ -159,10 +160,11 @@ class buildModel extends model
* @param int $executionID
* @param string $type all|product|bysearch
* @param int|string $param productID|buildQuery
* @param string $orderBy
* @access public
* @return array
*/
public function getExecutionBuilds($executionID, $type = '', $param = '')
public function getExecutionBuilds($executionID, $type = '', $param = '', $orderBy = 't1.date_desc,t1.id_desc')
{
return $this->dao->select('t1.*, t2.name as executionName, t3.name as productName, t4.name as branchName')
->from(TABLE_BUILD)->alias('t1')
@@ -173,7 +175,7 @@ class buildModel extends model
->andWhere('t1.deleted')->eq(0)
->beginIF($type == 'product' and $param)->andWhere('t1.product')->eq($param)->fi()
->beginIF($type == 'bysearch')->andWhere($param)->fi()
->orderBy('t1.date DESC, t1.id desc')
->orderBy($orderBy)
->fetchAll('id');
}
+3 -1
View File
@@ -92,5 +92,7 @@
</form>
</div>
</div>
<?php js::set('productGroups', $productGroups)?>
<?php js::set('productGroups', $productGroups);?>
<?php js::set('executionID', $executionID);?>
<?php js::set('currentTab', $this->app->tab);?>
<?php include '../../common/view/footer.html.php';?>
+3
View File
@@ -106,6 +106,9 @@ $lang->lineNumber = '行号';
$lang->tutorialConfirm = '检测到你尚未退出新手教程模式,是否现在退出?';
$lang->levelExceeded = '层级已超过显示范围,更多信息请前往网页端查看或者是通过搜索方式查看。';
$lang->serviceAgreement = "服务协议";
$lang->privacyPolicy = "隐私政策";
$lang->preShortcutKey = '[快捷键:←]';
$lang->nextShortcutKey = '[快捷键:→]';
$lang->backShortcutKey = '[快捷键:Alt+↑]';
+2 -1
View File
@@ -1865,9 +1865,10 @@ EOD;
{
$queryObjects = $this->dao->query($sql);
$objectList = array();
$key = 'id';
while($object = $queryObjects->fetch())
{
$key = (!$this->session->$typeOnlyCondition and $type == 'testcase' and isset($object->case)) ? 'case' : 'id';
if(!$this->session->$typeOnlyCondition and $type == 'testcase' and isset($object->case)) $key = 'case';
$id = $object->$key;
$objectList[$id] = $id;
}
+6 -2
View File
@@ -476,7 +476,11 @@ class doc extends control
/* Get doc. */
$docID = (int)$docID;
$doc = $this->doc->getById($docID, $version, true);
if(!$doc) die(js::error($this->lang->notFound) . js::locate($this->createLink('doc', 'index')));
if(!$doc)
{
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'code' => 404, 'message' => '404 Not found'));
die(js::error($this->lang->notFound) . js::locate($this->createLink('doc', 'index')));
}
/* The global search opens in the document library. */
if(!isonlybody())
@@ -496,7 +500,7 @@ class doc extends control
}
$browseLink = inLink('objectLibs', "type=$type&objectID=$objectID&libID=$libID&docID=$docID");
$this->locate($browseLink);
if(!(defined('RUN_MODE') && RUN_MODE == 'api')) $this->locate($browseLink);
}
if($doc->contentType == 'markdown')
+4 -3
View File
@@ -986,10 +986,11 @@ class execution extends control
* @param int $executionID
* @param string $type all|product|bysearch
* @param int $param
* @param string $orderBy
* @access public
* @return void
*/
public function build($executionID = 0, $type = 'all', $param = 0)
public function build($executionID = 0, $type = 'all', $param = 0, $orderBy = 't1.date_desc,t1.id_desc')
{
/* Load module and set session. */
$this->loadModel('testtask');
@@ -1015,7 +1016,7 @@ class execution extends control
}
else
{
$builds = $this->loadModel('build')->getExecutionBuilds((int)$executionID, $type, $param);
$builds = $this->loadModel('build')->getExecutionBuilds((int)$executionID, $type, $param, $orderBy);
}
/* Set execution builds. */
@@ -2515,7 +2516,7 @@ class execution extends control
if($browseType == 'bySearch')
{
$allStories = $this->story->getBySearch('', 0, $queryID, 'id', $objectID);
$allStories = $this->story->getBySearch('', '', $queryID, 'id', $objectID);
}
else
{
+5 -2
View File
@@ -549,8 +549,11 @@ class executionModel extends model
}
if(isset($execution->project) and $execution->project) $this->addProjectMembers($execution->project, $teamMembers);
$whitelist = explode(',', $execution->whitelist);
$this->loadModel('personnel')->updateWhitelist($whitelist, 'sprint', $executionID);
if(!empty($execution->whitelist))
{
$whitelist = explode(',', $execution->whitelist);
$this->loadModel('personnel')->updateWhitelist($whitelist, 'sprint', $executionID);
}
/* Fix bug#3074, Update views for team members. */
if($execution->acl != 'open') $this->updateUserView($executionID, 'sprint', $changedAccounts);
+6 -1
View File
@@ -115,7 +115,11 @@ class file extends control
{
if(session_id() != $this->app->sessionID) helper::restartSession($this->app->sessionID);
$file = $this->file->getById($fileID);
if(empty($file)) die("<html><head><meta charset='utf-8'></head><body>{$this->lang->file->fileNotFound}</body></html>");
if(empty($file))
{
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'code' => 404, 'message' => $this->lang->file->fileNotFound));
die("<html><head><meta charset='utf-8'></head><body>{$this->lang->file->fileNotFound}</body></html>");
}
/* Judge the mode, down or open. */
$mode = 'down';
@@ -156,6 +160,7 @@ class file extends control
}
else
{
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'code' => 404, 'message' => $this->lang->file->fileNotFound));
die("<html><head><meta charset='utf-8'></head><body>{$this->lang->file->fileNotFound}</body></html>");
}
}
+1 -1
View File
@@ -148,7 +148,7 @@
if(methodLowerCase === 'browse')
{
var viewType = link.params.view || link.params.$2;
if(['bug', 'case', 'caselib'].includes(viewType)) return link.params.from === 'project' ? 'project' : 'qa';
if(['bug', 'case', 'caselib'].includes(viewType)) return link.params.$5 === 'project' ? 'project' : 'qa';
if(viewType === 'doc' && (link.params.from === 'product' || link.params.$5 == 'product')) return 'product';
if(viewType === 'doc' && (link.params.from === 'project' || link.params.$5 == 'project')) return 'project';
+7 -6
View File
@@ -69,14 +69,15 @@ class product extends control
/**
* The projects which linked the product.
*
* @param string $status
* @param int $productID
* @param int|string $branch
* @param int $involved
* @param string $status
* @param int $productID
* @param int $branch
* @param int $involved
* @param string $orderBy
* @access public
* @return void
*/
public function project($status = 'all', $productID = 0, $branch = '', $involved = 0)
public function project($status = 'all', $productID = 0, $branch = '', $involved = 0, $orderBy = 'order_desc')
{
$this->app->loadLang('execution');
$this->app->loadLang('project');
@@ -88,7 +89,7 @@ class product extends control
/* Get PM id list. */
$accounts = array();
$projectStats = $this->product->getProjectStatsByProduct($productID, $status, $branch, $involved);
$projectStats = $this->product->getProjectStatsByProduct($productID, $status, $branch, $involved, $orderBy);
foreach($projectStats as $project)
{
+8 -4
View File
@@ -533,7 +533,8 @@ class productModel extends model
$notNormalProduct = (isset($currentProduct->type) and $currentProduct->type != 'normal');
$isTrackMethod = ($currentModule == 'story' and $currentMethod == 'track');
$isShowBranchMethod = (strpos($this->config->product->showBranchMethod, $currentMethod) !== false and $currentModule == 'product') || $isTrackMethod;
$isTreeBrowseMethod = ($currentModule == 'tree' and $currentMethod == 'browse');
$isShowBranchMethod = (strpos($this->config->product->showBranchMethod, $currentMethod) !== false and $currentModule == 'product') || $isTrackMethod || $isTreeBrowseMethod;
if($notNormalProduct and strpos(',testsuite,testreport,', ',' . $currentModule . ',') === false and ($this->app->tab == 'qa' or $isShowBranchMethod))
{
$this->lang->product->branch = sprintf($this->lang->product->branch, $this->lang->product->branchName[$currentProduct->type]);
@@ -957,10 +958,11 @@ class productModel extends model
* @param string $browseType
* @param int $branch
* @param int $involved
* @param string $orderBy
* @access public
* @return array
*/
public function getProjectListByProduct($productID, $browseType = 'all', $branch = 0, $involved = 0)
public function getProjectListByProduct($productID, $browseType = 'all', $branch = 0, $involved = 0, $orderBy = 'order_desc')
{
$projectList = $this->dao->select('t2.*')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
@@ -977,6 +979,7 @@ class productModel extends model
->fi()
->beginIF($branch)->andWhere('t1.branch')->in($branch)->fi()
->andWhere('t2.deleted')->eq('0')
->orderBy($orderBy)
->fetchAll('id');
/* Determine how to display the name of the program. */
@@ -997,12 +1000,13 @@ class productModel extends model
* @param string $browseType
* @param int $branch
* @param int $involved
* @param string $orderBy
* @access public
* @return array
*/
public function getProjectStatsByProduct($productID, $browseType = 'all', $branch = 0, $involved = 0)
public function getProjectStatsByProduct($productID, $browseType = 'all', $branch = 0, $involved = 0, $orderBy = 'order_desc')
{
$projects = $this->getProjectListByProduct($productID, $browseType, $branch, $involved);
$projects = $this->getProjectListByProduct($productID, $browseType, $branch, $involved, $orderBy);
if(empty($projects)) return array();
$projectKeys = array_keys($projects);
@@ -30,6 +30,8 @@ a.productName:focus, a.productName:hover {background: #0c64eb; color: #fff !impo
#swapper li > a {padding-top: 4px; padding-bottom: 4px;}
#swapper li {padding-top: 0; padding-bottom: 0;}
#swapper .tree li>.list-toggle {top: -1px;}
#subHeader .tree ul {display: block;}
</style>
<?php
$productCounts = array();
+2 -2
View File
@@ -65,7 +65,7 @@ $projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
echo "<li>" . html::a($this->createLink('projectstory', 'story', "projectID=$projectID"), $lang->product->all) . "</li>";
foreach($projectProducts as $product)
{
echo "<li>" . html::a($this->createLink('projectstory', 'story', "projectID=$projectID&productID=$product->id&branch=0"), $product->name, '', "title='{$product->name}' class='text-ellipsis'") . "</li>";
echo "<li>" . html::a($this->createLink('projectstory', 'story', "projectID=$projectID&productID=$product->id&branch=all"), $product->name, '', "title='{$product->name}' class='text-ellipsis'") . "</li>";
}
?>
</ul>
@@ -245,7 +245,7 @@ $projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
<?php endif;?>
<?php echo $moduleTree;?>
<div class="text-center">
<?php if($productID) common::printLink('tree', 'browse', "rootID=$productID&view=story", $lang->tree->manage, '', "class='btn btn-info btn-wide'");?>
<?php if($productID) common::printLink('tree', 'browse', "rootID=$productID&view=story&currentModuleID=0&branch=$branchID", $lang->tree->manage, '', "class='btn btn-info btn-wide'");?>
<hr class="space-sm" />
</div>
</div>
+6 -3
View File
@@ -156,10 +156,9 @@ class program extends control
{
$programID = $this->program->create();
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $programID));
$this->loadModel('action')->create('program', $programID, 'opened');
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $programID, 'locate' => inlink('browse')));
}
$extra = str_replace(array(',', ' '), array('&', ''), $extra);
@@ -386,7 +385,11 @@ class program extends control
public function delete($programID, $confirm = 'no')
{
$childrenCount = $this->dao->select('count(*) as count')->from(TABLE_PROGRAM)->where('parent')->eq($programID)->andWhere('deleted')->eq(0)->fetch('count');
if($childrenCount) die(js::alert($this->lang->program->hasChildren));
if($childrenCount)
{
if($this->viewType == 'json' or (defined('RUN_MODE') && RUN_MODE == 'api')) return $this->send(array('result' => 'fail', 'message' => 'Cannot delete the program has children'));
die(js::alert($this->lang->program->hasChildren));
}
$productCount = $this->dao->select('count(*) as count')->from(TABLE_PRODUCT)->where('program')->eq($programID)->andWhere('deleted')->eq(0)->fetch('count');
if($productCount) die(js::alert($this->lang->program->hasProduct));
+21 -34
View File
@@ -440,43 +440,30 @@ class programModel extends model
$path = $program->path;
}
$projectList = $this->dao->select('*')->from(TABLE_PROJECT)
->where('deleted')->eq('0')
->beginIF($this->config->systemMode == 'new')->andWhere('type')->eq('project')->fi()
->beginIF($browseType != 'all' and $browseType != 'undone')->andWhere('status')->eq($browseType)->fi()
->beginIF($browseType == 'undone')->andWhere('status')->in('wait,doing')->fi()
->beginIF($path)->andWhere('path')->like($path . '%')->fi()
->beginIF(!$queryAll and !$this->app->user->admin and $this->config->systemMode == 'new')->andWhere('id')->in($this->app->user->view->projects)->fi()
->beginIF(!$queryAll and !$this->app->user->admin and $this->config->systemMode == 'classic')->andWhere('id')->in($this->app->user->view->sprints)->fi()
$projectList = $this->dao->select('distinct t1.*')->from(TABLE_PROJECT)->alias('t1')
->leftJoin(TABLE_TEAM)->alias('t2')->on('t1.id=t2.root')
->leftJoin(TABLE_STAKEHOLDER)->alias('t3')->on('t1.id=t3.objectID')
->where('t1.deleted')->eq('0')
->beginIF($this->config->systemMode == 'new')->andWhere('t1.type')->eq('project')->fi()
->beginIF($this->config->systemMode == 'new' and ($this->cookie->involved or $involved))->andWhere('t2.type')->eq('project')->fi()
->beginIF($this->config->systemMode == 'new' and ($this->cookie->involved or $involved))->andWhere('t3.objectType')->eq('project')->fi()
->beginIF($browseType != 'all' and $browseType != 'undone')->andWhere('t1.status')->eq($browseType)->fi()
->beginIF($browseType == 'undone')->andWhere('t1.status')->in('wait,doing')->fi()
->beginIF($path)->andWhere('t1.path')->like($path . '%')->fi()
->beginIF(!$queryAll and !$this->app->user->admin and $this->config->systemMode == 'new')->andWhere('t1.id')->in($this->app->user->view->projects)->fi()
->beginIF(!$queryAll and !$this->app->user->admin and $this->config->systemMode == 'classic')->andWhere('t1.id')->in($this->app->user->view->sprints)->fi()
->beginIF($this->cookie->involved or $involved)
->andWhere('t1.openedBy', true)->eq($this->app->user->account)
->orWhere('t1.PM')->eq($this->app->user->account)
->orWhere('t2.account')->eq($this->app->user->account)
->orWhere('t3.user')->eq($this->app->user->account)
->orWhere("CONCAT(',', t1.whitelist, ',')")->like("%,{$this->app->user->account},%")
->markRight(1)
->fi()
->orderBy($orderBy)
->page($pager)
->page($pager, 't1.id')
->fetchAll('id');
if($this->cookie->involved or $involved)
{
$stakeholderGroup = $this->dao->select('objectID,user')->from(TABLE_STAKEHOLDER)
->where('deleted')->eq('0')
->andWhere('objectID')->in(array_keys($projectList))
->fetchGroup('objectID', 'user');
$teamMembersGroup = $this->dao->select('root,account')->from(TABLE_TEAM)
->where('root')->in(array_keys($projectList))
->fetchGroup('root','account');
foreach($projectList as $id => $project)
{
$whitelist = explode(",", $project->whitelist);
if($project->openedBy == $this->app->user->account) continue;
if($project->PM == $this->app->user->account) continue;
if(in_array($this->app->user->account, $whitelist)) continue;
if(isset($teamMembersGroup[$project->id][$this->app->user->account])) continue;
if(isset($stakeholderGroup[$project->id][$this->app->user->account])) continue;
unset($projectList[$id]);
$pager->recTotal -= 1;
}
}
/* Determine how to display the name of the program. */
if($programTitle and $this->config->systemMode == 'new')
{
+1 -1
View File
@@ -17,7 +17,7 @@
<?php echo html::a($this->createLink('program', 'stakeholder', "programID=$programID"), '<span class="text">' . $lang->program->stakeholder . '</span>', '', 'class="btn btn-link btn-active-text"');?>
</div>
<div class="btn-toolbar pull-right">
<?php common::printLink('stakeholder', 'create', "programID=$programID", "<i class='icon icon-plus'></i> " . $lang->program->createStakeholder, '', "class='btn btn-primary'");?>
<?php common::printLink('program', 'createStakeholder', "programID=$programID", "<i class='icon icon-plus'></i> " . $lang->program->createStakeholder, '', "class='btn btn-primary'");?>
</div>
</div>
<div id='mainContent' class='main-row fade'>
+6 -3
View File
@@ -967,6 +967,7 @@ class project extends control
{
$this->loadModel('product');
$this->session->set('bugList', $this->app->getURI(true), 'project');
$products = array('0' => $this->lang->product->all) + $this->product->getProducts($projectID, 'all', '', false);
$this->lang->modulePageNav = $this->product->select($products, $productID, 'project', 'testcase', '', $branch, 0, '', false);
@@ -1042,12 +1043,14 @@ class project extends control
/**
* Browse builds of a project.
*
* @param int $projectID
* @param string $type all|product|bysearch
* @param int $param
* @param string $orderBy
* @access public
* @return void
*/
public function build($projectID = 0, $type = 'all', $param = 0)
public function build($projectID = 0, $type = 'all', $param = 0, $orderBy = 't1.date_desc,t1.id_desc')
{
/* Load module and get project. */
$this->loadModel('build');
@@ -1074,11 +1077,11 @@ class project extends control
if($type == 'bysearch')
{
$builds = $this->build->getProjectBuildsBySearch((int)$projectID, (int)$param);
$builds = $this->build->getProjectBuildsBySearch((int)$projectID, (int)$param, $orderBy);
}
else
{
$builds = $this->build->getProjectBuilds((int)$projectID, $type, $param);
$builds = $this->build->getProjectBuilds((int)$projectID, $type, $param, $orderBy);
}
/* Set project builds. */
+4
View File
@@ -11,3 +11,7 @@ td.c-PM {white-space: nowrap; overflow: hidden;}
.icon-cards-view {padding-left: 7px; font-size: 16px;}
.icon-list {padding-left: 7px;}
.panel-actions {position: relative; padding: 0 0;}
@media screen and (max-width: 1460px)
{
th.c-name {width: 360px !important;}
}
+3 -2
View File
@@ -62,10 +62,11 @@ class projectrelease extends control
* @param int $projectID
* @param int $executionID
* @param string $type
* @param string $orderBy
* @access public
* @return void
*/
public function browse($projectID = 0, $executionID = 0, $type = 'all')
public function browse($projectID = 0, $executionID = 0, $type = 'all', $orderBy = 't1.date_desc')
{
$this->session->set('releaseList', $this->app->getURI(true), 'project');
$project = $this->project->getById($projectID);
@@ -81,7 +82,7 @@ class projectrelease extends control
$this->view->execution = $execution;
$this->view->project = $project;
$this->view->products = $this->loadModel('product')->getProducts($projectID);
$this->view->releases = $this->projectrelease->getList($projectID, $type);
$this->view->releases = $this->projectrelease->getList($projectID, $type, $orderBy);
$this->view->projectID = $projectID;
$this->view->executionID = $executionID;
$this->view->type = $type;
+3 -2
View File
@@ -45,10 +45,11 @@ class projectreleaseModel extends model
*
* @param int $projectID
* @param string $type
* @param string $orderBy
* @access public
* @return array
*/
public function getList($projectID, $type = 'all')
public function getList($projectID, $type = 'all', $orderBy = 't1.date_desc')
{
return $this->dao->select('t1.*, t2.name as productName, t3.id as buildID, t3.name as buildName, t3.execution, t4.name as executionName')
->from(TABLE_RELEASE)->alias('t1')
@@ -58,7 +59,7 @@ class projectreleaseModel extends model
->where('t1.project')->eq((int)$projectID)
->beginIF($type != 'all')->andWhere('t1.status')->eq($type)->fi()
->andWhere('t1.deleted')->eq(0)
->orderBy('t1.date DESC')
->orderBy($orderBy)
->fetchAll();
}
+6 -5
View File
@@ -34,20 +34,21 @@ class release extends control
/**
* Browse releases.
*
* @param int $productID
* @param string|int $branch
* @param string $type
* @param int $productID
* @param int $branch
* @param string $type
* @param string $orderBy
* @access public
* @return void
*/
public function browse($productID, $branch = 'all', $type = 'all')
public function browse($productID, $branch = 'all', $type = 'all', $orderBy = 't1.date_desc')
{
$this->commonAction($productID, $branch);
$this->session->set('releaseList', $this->app->getURI(true), 'product');
$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);
$this->view->releases = $this->release->getList($productID, $branch, $type, $orderBy);
$this->view->type = $type;
$this->display();
}
+6 -5
View File
@@ -43,13 +43,14 @@ class releaseModel extends model
/**
* Get list of releases.
*
* @param int $productID
* @param string|int $branch
* @param string $type
* @param int $productID
* @param int $branch
* @param string $type
* @param string $orderBy
* @access public
* @return array
*/
public function getList($productID, $branch = 'all', $type = 'all')
public function getList($productID, $branch = 'all', $type = 'all', $orderBy = 't1.date_desc')
{
return $this->dao->select('t1.*, t2.name as productName, t3.id as buildID, t3.name as buildName, t3.project, t4.name as projectName')
->from(TABLE_RELEASE)->alias('t1')
@@ -60,7 +61,7 @@ class releaseModel extends model
->beginIF($branch !== 'all')->andWhere('t1.branch')->eq($branch)->fi()
->beginIF($type != 'all')->andWhere('t1.status')->eq($type)->fi()
->andWhere('t1.deleted')->eq(0)
->orderBy('t1.date DESC')
->orderBy($orderBy)
->fetchAll();
}
+1 -1
View File
@@ -266,7 +266,7 @@ class searchModel extends model
if($hasUser)
{
$users = $this->loadModel('user')->getPairs('realname|noclosed', $appendUsers);
$users = $this->loadModel('user')->getPairs('realname|noclosed', $appendUsers, $this->config->maxCount);
$users['$@me'] = $this->lang->search->me;
}
if($hasProduct) $products = array('' => '') + $this->loadModel('product')->getPairs('', $this->session->project);
+3 -2
View File
@@ -1687,7 +1687,7 @@ class story extends control
* @access public
* @return void
*/
public function zeroCase($productID = 0, $branchID = 0, $orderBy = 'id_desc')
public function zeroCase($productID = 0, $branchID = 0, $orderBy = 'id_desc', $projectID = 0)
{
$this->session->set('storyList', $this->app->getURI(true) . '#app=' . $this->app->tab, 'product');
$this->session->set('caseList', $this->app->getURI(true), $this->app->tab);
@@ -1700,7 +1700,7 @@ class story extends control
$this->lang->project->menu->qa['subMenu']->testcase['subModule'] = 'story';
$products = $this->product->getProducts($this->session->project, 'all', '', false);
$productID = $this->product->saveState($productID, $products);
$this->lang->modulePageNav = $this->product->select($products, $productID, 'story', 'zeroCase', '', $branchID);
$this->lang->modulePageNav = $this->product->select($products, $productID, 'story', 'zeroCase', "projectID=$projectID", $branchID);
}
else
{
@@ -1721,6 +1721,7 @@ class story extends control
$this->view->stories = $this->story->getZeroCase($productID, $branchID, $sort);
$this->view->users = $this->user->getPairs('noletter');
$this->view->projectID = $projectID;
$this->view->productID = $productID;
$this->view->branchID = $branchID;
$this->view->orderBy = $orderBy;
+4 -3
View File
@@ -132,7 +132,7 @@ $lang->story->version = '版本号';
$lang->story->plan = "所属计划";
$lang->story->planAB = '计划';
$lang->story->comment = '备注';
$lang->story->children = "子{$lang->SRCommon}";
$lang->story->children = "子需求";
$lang->story->childrenAB = "子";
$lang->story->linkStories = "相关{$lang->SRCommon}";
$lang->story->childStories = "细分{$lang->SRCommon}";
@@ -235,7 +235,7 @@ $lang->story->changeList['no'] = '不变更';
$lang->story->changeList['yes'] = '变更';
$lang->story->legendBasicInfo = '基本信息';
$lang->story->legendLifeTime = "{$lang->SRCommon}的一生";
$lang->story->legendLifeTime = "需求的一生";
$lang->story->legendRelated = '相关信息';
$lang->story->legendMailto = '抄送给';
$lang->story->legendAttatch = '附件';
@@ -245,9 +245,10 @@ $lang->story->legendFromBug = '来源Bug';
$lang->story->legendCases = '相关用例';
$lang->story->legendLinkStories = "相关{$lang->SRCommon}";
$lang->story->legendChildStories = "细分{$lang->SRCommon}";
$lang->story->legendSpec = "{$lang->SRCommon}描述";
$lang->story->legendSpec = "需求描述";
$lang->story->legendVerify = '验收标准';
$lang->story->legendMisc = '其他相关';
$lang->story->legendInformation = '需求信息';
$lang->story->lblChange = "变更{$lang->SRCommon}";
$lang->story->lblReview = "评审{$lang->SRCommon}";
+14 -7
View File
@@ -47,7 +47,7 @@ class storyModel extends model
->andWhere('t2.type')->in('sprint,stage')
->orderBy('t1.`order` DESC')
->fetchAll('project');
$story->tasks = $this->dao->select('id, name, assignedTo, execution, status, consumed, `left`')->from(TABLE_TASK)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->orderBy('id DESC')->fetchGroup('execution');
$story->tasks = $this->dao->select('id, name, assignedTo, execution, status, consumed, `left`,type')->from(TABLE_TASK)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->orderBy('id DESC')->fetchGroup('execution');
$story->stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->eq($storyID)->fetchPairs('branch', 'stage');
//$story->bugCount = $this->dao->select('COUNT(*)')->alias('count')->from(TABLE_BUG)->where('story')->eq($storyID)->fetch('count');
//$story->caseCount = $this->dao->select('COUNT(*)')->alias('count')->from(TABLE_CASE)->where('story')->eq($storyID)->fetch('count');
@@ -2456,10 +2456,18 @@ class storyModel extends model
$branches = array();
foreach($products as $product)
{
foreach($product->branches as $branchID) $branches[$branchID] = $branchID;
if($product->type != 'normal')
{
$branches[BRANCH_MAIN] = BRANCH_MAIN;
foreach($product->branches as $branchID)
{
if($branch == BRANCH_MAIN and $branchID) continue;
$branches[$branchID] = $branchID;
}
}
}
$branches = join(',', $branches);
if($branches) $storyQuery .= " AND `branch`" . helper::dbIN($branches);
$storyQuery .= " AND `branch`" . helper::dbIN($branches);
if($this->app->moduleName == 'release' or $this->app->moduleName == 'build')
{
@@ -2600,9 +2608,9 @@ class storyModel extends model
else
{
$productParam = ($type == 'byproduct' and $param) ? $param : $this->cookie->storyProductParam;
$branchParam = $branchID = ($type == 'bybranch' and $param !== '') ? $param : $this->cookie->storyBranchParam;
$branchParam = ($type == 'bybranch' and $param !== '') ? $param : $this->cookie->storyBranchParam;
$moduleParam = ($type == 'bymodule' and $param) ? $param : $this->cookie->storyModuleParam;
$modules = (empty($moduleParam) or $type != 'bymodule') ? array() : $this->dao->select('*')->from(TABLE_MODULE)->where('path')->like("%,$moduleParam,%")->andWhere('type')->eq('story')->andWhere('deleted')->eq(0)->fetchPairs('id', 'id');
$modules = (empty($moduleParam) or strpos(',all,unclosed,bymodule,', ",$type,") === false) ? array() : $this->dao->select('id')->from(TABLE_MODULE)->where('path')->like("%,$moduleParam,%")->andWhere('type')->eq('story')->andWhere('deleted')->eq(0)->fetchPairs();
if(strpos($branchParam, ',') !== false) list($productParam, $branchParam) = explode(',', $branchParam);
$unclosedStatus = $this->lang->story->statusList;
@@ -2627,7 +2635,7 @@ class storyModel extends model
->beginIF($excludeStories)->andWhere('t2.id')->notIN($excludeStories)->fi()
->beginIF($execution->type == 'project')
->beginIF(!empty($productID))->andWhere('t1.product')->eq($productID)
->beginIF($type == 'bybranch' and $branchParam !== '')->andWhere('t2.branch')->eq($branchParam)->fi()
->beginIF($type == 'bybranch' and $branchParam !== '')->andWhere('t2.branch')->in("0,$branchParam")->fi()
->beginIF(strpos('changed|closed', $type) !== false)->andWhere('t2.status')->eq($type)->fi()
->beginIF($type == 'unclosed')->andWhere('t2.status')->in(array_keys($unclosedStatus))->fi()
->beginIF($type == 'linkedexecution')->andWhere('t2.id')->in($storyIdList)->fi()
@@ -2638,7 +2646,6 @@ class storyModel extends model
->beginIF($this->session->executionStoryBrowseType and strpos('changed|', $this->session->executionStoryBrowseType) !== false)->andWhere('t2.status')->in(array_keys($unclosedStatus))->fi()
->fi()
->beginIF($this->session->storyBrowseType and strpos('changed|', $this->session->storyBrowseType) !== false)->andWhere('t2.status')->in(array_keys($unclosedStatus))->fi()
->beginIF(!empty($branchParam))->andWhere('t2.branch')->eq($branchParam)->fi()
->beginIF($modules)->andWhere('t2.module')->in($modules)->fi()
->andWhere('t2.deleted')->eq(0)
->orderBy($orderBy)
+2 -1
View File
@@ -72,11 +72,12 @@ foreach(explode(',', $showFields) as $field)
<?php if($branchProduct):?>
<td class='text-left<?php echo zget($visibleFields, 'branch', ' hidden')?>'>
<?php $disabled = $products[$story->product]->type == 'normal' ? "disabled='disabled'" : '';?>
<?php if($products[$story->product]->type == 'normal') $branches[$story->product] = array();?>
<?php echo html::select("branches[$storyID]", $branches[$story->product], $story->branch, "class='form-control chosen' onchange='loadBranches($story->product, this.value, $storyID);' $disabled");?>
</td>
<?php endif;?>
<td class='text-left<?php echo zget($visibleFields, 'module')?>'>
<?php echo html::select("modules[$storyID]", $modules[$story->product][$story->branch], $story->module, "class='form-control chosen'");?>
<?php echo html::select("modules[$storyID]", isset($modules[$story->product][$story->branch]) ? $modules[$story->product][$story->branch] : array('0' => '/'), $story->module, "class='form-control chosen'");?>
</td>
<td class='text-left<?php echo zget($visibleFields, 'plan', ' hidden')?>'>
<?php echo html::select("plans[$storyID]", isset($plans[$story->product][$story->branch]) ? array('' => '') + $plans[$story->product][$story->branch] : '', $story->plan, "class='form-control chosen'");?>
+2
View File
@@ -25,6 +25,7 @@ $lang->task->delayed = '延期';
$lang->task->view = "查看任务";
$lang->task->logEfforts = "记录工时";
$lang->task->record = "工时";
$lang->task->teamConsumed = "团队工时";
$lang->task->start = "开始";
$lang->task->startAction = "开始任务";
$lang->task->restart = "继续";
@@ -197,6 +198,7 @@ $lang->task->legendBasic = '基本信息';
$lang->task->legendEffort = '工时信息';
$lang->task->legendLife = '任务的一生';
$lang->task->legendDesc = '任务描述';
$lang->task->legendDetail = '任务详情';
$lang->task->confirmDelete = "您确定要删除这个任务吗?";
$lang->task->confirmDeleteEstimate = "您确定要删除这个记录吗?";
+9 -6
View File
@@ -126,6 +126,7 @@ class testcase extends control
if($this->app->tab == 'project')
{
$this->products = array('0' => $this->lang->product->all) + $this->product->getProducts($projectID, 'all', '', false);
$branch = 'all';
$this->loadModel('project')->setMenu($projectID);
}
else
@@ -171,7 +172,7 @@ class testcase extends control
$actionURL = $this->createLink($currentModule, $currentMethod, $projectParam . "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");
$this->config->testcase->search['onMenuBar'] = 'yes';
$this->testcase->buildSearchForm($productID, $this->products, $queryID, $actionURL);
$this->testcase->buildSearchForm($productID, $this->products, $queryID, $actionURL, $projectID);
$showModule = !empty($this->config->datatable->testcaseBrowse->showModule) ? $this->config->datatable->testcaseBrowse->showModule : '';
@@ -182,7 +183,7 @@ class testcase extends control
}
else
{
$moduleTree = $this->tree->getTreeMenu($productID, 'case', 0, array('treeModel', 'createCaseLink'), array('projectID' => $projectID, 'productID' => $productID), $projectID ? 0 : $branch);
$moduleTree = $this->tree->getTreeMenu($productID, 'case', 0, array('treeModel', 'createCaseLink'), array('projectID' => $projectID, 'productID' => $productID), $projectID ? '' : $branch);
}
$product = $this->product->getById($productID);
@@ -197,6 +198,7 @@ class testcase extends control
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common;
$this->view->position[] = html::a($this->createLink('testcase', 'browse', "productID=$productID&branch=$branch"), $this->products[$productID]);
$this->view->position[] = $this->lang->testcase->common;
$this->view->projectID = $projectID;
$this->view->productID = $productID;
$this->view->product = $product;
$this->view->productName = $this->products[$productID];
@@ -230,7 +232,7 @@ class testcase extends control
* @access public
* @return void
*/
public function groupCase($productID = 0, $branch = '', $groupBy = 'story')
public function groupCase($productID = 0, $branch = '', $groupBy = 'story', $projectID = 0)
{
$groupBy = empty($groupBy) ? 'story' : $groupBy;
$productID = $this->product->saveState($productID, $this->products);
@@ -242,7 +244,7 @@ class testcase extends control
if($this->app->tab == 'project')
{
$products = array('0' => $this->lang->product->all) + $this->product->getProducts($this->session->project, 'all', '', false);
$this->lang->modulePageNav = $this->product->select($products, $productID, 'testcase', 'groupCase', '', $branch);
$this->lang->modulePageNav = $this->product->select($products, $productID, 'testcase', 'groupCase', "projectID=$projectID", $branch);
}
$this->session->set('caseList', $this->app->getURI(true), $this->app->tab);
@@ -269,6 +271,7 @@ class testcase extends control
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common;
$this->view->position[] = html::a($this->createLink('testcase', 'groupTask', "productID=$productID&groupBy=$groupBy"), $this->products[$productID]);
$this->view->position[] = $this->lang->testcase->common;
$this->view->projectID = $projectID;
$this->view->productID = $productID;
$this->view->productName = $this->products[$productID];
$this->view->users = $this->user->getPairs('noletter');
@@ -1711,7 +1714,7 @@ class testcase extends control
* @access public
* @return void
*/
public function importFromLib($productID, $branch = 0, $libID = 0, $orderBy = 'id_desc', $browseType = '', $queryID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
public function importFromLib($productID, $branch = 0, $libID = 0, $orderBy = 'id_desc', $browseType = '', $queryID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1, $projectID = 0)
{
$browseType = strtolower($browseType);
$queryID = (int)$queryID;
@@ -1762,7 +1765,7 @@ class testcase extends control
$this->view->libModules = $this->tree->getOptionMenu($libID, 'caselib');
$this->view->pager = $pager;
$this->view->orderBy = $orderBy;
$this->view->branches = $this->loadModel('branch')->getPairs($productID);
$this->view->branches = array('0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, '', $projectID);
$this->view->browseType = $browseType;
$this->view->queryID = $queryID;
+5 -5
View File
@@ -317,9 +317,8 @@ class testcaseModel extends model
{
return $this->dao->select('distinct t1.*, t2.*')->from(TABLE_PROJECTCASE)->alias('t1')
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case=t2.id')
->leftJoin(TABLE_STORY)->alias('t3')->on('t1.story = t3.id')
->leftJoin(TABLE_STORY)->alias('t3')->on('t2.story = t3.id')
->where('t1.project')->eq((int)$executionID)
->beginIF($browseType != 'all')->andWhere('t2.status')->eq($browseType)->fi()
->andWhere('t2.deleted')->eq('0')
->andWhere('t3.version > t2.storyVersion')
->andWhere("t3.status")->eq('active')
@@ -466,7 +465,7 @@ class testcaseModel extends model
/* Cases need confirmed. */
elseif($browseType == 'needconfirm')
{
$cases = $this->dao->select('t1.*, t2.title AS storyTitle')->from(TABLE_CASE)->alias('t1')
$cases = $this->dao->select('distinct t1.*, t2.title AS storyTitle')->from(TABLE_CASE)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
->leftJoin(TABLE_PROJECTCASE)->alias('t3')->on('t1.id = t3.case')
->where("t2.status = 'active'")
@@ -1447,10 +1446,11 @@ class testcaseModel extends model
* @param array $products
* @param int $queryID
* @param string $actionURL
* @param string $projectID
* @access public
* @return void
*/
public function buildSearchForm($productID, $products, $queryID, $actionURL)
public function buildSearchForm($productID, $products, $queryID, $actionURL, $projectID)
{
$product = ($this->app->tab == 'project' and empty($productID)) ? $products : array($productID => $products[$productID]) + array('all' => $this->lang->testcase->allProduct);
$this->config->testcase->search['params']['product']['values'] = $product;
@@ -1474,7 +1474,7 @@ class testcaseModel extends model
{
$productInfo = $this->loadModel('product')->getByID($productID);
$this->config->testcase->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$productInfo->type]);
$this->config->testcase->search['params']['branch']['values'] = array('' => '', '0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
$this->config->testcase->search['params']['branch']['values'] = array('' => '', '0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, '', $projectID) + array('all' => $this->lang->branch->all);
}
if(!$this->config->testcase->needReview) unset($this->config->testcase->search['params']['status']['values']['wait']);
$this->config->testcase->search['actionURL'] = $actionURL;
+1 -1
View File
@@ -42,7 +42,7 @@ js::set('suiteID', $suiteID);
<?php endif;?>
<?php echo $moduleTree;?>
<div class='text-center'>
<?php if(!empty($productID)) common::printLink('tree', 'browse', "productID=$productID&view=case&currentModuleID=0&branch=0&from={$this->lang->navGroup->testcase}", $lang->tree->manage, '', "class='btn btn-info btn-wide'");?>
<?php if(!empty($productID)) common::printLink('tree', 'browse', "productID=$productID&view=case&currentModuleID=0&branch=0&from={$this->app->tab}", $lang->tree->manage, '', "class='btn btn-info btn-wide' data-app='{$this->app->tab}'");?>
<hr class="space-sm" />
</div>
</div>
+3 -3
View File
@@ -89,7 +89,7 @@
$active = !empty($groupBy) ? 'btn-active-text' : '';
echo "<div id='groupTab' class='btn-group'>";
echo html::a($this->createLink('testcase', 'groupCase', "productID=$productID&branch=$branch&groupBy=story"), "<span class='text'>{$lang->testcase->groupByStories}</span>", '', "class='btn btn-link $active' data-app='{$this->app->tab}'");
echo html::a($this->createLink('testcase', 'groupCase', "productID=$productID&branch=$branch&groupBy=story&projectID=$projectID"), "<span class='text'>{$lang->testcase->groupByStories}</span>", '', "class='btn btn-link $active' data-app='{$this->app->tab}'");
echo '</div>';
}
elseif($hasZeroPriv and $menuType == 'zerocase')
@@ -99,7 +99,7 @@
}
elseif($hasUnitPriv and $menuType == 'browseunits')
{
echo html::a($this->createLink('testtask', 'browseUnits', "productID=$productID"), "<span class='text'>{$lang->testcase->browseUnits}</span>", '', "class='btn btn-link' id='browseunitsTab' data-app='{$this->app->tab}'");
echo html::a($this->createLink('testtask', 'browseUnits', "productID=$productID&browseType=newest&orderBy=id_desc&recTotal=0&recPerPage=20&pageID=1&projectID=$projectID"), "<span class='text'>{$lang->testcase->browseUnits}</span>", '', "class='btn btn-link' id='browseunitsTab' data-app='{$this->app->tab}'");
}
?>
<?php endforeach;?>
@@ -143,7 +143,7 @@
$class = common::hasPriv('testcase', 'importFromLib') ? '' : "class=disabled";
$misc = common::hasPriv('testcase', 'importFromLib') ? "data-app='{$this->app->tab}'" : "class=disabled";
$link = common::hasPriv('testcase', 'importFromLib') ? $this->createLink('testcase', 'importFromLib', "productID=$productID&branch=$branch") : '#';
$link = common::hasPriv('testcase', 'importFromLib') ? $this->createLink('testcase', 'importFromLib', "productID=$productID&branch=$branch&libID=0&orderBy=id_desc&browseType=&queryID=10&recTotal=0&recPerPage=20&pageID=1&projectID=$projectID") : '#';
echo "<li $class>" . html::a($link, $lang->testcase->importFromLib, '', $misc . "data-app={$this->app->tab}") . "</li>";
?>
</ul>
+1 -1
View File
@@ -190,7 +190,7 @@ class testsuite extends control
$this->view->orderBy = $orderBy;
$this->view->pager = $pager;
$this->view->modules = $this->loadModel('tree')->getOptionMenu($suite->product, 'case', 0, 'all');
$this->view->branches = $this->loadModel('branch')->getPairs($suite->product, 'noempty');
$this->view->branches = $this->loadModel('branch')->getPairs($suite->product);
$this->view->canBeChanged = common::canBeChanged('testsuite', $suite);
$this->display();
+1
View File
@@ -0,0 +1 @@
.caseModule {overflow: hidden; white-space: nowrap;}

Some files were not shown because too many files have changed in this diff Show More