This commit is contained in:
liyang
2023-04-28 16:28:17 +08:00
21 changed files with 871 additions and 786 deletions
+2 -6
View File
@@ -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;
}
/**
+7 -79
View File
@@ -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
View File
@@ -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';
+89
View File
@@ -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');
+223
View File
@@ -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
View File
@@ -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();
}
+1
View File
@@ -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;
+78
View File
@@ -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
View File
@@ -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
View File
@@ -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'));
}
}
+19 -3
View File
@@ -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
View File
@@ -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();
}
}
+49 -13
View File
@@ -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
View File
@@ -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);
}
}
}
+5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();
}
}
-1
View File
@@ -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');
/**
+4 -5
View File
@@ -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
View File
@@ -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);
}
/**