Merge branch 'master' of https://git.zcorp.cc/easycorp/zentaopms
This commit is contained in:
@@ -927,12 +927,8 @@ class baseControl
|
||||
}
|
||||
|
||||
if(empty($this->output)) $this->parse($moduleName, $methodName);
|
||||
$trace = '';
|
||||
if($this->config->debug && $this->config->debug >= 2)
|
||||
{
|
||||
$trace = $this->app->loadClass('trace')->output();
|
||||
}
|
||||
echo $this->output . $trace;
|
||||
|
||||
echo $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,12 +12,6 @@ declare(strict_types=1);
|
||||
|
||||
class trace
|
||||
{
|
||||
protected $types = array(
|
||||
'Request' => '请求',
|
||||
'Files' => '文件',
|
||||
'SQL Query' => 'SQL 查询',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@@ -34,6 +28,12 @@ class trace
|
||||
$this->dao = $dao;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求信息。
|
||||
* Get request info.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getRequestInfo()
|
||||
{
|
||||
$this->trace['request'] = array(
|
||||
@@ -69,7 +69,7 @@ class trace
|
||||
*/
|
||||
public function getRequestSqls()
|
||||
{
|
||||
$this->trace['sqlQuery'] = dao::$querys;
|
||||
$this->trace['sqlQuery'] = dao::$querys;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,78 +100,6 @@ class trace
|
||||
return $this->trace;
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
$this->getTrace();
|
||||
$lines = '';
|
||||
foreach($this->trace as $type => $content)
|
||||
{
|
||||
$lines .= $this->console($type, empty($content) ? array() : $content);
|
||||
}
|
||||
|
||||
$lines .= $this->printSQLProfile();
|
||||
|
||||
$js = <<<JS
|
||||
|
||||
<script type='text/javascript'>
|
||||
{$lines}
|
||||
</script>
|
||||
JS;
|
||||
return $js;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接需要输出到 console 的内容。
|
||||
* Concat the content to output to console.
|
||||
*
|
||||
* @param string $type
|
||||
* @param array $content
|
||||
* @return string
|
||||
*/
|
||||
protected function console(string $type, $content)
|
||||
{
|
||||
$traceTabs = array_keys($this->types);
|
||||
$line = array();
|
||||
$line[] = $type == $traceTabs[0] ? "console.group('{$type}');" : "console.groupCollapsed('{$type}');";
|
||||
|
||||
foreach((array) $content as $key => $item)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'SQL Query':
|
||||
$msg = str_replace("\n", '\n', addslashes($item));
|
||||
$style = "color:#009bb4;";
|
||||
$line[] = "console.log(\"%c{$msg}\", \"{$style}\");";
|
||||
break;
|
||||
default:
|
||||
$item = is_string($key) ? $key . ' ' . $item : $key + 1 . ' ' . $item;
|
||||
$msg = json_encode($item);
|
||||
$line[] = "console.log({$msg});";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$line[] = "console.groupEnd();";
|
||||
return implode(PHP_EOL, $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接 SQL Profile。
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function printSQLProfile()
|
||||
{
|
||||
$lines = array();
|
||||
|
||||
$profiling = $this->dao->dbh->query('SHOW PROFILES')->fetchAll(PDO::FETCH_ASSOC);
|
||||
if(empty($profiling)) return '';
|
||||
|
||||
$lines[] = 'console.groupCollapsed("SQL Profile")';
|
||||
$lines[] = 'console.table(' . json_encode($profiling) . ')';
|
||||
$lines[] = 'console.groupEnd()';
|
||||
|
||||
return implode(PHP_EOL, $lines);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return json_encode($this->getTrace());
|
||||
|
||||
+2
-310
@@ -62,316 +62,6 @@ $config->bug->editor->activate = array('id' => 'comment', 'tools' => 'bugTools
|
||||
|
||||
$config->bug->discardedTypes = array('interface', 'designchange', 'newfeature', 'trackthings');
|
||||
|
||||
global $lang;
|
||||
$config->bug->search['module'] = 'bug';
|
||||
$config->bug->search['fields']['title'] = $lang->bug->title;
|
||||
$config->bug->search['fields']['module'] = $lang->bug->module;
|
||||
$config->bug->search['fields']['keywords'] = $lang->bug->keywords;
|
||||
$config->bug->search['fields']['steps'] = $lang->bug->steps;
|
||||
$config->bug->search['fields']['assignedTo'] = $lang->bug->assignedTo;
|
||||
$config->bug->search['fields']['resolvedBy'] = $lang->bug->resolvedBy;
|
||||
|
||||
$config->bug->search['fields']['status'] = $lang->bug->status;
|
||||
$config->bug->search['fields']['confirmed'] = $lang->bug->confirmed;
|
||||
$config->bug->search['fields']['story'] = $lang->bug->story;
|
||||
|
||||
$config->bug->search['fields']['project'] = $lang->bug->project;
|
||||
$config->bug->search['fields']['product'] = $lang->bug->product;
|
||||
$config->bug->search['fields']['branch'] = '';
|
||||
$config->bug->search['fields']['plan'] = $lang->bug->productplan;
|
||||
$config->bug->search['fields']['id'] = $lang->bug->id;
|
||||
$config->bug->search['fields']['execution'] = $lang->bug->execution;
|
||||
|
||||
$config->bug->search['fields']['severity'] = $lang->bug->severity;
|
||||
$config->bug->search['fields']['pri'] = $lang->bug->pri;
|
||||
$config->bug->search['fields']['type'] = $lang->bug->type;
|
||||
$config->bug->search['fields']['os'] = $lang->bug->os;
|
||||
$config->bug->search['fields']['browser'] = $lang->bug->browser;
|
||||
$config->bug->search['fields']['resolution'] = $lang->bug->resolution;
|
||||
|
||||
$config->bug->search['fields']['activatedCount'] = $lang->bug->activatedCount;
|
||||
|
||||
$config->bug->search['fields']['toTask'] = $lang->bug->toTask;
|
||||
$config->bug->search['fields']['toStory'] = $lang->bug->toStory;
|
||||
|
||||
$config->bug->search['fields']['openedBy'] = $lang->bug->openedBy;
|
||||
$config->bug->search['fields']['closedBy'] = $lang->bug->closedBy;
|
||||
$config->bug->search['fields']['lastEditedBy'] = $lang->bug->lastEditedByAB;
|
||||
|
||||
$config->bug->search['fields']['mailto'] = $lang->bug->mailto;
|
||||
|
||||
$config->bug->search['fields']['openedBuild'] = $lang->bug->openedBuild;
|
||||
$config->bug->search['fields']['resolvedBuild'] = $lang->bug->resolvedBuild;
|
||||
|
||||
$config->bug->search['fields']['openedDate'] = $lang->bug->openedDate;
|
||||
$config->bug->search['fields']['assignedDate'] = $lang->bug->assignedDate;
|
||||
$config->bug->search['fields']['resolvedDate'] = $lang->bug->resolvedDate;
|
||||
$config->bug->search['fields']['closedDate'] = $lang->bug->closedDate;
|
||||
$config->bug->search['fields']['lastEditedDate'] = $lang->bug->lastEditedDateAB;
|
||||
$config->bug->search['fields']['deadline'] = $lang->bug->deadline;
|
||||
$config->bug->search['fields']['activatedDate'] = $lang->bug->activatedDate;
|
||||
|
||||
$config->bug->search['params']['title'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['keywords'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['steps'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['assignedTo'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->bug->search['params']['resolvedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
|
||||
$config->bug->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->statusList);
|
||||
$config->bug->search['params']['confirmed'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->confirmedList);
|
||||
$config->bug->search['params']['story'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
|
||||
$config->bug->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->bug->search['params']['product'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->bug->search['params']['branch'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->bug->search['params']['plan'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->bug->search['params']['module'] = array('operator' => 'belong', 'control' => 'select', 'values' => 'modules');
|
||||
$config->bug->search['params']['execution'] = array('operator' => '=', 'control' => 'select', 'values' => 'executions');
|
||||
$config->bug->search['params']['severity'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->severityList);
|
||||
$config->bug->search['params']['pri'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->priList);
|
||||
$config->bug->search['params']['type'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->typeList);
|
||||
$config->bug->search['params']['os'] = array('operator' => 'include', 'control' => 'select', 'values' => $lang->bug->osList);
|
||||
$config->bug->search['params']['browser'] = array('operator' => 'include', 'control' => 'select', 'values' => $lang->bug->browserList);
|
||||
$config->bug->search['params']['resolution'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->resolutionList);
|
||||
$config->bug->search['params']['activatedCount']= array('operator' => '>=', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['toTask'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['toStory'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['openedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->bug->search['params']['closedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->bug->search['params']['lastEditedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->bug->search['params']['mailto'] = array('operator' => 'include', 'control' => 'select', 'values' => 'users');
|
||||
$config->bug->search['params']['openedBuild'] = array('operator' => 'include', 'control' => 'select', 'values' => 'builds');
|
||||
$config->bug->search['params']['resolvedBuild'] = array('operator' => '=', 'control' => 'select', 'values' => 'builds');
|
||||
$config->bug->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['resolvedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['lastEditedDate']= array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['deadline'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
|
||||
$config->bug->datatable = new stdclass();
|
||||
$config->bug->datatable->defaultField = array('id', 'title', 'severity', 'pri', 'status', 'openedBy', 'openedDate', 'confirmed', 'assignedTo', 'resolution', 'actions');
|
||||
|
||||
$config->bug->datatable->fieldList['id']['title'] = 'idAB';
|
||||
$config->bug->datatable->fieldList['id']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['id']['width'] = '70';
|
||||
$config->bug->datatable->fieldList['id']['required'] = 'yes';
|
||||
|
||||
$config->bug->datatable->fieldList['product']['title'] = 'product';
|
||||
$config->bug->datatable->fieldList['product']['control'] = 'hidden';
|
||||
$config->bug->datatable->fieldList['product']['dataSource'] = array('module' => 'product', 'method' => 'getPairs', 'params' => '&0&&all');
|
||||
|
||||
$config->bug->datatable->fieldList['module']['control'] = 'select';
|
||||
$config->bug->datatable->fieldList['module']['title'] = 'module';
|
||||
$config->bug->datatable->fieldList['module']['dataSource'] = array('module' => 'tree', 'method' => 'getOptionMenu', 'params' => '$productID&bug&0&all');
|
||||
|
||||
$config->bug->datatable->fieldList['title']['title'] = 'title';
|
||||
$config->bug->datatable->fieldList['title']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['title']['width'] = 'auto';
|
||||
$config->bug->datatable->fieldList['title']['required'] = 'yes';
|
||||
$config->bug->datatable->fieldList['title']['minWidth'] = '200';
|
||||
|
||||
$config->bug->datatable->fieldList['severity']['title'] = 'severityAB';
|
||||
$config->bug->datatable->fieldList['severity']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['severity']['width'] = '50';
|
||||
$config->bug->datatable->fieldList['severity']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['severity']['name'] = $lang->bug->severity;
|
||||
|
||||
$config->bug->datatable->fieldList['pri']['title'] = 'P';
|
||||
$config->bug->datatable->fieldList['pri']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['pri']['width'] = '50';
|
||||
$config->bug->datatable->fieldList['pri']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['pri']['name'] = $lang->bug->pri;
|
||||
|
||||
$config->bug->datatable->fieldList['confirmed']['title'] = 'confirmedAB';
|
||||
$config->bug->datatable->fieldList['confirmed']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['confirmed']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['confirmed']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['title']['title'] = 'title';
|
||||
$config->bug->datatable->fieldList['title']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['title']['width'] = 'auto';
|
||||
$config->bug->datatable->fieldList['title']['required'] = 'yes';
|
||||
$config->bug->datatable->fieldList['title']['minWidth'] = '200';
|
||||
|
||||
$config->bug->datatable->fieldList['status']['title'] = 'statusAB';
|
||||
$config->bug->datatable->fieldList['status']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['status']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['status']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['branch']['title'] = 'branch';
|
||||
$config->bug->datatable->fieldList['branch']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['branch']['width'] = '100';
|
||||
$config->bug->datatable->fieldList['branch']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['branch']['control'] = 'select';
|
||||
$config->bug->datatable->fieldList['branch']['dataSource'] = array('module' => 'branch', 'method' => 'getPairs', 'params' => '$productID');
|
||||
|
||||
$config->bug->datatable->fieldList['type']['title'] = 'type';
|
||||
$config->bug->datatable->fieldList['type']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['type']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['type']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['project']['title'] = 'project';
|
||||
$config->bug->datatable->fieldList['project']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['project']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['project']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['project']['control'] = 'hidden';
|
||||
$config->bug->datatable->fieldList['project']['dataSource'] = array('module' => 'product', 'method' => 'getProjectPairsByProduct', 'params' => '$productID&');
|
||||
|
||||
$config->bug->datatable->fieldList['execution']['title'] = 'execution';
|
||||
$config->bug->datatable->fieldList['execution']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['execution']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['execution']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['execution']['dataSource'] = array('module' => 'product', 'method' =>'getAllExecutionPairsByProduct', 'params' => '$productID&$branch&0&stagefilter');
|
||||
|
||||
$config->bug->datatable->fieldList['plan']['title'] = 'plan';
|
||||
$config->bug->datatable->fieldList['plan']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['plan']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['plan']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['openedBy']['title'] = 'openedByAB';
|
||||
$config->bug->datatable->fieldList['openedBy']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['openedBy']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['openedBy']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['openedDate']['title'] = 'openedDateAB';
|
||||
$config->bug->datatable->fieldList['openedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['openedDate']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['openedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['openedBuild']['title'] = 'openedBuild';
|
||||
$config->bug->datatable->fieldList['openedBuild']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['openedBuild']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['openedBuild']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['openedBuild']['control'] = 'multiple';
|
||||
$config->bug->datatable->fieldList['openedBuild']['dataSource'] = array('module' => 'build', 'method' =>'getBuildPairs', 'params' => '$productID&$branch&noempty,noterminate,nodone,withbranch');
|
||||
|
||||
$config->bug->datatable->fieldList['confirmed']['title'] = 'confirmedAB';
|
||||
$config->bug->datatable->fieldList['confirmed']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['confirmed']['width'] = '100';
|
||||
$config->bug->datatable->fieldList['confirmed']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['assignedTo']['title'] = 'assignedToAB';
|
||||
$config->bug->datatable->fieldList['assignedTo']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['assignedTo']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['assignedTo']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['assignedTo']['dataSource'] = array('module' => 'user', 'method' =>'getPairs', 'params' => 'noclosed|noletter');
|
||||
|
||||
$config->bug->datatable->fieldList['assignedDate']['title'] = 'assignedDate';
|
||||
$config->bug->datatable->fieldList['assignedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['assignedDate']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['assignedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['deadline']['title'] = 'deadline';
|
||||
$config->bug->datatable->fieldList['deadline']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['deadline']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['deadline']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['deadline']['control'] = 'date';
|
||||
|
||||
$config->bug->datatable->fieldList['resolvedBy']['title'] = 'resolvedBy';
|
||||
$config->bug->datatable->fieldList['resolvedBy']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['resolvedBy']['width'] = '100';
|
||||
$config->bug->datatable->fieldList['resolvedBy']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['resolution']['title'] = 'resolutionAB';
|
||||
$config->bug->datatable->fieldList['resolution']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['resolution']['width'] = '110';
|
||||
$config->bug->datatable->fieldList['resolution']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['resolvedDate']['title'] = 'resolvedDateAB';
|
||||
$config->bug->datatable->fieldList['resolvedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['resolvedDate']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['resolvedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['title'] = 'resolvedBuild';
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['control'] = 'select';
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['dataSource'] = array('module' => 'bug', 'method' =>'getRelatedObjects', 'params' => 'resolvedBuild&id,name');
|
||||
|
||||
$config->bug->datatable->fieldList['activatedCount']['title'] = 'activatedCountAB';
|
||||
$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['story']['title'] = 'story';
|
||||
$config->bug->datatable->fieldList['story']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['story']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['story']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['story']['control'] = 'select';
|
||||
$config->bug->datatable->fieldList['story']['dataSource'] = array('module' => 'story', 'method' =>'getProductStoryPairs', 'params' => '$productID');
|
||||
|
||||
$config->bug->datatable->fieldList['task']['title'] = 'task';
|
||||
$config->bug->datatable->fieldList['task']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['task']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['task']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['task']['dataSource'] = array('module' => 'bug', 'method' =>'getRelatedObjects', 'params' => 'task&id,name');
|
||||
|
||||
$config->bug->datatable->fieldList['toTask']['title'] = 'toTask';
|
||||
$config->bug->datatable->fieldList['toTask']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['toTask']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['toTask']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['keywords']['title'] = 'keywords';
|
||||
$config->bug->datatable->fieldList['keywords']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['keywords']['width'] = '100';
|
||||
$config->bug->datatable->fieldList['keywords']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['os']['title'] = 'os';
|
||||
$config->bug->datatable->fieldList['os']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['os']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['os']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['os']['control'] = 'multiple';
|
||||
|
||||
$config->bug->datatable->fieldList['browser']['title'] = 'browser';
|
||||
$config->bug->datatable->fieldList['browser']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['browser']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['browser']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['browser']['control'] = 'multiple';
|
||||
|
||||
$config->bug->datatable->fieldList['mailto']['title'] = 'mailto';
|
||||
$config->bug->datatable->fieldList['mailto']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['mailto']['width'] = '100';
|
||||
$config->bug->datatable->fieldList['mailto']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['closedBy']['title'] = 'closedBy';
|
||||
$config->bug->datatable->fieldList['closedBy']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['closedBy']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['closedBy']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['closedDate']['title'] = 'closedDate';
|
||||
$config->bug->datatable->fieldList['closedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['closedDate']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['closedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['lastEditedBy']['title'] = 'lastEditedBy';
|
||||
$config->bug->datatable->fieldList['lastEditedBy']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['lastEditedBy']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['lastEditedBy']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['lastEditedDate']['title'] = 'lastEditedDateAB';
|
||||
$config->bug->datatable->fieldList['lastEditedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['lastEditedDate']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['lastEditedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['actions']['title'] = 'actions';
|
||||
$config->bug->datatable->fieldList['actions']['fixed'] = 'right';
|
||||
$config->bug->datatable->fieldList['actions']['width'] = '150';
|
||||
$config->bug->datatable->fieldList['actions']['required'] = 'yes';
|
||||
|
||||
$config->bug->datatable->fieldList['steps']['title'] = 'steps';
|
||||
$config->bug->datatable->fieldList['steps']['control'] = 'textarea';
|
||||
|
||||
$config->bug->datatable->fieldList['case']['title'] = 'case';
|
||||
$config->bug->datatable->fieldList['case']['dataSource'] = array('module' => 'bug', 'method' =>'getRelatedObjects', 'params' => 'case&id,title');
|
||||
|
||||
$config->bug->colorList = new stdclass();
|
||||
$config->bug->colorList->pri[0] = '#c0c0c0';
|
||||
$config->bug->colorList->pri[1] = '#d50000';
|
||||
@@ -390,3 +80,5 @@ $config->bug->colorList->severity[6] = '#B6B4B4';
|
||||
$config->bug->colorList->severity[7] = '#BDBEBD';
|
||||
|
||||
include 'config/form.php';
|
||||
include 'config/table.php';
|
||||
include 'config/search.php';
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
global $lang;
|
||||
$config->bug->search['module'] = 'bug';
|
||||
$config->bug->search['fields']['title'] = $lang->bug->title;
|
||||
$config->bug->search['fields']['module'] = $lang->bug->module;
|
||||
$config->bug->search['fields']['keywords'] = $lang->bug->keywords;
|
||||
$config->bug->search['fields']['steps'] = $lang->bug->steps;
|
||||
$config->bug->search['fields']['assignedTo'] = $lang->bug->assignedTo;
|
||||
$config->bug->search['fields']['resolvedBy'] = $lang->bug->resolvedBy;
|
||||
|
||||
$config->bug->search['fields']['status'] = $lang->bug->status;
|
||||
$config->bug->search['fields']['confirmed'] = $lang->bug->confirmed;
|
||||
$config->bug->search['fields']['story'] = $lang->bug->story;
|
||||
|
||||
$config->bug->search['fields']['project'] = $lang->bug->project;
|
||||
$config->bug->search['fields']['product'] = $lang->bug->product;
|
||||
$config->bug->search['fields']['branch'] = '';
|
||||
$config->bug->search['fields']['plan'] = $lang->bug->productplan;
|
||||
$config->bug->search['fields']['id'] = $lang->bug->id;
|
||||
$config->bug->search['fields']['execution'] = $lang->bug->execution;
|
||||
|
||||
$config->bug->search['fields']['severity'] = $lang->bug->severity;
|
||||
$config->bug->search['fields']['pri'] = $lang->bug->pri;
|
||||
$config->bug->search['fields']['type'] = $lang->bug->type;
|
||||
$config->bug->search['fields']['os'] = $lang->bug->os;
|
||||
$config->bug->search['fields']['browser'] = $lang->bug->browser;
|
||||
$config->bug->search['fields']['resolution'] = $lang->bug->resolution;
|
||||
|
||||
$config->bug->search['fields']['activatedCount'] = $lang->bug->activatedCount;
|
||||
|
||||
$config->bug->search['fields']['toTask'] = $lang->bug->toTask;
|
||||
$config->bug->search['fields']['toStory'] = $lang->bug->toStory;
|
||||
|
||||
$config->bug->search['fields']['openedBy'] = $lang->bug->openedBy;
|
||||
$config->bug->search['fields']['closedBy'] = $lang->bug->closedBy;
|
||||
$config->bug->search['fields']['lastEditedBy'] = $lang->bug->lastEditedByAB;
|
||||
|
||||
$config->bug->search['fields']['mailto'] = $lang->bug->mailto;
|
||||
|
||||
$config->bug->search['fields']['openedBuild'] = $lang->bug->openedBuild;
|
||||
$config->bug->search['fields']['resolvedBuild'] = $lang->bug->resolvedBuild;
|
||||
|
||||
$config->bug->search['fields']['openedDate'] = $lang->bug->openedDate;
|
||||
$config->bug->search['fields']['assignedDate'] = $lang->bug->assignedDate;
|
||||
$config->bug->search['fields']['resolvedDate'] = $lang->bug->resolvedDate;
|
||||
$config->bug->search['fields']['closedDate'] = $lang->bug->closedDate;
|
||||
$config->bug->search['fields']['lastEditedDate'] = $lang->bug->lastEditedDateAB;
|
||||
$config->bug->search['fields']['deadline'] = $lang->bug->deadline;
|
||||
$config->bug->search['fields']['activatedDate'] = $lang->bug->activatedDate;
|
||||
|
||||
$config->bug->search['params']['title'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['keywords'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['steps'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['assignedTo'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->bug->search['params']['resolvedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
|
||||
$config->bug->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->statusList);
|
||||
$config->bug->search['params']['confirmed'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->confirmedList);
|
||||
$config->bug->search['params']['story'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
|
||||
$config->bug->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->bug->search['params']['product'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->bug->search['params']['branch'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->bug->search['params']['plan'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->bug->search['params']['module'] = array('operator' => 'belong', 'control' => 'select', 'values' => 'modules');
|
||||
$config->bug->search['params']['execution'] = array('operator' => '=', 'control' => 'select', 'values' => 'executions');
|
||||
$config->bug->search['params']['severity'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->severityList);
|
||||
$config->bug->search['params']['pri'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->priList);
|
||||
$config->bug->search['params']['type'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->typeList);
|
||||
$config->bug->search['params']['os'] = array('operator' => 'include', 'control' => 'select', 'values' => $lang->bug->osList);
|
||||
$config->bug->search['params']['browser'] = array('operator' => 'include', 'control' => 'select', 'values' => $lang->bug->browserList);
|
||||
$config->bug->search['params']['resolution'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->resolutionList);
|
||||
$config->bug->search['params']['activatedCount']= array('operator' => '>=', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['toTask'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['toStory'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
$config->bug->search['params']['openedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->bug->search['params']['closedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->bug->search['params']['lastEditedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->bug->search['params']['mailto'] = array('operator' => 'include', 'control' => 'select', 'values' => 'users');
|
||||
$config->bug->search['params']['openedBuild'] = array('operator' => 'include', 'control' => 'select', 'values' => 'builds');
|
||||
$config->bug->search['params']['resolvedBuild'] = array('operator' => '=', 'control' => 'select', 'values' => 'builds');
|
||||
$config->bug->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['resolvedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['lastEditedDate']= array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['deadline'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->bug->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
global $lang;
|
||||
$config->bug->datatable = new stdclass();
|
||||
$config->bug->datatable->defaultField = array('id', 'title', 'severity', 'pri', 'status', 'openedBy', 'openedDate', 'confirmed', 'assignedTo', 'resolution', 'actions');
|
||||
|
||||
$config->bug->datatable->fieldList['id']['title'] = 'idAB';
|
||||
$config->bug->datatable->fieldList['id']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['id']['width'] = '70';
|
||||
$config->bug->datatable->fieldList['id']['required'] = 'yes';
|
||||
|
||||
$config->bug->datatable->fieldList['product']['title'] = 'product';
|
||||
$config->bug->datatable->fieldList['product']['control'] = 'hidden';
|
||||
$config->bug->datatable->fieldList['product']['dataSource'] = array('module' => 'product', 'method' => 'getPairs', 'params' => '&0&&all');
|
||||
|
||||
$config->bug->datatable->fieldList['module']['control'] = 'select';
|
||||
$config->bug->datatable->fieldList['module']['title'] = 'module';
|
||||
$config->bug->datatable->fieldList['module']['dataSource'] = array('module' => 'tree', 'method' => 'getOptionMenu', 'params' => '$productID&bug&0&all');
|
||||
|
||||
$config->bug->datatable->fieldList['title']['title'] = 'title';
|
||||
$config->bug->datatable->fieldList['title']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['title']['width'] = 'auto';
|
||||
$config->bug->datatable->fieldList['title']['required'] = 'yes';
|
||||
$config->bug->datatable->fieldList['title']['minWidth'] = '200';
|
||||
|
||||
$config->bug->datatable->fieldList['severity']['title'] = 'severityAB';
|
||||
$config->bug->datatable->fieldList['severity']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['severity']['width'] = '50';
|
||||
$config->bug->datatable->fieldList['severity']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['severity']['name'] = $lang->bug->severity;
|
||||
|
||||
$config->bug->datatable->fieldList['pri']['title'] = 'P';
|
||||
$config->bug->datatable->fieldList['pri']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['pri']['width'] = '50';
|
||||
$config->bug->datatable->fieldList['pri']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['pri']['name'] = $lang->bug->pri;
|
||||
|
||||
$config->bug->datatable->fieldList['confirmed']['title'] = 'confirmedAB';
|
||||
$config->bug->datatable->fieldList['confirmed']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['confirmed']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['confirmed']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['title']['title'] = 'title';
|
||||
$config->bug->datatable->fieldList['title']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['title']['width'] = 'auto';
|
||||
$config->bug->datatable->fieldList['title']['required'] = 'yes';
|
||||
$config->bug->datatable->fieldList['title']['minWidth'] = '200';
|
||||
|
||||
$config->bug->datatable->fieldList['status']['title'] = 'statusAB';
|
||||
$config->bug->datatable->fieldList['status']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['status']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['status']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['branch']['title'] = 'branch';
|
||||
$config->bug->datatable->fieldList['branch']['fixed'] = 'left';
|
||||
$config->bug->datatable->fieldList['branch']['width'] = '100';
|
||||
$config->bug->datatable->fieldList['branch']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['branch']['control'] = 'select';
|
||||
$config->bug->datatable->fieldList['branch']['dataSource'] = array('module' => 'branch', 'method' => 'getPairs', 'params' => '$productID');
|
||||
|
||||
$config->bug->datatable->fieldList['type']['title'] = 'type';
|
||||
$config->bug->datatable->fieldList['type']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['type']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['type']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['project']['title'] = 'project';
|
||||
$config->bug->datatable->fieldList['project']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['project']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['project']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['project']['control'] = 'hidden';
|
||||
$config->bug->datatable->fieldList['project']['dataSource'] = array('module' => 'product', 'method' => 'getProjectPairsByProduct', 'params' => '$productID&');
|
||||
|
||||
$config->bug->datatable->fieldList['execution']['title'] = 'execution';
|
||||
$config->bug->datatable->fieldList['execution']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['execution']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['execution']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['execution']['dataSource'] = array('module' => 'product', 'method' =>'getAllExecutionPairsByProduct', 'params' => '$productID&$branch&0&stagefilter');
|
||||
|
||||
$config->bug->datatable->fieldList['plan']['title'] = 'plan';
|
||||
$config->bug->datatable->fieldList['plan']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['plan']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['plan']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['openedBy']['title'] = 'openedByAB';
|
||||
$config->bug->datatable->fieldList['openedBy']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['openedBy']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['openedBy']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['openedDate']['title'] = 'openedDateAB';
|
||||
$config->bug->datatable->fieldList['openedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['openedDate']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['openedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['openedBuild']['title'] = 'openedBuild';
|
||||
$config->bug->datatable->fieldList['openedBuild']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['openedBuild']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['openedBuild']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['openedBuild']['control'] = 'multiple';
|
||||
$config->bug->datatable->fieldList['openedBuild']['dataSource'] = array('module' => 'build', 'method' =>'getBuildPairs', 'params' => '$productID&$branch&noempty,noterminate,nodone,withbranch');
|
||||
|
||||
$config->bug->datatable->fieldList['confirmed']['title'] = 'confirmedAB';
|
||||
$config->bug->datatable->fieldList['confirmed']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['confirmed']['width'] = '100';
|
||||
$config->bug->datatable->fieldList['confirmed']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['assignedTo']['title'] = 'assignedToAB';
|
||||
$config->bug->datatable->fieldList['assignedTo']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['assignedTo']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['assignedTo']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['assignedTo']['dataSource'] = array('module' => 'user', 'method' =>'getPairs', 'params' => 'noclosed|noletter');
|
||||
|
||||
$config->bug->datatable->fieldList['assignedDate']['title'] = 'assignedDate';
|
||||
$config->bug->datatable->fieldList['assignedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['assignedDate']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['assignedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['deadline']['title'] = 'deadline';
|
||||
$config->bug->datatable->fieldList['deadline']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['deadline']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['deadline']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['deadline']['control'] = 'date';
|
||||
|
||||
$config->bug->datatable->fieldList['resolvedBy']['title'] = 'resolvedBy';
|
||||
$config->bug->datatable->fieldList['resolvedBy']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['resolvedBy']['width'] = '100';
|
||||
$config->bug->datatable->fieldList['resolvedBy']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['resolution']['title'] = 'resolutionAB';
|
||||
$config->bug->datatable->fieldList['resolution']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['resolution']['width'] = '110';
|
||||
$config->bug->datatable->fieldList['resolution']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['resolvedDate']['title'] = 'resolvedDateAB';
|
||||
$config->bug->datatable->fieldList['resolvedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['resolvedDate']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['resolvedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['title'] = 'resolvedBuild';
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['control'] = 'select';
|
||||
$config->bug->datatable->fieldList['resolvedBuild']['dataSource'] = array('module' => 'bug', 'method' =>'getRelatedObjects', 'params' => 'resolvedBuild&id,name');
|
||||
|
||||
$config->bug->datatable->fieldList['activatedCount']['title'] = 'activatedCountAB';
|
||||
$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['story']['title'] = 'story';
|
||||
$config->bug->datatable->fieldList['story']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['story']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['story']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['story']['control'] = 'select';
|
||||
$config->bug->datatable->fieldList['story']['dataSource'] = array('module' => 'story', 'method' =>'getProductStoryPairs', 'params' => '$productID');
|
||||
|
||||
$config->bug->datatable->fieldList['task']['title'] = 'task';
|
||||
$config->bug->datatable->fieldList['task']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['task']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['task']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['task']['dataSource'] = array('module' => 'bug', 'method' =>'getRelatedObjects', 'params' => 'task&id,name');
|
||||
|
||||
$config->bug->datatable->fieldList['toTask']['title'] = 'toTask';
|
||||
$config->bug->datatable->fieldList['toTask']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['toTask']['width'] = '120';
|
||||
$config->bug->datatable->fieldList['toTask']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['keywords']['title'] = 'keywords';
|
||||
$config->bug->datatable->fieldList['keywords']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['keywords']['width'] = '100';
|
||||
$config->bug->datatable->fieldList['keywords']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['os']['title'] = 'os';
|
||||
$config->bug->datatable->fieldList['os']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['os']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['os']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['os']['control'] = 'multiple';
|
||||
|
||||
$config->bug->datatable->fieldList['browser']['title'] = 'browser';
|
||||
$config->bug->datatable->fieldList['browser']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['browser']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['browser']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['browser']['control'] = 'multiple';
|
||||
|
||||
$config->bug->datatable->fieldList['mailto']['title'] = 'mailto';
|
||||
$config->bug->datatable->fieldList['mailto']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['mailto']['width'] = '100';
|
||||
$config->bug->datatable->fieldList['mailto']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['closedBy']['title'] = 'closedBy';
|
||||
$config->bug->datatable->fieldList['closedBy']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['closedBy']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['closedBy']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['closedDate']['title'] = 'closedDate';
|
||||
$config->bug->datatable->fieldList['closedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['closedDate']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['closedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['lastEditedBy']['title'] = 'lastEditedBy';
|
||||
$config->bug->datatable->fieldList['lastEditedBy']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['lastEditedBy']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['lastEditedBy']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['lastEditedDate']['title'] = 'lastEditedDateAB';
|
||||
$config->bug->datatable->fieldList['lastEditedDate']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['lastEditedDate']['width'] = '90';
|
||||
$config->bug->datatable->fieldList['lastEditedDate']['required'] = 'no';
|
||||
|
||||
$config->bug->datatable->fieldList['actions']['title'] = 'actions';
|
||||
$config->bug->datatable->fieldList['actions']['fixed'] = 'right';
|
||||
$config->bug->datatable->fieldList['actions']['width'] = '150';
|
||||
$config->bug->datatable->fieldList['actions']['required'] = 'yes';
|
||||
|
||||
$config->bug->datatable->fieldList['steps']['title'] = 'steps';
|
||||
$config->bug->datatable->fieldList['steps']['control'] = 'textarea';
|
||||
|
||||
$config->bug->datatable->fieldList['case']['title'] = 'case';
|
||||
$config->bug->datatable->fieldList['case']['dataSource'] = array('module' => 'bug', 'method' =>'getRelatedObjects', 'params' => 'case&id,title');
|
||||
+6
-57
@@ -313,7 +313,7 @@ class bug extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function create(string $productID, string $branch = '', string $extras = ''): void
|
||||
public function create(string $productID, string $branch = '', string $extras = '')
|
||||
{
|
||||
$productID = (int)$productID;
|
||||
|
||||
@@ -839,14 +839,15 @@ class bug extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看一个bug。
|
||||
* View a bug.
|
||||
*
|
||||
* @param int $bugID
|
||||
* @param string $bugID
|
||||
* @param string $form
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function view($bugID, $from = 'bug')
|
||||
public function view(string $bugID, string $from = 'bug')
|
||||
{
|
||||
/* Judge bug exits or not. */
|
||||
$bugID = (int)$bugID;
|
||||
@@ -860,60 +861,8 @@ class bug extends control
|
||||
/* Update action. */
|
||||
if($bug->assignedTo == $this->app->user->account) $this->loadModel('action')->read('bug', $bugID);
|
||||
|
||||
/* Set menu. */
|
||||
if(!isonlybody())
|
||||
{
|
||||
if($this->app->tab == 'project') $this->loadModel('project')->setMenu($bug->project);
|
||||
if($this->app->tab == 'execution') $this->loadModel('execution')->setMenu($bug->execution);
|
||||
if($this->app->tab == 'qa') $this->qa->setMenu($this->products, $bug->product, $bug->branch);
|
||||
|
||||
if($this->app->tab == 'devops')
|
||||
{
|
||||
$repos = $this->loadModel('repo')->getRepoPairs('project', $bug->project);
|
||||
$this->repo->setMenu($repos);
|
||||
$this->lang->navGroup->bug = 'devops';
|
||||
}
|
||||
|
||||
if($this->app->tab == 'product')
|
||||
{
|
||||
$this->loadModel('product')->setMenu($bug->product);
|
||||
$this->lang->product->menu->plan['subModule'] .= ',bug';
|
||||
}
|
||||
}
|
||||
|
||||
/* Get product info. */
|
||||
$productID = $bug->product;
|
||||
$product = $this->loadModel('product')->getByID($productID);
|
||||
$branches = $product->type == 'normal' ? array() : $this->loadModel('branch')->getPairs($bug->product);
|
||||
|
||||
$projects = $this->loadModel('product')->getProjectPairsByProduct($productID, $bug->branch);
|
||||
$this->session->set("project", key($projects), 'project');
|
||||
|
||||
$this->executeHooks($bugID);
|
||||
|
||||
/* Header and positon. */
|
||||
$this->view->title = "BUG #$bug->id $bug->title - " . $product->name;
|
||||
$this->view->position[] = html::a($this->createLink('bug', 'browse', "productID=$productID"), $product->name);
|
||||
$this->view->position[] = $this->lang->bug->view;
|
||||
|
||||
/* Assign. */
|
||||
$this->view->project = $this->loadModel('project')->getByID($bug->project);
|
||||
$this->view->productID = $productID;
|
||||
$this->view->branches = $branches;
|
||||
$this->view->modulePath = $this->tree->getParents($bug->module);
|
||||
$this->view->bugModule = empty($bug->module) ? '' : $this->tree->getById($bug->module);
|
||||
$this->view->bug = $bug;
|
||||
$this->view->from = $from;
|
||||
$this->view->branchName = $product->type == 'normal' ? '' : zget($branches, $bug->branch, '');
|
||||
$this->view->users = $this->user->getPairs('noletter');
|
||||
$this->view->actions = $this->action->getList('bug', $bugID);
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, 'all');
|
||||
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('bug', $bugID);
|
||||
$this->view->product = $product;
|
||||
$this->view->linkCommits = $this->loadModel('repo')->getCommitsByObject($bugID, 'bug');
|
||||
|
||||
$this->view->projects = array('' => '') + $projects;
|
||||
|
||||
if(!isonlybody()) $this->bugZen->setMenu4View($bug);
|
||||
$this->bugZen->setView4View($bug, $from);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ class bugTest
|
||||
$bug->openedBy = 'admin';
|
||||
$bug->openedDate = '2023-04-20';
|
||||
$bug->notifyEmail = '';
|
||||
$bug->steps = '';
|
||||
|
||||
foreach($param as $key => $value) $bug->$key = $value;
|
||||
|
||||
|
||||
@@ -149,4 +149,82 @@ class bugZen extends bug
|
||||
$this->view->users = $this->user->getPairs('devfirst|noclosed|nodeleted');
|
||||
$this->app->loadLang('release');
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果不是弹窗,调用该方法为查看bug设置导航。
|
||||
* If it's not a iframe, call this method to set menu for view bug page.
|
||||
*
|
||||
* @param object $bug
|
||||
* @return void
|
||||
*/
|
||||
protected function setMenu4View(object $bug): void
|
||||
{
|
||||
if($this->app->tab == 'project') $this->loadModel('project')->setMenu($bug->project);
|
||||
if($this->app->tab == 'execution') $this->loadModel('execution')->setMenu($bug->execution);
|
||||
if($this->app->tab == 'qa') $this->qa->setMenu($this->products, $bug->product, $bug->branch);
|
||||
|
||||
if($this->app->tab == 'devops')
|
||||
{
|
||||
$repos = $this->loadModel('repo')->getRepoPairs('project', $bug->project);
|
||||
$this->repo->setMenu($repos);
|
||||
$this->lang->navGroup->bug = 'devops';
|
||||
}
|
||||
|
||||
if($this->app->tab == 'product')
|
||||
{
|
||||
$this->loadModel('product')->setMenu($bug->product);
|
||||
$this->lang->product->menu->plan['subModule'] .= ',bug';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为查看bug页面设置View数据。
|
||||
* Set $this->view for view bug page.
|
||||
*
|
||||
* @param object $bug
|
||||
* @param string $from
|
||||
* @return void
|
||||
*/
|
||||
protected function setView4View(object $bug, string $from): void
|
||||
{
|
||||
$this->loadModel('project');
|
||||
$this->loadModel('product');
|
||||
$this->loadModel('build');
|
||||
$this->loadModel('common');
|
||||
$this->loadModel('repo');
|
||||
$this->loadModel('user');
|
||||
|
||||
$bugID = $bug->id;
|
||||
$productID = $bug->product;
|
||||
$product = $this->product->getByID($productID);
|
||||
$branches = $product->type == 'normal' ? array() : $this->loadModel('branch')->getPairs($bug->product);
|
||||
|
||||
$projects = $this->product->getProjectPairsByProduct($productID, $bug->branch);
|
||||
$this->session->set("project", key($projects), 'project');
|
||||
|
||||
$this->executeHooks($bugID);
|
||||
|
||||
/* Header and positon. */
|
||||
$this->view->title = "BUG #$bug->id $bug->title - " . $product->name;
|
||||
$this->view->position[] = html::a($this->createLink('bug', 'browse', "productID=$productID"), $product->name);
|
||||
$this->view->position[] = $this->lang->bug->view;
|
||||
|
||||
/* Assign. */
|
||||
$this->view->project = $this->project->getByID($bug->project);
|
||||
$this->view->productID = $productID;
|
||||
$this->view->branches = $branches;
|
||||
$this->view->modulePath = $this->tree->getParents($bug->module);
|
||||
$this->view->bugModule = empty($bug->module) ? '' : $this->tree->getById($bug->module);
|
||||
$this->view->bug = $bug;
|
||||
$this->view->from = $from;
|
||||
$this->view->branchName = $product->type == 'normal' ? '' : zget($branches, $bug->branch, '');
|
||||
$this->view->users = $this->user->getPairs('noletter');
|
||||
$this->view->actions = $this->action->getList('bug', $bugID);
|
||||
$this->view->builds = $this->build->getBuildPairs($productID, 'all');
|
||||
$this->view->preAndNext = $this->common->getPreAndNextObject('bug', $bugID);
|
||||
$this->view->product = $product;
|
||||
$this->view->linkCommits = $this->repo->getCommitsByObject($bugID, 'bug');
|
||||
|
||||
$this->view->projects = array('' => '') + $projects;
|
||||
}
|
||||
}
|
||||
|
||||
+21
-29
@@ -290,51 +290,43 @@ class executionModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the execution id user last visited to session.
|
||||
* 检查用户是否可以访问当前执行。
|
||||
* Check whether access to the current execution is allowed or not.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param array $executions
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function saveState($executionID, $executions)
|
||||
public function checkAccess(int $executionID, array $executions): int
|
||||
{
|
||||
if(defined('TUTORIAL')) return $executionID;
|
||||
|
||||
/* When the cookie and session do not exist, get it from the database. */
|
||||
if(empty($executionID) and isset($this->config->execution->lastExecution) and isset($executions[$this->config->execution->lastExecution]))
|
||||
/* When the cookie and session do not exist, get it from the config. */
|
||||
if(!$executionID)
|
||||
{
|
||||
$this->session->set('execution', $this->config->execution->lastExecution, $this->app->tab);
|
||||
$this->setProjectSession($this->session->execution);
|
||||
return $this->session->execution;
|
||||
if(isset($this->cookie->lastExecution)) $executionID = (int)$this->cookie->lastExecution;
|
||||
if(isset($this->session->execution)) $executionID = (int)$this->session->execution;
|
||||
if(isset($this->config->execution->lastExecution)) $executionID = (int)$this->config->execution->lastExecution;
|
||||
}
|
||||
|
||||
if($executionID == 0 and $this->cookie->lastExecution)
|
||||
/* If the execution doesn't exist in the list, use the first execution in the list. */
|
||||
if(!isset($executions[$executionID])) $executionID = key($executions);
|
||||
|
||||
/* Check execution again. */
|
||||
if($executionID)
|
||||
{
|
||||
/* Execution link is execution-task. */
|
||||
$executionID = (int)$this->cookie->lastExecution;
|
||||
$executionID = in_array($executionID, array_keys($executions)) ? $executionID : key($executions);
|
||||
$execution = $this->dao->findByID($executionID)->from(TABLE_EXECUTION)->fetch();
|
||||
if(empty($execution)) return js::error($this->lang->notFound);
|
||||
if(strpos(",{$this->app->user->view->sprints},", ",{$executionID},") === false) $this->accessDenied();
|
||||
}
|
||||
|
||||
if($executionID == 0 and $this->session->execution) $executionID = $this->session->execution;
|
||||
if($executionID == 0) $executionID = key($executions);
|
||||
/* Save session. */
|
||||
$this->session->set('execution', $executionID, $this->app->tab);
|
||||
$this->setProjectSession($executionID);
|
||||
|
||||
$this->session->set('execution', (int)$executionID, $this->app->tab);
|
||||
|
||||
if(!isset($executions[$executionID]))
|
||||
{
|
||||
$this->session->set('execution', key($executions), $this->app->tab);
|
||||
|
||||
if($executionID)
|
||||
{
|
||||
$execution = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->andWhere('type')->in('sprint,stage,kanban')->fetch();
|
||||
if(empty($execution)) return js::error($this->lang->notFound);
|
||||
if(strpos(",{$this->app->user->view->sprints},", ",{$executionID},") === false) $this->accessDenied();
|
||||
}
|
||||
}
|
||||
|
||||
$this->setProjectSession($this->session->execution);
|
||||
return $this->session->execution;
|
||||
/* Return execution id. */
|
||||
return $executionID;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+11
-29
@@ -1867,61 +1867,43 @@ class project extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a project.
|
||||
* 删除一个项目,并弹窗确认
|
||||
* Delete a project and confirm.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param string $projectID
|
||||
* @param string $confirm
|
||||
* @param string $from browse|view
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function delete($projectID, $confirm = 'no', $from = 'browse')
|
||||
public function delete(string $projectID, string $confirm = 'no', string $from = 'browse'): void
|
||||
{
|
||||
$projectID = (int)$projectID;
|
||||
$project = $this->getByID($projectID);
|
||||
|
||||
if($confirm == 'no')
|
||||
{
|
||||
$project = $this->project->getByID($projectID);
|
||||
return print(js::confirm(sprintf($this->lang->project->confirmDelete, $project->name), $this->createLink('project', 'delete', "projectID=$projectID&confirm=yes&from=$from")));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->loadModel('user');
|
||||
$this->loadModel('action');
|
||||
|
||||
$this->project->delete(TABLE_PROJECT, $projectID);
|
||||
$this->dao->update(TABLE_DOCLIB)->set('deleted')->eq(1)->where('execution')->eq($projectID)->exec();
|
||||
$this->user->updateUserView($projectID, 'project');
|
||||
|
||||
/* Delete the execution under the project. */
|
||||
$executionIdList = $this->loadModel('execution')->getPairs($projectID);
|
||||
|
||||
/* Delete shadow product.*/
|
||||
$project = $this->project->getByID($projectID);
|
||||
if(!$project->hasProduct)
|
||||
{
|
||||
$productID = $this->loadModel('product')->getProductIDByProject($projectID);
|
||||
$this->dao->update(TABLE_PRODUCT)->set('deleted')->eq(1)->where('id')->eq($productID)->exec();
|
||||
}
|
||||
$this->loadModel('user')->updateUserView($projectID, 'project');
|
||||
|
||||
$message = $this->executeHooks($projectID);
|
||||
if($message) $this->lang->saveSuccess = $message;
|
||||
|
||||
if(empty($executionIdList))
|
||||
{
|
||||
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess));
|
||||
if($from == 'view') return print(js::locate($this->createLink('project', 'browse'), 'parent'));
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_EXECUTION)->set('deleted')->eq(1)->where('id')->in(array_keys($executionIdList))->exec();
|
||||
foreach($executionIdList as $executionID => $execution) $this->action->create('execution', $executionID, 'deleted', '', ACTIONMODEL::CAN_UNDELETED);
|
||||
$this->user->updateUserView($executionIdList, 'sprint');
|
||||
$this->projectZen->removeAssociatedProducts($project);
|
||||
$this->projectZen->removeAssociatedExecutions($projectID);
|
||||
|
||||
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess));
|
||||
|
||||
$this->session->set('project', '');
|
||||
if($from == 'view') return print(js::locate($this->createLink('project', 'browse'), 'parent'));
|
||||
return print(js::reload('parent'));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1767,12 +1767,28 @@ class projectModel extends model
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除项目并同步执行与产品等状态为删除
|
||||
* Deletes a project and updates related items: product|execution
|
||||
*
|
||||
* @param string $table product|execution
|
||||
* @param int|array $idList
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function deleteProductAndExcution(string $table, int|array $idList):void
|
||||
{
|
||||
$this->dao->update($table)->set('deleted')->eq(1)->where('id')->in($idList)->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the program of the product.
|
||||
*
|
||||
* @param int $oldProgram
|
||||
* @param int $newProgram
|
||||
* @param array $products
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -1806,16 +1822,16 @@ class projectModel extends model
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function unlinkMember($projectID, $account, $removeExecution = 'no')
|
||||
public function unlinkMember(int $projectID, string $account, string $removeExecution = 'no'): void
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_TEAM)->where('root')->eq((int)$projectID)->andWhere('type')->eq('project')->andWhere('account')->eq($account)->exec();
|
||||
$this->projectTao->unlinkTeamMember($projectID, 'project', $account);
|
||||
|
||||
$this->loadModel('user')->updateUserView($projectID, 'project', array($account));
|
||||
|
||||
if($removeExecution == 'yes')
|
||||
{
|
||||
$executions = $this->loadModel('execution')->getByProject($projectID, 'undone', 0, true);
|
||||
$this->dao->delete()->from(TABLE_TEAM)->where('root')->in(array_keys($executions))->andWhere('type')->eq('execution')->andWhere('account')->eq($account)->exec();
|
||||
$this->projectTao->unlinkTeamMember(array_keys($executions), 'execution', $account);
|
||||
$this->user->updateUserView(array_keys($executions), 'sprint', array($account));
|
||||
}
|
||||
|
||||
|
||||
+24
-4
@@ -220,7 +220,7 @@ class projectTao extends projectModel
|
||||
* @param object $postData
|
||||
* @param object $program
|
||||
* @access protected
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
protected function createDocLib(int $projectID, object $project, object $postData, object $program): bool
|
||||
{
|
||||
@@ -269,7 +269,7 @@ class projectTao extends projectModel
|
||||
* @param object $postData
|
||||
* @param object $program
|
||||
* @access protected
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
protected function createProduct(int $projectID, object $project, object $postData, object $program): bool
|
||||
{
|
||||
@@ -333,7 +333,7 @@ class projectTao extends projectModel
|
||||
* @param object $rawdata
|
||||
* @param object $program
|
||||
* @access protected
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
protected function getLinkedProductsCount(object $project, object $rawdata): int
|
||||
{
|
||||
@@ -355,7 +355,7 @@ class projectTao extends projectModel
|
||||
*
|
||||
* @param int $projectID
|
||||
* @access protected
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
protected function addProjectAdmin(int $projectID): bool
|
||||
{
|
||||
@@ -383,4 +383,24 @@ class projectTao extends projectModel
|
||||
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除项目团队成员。
|
||||
* Delete project team member.
|
||||
*
|
||||
* @param array|int $projectIdList
|
||||
* @param string $type
|
||||
* @param string $account
|
||||
* @access protected
|
||||
* @return bool
|
||||
*/
|
||||
protected function unlinkTeamMember(int|array $projectIdList, string $type, string $account): bool
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_TEAM)
|
||||
->where('root')->in($projectIdList)
|
||||
->andWhere('type')->eq($type)
|
||||
->andWhere('account')->eq($account)
|
||||
->exec();
|
||||
return !dao::isError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,65 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(__FILE__, 5) . "/test/lib/init.php";
|
||||
su('admin');
|
||||
su('admin');
|
||||
|
||||
function initData()
|
||||
{
|
||||
$team = zdTable('team');
|
||||
$team->id->range('2-9');
|
||||
$team->root->range('2,7-9{3}');
|
||||
$team->type->range('project,execution{7}');
|
||||
$team->account->range('admin,user1,user2,admin');
|
||||
$team->limited->range('no');
|
||||
$team->join->range('2023-04-02');
|
||||
$team->days->range('7');
|
||||
$team->hours->range('7');
|
||||
$team->gen(8);
|
||||
|
||||
$execution = zdTable('project');
|
||||
$execution->id->range('2,6,8,9');
|
||||
$execution->project->range('2,3');
|
||||
$execution->name->prefix('项目')->range('8,9');
|
||||
$execution->code->prefix('project')->range('8,9');
|
||||
$execution->type->range('project{2},sprint,kanban');
|
||||
$execution->status->range('doing,suspended,closed');
|
||||
$execution->gen(4);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
title=测试 projectModel->unlinkMember();
|
||||
title=测试 projectModel::getByID;
|
||||
timeout=0
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
查看移除团队成员之前的ID为11的项目团队成员数量 >> 3
|
||||
查看移除团队成员之后的ID为11的项目团队成员数量 >> 2
|
||||
查看项目ID为11的团队成员的真实姓名 >> 产品经理92
|
||||
查看项目ID为11的团队成员的真实姓名 >> 产品经理92
|
||||
- 执行$diffMembers @1 >> 1
|
||||
>> admin
|
||||
- 执行$beforeMembers['admin'] @admin >> 0
|
||||
>> 1
|
||||
- 执行$afterMembers['admin'] @0 >> admin
|
||||
>> 0
|
||||
|
||||
*/
|
||||
|
||||
global $tester;
|
||||
$tester->loadModel('project');
|
||||
|
||||
$beforeMembers = $tester->project->getTeamMemberPairs(11);
|
||||
$tester->project->unlinkMember(11, 'admin', false);
|
||||
$afterMembers = $tester->project->getTeamMemberPairs(11);
|
||||
initData();
|
||||
|
||||
r(count($beforeMembers)) && p('') && e('3'); // 查看移除团队成员之前的ID为11的项目团队成员数量
|
||||
r(count($afterMembers)) && p('') && e('2'); // 查看移除团队成员之后的ID为11的项目团队成员数量
|
||||
r($beforeMembers) && p('pm92') && e('产品经理92'); // 查看项目ID为11的团队成员的真实姓名
|
||||
r($afterMembers) && p('pm92') && e('产品经理92'); // 查看项目ID为11的团队成员的真实姓名
|
||||
$beforeMembers = $tester->project->getTeamMemberPairs(2);
|
||||
$beforeExecutionMembers = $tester->project->getTeamMemberPairs(8);
|
||||
|
||||
$tester->project->unlinkMember(2, 'admin', 'yes');
|
||||
|
||||
$afterMembers = $tester->project->getTeamMemberPairs(2);
|
||||
$afterExecutionMembers = $tester->project->getTeamMemberPairs(6);
|
||||
$diffMembers = count($beforeMembers) - count($afterMembers);
|
||||
$diffExecutionMembers = count($beforeExecutionMembers) - count($afterExecutionMembers);
|
||||
|
||||
r($diffMembers) && p() && e('1');
|
||||
r($beforeMembers['admin']) && p() && e('admin');
|
||||
r($afterMembers['admin']) && p() && e('0');
|
||||
r($diffExecutionMembers) && p() && e('1');
|
||||
r($beforeExecutionMembers['admin']) && p() && e('admin');
|
||||
r($afterExecutionMembers['admin']) && p() && e('0');
|
||||
|
||||
+50
-6
@@ -56,9 +56,9 @@ class projectZen extends project
|
||||
* @param object $project
|
||||
* @param object $rawdata
|
||||
* @access protected
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
private function checkProductAndBranch(object $project, object $rawdata): bool
|
||||
private function checkProductAndBranch(object $project, object $rawdata): bool
|
||||
{
|
||||
$linkedProductsCount = $this->project->getLinkedProductsCount($project, $rawdata);
|
||||
|
||||
@@ -98,9 +98,9 @@ class projectZen extends project
|
||||
* @param object $project
|
||||
* @param object $rawdata
|
||||
* @access protected
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
private function checkDaysAndBudget(object $project, object $rawdata): bool
|
||||
private function checkDaysAndBudget(object $project, object $rawdata): bool
|
||||
{
|
||||
/* Judge workdays is legitimate. */
|
||||
$workdays = helper::diffDate($project->end, $project->begin) + 1;
|
||||
@@ -137,9 +137,9 @@ class projectZen extends project
|
||||
* @param object $project
|
||||
* @param object $rawdata
|
||||
* @access protected
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
private function checkProductNameUnqiue(object $project, object $rawdata): bool
|
||||
private function checkProductNameUnqiue(object $project, object $rawdata): bool
|
||||
{
|
||||
/* When select create new product, product name cannot be empty and duplicate. */
|
||||
if($project->hasProduct && isset($rawdata->newProduct))
|
||||
@@ -542,4 +542,48 @@ class projectZen extends project
|
||||
->remove('comment,readjustTime,readjustTask')
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从项目中删除所有关联的执行。
|
||||
* removes all associated executions from the be deleted project
|
||||
*
|
||||
* @param int $projectID
|
||||
*
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function removeAssociatedExecutions(int $projectID): void
|
||||
{
|
||||
/* Delete the execution under the project. */
|
||||
$executionIdList = $this->loadModel('execution')->getPairs($projectID);
|
||||
if(empty($executionIdList))
|
||||
{
|
||||
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess));
|
||||
if($from == 'view') return print(js::locate($this->createLink('project', 'browse'), 'parent'));
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
|
||||
$this->updateRelatedItemByDelete('zt_execution', array_keys($executionIdList));
|
||||
foreach($executionIdList as $executionID => $execution) $this->action->create('execution', $executionID, 'deleted', '', ACTIONMODEL::CAN_UNDELETED);
|
||||
$this->user->updateUserView($executionIdList, 'sprint');
|
||||
}
|
||||
|
||||
/**
|
||||
* 从项目中删除所有关联的产品。
|
||||
* removes all associated products from the be deleted project
|
||||
*
|
||||
* @param object $projectID
|
||||
*
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function removeAssociatedProducts(object $project): void
|
||||
{
|
||||
/* Delete shadow product.*/
|
||||
if(!$project->hasProduct)
|
||||
{
|
||||
$productID = $this->loadModel('product')->getProductIDByProject($project->id);
|
||||
$this->updateRelatedItemByDelete('zt_product', $productID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,3 +35,8 @@ $config->todo->assignTo->form['assignedTo'] = array('required' => true, 'type
|
||||
$config->todo->batchClose = new stdclass;
|
||||
$config->todo->batchClose->form = array();
|
||||
$config->todo->batchClose->form['todoIDList'] = array('required' => true, 'type' => 'array');
|
||||
|
||||
$config->todo->batchEdit = new stdClass;
|
||||
$config->todo->batchEdit->form = array();
|
||||
$config->todo->batchEdit->form['todoIDList'] = array('required' => true, 'type' => 'array');
|
||||
$config->todo->batchEdit->form['names'] = array('required' => true, 'type' => 'array');
|
||||
+74
-165
@@ -2,7 +2,7 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* The control file of example module of ZenTaoPMS.
|
||||
* The control file of todo module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
|
||||
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
@@ -29,15 +29,15 @@ class todo extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建待办
|
||||
* 创建待办。
|
||||
* Create a todo.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $from todo|feedback|block
|
||||
* @access public
|
||||
* @return int|void
|
||||
* @return int
|
||||
*/
|
||||
public function create(string $date = 'today', string $from = 'todo')
|
||||
public function create(string $date = 'today', string $from = 'todo'): int
|
||||
{
|
||||
if($date == 'today') $date = date::today();
|
||||
|
||||
@@ -56,7 +56,7 @@ class todo extends control
|
||||
|
||||
if($from == 'block')
|
||||
{
|
||||
$todo = $this->todo->getById($todoID);
|
||||
$todo = $this->todo->getByID($todoID);
|
||||
$todo->begin = date::formatTime($todo->begin);
|
||||
return $this->send(array('result' => 'success', 'id' => $todoID, 'name' => $todo->name, 'pri' => $todo->pri, 'priName' => $this->lang->todo->priList[$todo->pri], 'time' => date(DT_DATE4, strtotime($todo->date)) . ' ' . $todo->begin));
|
||||
}
|
||||
@@ -69,12 +69,7 @@ class todo extends control
|
||||
|
||||
unset($this->lang->todo->typeList['cycle']);
|
||||
|
||||
$this->view->title = $this->lang->todo->common . $this->lang->colon . $this->lang->todo->create;
|
||||
$this->view->date = date('Y-m-d', strtotime($date));
|
||||
$this->view->times = date::buildTimeList($this->config->todo->times->begin, $this->config->todo->times->end, $this->config->todo->times->delta);
|
||||
$this->view->time = date::now();
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|noempty');
|
||||
$this->display();
|
||||
$this->buildCreateView($date);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +123,7 @@ class todo extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑待办数据
|
||||
* 编辑待办数据。
|
||||
* Edit a todo.
|
||||
*
|
||||
* @param string $todoID
|
||||
@@ -137,8 +132,7 @@ class todo extends control
|
||||
*/
|
||||
public function edit(string $todoID)
|
||||
{
|
||||
$todoID = (int)$todoID;
|
||||
|
||||
$todoID = (int)$todoID;
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$formData = form::data($this->config->todo->edit->form);
|
||||
@@ -164,18 +158,14 @@ class todo extends control
|
||||
}
|
||||
|
||||
/* Judge a private todo or not, If private, die. */
|
||||
$todo = $this->todo->getById($todoID);
|
||||
$todo = $this->todo->getByID($todoID);
|
||||
if($todo->private and $this->app->user->account != $todo->account) return print('private');
|
||||
|
||||
unset($this->lang->todo->typeList['cycle']);
|
||||
|
||||
$todo->date = date("Y-m-d", strtotime($todo->date));
|
||||
$this->view->title = $this->lang->todo->common . $this->lang->colon . $this->lang->todo->edit;
|
||||
$this->view->times = date::buildTimeList($this->config->todo->times->begin, $this->config->todo->times->end, $this->config->todo->times->delta);
|
||||
$this->view->todo = $todo;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|noempty');
|
||||
$this->todoZen->buildEditView($todo);
|
||||
|
||||
$this->display();
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,113 +178,26 @@ class todo extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function batchEdit($from = '', $type = 'today', $userID = '', $status = 'all')
|
||||
public function batchEdit(string $from = '', string $type = 'today', string $userID = '', string $status = 'all')
|
||||
{
|
||||
/* Get form data for my-todo. */
|
||||
if($from == 'myTodo')
|
||||
if($from == 'myTodo') $this->todoZen->batchEditFromMyTodo($type, $userID, $status);
|
||||
if($from == 'todoBatchEdit')
|
||||
{
|
||||
/* Initialize vars. */
|
||||
$editedTodos = array();
|
||||
$todoIDList = array();
|
||||
$columns = 7;
|
||||
|
||||
if($userID == '') $userID = $this->app->user->id;
|
||||
$user = $this->loadModel('user')->getById($userID, 'id');
|
||||
$account = $user->account;
|
||||
|
||||
$reviews = array();
|
||||
if($this->config->edition == 'max') $reviews = $this->loadModel('review')->getUserReviewPairs($account);
|
||||
$allTodos = $this->todo->getList($type, $account, $status);
|
||||
if($this->post->todoIDList) $todoIDList = $this->post->todoIDList;
|
||||
|
||||
/* Initialize todos whose need to edited. */
|
||||
foreach($allTodos as $todo)
|
||||
{
|
||||
if(in_array($todo->id, $todoIDList))
|
||||
{
|
||||
$editedTodos[$todo->id] = $todo;
|
||||
if($todo->type != 'custom')
|
||||
{
|
||||
if(!isset($objectIDList[$todo->type])) $objectIDList[$todo->type] = array();
|
||||
$objectIDList[$todo->type][$todo->objectID] = $todo->objectID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$bugs = $this->bug->getUserBugPairs($account, true, 0, '', '', isset($objectIDList['bug']) ? $objectIDList['bug'] : '');
|
||||
$tasks = $this->task->getUserTaskPairs($account, 'wait,doing', '', isset($objectIDList['task']) ? $objectIDList['task'] : '');
|
||||
$storys = $this->loadModel('story')->getUserStoryPairs($account, 10, 'story', '', isset($objectIDList['story']) ? $objectIDList['story'] : '');
|
||||
if($this->config->edition != 'open') $this->view->feedbacks = $this->loadModel('feedback')->getUserFeedbackPairs($account, '', isset($objectIDList['feedback']) ? $objectIDList['feedback'] : '');
|
||||
if($this->config->edition == 'max')
|
||||
{
|
||||
$issues = $this->loadModel('issue')->getUserIssuePairs($account);
|
||||
$risks = $this->loadmodel('risk')->getUserRiskPairs($account);
|
||||
$opportunities = $this->loadmodel('opportunity')->getUserOpportunityPairs($account);
|
||||
}
|
||||
$testtasks = $this->loadModel('testtask')->getUserTestTaskPairs($account);
|
||||
|
||||
/* Judge whether the edited todos is too large. */
|
||||
$countInputVars = count($editedTodos) * $columns;
|
||||
$showSuhosinInfo = common::judgeSuhosinSetting($countInputVars);
|
||||
|
||||
unset($this->lang->todo->typeList['cycle']);
|
||||
/* Set Custom*/
|
||||
foreach(explode(',', $this->config->todo->list->customBatchEditFields) as $field) $customFields[$field] = $this->lang->todo->$field;
|
||||
$this->view->customFields = $customFields;
|
||||
$this->view->showFields = $this->config->todo->custom->batchEditFields;
|
||||
|
||||
/* Assign. */
|
||||
$title = $this->lang->todo->common . $this->lang->colon . $this->lang->todo->batchEdit;
|
||||
$position[] = html::a($this->createLink('my', 'todo'), $this->lang->my->todo);
|
||||
$position[] = $this->lang->todo->common;
|
||||
$position[] = $this->lang->todo->batchEdit;
|
||||
|
||||
if($showSuhosinInfo) $this->view->suhosinInfo = extension_loaded('suhosin') ? sprintf($this->lang->suhosinInfo, $countInputVars) : sprintf($this->lang->maxVarsInfo, $countInputVars);
|
||||
$this->view->bugs = $bugs;
|
||||
$this->view->tasks = $tasks;
|
||||
$this->view->storys = $storys;
|
||||
if($this->config->edition == 'max')
|
||||
{
|
||||
$this->view->issues = $issues;
|
||||
$this->view->risks = $risks;
|
||||
$this->view->opportunities = $opportunities;
|
||||
}
|
||||
$this->view->reviews = $reviews;
|
||||
$this->view->testtasks = $testtasks;
|
||||
$this->view->editedTodos = $editedTodos;
|
||||
$this->view->times = date::buildTimeList($this->config->todo->times->begin, $this->config->todo->times->end, $this->config->todo->times->delta);
|
||||
$this->view->time = date::now();
|
||||
$this->view->title = $title;
|
||||
$this->view->position = $position;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|noempty');
|
||||
|
||||
$this->display();
|
||||
}
|
||||
/* Get form data from todo-batchEdit. */
|
||||
elseif($from == 'todoBatchEdit')
|
||||
{
|
||||
$allChanges = $this->todo->batchUpdate();
|
||||
foreach($allChanges as $todoID => $changes)
|
||||
{
|
||||
if(empty($changes)) continue;
|
||||
|
||||
$actionID = $this->loadModel('action')->create('todo', $todoID, 'edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
return print(js::locate($this->session->todoList, 'parent'));
|
||||
$formData = form::data($this->config->todo->batchEdit->form);
|
||||
$this->todoZen->batchEditFromTodoBatchEdit($formData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启待办事项
|
||||
* 开启待办事项。
|
||||
* Start a todo.
|
||||
*
|
||||
* @param string $todoID
|
||||
* @access public
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function start(string $todoID)
|
||||
public function start(string $todoID): int
|
||||
{
|
||||
$todoID = (int)$todoID;
|
||||
$todo = $this->todo->getByID($todoID);
|
||||
@@ -303,79 +206,86 @@ class todo extends control
|
||||
if(in_array($todo->type, array('bug', 'task', 'story'))) return $this->todoZen->printConfirm($todo);
|
||||
if(isonlybody()) return print(js::reload('parent.parent'));
|
||||
|
||||
echo js::reload('parent');
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 激活待办事项
|
||||
* 激活待办事项。
|
||||
* Activated a todo.
|
||||
*
|
||||
* @param string $todoID
|
||||
* @access public
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function activate(string $todoID)
|
||||
public function activate(string $todoID): int
|
||||
{
|
||||
$todoID = (int)$todoID;
|
||||
$todo = $this->todo->getByID($todoID);
|
||||
|
||||
if($todo->status == 'done' or $todo->status == 'closed') $this->todo->activate($todoID);
|
||||
if($todo->status == 'done' || $todo->status == 'closed')
|
||||
{
|
||||
$isActivate = $this->todo->activate($todoID);
|
||||
if($isActivate === false) return print(js::error(dao::getError()));
|
||||
}
|
||||
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success'));
|
||||
if(isonlybody()) return print(js::reload('parent.parent'));
|
||||
|
||||
echo js::reload('parent');
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭待办。
|
||||
* Closed todo.
|
||||
*
|
||||
* @param $todoID
|
||||
*
|
||||
* @param string $todoID
|
||||
* @access public
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function close($todoID)
|
||||
public function close(string $todoID): int
|
||||
{
|
||||
$todo = $this->todo->getById($todoID);
|
||||
$todoID = (int)$todoID;
|
||||
$todo = $this->todo->getByID($todoID);
|
||||
if($todo->status == 'done') $this->todo->close($todoID);
|
||||
if(isonlybody()) return print(js::reload('parent.parent'));
|
||||
echo js::reload('parent');
|
||||
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 指派待办.
|
||||
* 指派待办。
|
||||
* Assign todo.
|
||||
*
|
||||
* @param string $todoID
|
||||
* @access public
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function assignTo(string $todoID)
|
||||
public function assignTo(string $todoID): int
|
||||
{
|
||||
$todoID = (int)$todoID;
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$formData = form::data($this->config->todo->assignTo->form);
|
||||
$todo = $this->todoZen->beforeAssignTo($formData);
|
||||
|
||||
$todo->id = (int)$todoID;
|
||||
$res = $this->todoZen->doAssignTo($todo);
|
||||
if(!$res) return print(js::error(dao::getError()));
|
||||
$todo->id = $todoID;
|
||||
$isAssigned = $this->todoZen->doAssignTo($todo);
|
||||
if(!$isAssigned) return print(js::error(dao::getError()));
|
||||
|
||||
return print(js::reload('parent.parent'));
|
||||
}
|
||||
|
||||
$this->view->todo = $this->todo->getById((int)$todoID);
|
||||
$this->view->todo = $this->todo->getByID($todoID);
|
||||
$this->view->members = $this->loadModel('user')->getPairs('noclosed|noempty|nodeleted');
|
||||
$this->view->times = date::buildTimeList($this->config->todo->times->begin, $this->config->todo->times->end, $this->config->todo->times->delta);
|
||||
$this->view->actions = $this->loadModel('action')->getList('todo', (int)$todoID);
|
||||
$this->view->actions = $this->loadModel('action')->getList('todo', $todoID);
|
||||
$this->view->users = $this->user->getPairs('noletter');
|
||||
$this->view->time = date::now();
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取待办的信息.
|
||||
* Get info of todo .
|
||||
* 获取待办的信息。
|
||||
* Get info of todo.
|
||||
*
|
||||
* @param string $todoID
|
||||
* @param string $from my|company
|
||||
@@ -383,9 +293,9 @@ class todo extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function view(string $todoID,string $from = 'company')
|
||||
public function view(string $todoID, string $from = 'company')
|
||||
{
|
||||
$todo = $this->todo->getById((int)$todoID, true);
|
||||
$todo = $this->todo->getByID((int)$todoID, true);
|
||||
|
||||
if(!$todo)
|
||||
{
|
||||
@@ -416,7 +326,6 @@ class todo extends control
|
||||
if(!isset($this->session->project)) $this->session->set('project', (int)key($projects));
|
||||
|
||||
$this->view->title = $account == $todo->account ? "{$this->lang->todo->common} #$todo->id $todo->name" : $this->lang->todo->common;
|
||||
$this->view->position[] = $this->lang->todo->view;
|
||||
$this->view->todo = $todo;
|
||||
$this->view->times = date::buildTimeList((int)$this->config->todo->times->begin, (int)$this->config->todo->times->end, 5);
|
||||
$this->view->from = $from;
|
||||
@@ -427,7 +336,7 @@ class todo extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除待办.
|
||||
* 删除待办。
|
||||
* Delete a todo.
|
||||
*
|
||||
* @param string $todoID
|
||||
@@ -437,28 +346,23 @@ class todo extends control
|
||||
*/
|
||||
public function delete(string $todoID, string $confirm = 'no')
|
||||
{
|
||||
$todoID = (int)$todoID;
|
||||
if($confirm == 'no')
|
||||
{
|
||||
return print(js::confirm($this->lang->todo->confirmDelete, $this->createLink('todo', 'delete', "todoID=(int)$todoID&confirm=yes")));
|
||||
return print(js::confirm($this->lang->todo->confirmDelete, $this->createLink('todo', 'delete', "todoID={$todoID}&confirm=yes")));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->todo->delete(TABLE_TODO, (int)$todoID);
|
||||
$this->todo->delete(TABLE_TODO, $todoID);
|
||||
|
||||
/* if ajax request, send result. */
|
||||
if($this->server->ajax)
|
||||
if(helper::isAjaxRequest())
|
||||
{
|
||||
$response = array();
|
||||
$response = array('result' => 'success', 'message' => '');
|
||||
if(dao::isError())
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = dao::getError();
|
||||
}
|
||||
else
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = '';
|
||||
}
|
||||
return $this->send($response);
|
||||
}
|
||||
|
||||
@@ -480,7 +384,7 @@ class todo extends control
|
||||
*/
|
||||
public function finish(string $todoID)
|
||||
{
|
||||
$todo = $this->todo->getById((int)$todoID);
|
||||
$todo = $this->todo->getByID((int)$todoID);
|
||||
if($todo->status != 'done' && $todo->status != 'closed') $this->todo->finish((int)$todoID);
|
||||
|
||||
if(in_array($todo->type, array('bug', 'task', 'story')))
|
||||
@@ -488,15 +392,20 @@ class todo extends control
|
||||
$confirmNote = 'confirm' . ucfirst($todo->type);
|
||||
$okTarget = isonlybody() ? 'parent' : 'window.parent.$.apps.open';
|
||||
$confirmURL = $this->createLink($todo->type, 'view', "id=$todo->objectID");
|
||||
|
||||
if($todo->type == 'bug') $app = 'qa';
|
||||
if($todo->type == 'task') $app = 'execution';
|
||||
if($todo->type == 'story') $app = 'product';
|
||||
$cancelURL = $this->server->HTTP_REFERER;
|
||||
$cancelURL = $this->server->http_referer;
|
||||
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success', 'message' => sprintf($this->lang->todo->$confirmNote, $todo->objectID), 'locate' => $confirmURL));
|
||||
return print(strpos($cancelURL, 'calendar') ? json_encode(array(sprintf($this->lang->todo->$confirmNote, $todo->objectID), $confirmURL)) : js::confirm(sprintf($this->lang->todo->$confirmNote, $todo->objectID), $confirmURL, $cancelURL, $okTarget, 'parent', $app));
|
||||
}
|
||||
|
||||
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success'));
|
||||
if(defined('RUN_MODE') && RUN_MODE == 'api')
|
||||
{
|
||||
$this->send(array('status' => 'success'));
|
||||
return;
|
||||
}
|
||||
if(isonlybody()) return print(js::reload('parent.parent'));
|
||||
echo js::reload('parent');
|
||||
}
|
||||
@@ -518,8 +427,8 @@ class todo extends control
|
||||
if($todo->status == 'done' || $todo->status == 'closed') unset($todoList[$todoID]);
|
||||
}
|
||||
|
||||
$res = $this->todo->batchFinish((array)array_keys($todoList));
|
||||
if(!$res) return false;
|
||||
$isBatchFinished = $this->todo->batchFinish(array_keys($todoList));
|
||||
if(!$isBatchFinished) return false;
|
||||
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
@@ -529,27 +438,27 @@ class todo extends control
|
||||
* Batch close todos. The status of todo which need to close should be done.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function batchClose(): void
|
||||
public function batchClose(): int
|
||||
{
|
||||
$waitIdList = array();
|
||||
$todoIdlist = form::data($this->config->todo->batchClose->form)->get('todoIDList');
|
||||
foreach($todoIdlist as $todoID)
|
||||
{
|
||||
$todoID = (int) $todoID;
|
||||
$todo = $this->todo->getById($todoID);
|
||||
$todo = $this->todo->getByID($todoID);
|
||||
if($todo->status == 'done') $this->todo->close($todoID);
|
||||
if($todo->status != 'done' and $todo->status != 'closed') $waitIdList[] = $todoID;
|
||||
}
|
||||
if(!empty($waitIdList)) echo js::alert(sprintf($this->lang->todo->unfinishedTodo, implode(',', $waitIdList)));
|
||||
|
||||
echo js::reload('parent');
|
||||
return print(js::reload('parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改选中待办的日期。
|
||||
* Import selected todoes to today.
|
||||
* Import selected todos to today.
|
||||
*
|
||||
* @param string $todoID
|
||||
* @access public
|
||||
@@ -559,10 +468,10 @@ class todo extends control
|
||||
{
|
||||
$todoIDList = $_POST ? $this->post->todoIDList : array($todoID);
|
||||
$date = !empty($_POST['date']) ? $_POST['date'] : date::today();
|
||||
if(!$date || !$todoIDList) $this->locate((string)$this->session->todoList);
|
||||
if(!$date || !$todoIDList) return $this->locate((string)$this->session->todoList);
|
||||
|
||||
$this->todo->editDate((array)$todoIDList, (string)$date);
|
||||
$this->locate((string)$this->session->todoList);
|
||||
return this->locate((string)$this->session->todoList);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -577,7 +486,7 @@ class todo extends control
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$user = $this->loadModel('user')->getById($userID, 'id');
|
||||
$user = $this->loadModel('user')->getByID($userID, 'id');
|
||||
$account = $user->account;
|
||||
|
||||
$todoLang = $this->lang->todo;
|
||||
|
||||
+45
-48
@@ -2,7 +2,7 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* The model file of example module of ZenTaoPMS.
|
||||
* The model file of todo module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
|
||||
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
@@ -128,7 +128,7 @@ class todoModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新待办数据
|
||||
* 更新待办数据。
|
||||
* update a todo.
|
||||
*
|
||||
* @param int $todoID
|
||||
@@ -138,7 +138,7 @@ class todoModel extends model
|
||||
*/
|
||||
public function update(int $todoID, object $todo): array|false
|
||||
{
|
||||
$oldTodo = $this->dao->findById($todoID)->from(TABLE_TODO)->fetch();
|
||||
$oldTodo = $this->dao->findByID($todoID)->from(TABLE_TODO)->fetch();
|
||||
|
||||
if(!$this->todoTao->updateRow($todoID, $todo)) return false;
|
||||
|
||||
@@ -191,7 +191,7 @@ class todoModel extends model
|
||||
foreach($todos as $todoID => $todo)
|
||||
{
|
||||
$oldTodo = $oldTodos[$todoID];
|
||||
if(in_array($todo->type, $this->config->todo->moduList)) $oldTodo->name = '';
|
||||
if(in_array($todo->type, $this->config->todo->moduleList)) $oldTodo->name = '';
|
||||
$this->dao->update(TABLE_TODO)->data($todo)
|
||||
->autoCheck()
|
||||
->checkIF(!in_array($todo->type, $this->config->todo->moduleList), $this->config->todo->edit->requiredFields, 'notempty')
|
||||
@@ -271,8 +271,8 @@ class todoModel extends model
|
||||
{
|
||||
foreach($todoIDList as $todoID)
|
||||
{
|
||||
$res = $this->dealFinishData($todoID);
|
||||
if(!$res) return $res;
|
||||
$finishResult = $this->dealFinishData($todoID);
|
||||
if(!$finishResult) return $finishResult;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -288,20 +288,20 @@ class todoModel extends model
|
||||
*/
|
||||
public function getByID(int $todoID, $setImgSize = false): object|false
|
||||
{
|
||||
$todo = $this->dao->findById($todoID)->from(TABLE_TODO)->fetch();
|
||||
$todo = $this->dao->findByID($todoID)->from(TABLE_TODO)->fetch();
|
||||
if(!$todo) return false;
|
||||
|
||||
$todo = $this->loadModel('file')->replaceImgURL((object)$todo, 'desc');
|
||||
if($setImgSize) $todo->desc = $this->file->setImgSize($todo->desc);
|
||||
if($todo->type == 'story') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_STORY)->fetch('title');
|
||||
if($todo->type == 'task') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_TASK)->fetch('name');
|
||||
if($todo->type == 'bug') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_BUG)->fetch('title');
|
||||
if($todo->type == 'issue' and $this->config->edition == 'max') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_ISSUE)->fetch('title');
|
||||
if($todo->type == 'risk' and $this->config->edition == 'max') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_RISK)->fetch('name');
|
||||
if($todo->type == 'opportunity' and $this->config->edition == 'max') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_OPPORTUNITY)->fetch('name');
|
||||
if($todo->type == 'review' and $this->config->edition == 'max') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_REVIEW)->fetch('title');
|
||||
if($todo->type == 'testtask') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_TESTTASK)->fetch('name');
|
||||
if($todo->type == 'feedback') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_FEEDBACK)->fetch('title');
|
||||
if($todo->type == 'story') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_STORY)->fetch('title');
|
||||
if($todo->type == 'task') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_TASK)->fetch('name');
|
||||
if($todo->type == 'bug') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_BUG)->fetch('title');
|
||||
if($todo->type == 'issue' and $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_ISSUE)->fetch('title');
|
||||
if($todo->type == 'risk' and $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_RISK)->fetch('name');
|
||||
if($todo->type == 'opportunity' and $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_OPPORTUNITY)->fetch('name');
|
||||
if($todo->type == 'review' and $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_REVIEW)->fetch('title');
|
||||
if($todo->type == 'testtask') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_TESTTASK)->fetch('name');
|
||||
if($todo->type == 'feedback') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_FEEDBACK)->fetch('title');
|
||||
$todo->date = str_replace('-', '', $todo->date);
|
||||
|
||||
return $todo;
|
||||
@@ -412,15 +412,15 @@ class todoModel extends model
|
||||
|
||||
while($todo = $stmt->fetch())
|
||||
{
|
||||
if($todo->type == 'story') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_STORY)->fetch('title');
|
||||
if($todo->type == 'task') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_TASK)->fetch('name');
|
||||
if($todo->type == 'bug') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_BUG)->fetch('title');
|
||||
if($todo->type == 'testtask') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_TESTTASK)->fetch('name');
|
||||
if($todo->type == 'issue' && $this->config->edition == 'max') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_ISSUE)->fetch('title');
|
||||
if($todo->type == 'risk' && $this->config->edition == 'max') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_RISK)->fetch('name');
|
||||
if($todo->type == 'opportunity' && $this->config->edition == 'max') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_OPPORTUNITY)->fetch('name');
|
||||
if($todo->type == 'review' && $this->config->edition == 'max') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_REVIEW)->fetch('title');
|
||||
if($todo->type == 'feedback' and $this->config->edition != 'open') $todo->name = $this->dao->findById($todo->objectID)->from(TABLE_FEEDBACK)->fetch('title');
|
||||
if($todo->type == 'story') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_STORY)->fetch('title');
|
||||
if($todo->type == 'task') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_TASK)->fetch('name');
|
||||
if($todo->type == 'bug') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_BUG)->fetch('title');
|
||||
if($todo->type == 'testtask') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_TESTTASK)->fetch('name');
|
||||
if($todo->type == 'issue' && $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_ISSUE)->fetch('title');
|
||||
if($todo->type == 'risk' && $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_RISK)->fetch('name');
|
||||
if($todo->type == 'opportunity' && $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_OPPORTUNITY)->fetch('name');
|
||||
if($todo->type == 'review' && $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_REVIEW)->fetch('title');
|
||||
if($todo->type == 'feedback' and $this->config->edition != 'open') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_FEEDBACK)->fetch('title');
|
||||
$todo->begin = date::formatTime($todo->begin);
|
||||
$todo->end = date::formatTime($todo->end);
|
||||
|
||||
@@ -556,18 +556,16 @@ class todoModel extends model
|
||||
{
|
||||
$isClosed = $this->todoTao->closeTodo($todoID);
|
||||
|
||||
if($isClosed)
|
||||
{
|
||||
$this->loadModel('action')->create('todo', $todoID, 'closed', '', 'closed');
|
||||
if(!$isClosed) return false;
|
||||
|
||||
if($this->config->edition == 'biz' || $this->config->edition == 'max')
|
||||
{
|
||||
$feedbackID = $this->dao->select('objectID')->from(TABLE_TODO)->where('id')->eq($todoID)->andWhere('type')->eq('feedback')->fetch('objectID');
|
||||
if($feedbackID) $this->loadModel('feedback')->updateStatus('todo', $feedbackID, 'closed');
|
||||
}
|
||||
return true;
|
||||
$this->loadModel('action')->create('todo', $todoID, 'closed', '', 'closed');
|
||||
|
||||
if($this->config->edition == 'biz' || $this->config->edition == 'max')
|
||||
{
|
||||
$feedbackID = $this->dao->select('objectID')->from(TABLE_TODO)->where('id')->eq($todoID)->andWhere('type')->eq('feedback')->fetch('objectID');
|
||||
if($feedbackID) $this->loadModel('feedback')->updateStatus('todo', $feedbackID, 'closed');
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -656,25 +654,24 @@ class todoModel extends model
|
||||
$todo->finishedBy = $this->app->user->account;
|
||||
$this->todoTao->updateRow($todoID, $todo);
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$this->loadModel('action')->create('todo', $todoID, 'finished', '', 'done');
|
||||
if(dao::isError()) return false;
|
||||
|
||||
if(($this->config->edition == 'biz' || $this->config->edition == 'max'))
|
||||
{
|
||||
$todo = $this->todoTao->fetch($todoID);
|
||||
$feedbackID = $todo->idvalue ?? '' ;
|
||||
if($feedbackID) $this->loadModel('feedback')->updateStatus('todo', $feedbackID, 'done');
|
||||
}
|
||||
return true;
|
||||
$this->loadModel('action')->create('todo', $todoID, 'finished', '', 'done');
|
||||
|
||||
if(($this->config->edition == 'biz' || $this->config->edition == 'max'))
|
||||
{
|
||||
$todo = $this->todoTao->fetch($todoID);
|
||||
$feedbackID = $todo->idvalue ?? '' ;
|
||||
if($feedbackID) $this->loadModel('feedback')->updateStatus('todo', $feedbackID, 'done');
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 修改待办事项的时间。
|
||||
/**
|
||||
* 修改待办事项的时间。
|
||||
* Edit the date of todo.
|
||||
*
|
||||
* @param array $idList
|
||||
* @param array $todoIDList
|
||||
* @param string $date
|
||||
* @access public
|
||||
* @return int
|
||||
|
||||
+16
-17
@@ -75,11 +75,10 @@ class todoTao extends todoModel
|
||||
->where('id')->eq($todoID)
|
||||
->exec();
|
||||
return !dao::isError();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* 处理要创建的todo的数据
|
||||
/**
|
||||
* 处理要创建的todo的数据。
|
||||
* Process the data for the todo to be created.
|
||||
*
|
||||
* @param object $todoData
|
||||
@@ -118,13 +117,13 @@ class todoTao extends todoModel
|
||||
}
|
||||
if(empty($todoData->cycle)) unset($todoData->config);
|
||||
|
||||
$todoData = $this->loadModel('file')->processImgURL($todoData, $this->config->todo->editor->create['id'], $this->post->uid);
|
||||
return $todoData;
|
||||
return $this->loadModel('file')->processImgURL($todoData, $this->config->todo->editor->create['id'], $this->post->uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取周期待办列表
|
||||
* Get cycle list.
|
||||
* 获取周期待办列表。
|
||||
* Get cycle list.
|
||||
*
|
||||
* @param array $todoList
|
||||
* @param string $orderBy
|
||||
* @access protected
|
||||
@@ -132,18 +131,18 @@ class todoTao extends todoModel
|
||||
*/
|
||||
protected function getCycleList(array $todoList, string $orderBy = 'date_asc'): array
|
||||
{
|
||||
return $this->dao->select('*')
|
||||
->from(TABLE_TODO)->where('type')->eq('cycle')
|
||||
return $this->dao->select('*')->from(TABLE_TODO)
|
||||
->where('type')->eq('cycle')
|
||||
->andWhere('deleted')->eq('0')
|
||||
->andWhere('objectID')->in(array_keys($todoList))
|
||||
->orderBy($orderBy)
|
||||
->fetchAll('objectID');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过待办构建周期待办数据
|
||||
* Build cycle todo.
|
||||
*
|
||||
* @param object $todo
|
||||
* @access protected
|
||||
* @return stdclass
|
||||
@@ -168,9 +167,9 @@ class todoTao extends todoModel
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过周期待办,获取要生成待办的日期
|
||||
*
|
||||
* 通过周期待办,获取要生成待办的日期。
|
||||
* Gets the date by the cycle todo.
|
||||
*
|
||||
* @param object $todo
|
||||
* @param object|string $lastCycle
|
||||
* @param string $today
|
||||
@@ -207,8 +206,7 @@ class todoTao extends todoModel
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过周期待办,获取要生成每日待办的日期
|
||||
*
|
||||
* 通过周期待办,获取要生成每日待办的日期。
|
||||
* Gets the daily todo date by the cycle todo.
|
||||
*
|
||||
* @param object $todo
|
||||
@@ -305,6 +303,7 @@ class todoTao extends todoModel
|
||||
return false;
|
||||
}
|
||||
$todoData->config['beforeDays'] = (int)$todoData->config['beforeDays'];
|
||||
|
||||
$todoData->config = json_encode($todoData->config);
|
||||
$todoData->type = 'cycle';
|
||||
|
||||
@@ -317,11 +316,11 @@ class todoTao extends todoModel
|
||||
*
|
||||
* @param array $idList
|
||||
* @param string $date
|
||||
* @return int
|
||||
* @return bool
|
||||
*/
|
||||
protected function updateDate(array $todoIdList, string $date): int
|
||||
protected function updateDate(array $todoIdList, string $date): bool
|
||||
{
|
||||
$this->dao->update(TABLE_TODO)->set('date')->eq($date)->where('id')->in($todoIdList)->exec();
|
||||
return dao::isError() ? 0 : 1;
|
||||
return !dao::isError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
include dirname(__FILE__, 5) . "/test/lib/init.php";
|
||||
include dirname(__FILE__, 2) . '/todo.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
declare(strict_types=1);
|
||||
namespace zin;
|
||||
/**
|
||||
* The batch create view of todo module of ZenTaoPMS.
|
||||
* AssignTo view of todo module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
|
||||
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Yue Liu <liuyue@easycorp.ltd>
|
||||
* @package todo
|
||||
* @version $Id: create.html.php 2741 2012-04-07 07:24:21 $
|
||||
* @link http://www.zentao.net
|
||||
* @link https://www.zentao.net
|
||||
*/
|
||||
|
||||
set::title($lang->todo->assignedTo);
|
||||
|
||||
+145
-14
@@ -3,11 +3,48 @@ declare(strict_types=1);
|
||||
|
||||
class todoZen extends todo
|
||||
{
|
||||
/**
|
||||
* 生成创建待办视图数据。
|
||||
* Build create form data.
|
||||
*
|
||||
* @param string $date
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function buildCreateView(string $date): void
|
||||
{
|
||||
$this->view->title = $this->lang->todo->common . $this->lang->colon . $this->lang->todo->create;
|
||||
$this->view->date = date('Y-m-d', strtotime($date));
|
||||
$this->view->times = date::buildTimeList($this->config->todo->times->begin, $this->config->todo->times->end, $this->config->todo->times->delta);
|
||||
$this->view->time = date::now();
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|noempty');
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成编辑待办视图数据。
|
||||
* Build create form data.
|
||||
*
|
||||
* @param object $todo
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function buildEditView(object $todo): void
|
||||
{
|
||||
$todo->date = date("Y-m-d", strtotime($todo->date));
|
||||
$this->view->title = $this->lang->todo->common . $this->lang->colon . $this->lang->todo->edit;
|
||||
$this->view->times = date::buildTimeList($this->config->todo->times->begin, $this->config->todo->times->end, $this->config->todo->times->delta);
|
||||
$this->view->todo = $todo;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|noempty');
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求数据
|
||||
* Processing request data.
|
||||
*
|
||||
* @process protected
|
||||
* @param object $formData
|
||||
* @access protected
|
||||
* @return object
|
||||
@@ -36,12 +73,13 @@ class todoZen extends todo
|
||||
->stripTags($this->config->todo->editor->create['id'], $this->config->allowedTags)
|
||||
->remove(implode(',', $this->config->todo->moduleList) . ',uid')
|
||||
->get();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a todo after data processing
|
||||
* 创建完成待办后数据处理
|
||||
* 创建完成待办后数据处理。
|
||||
* Create a todo after data processing.
|
||||
*
|
||||
* @param object $todo
|
||||
* @access protected
|
||||
@@ -65,7 +103,7 @@ class todoZen extends todo
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理编辑待办的请求数据
|
||||
* 处理编辑待办的请求数据。
|
||||
* Processing edit request data.
|
||||
*
|
||||
* @param int $todoID
|
||||
@@ -75,7 +113,7 @@ class todoZen extends todo
|
||||
*/
|
||||
protected function beforeEdit(int $todoID, object $formData): object|false
|
||||
{
|
||||
$oldTodo = $this->dao->findById($todoID)->from(TABLE_TODO)->fetch();
|
||||
$oldTodo = $this->dao->findByID($todoID)->from(TABLE_TODO)->fetch();
|
||||
|
||||
$objectID = 0;
|
||||
$rowData = $formData->rawdata;
|
||||
@@ -96,7 +134,7 @@ class todoZen extends todo
|
||||
->remove(implode(',', $this->config->todo->moduleList) . ',uid')
|
||||
->get();
|
||||
|
||||
$todo = (object) array_merge((array) $rowData, (array) $todo);
|
||||
$todo = (object)array_merge((array)$rowData, (array)$todo);
|
||||
|
||||
if(in_array($todo->type, $this->config->todo->moduleList))
|
||||
{
|
||||
@@ -114,9 +152,7 @@ class todoZen extends todo
|
||||
|
||||
if(!empty($oldTodo->cycle)) $this->handleCycleConfig($todo);
|
||||
|
||||
$todo = $this->loadModel('file')->processImgURL($todo, $this->config->todo->editor->edit['id'], $rowData->uid);
|
||||
|
||||
return $todo;
|
||||
return $this->loadModel('file')->processImgURL($todo, $this->config->todo->editor->edit['id'], $rowData->uid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,15 +171,109 @@ class todoZen extends todo
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
protected function batchEditFromMyTodo($type, $userID, $status)
|
||||
{
|
||||
/* Initialize vars. */
|
||||
$editedTodos = array();
|
||||
$todoIDList = array();
|
||||
$reviews = array();
|
||||
$columns = 7;
|
||||
|
||||
if($userID == '') $userID = $this->app->user->id;
|
||||
$user = $this->loadModel('user')->getById($userID, 'id');
|
||||
$account = $user->account;
|
||||
|
||||
if($this->config->edition == 'max') $reviews = $this->loadModel('review')->getUserReviewPairs($account);
|
||||
$allTodos = $this->todo->getList($type, $account, $status);
|
||||
if($this->post->todoIDList) $todoIDList = $this->post->todoIDList;
|
||||
|
||||
/* Initialize todos whose need to edited. */
|
||||
foreach($allTodos as $todo)
|
||||
{
|
||||
if(in_array($todo->id, $todoIDList))
|
||||
{
|
||||
$editedTodos[$todo->id] = $todo;
|
||||
if($todo->type != 'custom')
|
||||
{
|
||||
if(!isset($objectIDList[$todo->type])) $objectIDList[$todo->type] = array();
|
||||
$objectIDList[$todo->type][$todo->objectID] = $todo->objectID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$bugs = $this->bug->getUserBugPairs($account, true, 0, '', '', isset($objectIDList['bug']) ? $objectIDList['bug'] : '');
|
||||
$tasks = $this->task->getUserTaskPairs($account, 'wait,doing', '', isset($objectIDList['task']) ? $objectIDList['task'] : '');
|
||||
$storys = $this->loadModel('story')->getUserStoryPairs($account, 10, 'story', '', isset($objectIDList['story']) ? $objectIDList['story'] : '');
|
||||
if($this->config->edition != 'open') $this->view->feedbacks = $this->loadModel('feedback')->getUserFeedbackPairs($account, '', isset($objectIDList['feedback']) ? $objectIDList['feedback'] : '');
|
||||
if($this->config->edition == 'max')
|
||||
{
|
||||
$issues = $this->loadModel('issue')->getUserIssuePairs($account);
|
||||
$risks = $this->loadmodel('risk')->getUserRiskPairs($account);
|
||||
$opportunities = $this->loadmodel('opportunity')->getUserOpportunityPairs($account);
|
||||
}
|
||||
$testtasks = $this->loadModel('testtask')->getUserTestTaskPairs($account);
|
||||
|
||||
/* Judge whether the edited todos is too large. */
|
||||
$countInputVars = count($editedTodos) * $columns;
|
||||
$showSuhosinInfo = common::judgeSuhosinSetting($countInputVars);
|
||||
|
||||
unset($this->lang->todo->typeList['cycle']);
|
||||
/* Set Custom*/
|
||||
foreach(explode(',', $this->config->todo->list->customBatchEditFields) as $field) $customFields[$field] = $this->lang->todo->$field;
|
||||
$this->view->customFields = $customFields;
|
||||
$this->view->showFields = $this->config->todo->custom->batchEditFields;
|
||||
|
||||
/* Assign. */
|
||||
$title = $this->lang->todo->common . $this->lang->colon . $this->lang->todo->batchEdit;
|
||||
$position[] = html::a($this->createLink('my', 'todo'), $this->lang->my->todo);
|
||||
$position[] = $this->lang->todo->common;
|
||||
$position[] = $this->lang->todo->batchEdit;
|
||||
|
||||
if($showSuhosinInfo) $this->view->suhosinInfo = extension_loaded('suhosin') ? sprintf($this->lang->suhosinInfo, $countInputVars) : sprintf($this->lang->maxVarsInfo, $countInputVars);
|
||||
$this->view->bugs = $bugs;
|
||||
$this->view->tasks = $tasks;
|
||||
$this->view->storys = $storys;
|
||||
if($this->config->edition == 'max')
|
||||
{
|
||||
$this->view->issues = $issues;
|
||||
$this->view->risks = $risks;
|
||||
$this->view->opportunities = $opportunities;
|
||||
}
|
||||
$this->view->reviews = $reviews;
|
||||
$this->view->testtasks = $testtasks;
|
||||
$this->view->editedTodos = $editedTodos;
|
||||
$this->view->times = date::buildTimeList($this->config->todo->times->begin, $this->config->todo->times->end, $this->config->todo->times->delta);
|
||||
$this->view->time = date::now();
|
||||
$this->view->title = $title;
|
||||
$this->view->position = $position;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|noempty');
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
protected function batchEditFromTodoBatchEdit($formData)
|
||||
{
|
||||
$allChanges = $this->todo->batchUpdate();
|
||||
foreach($allChanges as $todoID => $changes)
|
||||
{
|
||||
if(empty($changes)) continue;
|
||||
|
||||
$actionID = $this->loadModel('action')->create('todo', $todoID, 'edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
return print(js::locate($this->session->todoList, 'parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理循环待办的配置文件
|
||||
* 处理周期待办的配置值。
|
||||
* Handle cycle config.
|
||||
*
|
||||
* @param object $todo
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function handleCycleConfig(object &$todo): void
|
||||
private function handleCycleConfig(object $todo): void
|
||||
{
|
||||
$todo->date = date('Y-m-d');
|
||||
$todo->config['begin'] = $todo->date;
|
||||
@@ -215,7 +345,7 @@ class todoZen extends todo
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出确认弹框
|
||||
* 输出确认弹框。
|
||||
* Output confirm alert.
|
||||
*
|
||||
* @param object $todo
|
||||
@@ -230,7 +360,8 @@ class todoZen extends todo
|
||||
if($todo->type == 'bug') $app = 'qa';
|
||||
if($todo->type == 'task') $app = 'execution';
|
||||
if($todo->type == 'story') $app = 'product';
|
||||
$cancelURL = $this->server->HTTP_REFERER;
|
||||
$cancelURL = $this->server->http_referer;
|
||||
|
||||
return print(js::confirm(sprintf($this->lang->todo->$confirmNote, $todo->objectID), $confirmURL, $cancelURL, $okTarget, 'parent', $app));
|
||||
}
|
||||
|
||||
@@ -244,7 +375,7 @@ class todoZen extends todo
|
||||
protected function getProjectPairsByModel(string $model): array
|
||||
{
|
||||
$model = $model == 'opportunity' ? 'waterfall' : 'all';
|
||||
return $this->loadModel('project')->getPairsByModel((string)$model);
|
||||
return $this->loadModel('project')->getPairsByModel($model);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user