Merge branch 'master' of github.com:easysoft/zentaopms
@@ -242,5 +242,5 @@ $filter->repo->diff->cookie['repoPairs'] = 'array';
|
||||
$filter->repo->view->cookie['repoPairs'] = 'array';
|
||||
$filter->repo->ajaxsynccommit->cookie['syncBranch'] = 'reg::any';
|
||||
|
||||
$filter->webhook->bind->get['whiteListDept'] = 'reg::checked';
|
||||
$filter->webhook->bind->cookie['whiteListDept'] = 'reg::checked';
|
||||
$filter->webhook->bind->get['selectedDepts'] = 'reg::checked';
|
||||
$filter->webhook->bind->cookie['selectedDepts'] = 'reg::checked';
|
||||
|
||||
@@ -1070,9 +1070,6 @@ class baseDAO
|
||||
$fieldLabel = isset($lang->$table->$fieldName) ? $lang->$table->$fieldName : $fieldName;
|
||||
$value = isset($this->sqlobj->data->$fieldName) ? $this->sqlobj->data->$fieldName : null;
|
||||
|
||||
$moduleName = $table == 'case' ? 'testcase' : $table;
|
||||
$selectFields = isset($config->$moduleName->selectFields) ? $config->$moduleName->selectFields : '';
|
||||
|
||||
/*
|
||||
* 检查唯一性。
|
||||
* Check unique.
|
||||
@@ -1107,13 +1104,6 @@ class baseDAO
|
||||
${"arg$i"} = isset($funcArgs[$i + 2]) ? $funcArgs[$i + 2] : null;
|
||||
}
|
||||
|
||||
/* When check not empty and field is select, then use empty function to check. */
|
||||
if(strtolower($funcName) == 'notempty')
|
||||
{
|
||||
$arg0 = false;
|
||||
if(!empty($selectFields) and strpos(",{$selectFields},", ",{$fieldName},") !== false) $arg0 = true;
|
||||
}
|
||||
|
||||
$checkFunc = 'check' . $funcName;
|
||||
if(validater::$checkFunc($value, $arg0, $arg1, $arg2) === false)
|
||||
{
|
||||
|
||||
@@ -324,17 +324,13 @@ class baseValidater
|
||||
* Not empty checking.
|
||||
*
|
||||
* @param mixed $var
|
||||
* @param bool $useEmpty
|
||||
* @static
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkNotEmpty($var, $useEmpty = false)
|
||||
public static function checkNotEmpty($var)
|
||||
{
|
||||
$var = trim($var);
|
||||
|
||||
if($useEmpty) return !empty($var);
|
||||
return strlen($var) != 0;
|
||||
return !empty($var);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,6 @@ class dingapi
|
||||
private $token;
|
||||
private $expires;
|
||||
private $errors = array();
|
||||
public $maxRequest = 100;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
@@ -48,22 +47,23 @@ class dingapi
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all users.
|
||||
* Get users.
|
||||
*
|
||||
* @param string $whiteListDept
|
||||
* @param string $selectedDepts
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getAllUsers($whiteListDept = '')
|
||||
public function getUsers($selectedDepts = '')
|
||||
{
|
||||
$depts = $this->getAllDepts($whiteListDept);
|
||||
if($this->isError()) return array('result' => 'fail', 'message' => $this->errors);
|
||||
if(empty($whiteListDept) and count($depts) > $this->maxRequest) return array('result' => 'fail', 'message' => 'moreRequest');
|
||||
$depts = trim($selectedDepts);
|
||||
if(empty($depts)) return array('result' => 'fail', 'message' => 'nodept');
|
||||
|
||||
set_time_limit(0);
|
||||
$users = array();
|
||||
foreach($depts as $deptID => $deptName)
|
||||
foreach(explode(',', $depts) as $deptID)
|
||||
{
|
||||
if(empty($deptID)) continue;
|
||||
|
||||
$response = $this->queryAPI($this->apiUrl . "user/simplelist?access_token={$this->token}&department_id={$deptID}");
|
||||
if($this->isError())
|
||||
{
|
||||
@@ -78,80 +78,39 @@ class dingapi
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all depts.
|
||||
*
|
||||
* @param string $whiteList
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getAllDepts($whiteList = '')
|
||||
{
|
||||
$response = $this->queryAPI($this->apiUrl . "department/list?access_token={$this->token}");
|
||||
if($this->isError()) return false;
|
||||
|
||||
/* Get parent and white list parent dept id list. */
|
||||
if($whiteList)
|
||||
{
|
||||
$parentIdList = array();
|
||||
$whiteListParent = array();
|
||||
foreach($response->department as $dept)
|
||||
{
|
||||
if(!empty($dept->parentid)) $parentIdList[$dept->id] = $dept->parentid;
|
||||
if(strpos(",{$whiteList},", ",{$dept->id},") !== false) $whiteListParent[$dept->id] = $dept->id;
|
||||
}
|
||||
}
|
||||
|
||||
$deptPairs = array();
|
||||
foreach($response->department as $dept)
|
||||
{
|
||||
if($whiteList)
|
||||
{
|
||||
if(empty($dept->parentid)) continue;
|
||||
if(isset($whiteListParent[$dept->id]))
|
||||
{
|
||||
$deptPairs[$dept->id] = $dept->name;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check this dept belong to white list. */
|
||||
$isWhiteList = false;
|
||||
$parentID = $dept->parentid;
|
||||
while(isset($parentIdList[$parentID]))
|
||||
{
|
||||
if(isset($whiteListParent[$parentID]))
|
||||
{
|
||||
$isWhiteList = true;
|
||||
break;
|
||||
}
|
||||
|
||||
$parentID = $parentIdList[$parentID];
|
||||
}
|
||||
if(!$isWhiteList) continue;
|
||||
}
|
||||
|
||||
$deptPairs[$dept->id] = $dept->name;
|
||||
}
|
||||
return $deptPairs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get top depts.
|
||||
* Get dept tree.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTopDepts()
|
||||
public function getDeptTree()
|
||||
{
|
||||
$response = $this->queryAPI($this->apiUrl . "department/list?access_token={$this->token}");
|
||||
if($this->isError()) return array('result' => 'fail', 'message' => $this->errors);
|
||||
|
||||
$topDepts = array();
|
||||
$parentDepts = array();
|
||||
foreach($response->department as $dept)
|
||||
{
|
||||
if(isset($dept->parentid) and $dept->parentid == '1') $topDepts[$dept->id] = $dept->name;
|
||||
$parentID = isset($dept->parentid) ? $dept->parentid : 0;
|
||||
$parentDepts[$parentID][$dept->id] = $dept->name;
|
||||
}
|
||||
|
||||
return array('result' => 'success', 'data' => $topDepts);
|
||||
$tree = array();
|
||||
foreach($parentDepts as $parentID => $depts)
|
||||
{
|
||||
foreach($depts as $deptID => $deptName)
|
||||
{
|
||||
$node = array();
|
||||
$node['id'] = $deptID;
|
||||
$node['pId'] = $parentID;
|
||||
$node['name'] = $deptName;
|
||||
if($parentID == 0) $node['open'] = true;
|
||||
|
||||
$tree[] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
return array('result' => 'success', 'data' => $tree);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -677,9 +677,9 @@ class actionModel extends model
|
||||
*/
|
||||
public function getActionCondition()
|
||||
{
|
||||
$actionCondition = '';
|
||||
if(!empty($this->app->user->admin)) return $actionCondition;
|
||||
if($this->app->user->admin) return '';
|
||||
|
||||
$actionCondition = '';
|
||||
if(isset($this->app->user->rights['acls']['actions']))
|
||||
{
|
||||
if(empty($this->app->user->rights['acls']['actions'])) return array();
|
||||
|
||||
@@ -328,7 +328,7 @@ class admin extends control
|
||||
|
||||
$this->loadModel('setting')->setItem('system.admin.log.saveDays', $this->post->days);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'reload'));
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
|
||||
}
|
||||
|
||||
$this->loadModel('message');
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<h2><?php echo $lang->webhook->setting;?></h2>
|
||||
</div>
|
||||
<div class='center-block mw-700px'>
|
||||
<form id='logForm' method='post' class='ajaxForm'>
|
||||
<form id='logForm' method='post' class='form-ajax'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='w-100px'><?php echo $lang->admin->days;?></th>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<?php
|
||||
$config->bug = new stdClass();
|
||||
$config->bug->batchCreate = 10;
|
||||
$config->bug->longlife = 7;
|
||||
$config->bug->selectFields = 'module,project,openedBuild,resolution,pri,severity,type,story,task,os,browser,plan,assignedTo,resolvedBuild';
|
||||
$config->bug->batchCreate = 10;
|
||||
$config->bug->longlife = 7;
|
||||
|
||||
$config->bug->create = new stdclass();
|
||||
$config->bug->edit = new stdclass();
|
||||
|
||||
@@ -12,6 +12,24 @@ function setDuplicate(resolution)
|
||||
|
||||
$(function()
|
||||
{
|
||||
/* Fix bug #3227. */
|
||||
var requiredFields = config.requiredFields;
|
||||
if(requiredFields.indexOf('resolvedBuild') == -1)
|
||||
{
|
||||
resolvedBuildTd = $('#resolvedBuild').closest('td');
|
||||
$('#resolution').change(function()
|
||||
{
|
||||
if($(this).val() == 'fixed')
|
||||
{
|
||||
resolvedBuildTd.addClass('required');
|
||||
}
|
||||
else
|
||||
{
|
||||
resolvedBuildTd.removeClass('required');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('#createBuild').change(function()
|
||||
{
|
||||
if($(this).prop('checked'))
|
||||
|
||||
@@ -145,7 +145,7 @@ class bugModel extends model
|
||||
->setIF($this->post->story != false, 'storyVersion', $this->loadModel('story')->getVersion($this->post->story))
|
||||
->setIF(strpos($this->config->bug->create->requiredFields, 'project') !== false, 'project', $this->post->project)
|
||||
->stripTags($this->config->bug->editor->create['id'], $this->config->allowedTags)
|
||||
->cleanInt('product, module, severity')
|
||||
->cleanInt('product,project,module,severity')
|
||||
->join('openedBuild', ',')
|
||||
->join('mailto', ',')
|
||||
->remove('files, labels,uid,oldTaskID,contactListMenu')
|
||||
@@ -230,10 +230,10 @@ class bugModel extends model
|
||||
$bug = new stdClass();
|
||||
$bug->openedBy = $this->app->user->account;
|
||||
$bug->openedDate = $now;
|
||||
$bug->product = $productID;
|
||||
$bug->branch = $data->branches[$i];
|
||||
$bug->module = $data->modules[$i];
|
||||
$bug->project = $data->projects[$i];
|
||||
$bug->product = (int)$productID;
|
||||
$bug->branch = (int)$data->branches[$i];
|
||||
$bug->module = (int)$data->modules[$i];
|
||||
$bug->project = (int)$data->projects[$i];
|
||||
$bug->openedBuild = implode(',', $data->openedBuilds[$i]);
|
||||
$bug->color = $data->color[$i];
|
||||
$bug->title = $data->title[$i];
|
||||
@@ -368,7 +368,7 @@ class bugModel extends model
|
||||
elseif($browseType == 'longlifebugs') $bugs = $this->getByLonglifebugs($productID, $branch, $modules, $projects, $sort, $pager);
|
||||
elseif($browseType == 'postponedbugs') $bugs = $this->getByPostponedbugs($productID, $branch, $modules, $projects, $sort, $pager);
|
||||
elseif($browseType == 'needconfirm') $bugs = $this->getByNeedconfirm($productID, $branch, $modules, $projects, $sort, $pager);
|
||||
elseif($browseType == 'bysearch') $bugs = $this->getBySearch($productID, $queryID, $sort, $pager, $branch);
|
||||
elseif($browseType == 'bysearch') $bugs = $this->getBySearch($productID, $branch, $queryID, $sort, '', $pager);
|
||||
elseif($browseType == 'overduebugs') $bugs = $this->getOverdueBugs($productID, $branch, $modules, $projects, $sort, $pager);
|
||||
|
||||
return $this->checkDelayBugs($bugs);
|
||||
@@ -637,9 +637,9 @@ class bugModel extends model
|
||||
|
||||
$now = helper::now();
|
||||
$bug = fixer::input('post')
|
||||
->cleanInt('product,module,severity,project,story,task')
|
||||
->cleanInt('product,module,severity,project,story,task,branch')
|
||||
->stripTags($this->config->bug->editor->edit['id'], $this->config->allowedTags)
|
||||
->setDefault('project,module,project,story,task,duplicateBug,branch', 0)
|
||||
->setDefault('product,module,project,story,task,duplicateBug,branch', 0)
|
||||
->setDefault('openedBuild', '')
|
||||
->setDefault('plan', 0)
|
||||
->setDefault('deadline', '0000-00-00')
|
||||
@@ -1245,7 +1245,7 @@ class bugModel extends model
|
||||
if($browseType == 'bySearch')
|
||||
{
|
||||
$bug = $this->getById($bugID);
|
||||
$bugs2Link = $this->getBySearch($bug->product, $queryID, 'id', null, $bug->branch);
|
||||
$bugs2Link = $this->getBySearch($bug->product, $bug->branch, $queryID, 'id');
|
||||
foreach($bugs2Link as $key => $bug2Link)
|
||||
{
|
||||
if($bug2Link->id == $bugID) unset($bugs2Link[$key]);
|
||||
@@ -1427,12 +1427,12 @@ class bugModel extends model
|
||||
* @param string $type
|
||||
* @param int $param
|
||||
* @param string $orderBy
|
||||
* @param string $excludeBugs
|
||||
* @param object $pager
|
||||
* @param array $excludeBugs
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getProjectBugs($projectID, $build = 0, $type = '', $param = 0, $orderBy = 'id_desc', $pager = null, $excludeBugs = array())
|
||||
public function getProjectBugs($projectID, $build = 0, $type = '', $param = 0, $orderBy = 'id_desc', $excludeBugs = '', $pager = null)
|
||||
{
|
||||
$type = strtolower($type);
|
||||
if($type == 'bysearch')
|
||||
@@ -2311,15 +2311,15 @@ class bugModel extends model
|
||||
* Get bugs by search.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param int $queryID
|
||||
* @param string $orderBy
|
||||
* @param string $excludeBugs
|
||||
* @param object $pager
|
||||
* @param int $branch
|
||||
* @param array $excludeBugs
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBySearch($productID, $queryID, $orderBy, $pager = null, $branch = 0, $excludeBugs = '')
|
||||
public function getBySearch($productID, $branch = 0, $queryID, $orderBy, $excludeBugs = '', $pager = null)
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
|
||||
@@ -8,5 +8,3 @@ $config->build->edit->requiredFields = 'product,project,name,builder,date';
|
||||
$config->build->editor = new stdclass();
|
||||
$config->build->editor->create = array('id' => 'desc', 'tools' => 'simpleTools');
|
||||
$config->build->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools');
|
||||
|
||||
$config->build->selectFields = 'product,project,builder';
|
||||
|
||||
@@ -15,10 +15,11 @@ class build extends control
|
||||
* Create a build.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param int $productID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function create($projectID)
|
||||
public function create($projectID, $productID = 0)
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
@@ -65,7 +66,7 @@ class build extends control
|
||||
$project = $this->loadModel('project')->getById($projectID);
|
||||
|
||||
$productGroups = $this->project->getProducts($projectID);
|
||||
$productID = key($productGroups);
|
||||
$productID = $productID ? $productID : key($productGroups);
|
||||
$products = array();
|
||||
foreach($productGroups as $product) $products[$product->id] = $product->name;
|
||||
|
||||
@@ -249,9 +250,9 @@ class build extends control
|
||||
$this->view->stories = $stories;
|
||||
$this->view->storyPager = $storyPager;
|
||||
|
||||
$newBugPager = new pager($type == 'newbug' ? $recTotal : 0, $recPerPage, $type == 'newbug' ? $pageID : 1);
|
||||
$this->view->generatedBugs = $this->bug->getProjectBugs($build->project, $build->id, '', 0, $type == 'newbug' ? $orderBy : 'status_desc,id_desc', $newBugPager);
|
||||
$this->view->newBugPager = $newBugPager;
|
||||
$generatedBugPager = new pager($type == 'generatedBug' ? $recTotal : 0, $recPerPage, $type == 'generatedBug' ? $pageID : 1);
|
||||
$this->view->generatedBugs = $this->bug->getProjectBugs($build->project, $build->id, '', 0, $type == 'generatedBug' ? $orderBy : 'status_desc,id_desc', '', $generatedBugPager);
|
||||
$this->view->generatedBugPager = $generatedBugPager;
|
||||
}
|
||||
|
||||
$this->executeHooks($buildID);
|
||||
@@ -396,7 +397,7 @@ class build extends control
|
||||
{
|
||||
if(empty($builds))
|
||||
{
|
||||
echo html::a($this->createLink('build', 'create', "projectID=$projectID", '', $onlybody = true), $this->lang->build->create, '', "data-toggle='modal' data-type='iframe'");
|
||||
echo html::a($this->createLink('build', 'create', "projectID=$projectID&productID=$productID", '', $onlybody = true), $this->lang->build->create, '', "data-toggle='modal' data-type='iframe'");
|
||||
echo ' ';
|
||||
echo html::a("javascript:loadProjectBuilds($projectID)", $this->lang->refresh);
|
||||
}
|
||||
@@ -474,11 +475,11 @@ class build extends control
|
||||
|
||||
if($browseType == 'bySearch')
|
||||
{
|
||||
$allStories = $this->story->getBySearch($build->product, $queryID, 'id', $pager, $build->project, $build->branch, 'story', $build->stories);
|
||||
$allStories = $this->story->getBySearch($build->product, $build->branch, $queryID, 'id', $build->project, 'story', $build->stories, $pager);
|
||||
}
|
||||
else
|
||||
{
|
||||
$allStories = $this->story->getProjectStories($build->project, 't1.`order`_desc', 'byModule', 0, $pager, 'story', $build->stories);
|
||||
$allStories = $this->story->getProjectStories($build->project, 't1.`order`_desc', 'byModule', 0, 'story', $build->stories, $pager);
|
||||
}
|
||||
|
||||
$this->view->allStories = $allStories;
|
||||
@@ -595,11 +596,11 @@ class build extends control
|
||||
|
||||
if($browseType == 'bySearch')
|
||||
{
|
||||
$allBugs = $this->bug->getBySearch($build->product, $queryID, 'id_desc', $pager, $build->branch, $build->bugs);
|
||||
$allBugs = $this->bug->getBySearch($build->product, $build->branch, $queryID, 'id_desc', $build->bugs, $pager);
|
||||
}
|
||||
else
|
||||
{
|
||||
$allBugs = $this->bug->getProjectBugs($build->project, 0, 'noclosed', 0, 'status_desc,id_desc', $pager, $build->bugs);
|
||||
$allBugs = $this->bug->getProjectBugs($build->project, 0, 'noclosed', 0, 'status_desc,id_desc', $build->bugs, $pager);
|
||||
}
|
||||
|
||||
$this->view->allBugs = $allBugs;
|
||||
|
||||
@@ -239,7 +239,7 @@ class buildModel extends model
|
||||
$build = fixer::input('post')->stripTags($this->config->build->editor->edit['id'], $this->config->allowedTags)
|
||||
->setDefault('product', $oldBuild->product)
|
||||
->setDefault('branch', $oldBuild->branch)
|
||||
->cleanInt('product,branch')
|
||||
->cleanInt('product,branch,project')
|
||||
->remove('allchecker,resolvedBy,files,labels,uid')
|
||||
->get();
|
||||
|
||||
|
||||
@@ -82,12 +82,12 @@ tbody tr td:first-child input{display:none;}
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div class='tabs' id='tabsNav'>
|
||||
<?php $countStories = count($stories); $countBugs = count($bugs); $countNewBugs = count($generatedBugs);?>
|
||||
<?php $countStories = count($stories); $countBugs = count($bugs); $countGeneratedBugs = count($generatedBugs);?>
|
||||
<ul class='nav nav-tabs'>
|
||||
<li <?php if($type == 'story') echo "class='active'"?>><a href='#stories' data-toggle='tab'><?php echo html::icon($lang->icons['story'], 'text-primary') . ' ' . $lang->build->stories;?></a></li>
|
||||
<li <?php if($type == 'bug') echo "class='active'"?>><a href='#bugs' data-toggle='tab'><?php echo html::icon($lang->icons['bug'], 'text-green') . ' ' . $lang->build->bugs;?></a></li>
|
||||
<li <?php if($type == 'newbug') echo "class='active'"?>><a href='#newBugs' data-toggle='tab'><?php echo html::icon($lang->icons['bug'], 'text-red') . ' ' . $lang->build->generatedBugs;?></a></li>
|
||||
<li <?php if($type == 'buildInfo') echo "class='active'"?>><a href='#buildInfo' data-toggle='tab'><?php echo html::icon($lang->icons['plan'], 'text-info') . ' ' . $lang->build->view;?></a></li>
|
||||
<li <?php if($type == 'story') echo "class='active'"?>><a href='#stories' data-toggle='tab'><?php echo html::icon($lang->icons['story'], 'text-primary') . ' ' . $lang->build->stories;?></a></li>
|
||||
<li <?php if($type == 'bug') echo "class='active'"?>><a href='#bugs' data-toggle='tab'><?php echo html::icon($lang->icons['bug'], 'text-green') . ' ' . $lang->build->bugs;?></a></li>
|
||||
<li <?php if($type == 'generatedBug') echo "class='active'"?>><a href='#generatedBugs' data-toggle='tab'><?php echo html::icon($lang->icons['bug'], 'text-red') . ' ' . $lang->build->generatedBugs;?></a></li>
|
||||
<li <?php if($type == 'buildInfo') echo "class='active'"?>><a href='#buildInfo' data-toggle='tab'><?php echo html::icon($lang->icons['plan'], 'text-info') . ' ' . $lang->build->view;?></a></li>
|
||||
</ul>
|
||||
<div class='tab-content'>
|
||||
<div class='tab-pane <?php if($type == 'story') echo 'active'?>' id='stories'>
|
||||
@@ -254,10 +254,10 @@ tbody tr td:first-child input{display:none;}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class='tab-pane <?php if($type == 'newbug') echo 'active'?>' id='newBugs'>
|
||||
<div class='tab-pane <?php if($type == 'generatedBug') echo 'active'?>' id='generatedBugs'>
|
||||
<div class='main-table' data-ride='table'>
|
||||
<table class='table has-sort-head'>
|
||||
<?php $vars = "buildID={$build->id}&type=newbug&link=$link¶m=$param&orderBy=%s";?>
|
||||
<?php $vars = "buildID={$build->id}&type=generatedBug&link=$link¶m=$param&orderBy=%s";?>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th class='c-id text-left'><?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
|
||||
@@ -308,12 +308,12 @@ tbody tr td:first-child input{display:none;}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class='table-footer'>
|
||||
<?php if($countNewBugs):?>
|
||||
<div class='text'><?php echo sprintf($lang->build->createdBugs, $countNewBugs);?></div>
|
||||
<?php if($countGeneratedBugs):?>
|
||||
<div class='text'><?php echo sprintf($lang->build->createdBugs, $countGeneratedBugs);?></div>
|
||||
<?php endif;?>
|
||||
<?php
|
||||
$this->app->rawParams['type'] = 'newbug';
|
||||
$newBugPager->show('right', 'pagerjs');
|
||||
$this->app->rawParams['type'] = 'generatedBug';
|
||||
$generatedBugPager->show('right', 'pagerjs');
|
||||
$this->app->rawParams['type'] = $type;
|
||||
?>
|
||||
</div>
|
||||
|
||||
@@ -581,15 +581,14 @@ class caselibModel extends model
|
||||
$this->loadModel('testcase');
|
||||
$this->loadModel('action');
|
||||
|
||||
$now = helper::now();
|
||||
$libID = (int)$libID;
|
||||
$cases = fixer::input('post')->get();
|
||||
$batchNum = count(reset($cases));
|
||||
$now = helper::now();
|
||||
$libID = (int)$libID;
|
||||
$cases = fixer::input('post')->get();
|
||||
|
||||
$result = $this->loadModel('common')->removeDuplicate('case', $cases, "lib={$libID}");
|
||||
$cases = $result['data'];
|
||||
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
foreach($cases->title as $i => $title)
|
||||
{
|
||||
if(!empty($cases->title[$i]) and empty($cases->type[$i])) die(js::alert(sprintf($this->lang->error->notempty, $this->lang->testcase->type)));
|
||||
}
|
||||
@@ -597,18 +596,18 @@ class caselibModel extends model
|
||||
$module = 0;
|
||||
$type = '';
|
||||
$pri = 3;
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
foreach($cases->title as $i => $title)
|
||||
{
|
||||
$module = $cases->module[$i] == 'ditto' ? $module : $cases->module[$i];
|
||||
$type = $cases->type[$i] == 'ditto' ? $type : $cases->type[$i];
|
||||
$pri = $cases->pri[$i] == 'ditto' ? $pri : $cases->pri[$i];
|
||||
$pri = $cases->pri[$i] == 'ditto' ? $pri : $cases->pri[$i];
|
||||
$cases->module[$i] = (int)$module;
|
||||
$cases->type[$i] = $type;
|
||||
$cases->pri[$i] = $pri;
|
||||
}
|
||||
|
||||
$forceNotReview = $this->testcase->forceNotReview();
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
foreach($cases->title as $i => $title)
|
||||
{
|
||||
if($cases->type[$i] != '' and $cases->title[$i] != '')
|
||||
{
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
</div>
|
||||
<table class='template' id='trTemp'>
|
||||
<tbody>
|
||||
<tr class='text-center'>
|
||||
<tr>
|
||||
<td>%s</td>
|
||||
<td class='text-left' style='overflow:visible'><?php echo html::select("module[%s]", $moduleOptionMenu, $currentModuleID, "class='form-control chosen'");?></td>
|
||||
<td style='overflow:visible'>
|
||||
@@ -91,8 +91,8 @@
|
||||
</div>
|
||||
</td>
|
||||
<td><?php echo html::select("type[%s]", $lang->testcase->typeList, $type, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select("pri[%s]", $lang->testcase->priList, $pri, "class=form-control chosen");?></td>
|
||||
<td><?php echo html::textarea("precondition[%s]", '', "class='form-control'")?></td>
|
||||
<td><?php echo html::select("pri[%s]", $lang->testcase->priList, $pri, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::textarea("precondition[%s]", '', "rows='1' class='form-control autosize'")?></td>
|
||||
<td><?php echo html::input("keywords[%s]", '', "class='form-control'");?></td>
|
||||
<td class='text-left' style='overflow:visible'><?php echo html::select("stage[%s][]", $lang->testcase->stageList, '', "class='form-control chosen' multiple");?></td>
|
||||
</tr>
|
||||
|
||||
@@ -337,7 +337,6 @@ $lang->testreport->menu->caselib = array('link' => 'Bibliothek|caselib|browse'
|
||||
|
||||
$lang->caselib = new stdclass();
|
||||
$lang->caselib->menu = new stdclass();
|
||||
$lang->caselib->subMenu = $lang->qa->subMenu;
|
||||
$lang->caselib->menu->bug = array('link' => 'Bug|bug|browse|');
|
||||
$lang->caselib->menu->testcase = array('link' => 'Fälle|testcase|browse|', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->caselib->menu->testtask = array('link' => 'Build|testtask|browse|');
|
||||
@@ -345,6 +344,11 @@ $lang->caselib->menu->testsuite = array('link' => 'Suite|testsuite|browse|');
|
||||
$lang->caselib->menu->report = array('link' => 'Berichte|testreport|browse|');
|
||||
$lang->caselib->menu->caselib = array('link' => 'Bibliothek|caselib|browse|libID=%s', 'alias' => 'create,createcase,view,edit,batchcreatecase,showimport', 'subModule' => 'tree,testcase');
|
||||
|
||||
$lang->caselib->subMenu = new stdclass();
|
||||
$lang->caselib->subMenu->testcase = new stdclass();
|
||||
$lang->caselib->subMenu->testcase->feature = array('link' => 'Functional Test|testcase|browse', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase,importfromlib', 'subModule' => 'tree,story');
|
||||
$lang->caselib->subMenu->testcase->unit = array('link' => 'Unit Test|testtask|browseUnits');
|
||||
|
||||
$lang->ci = new stdclass();
|
||||
$lang->ci->menu = new stdclass();
|
||||
$lang->ci->menu->code = array('link' => 'Code|repo|browse|repoID=%s', 'alias' => 'diff,view,revision,log,blame,showsynccomment');
|
||||
|
||||
@@ -337,7 +337,6 @@ $lang->testreport->menu->caselib = array('link' => 'Case Library|caselib|brows
|
||||
|
||||
$lang->caselib = new stdclass();
|
||||
$lang->caselib->menu = new stdclass();
|
||||
$lang->caselib->subMenu = $lang->qa->subMenu;
|
||||
$lang->caselib->menu->bug = array('link' => 'Bug|bug|browse|');
|
||||
$lang->caselib->menu->testcase = array('link' => 'Case|testcase|browse|', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->caselib->menu->testtask = array('link' => 'Request|testtask|browse|');
|
||||
@@ -345,6 +344,11 @@ $lang->caselib->menu->testsuite = array('link' => 'Suite|testsuite|browse|');
|
||||
$lang->caselib->menu->report = array('link' => 'Report|testreport|browse|');
|
||||
$lang->caselib->menu->caselib = array('link' => 'Case Library|caselib|browse|libID=%s', 'alias' => 'create,createcase,view,edit,batchcreatecase,showimport', 'subModule' => 'tree,testcase');
|
||||
|
||||
$lang->caselib->subMenu = new stdclass();
|
||||
$lang->caselib->subMenu->testcase = new stdclass();
|
||||
$lang->caselib->subMenu->testcase->feature = array('link' => 'Functional Test|testcase|browse', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase,importfromlib', 'subModule' => 'tree,story');
|
||||
$lang->caselib->subMenu->testcase->unit = array('link' => 'Unit Test|testtask|browseUnits');
|
||||
|
||||
$lang->ci = new stdclass();
|
||||
$lang->ci->menu = new stdclass();
|
||||
$lang->ci->menu->code = array('link' => 'Code|repo|browse|repoID=%s', 'alias' => 'diff,view,revision,log,blame,showsynccomment');
|
||||
|
||||
@@ -337,7 +337,6 @@ $lang->testreport->menu->caselib = array('link' => 'Library Recette|caselib|br
|
||||
|
||||
$lang->caselib = new stdclass();
|
||||
$lang->caselib->menu = new stdclass();
|
||||
$lang->caselib->subMenu = $lang->qa->subMenu;
|
||||
$lang->caselib->menu->bug = array('link' => 'Bug|bug|browse|');
|
||||
$lang->caselib->menu->testcase = array('link' => 'CasTest|testcase|browse|', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->caselib->menu->testtask = array('link' => 'Recette|testtask|browse|');
|
||||
@@ -345,6 +344,11 @@ $lang->caselib->menu->testsuite = array('link' => 'Cahier Recette|testsuite|brow
|
||||
$lang->caselib->menu->report = array('link' => 'Rapport|testreport|browse|');
|
||||
$lang->caselib->menu->caselib = array('link' => 'Library Recette|caselib|browse|libID=%s', 'alias' => 'create,createcase,view,edit,batchcreatecase,showimport', 'subModule' => 'tree,testcase');
|
||||
|
||||
$lang->caselib->subMenu = new stdclass();
|
||||
$lang->caselib->subMenu->testcase = new stdclass();
|
||||
$lang->caselib->subMenu->testcase->feature = array('link' => 'Functional Test|testcase|browse', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase,importfromlib', 'subModule' => 'tree,story');
|
||||
$lang->caselib->subMenu->testcase->unit = array('link' => 'Unit Test|testtask|browseUnits');
|
||||
|
||||
$lang->ci = new stdclass();
|
||||
$lang->ci->menu = new stdclass();
|
||||
$lang->ci->menu->code = array('link' => 'Code|repo|browse|repoID=%s', 'alias' => 'diff,view,revision,log,blame,showsynccomment');
|
||||
|
||||
@@ -337,7 +337,6 @@ $lang->testreport->menu->caselib = array('link' => 'Thư viện tình huống|
|
||||
|
||||
$lang->caselib = new stdclass();
|
||||
$lang->caselib->menu = new stdclass();
|
||||
$lang->caselib->subMenu = $lang->qa->subMenu;
|
||||
$lang->caselib->menu->bug = array('link' => 'Bug|bug|browse|');
|
||||
$lang->caselib->menu->testcase = array('link' => 'Tình huống|testcase|browse|', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->caselib->menu->testtask = array('link' => 'Yêu cầu|testtask|browse|');
|
||||
@@ -345,6 +344,11 @@ $lang->caselib->menu->testsuite = array('link' => 'Suite|testsuite|browse|');
|
||||
$lang->caselib->menu->report = array('link' => 'Báo cáo|testreport|browse|');
|
||||
$lang->caselib->menu->caselib = array('link' => 'Thư viện tình huống|caselib|browse|libID=%s', 'alias' => 'create,createcase,view,edit,batchcreatecase,showimport', 'subModule' => 'tree,testcase');
|
||||
|
||||
$lang->caselib->subMenu = new stdclass();
|
||||
$lang->caselib->subMenu->testcase = new stdclass();
|
||||
$lang->caselib->subMenu->testcase->feature = array('link' => 'Functional Test|testcase|browse', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase,importfromlib', 'subModule' => 'tree,story');
|
||||
$lang->caselib->subMenu->testcase->unit = array('link' => 'Unit Test|testtask|browseUnits');
|
||||
|
||||
$lang->ci = new stdclass();
|
||||
$lang->ci->menu = new stdclass();
|
||||
$lang->ci->menu->code = array('link' => 'Code|repo|browse|repoID=%s', 'alias' => 'diff,view,revision,log,blame,showsynccomment');
|
||||
|
||||
@@ -337,7 +337,6 @@ $lang->testreport->menu->caselib = array('link' => '用例库|caselib|browse')
|
||||
|
||||
$lang->caselib = new stdclass();
|
||||
$lang->caselib->menu = new stdclass();
|
||||
$lang->caselib->subMenu = $lang->qa->subMenu;
|
||||
$lang->caselib->menu->bug = array('link' => 'Bug|bug|browse|');
|
||||
$lang->caselib->menu->testcase = array('link' => '用例|testcase|browse|', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->caselib->menu->testtask = array('link' => '测试单|testtask|browse|');
|
||||
@@ -345,6 +344,11 @@ $lang->caselib->menu->testsuite = array('link' => '套件|testsuite|browse|');
|
||||
$lang->caselib->menu->report = array('link' => '报告|testreport|browse|');
|
||||
$lang->caselib->menu->caselib = array('link' => '用例库|caselib|browse|libID=%s', 'alias' => 'create,createcase,view,edit,batchcreatecase,showimport', 'subModule' => 'tree,testcase');
|
||||
|
||||
$lang->caselib->subMenu = new stdclass();
|
||||
$lang->caselib->subMenu->testcase = new stdclass();
|
||||
$lang->caselib->subMenu->testcase->feature = array('link' => '功能测试|testcase|browse', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase,importfromlib', 'subModule' => 'tree,story');
|
||||
$lang->caselib->subMenu->testcase->unit = array('link' => '单元测试|testtask|browseUnits');
|
||||
|
||||
$lang->ci = new stdclass();
|
||||
$lang->ci->menu = new stdclass();
|
||||
$lang->ci->menu->code = array('link' => '代码|repo|browse|repoID=%s', 'alias' => 'diff,view,revision,log,blame,showsynccomment');
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php if($extView = $this->getExtViewFile(__FILE__)){include $extView; return helper::cd();}?>
|
||||
<?php
|
||||
css::import($jsRoot . 'jquery/ztree/css/ztree.css');
|
||||
js::import($jsRoot . 'jquery/ztree/js/ztree.js');
|
||||
?>
|
||||
@@ -205,13 +205,15 @@ class fileModel extends model
|
||||
$file['title'] = $purifier->purify($file['title']);
|
||||
$file['size'] = $_POST['size'];
|
||||
$file['tmpname'] = $tmp_name;
|
||||
/* Fix for build uuid like '../../'. */
|
||||
$file['uuid'] = str_replace(array('.', '/', '\\'), '', $_POST['uuid']);
|
||||
$file['uuid'] = $_POST['uuid'];
|
||||
$file['pathname'] = $this->setPathName(0, $file['extension']);
|
||||
$file['chunkpath'] = 'chunks' . DS .'f_' . $file['uuid'] . '.' . $file['extension'] . '.part';
|
||||
$file['chunks'] = isset($_POST['chunks']) ? intval($_POST['chunks']) : 0;
|
||||
$file['chunk'] = isset($_POST['chunk']) ? intval($_POST['chunk']) : 0;
|
||||
|
||||
/* Fix for build uuid like '../../'. */
|
||||
if(!preg_match('/[a-z0-9_]/i', $file['uuid'])) return false;
|
||||
|
||||
if(stripos($this->config->file->allowed, ',' . $file['extension'] . ',') === false)
|
||||
{
|
||||
$file['pathname'] = $file['pathname'] . '.notAllowed';
|
||||
|
||||
@@ -19,7 +19,7 @@ table th,table td{padding:5px;}
|
||||
</style>
|
||||
<title><?php echo $fileName;?></title>
|
||||
<body>
|
||||
<?php if($this->post->kind == 'task') echo "<font color='red'>" . $this->lang->file->childTaskTag . '</font>';?>
|
||||
<?php if($this->post->kind == 'task') echo "<font color='red'>" . $this->lang->file->childTaskTips . '</font>';?>
|
||||
<table>
|
||||
<tr>
|
||||
<?php
|
||||
|
||||
@@ -4,5 +4,3 @@ $config->job->create = new stdclass();
|
||||
$config->job->edit = new stdclass();
|
||||
$config->job->create->requiredFields = 'name,repo,jkHost,jkJob,triggerType';
|
||||
$config->job->edit->requiredFields = 'name,repo,jkHost,jkJob,triggerType';
|
||||
|
||||
$config->job->selectFields = 'repo,jkHost,jkJob,triggerType';
|
||||
|
||||
@@ -81,6 +81,7 @@ $lang->mail->noticeResend = 'Nochmals senden!';
|
||||
$lang->mail->inputFromEmail = 'Sender Email';
|
||||
$lang->mail->nextStep = 'Weiter';
|
||||
$lang->mail->successSaved = 'Konfiguration wurde gespeichert.';
|
||||
$lang->mail->setForUser = 'Could not test mail configure because the users are without mail in system. Please set mail for user first.';
|
||||
$lang->mail->testSubject = 'Email testen';
|
||||
$lang->mail->testContent = 'Email konfiguriert!';
|
||||
$lang->mail->successSended = 'Gesendet!';
|
||||
|
||||
@@ -81,6 +81,7 @@ $lang->mail->noticeResend = 'The Email has been re-sent!';
|
||||
$lang->mail->inputFromEmail = 'Sender Email';
|
||||
$lang->mail->nextStep = 'Next';
|
||||
$lang->mail->successSaved = 'Email settings are saved.';
|
||||
$lang->mail->setForUser = 'Could not test mail configure because the users are without mail in system. Please set mail for user first.';
|
||||
$lang->mail->testSubject = 'Testing Email';
|
||||
$lang->mail->testContent = 'Email settings are done!';
|
||||
$lang->mail->successSended = 'Sent!';
|
||||
|
||||
@@ -81,6 +81,7 @@ $lang->mail->noticeResend = 'Le mail a
|
||||
$lang->mail->inputFromEmail = 'Expéditeur Email';
|
||||
$lang->mail->nextStep = 'Suivant';
|
||||
$lang->mail->successSaved = 'Paramétrage Email sauvegardés.';
|
||||
$lang->mail->setForUser = 'Could not test mail configure because the users are without mail in system. Please set mail for user first.';
|
||||
$lang->mail->testSubject = 'mail de test';
|
||||
$lang->mail->testContent = 'Les Paramétrages Email sont ok !';
|
||||
$lang->mail->successSended = 'Envoyé !';
|
||||
|
||||
@@ -81,6 +81,7 @@ $lang->mail->noticeResend = 'Email này đã được gửi lại!';
|
||||
$lang->mail->inputFromEmail = 'Email người gửi';
|
||||
$lang->mail->nextStep = 'Tiếp';
|
||||
$lang->mail->successSaved = 'Thiết lập Email đã được lưu.';
|
||||
$lang->mail->setForUser = 'Could not test mail configure because the users are without mail in system. Please set mail for user first.';
|
||||
$lang->mail->testSubject = 'Testing Email';
|
||||
$lang->mail->testContent = 'Thiết lập Email đã hoàn thành!';
|
||||
$lang->mail->successSended = 'Đã gửi!';
|
||||
|
||||
@@ -81,6 +81,7 @@ $lang->mail->noticeResend = '已经重新发信!';
|
||||
$lang->mail->inputFromEmail = '请输入发信邮箱:';
|
||||
$lang->mail->nextStep = '下一步';
|
||||
$lang->mail->successSaved = '配置信息已经成功保存。';
|
||||
$lang->mail->setForUser = '系统内用户都没有维护可用邮箱,无法测试发信,请先为用户维护邮箱。';
|
||||
$lang->mail->testSubject = '测试邮件';
|
||||
$lang->mail->testContent = '邮箱设置成功';
|
||||
$lang->mail->successSended = '成功发送!';
|
||||
|
||||
@@ -81,6 +81,7 @@ $lang->mail->noticeResend = '已經重新發信!';
|
||||
$lang->mail->inputFromEmail = '請輸入發信郵箱:';
|
||||
$lang->mail->nextStep = '下一步';
|
||||
$lang->mail->successSaved = '配置信息已經成功保存。';
|
||||
$lang->mail->setForUser = '系統內用戶都沒有維護可用郵箱,無法測試發信,請先為用戶維護郵箱。';
|
||||
$lang->mail->testSubject = '測試郵件';
|
||||
$lang->mail->testContent = '郵箱設置成功';
|
||||
$lang->mail->successSended = '成功發送!';
|
||||
|
||||
@@ -22,7 +22,15 @@
|
||||
<div class='alert alert-block with-icon'>
|
||||
<div class='content'>
|
||||
<?php echo $lang->mail->successSaved;?>
|
||||
<?php if($this->post->turnon and $mailExist) echo html::a(inlink('test'), $lang->mail->test . ' <i class="icon-rocket"></i>', '', "class='btn btn-primary btn-sm'");?>
|
||||
<?php if($this->post->turnon):?>
|
||||
<?php if($mailExist):?>
|
||||
<?php echo html::a(inlink('test'), $lang->mail->test . ' <i class="icon-rocket"></i>', '', "class='btn btn-primary btn-sm'");?>
|
||||
<?php else:?>
|
||||
<span class='content alert-warning'>
|
||||
<i class="icon-exclamation-sign"></i><?php echo $lang->mail->setForUser;?>
|
||||
</span>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
$config->product = new stdclass();
|
||||
$config->product->orderBy = 'isClosed,order_desc';
|
||||
$config->product->selectFields = 'line,PO,QD,RD,type';
|
||||
$config->product->orderBy = 'isClosed,order_desc';
|
||||
|
||||
$config->product->customBatchEditFields = 'line,PO,QD,RD,status,type,desc';
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@ class productModel extends model
|
||||
if($browseType == 'unplan') $stories = $this->story->getByPlan($productID, $queryID, $modules, '', $type, $sort, $pager);
|
||||
if($browseType == 'allstory') $stories = $this->story->getProductStories($productID, $branch, $modules, 'all', $type, $sort, $pager);
|
||||
if($browseType == 'bymodule') $stories = $this->story->getProductStories($productID, $branch, $modules, 'all', $type, $sort, $pager);
|
||||
if($browseType == 'bysearch') $stories = $this->story->getBySearch($productID, $queryID, $sort, $pager, '', $branch, $type);
|
||||
if($browseType == 'bysearch') $stories = $this->story->getBySearch($productID, $branch, $queryID, $sort, '', $type, '', $pager);
|
||||
if($browseType == 'assignedtome') $stories = $this->story->getByAssignedTo($productID, $branch, $modules, $this->app->user->account, $type, $sort, $pager);
|
||||
if($browseType == 'openedbyme') $stories = $this->story->getByOpenedBy($productID, $branch, $modules, $this->app->user->account, $type, $sort, $pager);
|
||||
if($browseType == 'reviewedbyme') $stories = $this->story->getByReviewedBy($productID, $branch, $modules, $this->app->user->account, $type, $sort, $pager);
|
||||
|
||||
@@ -393,7 +393,7 @@ class productplan extends control
|
||||
|
||||
if($browseType == 'bySearch')
|
||||
{
|
||||
$allStories = $this->story->getBySearch($plan->product, $queryID, 'id', $pager = null, $projectID = '', $plan->branch);
|
||||
$allStories = $this->story->getBySearch($plan->product, $plan->branch, $queryID, 'id');
|
||||
foreach($allStories as $key => $story)
|
||||
{
|
||||
if($story->status == 'closed') unset($allStories[$key]);
|
||||
@@ -525,7 +525,7 @@ class productplan extends control
|
||||
|
||||
if($browseType == 'bySearch')
|
||||
{
|
||||
$allBugs = $this->bug->getBySearch($plan->product, $queryID, 'id_desc', null, $plan->branch);
|
||||
$allBugs = $this->bug->getBySearch($plan->product, $plan->branch, $queryID, 'id_desc');
|
||||
foreach($allBugs as $key => $bug)
|
||||
{
|
||||
if($bug->status != 'active' or $bug->toTask != 0 or $bug->toStory != 0) unset($allBugs[$key]);
|
||||
|
||||
@@ -55,7 +55,7 @@ $lang->productplan->last = '上次計劃';
|
||||
$lang->productplan->future = '待定';
|
||||
$lang->productplan->stories = "{$lang->storyCommon}數";
|
||||
$lang->productplan->bugs = 'Bug數';
|
||||
$lang->productplan->hour = '工時';
|
||||
$lang->productplan->hour = $lang->hourCommon;
|
||||
$lang->productplan->project = $lang->projectCommon;
|
||||
$lang->productplan->parent = "父計劃";
|
||||
$lang->productplan->parentAB = "父";
|
||||
|
||||
@@ -695,7 +695,7 @@ class project extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$stories = $this->story->getProjectStories($projectID, $sort, $type, $param, $pager);
|
||||
$stories = $this->story->getProjectStories($projectID, $sort, $type, $param, 'story', '', $pager);
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story', false);
|
||||
$users = $this->user->getPairs('noletter');
|
||||
|
||||
@@ -812,7 +812,7 @@ class project extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
$sort = $this->loadModel('common')->appendOrder($orderBy);
|
||||
$bugs = $this->bug->getProjectBugs($projectID, $build, $type, $param, $sort, $pager);
|
||||
$bugs = $this->bug->getProjectBugs($projectID, $build, $type, $param, $sort, '', $pager);
|
||||
$users = $this->user->getPairs('noletter');
|
||||
|
||||
/* team member pairs. */
|
||||
@@ -2018,7 +2018,7 @@ class project extends control
|
||||
|
||||
if($browseType == 'bySearch')
|
||||
{
|
||||
$allStories = $this->story->getBySearch('', $queryID, 'id', null, $projectID);
|
||||
$allStories = $this->story->getBySearch('', 0, $queryID, 'id', $projectID);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1050,15 +1050,15 @@ class projectModel extends model
|
||||
}
|
||||
|
||||
$total = $this->dao->select('
|
||||
ROUND(SUM(estimate), 1) AS totalEstimate,
|
||||
ROUND(SUM(consumed), 1) AS totalConsumed,
|
||||
ROUND(SUM(`left`), 1) AS totalLeft')
|
||||
ROUND(SUM(estimate), 2) AS totalEstimate,
|
||||
ROUND(SUM(consumed), 2) AS totalConsumed,
|
||||
ROUND(SUM(`left`), 2) AS totalLeft')
|
||||
->from(TABLE_TASK)
|
||||
->where('project')->eq((int)$projectID)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('parent')->lt(1)
|
||||
->fetch();
|
||||
$closedTotalLeft = $this->dao->select('ROUND(SUM(`left`), 1) AS totalLeft')->from(TABLE_TASK)
|
||||
$closedTotalLeft = $this->dao->select('ROUND(SUM(`left`), 2) AS totalLeft')->from(TABLE_TASK)
|
||||
->where('project')->eq((int)$projectID)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('parent')->lt(1)
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<td><?php echo zget($users, $task->owner);?></td>
|
||||
<td><?php echo $task->begin?></td>
|
||||
<td><?php echo $task->end?></td>
|
||||
<?php $status = $this->processStatus('task', $task);?>
|
||||
<?php $status = $this->processStatus('testtask', $task);?>
|
||||
<td title='<?php echo $status;?>'>
|
||||
<span class='status-testtask status-<?php echo $task->status?>'><?php echo $status;?></span>
|
||||
</td>
|
||||
|
||||
@@ -242,23 +242,23 @@
|
||||
<th><?php echo $lang->project->begin;?></th>
|
||||
<td><?php echo $project->begin;?></td>
|
||||
<th><?php echo $lang->project->totalEstimate;?></th>
|
||||
<td><em><?php echo $project->totalEstimate . $lang->project->workHour;?></em></td>
|
||||
<td><em><?php echo (float)$project->totalEstimate . $lang->project->workHour;?></em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->end;?></th>
|
||||
<td><?php echo $project->end;?></td>
|
||||
<th><?php echo $lang->project->totalConsumed;?></th>
|
||||
<td><em><?php echo $project->totalConsumed . $lang->project->workHour;?></em></td>
|
||||
<td><em><?php echo (float)$project->totalConsumed . $lang->project->workHour;?></em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->totalDays;?></th>
|
||||
<td><?php echo $project->days;?></td>
|
||||
<th><?php echo $lang->project->totalLeft;?></th>
|
||||
<td><em><?php echo $project->totalLeft . $lang->project->workHour;?></em></td>
|
||||
<td><em><?php echo (float)$project->totalLeft . $lang->project->workHour;?></em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->totalHours;?></th>
|
||||
<td><em><?php echo $project->totalHours . $lang->project->workHour;?></em></td>
|
||||
<td><em><?php echo (float)$project->totalHours . $lang->project->workHour;?></em></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -8,5 +8,3 @@ $config->release->edit->requiredFields = 'name,date,build';
|
||||
$config->release->editor = new stdclass();
|
||||
$config->release->editor->create = array('id' => 'desc', 'tools' => 'simpleTools');
|
||||
$config->release->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools');
|
||||
|
||||
$config->release->selectFields = 'build';
|
||||
|
||||
@@ -417,11 +417,11 @@ class release extends control
|
||||
|
||||
if($browseType == 'bySearch')
|
||||
{
|
||||
$allStories = $this->story->getBySearch($release->product, $queryID, 'id', $pager, $build->project ? $build->project : '', $release->branch, 'story', $release->stories);
|
||||
$allStories = $this->story->getBySearch($release->product, $release->branch, $queryID, 'id', $build->project ? $build->project : '', 'story', $release->stories, $pager);
|
||||
}
|
||||
else
|
||||
{
|
||||
$allStories = $this->story->getProjectStories($build->project, 't1.`order`_desc', 'byModule', 0, $pager, 'story', $release->stories);
|
||||
$allStories = $this->story->getProjectStories($build->project, 't1.`order`_desc', 'byModule', 0, 'story', $release->stories, $pager);
|
||||
}
|
||||
|
||||
$this->view->allStories = $allStories;
|
||||
@@ -538,7 +538,7 @@ class release extends control
|
||||
$releaseBugs = $type == 'bug' ? $release->bugs : $release->leftBugs;
|
||||
if($browseType == 'bySearch')
|
||||
{
|
||||
$allBugs = $this->bug->getBySearch($release->product, $queryID, 'id_desc', $pager, $release->branch, $releaseBugs);
|
||||
$allBugs = $this->bug->getBySearch($release->product, $release->branch, $queryID, 'id_desc', $releaseBugs, $pager);
|
||||
}
|
||||
elseif($build->project)
|
||||
{
|
||||
|
||||
@@ -716,19 +716,21 @@ class repo extends control
|
||||
/* Init branchID. */
|
||||
if($this->cookie->syncBranch) $branchID = $this->cookie->syncBranch;
|
||||
if(!isset($branches[$branchID])) $branchID = '';
|
||||
if(empty($branchID)) $branchID = reset($branches);
|
||||
if(empty($branchID)) $branchID = 'master';
|
||||
|
||||
/* Get unsynced branches. */
|
||||
foreach($branches as $branch)
|
||||
unset($branches['master']);
|
||||
if($branchID != 'master')
|
||||
{
|
||||
unset($branches[$branch]);
|
||||
if($branch == $branchID)
|
||||
foreach($branches as $branch)
|
||||
{
|
||||
$this->repo->setRepoBranch($branchID);
|
||||
setcookie("syncBranch", $branchID, 0, $this->config->webRoot);
|
||||
break;
|
||||
unset($branches[$branch]);
|
||||
if($branch == $branchID) break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->repo->setRepoBranch($branchID);
|
||||
setcookie("syncBranch", $branchID, 0, $this->config->webRoot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,7 +755,7 @@ class repo extends control
|
||||
}
|
||||
|
||||
$commitCount = $this->repo->saveCommit($repoID, $logs, $version, $branchID);
|
||||
if(empty($commitCount) or ($type == 'batch' and $commitCount < $this->config->repo->batchNum))
|
||||
if(empty($commitCount))
|
||||
{
|
||||
if(!$repo->synced)
|
||||
{
|
||||
@@ -813,7 +815,7 @@ class repo extends control
|
||||
|
||||
$logs = $this->scm->getCommits($revision, $this->config->repo->batchNum, $branch);
|
||||
$commitCount = $this->repo->saveCommit($repoID, $logs, $version, $branch);
|
||||
if(empty($commitCount) or $commitCount < $this->config->repo->batchNum)
|
||||
if(empty($commitCount))
|
||||
{
|
||||
if($branch) $this->repo->saveExistCommits4Branch($repo->id, $branch);
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ $config->story = new stdclass();
|
||||
$config->story->batchCreate = 10;
|
||||
$config->story->affectedFixedNum = 7;
|
||||
$config->story->needReview = 1;
|
||||
$config->story->selectFields = 'module,plan,source,pri,closedReason,assignedTo,reviewedBy';
|
||||
|
||||
$config->story->batchClose = new stdclass();
|
||||
$config->story->batchClose->columns = 10;
|
||||
|
||||
@@ -192,8 +192,19 @@ class storyModel extends model
|
||||
if($this->checkForceReview()) $story->status = 'draft';
|
||||
if($story->status == 'draft') $story->stage = $this->post->plan > 0 ? 'planned' : 'wait';
|
||||
$story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->create['id'], $this->post->uid);
|
||||
if($story->type == 'requirement') $this->config->story->create->requiredFields = str_replace('plan,', '', $this->config->story->create->requiredFields);
|
||||
$this->dao->insert(TABLE_STORY)->data($story, 'spec,verify')->autoCheck()->batchCheck($this->config->story->create->requiredFields, 'notempty')->exec();
|
||||
|
||||
$requiredFields = "," . $this->config->story->create->requiredFields . ",";
|
||||
|
||||
if($story->type == 'requirement') $requiredFields = str_replace(',plan,', ',', $requiredFields);
|
||||
if(strpos($requiredFields, ',estimate,') !== false)
|
||||
{
|
||||
if(strlen(trim($story->estimate)) == 0) dao::$errors['estimate'] = sprintf($this->lang->error->notempty, $this->lang->story->estimate);
|
||||
$requiredFields = str_replace(',estimate,', ',', $requiredFields);
|
||||
}
|
||||
|
||||
$requiredFields = trim($requiredFields, ',');
|
||||
|
||||
$this->dao->insert(TABLE_STORY)->data($story, 'spec,verify')->autoCheck()->batchCheck($requiredFields, 'notempty')->exec();
|
||||
if(!dao::isError())
|
||||
{
|
||||
$storyID = $this->dao->lastInsertID();
|
||||
@@ -335,7 +346,14 @@ class storyModel extends model
|
||||
foreach(explode(',', $this->config->story->create->requiredFields) as $field)
|
||||
{
|
||||
$field = trim($field);
|
||||
if($field and empty($story->$field)) die(js::alert(sprintf($this->lang->error->notempty, $this->lang->story->$field)));
|
||||
if(empty($field)) continue;
|
||||
if($type == 'requirement' and $field == 'plan') continue;
|
||||
|
||||
if(!empty($story->$field)) continue;
|
||||
if($field == 'estimate' and strlen(trim($story->estimate)) != 0) continue;
|
||||
|
||||
dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->story->$field);
|
||||
return false;
|
||||
}
|
||||
|
||||
$data[$i] = $story;
|
||||
@@ -343,9 +361,7 @@ class storyModel extends model
|
||||
|
||||
foreach($data as $i => $story)
|
||||
{
|
||||
$this->dao->insert(TABLE_STORY)->data($story)->autoCheck()
|
||||
->batchCheck($this->config->story->create->requiredFields, 'notempty')
|
||||
->exec();
|
||||
$this->dao->insert(TABLE_STORY)->data($story)->autoCheck()->exec();
|
||||
if(dao::isError())
|
||||
{
|
||||
echo js::error(dao::getError());
|
||||
@@ -482,7 +498,7 @@ class storyModel extends model
|
||||
$data->title = $story->title;
|
||||
$data->spec = $story->spec;
|
||||
$data->verify = $story->verify;
|
||||
$this->dao->replace(TABLE_STORYSPEC)->data($data)->exec();
|
||||
$this->dao->insert(TABLE_STORYSPEC)->data($data)->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -948,7 +964,12 @@ class storyModel extends model
|
||||
{
|
||||
$preTitle = $this->dao->select('title')->from(TABLE_STORYSPEC)->where('story')->eq($storyID)->andWHere('version')->eq($this->post->preVersion)->fetch('title');
|
||||
$this->dao->update(TABLE_STORY)->set('title')->eq($preTitle)->where('id')->eq($storyID)->exec();
|
||||
$this->dao->delete()->from(TABLE_STORYSPEC)->where('story')->eq($storyID)->andWHere('version')->eq($oldStory->version)->exec();
|
||||
|
||||
/* Delete versions that is after this version. */
|
||||
$deleteVersion = array();
|
||||
for($version = $oldStory->version; $version > $story->version; $version --) $deleteVersion[] = $version;
|
||||
if($deleteVersion) $this->dao->delete()->from(TABLE_STORYSPEC)->where('story')->eq($storyID)->andWHere('version')->in($deleteVersion)->exec();
|
||||
|
||||
$this->dao->delete()->from(TABLE_FILE)->where('objectType')->eq('story')->andWhere('objectID')->eq($storyID)->andWhere('extra')->eq($oldStory->version)->exec();
|
||||
}
|
||||
if($this->post->result != 'reject') $this->setStage($storyID);
|
||||
@@ -1514,7 +1535,7 @@ class storyModel extends model
|
||||
if($statusList['devel']['done'] == $develTasks and $develTasks > 0 and $statusList['test']['wait'] > 0 and $statusList['test']['done'] > 0) $stage = 'testing';
|
||||
if($statusList['test']['doing'] > 0) $stage = 'testing';
|
||||
if(($statusList['devel']['wait'] > 0 or $statusList['devel']['doing'] > 0) and $statusList['test']['done'] == $testTasks and $testTasks > 0) $stage = 'testing';
|
||||
if($statusList['devel']['done'] == $develTasks and $develTasks > 0 and $statusList['test']['done'] == $testTasks and $testTasks > 0) $stage = 'tested';
|
||||
if($statusList['devel']['done'] == $develTasks and $statusList['test']['done'] == $testTasks and $testTasks > 0) $stage = 'tested';
|
||||
|
||||
$stages[$branch] = $stage;
|
||||
}
|
||||
@@ -1571,7 +1592,7 @@ class storyModel extends model
|
||||
if($browseType == 'bySearch')
|
||||
{
|
||||
$story = $this->getById($storyID);
|
||||
$stories2Link = $this->getBySearch($story->product, $queryID, 'id', null, '', $story->branch);
|
||||
$stories2Link = $this->getBySearch($story->product, $story->branch, $queryID, 'id');
|
||||
foreach($stories2Link as $key => $story2Link)
|
||||
{
|
||||
if($story2Link->id == $storyID) unset($stories2Link[$key]);
|
||||
@@ -1813,17 +1834,17 @@ class storyModel extends model
|
||||
*
|
||||
* @access public
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param int $queryID
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param string $projectID
|
||||
* @param int $branch
|
||||
* @param string $type requirement|story
|
||||
* @param string $excludeStories
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBySearch($productID, $queryID, $orderBy, $pager = null, $projectID = '', $branch = 0, $type = 'story', $excludeStories = '')
|
||||
public function getBySearch($productID, $branch = 0, $queryID, $orderBy, $projectID = '', $type = 'story', $excludeStories = '', $pager = null)
|
||||
{
|
||||
if($projectID != '')
|
||||
{
|
||||
@@ -1930,13 +1951,13 @@ class storyModel extends model
|
||||
* @param string $orderBy
|
||||
* @param string $type
|
||||
* @param int $param
|
||||
* @param object $pager
|
||||
* @param string $storyType
|
||||
* @param string $excludeStories
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getProjectStories($projectID = 0, $orderBy = 't1.`order`_desc', $type = 'byModule', $param = 0, $pager = null, $storyType = 'story', $excludeStories = '')
|
||||
public function getProjectStories($projectID = 0, $orderBy = 't1.`order`_desc', $type = 'byModule', $param = 0, $storyType = 'story', $excludeStories = '', $pager = null)
|
||||
{
|
||||
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProjectStories();
|
||||
|
||||
@@ -2651,11 +2672,12 @@ class storyModel extends model
|
||||
|
||||
if($story->parent < 0 and $action != 'edit' and $action != 'batchcreate') return false;
|
||||
|
||||
if($action == 'change') return $story->status != 'closed';
|
||||
if($action == 'review') return $story->status == 'draft' or $story->status == 'changed';
|
||||
if($action == 'close') return $story->status != 'closed';
|
||||
if($action == 'activate') return $story->status == 'closed';
|
||||
if($action == 'assignto') return $story->status != 'closed';
|
||||
if($action == 'change') return $story->status != 'closed';
|
||||
if($action == 'review') return $story->status == 'draft' or $story->status == 'changed';
|
||||
if($action == 'close') return $story->status != 'closed';
|
||||
if($action == 'activate') return $story->status == 'closed';
|
||||
if($action == 'assignto') return $story->status != 'closed';
|
||||
if($action == 'createcase') return $story->type != 'requirement';
|
||||
if($action == 'batchcreate' and $story->parent > 0) return false;
|
||||
if($action == 'batchcreate' and $story->type == 'requirement') return $story->status != 'draft';
|
||||
if($action == 'batchcreate' and ($story->status != 'active' or $story->stage != 'wait')) return false;
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
common::printIcon('story', 'close', "storyID=$story->id", $story, 'button', '', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('story', 'activate', "storyID=$story->id", $story, 'button', '', '', 'iframe showinonlybody', true);
|
||||
|
||||
if($config->global->flow != 'onlyStory' and !isonlybody() and $story->parent >= 0 and (common::hasPriv('testcase', 'create') or common::hasPriv('testcase', 'batchCreate')))
|
||||
if($config->global->flow != 'onlyStory' and !isonlybody() and $story->parent >= 0 and $story->type != 'requirement' and (common::hasPriv('testcase', 'create') or common::hasPriv('testcase', 'batchCreate')))
|
||||
{
|
||||
$this->app->loadLang('testcase');
|
||||
echo "<div class='btn-group dropup'>";
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
$config->task = new stdclass();
|
||||
$config->task->batchCreate = 10;
|
||||
$config->task->selectFields = 'project,type,story,module,pri,assignedTo';
|
||||
$config->task->batchCreate = 10;
|
||||
|
||||
$config->task->create = new stdclass();
|
||||
$config->task->edit = new stdclass();
|
||||
|
||||
@@ -202,7 +202,6 @@ $lang->task->error->totalNumber = '"Total Cost" must be numbers.';
|
||||
$lang->task->error->consumedNumber = '"Verbraucht" muss eine Zahl sein.';
|
||||
$lang->task->error->estimateNumber = '"Stunden" müss eine Zahl sein.';
|
||||
$lang->task->error->recordMinus = 'Work hours should not be negative number.';
|
||||
$lang->task->error->recordZero = 'Work hours should not be zero.';
|
||||
$lang->task->error->consumedSmall = '"Genutzt" muss larger than before.';
|
||||
$lang->task->error->consumedThisTime = 'Bitte geben Sie die Stunden an';
|
||||
$lang->task->error->left = 'Bitte geben Sie die verbleibenden Stunden an"';
|
||||
|
||||
@@ -202,7 +202,6 @@ $lang->task->error->totalNumber = '"Total Cost" must be numbers.';
|
||||
$lang->task->error->consumedNumber = '"Current Cost" must be numbers.';
|
||||
$lang->task->error->estimateNumber = '"Estimates" must be numbers.';
|
||||
$lang->task->error->recordMinus = 'Work hours should not be negative number.';
|
||||
$lang->task->error->recordZero = 'Work hours should not be zero.';
|
||||
$lang->task->error->consumedSmall = '"Total Cost" must be > the last number.';
|
||||
$lang->task->error->consumedThisTime = 'Please enter "Hours Cost"';
|
||||
$lang->task->error->left = 'Please enter "Hours Left"';
|
||||
|
||||
@@ -202,7 +202,6 @@ $lang->task->error->totalNumber = '"Total Cost" must be numbers.';
|
||||
$lang->task->error->consumedNumber = '"Coût" doit être numérique.';
|
||||
$lang->task->error->estimateNumber = '"Estimé" doit être numérique.';
|
||||
$lang->task->error->recordMinus = 'Work hours should not be negative number.';
|
||||
$lang->task->error->recordZero = 'Work hours should not be zero.';
|
||||
$lang->task->error->consumedSmall = '"Coût Total" doit être > au dernier chiffre.';
|
||||
$lang->task->error->consumedThisTime = 'Entrez le "Coût en Heures"';
|
||||
$lang->task->error->left = 'Entrez les "Heures Restantes"';
|
||||
|
||||
@@ -202,7 +202,6 @@ $lang->task->error->totalNumber = '"Total Cost" must be numbers.';
|
||||
$lang->task->error->consumedNumber = '"Giờ làm" phải là số.';
|
||||
$lang->task->error->estimateNumber = '"Dự tính" phải là số.';
|
||||
$lang->task->error->recordMinus = 'Giờ làm không nên là số âm';
|
||||
$lang->task->error->recordZero = 'Work hours should not be zero.';
|
||||
$lang->task->error->consumedSmall = '"Tổng giờ làm" phải là > số cuối cùng.';
|
||||
$lang->task->error->consumedThisTime = 'Vui lòng nhập "Số giờ làm"';
|
||||
$lang->task->error->left = 'Vui lòng nhập "Giờ còn lại"';
|
||||
|
||||
@@ -202,7 +202,6 @@ $lang->task->error->totalNumber = '"总计消耗"必须为数字';
|
||||
$lang->task->error->consumedNumber = '"本次消耗"必须为数字';
|
||||
$lang->task->error->estimateNumber = '"预计剩余"必须为数字';
|
||||
$lang->task->error->recordMinus = '工时不能为负数';
|
||||
$lang->task->error->recordZero = '工时不能为零';
|
||||
$lang->task->error->consumedSmall = '"总计消耗"必须大于之前消耗';
|
||||
$lang->task->error->consumedThisTime = '请填写"工时"';
|
||||
$lang->task->error->left = '请填写"剩余"';
|
||||
|
||||
@@ -202,7 +202,6 @@ $lang->task->error->totalNumber = '"總計消耗"必須為數字';
|
||||
$lang->task->error->consumedNumber = '"本次消耗"必須為數字';
|
||||
$lang->task->error->estimateNumber = '"預計剩餘"必須為數字';
|
||||
$lang->task->error->recordMinus = '工時不能為負數';
|
||||
$lang->task->error->recordZero = '工時不能為零';
|
||||
$lang->task->error->consumedSmall = '"總計消耗"必須大於之前消耗';
|
||||
$lang->task->error->consumedThisTime = '請填寫"工時"';
|
||||
$lang->task->error->left = '請填寫"剩餘"';
|
||||
|
||||
@@ -27,11 +27,7 @@ class taskModel extends model
|
||||
dao::$errors[] = $this->lang->task->error->recordMinus;
|
||||
return false;
|
||||
}
|
||||
elseif($this->post->estimate === '0')
|
||||
{
|
||||
dao::$errors[] = $this->lang->task->error->recordZero;
|
||||
return false;
|
||||
}
|
||||
|
||||
$projectID = (int)$projectID;
|
||||
$taskIdList = array();
|
||||
$taskFiles = array();
|
||||
@@ -98,6 +94,13 @@ class taskModel extends model
|
||||
$requiredFields = str_replace(",estStarted,", ',', "$requiredFields");
|
||||
$requiredFields = str_replace(",deadline,", ',', "$requiredFields");
|
||||
}
|
||||
|
||||
if(strpos($requiredFields, ',estimate,') !== false)
|
||||
{
|
||||
if(strlen(trim($task->estimate)) == 0) dao::$errors['estimate'] = sprintf($this->lang->error->notempty, $this->lang->task->estimate);
|
||||
$requiredFields = str_replace(',estimate,', ',', $requiredFields);
|
||||
}
|
||||
|
||||
$requiredFields = trim($requiredFields, ',');
|
||||
|
||||
/* Fix Bug #2466 */
|
||||
@@ -301,10 +304,10 @@ class taskModel extends model
|
||||
}
|
||||
|
||||
/* Fix bug #1525*/
|
||||
$projectType =$this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetch('type');
|
||||
$requiredFields = explode(',', $this->config->task->create->requiredFields);
|
||||
if($projectType == 'ops') unset($requiredFields[array_search('story', $requiredFields)]);
|
||||
$requiredFields = implode(',', $requiredFields);
|
||||
$projectType = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetch('type');
|
||||
$requiredFields = ',' . $this->config->task->create->requiredFields . ',';
|
||||
if($projectType == 'ops') $requiredFields = str_replace(',story,', ',', $requiredFields);
|
||||
$requiredFields = trim($requiredFields, ',');
|
||||
|
||||
/* check data. */
|
||||
foreach($data as $i => $task)
|
||||
@@ -314,19 +317,23 @@ class taskModel extends model
|
||||
dao::$errors['message'][] = $this->lang->task->error->deadlineSmall;
|
||||
return false;
|
||||
}
|
||||
|
||||
if($task->estimate and !preg_match("/^[0-9]+(.[0-9]{1,3})?$/", $task->estimate))
|
||||
{
|
||||
dao::$errors['message'][] = $this->lang->task->error->estimateNumber;
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach(explode(',', $requiredFields) as $field)
|
||||
{
|
||||
$field = trim($field);
|
||||
if($field and empty($task->$field))
|
||||
{
|
||||
dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->task->$field);
|
||||
return false;
|
||||
}
|
||||
if(empty($field)) continue;
|
||||
|
||||
if(!empty($task->$field)) continue;
|
||||
if($field == 'estimate' and strlen(trim($task->estimate)) != 0) continue;
|
||||
|
||||
dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->task->$field);
|
||||
return false;
|
||||
}
|
||||
if($task->estimate) $task->estimate = (float)$task->estimate;
|
||||
}
|
||||
@@ -337,7 +344,6 @@ class taskModel extends model
|
||||
{
|
||||
$this->dao->insert(TABLE_TASK)->data($task)
|
||||
->autoCheck()
|
||||
->batchCheck($requiredFields, 'notempty')
|
||||
->checkIF($task->estimate != '', 'estimate', 'float')
|
||||
->exec();
|
||||
|
||||
@@ -815,9 +821,25 @@ class taskModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
$projectType = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($task->project)->fetch('type');
|
||||
$requiredFields = "," . $this->config->task->edit->requiredFields . ",";
|
||||
if($projectType == 'ops')
|
||||
{
|
||||
$requiredFields = str_replace(",story,", ',', "$requiredFields");
|
||||
$task->story = 0;
|
||||
}
|
||||
|
||||
if($task->status != 'cancel' and strpos($requiredFields, ',estimate,') !== false)
|
||||
{
|
||||
if(strlen(trim($task->estimate)) == 0) dao::$errors['estimate'] = sprintf($this->lang->error->notempty, $this->lang->task->estimate);
|
||||
$requiredFields = str_replace(',estimate,', ',', $requiredFields);
|
||||
}
|
||||
|
||||
$requiredFields = trim($requiredFields, ',');
|
||||
|
||||
$this->dao->update(TABLE_TASK)->data($task)
|
||||
->autoCheck()
|
||||
->batchCheckIF($task->status != 'cancel', $this->config->task->edit->requiredFields, 'notempty')
|
||||
->batchCheckIF($task->status != 'cancel', $requiredFields, 'notempty')
|
||||
->checkIF($task->deadline != '0000-00-00', 'deadline', 'ge', $task->estStarted)
|
||||
|
||||
->checkIF($task->estimate != false, 'estimate', 'float')
|
||||
@@ -930,6 +952,7 @@ class taskModel extends model
|
||||
/* Initialize tasks from the post data.*/
|
||||
$extendFields = $this->getFlowExtendFields();
|
||||
$oldTasks = $taskIDList ? $this->getByList($taskIDList) : array();
|
||||
$tasks = array();
|
||||
foreach($taskIDList as $taskID)
|
||||
{
|
||||
$oldTask = $oldTasks[$taskID];
|
||||
@@ -1028,9 +1051,30 @@ class taskModel extends model
|
||||
}
|
||||
if($task->assignedTo) $task->assignedDate = $now;
|
||||
|
||||
$tasks[$taskID] = $task;
|
||||
}
|
||||
|
||||
/* Check field not empty. */
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
if($task->status == 'cancel') continue;
|
||||
foreach(explode(',', $this->config->task->edit->requiredFields) as $field)
|
||||
{
|
||||
$field = trim($field);
|
||||
if(empty($field)) continue;
|
||||
|
||||
if(!empty($task->$field)) continue;
|
||||
if($field == 'estimate' and strlen(trim($task->estimate)) != 0) continue;
|
||||
|
||||
dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->task->$field);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
$this->dao->update(TABLE_TASK)->data($task)
|
||||
->autoCheck()
|
||||
->batchCheckIF($task->status != 'cancel', $this->config->task->edit->requiredFields, 'notempty')
|
||||
|
||||
->checkIF($task->estimate != false, 'estimate', 'float')
|
||||
->checkIF($task->consumed != false, 'consumed', 'float')
|
||||
|
||||
@@ -3,7 +3,6 @@ $config->testcase = new stdclass();
|
||||
$config->testcase->defaultSteps = 3;
|
||||
$config->testcase->batchCreate = 10;
|
||||
$config->testcase->needReview = 0;
|
||||
$config->testcase->selectFields = 'lib,stage,type,story,pri,status';
|
||||
|
||||
$config->testcase->create = new stdclass();
|
||||
$config->testcase->edit = new stdclass();
|
||||
|
||||
@@ -807,7 +807,7 @@ class testcase extends control
|
||||
$changes = $this->testcase->review($caseID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
if($changes)
|
||||
if($changes or $this->post->comment != '')
|
||||
{
|
||||
$result = $this->post->result;
|
||||
$actionID = $this->loadModel('action')->create('case', $caseID, 'Reviewed', $this->post->comment, ucfirst($result));
|
||||
|
||||
@@ -8,5 +8,3 @@ $config->testreport->edit->requiredFields = 'title,owner';
|
||||
$config->testreport->editor = new stdclass();
|
||||
$config->testreport->editor->create = array('id' => 'report', 'tools' => 'simpleTools');
|
||||
$config->testreport->editor->edit = array('id' => 'report', 'tools' => 'simpleTools');
|
||||
|
||||
$config->testreport->selectFields = 'owner';
|
||||
|
||||
@@ -202,14 +202,14 @@ class testreportModel extends model
|
||||
*/
|
||||
public function getBugInfo($tasks, $productIdList, $begin, $end, $builds)
|
||||
{
|
||||
$allNewBugs = $this->dao->select('*')->from(TABLE_BUG)->where('product')->in($productIdList)->andWhere('openedDate')->ge($begin)->andWhere('openedDate')->le("$end 23:59:59")->andWhere('deleted')->eq(0)->fetchAll();
|
||||
$foundBugs = array();
|
||||
$legacyBugs = array();
|
||||
$byCaseNum = 0;
|
||||
$buildIdList = array_keys($builds);
|
||||
$taskIdList = array_keys($tasks);
|
||||
$generatedBugs = $this->dao->select('*')->from(TABLE_BUG)->where('product')->in($productIdList)->andWhere('openedDate')->ge($begin)->andWhere('openedDate')->le("$end 23:59:59")->andWhere('deleted')->eq(0)->fetchAll();
|
||||
$foundBugs = array();
|
||||
$legacyBugs = array();
|
||||
$byCaseNum = 0;
|
||||
$buildIdList = array_keys($builds);
|
||||
$taskIdList = array_keys($tasks);
|
||||
|
||||
foreach($allNewBugs as $bug)
|
||||
foreach($generatedBugs as $bug)
|
||||
{
|
||||
if(!array_diff(explode(',', $bug->openedBuild), $buildIdList))
|
||||
{
|
||||
|
||||
@@ -5,8 +5,6 @@ $config->testtask->edit = new stdclass();
|
||||
$config->testtask->create->requiredFields = 'project,build,begin,end,name';
|
||||
$config->testtask->edit->requiredFields = 'project,build,begin,end,name';
|
||||
|
||||
$config->testtask->selectFields = 'project,build,owner';
|
||||
|
||||
$config->testtask->importunitresult = new stdclass();
|
||||
$config->testtask->importunitresult->requiredFields = 'project,build,begin,end,name,resultFile';
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<div class='input-group' id='buildBox'>
|
||||
<?php echo html::select('build', empty($builds) ? '' : $builds, $build, "class='form-control chosen'");?>
|
||||
<?php if(isset($projectID) and $projectID and empty($builds)):?>
|
||||
<span class='input-group-addon'><?php echo html::a(helper::createLink('build', 'create', "projectID=$projectID", '', true), $lang->build->create, '', "data-toggle='modal' data-type='iframe' data-width='95%'")?> </span>
|
||||
<span class='input-group-addon'><?php echo html::a(helper::createLink('build', 'create', "projectID=$projectID&productID=$productID", '', true), $lang->build->create, '', "data-toggle='modal' data-type='iframe' data-width='95%'")?> </span>
|
||||
</div>
|
||||
<div class='hidden'><?php echo ' ' . html::a("javascript:void(0)", $lang->refresh, '', "class='refresh' onclick='loadProjectBuilds($projectID)'");?></div>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
<td><?php if(isset($result->version)) echo nl2br($result->version);?></td>
|
||||
<?php if(!empty($stepResult['result'])):?>
|
||||
<td class='<?php echo $stepResult['result'];?> text-center'><?php echo $lang->testcase->resultList[$stepResult['result']];?></td>
|
||||
<td><?php echo nl2br(htmlspecialchars($stepResult['real']));?></td>
|
||||
<td><?php echo nl2br($stepResult['real']);?></td>
|
||||
<td class='text-center'><?php if(!empty($stepResult['files'])) echo html::a("#stepResult{$modalID}", $lang->files . $fileCount, '', "data-toggle='modal' data-type='iframe'")?></td>
|
||||
<?php else:?>
|
||||
<td></td>
|
||||
|
||||
@@ -16,135 +16,141 @@
|
||||
<?php if(common::checkNotCN()):?>
|
||||
<style> label.col-sm-1{width:100px;} </style>
|
||||
<?php endif;?>
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class='modal-title pull-left'><?php echo html::a($this->createLink('todo', 'view', 'todo=' . $todo->id), "TODO #{$todo->id} {$todo->name}");?></h4>
|
||||
</div>
|
||||
<form class='modal-body form-horizontal' target='hiddenwin' method='post' id='dataform'>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->date;?></label>
|
||||
<div class="col-sm-10">
|
||||
<div class='input-group has-icon-right'>
|
||||
<?php echo html::input('date', $todo->date, "class='form-control form-date'");?>
|
||||
<label for="date" class="input-control-icon-right"><i class="icon icon-delay"></i></label>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2>
|
||||
<span class='label label-id'><?php echo $todo->id;?></span>
|
||||
<?php echo html::a($this->createLink('todo', 'view', 'todo=' . $todo->id), $todo->name);?>
|
||||
<small class='text-muted'><?php echo $lang->arrow . $lang->todo->edit;?></small>
|
||||
</h2>
|
||||
</div>
|
||||
<form class='modal-body form-horizontal' target='hiddenwin' method='post' id='dataform'>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->date;?></label>
|
||||
<div class="col-sm-10">
|
||||
<div class='input-group has-icon-right'>
|
||||
<?php echo html::input('date', $todo->date, "class='form-control form-date'");?>
|
||||
<label for="date" class="input-control-icon-right"><i class="icon icon-delay"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if($todo->cycle):?>
|
||||
<?php $todo->config = json_decode($todo->config);?>
|
||||
<div class="row form-group cycleConfig">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->cycleConfig;?></label>
|
||||
<div class="col-sm-10">
|
||||
<ul class="nav nav-tabs">
|
||||
<li <?php if($todo->config->type == 'day') echo "class='active'"?>><a data-tab data-type='day' href="#day"><?php echo $lang->todo->cycleDay;?></a></li>
|
||||
<li <?php if($todo->config->type == 'week') echo "class='active'"?>><a data-tab data-type='week' href="#week"><?php echo $lang->todo->cycleWeek;?></a></li>
|
||||
<li <?php if($todo->config->type == 'month') echo "class='active'"?>><a data-tab data-type='month' href="#month"><?php echo $lang->todo->cycleMonth;?></a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane <?php if($todo->config->type == 'day') echo 'active'?>" id="day">
|
||||
<div class='input-group w-150px'>
|
||||
<span class='input-group-addon'><?php echo $lang->todo->every;?></span>
|
||||
<?php echo html::input('config[day]', isset($todo->config->day) ? $todo->config->day : 1, "class='form-control'")?>
|
||||
<span class='input-group-addon'><?php echo $lang->todo->cycleDay;?></span>
|
||||
<?php if($todo->cycle):?>
|
||||
<?php $todo->config = json_decode($todo->config);?>
|
||||
<div class="row form-group cycleConfig">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->cycleConfig;?></label>
|
||||
<div class="col-sm-10">
|
||||
<ul class="nav nav-tabs">
|
||||
<li <?php if($todo->config->type == 'day') echo "class='active'"?>><a data-tab data-type='day' href="#day"><?php echo $lang->todo->cycleDay;?></a></li>
|
||||
<li <?php if($todo->config->type == 'week') echo "class='active'"?>><a data-tab data-type='week' href="#week"><?php echo $lang->todo->cycleWeek;?></a></li>
|
||||
<li <?php if($todo->config->type == 'month') echo "class='active'"?>><a data-tab data-type='month' href="#month"><?php echo $lang->todo->cycleMonth;?></a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane <?php if($todo->config->type == 'day') echo 'active'?>" id="day">
|
||||
<div class='input-group w-150px'>
|
||||
<span class='input-group-addon'><?php echo $lang->todo->every;?></span>
|
||||
<?php echo html::input('config[day]', isset($todo->config->day) ? $todo->config->day : 1, "class='form-control'")?>
|
||||
<span class='input-group-addon'><?php echo $lang->todo->cycleDay;?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane <?php if($todo->config->type == 'week') echo 'active'?>" id="week">
|
||||
<?php echo html::checkbox('config[week]', $lang->todo->dayNames, isset($todo->config->week) ? $todo->config->week : '')?>
|
||||
</div>
|
||||
<div class="tab-pane <?php if($todo->config->type == 'month') echo 'active'?>" id="month">
|
||||
<?php
|
||||
$days = array();
|
||||
for($i = 1; $i <= 10; $i ++) $days[$i] = $i;
|
||||
echo "<p class='box1-10'>" . html::checkbox('config[month]', $days, isset($todo->config->month) ? $todo->config->month : '') . '</p>';
|
||||
$days = array();
|
||||
for($i = 11; $i <= 20; $i ++) $days[$i] = $i;
|
||||
echo "<p class='box11-20'>" . html::checkbox('config[month]', $days, isset($todo->config->month) ? $todo->config->month : '') . '</p>';
|
||||
$days = array();
|
||||
for($i = 21; $i <= 31; $i ++) $days[$i] = $i;
|
||||
echo "<p class='box21-31'>" . html::checkbox('config[month]', $days, isset($todo->config->month) ? $todo->config->month : '') . '</p>';
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane <?php if($todo->config->type == 'week') echo 'active'?>" id="week">
|
||||
<?php echo html::checkbox('config[week]', $lang->todo->dayNames, isset($todo->config->week) ? $todo->config->week : '')?>
|
||||
<?php echo html::hidden('config[type]', $todo->config->type)?>
|
||||
<div class='input-group' style='width:250px; padding-top:5px;'>
|
||||
<?php printf($lang->todo->beforeDays, html::input('config[beforeDays]', $todo->config->beforeDays, "class='form-control'"));?>
|
||||
</div>
|
||||
<div class="tab-pane <?php if($todo->config->type == 'month') echo 'active'?>" id="month">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group cycleConfig">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->deadline;?></label>
|
||||
<div class="col-sm-10">
|
||||
<?php echo html::input("config[end]", $todo->config->end, "class='form-control form-date'");?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->type;?></label>
|
||||
<div class="col-sm-10 todoType">
|
||||
<input type='hidden' name='type' value='<?php echo $todo->type;?>' />
|
||||
<?php echo $lang->todo->typeList[$todo->type];?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->pri;?></label>
|
||||
<div class="col-sm-2">
|
||||
<?php echo html::select('pri', $lang->todo->priList, $todo->pri, "class='form-control chosen'");?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->name;?></label>
|
||||
<div class="col-sm-10">
|
||||
<div id='nameBox' class='required'>
|
||||
<?php
|
||||
$days = array();
|
||||
for($i = 1; $i <= 10; $i ++) $days[$i] = $i;
|
||||
echo "<p class='box1-10'>" . html::checkbox('config[month]', $days, isset($todo->config->month) ? $todo->config->month : '') . '</p>';
|
||||
$days = array();
|
||||
for($i = 11; $i <= 20; $i ++) $days[$i] = $i;
|
||||
echo "<p class='box11-20'>" . html::checkbox('config[month]', $days, isset($todo->config->month) ? $todo->config->month : '') . '</p>';
|
||||
$days = array();
|
||||
for($i = 21; $i <= 31; $i ++) $days[$i] = $i;
|
||||
echo "<p class='box21-31'>" . html::checkbox('config[month]', $days, isset($todo->config->month) ? $todo->config->month : '') . '</p>';
|
||||
$readType = ($todo->type == 'bug' or $todo->type == 'task') ? 'readonly' : '';
|
||||
echo html::input('name', $todo->name, "$readType class='form-control'");
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo html::hidden('config[type]', $todo->config->type)?>
|
||||
<div class='input-group' style='width:250px; padding-top:5px;'>
|
||||
<?php printf($lang->todo->beforeDays, html::input('config[beforeDays]', $todo->config->beforeDays, "class='form-control'"));?>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->desc;?></label>
|
||||
<div class="col-sm-10">
|
||||
<?php echo html::textarea('desc', htmlspecialchars($todo->desc), "rows='8' class='form-control'");?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group cycleConfig">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->deadline;?></label>
|
||||
<div class="col-sm-10">
|
||||
<?php echo html::input("config[end]", $todo->config->end, "class='form-control form-date'");?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->type;?></label>
|
||||
<div class="col-sm-10 todoType">
|
||||
<input type='hidden' name='type' value='<?php echo $todo->type;?>' />
|
||||
<?php echo $lang->todo->typeList[$todo->type];?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->pri;?></label>
|
||||
<div class="col-sm-2">
|
||||
<?php echo html::select('pri', $lang->todo->priList, $todo->pri, "class='form-control chosen'");?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->name;?></label>
|
||||
<div class="col-sm-10">
|
||||
<div id='nameBox' class='required'>
|
||||
<?php
|
||||
$readType = ($todo->type == 'bug' or $todo->type == 'task') ? 'readonly' : '';
|
||||
echo html::input('name', $todo->name, "$readType class='form-control'");
|
||||
?>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->status;?></label>
|
||||
<div class="col-sm-2">
|
||||
<?php echo html::select('status', $lang->todo->statusList, $todo->status, "class='form-control'");?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->desc;?></label>
|
||||
<div class="col-sm-10">
|
||||
<?php echo html::textarea('desc', htmlspecialchars($todo->desc), "rows='8' class='form-control'");?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->status;?></label>
|
||||
<div class="col-sm-2">
|
||||
<?php echo html::select('status', $lang->todo->statusList, $todo->status, "class='form-control'");?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->beginAndEnd;?></label>
|
||||
<div class="col-sm-2" style='padding-right:0px'>
|
||||
<?php echo html::select('begin', $times, $todo->begin, 'onchange=selectNext(); class="form-control chosen" data-drop_direction="up"')?>
|
||||
</div>
|
||||
<div class="col-sm-2" style='padding-left:0px'>
|
||||
<?php echo html::select('end', $times, $todo->end, 'class="form-control chosen" data-drop_direction="up"');?>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class='checkbox-primary dateSwitcher'>
|
||||
<input type='checkbox' id='dateSwitcher' onclick='switchDateFeature(this);' <?php if($todo->begin == 2400) echo 'checked';?> >
|
||||
<label for='dateSwitcher'><?php echo $lang->todo->lblDisableDate;?></label>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->beginAndEnd;?></label>
|
||||
<div class="col-sm-2" style='padding-right:0px'>
|
||||
<?php echo html::select('begin', $times, $todo->begin, 'onchange=selectNext(); class="form-control chosen" data-drop_direction="up"')?>
|
||||
</div>
|
||||
<div class="col-sm-2" style='padding-left:0px'>
|
||||
<?php echo html::select('end', $times, $todo->end, 'class="form-control chosen" data-drop_direction="up"');?>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class='checkbox-primary dateSwitcher'>
|
||||
<input type='checkbox' id='dateSwitcher' onclick='switchDateFeature(this);' <?php if($todo->begin == 2400) echo 'checked';?> >
|
||||
<label for='dateSwitcher'><?php echo $lang->todo->lblDisableDate;?></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"></label>
|
||||
<div class="col-sm-10">
|
||||
<div class='checkbox-primary'>
|
||||
<input type='checkbox' name='private' id='private' value='1' <?php if($todo->private) echo 'checked';?> />
|
||||
<label for='private'><?php echo $lang->todo->private;?></label>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"></label>
|
||||
<div class="col-sm-10">
|
||||
<div class='checkbox-primary'>
|
||||
<input type='checkbox' name='private' id='private' value='1' <?php if($todo->private) echo 'checked';?> />
|
||||
<label for='private'><?php echo $lang->todo->private;?></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group form-actions">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<?php echo html::submitButton();?>
|
||||
<?php echo html::backButton();?>
|
||||
<div class="row form-group form-actions">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<?php echo html::submitButton();?>
|
||||
<?php echo html::backButton();?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php include './footer.html.php';?>
|
||||
<script>switchDateFeature(document.getElementById('dateSwitcher'));</script>
|
||||
|
||||
@@ -17,4 +17,3 @@ $config->user->contactField = 'mobile,phone,qq,dingding,weixin,skype,whatsapp,sl
|
||||
$config->user->failTimes = 6;
|
||||
$config->user->lockMinutes = 10;
|
||||
$config->user->batchCreate = 10;
|
||||
$config->user->selectFields = 'dept,role';
|
||||
|
||||
@@ -377,7 +377,7 @@ class userModel extends model
|
||||
$oldUser = $this->getById($userID, 'id');
|
||||
|
||||
$userID = $oldUser->id;
|
||||
$user = fixer::input('post')
|
||||
$user = fixer::input('post')
|
||||
->setDefault('join', '0000-00-00')
|
||||
->setIF($this->post->password1 != false, 'password', substr($this->post->password1, 0, 32))
|
||||
->setIF($this->post->email != false, 'email', trim($this->post->email))
|
||||
@@ -418,18 +418,32 @@ class userModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
$this->dao->delete()->from(TABLE_USERGROUP)->where('account')->eq($this->post->account)->exec();
|
||||
if(isset($_POST['groups']))
|
||||
$oldGroups = $this->dao->select('`group`')->from(TABLE_USERGROUP)->where('account')->eq($this->post->account)->fetchPairs('group', 'group');
|
||||
$newGroups = zget($_POST, 'groups', array());
|
||||
sort($oldGroups);
|
||||
sort($newGroups);
|
||||
|
||||
/* If change group then reset usergroup. */
|
||||
if(join(',', $oldGroups) != join(',', $newGroups))
|
||||
{
|
||||
foreach($this->post->groups as $groupID)
|
||||
/* Reset usergroup for account. */
|
||||
$this->dao->delete()->from(TABLE_USERGROUP)->where('account')->eq($this->post->account)->exec();
|
||||
|
||||
/* Set usergroup for account. */
|
||||
if(isset($_POST['groups']))
|
||||
{
|
||||
$data = new stdclass();
|
||||
$data->account = $this->post->account;
|
||||
$data->group = $groupID;
|
||||
$this->dao->replace(TABLE_USERGROUP)->data($data)->exec();
|
||||
foreach($this->post->groups as $groupID)
|
||||
{
|
||||
$data = new stdclass();
|
||||
$data->account = $this->post->account;
|
||||
$data->group = $groupID;
|
||||
$this->dao->replace(TABLE_USERGROUP)->data($data)->exec();
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute user view. */
|
||||
$this->computeUserView($this->post->account, true);
|
||||
}
|
||||
$this->computeUserView($this->post->account, true);
|
||||
|
||||
if(!empty($user->password) and $user->account == $this->app->user->account) $this->app->user->password = $user->password;
|
||||
if(!dao::isError())
|
||||
|
||||
@@ -40,8 +40,8 @@ class webhook extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
/* Unset whiteListDept cookie. */
|
||||
setcookie('whiteListDept', '', 0, $this->config->webRoot, '', false, true);
|
||||
/* Unset selectedDepts cookie. */
|
||||
setcookie('selectedDepts', '', 0, $this->config->webRoot, '', false, true);
|
||||
|
||||
$this->view->title = $this->lang->webhook->api . $this->lang->colon . $this->lang->webhook->list;
|
||||
$this->view->webhooks = $this->webhook->getList($orderBy, $pager);
|
||||
@@ -178,19 +178,19 @@ class webhook extends control
|
||||
}
|
||||
$webhook->secret = json_decode($webhook->secret);
|
||||
|
||||
/* Get whiteList dept. */
|
||||
if($this->get->whiteListDept)
|
||||
/* Get selected depts. */
|
||||
if($this->get->selectedDepts)
|
||||
{
|
||||
setcookie('whiteListDept', $this->get->whiteListDept, 0, $this->config->webRoot, '', false, true);
|
||||
$_COOKIE['whiteListDept'] = $this->get->whiteListDept;
|
||||
setcookie('selectedDepts', $this->get->selectedDepts, 0, $this->config->webRoot, '', false, true);
|
||||
$_COOKIE['selectedDepts'] = $this->get->selectedDepts;
|
||||
}
|
||||
$whiteListDept = $this->cookie->whiteListDept ? $this->cookie->whiteListDept : '';
|
||||
$selectedDepts = $this->cookie->selectedDepts ? $this->cookie->selectedDepts : '';
|
||||
|
||||
if($webhook->type == 'dinguser')
|
||||
{
|
||||
$this->app->loadClass('dingapi', true);
|
||||
$dingapi = new dingapi($webhook->secret->appKey, $webhook->secret->appSecret, $webhook->secret->agentId);
|
||||
$response = $dingapi->getAllUsers($whiteListDept);
|
||||
$response = $dingapi->getUsers($selectedDepts);
|
||||
}
|
||||
elseif($webhook->type == 'wechatuser')
|
||||
{
|
||||
@@ -201,9 +201,9 @@ class webhook extends control
|
||||
|
||||
if($response['result'] == 'fail')
|
||||
{
|
||||
if($response['message'] == 'moreRequest')
|
||||
if($response['message'] == 'nodept')
|
||||
{
|
||||
echo js::error($this->webhook->error->moreDept);
|
||||
echo js::error($this->lang->webhook->error->noDept);
|
||||
die(js::locate($this->createLink('webhook', 'chooseDept', "id=$id")));
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ class webhook extends control
|
||||
$this->view->users = $users;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->bindedUsers = $bindedPairs;
|
||||
$this->view->whiteListDept = $whiteListDept;
|
||||
$this->view->selectedDepts = $selectedDepts;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ class webhook extends control
|
||||
{
|
||||
$this->app->loadClass('dingapi', true);
|
||||
$dingapi = new dingapi($webhook->secret->appKey, $webhook->secret->appSecret, $webhook->secret->agentId);
|
||||
$response = $dingapi->getTopDepts();
|
||||
$response = $dingapi->getDeptTree();
|
||||
}
|
||||
|
||||
if($response['result'] == 'fail')
|
||||
@@ -276,7 +276,7 @@ class webhook extends control
|
||||
$this->view->title = $this->lang->webhook->chooseDept;
|
||||
$this->view->position[] = $this->lang->webhook->chooseDept;
|
||||
|
||||
$this->view->topDepts = $response['data'];
|
||||
$this->view->deptTree = $response['data'];
|
||||
$this->view->webhookID = $id;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -9,11 +9,10 @@ $lang->webhook->chooseDept = 'Choose department';
|
||||
$lang->webhook->assigned = 'Augeordnet an';
|
||||
$lang->webhook->setting = 'Einstellungen';
|
||||
|
||||
$lang->webhook->browse = 'Durchsuchen';
|
||||
$lang->webhook->create = 'Erstellen';
|
||||
$lang->webhook->edit = 'Bearbeiten';
|
||||
$lang->webhook->delete = 'Löschen';
|
||||
$lang->webhook->rechooseDept = 'Rechoose department';
|
||||
$lang->webhook->browse = 'Durchsuchen';
|
||||
$lang->webhook->create = 'Erstellen';
|
||||
$lang->webhook->edit = 'Bearbeiten';
|
||||
$lang->webhook->delete = 'Löschen';
|
||||
|
||||
$lang->webhook->id = 'ID';
|
||||
$lang->webhook->type = 'Typ';
|
||||
@@ -46,11 +45,12 @@ $lang->webhook->typeList['default'] = 'Others';
|
||||
$lang->webhook->sendTypeList['sync'] = 'Synchron';
|
||||
$lang->webhook->sendTypeList['async'] = 'Asynchron';
|
||||
|
||||
$lang->webhook->dingAgentId = 'AgentID';
|
||||
$lang->webhook->dingAppKey = 'AppKey';
|
||||
$lang->webhook->dingAppSecret = 'AppSecret';
|
||||
$lang->webhook->dingUserid = 'Ding Userid';
|
||||
$lang->webhook->dingBindStatus = 'Bind Status';
|
||||
$lang->webhook->dingAgentId = 'AgentID';
|
||||
$lang->webhook->dingAppKey = 'AppKey';
|
||||
$lang->webhook->dingAppSecret = 'AppSecret';
|
||||
$lang->webhook->dingUserid = 'Ding Userid';
|
||||
$lang->webhook->dingBindStatus = 'Bind Status';
|
||||
$lang->webhook->chooseDeptAgain = 'Rechoose department';
|
||||
|
||||
$lang->webhook->wechatCorpId = 'Corp ID';
|
||||
$lang->webhook->wechatCorpSecret = 'Corp Secret';
|
||||
@@ -92,5 +92,5 @@ $lang->webhook->note->typeList['weixin'] = 'Add a customized bot in WeChat an
|
||||
$lang->webhook->note->typeList['default'] = 'Webhookadresse on anderen erhalten.';
|
||||
|
||||
$lang->webhook->error = new stdclass();
|
||||
$lang->webhook->error->curl = 'Laden Sie php-curl in der php.ini.';
|
||||
$lang->webhook->error->moreDept = 'There are too many departments. Getting users may time out. Please choose department first.';
|
||||
$lang->webhook->error->curl = 'Laden Sie php-curl in der php.ini.';
|
||||
$lang->webhook->error->noDept = 'There is no department selected. Please choose department first.';
|
||||
|
||||
@@ -9,11 +9,10 @@ $lang->webhook->chooseDept = 'Choose department';
|
||||
$lang->webhook->assigned = 'AssignedTo';
|
||||
$lang->webhook->setting = 'Settings';
|
||||
|
||||
$lang->webhook->browse = 'Browse';
|
||||
$lang->webhook->create = 'Create';
|
||||
$lang->webhook->edit = 'Edit';
|
||||
$lang->webhook->delete = 'Delete';
|
||||
$lang->webhook->rechooseDept = 'Rechoose department';
|
||||
$lang->webhook->browse = 'Browse';
|
||||
$lang->webhook->create = 'Create';
|
||||
$lang->webhook->edit = 'Edit';
|
||||
$lang->webhook->delete = 'Delete';
|
||||
|
||||
$lang->webhook->id = 'ID';
|
||||
$lang->webhook->type = 'Type';
|
||||
@@ -46,11 +45,12 @@ $lang->webhook->typeList['default'] = 'Others';
|
||||
$lang->webhook->sendTypeList['sync'] = 'Synchronous';
|
||||
$lang->webhook->sendTypeList['async'] = 'Asynchronous';
|
||||
|
||||
$lang->webhook->dingAgentId = 'AgentID';
|
||||
$lang->webhook->dingAppKey = 'AppKey';
|
||||
$lang->webhook->dingAppSecret = 'AppSecret';
|
||||
$lang->webhook->dingUserid = 'Ding UserID';
|
||||
$lang->webhook->dingBindStatus = 'Bind Status';
|
||||
$lang->webhook->dingAgentId = 'AgentID';
|
||||
$lang->webhook->dingAppKey = 'AppKey';
|
||||
$lang->webhook->dingAppSecret = 'AppSecret';
|
||||
$lang->webhook->dingUserid = 'Ding UserID';
|
||||
$lang->webhook->dingBindStatus = 'Bind Status';
|
||||
$lang->webhook->chooseDeptAgain = 'Rechoose department';
|
||||
|
||||
$lang->webhook->wechatCorpId = 'Corp ID';
|
||||
$lang->webhook->wechatCorpSecret = 'Corp Secret';
|
||||
@@ -92,5 +92,5 @@ $lang->webhook->note->typeList['weixin'] = 'Add a customized bot in WeChat an
|
||||
$lang->webhook->note->typeList['default'] = 'Get a webhook url from others';
|
||||
|
||||
$lang->webhook->error = new stdclass();
|
||||
$lang->webhook->error->curl = 'Load php-curl in php.ini.';
|
||||
$lang->webhook->error->moreDept = 'There are too many departments. Getting users may time out. Please choose department first.';
|
||||
$lang->webhook->error->curl = 'Load php-curl in php.ini.';
|
||||
$lang->webhook->error->noDept = 'There is no department selected. Please choose department first.';
|
||||
|
||||
@@ -9,11 +9,10 @@ $lang->webhook->chooseDept = 'Choose department';
|
||||
$lang->webhook->assigned = 'Assign';
|
||||
$lang->webhook->setting = 'Paramétrages';
|
||||
|
||||
$lang->webhook->browse = 'Consulter';
|
||||
$lang->webhook->create = 'Créer';
|
||||
$lang->webhook->edit = 'Modifier';
|
||||
$lang->webhook->delete = 'Supprimer';
|
||||
$lang->webhook->rechooseDept = 'Rechoose department';
|
||||
$lang->webhook->browse = 'Consulter';
|
||||
$lang->webhook->create = 'Créer';
|
||||
$lang->webhook->edit = 'Modifier';
|
||||
$lang->webhook->delete = 'Supprimer';
|
||||
|
||||
$lang->webhook->id = 'ID';
|
||||
$lang->webhook->type = 'Type';
|
||||
@@ -46,11 +45,12 @@ $lang->webhook->typeList['default'] = 'Others';
|
||||
$lang->webhook->sendTypeList['sync'] = 'Synchrone';
|
||||
$lang->webhook->sendTypeList['async'] = 'Asynchrone';
|
||||
|
||||
$lang->webhook->dingAgentId = 'AgentID';
|
||||
$lang->webhook->dingAppKey = 'AppKey';
|
||||
$lang->webhook->dingAppSecret = 'AppSecret';
|
||||
$lang->webhook->dingUserid = 'Ding Userid';
|
||||
$lang->webhook->dingBindStatus = 'Bind Status';
|
||||
$lang->webhook->dingAgentId = 'AgentID';
|
||||
$lang->webhook->dingAppKey = 'AppKey';
|
||||
$lang->webhook->dingAppSecret = 'AppSecret';
|
||||
$lang->webhook->dingUserid = 'Ding Userid';
|
||||
$lang->webhook->dingBindStatus = 'Bind Status';
|
||||
$lang->webhook->chooseDeptAgain = 'Rechoose department';
|
||||
|
||||
$lang->webhook->wechatCorpId = 'Corp ID';
|
||||
$lang->webhook->wechatCorpSecret = 'Corp Secret';
|
||||
@@ -92,5 +92,5 @@ $lang->webhook->note->typeList['weixin'] = 'Add a customized bot in WeChat an
|
||||
$lang->webhook->note->typeList['default'] = "Obtenir les url d'autres flux webhook.";
|
||||
|
||||
$lang->webhook->error = new stdclass();
|
||||
$lang->webhook->error->curl = 'Chargez php-curl dans php.ini.';
|
||||
$lang->webhook->error->moreDept = 'There are too many departments. Getting users may time out. Please choose department first.';
|
||||
$lang->webhook->error->curl = 'Chargez php-curl dans php.ini.';
|
||||
$lang->webhook->error->noDept = 'There is no department selected. Please choose department first.';
|
||||
|
||||
@@ -13,7 +13,6 @@ $lang->webhook->browse = 'Browse';
|
||||
$lang->webhook->create = 'Tạo';
|
||||
$lang->webhook->edit = 'Sửa';
|
||||
$lang->webhook->delete = 'Xóa';
|
||||
$lang->webhook->rechooseDept = 'Rechoose department';
|
||||
|
||||
$lang->webhook->id = 'ID';
|
||||
$lang->webhook->type = 'Loại';
|
||||
@@ -46,11 +45,12 @@ $lang->webhook->typeList['default'] = 'Khác';
|
||||
$lang->webhook->sendTypeList['sync'] = 'Synchronous';
|
||||
$lang->webhook->sendTypeList['async'] = 'Asynchronous';
|
||||
|
||||
$lang->webhook->dingAgentId = 'AgentID';
|
||||
$lang->webhook->dingAppKey = 'AppKey';
|
||||
$lang->webhook->dingAppSecret = 'AppSecret';
|
||||
$lang->webhook->dingUserid = 'Ding UserID';
|
||||
$lang->webhook->dingBindStatus = 'Bind tình trạng';
|
||||
$lang->webhook->dingAgentId = 'AgentID';
|
||||
$lang->webhook->dingAppKey = 'AppKey';
|
||||
$lang->webhook->dingAppSecret = 'AppSecret';
|
||||
$lang->webhook->dingUserid = 'Ding UserID';
|
||||
$lang->webhook->dingBindStatus = 'Bind tình trạng';
|
||||
$lang->webhook->chooseDeptAgain = 'Rechoose department';
|
||||
|
||||
$lang->webhook->wechatCorpId = 'Corp ID';
|
||||
$lang->webhook->wechatCorpSecret = 'Corp Secret';
|
||||
@@ -92,5 +92,5 @@ $lang->webhook->note->typeList['weixin'] = 'Thêm a customized bot in WeChat
|
||||
$lang->webhook->note->typeList['default'] = 'Nhận a webhook url from others';
|
||||
|
||||
$lang->webhook->error = new stdclass();
|
||||
$lang->webhook->error->curl = 'Load php-curl in php.ini.';
|
||||
$lang->webhook->error->moreDept = 'There are too many departments. Getting users may time out. Please choose department first.';
|
||||
$lang->webhook->error->curl = 'Load php-curl in php.ini.';
|
||||
$lang->webhook->error->noDept = 'There is no department selected. Please choose department first.';
|
||||
|
||||
@@ -9,11 +9,10 @@ $lang->webhook->chooseDept = '选择同步部门';
|
||||
$lang->webhook->assigned = '指派给';
|
||||
$lang->webhook->setting = '设置';
|
||||
|
||||
$lang->webhook->browse = '浏览Webhook';
|
||||
$lang->webhook->create = '添加Webhook';
|
||||
$lang->webhook->edit = '编辑Webhook';
|
||||
$lang->webhook->delete = '删除Webhook';
|
||||
$lang->webhook->rechooseDept = '重选部门';
|
||||
$lang->webhook->browse = '浏览Webhook';
|
||||
$lang->webhook->create = '添加Webhook';
|
||||
$lang->webhook->edit = '编辑Webhook';
|
||||
$lang->webhook->delete = '删除Webhook';
|
||||
|
||||
$lang->webhook->id = 'ID';
|
||||
$lang->webhook->type = '类型';
|
||||
@@ -46,11 +45,12 @@ $lang->webhook->typeList['default'] = '其他';
|
||||
$lang->webhook->sendTypeList['sync'] = '同步';
|
||||
$lang->webhook->sendTypeList['async'] = '异步';
|
||||
|
||||
$lang->webhook->dingAgentId = '钉钉AgentId';
|
||||
$lang->webhook->dingAppKey = '钉钉AppKey';
|
||||
$lang->webhook->dingAppSecret = '钉钉AppSecret';
|
||||
$lang->webhook->dingUserid = '钉钉用户';
|
||||
$lang->webhook->dingBindStatus = '钉钉绑定状态';
|
||||
$lang->webhook->dingAgentId = '钉钉AgentId';
|
||||
$lang->webhook->dingAppKey = '钉钉AppKey';
|
||||
$lang->webhook->dingAppSecret = '钉钉AppSecret';
|
||||
$lang->webhook->dingUserid = '钉钉用户';
|
||||
$lang->webhook->dingBindStatus = '钉钉绑定状态';
|
||||
$lang->webhook->chooseDeptAgain = '重选部门';
|
||||
|
||||
$lang->webhook->wechatCorpId = '企业ID';
|
||||
$lang->webhook->wechatCorpSecret = '应用的凭证密钥';
|
||||
@@ -92,5 +92,5 @@ $lang->webhook->note->typeList['weixin'] = '请在企业微信中添加一个
|
||||
$lang->webhook->note->typeList['default'] = '从第三方系统获取webhook并填写到此处。';
|
||||
|
||||
$lang->webhook->error = new stdclass();
|
||||
$lang->webhook->error->curl = '需要加载php-curl扩展。';
|
||||
$lang->webhook->error->moreDept = '部门太多,获取用户可能会超时,请先选择同步部门。';
|
||||
$lang->webhook->error->curl = '需要加载php-curl扩展。';
|
||||
$lang->webhook->error->noDept = '没有选择部门,请先选择同步部门。';
|
||||
|
||||
@@ -9,11 +9,10 @@ $lang->webhook->chooseDept = '選擇同步部門';
|
||||
$lang->webhook->assigned = '指派給';
|
||||
$lang->webhook->setting = '設置';
|
||||
|
||||
$lang->webhook->browse = '瀏覽Webhook';
|
||||
$lang->webhook->create = '添加Webhook';
|
||||
$lang->webhook->edit = '編輯Webhook';
|
||||
$lang->webhook->delete = '刪除Webhook';
|
||||
$lang->webhook->rechooseDept = '重選部門';
|
||||
$lang->webhook->browse = '瀏覽Webhook';
|
||||
$lang->webhook->create = '添加Webhook';
|
||||
$lang->webhook->edit = '編輯Webhook';
|
||||
$lang->webhook->delete = '刪除Webhook';
|
||||
|
||||
$lang->webhook->id = 'ID';
|
||||
$lang->webhook->type = '類型';
|
||||
@@ -46,11 +45,12 @@ $lang->webhook->typeList['default'] = '其他';
|
||||
$lang->webhook->sendTypeList['sync'] = '同步';
|
||||
$lang->webhook->sendTypeList['async'] = '非同步';
|
||||
|
||||
$lang->webhook->dingAgentId = '釘釘AgentId';
|
||||
$lang->webhook->dingAppKey = '釘釘AppKey';
|
||||
$lang->webhook->dingAppSecret = '釘釘AppSecret';
|
||||
$lang->webhook->dingUserid = '釘釘用戶';
|
||||
$lang->webhook->dingBindStatus = '釘釘綁定狀態';
|
||||
$lang->webhook->dingAgentId = '釘釘AgentId';
|
||||
$lang->webhook->dingAppKey = '釘釘AppKey';
|
||||
$lang->webhook->dingAppSecret = '釘釘AppSecret';
|
||||
$lang->webhook->dingUserid = '釘釘用戶';
|
||||
$lang->webhook->dingBindStatus = '釘釘綁定狀態';
|
||||
$lang->webhook->chooseDeptAgain = '重選部門';
|
||||
|
||||
$lang->webhook->wechatCorpId = '企業ID';
|
||||
$lang->webhook->wechatCorpSecret = '應用的憑證密鑰';
|
||||
@@ -92,5 +92,5 @@ $lang->webhook->note->typeList['weixin'] = '請在企業微信中添加一個
|
||||
$lang->webhook->note->typeList['default'] = '從第三方系統獲取webhook並填寫到此處。';
|
||||
|
||||
$lang->webhook->error = new stdclass();
|
||||
$lang->webhook->error->curl = '需要加載php-curl擴展。';
|
||||
$lang->webhook->error->moreDept = '部門太多,獲取用戶可能會超時,請先選擇同步部門。';
|
||||
$lang->webhook->error->curl = '需要加載php-curl擴展。';
|
||||
$lang->webhook->error->noDept = '沒有選擇部門,請先選擇同步部門。';
|
||||
|
||||
@@ -423,7 +423,7 @@ class webhookModel extends model
|
||||
unset($_GET['onlybody']);
|
||||
}
|
||||
if($objectType == 'case') $objectType = 'testcase';
|
||||
$viewLink = helper::createLink($objectType, 'view', "id=$objectID");
|
||||
$viewLink = helper::createLink($objectType, 'view', "id=$objectID", 'html');
|
||||
if($oldOnlyBody) $_GET['onlybody'] = $oldOnlyBody;
|
||||
|
||||
return $viewLink;
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<div class='text'>
|
||||
<?php echo html::submitButton($lang->save, '', 'btn btn-primary');?>
|
||||
<?php echo html::a($this->createLink('webhook', 'browse'), $lang->goback, '', "class='btn'");?>
|
||||
<?php if($whiteListDept) echo html::a($this->createLink('webhook', 'chooseDept', "id={$webhook->id}"), $lang->webhook->rechooseDept, '', "class='btn'");?>
|
||||
<?php if($selectedDepts) echo html::a($this->createLink('webhook', 'chooseDept', "id={$webhook->id}"), $lang->webhook->chooseDeptAgain, '', "class='btn'");?>
|
||||
</div>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
</div>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<td class='text' title='<?php echo $webhook->url;?>'><?php echo $webhook->url;?></td>
|
||||
<td class='c-actions text-right'>
|
||||
<?php
|
||||
if($webhook->type == 'dinguser' or $webhook->type == 'wechatuser') common::printIcon('webhook', 'bind', "webhookID=$id", '', 'list', 'link');
|
||||
if($webhook->type == 'dinguser' or $webhook->type == 'wechatuser') common::printIcon('webhook', 'chooseDept', "webhookID=$id", '', 'list', 'link');
|
||||
common::printIcon('webhook', 'log', "webhookID=$id", '', 'list', 'file-text');
|
||||
common::printIcon('webhook', 'edit', "webhookID=$id", '', 'list');
|
||||
if(common::hasPriv('webhook', 'delete'))
|
||||
|
||||
@@ -11,45 +11,51 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/ztree.html.php';?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block mw-800px'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->webhook->chooseDept?></h2>
|
||||
</div>
|
||||
<table id='deptList' class='table table-fixed table-bordered active-disabled table-hover'>
|
||||
<tbody>
|
||||
<?php foreach($topDepts as $deptID => $deptName):?>
|
||||
<tr>
|
||||
<td><?php echo html::checkbox('deptID', array($deptID => $deptName));?></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>
|
||||
<?php echo html::selectAll();?>
|
||||
<?php echo html::selectReverse();?>
|
||||
<?php echo html::commonButton($lang->save, '', 'btn btn-primary save');?>
|
||||
<?php echo html::a($this->createLink('webhook', 'browse'), $lang->goback, '', "class='btn'");?>
|
||||
</td>
|
||||
</tfoot>
|
||||
</table>
|
||||
<ul id='deptList' class="ztree"></ul>
|
||||
<div class='actions'>
|
||||
<?php echo html::commonButton($lang->save, '', 'btn btn-primary save');?>
|
||||
<?php echo html::a($this->createLink('webhook', 'browse'), $lang->goback, '', "class='btn'");?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php js::set('deptTree', $deptTree);?>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
$('#deptList tfoot .save').click(function()
|
||||
var ztreeSettings =
|
||||
{
|
||||
var whiteListDept = '';
|
||||
$('#deptList tbody tr td :checkbox[id^=deptID]:checked').each(function()
|
||||
check:
|
||||
{
|
||||
whiteListDept += ',' + $(this).val();
|
||||
});
|
||||
if(whiteListDept) whiteListDept = whiteListDept.substr(1);
|
||||
enable: true,
|
||||
chkStyle: "checkbox",
|
||||
chkboxType: {"Y":"s", "N":"s"}
|
||||
},
|
||||
data:
|
||||
{
|
||||
simpleData: {enable: true}
|
||||
}
|
||||
};
|
||||
ztreeObj = $.fn.zTree.init($("#deptList"), ztreeSettings, deptTree);
|
||||
|
||||
$('.actions .save').click(function()
|
||||
{
|
||||
var nodes = ztreeObj.getCheckedNodes(true);
|
||||
var selectedDepts = '';
|
||||
for(i in nodes)
|
||||
{
|
||||
node = nodes[i];
|
||||
selectedDepts += ',' + node.id;
|
||||
}
|
||||
if(selectedDepts) selectedDepts = selectedDepts.substr(1);
|
||||
|
||||
var sign = config.requestType == 'PATH_INFO' ? '?' : '&';
|
||||
var link = createLink('webhook', 'bind', "id=<?php echo $webhookID;?>") + sign + "whiteListDept=" + whiteListDept;
|
||||
var link = createLink('webhook', 'bind', "id=<?php echo $webhookID;?>") + sign + "selectedDepts=" + selectedDepts;
|
||||
location.href = link;
|
||||
|
||||
return false;
|
||||
|
||||
|
After Width: | Height: | Size: 601 B |
|
After Width: | Height: | Size: 580 B |
|
After Width: | Height: | Size: 570 B |
|
After Width: | Height: | Size: 762 B |
|
After Width: | Height: | Size: 399 B |
|
After Width: | Height: | Size: 710 B |
|
After Width: | Height: | Size: 432 B |
|
After Width: | Height: | Size: 534 B |
|
After Width: | Height: | Size: 529 B |
|
After Width: | Height: | Size: 467 B |
|
After Width: | Height: | Size: 45 B |
|
After Width: | Height: | Size: 381 B |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,97 @@
|
||||
/*-------------------------------------
|
||||
zTree Style
|
||||
|
||||
version: 3.5.19
|
||||
author: Hunter.z
|
||||
email: hunter.z@263.net
|
||||
website: http://code.google.com/p/jquerytree/
|
||||
|
||||
-------------------------------------*/
|
||||
|
||||
.ztree * {padding:0; margin:0; font-size:13px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif}
|
||||
.ztree {margin:0; padding:5px; color:#333}
|
||||
.ztree li{padding:0; margin:0; list-style:none; line-height:14px; text-align:left; white-space:nowrap; outline:0}
|
||||
.ztree li ul{ margin:0; padding:0 0 0 18px}
|
||||
.ztree li ul.line{ background:url(./img/line_conn.gif) 0 0 repeat-y;}
|
||||
|
||||
.ztree li a {padding:1px 3px 0 0; margin:0; cursor:pointer; height:17px; color:#333; background-color: transparent;
|
||||
text-decoration:none; vertical-align:top; display: inline-block}
|
||||
.ztree li a:hover {text-decoration:underline}
|
||||
.ztree li a.curSelectedNode {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;}
|
||||
.ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;}
|
||||
.ztree li a.tmpTargetNode_inner {padding-top:0px; background-color:#316AC5; color:white; height:16px; border:1px #316AC5 solid;
|
||||
opacity:0.8; filter:alpha(opacity=80)}
|
||||
.ztree li a.tmpTargetNode_prev {}
|
||||
.ztree li a.tmpTargetNode_next {}
|
||||
.ztree li a input.rename {height:14px; width:80px; padding:0; margin:0;
|
||||
font-size:13px; border:1px #7EC4CC solid; *border:0px}
|
||||
.ztree li span {line-height:16px; margin-right:2px}
|
||||
.ztree li span.button {line-height:0; margin:0; width:16px; height:16px; display: inline-block; vertical-align:middle;
|
||||
border:0 none; cursor: pointer;outline:none;
|
||||
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
|
||||
background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")}
|
||||
|
||||
.ztree li span.button.chk {width:13px; height:13px; margin:0 3px 0 0; cursor: auto}
|
||||
.ztree li span.button.chk.checkbox_false_full {background-position:0 0}
|
||||
.ztree li span.button.chk.checkbox_false_full_focus {background-position:0 -14px}
|
||||
.ztree li span.button.chk.checkbox_false_part {background-position:0 -28px}
|
||||
.ztree li span.button.chk.checkbox_false_part_focus {background-position:0 -42px}
|
||||
.ztree li span.button.chk.checkbox_false_disable {background-position:0 -56px}
|
||||
.ztree li span.button.chk.checkbox_true_full {background-position:-14px 0}
|
||||
.ztree li span.button.chk.checkbox_true_full_focus {background-position:-14px -14px}
|
||||
.ztree li span.button.chk.checkbox_true_part {background-position:-14px -28px}
|
||||
.ztree li span.button.chk.checkbox_true_part_focus {background-position:-14px -42px}
|
||||
.ztree li span.button.chk.checkbox_true_disable {background-position:-14px -56px}
|
||||
.ztree li span.button.chk.radio_false_full {background-position:-28px 0}
|
||||
.ztree li span.button.chk.radio_false_full_focus {background-position:-28px -14px}
|
||||
.ztree li span.button.chk.radio_false_part {background-position:-28px -28px}
|
||||
.ztree li span.button.chk.radio_false_part_focus {background-position:-28px -42px}
|
||||
.ztree li span.button.chk.radio_false_disable {background-position:-28px -56px}
|
||||
.ztree li span.button.chk.radio_true_full {background-position:-42px 0}
|
||||
.ztree li span.button.chk.radio_true_full_focus {background-position:-42px -14px}
|
||||
.ztree li span.button.chk.radio_true_part {background-position:-42px -28px}
|
||||
.ztree li span.button.chk.radio_true_part_focus {background-position:-42px -42px}
|
||||
.ztree li span.button.chk.radio_true_disable {background-position:-42px -56px}
|
||||
|
||||
.ztree li span.button.switch {width:18px; height:18px}
|
||||
.ztree li span.button.root_open{background-position:-92px -54px}
|
||||
.ztree li span.button.root_close{background-position:-74px -54px}
|
||||
.ztree li span.button.roots_open{background-position:-92px 0}
|
||||
.ztree li span.button.roots_close{background-position:-74px 0}
|
||||
.ztree li span.button.center_open{background-position:-92px -18px}
|
||||
.ztree li span.button.center_close{background-position:-74px -18px}
|
||||
.ztree li span.button.bottom_open{background-position:-92px -36px}
|
||||
.ztree li span.button.bottom_close{background-position:-74px -36px}
|
||||
.ztree li span.button.noline_open{background-position:-92px -72px}
|
||||
.ztree li span.button.noline_close{background-position:-74px -72px}
|
||||
.ztree li span.button.root_docu{ background:none;}
|
||||
.ztree li span.button.roots_docu{background-position:-56px 0}
|
||||
.ztree li span.button.center_docu{background-position:-56px -18px}
|
||||
.ztree li span.button.bottom_docu{background-position:-56px -36px}
|
||||
.ztree li span.button.noline_docu{ background:none;}
|
||||
|
||||
.ztree li span.button.ico_open{margin-right:2px; background-position:-110px -16px; vertical-align:top; *vertical-align:middle}
|
||||
.ztree li span.button.ico_close{margin-right:2px; background-position:-110px 0; vertical-align:top; *vertical-align:middle}
|
||||
.ztree li span.button.ico_docu{margin-right:2px; background-position:-110px -32px; vertical-align:top; *vertical-align:middle}
|
||||
.ztree li span.button.edit {margin-right:2px; background-position:-110px -48px; vertical-align:top; *vertical-align:middle}
|
||||
.ztree li span.button.remove {margin-right:2px; background-position:-110px -64px; vertical-align:top; *vertical-align:middle}
|
||||
|
||||
.ztree li span.button.ico_loading{margin-right:2px; background:url(./img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}
|
||||
|
||||
ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)}
|
||||
|
||||
span.tmpzTreeMove_arrow {width:16px; height:16px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute;
|
||||
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
|
||||
background-position:-110px -80px; background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")}
|
||||
|
||||
ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)}
|
||||
.zTreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute}
|
||||
|
||||
/* level style*/
|
||||
/*.ztree li span.button.level0 {
|
||||
display:none;
|
||||
}
|
||||
.ztree li ul.level0 {
|
||||
padding:0;
|
||||
background:none;
|
||||
}*/
|
||||