Merge branch 'master' of github.com:easysoft/zentaopms
This commit is contained in:
@@ -158,7 +158,6 @@ $filter->todo->export->cookie['checkedItem'] = 'reg::checked';
|
||||
|
||||
$filter->user->login->cookie['keepLogin'] = 'equal::on';
|
||||
|
||||
|
||||
$filter->block->default->get['hash'] = 'reg::md5';
|
||||
$filter->block->main->get['blockid'] = 'code';
|
||||
$filter->block->main->get['blockTitle'] = 'reg::any';
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `zt_bug` ADD `activatedDate` datetime NOT NULL AFTER `activatedCount`;
|
||||
ALTER TABLE `zt_user` ADD `limitedUser` varchar(8) NOT NULL default 'no' AFTER `role`;
|
||||
ALTER TABLE `zt_team` ADD `limitedUser` varchar(8) NOT NULL default 'no' AFTER `role`;
|
||||
@@ -68,6 +68,7 @@ CREATE TABLE IF NOT EXISTS `zt_bug` (
|
||||
`color` char(7) NOT NULL,
|
||||
`confirmed` tinyint(1) NOT NULL default '0',
|
||||
`activatedCount` smallint(6) NOT NULL,
|
||||
`activatedDate` datetime NOT NULL,
|
||||
`mailto` text,
|
||||
`openedBy` varchar(30) NOT NULL default '',
|
||||
`openedDate` datetime NOT NULL,
|
||||
|
||||
@@ -112,7 +112,7 @@ class baseHTML
|
||||
|
||||
if(empty($title)) $title = $href;
|
||||
$newline = $newline ? "\n" : '';
|
||||
|
||||
|
||||
return "<a href='$href' $misc>$title</a>$newline";
|
||||
}
|
||||
|
||||
|
||||
@@ -202,6 +202,11 @@ $config->bug->datatable->fieldList['activatedCount']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['activatedCount']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['activatedCount']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['activatedDate']['title'] = 'activatedDate';
|
||||
$config->bug->datatable->fieldList['activatedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['activatedDate']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['activatedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['openedBy']['title'] = 'openedByAB';
|
||||
$config->bug->datatable->fieldList['openedBy']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['openedBy']['width'] = '80';
|
||||
|
||||
@@ -264,6 +264,8 @@ class bug extends control
|
||||
$keywords = '';
|
||||
$severity = 3;
|
||||
$type = 'codeerror';
|
||||
$pri = '';
|
||||
$color = '';
|
||||
|
||||
/* Parse the extras. */
|
||||
$extras = str_replace(array(',', ' '), array('&', ''), $extras);
|
||||
@@ -273,7 +275,7 @@ class bug extends control
|
||||
if(!$runID and $caseID) extract($this->bug->getBugInfoFromResult($resultID, $caseID, $version));// If not set runID but set caseID, get the result info by resultID and case info.
|
||||
|
||||
/* If bugID setted, use this bug as template. */
|
||||
if(isset($bugID))
|
||||
if(isset($bugID))
|
||||
{
|
||||
$bug = $this->bug->getById($bugID);
|
||||
extract((array)$bug);
|
||||
@@ -286,6 +288,7 @@ class bug extends control
|
||||
$type = $bug->type;
|
||||
$assignedTo = $bug->assignedTo;
|
||||
$deadline = $bug->deadline;
|
||||
$color = $bug->color;
|
||||
}
|
||||
|
||||
/* If projectID is setted, get builds and stories of this project. */
|
||||
@@ -302,13 +305,13 @@ class bug extends control
|
||||
|
||||
/* Set team members of the latest project as assignedTo list. */
|
||||
$latestProject = $this->product->getLatestProject($productID);
|
||||
if(!empty($latestProject))
|
||||
if(!empty($latestProject))
|
||||
{
|
||||
$projectMembers = $this->loadModel('project')->getTeamMemberPairs($latestProject->id, 'nodeleted');
|
||||
}
|
||||
else
|
||||
{
|
||||
$projectMembers = $this->view->users;
|
||||
$projectMembers = $this->view->users;
|
||||
}
|
||||
|
||||
/* Set custom. */
|
||||
@@ -336,6 +339,7 @@ class bug extends control
|
||||
$this->view->version = $version;
|
||||
$this->view->testtask = $testtask;
|
||||
$this->view->bugTitle = $title;
|
||||
$this->view->pri = $pri;
|
||||
$this->view->steps = htmlspecialchars($steps);
|
||||
$this->view->os = $os;
|
||||
$this->view->browser = $browser;
|
||||
@@ -348,6 +352,7 @@ class bug extends control
|
||||
$this->view->type = $type;
|
||||
$this->view->branch = $branch;
|
||||
$this->view->branches = $branches;
|
||||
$this->view->color = $color;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -1443,7 +1448,7 @@ class bug extends control
|
||||
if(isset($bugLang->statusList[$bug->status])) $bug->status = $bugLang->statusList[$bug->status];
|
||||
if(isset($bugLang->confirmedList[$bug->confirmed])) $bug->confirmed = $bugLang->confirmedList[$bug->confirmed];
|
||||
if(isset($bugLang->resolutionList[$bug->resolution])) $bug->resolution = $bugLang->resolutionList[$bug->resolution];
|
||||
|
||||
|
||||
if(isset($users[$bug->openedBy])) $bug->openedBy = $users[$bug->openedBy];
|
||||
if(isset($users[$bug->assignedTo])) $bug->assignedTo = $users[$bug->assignedTo];
|
||||
if(isset($users[$bug->resolvedBy])) $bug->resolvedBy = $users[$bug->resolvedBy];
|
||||
|
||||
@@ -12,7 +12,7 @@ $(function()
|
||||
oldStoryID = $('#story').val() || 0;
|
||||
oldProjectID = 0;
|
||||
oldOpenedBuild = '';
|
||||
oldTaskID = 0;
|
||||
oldTaskID = $('#oldTaskID').val() || 0;
|
||||
if(!assignedto) setAssignedTo(moduleID, productID);
|
||||
notice();
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ $lang->bug->status = 'Status';
|
||||
$lang->bug->statusAB = 'Status';
|
||||
$lang->bug->activatedCount = 'Active';
|
||||
$lang->bug->activatedCountAB = 'Active';
|
||||
$lang->bug->activatedDate = 'Active On';
|
||||
$lang->bug->confirmed = 'Confirmed';
|
||||
$lang->bug->toTask = 'Convert to Task';
|
||||
$lang->bug->toStory = 'Convert to Story';
|
||||
|
||||
@@ -32,6 +32,7 @@ $lang->bug->status = 'Bug状态';
|
||||
$lang->bug->statusAB = '状态';
|
||||
$lang->bug->activatedCount = '激活次数';
|
||||
$lang->bug->activatedCountAB = '激活次数';
|
||||
$lang->bug->activatedDate = '激活日期';
|
||||
$lang->bug->confirmed = '是否确认';
|
||||
$lang->bug->toTask = '转任务';
|
||||
$lang->bug->toStory = '转需求';
|
||||
|
||||
@@ -32,6 +32,7 @@ $lang->bug->status = 'Bug狀態';
|
||||
$lang->bug->statusAB = '狀態';
|
||||
$lang->bug->activatedCount = '激活次數';
|
||||
$lang->bug->activatedCountAB = '激活次數';
|
||||
$lang->bug->activatedDate = '激活日期';
|
||||
$lang->bug->confirmed = '是否確認';
|
||||
$lang->bug->toTask = '轉任務';
|
||||
$lang->bug->toStory = '轉需求';
|
||||
|
||||
+12
-6
@@ -976,6 +976,7 @@ class bugModel extends model
|
||||
->add('toStory', 0)
|
||||
->add('lastEditedBy', $this->app->user->account)
|
||||
->add('lastEditedDate', $now)
|
||||
->add('activatedDate', $now)
|
||||
->join('openedBuild', ',')
|
||||
->remove('comment,files,labels')
|
||||
->get();
|
||||
@@ -2242,6 +2243,8 @@ class bugModel extends model
|
||||
{
|
||||
$action = strtolower($action);
|
||||
|
||||
if(!common::limitedUser($object)) return false;
|
||||
|
||||
if($action == 'confirmbug') return $object->status == 'active' and $object->confirmed == 0;
|
||||
if($action == 'resolve') return $object->status == 'active';
|
||||
if($action == 'close') return $object->status == 'resolved';
|
||||
@@ -2300,12 +2303,12 @@ class bugModel extends model
|
||||
|
||||
/**
|
||||
* Print cell data.
|
||||
*
|
||||
* @param object $col
|
||||
* @param object $bug
|
||||
* @param array $users
|
||||
* @param array $builds
|
||||
* @param array $branches
|
||||
*
|
||||
* @param object $col
|
||||
* @param object $bug
|
||||
* @param array $users
|
||||
* @param array $builds
|
||||
* @param array $branches
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -2357,6 +2360,9 @@ class bugModel extends model
|
||||
case 'activatedCount':
|
||||
echo $bug->activatedCount;
|
||||
break;
|
||||
case 'activatedDate':
|
||||
echo substr($bug->activatedDate, 5, 11);
|
||||
break;
|
||||
case 'openedBy':
|
||||
echo zget($users, $bug->openedBy);
|
||||
break;
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
<?php
|
||||
$params = "bugID=$bug->id";
|
||||
common::printIcon('bug', 'confirmBug', $params, $bug, 'list', 'search', '', 'iframe', true);
|
||||
common::printIcon('bug', 'assignTo', $params, '', 'list', '', '', 'iframe', true);
|
||||
common::printIcon('bug', 'assignTo', $params, $bug, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('bug', 'resolve', $params, $bug, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('bug', 'close', $params, $bug, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('bug', 'edit', $params, $bug, 'list');
|
||||
|
||||
@@ -149,7 +149,7 @@ js::set('confirmDeleteTemplate', $lang->bug->confirmDeleteTemplate);
|
||||
<div class='row-table'>
|
||||
<div class='col-table w-p100'>
|
||||
<div class='input-group w-p100'>
|
||||
<input type='hidden' id='color' name='color' data-provide='colorpicker' data-wrapper='input-group-btn' data-pull-menu-right='false' data-btn-tip='<?php echo $lang->bug->colorTag ?>' data-update-text='#title'>
|
||||
<input type='hidden' id='color' name='color' data-provide='colorpicker' data-wrapper='input-group-btn' data-pull-menu-right='false' data-btn-tip='<?php echo $lang->bug->colorTag ?>' data-update-text='#title' value='<?php echo $color;?>'>
|
||||
<?php echo html::input('title', $bugTitle, "class='form-control'");?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -198,14 +198,14 @@ js::set('confirmDeleteTemplate', $lang->bug->confirmDeleteTemplate);
|
||||
}
|
||||
?>
|
||||
<?php if($hasCustomPri):?>
|
||||
<?php echo html::select('pri', (array)$lang->bug->priList, '', "class='form-control minw-80px'");?>
|
||||
<?php echo html::select('pri', (array)$lang->bug->priList, $pri, "class='form-control minw-80px'");?>
|
||||
<?php else: ?>
|
||||
<div class='input-group-btn dropdown-pris'>
|
||||
<button type='button' class='btn dropdown-toggle br-0' data-toggle='dropdown'>
|
||||
<span class='pri-text'></span> <span class='caret'></span>
|
||||
</button>
|
||||
<ul class='dropdown-menu pull-right'></ul>
|
||||
<?php echo html::select('pri', $lang->bug->priList, '', "class='hide'");?>
|
||||
<?php echo html::select('pri', $lang->bug->priList, $pri, "class='hide'");?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
@@ -214,7 +214,7 @@ js::set('confirmDeleteTemplate', $lang->bug->confirmDeleteTemplate);
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->bug->steps;?></th>
|
||||
<td colspan='2'>
|
||||
@@ -250,7 +250,7 @@ js::set('confirmDeleteTemplate', $lang->bug->confirmDeleteTemplate);
|
||||
<?php if($showStory):?>
|
||||
<span class='input-group-addon'><?php echo $lang->bug->task?></span>
|
||||
<?php endif;?>
|
||||
<span id='taskIdBox'> <?php echo html::select('task', '', $taskID, "class='form-control chosen'");?></span>
|
||||
<span id='taskIdBox'> <?php echo html::select('task', '', $taskID, "class='form-control chosen'") . html::hidden('oldTaskID', $taskID);?></span>
|
||||
</div>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -31,20 +31,20 @@
|
||||
ob_start();
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('bug', 'confirmBug', $params, $bug, 'button', 'search', '', 'iframe', true);
|
||||
common::printIcon('bug', 'assignTo', $params, '', 'button', '', '', 'iframe', true);
|
||||
common::printIcon('bug', 'assignTo', $params, $bug, 'button', '', '', 'iframe', true);
|
||||
common::printIcon('bug', 'resolve', $params, $bug, 'button', '', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('bug', 'close', $params, $bug, 'button', '', '', 'text-danger iframe showinonlybody', true);
|
||||
common::printIcon('bug', 'activate', $params, $bug, 'button', '', '', 'text-success iframe showinonlybody', true);
|
||||
|
||||
if($this->config->global->flow != 'onlyTest') common::printIcon('bug', 'toStory', "product=$bug->product&branch=$bug->branch&module=0&story=0&project=0&bugID=$bug->id", $bug, 'button', $lang->icons['story']);
|
||||
common::printIcon('bug', 'createCase', $convertParams, '', 'button', 'sitemap');
|
||||
common::printIcon('bug', 'createCase', $convertParams, $bug, 'button', 'sitemap');
|
||||
echo '</div>';
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('bug', 'edit', $params);
|
||||
common::printCommentIcon('bug');
|
||||
common::printIcon('bug', 'create', $copyParams, '', 'button', 'copy');
|
||||
common::printIcon('bug', 'delete', $params, '', 'button', '', 'hiddenwin');
|
||||
common::printIcon('bug', 'edit', $params, $bug);
|
||||
common::printCommentIcon('bug', $bug);
|
||||
common::printIcon('bug', 'create', $copyParams, $bug, 'button', 'copy');
|
||||
common::printIcon('bug', 'delete', $params, $bug, 'button', '', 'hiddenwin');
|
||||
echo '</div>';
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
@@ -168,6 +168,10 @@
|
||||
<th><?php echo $lang->bug->activatedCount;?></th>
|
||||
<td><?php echo $bug->activatedCount;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->bug->activatedDate;?></th>
|
||||
<td><?php echo $bug->activatedDate;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->bug->confirmed;?></th>
|
||||
<td><?php echo $lang->bug->confirmedList[$bug->confirmed];?></td>
|
||||
|
||||
@@ -407,4 +407,19 @@ class buildModel extends model
|
||||
$this->loadModel('action')->create('bug', $unlinkBugID, 'unlinkedfrombuild', '', $buildID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge an action is clickable or not.
|
||||
*
|
||||
* @param object $project
|
||||
* @param string $action
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public static function isClickable($build, $action)
|
||||
{
|
||||
if(!common::limitedUser($build)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ tfoot tr td .table-actions .btn{display:none;}
|
||||
echo '</div>';
|
||||
}
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('build', 'edit', "buildID=$build->id");
|
||||
common::printIcon('build', 'delete', "buildID=$build->id", '', 'button', '', 'hiddenwin');
|
||||
common::printIcon('build', 'edit', "buildID=$build->id", $build);
|
||||
common::printIcon('build', 'delete', "buildID=$build->id", $build, 'button', '', 'hiddenwin');
|
||||
echo '</div>';
|
||||
}
|
||||
echo common::printRPN($browseLink);
|
||||
@@ -69,8 +69,8 @@ tfoot tr td .table-actions .btn{display:none;}
|
||||
$browseLink = $this->session->buildList ? $this->session->buildList : $this->createLink('product', 'build', "productID=$build->product");
|
||||
if(!$build->deleted)
|
||||
{
|
||||
common::printIcon('build', 'edit', "buildID=$build->id");
|
||||
common::printIcon('build', 'delete', "buildID=$build->id", '', 'button', '', 'hiddenwin');
|
||||
common::printIcon('build', 'edit', "buildID=$build->id", $build);
|
||||
common::printIcon('build', 'delete', "buildID=$build->id", $build, 'button', '', 'hiddenwin');
|
||||
}
|
||||
echo common::printRPN($browseLink);
|
||||
?>
|
||||
|
||||
+94
-45
@@ -13,7 +13,7 @@ class commonModel extends model
|
||||
{
|
||||
/**
|
||||
* The construc method, to do some auto things.
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -35,7 +35,7 @@ class commonModel extends model
|
||||
|
||||
/**
|
||||
* Set the header info.
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -54,7 +54,7 @@ class commonModel extends model
|
||||
* @return void
|
||||
*/
|
||||
public function setCompany()
|
||||
{
|
||||
{
|
||||
$httpHost = $this->server->http_host;
|
||||
|
||||
if($this->session->company)
|
||||
@@ -118,7 +118,7 @@ class commonModel extends model
|
||||
|
||||
/**
|
||||
* Load custom lang from db.
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -134,9 +134,9 @@ class commonModel extends model
|
||||
|
||||
/**
|
||||
* Juage a method of one module is open or not?
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
@@ -292,7 +292,7 @@ class commonModel extends model
|
||||
|
||||
/**
|
||||
* Create menu item link
|
||||
*
|
||||
*
|
||||
* @param object $menuItemLink
|
||||
* @param boolean $isTutorialMode
|
||||
* @access public
|
||||
@@ -319,8 +319,8 @@ class commonModel extends model
|
||||
|
||||
/**
|
||||
* Print the main menu.
|
||||
*
|
||||
* @param string $moduleName
|
||||
*
|
||||
* @param string $moduleName
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
@@ -352,7 +352,7 @@ class commonModel extends model
|
||||
|
||||
/**
|
||||
* Print the search box.
|
||||
*
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
@@ -377,7 +377,7 @@ class commonModel extends model
|
||||
$searchObject = $methodName;
|
||||
}
|
||||
if(empty($lang->searchObjects[$searchObject]))
|
||||
{
|
||||
{
|
||||
$searchObject = 'bug';
|
||||
if($config->global->flow == 'onlyStory') $searchObject = 'story';
|
||||
if($config->global->flow == 'onlyTask') $searchObject = 'task';
|
||||
@@ -598,9 +598,9 @@ class commonModel extends model
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public static function printLink($module, $method, $vars = '', $label, $target = '', $misc = '', $newline = true, $onlyBody = false)
|
||||
public static function printLink($module, $method, $vars = '', $label, $target = '', $misc = '', $newline = true, $onlyBody = false, $object = null)
|
||||
{
|
||||
if(!commonModel::hasPriv($module, $method)) return false;
|
||||
if(!commonModel::hasPriv($module, $method, $object)) return false;
|
||||
echo html::a(helper::createLink($module, $method, $vars, '', $onlyBody), $label, $target, $misc, $newline);
|
||||
return true;
|
||||
}
|
||||
@@ -625,29 +625,29 @@ class commonModel extends model
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function printCommentIcon($module)
|
||||
public static function printCommentIcon($module, $object = null)
|
||||
{
|
||||
if(isonlybody()) return false;
|
||||
|
||||
global $lang;
|
||||
|
||||
if(!commonModel::hasPriv($module, 'edit')) return false;
|
||||
if(!commonModel::hasPriv($module, 'edit', $object)) return false;
|
||||
echo html::a('#commentBox', '<i class="icon-comment-alt"></i>', '', "title='$lang->comment' onclick='setComment()' class='btn'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Build icon button.
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @param string $vars
|
||||
* @param object $object
|
||||
* @param string $type button|list
|
||||
* @param string $icon
|
||||
* @param string $target
|
||||
* @param string $extraClass
|
||||
* @param bool $onlyBody
|
||||
* @param string $misc
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @param string $vars
|
||||
* @param object $object
|
||||
* @param string $type button|list
|
||||
* @param string $icon
|
||||
* @param string $target
|
||||
* @param string $extraClass
|
||||
* @param bool $onlyBody
|
||||
* @param string $misc
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
@@ -736,17 +736,17 @@ class commonModel extends model
|
||||
|
||||
/**
|
||||
* Print link icon.
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @param string $vars
|
||||
* @param object $object
|
||||
* @param string $type button|list
|
||||
* @param string $icon
|
||||
* @param string $target
|
||||
* @param string $extraClass
|
||||
* @param bool $onlyBody
|
||||
* @param string $misc
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @param string $vars
|
||||
* @param object $object
|
||||
* @param string $type button|list
|
||||
* @param string $icon
|
||||
* @param string $target
|
||||
* @param string $extraClass
|
||||
* @param bool $onlyBody
|
||||
* @param string $misc
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
@@ -758,9 +758,9 @@ class commonModel extends model
|
||||
|
||||
/**
|
||||
* Print backLink and preLink and nextLink.
|
||||
*
|
||||
* @param string $backLink
|
||||
* @param object $preAndNext
|
||||
*
|
||||
* @param string $backLink
|
||||
* @param object $preAndNext
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -1118,14 +1118,14 @@ class commonModel extends model
|
||||
|
||||
/**
|
||||
* Check the user has permisson of one method of one module.
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @static
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasPriv($module, $method)
|
||||
public static function hasPriv($module, $method, $object = null)
|
||||
{
|
||||
global $app, $lang;
|
||||
|
||||
@@ -1140,6 +1140,8 @@ class commonModel extends model
|
||||
|
||||
if(isset($rights[$module][$method]))
|
||||
{
|
||||
if(!commonModel::limitedUser($object, $module, $method)) return false;
|
||||
|
||||
if(empty($acls['views'])) return true;
|
||||
$menu = isset($lang->menugroup->$module) ? $lang->menugroup->$module : $module;
|
||||
$menu = strtolower($menu);
|
||||
@@ -1148,8 +1150,55 @@ class commonModel extends model
|
||||
if($module == 'company' and $method == 'dynamic') return true;
|
||||
if($module == 'action' and $method == 'editcomment') return true;
|
||||
if(!isset($acls['views'][$menu])) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function limitedUser($object, $module = null, $method = null)
|
||||
{
|
||||
global $app;
|
||||
|
||||
if(!empty($app->user->admin) || $app->user->account == 'guest') return true;
|
||||
|
||||
// limited project
|
||||
$limitedProject = false;
|
||||
if(!empty($module) && $module == 'task' && !empty($object->project) ||
|
||||
!empty($module) && $module == 'task' && !empty($object->id))
|
||||
{
|
||||
$objectID = '';
|
||||
if(!empty($object->id)) $objectID = $object->id;
|
||||
if(!empty($object->id) && !empty($object->project)) $objectID = $object->project;
|
||||
|
||||
$sessionKey = $app->user->account . 'project' . $objectID;
|
||||
if(!empty($_SESSION[$sessionKey]) && $_SESSION[$sessionKey] == $objectID)
|
||||
{
|
||||
$limitedProject = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($app->user->limitedUser) && $app->user->limitedUser === 'no' && !$limitedProject) return true;
|
||||
|
||||
if(!is_null($method) && strpos($method, 'batch') === 0) return false;
|
||||
if(!is_null($method) && strpos($method, 'link') === 0) return false;
|
||||
if(!is_null($method) && strpos($method, 'create') === 0) return false;
|
||||
if(!is_null($method) && strpos($method, 'import') === 0) return false;
|
||||
|
||||
if(is_null($object)) return true;
|
||||
|
||||
if(!empty($object->openedBy) && $object->openedBy == $app->user->account ||
|
||||
!empty($object->addedBy) && $object->addedBy == $app->user->account ||
|
||||
!empty($object->assignedTo) && $object->assignedTo == $app->user->account ||
|
||||
!empty($object->finishedBy) && $object->finishedBy == $app->user->account ||
|
||||
!empty($object->canceledBy) && $object->canceledBy == $app->user->account ||
|
||||
!empty($object->closedBy) && $object->closedBy == $app->user->account ||
|
||||
!empty($object->lastEditedBy) && $object->lastEditedBy == $app->user->account)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,9 @@ class custom extends control
|
||||
{
|
||||
$this->app->loadConfig($module);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
|
||||
$this->view->needReview = zget($this->config->$module, 'needReview', 1);
|
||||
$this->view->forceReview = zget($this->config->$module, 'forceReview', '');
|
||||
$this->view->needReview = zget($this->config->$module, 'needReview', 1);
|
||||
$this->view->forceReview = zget($this->config->$module, 'forceReview', '');
|
||||
$this->view->forceNotReview = zget($this->config->$module, 'forceNotReview', '');
|
||||
}
|
||||
if($module == 'task' and $field == 'hours')
|
||||
{
|
||||
@@ -82,7 +83,9 @@ class custom extends control
|
||||
{
|
||||
if(($module == 'story' or $module == 'testcase') and $field == 'review')
|
||||
{
|
||||
$data = fixer::input('post')->join('forceReview', ',')->get();
|
||||
$review = fixer::input('post')->get();
|
||||
if($review->needReview) $data = fixer::input('post')->join('forceNotReview', ',')->remove('forceReview')->get();
|
||||
if(!$review->needReview) $data = fixer::input('post')->join('forceReview', ',')->remove('forceNotReview')->get();
|
||||
$this->loadModel('setting')->setItems("system.$module", $data);
|
||||
}
|
||||
elseif($module == 'task' and $field == 'hours')
|
||||
@@ -117,7 +120,7 @@ class custom extends control
|
||||
/* Fix bug #942. */
|
||||
if($field == 'priList' and !is_numeric($key)) die(js::alert($this->lang->custom->notice->priListKey));
|
||||
if($module == 'bug' and $field == 'severityList' and !is_numeric($key)) die(js::alert($this->lang->custom->notice->severityListKey));
|
||||
if(!empty($key) and !validater::checkCode($key)) die(js::alert($this->lang->custom->notice->keyList));
|
||||
if(!empty($key) and $key != 'n/a' and !validater::checkCode($key)) die(js::alert($this->lang->custom->notice->keyList));
|
||||
|
||||
/* the length of role is 20, check it when save. */
|
||||
if($module == 'user' and $field == 'roleList' and strlen($key) > 20) die(js::alert($this->lang->custom->notice->userRole));
|
||||
|
||||
@@ -82,6 +82,7 @@ $lang->custom->notice = new stdclass();
|
||||
$lang->custom->notice->userRole = 'Key must be no more than 20 characters!';
|
||||
$lang->custom->notice->canNotAdd = 'This item will be processed, so customized feature is not enabled.';
|
||||
$lang->custom->notice->forceReview = 'Review is required for %s submitted by certain assignee.';
|
||||
$lang->custom->notice->forceNotReview = "Not review is required for %s submitted by certain assignee.";
|
||||
$lang->custom->notice->longlife = 'List "Undone" bugs that are older than hold days from "Longlife" bugs.';
|
||||
$lang->custom->notice->priListKey = 'Priority list key should be numbers!';
|
||||
$lang->custom->notice->keyList = 'key should be English or digital!';
|
||||
|
||||
@@ -82,6 +82,7 @@ $lang->custom->notice = new stdclass();
|
||||
$lang->custom->notice->userRole = '键的长度必须小于20个字符!';
|
||||
$lang->custom->notice->canNotAdd = '该项参与运算,不提供自定义添加功能';
|
||||
$lang->custom->notice->forceReview = "指定人提交的%s必须评审。";
|
||||
$lang->custom->notice->forceNotReview = "指定人提交的%s不需要评审。";
|
||||
$lang->custom->notice->longlife = 'Bug列表页面的久未处理标签中,列出设置天数之前未处理的Bug。';
|
||||
$lang->custom->notice->priListKey = '优先级的键应当为数字!';
|
||||
$lang->custom->notice->keyList = '键值应当为英文或数字';
|
||||
@@ -90,10 +91,11 @@ $lang->custom->notice->indexPage['product'] = "从8.2版本起增加了产品主
|
||||
$lang->custom->notice->indexPage['project'] = "从8.2版本起增加了项目主页视图,是否默认进入项目主页?";
|
||||
$lang->custom->notice->indexPage['qa'] = "从8.2版本起增加了测试主页视图,是否默认进入测试主页?";
|
||||
|
||||
$lang->custom->storyReview = '评审流程';
|
||||
$lang->custom->forceReview = '强制评审';
|
||||
$lang->custom->reviewList[1] = '开启';
|
||||
$lang->custom->reviewList[0] = '关闭';
|
||||
$lang->custom->storyReview = '评审流程';
|
||||
$lang->custom->forceReview = '强制评审';
|
||||
$lang->custom->forceNotReview = '不需要评审';
|
||||
$lang->custom->reviewList[1] = '开启';
|
||||
$lang->custom->reviewList[0] = '关闭';
|
||||
|
||||
$lang->custom->deletedList[1] = '列出';
|
||||
$lang->custom->deletedList[0] = '不列出';
|
||||
|
||||
@@ -82,6 +82,7 @@ $lang->custom->notice->userRole = '鍵的長度必須小於20個字
|
||||
$lang->custom->notice->canNotAdd = '該項參與運算,不提供自定義添加功能';
|
||||
$lang->custom->notice->forceReview = "指定人提交的%s必須評審。";
|
||||
$lang->custom->notice->longlife = 'Bug列表頁面的久未處理標籤中,列出設置天數之前未處理的Bug。';
|
||||
$lang->custom->notice->forceNotReview = "指定人提交的%s不需要評審。";
|
||||
$lang->custom->notice->priListKey = '優先順序的鍵應當為數字!';
|
||||
$lang->custom->notice->keyList = '鍵值應當為英文或數字';
|
||||
$lang->custom->notice->severityListKey = 'Bug嚴重程度的鍵應當為數字!';
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php
|
||||
<?php
|
||||
$itemRow = <<<EOT
|
||||
<tr class='text-center'>
|
||||
<td>
|
||||
@@ -76,6 +76,13 @@ EOT;
|
||||
<td><?php echo html::select('forceReview[]', $users, $forceReview, "class='form-control chosen' multiple");?></td>
|
||||
<td class='w-180px'><?php printf($lang->custom->notice->forceReview, $lang->$module->common);?></td>
|
||||
</tr>
|
||||
<?php if($module == 'testcase'):?>
|
||||
<tr <?php if(!$needReview) echo "class='hidden'"?>>
|
||||
<th><?php echo $lang->custom->forceNotReview;?></th>
|
||||
<td><?php echo html::select('forceNotReview[]', $users, $forceNotReview, "class='form-control chosen' multiple");?></td>
|
||||
<td class='w-180px'><?php printf($lang->custom->notice->forceNotReview, $lang->$module->common);?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><?php echo html::submitButton();?></td>
|
||||
@@ -182,10 +189,12 @@ $(function()
|
||||
if($(this).val() == 0)
|
||||
{
|
||||
$('#forceReview').closest('tr').removeClass('hidden');
|
||||
$('#forceNotReview').closest('tr').addClass('hidden');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#forceReview').closest('tr').addClass('hidden');
|
||||
$('#forceNotReview').closest('tr').removeClass('hidden');
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -40,8 +40,8 @@ class datatableModel extends model
|
||||
|
||||
/**
|
||||
* Get save setting field.
|
||||
*
|
||||
* @param string $module
|
||||
*
|
||||
* @param string $module
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
|
||||
@@ -13,7 +13,7 @@ class doc extends control
|
||||
{
|
||||
/**
|
||||
* Construct function, load user, tree, action auto.
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -223,7 +223,7 @@ class doc extends control
|
||||
}
|
||||
die(js::locate($this->createLink($this->moduleName, 'browse', "libID=$libID"), 'parent.parent'));
|
||||
}
|
||||
|
||||
|
||||
$lib = $this->doc->getLibByID($libID);
|
||||
if(!empty($lib->product)) $this->view->product = $this->dao->select('id,name')->from(TABLE_PRODUCT)->where('id')->eq($lib->product)->fetch();
|
||||
if(!empty($lib->project)) $this->view->project = $this->dao->select('id,name')->from(TABLE_PROJECT)->where('id')->eq($lib->project)->fetch();
|
||||
@@ -259,7 +259,7 @@ class doc extends control
|
||||
die(js::locate($this->createLink('doc', 'browse'), 'parent'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a doc.
|
||||
*
|
||||
@@ -382,8 +382,8 @@ class doc extends control
|
||||
|
||||
/**
|
||||
* View a doc.
|
||||
*
|
||||
* @param int $docID
|
||||
*
|
||||
* @param int $docID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
|
||||
@@ -1158,4 +1158,19 @@ class docModel extends model
|
||||
|
||||
return $teams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge an action is clickable or not.
|
||||
*-
|
||||
* @param object $product-
|
||||
* @param string $action-
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function isClickable($doc, $action)
|
||||
{
|
||||
if(!common::limitedUser($doc)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,8 +93,8 @@ var browseType = '<?php echo $browseType;?>';
|
||||
<td><?php echo substr($doc->editedDate, 5, 11);?></td>
|
||||
<td>
|
||||
<?php
|
||||
common::printIcon('doc', 'edit', "doc={$doc->id}", '', 'list');
|
||||
if(common::hasPriv('doc', 'delete'))
|
||||
common::printIcon('doc', 'edit', "doc={$doc->id}", $doc, 'list');
|
||||
if(common::hasPriv('doc', 'delete', $doc))
|
||||
{
|
||||
$deleteURL = $this->createLink('doc', 'delete', "docID=$doc->id&confirm=yes");
|
||||
echo html::a("javascript:ajaxDelete(\"$deleteURL\",\"docList\",confirmDelete)", '<i class="icon-remove"></i>', '', "class='btn-icon' title='{$lang->doc->delete}'");
|
||||
|
||||
@@ -76,8 +76,8 @@
|
||||
<td><?php echo isset($file->addedDate) ? substr($file->addedDate, 0, 10) : '';?></td>
|
||||
<td class='text-center'>
|
||||
<?php
|
||||
common::printLink('file', 'download', "fileID=$file->id", $lang->doc->download, "data-toggle='modal'");
|
||||
common::printLink('file', 'delete', "fileID=$file->id", $lang->delete, 'hiddenwin');
|
||||
common::printLink('file', 'download', "fileID=$file->id", $lang->doc->download, "data-toggle='modal'", '', true, false, $file);
|
||||
common::printLink('file', 'delete', "fileID=$file->id", $lang->delete, 'hiddenwin', '', true, false, $file);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -68,9 +68,9 @@
|
||||
{
|
||||
ob_start();
|
||||
echo "<div class='btn-group'>";
|
||||
common::printCommentIcon('doc');
|
||||
common::printIcon('doc', 'edit', $params);
|
||||
common::printIcon('doc', 'delete', $params, '', 'button', '', 'hiddenwin');
|
||||
common::printCommentIcon('doc', $doc);
|
||||
common::printIcon('doc', 'edit', $params, $doc);
|
||||
common::printIcon('doc', 'delete', $params, $doc, 'button', '', 'hiddenwin');
|
||||
echo '</div>';
|
||||
echo "<div class='btn-group'>";
|
||||
common::printRPN($browseLink, $preAndNext);
|
||||
|
||||
@@ -55,6 +55,9 @@ $lang->extension->publicList[1] = 'Auto';
|
||||
$lang->extension->compatibleList[0] = 'Unknown';
|
||||
$lang->extension->compatibleList[1] = 'Compatible';
|
||||
|
||||
$lang->extension->obtainOfficial[0] = 'Third party';
|
||||
$lang->extension->obtainOfficial[1] = 'Official';
|
||||
|
||||
$lang->extension->byDownloads = 'Downloads';
|
||||
$lang->extension->byAddedTime = 'Latest Added';
|
||||
$lang->extension->byUpdatedTime = 'Latest Update';
|
||||
|
||||
@@ -55,6 +55,9 @@ $lang->extension->publicList[1] = '直接下载';
|
||||
$lang->extension->compatibleList[0] = '未知';
|
||||
$lang->extension->compatibleList[1] = '兼容';
|
||||
|
||||
$lang->extension->obtainOfficial[0] = '第三方';
|
||||
$lang->extension->obtainOfficial[1] = '官方';
|
||||
|
||||
$lang->extension->byDownloads = '最多下载';
|
||||
$lang->extension->byAddedTime = '最新添加';
|
||||
$lang->extension->byUpdatedTime = '最近更新';
|
||||
|
||||
@@ -55,6 +55,9 @@ $lang->extension->publicList[1] = '直接下載';
|
||||
$lang->extension->compatibleList[0] = '未知';
|
||||
$lang->extension->compatibleList[1] = '兼容';
|
||||
|
||||
$lang->extension->obtainOfficial[0] = '第三方';
|
||||
$lang->extension->obtainOfficial[1] = '官方';
|
||||
|
||||
$lang->extension->byDownloads = '最多下載';
|
||||
$lang->extension->byAddedTime = '最新添加';
|
||||
$lang->extension->byUpdatedTime = '最近更新';
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<?php if($extensions):?>
|
||||
<div class='cards pd-0 mg-0'>
|
||||
<?php foreach($extensions as $extension):?>
|
||||
<?php
|
||||
<?php
|
||||
$currentRelease = $extension->currentRelease;
|
||||
$latestRelease = isset($extension->latestRelease) ? $extension->latestRelease : '';
|
||||
?>
|
||||
@@ -51,7 +51,10 @@
|
||||
printf($lang->extension->latest, $latestRelease->viewLink, $latestRelease->releaseVersion, $latestRelease->zentaoCompatible);
|
||||
}?>
|
||||
</small>
|
||||
<h5 class='mg-0'><?php echo $extension->name . "($currentRelease->releaseVersion)";?></h5>
|
||||
<h5 class='mg-0'>
|
||||
<?php echo $extension->name . "($currentRelease->releaseVersion)";?>
|
||||
<small class='label <?php echo $extension->offcial ? 'label-info' : 'label-warning';?>'><?php echo $lang->extension->obtainOfficial[$extension->offcial];?></small>
|
||||
</h5>
|
||||
</div>
|
||||
<div class='card-content text-muted'>
|
||||
<?php echo $extension->abstract;?>
|
||||
@@ -62,7 +65,7 @@
|
||||
echo "{$lang->extension->author}: {$extension->author} ";
|
||||
echo "{$lang->extension->downloads}: {$extension->downloads} ";
|
||||
echo "{$lang->extension->compatible}: {$lang->extension->compatibleList[$currentRelease->compatible]} ";
|
||||
|
||||
|
||||
echo " {$lang->extension->depends}: ";
|
||||
if(!empty($currentRelease->depends))
|
||||
{
|
||||
|
||||
@@ -70,6 +70,13 @@ class install extends control
|
||||
$this->view->pdoResult = $this->install->checkPDO();
|
||||
$this->view->pdoMySQLResult = $this->install->checkPDOMySQL();
|
||||
$this->view->jsonResult = $this->install->checkJSON();
|
||||
$this->view->opensslResult = $this->install->checkOpenssl();
|
||||
$this->view->mbstringResult = $this->install->checkMbstring();
|
||||
$this->view->zlibResult = $this->install->checkZlib();
|
||||
$this->view->curlResult = $this->install->checkCurl();
|
||||
$this->view->filterResult = $this->install->checkFilter();
|
||||
$this->view->gdResult = $this->install->checkGD();
|
||||
$this->view->iconvResult = $this->install->checkIconv();
|
||||
$this->view->tmpRootInfo = $this->install->getTmpRoot();
|
||||
$this->view->tmpRootResult = $this->install->checkTmpRoot();
|
||||
$this->view->dataRootInfo = $this->install->getDataRoot();
|
||||
|
||||
@@ -62,6 +62,20 @@ $lang->install->pdoMySQL = 'PDO_MySQL';
|
||||
$lang->install->pdoMySQLFail = 'Edit PHP ini file to load PDO_MySQL extsion.';
|
||||
$lang->install->json = 'JSON Extension';
|
||||
$lang->install->jsonFail = 'Edit the php.ini file to load JSON extension.';
|
||||
$lang->install->openssl = 'OPENSSL Extension';
|
||||
$lang->install->opensslFail = 'Edit the php.ini file to load openssl extension.';
|
||||
$lang->install->mbstring = 'MBSTRING Extension';
|
||||
$lang->install->mbstringFail = 'Edit the php.ini file to load mbstring extension.';
|
||||
$lang->install->zlib = 'ZLIB Extension';
|
||||
$lang->install->zlibFail = 'Edit the php.ini file to load zlib extension.';
|
||||
$lang->install->curl = 'CURL Extension';
|
||||
$lang->install->curlFail = 'Edit the php.ini file to load curl extension.';
|
||||
$lang->install->filter = 'FILTER Extension';
|
||||
$lang->install->filterFail = 'Edit the php.ini file to load filter extension.';
|
||||
$lang->install->gd = 'GD Extension';
|
||||
$lang->install->gdFail = 'Edit the php.ini file to load gd extension.';
|
||||
$lang->install->iconv = 'ICONV Extension';
|
||||
$lang->install->iconvFail = 'Edit the php.ini file to load iconv extension.';
|
||||
$lang->install->tmpRoot = 'Temp File Directory';
|
||||
$lang->install->dataRoot = 'Uploaded File Directory';
|
||||
$lang->install->session = 'Session Save Path';
|
||||
|
||||
@@ -62,6 +62,20 @@ $lang->install->pdoMySQL = 'PDO_MySQL扩展';
|
||||
$lang->install->pdoMySQLFail = '修改PHP配置文件,加载pdo_mysql扩展。';
|
||||
$lang->install->json = 'JSON扩展';
|
||||
$lang->install->jsonFail = '修改PHP配置文件,加载JSON扩展。';
|
||||
$lang->install->openssl = 'OPENSSL扩展';
|
||||
$lang->install->opensslFail = '修改PHP配置文件,加载OPENSSL扩展。';
|
||||
$lang->install->mbstring = 'MBSTRING扩展';
|
||||
$lang->install->mbstringFail = '修改PHP配置文件,加载MBSTRING扩展。';
|
||||
$lang->install->zlib = 'ZLIB扩展';
|
||||
$lang->install->zlibFail = '修改PHP配置文件,加载ZLIB扩展。';
|
||||
$lang->install->curl = 'CURL扩展';
|
||||
$lang->install->curlFail = '修改PHP配置文件,加载CURL扩展。';
|
||||
$lang->install->filter = 'FILTER扩展';
|
||||
$lang->install->filterFail = '修改PHP配置文件,加载FILTER扩展。';
|
||||
$lang->install->gd = 'GD扩展';
|
||||
$lang->install->gdFail = '修改PHP配置文件,加载GD扩展。';
|
||||
$lang->install->iconv = 'ICONV扩展';
|
||||
$lang->install->iconvFail = '修改PHP配置文件,加载ICONV扩展。';
|
||||
$lang->install->tmpRoot = '临时文件目录';
|
||||
$lang->install->dataRoot = '上传文件目录';
|
||||
$lang->install->session = 'Session存储目录';
|
||||
|
||||
@@ -62,6 +62,20 @@ $lang->install->pdoMySQL = 'PDO_MySQL擴展';
|
||||
$lang->install->pdoMySQLFail = '修改PHP配置檔案,加載pdo_mysql擴展。';
|
||||
$lang->install->json = 'JSON擴展';
|
||||
$lang->install->jsonFail = '修改PHP配置檔案,加載JSON擴展。';
|
||||
$lang->install->openssl = 'OPENSSL擴展';
|
||||
$lang->install->opensslFail = '修改PHP配置檔案,加載OPENSSL擴展。';
|
||||
$lang->install->mbstring = 'MBSTRING擴展';
|
||||
$lang->install->mbstringFail = '修改PHP配置檔案,加載MBSTRING擴展。';
|
||||
$lang->install->zlib = 'ZLIB擴展';
|
||||
$lang->install->zlibFail = '修改PHP配置檔案,加載ZLIB擴展。';
|
||||
$lang->install->curl = 'CURL擴展';
|
||||
$lang->install->curlFail = '修改PHP配置檔案,加載CURL擴展。';
|
||||
$lang->install->filter = 'FILTER擴展';
|
||||
$lang->install->filterFail = '修改PHP配置檔案,加載FILTER擴展。';
|
||||
$lang->install->gd = 'GD擴展';
|
||||
$lang->install->gdFail = '修改PHP配置檔案,加載GD擴展。';
|
||||
$lang->install->iconv = 'ICONV擴展';
|
||||
$lang->install->iconvFail = '修改PHP配置檔案,加載ICONV擴展。';
|
||||
$lang->install->tmpRoot = '臨時檔案目錄';
|
||||
$lang->install->dataRoot = '上傳檔案目錄';
|
||||
$lang->install->session = 'Session存儲目錄';
|
||||
|
||||
@@ -90,7 +90,7 @@ class installModel extends model
|
||||
|
||||
/**
|
||||
* Check json extension.
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @return string ok|fail
|
||||
*/
|
||||
@@ -99,6 +99,83 @@ class installModel extends model
|
||||
return $result = extension_loaded('json') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check openssl extension.
|
||||
*
|
||||
* @access public
|
||||
* @return string ok|fail
|
||||
*/
|
||||
public function checkOpenssl()
|
||||
{
|
||||
return $result = extension_loaded('openssl') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check mbstring extension.
|
||||
*
|
||||
* @access public
|
||||
* @return string ok|fail
|
||||
*/
|
||||
public function checkMbstring()
|
||||
{
|
||||
return $result = extension_loaded('mbstring') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check zlib extension.
|
||||
*
|
||||
* @access public
|
||||
* @return string ok|fail
|
||||
*/
|
||||
public function checkZlib()
|
||||
{
|
||||
return $result = extension_loaded('zlib') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check curl extension.
|
||||
*
|
||||
* @access public
|
||||
* @return string ok|fail
|
||||
*/
|
||||
public function checkCurl()
|
||||
{
|
||||
return $result = extension_loaded('curl') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check filter extension.
|
||||
*
|
||||
* @access public
|
||||
* @return string ok|fail
|
||||
*/
|
||||
public function checkFilter()
|
||||
{
|
||||
return $result = extension_loaded('filter') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check gd extension.
|
||||
*
|
||||
* @access public
|
||||
* @return string ok|fail
|
||||
*/
|
||||
public function checkGD()
|
||||
{
|
||||
return $result = extension_loaded('gd') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check iconv extension.
|
||||
*
|
||||
* @access public
|
||||
* @return string ok|fail
|
||||
*/
|
||||
public function checkIconv()
|
||||
{
|
||||
return $result = extension_loaded('iconv') ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tempRoot info.
|
||||
*
|
||||
|
||||
@@ -47,6 +47,48 @@
|
||||
<td class='<?php echo $jsonResult;?>'><?php echo $lang->install->$jsonResult;?></td>
|
||||
<td class='text-left f-12px'><?php if($jsonResult == 'fail') echo $lang->install->jsonFail;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->install->openssl;?></th>
|
||||
<td><?php $opensslResult == 'ok' ? printf($lang->install->loaded) : printf($lang->install->unloaded);?></td>
|
||||
<td class='<?php echo $opensslResult;?>'><?php echo $lang->install->$opensslResult;?></td>
|
||||
<td class='text-left f-12px'><?php if($opensslResult == 'fail') echo $lang->install->opensslFail;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->install->mbstring;?></th>
|
||||
<td><?php $mbstringResult == 'ok' ? printf($lang->install->loaded) : printf($lang->install->unloaded);?></td>
|
||||
<td class='<?php echo $mbstringResult;?>'><?php echo $lang->install->$mbstringResult;?></td>
|
||||
<td class='text-left f-12px'><?php if($mbstringResult == 'fail') echo $lang->install->mbstringFail;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->install->zlib;?></th>
|
||||
<td><?php $zlibResult == 'ok' ? printf($lang->install->loaded) : printf($lang->install->unloaded);?></td>
|
||||
<td class='<?php echo $zlibResult;?>'><?php echo $lang->install->$zlibResult;?></td>
|
||||
<td class='text-left f-12px'><?php if($zlibResult == 'fail') echo $lang->install->zlibFail;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->install->curl;?></th>
|
||||
<td><?php $curlResult == 'ok' ? printf($lang->install->loaded) : printf($lang->install->unloaded);?></td>
|
||||
<td class='<?php echo $curlResult;?>'><?php echo $lang->install->$curlResult;?></td>
|
||||
<td class='text-left f-12px'><?php if($curlResult == 'fail') echo $lang->install->curlFail;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->install->filter;?></th>
|
||||
<td><?php $filterResult == 'ok' ? printf($lang->install->loaded) : printf($lang->install->unloaded);?></td>
|
||||
<td class='<?php echo $filterResult;?>'><?php echo $lang->install->$filterResult;?></td>
|
||||
<td class='text-left f-12px'><?php if($filterResult == 'fail') echo $lang->install->filterFail;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->install->gd;?></th>
|
||||
<td><?php $gdResult == 'ok' ? printf($lang->install->loaded) : printf($lang->install->unloaded);?></td>
|
||||
<td class='<?php echo $gdResult;?>'><?php echo $lang->install->$gdResult;?></td>
|
||||
<td class='text-left f-12px'><?php if($gdResult == 'fail') echo $lang->install->gdFail;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->install->iconv;?></th>
|
||||
<td><?php $iconvResult == 'ok' ? printf($lang->install->loaded) : printf($lang->install->unloaded);?></td>
|
||||
<td class='<?php echo $iconvResult;?>'><?php echo $lang->install->$iconvResult;?></td>
|
||||
<td class='text-left f-12px'><?php if($iconvResult == 'fail') echo $lang->install->iconvFail;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->install->tmpRoot;?></th>
|
||||
<td>
|
||||
@@ -110,7 +152,20 @@
|
||||
</div>
|
||||
<div class='modal-footer'>
|
||||
<?php
|
||||
if($phpResult == 'ok' and $pdoResult == 'ok' and $pdoMySQLResult == 'ok' and $tmpRootResult == 'ok' and $dataRootResult == 'ok' and $sessionResult == 'ok')
|
||||
if($phpResult == 'ok' and
|
||||
$pdoResult == 'ok' and
|
||||
$pdoMySQLResult == 'ok' and
|
||||
$tmpRootResult == 'ok' and
|
||||
$dataRootResult == 'ok' and
|
||||
$sessionResult == 'ok' and
|
||||
$jsonResult == 'ok' and
|
||||
$opensslResult == 'ok' and
|
||||
$mbstringResult == 'ok' and
|
||||
$zlibResult == 'ok' and
|
||||
$curlResult == 'ok' and
|
||||
$filterResult == 'ok' and
|
||||
$gdResult == 'ok' and
|
||||
$iconvResult == 'ok')
|
||||
{
|
||||
echo html::a($this->createLink('install', 'step2'), $lang->install->next, '', "class='btn btn-primary'");
|
||||
}
|
||||
@@ -122,7 +177,7 @@
|
||||
echo '<div class="panel panel-sm text-left"><div class="panel-heading strong">' . $lang->install->phpINI . '</div><div class="panel-body">' . nl2br($this->install->getIniInfo()) . '</div></div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
<th><?php echo $lang->group->priv;?></th>
|
||||
<td><?php foreach($groups as $group) echo $group->name . ' '; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->user->limitedUser;?></th>
|
||||
<td><?php echo $lang->user->limitedUserList[$user->limitedUser];?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->user->commiter;?></th>
|
||||
<td><?php echo $user->commiter;?></td>
|
||||
|
||||
@@ -23,8 +23,9 @@ $config->product->search['fields']['module'] = $lang->story->module;
|
||||
$config->product->search['fields']['plan'] = $lang->story->plan;
|
||||
$config->product->search['fields']['estimate'] = $lang->story->estimate;
|
||||
|
||||
$config->product->search['fields']['source'] = $lang->story->source;
|
||||
$config->product->search['fields']['fromBug'] = $lang->story->fromBug;
|
||||
$config->product->search['fields']['source'] = $lang->story->source;
|
||||
$config->product->search['fields']['sourceNote'] = $lang->story->sourceNote;
|
||||
$config->product->search['fields']['fromBug'] = $lang->story->fromBug;
|
||||
|
||||
$config->product->search['fields']['openedBy'] = $lang->story->openedBy;
|
||||
$config->product->search['fields']['reviewedBy'] = $lang->story->reviewedBy;
|
||||
@@ -56,6 +57,7 @@ $config->product->search['params']['plan'] = array('operator' => '=',
|
||||
$config->product->search['params']['estimate'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
|
||||
$config->product->search['params']['source'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->story->sourceList);
|
||||
$config->product->search['params']['sourceNote'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->product->search['params']['fromBug'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
|
||||
$config->product->search['params']['openedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
|
||||
@@ -627,13 +627,13 @@ class product extends control
|
||||
|
||||
/**
|
||||
* All product.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param string $status
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
*
|
||||
* @param int $productID
|
||||
* @param string $status
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -662,8 +662,8 @@ class product extends control
|
||||
|
||||
/**
|
||||
* Doc for compatible.
|
||||
*
|
||||
* @param int $productID
|
||||
*
|
||||
* @param int $productID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
|
||||
@@ -241,9 +241,9 @@ class productModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get products by project.
|
||||
*
|
||||
* @param int $projectID
|
||||
* Get products by project.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
@@ -256,6 +256,7 @@ class productModel extends model
|
||||
->leftJoin(TABLE_PRODUCT)->alias('t2')
|
||||
->on('t1.product = t2.id')
|
||||
->where('t1.project')->eq($projectID)
|
||||
->orderBy('t2.order desc')
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
@@ -654,11 +655,11 @@ class productModel extends model
|
||||
|
||||
/**
|
||||
* Get product stats.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param int $pager
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param int $pager
|
||||
* @access public
|
||||
* @return array
|
||||
* @return array
|
||||
*/
|
||||
public function getStats($orderBy = 'order_desc', $pager = null, $status = 'noclosed')
|
||||
{
|
||||
@@ -829,6 +830,8 @@ class productModel extends model
|
||||
{
|
||||
$action = strtolower($action);
|
||||
|
||||
if(!common::limitedUser($product)) return false;
|
||||
|
||||
if($action == 'close') return $product->status != 'closed';
|
||||
|
||||
return true;
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
?>
|
||||
</td>
|
||||
<td class='text-right'>
|
||||
<?php
|
||||
<?php
|
||||
$vars = "story={$story->id}";
|
||||
common::printIcon('story', 'change', $vars, $story, 'list', 'random');
|
||||
common::printIcon('story', 'review', $vars, $story, 'list', 'review');
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
common::printIcon('product', 'close', "productID=$product->id", $product, 'button', '', '', 'iframe text-danger', true);
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('product', 'edit', $params);
|
||||
common::printIcon('product', 'delete', $params, '', 'button', '', 'hiddenwin');
|
||||
common::printIcon('product', 'edit', $params, $product);
|
||||
common::printIcon('product', 'delete', $params, $product, 'button', '', 'hiddenwin');
|
||||
echo '</div>';
|
||||
common::printRPN($browseLink);
|
||||
|
||||
@@ -64,31 +64,31 @@
|
||||
<tr>
|
||||
<th class='strong w-80px'><?php echo $lang->product->name;?></th>
|
||||
<td <?php if($product->deleted) echo "class='deleted text-danger'";?>><strong><?php echo $product->name;?></strong></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->code;?></th>
|
||||
<td><?php echo $product->code;?></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->PO;?></th>
|
||||
<td><?php echo zget($users, $product->PO);?></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->QD;?></th>
|
||||
<td><?php echo zget($users, $product->QD);?></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->RD;?></th>
|
||||
<td><?php echo zget($users, $product->RD);?></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->type;?></th>
|
||||
<td><?php echo $lang->product->typeList[$product->type];?></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->status;?></th>
|
||||
<td class='product-<?php echo $product->status?>'><?php echo $lang->product->statusList[$product->status];?></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->openedBy?></th>
|
||||
<td><?php echo zget($users, $product->createdBy);?></td>
|
||||
|
||||
@@ -203,10 +203,10 @@ class productplan extends control
|
||||
|
||||
/**
|
||||
* View plan.
|
||||
*
|
||||
* @param int $planID
|
||||
* @param string $type
|
||||
* @param string $orderBy
|
||||
*
|
||||
* @param int $planID
|
||||
* @param string $type
|
||||
* @param string $orderBy
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -264,8 +264,8 @@ class productplan extends control
|
||||
|
||||
/**
|
||||
* Link stories.
|
||||
*
|
||||
* @param int $planID
|
||||
*
|
||||
* @param int $planID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
|
||||
@@ -292,9 +292,9 @@ class productplanModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink bug.
|
||||
*
|
||||
* @param int $bugID
|
||||
* Unlink bug.
|
||||
*
|
||||
* @param int $bugID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -304,4 +304,19 @@ class productplanModel extends model
|
||||
$this->dao->update(TABLE_BUG)->set('plan')->eq(0)->where('id')->eq((int)$bugID)->exec();
|
||||
$this->loadModel('action')->create('bug', $bugID, 'unlinkedfromplan', '', $planID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge an action is clickable or not.
|
||||
*-
|
||||
* @param object $product-
|
||||
* @param string $action-
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function isClickable($productPlan, $action)
|
||||
{
|
||||
if(!common::limitedUser($productPlan)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@
|
||||
<?php
|
||||
if(common::hasPriv('productplan', 'linkStory')) echo html::a(inlink('view', "planID=$plan->id&type=story&orderBy=id_desc&link=true"), '<i class="icon-link"></i>', '', "class='btn-icon' title='{$lang->productplan->linkStory}'");
|
||||
if(common::hasPriv('productplan', 'linkBug') and $config->global->flow != 'onlyStory') echo html::a(inlink('view', "planID=$plan->id&type=bug&orderBy=id_desc&link=true"), '<i class="icon-bug"></i>', '', "class='btn-icon' title='{$lang->productplan->linkBug}'");
|
||||
common::printIcon('productplan', 'edit', "planID=$plan->id", '', 'list');
|
||||
common::printIcon('productplan', 'edit', "planID=$plan->id", $plan, 'list');
|
||||
|
||||
if(common::hasPriv('productplan', 'delete'))
|
||||
if(common::hasPriv('productplan', 'delete', $plan))
|
||||
{
|
||||
$deleteURL = $this->createLink('productplan', 'delete', "planID=$plan->id&confirm=yes");
|
||||
echo html::a("javascript:ajaxDelete(\"$deleteURL\",\"productplan\",confirmDelete)", '<i class="icon-remove"></i>', '', "class='btn-icon' title='{$lang->productplan->delete}'");
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
{
|
||||
ob_start();
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('story', 'create', "productID=$plan->product&branch=$plan->branch&moduleID=0&storyID=0&projectID=0&bugID=0&planID=$plan->id", '', 'button', 'plus');
|
||||
common::printIcon('story', 'create', "productID=$plan->product&branch=$plan->branch&moduleID=0&storyID=0&projectID=0&bugID=0&planID=$plan->id", $plan, 'button', 'plus');
|
||||
if(common::hasPriv('productplan', 'linkStory')) echo html::a(inlink('view', "planID=$plan->id&type=story&orderBy=id_desc&link=true"), '<i class="icon-link"></i> ' . $lang->productplan->linkStory, '', "class='btn'");
|
||||
if(common::hasPriv('productplan', 'linkBug') and $config->global->flow != 'onlyStory') echo html::a(inlink('view', "planID=$plan->id&type=bug&orderBy=id_desc&link=true"), '<i class="icon-bug"></i> ' . $lang->productplan->linkBug, '', "class='btn'");
|
||||
echo '</div>';
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('productplan', 'edit', "planID=$plan->id");
|
||||
common::printIcon('productplan', 'delete', "planID=$plan->id", '', 'button', '', 'hiddenwin');
|
||||
common::printIcon('productplan', 'edit', "planID=$plan->id", $plan);
|
||||
common::printIcon('productplan', 'delete', "planID=$plan->id", $plan, 'button', '', 'hiddenwin');
|
||||
echo '</div>';
|
||||
$actionLinks = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
+14
-11
@@ -126,6 +126,8 @@ class project extends control
|
||||
$this->loadModel('task');
|
||||
$this->loadModel('datatable');
|
||||
|
||||
$this->project->getLimitedProject();
|
||||
|
||||
/* Set browse type. */
|
||||
$browseType = strtolower($status);
|
||||
if($this->config->global->flow == 'onlyTask' and $browseType == 'byproduct') $param = 0;
|
||||
@@ -608,6 +610,7 @@ class project extends control
|
||||
$this->view->users = $users;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->branchGroups = $branchGroups;
|
||||
$this->view->limitedUser = $this->app->user->limitedUser == 'yes' ? true : false;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -1932,15 +1935,15 @@ class project extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* All project.
|
||||
*
|
||||
* @param string $status
|
||||
* @param int $projectID
|
||||
* @param string $orderBy
|
||||
* @param int $productID
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* All project.
|
||||
*
|
||||
* @param string $status
|
||||
* @param int $projectID
|
||||
* @param string $orderBy
|
||||
* @param int $productID
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -1974,8 +1977,8 @@ class project extends control
|
||||
|
||||
/**
|
||||
* Doc for compatible.
|
||||
*
|
||||
* @param int $projectID
|
||||
*
|
||||
* @param int $projectID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
|
||||
@@ -79,6 +79,10 @@ $lang->team->hours = 'Hour/Day';
|
||||
$lang->team->days = 'Workdays';
|
||||
$lang->team->totalHours = 'Total';
|
||||
|
||||
$lang->team->limitedUser = 'limited User';
|
||||
$lang->team->limitedUserList['no'] = 'No';
|
||||
$lang->team->limitedUserList['yes'] = 'Yes';
|
||||
|
||||
$lang->project->basicInfo = 'Basic Info';
|
||||
$lang->project->otherInfo = 'Other Info';
|
||||
|
||||
|
||||
@@ -78,7 +78,11 @@ $lang->team->join = '加盟日';
|
||||
$lang->team->hours = '可用工时/天';
|
||||
$lang->team->days = '可用工日';
|
||||
$lang->team->totalHours = '总计';
|
||||
|
||||
|
||||
$lang->team->limitedUser = '受限用户';
|
||||
$lang->team->limitedUserList['no'] = '否';
|
||||
$lang->team->limitedUserList['yes'] = '是';
|
||||
|
||||
$lang->project->basicInfo = '基本信息';
|
||||
$lang->project->otherInfo = '其他信息';
|
||||
|
||||
|
||||
@@ -78,7 +78,11 @@ $lang->team->join = '加盟日';
|
||||
$lang->team->hours = '可用工時/天';
|
||||
$lang->team->days = '可用工日';
|
||||
$lang->team->totalHours = '總計';
|
||||
|
||||
|
||||
$lang->team->limitedUser = '受限用戶';
|
||||
$lang->team->limitedUserList['no'] = '否';
|
||||
$lang->team->limitedUserList['yes'] = '是';
|
||||
|
||||
$lang->project->basicInfo = '基本信息';
|
||||
$lang->project->otherInfo = '其他信息';
|
||||
|
||||
|
||||
@@ -574,6 +574,7 @@ class projectModel extends model
|
||||
$firstProject = $projects[0];
|
||||
$pairs[$firstProject->id] = $firstProject->name;
|
||||
}
|
||||
|
||||
return $pairs;
|
||||
}
|
||||
|
||||
@@ -1453,8 +1454,8 @@ class projectModel extends model
|
||||
|
||||
/**
|
||||
* Manage team members.
|
||||
*
|
||||
* @param int $projectID
|
||||
*
|
||||
* @param int $projectID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -1469,9 +1470,10 @@ class projectModel extends model
|
||||
if(empty($account)) continue;
|
||||
|
||||
$member = new stdclass();
|
||||
$member->role = $roles[$key];
|
||||
$member->days = $days[$key];
|
||||
$member->hours = $hours[$key];
|
||||
$member->role = $roles[$key];
|
||||
$member->days = $days[$key];
|
||||
$member->hours = $hours[$key];
|
||||
$member->limitedUser = $limitedUser[$key];
|
||||
|
||||
$mode = $modes[$key];
|
||||
if($mode == 'update')
|
||||
@@ -1749,6 +1751,8 @@ class projectModel extends model
|
||||
{
|
||||
$action = strtolower($action);
|
||||
|
||||
if(!common::limitedUser($project, 'project')) return false;
|
||||
|
||||
if($action == 'start') return $project->status == 'wait';
|
||||
if($action == 'close') return $project->status != 'done';
|
||||
if($action == 'suspend') return $project->status == 'wait' or $project->status == 'doing';
|
||||
@@ -1771,7 +1775,7 @@ class projectModel extends model
|
||||
{
|
||||
$link = '';
|
||||
if($module == 'task' and ($method == 'view' || $method == 'edit' || $method == 'batchedit'))
|
||||
{
|
||||
{
|
||||
$module = 'project';
|
||||
$method = 'task';
|
||||
}
|
||||
@@ -1865,9 +1869,29 @@ class projectModel extends model
|
||||
return round($estimate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the privilege.
|
||||
*
|
||||
* @param object $project
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function getLimitedProject()
|
||||
{
|
||||
/* If is admin, return true. */
|
||||
if($this->app->user->admin) return true;
|
||||
|
||||
/* Get all teams of all projects and group by projects, save it as static. */
|
||||
$teams = $this->dao->select('project, limitedUser')->from(TABLE_TEAM)->where('account')->eq($this->app->user->account)->fetchAll('project');
|
||||
foreach($teams as $projectID => $object)
|
||||
{
|
||||
if($object->limitedUser == 'yes') $this->session->set($this->app->user->account . 'project' . $object->project, $object->project);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix order.
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<?php
|
||||
$params = "bugID=$bug->id";
|
||||
common::printIcon('bug', 'confirmBug', $params, $bug, 'list', 'search', '', 'iframe', true);
|
||||
common::printIcon('bug', 'assignTo', $params, '', 'list', '', '', 'iframe', true);
|
||||
common::printIcon('bug', 'assignTo', $params, $bug, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('bug', 'resolve', $params, $bug, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('bug', 'close', $params, $bug, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('bug', 'edit', $params, $bug, 'list');
|
||||
|
||||
@@ -49,16 +49,16 @@
|
||||
<td><?php echo $build->date?></td>
|
||||
<td><?php echo $users[$build->builder]?></td>
|
||||
<td class='text-right'>
|
||||
<?php
|
||||
<?php
|
||||
if(common::hasPriv('build', 'linkstory') and common::hasPriv('build', 'view'))
|
||||
{
|
||||
echo html::a($this->createLink('build', 'view', "buildID=$build->id&type=story&link=true"), "<i class='icon icon-link'></i>", '', "class='btn-icon' title='{$lang->build->linkStory}'");
|
||||
}
|
||||
common::printIcon('testtask', 'create', "product=$build->product&project=$project->id&build=$build->id", '', 'list', 'bullhorn');
|
||||
common::printIcon('testtask', 'create', "product=$build->product&project=$project->id&build=$build->id", $build, 'list', 'bullhorn');
|
||||
$lang->project->bug = $lang->project->viewBug;
|
||||
common::printIcon('project', 'bug', "project=$project->id&orderBy=status&build=$build->id", '', 'list');
|
||||
common::printIcon('build', 'edit', "buildID=$build->id", '', 'list');
|
||||
if(common::hasPriv('build', 'delete'))
|
||||
common::printIcon('project', 'bug', "project=$project->id&orderBy=status&build=$build->id", $build, 'list');
|
||||
common::printIcon('build', 'edit', "buildID=$build->id", $build, 'list');
|
||||
if(common::hasPriv('build', 'delete', $build))
|
||||
{
|
||||
$deleteURL = $this->createLink('build', 'delete', "buildID=$build->id&confirm=yes");
|
||||
echo html::a("javascript:ajaxDelete(\"$deleteURL\",\"buildList\",confirmDelete)", '<i class="icon-remove"></i>', '', "class='btn-icon' title='{$lang->build->delete}'");
|
||||
|
||||
@@ -134,15 +134,15 @@
|
||||
<tr>
|
||||
<th><?php echo $lang->project->desc;?></th>
|
||||
<td colspan='2'><?php echo html::textarea('desc', htmlspecialchars($project->desc), "rows='6' class='form-control'");?></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->acl;?></th>
|
||||
<td colspan='2'><?php echo nl2br(html::radio('acl', $lang->project->aclList, $project->acl, "onclick='setWhite(this.value);'", 'block'));?></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr id='whitelistBox' <?php if($project->acl != 'custom') echo "class='hidden'";?>>
|
||||
<th><?php echo $lang->project->whitelist;?></th>
|
||||
<td colspan='2' id='whitelistBox'><?php echo html::checkbox('whitelist', $groups, $project->whitelist);?></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr><td></td><td colspan='2'><?php echo html::submitButton() . html::backButton();?></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<?php if($productType != 'normal'):?>
|
||||
<td><?php if(isset($branchGroups[$story->product][$story->branch])) echo $branchGroups[$story->product][$story->branch];?></td>
|
||||
<?php endif;?>
|
||||
<td><?php echo $users[$story->openedBy];?></td>
|
||||
<td><?php echo zget($users, $story->openedBy, $story->openedBy);?></td>
|
||||
<td><?php echo $story->estimate;?></td>
|
||||
</tr>
|
||||
<?php $storyCount ++;?>
|
||||
|
||||
@@ -41,11 +41,12 @@
|
||||
<th><?php echo $lang->team->role;?></th>
|
||||
<th class='w-100px'><?php echo $lang->team->days;?></th>
|
||||
<th class='w-100px'><?php echo $lang->team->hours;?></th>
|
||||
<th class='w-100px'><?php echo $lang->team->limitedUser;?></th>
|
||||
<th class="w-40px"> <?php echo $lang->actions;?></th>
|
||||
<th class="w-40px"> <?php echo $lang->delete;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<?php $i = 1; $memberCount = 0;?>
|
||||
<?php $i = 0; $memberCount = 0;?>
|
||||
<?php foreach($currentMembers as $member):?>
|
||||
<?php if(!isset($users[$member->account])) continue;?>
|
||||
<?php unset($users[$member->account]);?>
|
||||
@@ -58,6 +59,7 @@
|
||||
<input type='hidden' name='modes[]' value='update' />
|
||||
<input type='hidden' name='accounts[]' value='<?php echo $member->account;?>' />
|
||||
</td>
|
||||
<td><?php echo html::radio("limitedUser[$i]", $lang->team->limitedUserList, $member->limitedUser);?></td>
|
||||
<td><a href='javascript:;' onclick='addItem()' class='btn btn-block'><i class='icon-plus'></i></a></td>
|
||||
<td><a href='javascript:;' onclick='deleteItem()' class='disabled btn btn-block'><i class='icon icon-remove'></i></a></td>
|
||||
</tr>
|
||||
@@ -73,6 +75,7 @@
|
||||
<input type='text' name='hours[]' id='hours<?php echo $i;?>' class='form-control' value='<?php echo $member2Import->hours;?>' />
|
||||
<input type='hidden' name='modes[]' value='create' />
|
||||
</td>
|
||||
<td><?php echo html::radio("limitedUser[$i]", $lang->team->limitedUserList, 'no');?></td>
|
||||
<td><a href='javascript:;' onclick='addItem()' class='btn btn-block'><i class='icon-plus'></i></a></td>
|
||||
<td><a href='javascript:;' onclick='deleteItem(this)' class='btn btn-block'><i class='icon icon-remove'></i></a></td>
|
||||
</tr>
|
||||
@@ -89,6 +92,7 @@
|
||||
<input type='text' name='hours[]' id='hours<?php echo $i;?>' class='form-control' value='<?php echo $config->project->defaultWorkhours?>' />
|
||||
<input type='hidden' name='modes[]' value='create' />
|
||||
</td>
|
||||
<td><?php echo html::radio("limitedUser[$i]", $lang->team->limitedUserList, 'no');?></td>
|
||||
<td><a href='javascript:;' onclick='addItem()' class='btn btn-block'><i class='icon-plus'></i></a></td>
|
||||
<td><a href='javascript:;' onclick='deleteItem(this)' class='btn btn-block'><i class='icon icon-remove'></i></a></td>
|
||||
</tr>
|
||||
@@ -105,6 +109,7 @@
|
||||
<input type='text' name='hours[]' id='hours<?php echo ($i);?>' class='form-control' value='<?php echo $config->project->defaultWorkhours?>' />
|
||||
<input type='hidden' name='modes[]' value='create' />
|
||||
</td>
|
||||
<td><?php echo html::radio("limitedUser[$i]", $lang->team->limitedUserList, 'no');?></td>
|
||||
<td><a href='javascript:;' onclick='addItem()' class='btn btn-block'><i class='icon-plus'></i></a></td>
|
||||
<td><a href='javascript:;' onclick='deleteItem(this)' class='btn btn-block'><i class='icon icon-remove'></i></a></td>
|
||||
</tr>
|
||||
@@ -113,7 +118,7 @@
|
||||
<?php js::set('i', $i);?>
|
||||
|
||||
<tr id='submit'>
|
||||
<td colspan='6' class='text-center'>
|
||||
<td colspan='7' class='text-center'>
|
||||
<?php echo html::submitButton() ?>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -131,6 +136,7 @@
|
||||
<input type='text' name='hours[]' id='hours<?php echo ($i);?>' class='form-control' value='<?php echo $config->project->defaultWorkhours?>' />
|
||||
<input type='hidden' name='modes[]' value='create' />
|
||||
</td>
|
||||
<td><?php echo html::radio("limitedUser[$i]", $lang->team->limitedUserList, $member->realname ? $member->limitedUser : 'no');?></td>
|
||||
<td><a href='javascript:;' onclick='addItem()' class='btn btn-block'><i class='icon-plus'></i></a></td>
|
||||
<td><a href='javascript:;' onclick='deleteItem(this)' class='btn btn-block'><i class='icon icon-remove'></i></a></td>
|
||||
</tr>
|
||||
|
||||
@@ -104,21 +104,21 @@
|
||||
<?php
|
||||
$tasksLink = $this->createLink('story', 'tasks', "storyID=$story->id&projectID=$project->id");
|
||||
$storyTasks[$story->id] > 0 ? print(html::a($tasksLink, $storyTasks[$story->id], '', 'class="iframe"')) : print(0);
|
||||
?>
|
||||
?>
|
||||
<td>
|
||||
<?php
|
||||
<?php
|
||||
$bugsLink = $this->createLink('story', 'bugs', "storyID=$story->id&projectID=$project->id");
|
||||
$storyBugs[$story->id] > 0 ? print(html::a($bugsLink, $storyBugs[$story->id], '', 'class="iframe"')) : print(0);
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
<?php
|
||||
$casesLink = $this->createLink('story', 'cases', "storyID=$story->id&projectID=$project->id");
|
||||
$storyCases[$story->id] > 0 ? print(html::a($casesLink, $storyCases[$story->id], '', 'class="iframe"')) : print(0);
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
<?php
|
||||
$param = "projectID={$project->id}&story={$story->id}&moduleID={$story->module}";
|
||||
|
||||
$lang->task->create = $lang->project->wbs;
|
||||
@@ -129,16 +129,16 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
common::printIcon('task', 'create', $param, '', 'list', 'plus-border', '', 'btn-task-create');
|
||||
if(!$limitedUser) common::printIcon('task', 'create', $param, $story, 'list', 'plus-border', '', 'btn-task-create');
|
||||
}
|
||||
|
||||
$lang->task->batchCreate = $lang->project->batchWBS;
|
||||
common::printIcon('task', 'batchCreate', "projectID={$project->id}&story={$story->id}", '', 'list', 'plus-sign');
|
||||
if(!$limitedUser) common::printIcon('task', 'batchCreate', "projectID={$project->id}&story={$story->id}", $story, 'list', 'plus-sign');
|
||||
|
||||
$lang->testcase->batchCreate = $lang->testcase->create;
|
||||
if($productID) common::printIcon('testcase', 'batchCreate', "productID=$story->product&branch=$story->branch&moduleID=$story->module&storyID=$story->id", '', 'list', 'sitemap');
|
||||
if($productID && !$limitedUser) common::printIcon('testcase', 'batchCreate', "productID=$story->product&branch=$story->branch&moduleID=$story->module&storyID=$story->id", $story, 'list', 'sitemap');
|
||||
|
||||
if(common::hasPriv('project', 'unlinkStory'))
|
||||
if(common::hasPriv('project', 'unlinkStory') && !$limitedUser)
|
||||
{
|
||||
$unlinkURL = $this->createLink('project', 'unlinkStory', "projectID=$project->id&storyID=$story->id&confirm=yes");
|
||||
echo html::a("javascript:ajaxDelete(\"$unlinkURL\",\"storyList\",confirmUnlinkStory)", '<i class="icon-unlink"></i>', '', "class='btn-icon' title='{$lang->project->unlinkStory}'");
|
||||
|
||||
@@ -55,11 +55,11 @@ js::set('browseType', $browseType);
|
||||
<td colspan='<?php echo $columns;?>'>
|
||||
<div class='table-actions clearfix'>
|
||||
<?php
|
||||
$canBatchEdit = common::hasPriv('task', 'batchEdit');
|
||||
$canBatchClose = (common::hasPriv('task', 'batchClose') && strtolower($browseType) != 'closedBy');
|
||||
$canBatchCancel = common::hasPriv('task', 'batchCancel');
|
||||
$canBatchChangeModule = common::hasPriv('task', 'batchChangeModule');
|
||||
$canBatchAssignTo = common::hasPriv('task', 'batchAssignTo');
|
||||
$canBatchEdit = common::hasPriv('task', 'batchEdit', $task);
|
||||
$canBatchClose = (common::hasPriv('task', 'batchClose', $task) && strtolower($browseType) != 'closedBy');
|
||||
$canBatchCancel = common::hasPriv('task', 'batchCancel', $task);
|
||||
$canBatchChangeModule = common::hasPriv('task', 'batchChangeModule', $task);
|
||||
$canBatchAssignTo = common::hasPriv('task', 'batchAssignTo', $task);
|
||||
if(count($tasks))
|
||||
{
|
||||
echo html::selectButton();
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
}
|
||||
common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('task', 'edit', "taskID=$task->id", '', 'list');
|
||||
common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list');
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -123,8 +123,8 @@
|
||||
<div class='btn-group'>
|
||||
<div class='btn-group' id='createActionMenu'>
|
||||
<?php
|
||||
$misc = common::hasPriv('task', 'create') ? "class='btn btn-primary'" : "class='btn btn-primary disabled'";
|
||||
$link = common::hasPriv('task', 'create') ? $this->createLink('task', 'create', "project=$projectID" . (isset($moduleID) ? "&storyID=&moduleID=$moduleID" : '')) : '#';
|
||||
$misc = common::hasPriv('task', 'create', $project) ? "class='btn btn-primary'" : "class='btn btn-primary disabled'";
|
||||
$link = common::hasPriv('task', 'create', $project) ? $this->createLink('task', 'create', "project=$projectID" . (isset($moduleID) ? "&storyID=&moduleID=$moduleID" : '')) : '#';
|
||||
echo html::a($link, "<i class='icon icon-plus'></i>" . $lang->task->create, '', $misc);
|
||||
?>
|
||||
<button type='button' class='btn btn-primary dropdown-toggle' data-toggle='dropdown'>
|
||||
@@ -132,8 +132,8 @@
|
||||
</button>
|
||||
<ul class='dropdown-menu pull-right'>
|
||||
<?php
|
||||
$misc = common::hasPriv('task', 'batchCreate') ? '' : "class=disabled";
|
||||
$link = common::hasPriv('task', 'batchCreate') ? $this->createLink('task', 'batchCreate', "project=$projectID" . (isset($moduleID) ? "&storyID=&moduleID=$moduleID" : '')) : '#';
|
||||
$misc = common::hasPriv('task', 'batchCreate', $project) ? '' : "class=disabled";
|
||||
$link = common::hasPriv('task', 'batchCreate', $project) ? $this->createLink('task', 'batchCreate', "project=$projectID" . (isset($moduleID) ? "&storyID=&moduleID=$moduleID" : '')) : '#';
|
||||
echo "<li>" . html::a($link, $lang->task->batchCreate, '', $misc) . "</li>";
|
||||
?>
|
||||
</ul>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
common::printLink('project', 'managemembers', "projectID=$project->id", $lang->project->manageMembers, '', "class='btn btn-primary manage-team-btn'");
|
||||
if($app->user->limitedUser === 'no') common::printLink('project', 'managemembers', "projectID=$project->id", $lang->project->manageMembers, '', "class='btn btn-primary manage-team-btn'");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
@@ -41,6 +41,7 @@
|
||||
<th><?php echo $lang->team->days;?></th>
|
||||
<th><?php echo $lang->team->hours;?></th>
|
||||
<th><?php echo $lang->team->totalHours;?></th>
|
||||
<th><?php echo $lang->team->limitedUser;?></th>
|
||||
<th><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -60,9 +61,10 @@
|
||||
<td><?php echo $member->days . $lang->project->day;?></td>
|
||||
<td><?php echo $member->hours . $lang->project->workHour;?></td>
|
||||
<td><?php echo $memberHours . $lang->project->workHour;?></td>
|
||||
<td><?php echo $lang->team->limitedUserList[$member->limitedUser];?></td>
|
||||
<td>
|
||||
<?php
|
||||
if (common::hasPriv('project', 'unlinkMember'))
|
||||
if (common::hasPriv('project', 'unlinkMember', $member))
|
||||
{
|
||||
$unlinkURL = $this->createLink('project', 'unlinkMember', "projectID=$project->id&account=$member->account&confirm=yes");
|
||||
echo html::a("javascript:ajaxDelete(\"$unlinkURL\",\"memberList\",confirmUnlinkMember)", '<i class="icon-green-project-unlinkMember icon-remove"></i>', '', "class='btn-icon' title='{$lang->project->unlinkMember}'");
|
||||
@@ -74,7 +76,7 @@
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan='7'>
|
||||
<td colspan='8'>
|
||||
<div class='table-actions clearfix'><div class='text'><?php echo $lang->team->totalHours . ':' . "<strong>$totalHours{$lang->project->workHour}</strong>";?></div></div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -50,12 +50,12 @@
|
||||
<td class='status-<?php echo $task->status?>'><?php echo $lang->testtask->statusList[$task->status];?></td>
|
||||
<td>
|
||||
<?php
|
||||
common::printIcon('testtask', 'cases', "taskID=$task->id", '', 'list', 'sitemap');
|
||||
common::printIcon('testtask', 'linkCase', "taskID=$task->id", '', 'list', 'link');
|
||||
common::printIcon('testtask', 'edit', "taskID=$task->id", '', 'list');
|
||||
common::printIcon('testreport', 'create', "objectID=$task->id&objectType=testtask", '', 'list','flag');
|
||||
common::printIcon('testtask', 'cases', "taskID=$task->id", $task, 'list', 'sitemap');
|
||||
common::printIcon('testtask', 'linkCase', "taskID=$task->id", $task, 'list', 'link');
|
||||
common::printIcon('testtask', 'edit', "taskID=$task->id", $task, 'list');
|
||||
common::printIcon('testreport', 'create', "objectID=$task->id&objectType=testtask", $task, 'list','flag');
|
||||
|
||||
if(common::hasPriv('testtask', 'delete'))
|
||||
if(common::hasPriv('testtask', 'delete', $task))
|
||||
{
|
||||
$deleteURL = $this->createLink('testtask', 'delete', "taskID=$task->id&confirm=yes");
|
||||
echo html::a("javascript:ajaxDelete(\"$deleteURL\",\"taskList\",confirmDelete)", '<i class="icon-remove"></i>', '', "class='btn-icon' title='{$lang->testtask->delete}'");
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
echo '</div>';
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('project', 'edit', $params);
|
||||
common::printIcon('project', 'delete', $params, '', 'button', '', 'hiddenwin');
|
||||
common::printIcon('project', 'edit', $params, $project);
|
||||
common::printIcon('project', 'delete', $params, $project, 'button', '', 'hiddenwin');
|
||||
echo '</div>';
|
||||
common::printRPN($browseLink);
|
||||
|
||||
|
||||
@@ -319,4 +319,19 @@ class releaseModel extends model
|
||||
$this->dao->update(TABLE_RELEASE)->set('status')->eq($status)->where('id')->eq($releaseID)->exec();
|
||||
return dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge an action is clickable or not.
|
||||
*-
|
||||
* @param object $product-
|
||||
* @param string $action-
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function isClickable($release, $action)
|
||||
{
|
||||
if(!common::limitedUser($release)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,13 +53,13 @@
|
||||
<?php
|
||||
if(common::hasPriv('release', 'linkStory')) echo html::a(inlink('view', "releaseID=$release->id&type=story&link=true"), '<i class="icon-link"></i> ', '', "class='btn-icon' title='{$lang->release->linkStory}'");
|
||||
if(common::hasPriv('release', 'linkBug') and $this->config->global->flow != 'onlyStory') echo html::a(inlink('view', "releaseID=$release->id&type=bug&link=true"), '<i class="icon-bug"></i> ', '', "class='btn-icon' title='{$lang->release->linkBug}'");
|
||||
if(common::hasPriv('release', 'changeStatus'))
|
||||
if(common::hasPriv('release', 'changeStatus', $release))
|
||||
{
|
||||
$changedStatus = $release->status == 'normal' ? 'terminate' : 'normal';
|
||||
echo html::a(inlink('changeStatus', "releaseID=$release->id&status=$changedStatus"), '<i class="icon-' . ($release->status == 'normal' ? 'pause' : 'play') . '"></i> ', 'hiddenwin', "class='btn-icon' title='{$lang->release->changeStatusList[$changedStatus]}'");
|
||||
}
|
||||
common::printIcon('release', 'edit', "release=$release->id", '', 'list');
|
||||
if(common::hasPriv('release', 'delete'))
|
||||
common::printIcon('release', 'edit', "release=$release->id", $release, 'list');
|
||||
if(common::hasPriv('release', 'delete', $release))
|
||||
{
|
||||
$deleteURL = $this->createLink('release', 'delete', "releaseID=$release->id&confirm=yes");
|
||||
echo html::a("javascript:ajaxDelete(\"$deleteURL\",\"releaseList\",confirmDelete)", '<i class="icon-remove"></i>', '', "class='btn-icon' title='{$lang->release->delete}'");
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
ob_start();
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
if(common::hasPriv('release', 'changeStatus'))
|
||||
if(common::hasPriv('release', 'changeStatus', $release))
|
||||
{
|
||||
$changedStatus = $release->status == 'normal' ? 'terminate' : 'normal';
|
||||
echo html::a(inlink('changeStatus', "releaseID=$release->id&type=$changedStatus"), '<i class="icon-' . ($release->status == 'normal' ? 'pause' : 'play') . '"></i> ' . $lang->release->changeStatusList[$changedStatus], 'hiddenwin', "class='btn'");
|
||||
@@ -39,8 +39,8 @@
|
||||
echo '</div>';
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('release', 'edit', "releaseID=$release->id");
|
||||
common::printIcon('release', 'delete', "releaseID=$release->id", '', 'button', '', 'hiddenwin');
|
||||
common::printIcon('release', 'edit', "releaseID=$release->id", $release);
|
||||
common::printIcon('release', 'delete', "releaseID=$release->id", $release, 'button', '', 'hiddenwin');
|
||||
echo '</div>';
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
|
||||
@@ -21,10 +21,10 @@ class report extends control
|
||||
{
|
||||
$this->locate(inlink('productSummary'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Project deviation report.
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
setTimeout(function(){fixedTheadOfList('#bugAssign')}, 100);
|
||||
});
|
||||
@@ -1,3 +1,8 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
setTimeout(function(){fixedTheadOfList('#bug')}, 100);
|
||||
});
|
||||
|
||||
function changeParams(obj)
|
||||
{
|
||||
var begin = $('.main .row').find('#begin').val();
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
setTimeout(function(){fixedTheadOfList('#product')}, 100);
|
||||
});
|
||||
|
||||
$('#conditions input:checkbox').change(function()
|
||||
{
|
||||
var conditions = '';
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
setTimeout(function(){fixedTheadOfList('#projectList')}, 100);
|
||||
});
|
||||
|
||||
function changeDate(begin, end)
|
||||
{
|
||||
if(begin.indexOf('-') != -1)
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
setTimeout(function(){fixedTheadOfList('#workload')}, 100);
|
||||
});
|
||||
|
||||
function changeParams(obj)
|
||||
{
|
||||
var begin = $('.main .row').find('#begin').val();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<span class='input-group-addon'><?php echo $lang->report->to;?></span>
|
||||
<div class='datepicker-wrapper datepicker-date'><?php echo html::input('date', $end, "class='form-control form-date' onchange='changeDate(\"$begin\", this.value)'");?></div>
|
||||
</div>
|
||||
<table class='table table-condensed table-striped table-bordered tablesorter table-fixed active-disabled'>
|
||||
<table class='table table-condensed table-striped table-bordered tablesorter table-fixed active-disabled' id='projectList'>
|
||||
<thead>
|
||||
<tr class='colhead'>
|
||||
<th class='w-id'><?php echo $lang->report->id;?></th>
|
||||
|
||||
@@ -29,12 +29,12 @@ $config->story->editor->activate = array('id' => 'comment', 'tools' => 'simpleTo
|
||||
|
||||
$config->story->list = new stdclass();
|
||||
$config->story->list->exportFields = '
|
||||
id, product, branch, module, plan, source, title, spec, verify, keywords,
|
||||
id, product, branch, module, plan, source, sourceNote, title, spec, verify, keywords,
|
||||
pri, estimate, status, stage, taskCountAB, bugCountAB, caseCountAB,
|
||||
openedBy, openedDate, assignedTo, assignedDate, mailto,
|
||||
reviewedBy, reviewedDate,
|
||||
openedBy, openedDate, assignedTo, assignedDate, mailto,
|
||||
reviewedBy, reviewedDate,
|
||||
closedBy, closedDate, closedReason,
|
||||
lastEditedBy, lastEditedDate,
|
||||
lastEditedBy, lastEditedDate,
|
||||
childStories, linkStories, duplicateStory, files';
|
||||
|
||||
$config->story->list->customCreateFields = 'source,verify,pri,estimate,mailto,keywords';
|
||||
@@ -74,6 +74,11 @@ $config->story->datatable->fieldList['source']['fixed'] = 'no';
|
||||
$config->story->datatable->fieldList['source']['width'] = '90';
|
||||
$config->story->datatable->fieldList['source']['required'] = 'no';
|
||||
|
||||
$config->story->datatable->fieldList['sourceNote']['title'] = 'sourceNote';
|
||||
$config->story->datatable->fieldList['sourceNote']['fixed'] = 'no';
|
||||
$config->story->datatable->fieldList['sourceNote']['width'] = '90';
|
||||
$config->story->datatable->fieldList['sourceNote']['required'] = 'no';
|
||||
|
||||
$config->story->datatable->fieldList['status']['title'] = 'statusAB';
|
||||
$config->story->datatable->fieldList['status']['fixed'] = 'no';
|
||||
$config->story->datatable->fieldList['status']['width'] = '80';
|
||||
|
||||
+25
-15
@@ -29,14 +29,14 @@ class story extends control
|
||||
|
||||
/**
|
||||
* Create a story.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param int $moduleID
|
||||
* @param int $storyID
|
||||
* @param int $projectID
|
||||
* @param int $bugID
|
||||
* @param int $planID
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param int $moduleID
|
||||
* @param int $storyID
|
||||
* @param int $projectID
|
||||
* @param int $bugID
|
||||
* @param int $planID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -116,12 +116,15 @@ class story extends control
|
||||
$verify = '';
|
||||
$keywords = '';
|
||||
$mailto = '';
|
||||
$color = '';
|
||||
|
||||
if($storyID > 0)
|
||||
{
|
||||
$story = $this->story->getByID($storyID);
|
||||
$planID = $story->plan;
|
||||
$source = $story->source;
|
||||
$sourceNote = $story->sourceNote;
|
||||
$color = $story->color;
|
||||
$pri = $story->pri;
|
||||
$productID = $story->product;
|
||||
$moduleID = $story->module;
|
||||
@@ -169,6 +172,7 @@ class story extends control
|
||||
$this->view->planID = $planID;
|
||||
$this->view->source = $source;
|
||||
$this->view->sourceNote = $sourceNote;
|
||||
$this->view->color = $color;
|
||||
$this->view->pri = $pri;
|
||||
$this->view->branch = $branch;
|
||||
$this->view->branches = $product->type != 'normal' ? $this->loadModel('branch')->getPairs($productID) : array();
|
||||
@@ -185,7 +189,7 @@ class story extends control
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a batch stories.
|
||||
*
|
||||
@@ -1255,15 +1259,20 @@ class story extends control
|
||||
|
||||
/**
|
||||
* AJAX: get module of a story.
|
||||
*
|
||||
* @param int $storyID
|
||||
*
|
||||
* @param int $storyID
|
||||
* @access public
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function ajaxGetModule($storyID)
|
||||
public function ajaxGetInfo($storyID)
|
||||
{
|
||||
$story = $this->story->getByID($storyID);
|
||||
echo $story->module;
|
||||
$story = $this->story->getByID($storyID);
|
||||
|
||||
$storyInfo['moduleID'] = $story->module;
|
||||
$storyInfo['estimate'] = $story->estimate;
|
||||
$storyInfo['pri'] = $story->pri;
|
||||
$storyInfo['spec'] = $story->spec;
|
||||
echo json_encode($storyInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1436,6 +1445,7 @@ class story extends control
|
||||
if(isset($storyLang->stageList[$story->stage])) $story->stage = $storyLang->stageList[$story->stage];
|
||||
if(isset($storyLang->reasonList[$story->closedReason])) $story->closedReason = $storyLang->reasonList[$story->closedReason];
|
||||
if(isset($storyLang->sourceList[$story->source])) $story->source = $storyLang->sourceList[$story->source];
|
||||
if(isset($storyLang->sourceList[$story->sourceNote])) $story->sourceNote = $storyLang->sourceList[$story->sourceNote];
|
||||
|
||||
if(isset($users[$story->openedBy])) $story->openedBy = $users[$story->openedBy];
|
||||
if(isset($users[$story->assignedTo])) $story->assignedTo = $users[$story->assignedTo];
|
||||
|
||||
@@ -18,5 +18,6 @@ select {border:1px solid #ccc}
|
||||
|
||||
.colorpicker.input-group-btn > .btn {border-right: none}
|
||||
|
||||
#branch_chosen.chosen-container .chosen-drop {min-width: 280px; border-top: 1px solid #ddd!important}
|
||||
#branch {border-left-width: 0px}
|
||||
#mailtoGroup .chosen-container-single a {border-left-width: 0px}
|
||||
|
||||
@@ -90,6 +90,7 @@ $lang->story->keywords = 'Keywords';
|
||||
$lang->story->newStory = 'Continue adding Story.';
|
||||
$lang->story->colorTag = 'Color Tag';
|
||||
$lang->story->files = 'Files';
|
||||
$lang->story->copy = "Duplicate a Story";
|
||||
|
||||
$lang->story->ditto = 'Ditto';
|
||||
$lang->story->dittoNotice = 'This Story does not belong to the same Product as the last Story does!';
|
||||
|
||||
@@ -90,6 +90,7 @@ $lang->story->keywords = '关键词';
|
||||
$lang->story->newStory = '继续添加需求';
|
||||
$lang->story->colorTag = '颜色标签';
|
||||
$lang->story->files = '附件';
|
||||
$lang->story->copy = "复制需求";
|
||||
|
||||
$lang->story->ditto = '同上';
|
||||
$lang->story->dittoNotice = '该需求与上一需求不属于同一产品!';
|
||||
|
||||
@@ -90,6 +90,7 @@ $lang->story->keywords = '關鍵詞';
|
||||
$lang->story->newStory = '繼續添加需求';
|
||||
$lang->story->colorTag = '顏色標籤';
|
||||
$lang->story->files = '附件';
|
||||
$lang->story->copy = "復制需求";
|
||||
|
||||
$lang->story->ditto = '同上';
|
||||
$lang->story->dittoNotice = '該需求與上一需求不屬於同一產品!';
|
||||
|
||||
+31
-26
@@ -1456,19 +1456,19 @@ class storyModel extends model
|
||||
|
||||
/**
|
||||
* Get stories through search.
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @param int $productID
|
||||
* @param int $queryID
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param string $projectID
|
||||
* @param int $productID
|
||||
* @param int $queryID
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param string $projectID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBySearch($productID, $queryID, $orderBy, $pager = null, $projectID = '', $branch = 0)
|
||||
{
|
||||
if($projectID != '')
|
||||
if($projectID != '')
|
||||
{
|
||||
$products = $this->loadModel('project')->getProducts($projectID);
|
||||
}
|
||||
@@ -1668,11 +1668,11 @@ class storyModel extends model
|
||||
|
||||
/**
|
||||
* Get stories list of a plan.
|
||||
*
|
||||
* @param int $planID
|
||||
* @param string $status
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
*
|
||||
* @param int $planID
|
||||
* @param string $status
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
@@ -1683,19 +1683,19 @@ class storyModel extends model
|
||||
->beginIF($status and $status != 'all')->andWhere('status')->in($status)->fi()
|
||||
->andWhere('deleted')->eq(0)
|
||||
->orderBy($orderBy)->page($pager)->fetchAll('id');
|
||||
|
||||
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story');
|
||||
|
||||
|
||||
return $stories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stories pairs of a plan.
|
||||
*
|
||||
* @param int $planID
|
||||
* @param string $status
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
*
|
||||
* @param int $planID
|
||||
* @param string $status
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
@@ -2186,6 +2186,8 @@ class storyModel extends model
|
||||
{
|
||||
$action = strtolower($action);
|
||||
|
||||
if(!common::limitedUser($story)) 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';
|
||||
@@ -2234,12 +2236,12 @@ class storyModel extends model
|
||||
|
||||
/**
|
||||
* Print cell data
|
||||
*
|
||||
* @param object $col
|
||||
* @param object $story
|
||||
* @param array $users
|
||||
* @param array $branches
|
||||
* @param array $storyStages
|
||||
*
|
||||
* @param object $col
|
||||
* @param object $story
|
||||
* @param array $users
|
||||
* @param array $branches
|
||||
* @param array $storyStages
|
||||
* @param array $modulePairs
|
||||
* @param array $storyTasks
|
||||
* @param array $storyBugs
|
||||
@@ -2259,7 +2261,7 @@ class storyModel extends model
|
||||
if($id == 'title') $class .= ' text-left';
|
||||
if($id == 'assignedTo' && $story->assignedTo == $account) $class .= ' red';
|
||||
|
||||
$title = '';
|
||||
$title = '';
|
||||
if($id == 'title') $title = $story->title;
|
||||
if($id == 'plan') $title = $story->planTitle;
|
||||
|
||||
@@ -2288,6 +2290,9 @@ class storyModel extends model
|
||||
case 'source':
|
||||
echo zget($this->lang->story->sourceList, $story->source, $story->source);
|
||||
break;
|
||||
case 'sourceNote':
|
||||
echo $story->sourceNote;
|
||||
break;
|
||||
case 'status':
|
||||
echo $this->lang->story->statusList[$story->status];
|
||||
break;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<td class='w-p45-f'>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select('product', $products, $productID, "onchange='loadProduct(this.value);' class='form-control chosen'");?>
|
||||
<?php if($product->type != 'normal') echo html::select('branch', $branches, $branch, "onchange='loadBranch();' class='form-control' style='width:120px'");?>
|
||||
<?php if($product->type != 'normal') echo html::select('branch', $branches, $branch, "onchange='loadBranch();' class='form-control chosen' style='width:120px'");?>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
@@ -72,7 +72,7 @@
|
||||
<div class='input-group'>
|
||||
<span class='input-group-addon'><?php echo $lang->story->source?></span>
|
||||
<?php echo html::select('source', $lang->story->sourceList, $source, "class='form-control'");?>
|
||||
<span class='input-group-addon fix-border'><?php echo $lang->comment?></span>
|
||||
<span class='input-group-addon fix-border'><?php echo $lang->story->sourceNote?></span>
|
||||
<?php echo html::input('sourceNote', $sourceNote, "class='form-control' autocomplete='off'");?>
|
||||
</div>
|
||||
</td>
|
||||
@@ -95,7 +95,7 @@
|
||||
<div class='row-table'>
|
||||
<div class='col-table'>
|
||||
<div class="input-group w-p100">
|
||||
<input type='hidden' id='color' name='color' data-provide='colorpicker' data-wrapper='input-group-btn' data-pull-menu-right='false' data-btn-tip='<?php echo $lang->story->colorTag ?>' data-update-text='#title'>
|
||||
<input type='hidden' id='color' name='color' data-provide='colorpicker' data-wrapper='input-group-btn' data-pull-menu-right='false' data-btn-tip='<?php echo $lang->story->colorTag ?>' data-update-text='#title' value='<?php echo $color;?>'>
|
||||
<?php echo html::input('title', $storyTitle, "class='form-control' autocomplete='off'");?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -141,11 +141,11 @@
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->spec;?></th>
|
||||
<td colspan='2'><?php echo html::textarea('spec', $spec, "rows='9' class='form-control disabled-ie-placeholder' placeholder='" . htmlspecialchars($lang->story->specTemplate) . "'");?></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<?php if(strpos(",$showFields,", ',verify,') !== false):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->verify;?></th>
|
||||
|
||||
@@ -108,17 +108,12 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->source;?></th>
|
||||
<td>
|
||||
<div class='row-table'>
|
||||
<div class='col-table w-90px'><?php echo html::select('source', $lang->story->sourceList, $story->source, 'class=form-control');?></div>
|
||||
<div class='col-table'>
|
||||
<div class='input-group'>
|
||||
<span class='input-group-addon fix-border'><?php echo $lang->comment?></span>
|
||||
<?php echo html::input('sourceNote', $story->sourceNote, "class='form-control' autocomplete='off'");?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><?php echo html::select('source', $lang->story->sourceList, $story->source, 'class=form-control');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->sourceNote;?></th>
|
||||
<td><?php echo html::input('sourceNote', $story->sourceNote, "class='form-control' autocomplete='off'");?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->status;?></th>
|
||||
|
||||
@@ -41,8 +41,8 @@
|
||||
ob_start();
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('story', 'change', "storyID=$story->id", $story);
|
||||
common::printIcon('story', 'review', "storyID=$story->id", $story);
|
||||
common::printIcon('story', 'change', "storyID=$story->id", $story);
|
||||
common::printIcon('story', 'review', "storyID=$story->id", $story);
|
||||
|
||||
if($story->status != 'closed' and !isonlybody())
|
||||
{
|
||||
@@ -51,8 +51,8 @@
|
||||
if(common::hasPriv('story', 'batchCreate')) echo html::a($link, "<i class='icon icon-branch'></i> " . $lang->story->subdivide, '', $misc);
|
||||
}
|
||||
|
||||
common::printIcon('story', 'close', "storyID=$story->id", $story, 'button', '', '', 'iframe text-danger', true);
|
||||
common::printIcon('story', 'activate', "storyID=$story->id", $story, 'button', '', '', 'iframe text-success', true);
|
||||
common::printIcon('story', 'close', "storyID=$story->id", $story, 'button', '', '', 'iframe text-danger', true);
|
||||
common::printIcon('story', 'activate', "storyID=$story->id", $story, 'button', '', '', 'iframe text-success', true);
|
||||
|
||||
if($this->config->global->flow != 'onlyStory' and !isonlybody() and (common::hasPriv('testcase', 'create') or common::hasPriv('testcase', 'batchCreate')))
|
||||
{
|
||||
@@ -64,7 +64,7 @@
|
||||
echo "<ul class='dropdown-menu' id='createCaseActionMenu'>";
|
||||
$misc = "data-toggle='modal' data-type='iframe' data-width='95%'";
|
||||
$link = $this->createLink('testcase', 'create', "productID=$story->product&branch=$story->branch&moduleID=0&from=¶m=0&storyID=$story->id", '', true);
|
||||
if(common::hasPriv('testcase', 'create')) echo "<li>" . html::a($link, $lang->testcase->create, '', $misc) . "</li>";
|
||||
if(common::hasPriv('testcase', 'create', $story)) echo "<li>" . html::a($link, $lang->testcase->create, '', $misc) . "</li>";
|
||||
$misc = "data-toggle='modal' data-type='iframe' data-width='95%'";
|
||||
$link = $this->createLink('testcase', 'batchCreate', "productID=$story->product&branch=$story->branch&moduleID=0&storyID=$story->id", '', true);
|
||||
if(common::hasPriv('testcase', 'batchCreate')) echo "<li>" . html::a($link, $lang->testcase->batchCreate, '', $misc) . "</li>";
|
||||
@@ -72,14 +72,14 @@
|
||||
echo "</div>";
|
||||
}
|
||||
|
||||
if($from == 'project') common::printIcon('task', 'create', "project=$param&storyID=$story->id&moduleID=$story->module", '', 'button', 'smile');
|
||||
if($from == 'project') common::printIcon('task', 'create', "project=$param&storyID=$story->id&moduleID=$story->module", $story, 'button', 'smile');
|
||||
echo '</div>';
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('story', 'edit', "storyID=$story->id");
|
||||
common::printCommentIcon('story');
|
||||
common::printIcon('story', 'create', "productID=$story->product&branch=$story->branch&moduleID=$story->module&storyID=$story->id", '', 'button', 'copy');
|
||||
common::printIcon('story', 'delete', "storyID=$story->id", '', 'button', '', 'hiddenwin');
|
||||
common::printIcon('story', 'edit', "storyID=$story->id", $story);
|
||||
common::printCommentIcon('story', $story);
|
||||
common::printIcon('story', 'create', "productID=$story->product&branch=$story->branch&moduleID=$story->module&storyID=$story->id", $story, 'button', 'copy');
|
||||
common::printIcon('story', 'delete', "storyID=$story->id", $story, 'button', '', 'hiddenwin');
|
||||
echo '</div>';
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
@@ -188,7 +188,11 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->source;?></th>
|
||||
<td id='source'><?php echo $lang->story->sourceList[$story->source] . ' ' . $story->sourceNote;?></td>
|
||||
<td id='source'><?php echo $lang->story->sourceList[$story->source];?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->sourceNote;?></th>
|
||||
<td><?php echo $story->sourceNote;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->status;?></th>
|
||||
@@ -350,7 +354,7 @@
|
||||
<td class='pd-0'>
|
||||
<ul class='list-unstyled'>
|
||||
<?php
|
||||
$linkStories = explode(',', $story->linkStories) ;
|
||||
$linkStories = explode(',', $story->linkStories) ;
|
||||
foreach($linkStories as $linkStoryID)
|
||||
{
|
||||
if(isset($story->extraStories[$linkStoryID])) echo '<li>' . html::a(inlink('view', "storyID=$linkStoryID"), "#$linkStoryID " . $story->extraStories[$linkStoryID]) . '</li>';
|
||||
@@ -364,7 +368,7 @@
|
||||
<td class='pd-0'>
|
||||
<ul class='list-unstyled'>
|
||||
<?php
|
||||
$childStories = explode(',', $story->childStories) ;
|
||||
$childStories = explode(',', $story->childStories) ;
|
||||
foreach($childStories as $childStoryID)
|
||||
{
|
||||
if(isset($story->extraStories[$childStoryID])) echo '<li>' . html::a(inlink('view', "storyID=$childStoryID"), "#$childStoryID " . $story->extraStories[$childStoryID]) . '</li>';
|
||||
|
||||
@@ -30,7 +30,7 @@ $config->task->editor->cancel = array('id' => 'comment', 'tools' => 'simpleToo
|
||||
$config->task->editor->pause = array('id' => 'comment', 'tools' => 'simpleTools');
|
||||
|
||||
$config->task->exportFields = '
|
||||
id, project, module, story,
|
||||
id, project, module, progess, story,
|
||||
name, desc,
|
||||
type, pri,estStarted, realStarted, deadline, status,estimate, consumed, left,
|
||||
mailto,
|
||||
|
||||
+28
-6
@@ -56,6 +56,7 @@ class task extends control
|
||||
$task->estStarted = '';
|
||||
$task->deadline = '';
|
||||
$task->mailto = '';
|
||||
$task->color = '';
|
||||
if($taskID > 0)
|
||||
{
|
||||
$task = $this->task->getByID($taskID);
|
||||
@@ -104,7 +105,7 @@ class task extends control
|
||||
$taskID = $taskID['id'];
|
||||
$actionID = $this->action->create('task', $taskID, 'Opened', '');
|
||||
$this->task->sendmail($taskID, $actionID);
|
||||
}
|
||||
}
|
||||
|
||||
/* If link from no head then reload*/
|
||||
if(isonlybody())
|
||||
@@ -167,9 +168,9 @@ class task extends control
|
||||
|
||||
/**
|
||||
* Batch create task.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param int $storyID
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param int $storyID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -487,8 +488,8 @@ class task extends control
|
||||
|
||||
/**
|
||||
* View a task.
|
||||
*
|
||||
* @param int $taskID
|
||||
*
|
||||
* @param int $taskID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -1150,6 +1151,27 @@ class task extends control
|
||||
$tasks = $this->dao->select('*')->from(TABLE_TASK)->alias('t1')->where($this->session->taskQueryCondition)
|
||||
->beginIF($this->post->exportType == 'selected')->andWhere('t1.id')->in($this->cookie->checkedItem)->fi()
|
||||
->orderBy($orderBy)->fetchAll('id');
|
||||
|
||||
foreach($tasks as $key => $task)
|
||||
{
|
||||
/* Compute task progess. */
|
||||
if($task->consumed == 0 and $task->left == 0)
|
||||
{
|
||||
$task->progess = 0;
|
||||
}
|
||||
elseif($task->consumed != 0 and $task->left == 0)
|
||||
{
|
||||
$task->progess = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
$task->progess = round($task->consumed / ($task->consumed + $task->left), 2) * 100;
|
||||
}
|
||||
|
||||
$task->progess .= '%';
|
||||
|
||||
$tasks[$key] = $task;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -38,7 +38,14 @@ function copyStoryTitle(num)
|
||||
startPosition = storyTitle.indexOf(':') + 1;
|
||||
endPosition = storyTitle.lastIndexOf('[');
|
||||
storyTitle = storyTitle.substr(startPosition, endPosition - startPosition);
|
||||
|
||||
$('#name\\[' + num + '\\]').val(storyTitle);
|
||||
$('#estimate\\[' + num + '\\]').val($('#storyEstimate' + num).val());
|
||||
$('#desc\\[' + num + '\\]').val($('#storyDesc' + num).val());
|
||||
|
||||
var storyPri = $('#storyPri' + num).val();
|
||||
if(storyPri == 0) $('#pri' + num ).val('3');
|
||||
if(storyPri != 0) $('#pri' + num ).val(storyPri);
|
||||
}
|
||||
|
||||
/* Set the story module. */
|
||||
@@ -47,11 +54,15 @@ function setStoryRelated(num)
|
||||
var storyID = $('#story' + num).val();
|
||||
if(storyID)
|
||||
{
|
||||
var link = createLink('story', 'ajaxGetModule', 'storyID=' + storyID);
|
||||
$.get(link, function(moduleID)
|
||||
var link = createLink('story', 'ajaxGetInfo', 'storyID=' + storyID);
|
||||
$.getJSON(link, function(storyInfo)
|
||||
{
|
||||
$('#module' + num).val(parseInt(moduleID));
|
||||
$('#module' + num).val(parseInt(storyInfo.moduleID));
|
||||
$('#module' + num).trigger("chosen:updated");
|
||||
|
||||
$('#storyEstimate' + num).val(storyInfo.estimate);
|
||||
$('#storyPri' + num).val(storyInfo.pri);
|
||||
$('#storyDesc' + num).val(storyInfo.spec);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,10 +40,10 @@ function setStoryModule()
|
||||
var storyID = $('#story').val();
|
||||
if(storyID)
|
||||
{
|
||||
var link = createLink('story', 'ajaxGetModule', 'storyID=' + storyID);
|
||||
$.get(link, function(moduleID)
|
||||
var link = createLink('story', 'ajaxGetInfo', 'storyID=' + storyID);
|
||||
$.getJSON(link, function(storyInfo)
|
||||
{
|
||||
$('#module').val(moduleID);
|
||||
$('#module').val(storyInfo.moduleID);
|
||||
$("#module").trigger("chosen:updated");
|
||||
});
|
||||
}
|
||||
@@ -88,7 +88,7 @@ function setAfter()
|
||||
}
|
||||
else
|
||||
{
|
||||
$('input[value="continueAdding"]').attr('checked', 'checked');
|
||||
if(!toTaskList) $('input[value="continueAdding"]').attr('checked', 'checked');
|
||||
$('input[value="continueAdding"]').attr('disabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
+13
-11
@@ -51,7 +51,7 @@ class taskModel extends model
|
||||
/* Check duplicate task. */
|
||||
if($task->type != 'affair')
|
||||
{
|
||||
$result = $this->loadModel('common')->removeDuplicate('task', $task, "project=$projectID");
|
||||
$result = $this->loadModel('common')->removeDuplicate('task', $task, "project=$projectID and story=$task->story");
|
||||
if($result['stop'])
|
||||
{
|
||||
$tasksID[$assignedTo] = array('status' => 'exists', 'id' => $result['duplicate']);
|
||||
@@ -98,8 +98,8 @@ class taskModel extends model
|
||||
|
||||
/**
|
||||
* Create a batch task.
|
||||
*
|
||||
* @param int $projectID
|
||||
*
|
||||
* @param int $projectID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -131,7 +131,7 @@ class taskModel extends model
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
{
|
||||
$story = $tasks->story[$i] == 'ditto' ? $story : $tasks->story[$i];
|
||||
$module = $tasks->module[$i] == 'ditto' ? $module : $tasks->module[$i];
|
||||
$module = $tasks->module[$i] == 'ditto' ? $module : $tasks->module[$i];
|
||||
$type = $tasks->type[$i] == 'ditto' ? $type : $tasks->type[$i];
|
||||
$assignedTo = $tasks->assignedTo[$i] == 'ditto' ? $assignedTo: $tasks->assignedTo[$i];
|
||||
|
||||
@@ -176,7 +176,7 @@ class taskModel extends model
|
||||
$taskID = $this->dao->lastInsertID();
|
||||
if($tasks->story[$i] != false) $this->story->setStage($tasks->story[$i]);
|
||||
$actionID = $this->action->create('task', $taskID, 'Opened', '');
|
||||
|
||||
|
||||
$mails[$i] = new stdclass();
|
||||
$mails[$i]->taskID = $taskID;
|
||||
$mails[$i]->actionID = $actionID;
|
||||
@@ -1215,25 +1215,25 @@ class taskModel extends model
|
||||
|
||||
/**
|
||||
* Process a task, judge it's status.
|
||||
*
|
||||
* @param object $task
|
||||
*
|
||||
* @param object $task
|
||||
* @access private
|
||||
* @return object
|
||||
*/
|
||||
public function processTask($task)
|
||||
{
|
||||
$today = helper::today();
|
||||
|
||||
|
||||
/* Delayed or not?. */
|
||||
if($task->status !== 'done' and $task->status !== 'cancel' and $task->status != 'closed')
|
||||
{
|
||||
if($task->deadline != '0000-00-00')
|
||||
{
|
||||
$delay = helper::diffDate($today, $task->deadline);
|
||||
if($delay > 0) $task->delay = $delay;
|
||||
}
|
||||
if($delay > 0) $task->delay = $delay;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Story changed or not. */
|
||||
$task->needConfirm = false;
|
||||
if($task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion) $task->needConfirm = true;
|
||||
@@ -1593,6 +1593,8 @@ class taskModel extends model
|
||||
{
|
||||
$action = strtolower($action);
|
||||
|
||||
if(!common::limitedUser($task, 'task')) return false;
|
||||
|
||||
if($action == 'assignto') return $task->status != 'closed' and $task->status != 'cancel';
|
||||
if($action == 'start') return $task->status == 'wait';
|
||||
if($action == 'restart') return $task->status == 'pause';
|
||||
|
||||
@@ -80,6 +80,7 @@ if($hiddenStory and isset($visibleFields['story'])) $colspan -= 1;
|
||||
<?php echo html::select("story[$i]", $stories, $currentStory, "class='form-control chosen' onchange='setStoryRelated($i)'");?>
|
||||
<span class='input-group-btn'>
|
||||
<a href='javascript:copyStoryTitle(<?php echo $i;?>)' class='btn' title='<?php echo $lang->task->copyStoryTitle; ?>'><i class='icon-angle-right'></i></a>
|
||||
<?php echo html::hidden("storyEstimate$i") . html::hidden("storyDesc$i") . html::hidden("storyPri$i");?>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<?php include '../../common/view/form.html.php';?>
|
||||
<?php include '../../common/view/datepicker.html.php';?>
|
||||
<?php include '../../common/view/kindeditor.html.php';?>
|
||||
<?php js::set('toTaskList',$this->config->global->flow == 'onlyTask' || !empty($task->id));?>
|
||||
<div class='container mw-1400px'>
|
||||
<div id='titlebar'>
|
||||
<div class='heading'>
|
||||
@@ -63,7 +64,7 @@
|
||||
<div class='row-table'>
|
||||
<div class='col-table'>
|
||||
<div class="input-group w-p100">
|
||||
<input type='hidden' id='color' name='color' data-provide='colorpicker' data-wrapper='input-group-btn fix-border-right' data-pull-menu-right='false' data-btn-tip='<?php echo $lang->task->colorTag ?>' data-update-text='#name'>
|
||||
<input type='hidden' id='color' name='color' data-provide='colorpicker' data-wrapper='input-group-btn fix-border-right' data-pull-menu-right='false' data-btn-tip='<?php echo $lang->task->colorTag ?>' data-update-text='#name' value='<?php echo $task->color;?>'>
|
||||
<?php echo html::input('name', $task->name, "class='form-control' autocomplete='off'");?>
|
||||
<?php if($this->config->global->flow != 'onlyTask'):?>
|
||||
<span class='input-group-btn'><a href='javascript:copyStoryTitle();' id='copyButton' class='btn'><?php echo $lang->task->copyStoryTitle;?></a></span>
|
||||
@@ -90,14 +91,14 @@
|
||||
<div class='input-group'>
|
||||
<span class='input-group-addon fix-border br-0'><?php echo $lang->task->pri;?></span>
|
||||
<?php if($hasCustomPri):?>
|
||||
<?php echo html::select('pri', $lang->task->priList, '', "class='form-control'");?>
|
||||
<?php echo html::select('pri', $lang->task->priList, $task->pri, "class='form-control'");?>
|
||||
<?php else: ?>
|
||||
<div class='input-group-btn dropdown-pris'>
|
||||
<button type='button' class='btn dropdown-toggle br-0' data-toggle='dropdown'>
|
||||
<span class='pri-text'></span> <span class='caret'></span>
|
||||
</button>
|
||||
<ul class='dropdown-menu pull-right'></ul>
|
||||
<?php echo html::select('pri', $lang->task->priList, '', "class='hide'");?>
|
||||
<?php echo html::select('pri', $lang->task->priList, $task->pri, "class='hide'");?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -108,7 +109,7 @@
|
||||
<div class='col-table' id='estRowCol'>
|
||||
<div class='input-group'>
|
||||
<span class='input-group-addon fix-border br-0'><?php echo $lang->task->estimateAB;?></span>
|
||||
<?php echo html::input('estimate', '', "class='form-control' placeholder='{$lang->task->hour}' autocomplete='off'");?>
|
||||
<?php echo html::input('estimate', $task->estimate, "class='form-control' placeholder='{$lang->task->hour}' autocomplete='off'");?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
@@ -165,7 +166,7 @@
|
||||
</tr>
|
||||
<tr <?php echo $this->config->global->flow == 'onlyTask' ? "class='hidden'" : '';?>>
|
||||
<th><?php echo $lang->task->afterSubmit;?></th>
|
||||
<td colspan='5'><?php echo html::radio('after', $lang->task->afterChoices, $this->config->global->flow == 'onlyTask' ? 'toTaskList' : 'continueAdding');?></td>
|
||||
<td colspan='5'><?php echo html::radio('after', $lang->task->afterChoices, $this->config->global->flow == 'onlyTask' || !empty($task->id) ? 'toTaskList' : 'continueAdding');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
|
||||
@@ -43,10 +43,10 @@
|
||||
echo '</div>';
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
common::printIcon('task', 'edit', "taskID=$task->id");
|
||||
common::printCommentIcon('task');
|
||||
common::printIcon('task', 'create', "productID=0&storyID=0&moduleID=0&taskID=$task->id", '', 'button', 'copy');
|
||||
common::printIcon('task', 'delete', "projectID=$task->project&taskID=$task->id", '', 'button', '', 'hiddenwin');
|
||||
common::printIcon('task', 'edit', "taskID=$task->id", $task);
|
||||
common::printCommentIcon('task', $task);
|
||||
common::printIcon('task', 'create', "productID=0&storyID=0&moduleID=0&taskID=$task->id", $task, 'button', 'copy');
|
||||
common::printIcon('task', 'delete', "projectID=$task->project&taskID=$task->id", $task, 'button', '', 'hiddenwin');
|
||||
echo '</div>';
|
||||
|
||||
echo "<div class='btn-group'>";
|
||||
|
||||
@@ -24,7 +24,7 @@ $config->testcase->exportFields = '
|
||||
lastEditedBy, lastEditedDate, version, linkCase';
|
||||
|
||||
$config->testcase->customCreateFields = 'story,stage,pri,keywords';
|
||||
$config->testcase->customBatchCreateFields = 'module,stage,story,pri,precondition,keywords';
|
||||
$config->testcase->customBatchCreateFields = 'module,stage,story,pri,precondition,keywords,review';
|
||||
$config->testcase->customBatchEditFields = 'module,story,stage,precondition,status,pri,keywords';
|
||||
|
||||
$config->testcase->custom = new stdclass();
|
||||
|
||||
+21
-17
@@ -42,14 +42,14 @@ class testcase extends control
|
||||
|
||||
/**
|
||||
* Browse cases.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param string $browseType
|
||||
* @param int $param
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
*
|
||||
* @param int $productID
|
||||
* @param string $browseType
|
||||
* @param int $param
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -265,6 +265,7 @@ class testcase extends control
|
||||
$precondition = '';
|
||||
$keywords = '';
|
||||
$steps = array();
|
||||
$color = '';
|
||||
|
||||
/* If testcaseID large than 0, use this testcase as template. */
|
||||
if($testcaseID > 0)
|
||||
@@ -279,8 +280,9 @@ class testcase extends control
|
||||
$precondition = $testcase->precondition;
|
||||
$keywords = $testcase->keywords;
|
||||
$steps = $testcase->steps;
|
||||
$color = $testcase->color;
|
||||
}
|
||||
|
||||
|
||||
/* If bugID large than 0, use this bug as template. */
|
||||
if($bugID > 0)
|
||||
{
|
||||
@@ -292,7 +294,7 @@ class testcase extends control
|
||||
$keywords = $bug->keywords;
|
||||
$steps = $this->testcase->createStepsFromBug($bug->steps);
|
||||
}
|
||||
|
||||
|
||||
/* Padding the steps to the default steps count. */
|
||||
if(count($steps) < $this->config->testcase->defaultSteps)
|
||||
{
|
||||
@@ -332,6 +334,7 @@ class testcase extends control
|
||||
$this->view->currentModuleID = $currentModuleID ? $currentModuleID : (isset($story->module) ? $story->module : 0);
|
||||
$this->view->stories = $stories;
|
||||
$this->view->caseTitle = $caseTitle;
|
||||
$this->view->color = $color;
|
||||
$this->view->type = $type;
|
||||
$this->view->stage = $stage;
|
||||
$this->view->pri = $pri;
|
||||
@@ -346,12 +349,12 @@ class testcase extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a batch test case.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $moduleID
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $moduleID
|
||||
* @param int $storyID
|
||||
* @access public
|
||||
* @return void
|
||||
@@ -418,6 +421,7 @@ class testcase extends control
|
||||
$this->view->currentModuleID = $currentModuleID;
|
||||
$this->view->branch = $branch;
|
||||
$this->view->branches = $this->loadModel('branch')->getPairs($productID);
|
||||
$this->view->needReview = $this->testcase->forceNotReview() == true ? 0 : 1;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -559,7 +563,7 @@ class testcase extends control
|
||||
$case->steps[] = $step;
|
||||
}
|
||||
|
||||
$isLibCase = ($case->lib and empty($case->product));
|
||||
$isLibCase = ($case->lib and empty($case->product));
|
||||
if($isLibCase)
|
||||
{
|
||||
$libraries = $this->loadModel('testsuite')->getLibraries();
|
||||
@@ -602,7 +606,7 @@ class testcase extends control
|
||||
$this->view->moduleOptionMenu = $moduleOptionMenu;
|
||||
$this->view->stories = $this->story->getProductStoryPairs($productID, $case->branch);
|
||||
}
|
||||
if(!$this->testcase->forceReview()) unset($this->lang->testcase->statusList['wait']);
|
||||
if($this->testcase->forceNotReview()) unset($this->lang->testcase->statusList['wait']);
|
||||
$position[] = $this->lang->testcase->common;
|
||||
$position[] = $this->lang->testcase->edit;
|
||||
|
||||
@@ -710,7 +714,7 @@ class testcase extends control
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->testcase->forceReview()) unset($this->lang->testcase->statusList['wait']);
|
||||
if(!$this->testcase->forceNotReview()) unset($this->lang->testcase->statusList['wait']);
|
||||
|
||||
/* Judge whether the editedTasks is too large and set session. */
|
||||
$countInputVars = count($cases) * (count(explode(',', $this->config->testcase->custom->batchEditFields)) + 3);
|
||||
|
||||
@@ -36,6 +36,7 @@ $lang->testcase->stage = 'Stage';
|
||||
$lang->testcase->reviewedBy = 'Reviewed By';
|
||||
$lang->testcase->reviewedDate = 'Reviewed Date';
|
||||
$lang->testcase->reviewResult = 'Review Result';
|
||||
$lang->testcase->forceNotReview = 'No Review';
|
||||
$lang->testcase->lastEditedByAB = 'Last Edited By';
|
||||
$lang->testcase->lastEditedDateAB = 'Last Edited on';
|
||||
$lang->testcase->lastEditedDate = 'Last Edited on';
|
||||
@@ -129,6 +130,9 @@ $lang->testcase->confirmBatchDelete = 'Do you want to batch delete thess Test Ca
|
||||
$lang->testcase->ditto = 'Ditto';
|
||||
$lang->testcase->dittoNotice = 'This Case does not belong to the Product as the previous one!';
|
||||
|
||||
$lang->testcase->reviewList[0] = 'NO';
|
||||
$lang->testcase->reviewList[1] = 'YES';
|
||||
|
||||
$lang->testcase->priList[3] = 3;
|
||||
$lang->testcase->priList[1] = 1;
|
||||
$lang->testcase->priList[2] = 2;
|
||||
|
||||
@@ -36,6 +36,7 @@ $lang->testcase->stage = '适用阶段';
|
||||
$lang->testcase->reviewedBy = '由谁评审';
|
||||
$lang->testcase->reviewedDate = '评审时间';
|
||||
$lang->testcase->reviewResult = '评审结果';
|
||||
$lang->testcase->forceNotReview = '不需要评审';
|
||||
$lang->testcase->lastEditedByAB = '修改者';
|
||||
$lang->testcase->lastEditedDateAB = '修改日期';
|
||||
$lang->testcase->lastEditedDate = '修改日期';
|
||||
@@ -112,11 +113,11 @@ $lang->testcase->allCases = '所有';
|
||||
$lang->testcase->needConfirm = '需求变动';
|
||||
$lang->testcase->bySearch = '搜索';
|
||||
|
||||
$lang->testcase->lblStory = '相关需求';
|
||||
$lang->testcase->lblLastEdited = '最后编辑';
|
||||
$lang->testcase->lblTypeValue = '类型可选值列表';
|
||||
$lang->testcase->lblStageValue = '阶段可选值列表';
|
||||
$lang->testcase->lblStatusValue = '状态可选值列表';
|
||||
$lang->testcase->lblStory = '相关需求';
|
||||
$lang->testcase->lblLastEdited = '最后编辑';
|
||||
$lang->testcase->lblTypeValue = '类型可选值列表';
|
||||
$lang->testcase->lblStageValue = '阶段可选值列表';
|
||||
$lang->testcase->lblStatusValue = '状态可选值列表';
|
||||
|
||||
$lang->testcase->legendBasicInfo = '基本信息';
|
||||
$lang->testcase->legendAttatch = '附件';
|
||||
@@ -129,6 +130,9 @@ $lang->testcase->confirmBatchDelete = '您确认要批量删除这些测试用
|
||||
$lang->testcase->ditto = '同上';
|
||||
$lang->testcase->dittoNotice = '该用例与上一用例不属于同一产品!';
|
||||
|
||||
$lang->testcase->reviewList[0] = '否';
|
||||
$lang->testcase->reviewList[1] = '是';
|
||||
|
||||
$lang->testcase->priList[3] = 3;
|
||||
$lang->testcase->priList[1] = 1;
|
||||
$lang->testcase->priList[2] = 2;
|
||||
|
||||
@@ -36,6 +36,7 @@ $lang->testcase->stage = '適用階段';
|
||||
$lang->testcase->reviewedBy = '由誰評審';
|
||||
$lang->testcase->reviewedDate = '評審時間';
|
||||
$lang->testcase->reviewResult = '評審結果';
|
||||
$lang->testcase->forceNotReview = '不需要評審';
|
||||
$lang->testcase->lastEditedByAB = '修改者';
|
||||
$lang->testcase->lastEditedDateAB = '修改日期';
|
||||
$lang->testcase->lastEditedDate = '修改日期';
|
||||
@@ -129,6 +130,9 @@ $lang->testcase->confirmBatchDelete = '您確認要批量刪除這些測試用
|
||||
$lang->testcase->ditto = '同上';
|
||||
$lang->testcase->dittoNotice = '該用例與上一用例不屬於同一產品!';
|
||||
|
||||
$lang->testcase->reviewList[0] = '否';
|
||||
$lang->testcase->reviewList[1] = '是';
|
||||
|
||||
$lang->testcase->priList[3] = 3;
|
||||
$lang->testcase->priList[1] = 1;
|
||||
$lang->testcase->priList[2] = 2;
|
||||
|
||||
+28
-25
@@ -73,7 +73,7 @@ class testcaseModel extends model
|
||||
|
||||
/**
|
||||
* Create a case.
|
||||
*
|
||||
*
|
||||
* @param int $bugID
|
||||
* @access public
|
||||
* @return void
|
||||
@@ -84,11 +84,11 @@ class testcaseModel extends model
|
||||
$case = fixer::input('post')
|
||||
->add('openedBy', $this->app->user->account)
|
||||
->add('openedDate', $now)
|
||||
->add('status', $this->forceReview() ? 'wait' : 'normal')
|
||||
->add('status', $this->forceNotReview() || $this->post->forceNotReview ? 'normal' : 'wait')
|
||||
->add('version', 1)
|
||||
->add('fromBug', $bugID)
|
||||
->setIF($this->post->story != false, 'storyVersion', $this->loadModel('story')->getVersion((int)$this->post->story))
|
||||
->remove('steps,expects,files,labels,stepType')
|
||||
->remove('steps,expects,files,labels,stepType,forceNotReview')
|
||||
->setDefault('story', 0)
|
||||
->join('stage', ',')
|
||||
->get();
|
||||
@@ -125,12 +125,12 @@ class testcaseModel extends model
|
||||
return array('status' => 'created', 'id' => $caseID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Batch create cases.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $storyID
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int $storyID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -160,14 +160,14 @@ class testcaseModel extends model
|
||||
$type = $cases->type[$i] == 'ditto' ? $type : $cases->type[$i];
|
||||
$pri = $cases->pri[$i] == 'ditto' ? $pri : $cases->pri[$i];
|
||||
$cases->module[$i] = (int)$module;
|
||||
$cases->story[$i] = (int)$story;
|
||||
$cases->story[$i] = (int)$story;
|
||||
$cases->type[$i] = $type;
|
||||
$cases->pri[$i] = $pri;
|
||||
}
|
||||
|
||||
$this->loadModel('story');
|
||||
$storyVersions = array();
|
||||
$forceReview = $this->forceReview();
|
||||
$forceNotReview = $this->forceNotReview();
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
{
|
||||
if($cases->type[$i] != '' and $cases->title[$i] != '')
|
||||
@@ -186,7 +186,7 @@ class testcaseModel extends model
|
||||
$data[$i]->keywords = $cases->keywords[$i];
|
||||
$data[$i]->openedBy = $this->app->user->account;
|
||||
$data[$i]->openedDate = $now;
|
||||
$data[$i]->status = $forceReview ? 'wait' : 'normal';
|
||||
$data[$i]->status = $forceNotReview || $cases->needReview[$i] == 0 ? 'normal' : 'wait';
|
||||
$data[$i]->version = 1;
|
||||
|
||||
$caseStory = $data[$i]->story;
|
||||
@@ -522,7 +522,7 @@ class testcaseModel extends model
|
||||
$steps = array();
|
||||
|
||||
//---------------- Judge steps changed or not.-------------------- */
|
||||
|
||||
|
||||
/* Remove the empty setps in post. */
|
||||
foreach($this->post->steps as $key => $desc)
|
||||
{
|
||||
@@ -558,7 +558,7 @@ class testcaseModel extends model
|
||||
->join('stage', ',')
|
||||
->remove('comment,steps,expects,files,labels,stepType')
|
||||
->get();
|
||||
if($this->forceReview() and $stepChanged) $case->status = 'wait';
|
||||
if(!$this->forceNotReview() and $stepChanged) $case->status = 'wait';
|
||||
$this->dao->update(TABLE_CASE)->data($case)->autoCheck()->batchCheck($this->config->testcase->edit->requiredFields, 'notempty')->where('id')->eq((int)$caseID)->exec();
|
||||
if(!$this->dao->isError())
|
||||
{
|
||||
@@ -932,6 +932,8 @@ class testcaseModel extends model
|
||||
{
|
||||
$action = strtolower($action);
|
||||
|
||||
if(!common::limitedUser($case)) return false;
|
||||
|
||||
if($action == 'createbug') return $case->caseFails > 0;
|
||||
if($action == 'review') return $case->status == 'wait';
|
||||
|
||||
@@ -997,7 +999,7 @@ class testcaseModel extends model
|
||||
$cases[$key] =$caseData;
|
||||
}
|
||||
|
||||
$forceReview = $this->forceReview();
|
||||
$forceNotReview = $this->forceNotReview();
|
||||
foreach($cases as $key => $caseData)
|
||||
{
|
||||
$caseID = 0;
|
||||
@@ -1059,7 +1061,7 @@ class testcaseModel extends model
|
||||
{
|
||||
$caseData->lastEditedBy = $this->app->user->account;
|
||||
$caseData->lastEditedDate = $now;
|
||||
if($stepChanged and $forceReview) $caseData->status = 'wait';
|
||||
if($stepChanged and !$forceNotReview) $caseData->status = 'wait';
|
||||
$this->dao->update(TABLE_CASE)->data($caseData)->where('id')->eq($caseID)->autoCheck()->exec();
|
||||
if($stepChanged)
|
||||
{
|
||||
@@ -1094,7 +1096,7 @@ class testcaseModel extends model
|
||||
$caseData->openedDate = $now;
|
||||
$caseData->branch = isset($data->branch[$key]) ? $data->branch[$key] : $branch;
|
||||
if($caseData->story) $caseData->storyVersion = zget($storyVersionPairs, $caseData->story, 1);
|
||||
$caseData->status = $forceReview ? 'wait' : 'normal';
|
||||
$caseData->status = !$forceNotReview ? 'wait' : 'normal';
|
||||
$this->dao->insert(TABLE_CASE)->data($caseData)->autoCheck()->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
@@ -1224,11 +1226,11 @@ class testcaseModel extends model
|
||||
|
||||
/**
|
||||
* Print cell data
|
||||
*
|
||||
* @param object $col
|
||||
* @param object $case
|
||||
* @param array $users
|
||||
* @param array $branches
|
||||
*
|
||||
* @param object $col
|
||||
* @param object $case
|
||||
* @param array $users
|
||||
* @param array $branches
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -1393,15 +1395,16 @@ class testcaseModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether force review
|
||||
*
|
||||
* Check whether force not review
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function forceReview()
|
||||
public function forceNotReview()
|
||||
{
|
||||
if($this->config->testcase->needReview) return true;
|
||||
if(strpos(",{$this->config->testcase->forceReview},", ",{$this->app->user->account},") !== false) return true;
|
||||
if(!$this->config->testcase->needReview && strpos(",{$this->config->testcase->forceReview},", ",{$this->app->user->account},") === false) return true;
|
||||
if($this->config->testcase->needReview && strpos(",{$this->config->testcase->forceNotReview},", ",{$this->app->user->account},")) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ if($hiddenStory and isset($visibleFields['story'])) $colspan -= 1;
|
||||
<th class='w-150px<?php echo zget($visibleFields, 'precondition', ' hidden')?>'><?php echo $lang->testcase->precondition;?></th>
|
||||
<th class='w-100px<?php echo zget($visibleFields, 'keywords', ' hidden')?>'> <?php echo $lang->testcase->keywords;?></th>
|
||||
<th class='w-200px<?php echo zget($visibleFields, 'stage', ' hidden')?>'> <?php echo $lang->testcase->stage;?></th>
|
||||
<th class='w-70px<?php echo zget($visibleFields, 'review', ' hidden')?>'> <?php echo $lang->testcase->review;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -83,6 +84,7 @@ if($hiddenStory and isset($visibleFields['story'])) $colspan -= 1;
|
||||
<td class='<?php echo zget($visibleFields, 'precondition', 'hidden')?>'><?php echo html::textarea("precondition[$i]", '', "rows='1' class='form-control autosize'")?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'> <?php echo html::input("keywords[$i]", '', "class='form-control' autocomplete='off'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'stage', ' hidden')?>' style='overflow:visible'><?php echo html::select("stage[$i][]", $lang->testcase->stageList, '', "class='form-control chosen' multiple");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'review', 'hidden')?>'><?php echo html::select("needReview[$i]", $lang->testcase->reviewList, $needReview, "class='form-control'");?></td>
|
||||
</tr>
|
||||
<?php endfor;?>
|
||||
<tfoot>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user