Merge branch 'sunhuawei_fixbug_19247'
This commit is contained in:
+1
-1
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
|
||||
if(!function_exists('getWebRoot')){function getWebRoot(){}}
|
||||
|
||||
/* 基本设置。Basic settings. */
|
||||
$config->version = '16.3'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
|
||||
$config->version = '16.4'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
|
||||
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
|
||||
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
|
||||
$config->timezone = 'Asia/Shanghai'; // 时区设置。 The time zone setting, for more see http://www.php.net/manual/en/timezones.php.
|
||||
|
||||
@@ -23,6 +23,14 @@ $config->productCommonList['fr'][0] = 'Product';
|
||||
$config->productCommonList['fr'][1] = 'Project';
|
||||
$config->productCommonList['vi'][0] = 'Sản phẩm';
|
||||
$config->productCommonList['vi'][1] = 'Project';
|
||||
$config->productCommonList['ru'][0] = 'продукт';
|
||||
$config->productCommonList['ru'][1] = 'Проект';
|
||||
$config->productCommonList['ja'][0] = '製品';
|
||||
$config->productCommonList['ja'][1] = 'プロジェクト';
|
||||
$config->productCommonList['es'][0] = 'Productos';
|
||||
$config->productCommonList['es'][1] = 'Proyecto';
|
||||
$config->productCommonList['pt'][0] = 'produto';
|
||||
$config->productCommonList['pt'][1] = 'projecto';
|
||||
|
||||
/* Project common list. */
|
||||
$config->projectCommonList['zh-cn'][0] = '项目';
|
||||
@@ -49,6 +57,22 @@ $config->projectCommonList['vi'][0] = 'Project';
|
||||
$config->projectCommonList['vi'][1] = 'Iteration';
|
||||
$config->projectCommonList['vi'][2] = 'Sprint';
|
||||
|
||||
$config->projectCommonList['ru'][0] = 'Проект';
|
||||
$config->projectCommonList['ru'][1] = 'итерация';
|
||||
$config->projectCommonList['ru'][2] = 'пробивание';
|
||||
|
||||
$config->projectCommonList['ja'][0] = 'プロジェクト';
|
||||
$config->projectCommonList['ja'][1] = '反復';
|
||||
$config->projectCommonList['ja'][2] = 'スパート';
|
||||
|
||||
$config->projectCommonList['es'][0] = 'Proyecto';
|
||||
$config->projectCommonList['es'][1] = 'Iteración';
|
||||
$config->projectCommonList['es'][2] = 'Sprint';
|
||||
|
||||
$config->projectCommonList['pt'][0] = 'Projecto';
|
||||
$config->projectCommonList['pt'][1] = 'Iteração';
|
||||
$config->projectCommonList['pt'][2] = 'Sprint';
|
||||
|
||||
$config->executionCommonList['zh-cn'][0] = '迭代';
|
||||
$config->executionCommonList['zh-cn'][1] = '冲刺';
|
||||
$config->executionCommonList['zh-cn'][2] = '阶段';
|
||||
@@ -73,6 +97,22 @@ $config->executionCommonList['vi'][0] = 'Lặp lại';
|
||||
$config->executionCommonList['vi'][1] = 'Sprint';
|
||||
$config->executionCommonList['vi'][2] = 'Giai đoạn';
|
||||
|
||||
$config->executionCommonList['ru'][0] = 'итерация';
|
||||
$config->executionCommonList['ru'][1] = 'пробивание';
|
||||
$config->executionCommonList['ru'][2] = ' этап';
|
||||
|
||||
$config->executionCommonList['ja'][0] = '反復';
|
||||
$config->executionCommonList['ja'][1] = 'スパート';
|
||||
$config->executionCommonList['ja'][2] = 'ステージ';
|
||||
|
||||
$config->executionCommonList['es'][0] = 'Iteración';
|
||||
$config->executionCommonList['es'][1] = 'Sprint';
|
||||
$config->executionCommonList['es'][2] = 'Fase';
|
||||
|
||||
$config->executionCommonList['pt'][0] = 'Iteração';
|
||||
$config->executionCommonList['pt'][1] = 'Sprint';
|
||||
$config->executionCommonList['pt'][2] = 'Fase';
|
||||
|
||||
/* Story common list. */
|
||||
$config->hourPointCommonList['zh-cn'][0] = '工时';
|
||||
$config->hourPointCommonList['zh-cn'][1] = '故事点';
|
||||
@@ -98,6 +138,22 @@ $config->hourPointCommonList['vi'][0] = 'giờ';
|
||||
$config->hourPointCommonList['vi'][1] = 'điểm';
|
||||
$config->hourPointCommonList['vi'][2] = 'function point';
|
||||
|
||||
$config->hourPointCommonList['ru'][0] = 'продолжительность рабочего времени';
|
||||
$config->hourPointCommonList['ru'][1] = 'точка повести';
|
||||
$config->hourPointCommonList['ru'][2] = 'функциональная точка';
|
||||
|
||||
$config->hourPointCommonList['ja'][0] = '工数';
|
||||
$config->hourPointCommonList['ja'][1] = 'ストーリーポイント';
|
||||
$config->hourPointCommonList['ja'][2] = 'きのうてん';
|
||||
|
||||
$config->hourPointCommonList['es'][0] = 'Horas de trabajo';
|
||||
$config->hourPointCommonList['es'][1] = 'Punto de historia';
|
||||
$config->hourPointCommonList['es'][2] = 'Punto de función';
|
||||
|
||||
$config->hourPointCommonList['pt'][0] = 'horas de trabalho';
|
||||
$config->hourPointCommonList['pt'][1] = 'Ponto da história';
|
||||
$config->hourPointCommonList['pt'][2] = 'Ponto de função';
|
||||
|
||||
$config->manualUrl['home'] = 'https://www.zentao.net/book/zentaopmshelp.html?fullScreen=zentao';
|
||||
$config->manualUrl['int'] = 'https://www.zentao.pm/book/zentaomanual/zentao-installation-11.html?fullScreen=zentao';
|
||||
|
||||
@@ -114,6 +170,14 @@ $config->charsets['fr']['utf-8'] = 'UTF-8';
|
||||
$config->charsets['fr']['GBK'] = 'GBK';
|
||||
$config->charsets['vi']['utf-8'] = 'UTF-8';
|
||||
$config->charsets['vi']['GBK'] = 'GBK';
|
||||
$config->charsets['ru']['utf-8'] = 'UTF-8';
|
||||
$config->charsets['ru']['GBK'] = 'GBK';
|
||||
$config->charsets['ja']['utf-8'] = 'UTF-8';
|
||||
$config->charsets['ja']['GBK'] = 'GBK';
|
||||
$config->charsets['es']['utf-8'] = 'UTF-8';
|
||||
$config->charsets['es']['GBK'] = 'GBK';
|
||||
$config->charsets['pt']['utf-8'] = 'UTF-8';
|
||||
$config->charsets['pt']['GBK'] = 'GBK';
|
||||
|
||||
$config->openMethods = array();
|
||||
$config->openMethods[] = 'gitlab.webhook';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@ CREATE TABLE `zt_kanban` (
|
||||
`desc` text NOT NULL,
|
||||
`acl` char(30) NOT NULL DEFAULT 'open',
|
||||
`whitelist` text NOT NULL,
|
||||
`archived` enum('0', '1') NOT NULL DEFAULT '1',
|
||||
`archived` enum('0', '1') NOT NULL DEFAULT '0',
|
||||
`status` enum('active','closed') NOT NULL default 'active',
|
||||
`order` smallint(6) NOT NULL DEFAULT '0',
|
||||
`createdBy` char(30) NOT NULL,
|
||||
|
||||
@@ -1,3 +1,34 @@
|
||||
2022-02-15 16.4
|
||||
完成的需求
|
||||
30526 实现JIRA数据导入到禅道功能
|
||||
30675 优化禅道中SonarQube的扫描结果详情页面
|
||||
30583 SonarQube免登录探针需求
|
||||
30576 在禅道中当对应的GitLab项目的代码库为空时,隐藏GitLab项目下下关于分支与标签操作的按钮。
|
||||
30559 在禅道中设置GitLab项目或群组权限为公开时给予告警提示
|
||||
30558 实现GitLab群组URL可点击的功能
|
||||
30556 GitLab服务器列表中地址可点击
|
||||
30554 修改GitLab服务器列表“GitLab名称”为“GitLab服务器”
|
||||
30553 在禅道中实现创建GitLab服务器时对当前GitLab版本进行兼容性检查功能
|
||||
30552 在禅道中针对无权限用户将合并请求编辑按钮置灰
|
||||
30461 实现在禅道中将SonarQube问题转成禅道Bug的功能
|
||||
30455 实现SonarQube问题详情页面
|
||||
30453 实现SonarQube问题列表页面的搜索功能
|
||||
30451 实现SonarQube问题列表页面的返回功能
|
||||
30447 在SonarQube扫描报告概要页面添加问题详情列表的入口
|
||||
30443 实现在添加/编辑SonarQube服务器时验证填写用户是否为SonarQube管理员的功能
|
||||
30183 实现从禅道SonarQube项目列表查看SonarQube代码检查结果的入口
|
||||
29859 实现禅道中创建SonarQube项目功能
|
||||
29241 实现构建通知发送到喧喧功能
|
||||
29228 实现SonarQube项目问题列表页面
|
||||
修复的BUG
|
||||
18816 DevOps-代码中,GitLab类型的版本库代码内容未显示完全
|
||||
18382 代码页面版本列版本号显示不一致
|
||||
18380 历史记录中重复显示多条记录
|
||||
18104 VS Code COMMIT_EDITMSG文件中应只显示未选中的需求/Bug/任务
|
||||
18076 VSCode中查看项目/执行下的需求时应跳转到项目/执行下的需求详情页
|
||||
17869 VScode中查看需求、任务和Bug提示“请求后端出错”
|
||||
17851 vscode查看执行下的需求,提示先选择项目
|
||||
|
||||
2022-01-26 16.3
|
||||
完成的需求
|
||||
29706 研发看板相关操作支持平滑刷新方式呈现
|
||||
|
||||
@@ -321,7 +321,7 @@ class block extends control
|
||||
$pager = new pager(0, 30, 1);
|
||||
|
||||
$this->view->actions = $this->loadModel('action')->getDynamic('all', 'today', 'date_desc', $pager);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|noletter|all');
|
||||
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noletter|all');
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
|
||||
<?php else:?>
|
||||
<style>
|
||||
.status-bars {display: table;width: 60%;height: 140px;padding: 5px;padding-top: 50px;margin: 0;overflow: hidden;}
|
||||
.status-bars {display: table; width: 80%; height: 140px; padding: 5px; padding-top: 50px; margin: 0; overflow: hidden;}
|
||||
</style>
|
||||
<div class="panel-body table-row">
|
||||
<div class="col-4 text-middle text-center">
|
||||
|
||||
@@ -189,10 +189,13 @@ $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';
|
||||
if($config->systemMode == 'new')
|
||||
{
|
||||
$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['execution']['title'] = 'execution';
|
||||
$config->bug->datatable->fieldList['execution']['fixed'] = 'no';
|
||||
|
||||
@@ -2228,6 +2228,6 @@ class bug extends control
|
||||
{
|
||||
$project = $this->loadModel('project')->getByID($projectID);
|
||||
if($project->model == 'kanban') return print($this->lang->bug->kanban);
|
||||
if($project->model != 'kanban') return print($this->lang->bug->execution);
|
||||
return print($this->lang->bug->execution);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
.main-table {height: 600px !important}
|
||||
#mainContent {min-height: 400px;}
|
||||
|
||||
@@ -19,6 +19,7 @@ $lang->bug->module = 'Module';
|
||||
$lang->bug->moduleAB = 'Module';
|
||||
$lang->bug->project = 'Project';
|
||||
$lang->bug->execution = $lang->execution->common;
|
||||
$lang->bug->kanban = 'Kanban';
|
||||
$lang->bug->story = 'Story';
|
||||
$lang->bug->storyVersion = 'Story Version';
|
||||
$lang->bug->color = 'Color';
|
||||
|
||||
@@ -1366,7 +1366,7 @@ class bugModel extends model
|
||||
{
|
||||
$bug = $this->getById($bugID);
|
||||
$bugIDList = $bug->id . ',' . $bug->linkBug;
|
||||
$bugs2Link = $this->getBySearch($bug->product, 'all', $queryID, 'id', $bugIDList ,$pager);
|
||||
$bugs2Link = $this->getBySearch($bug->product, 'all', $queryID, 'id', $bugIDList, $pager);
|
||||
return $bugs2Link;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<?php printf('%03d', $bug2Link->id);?>
|
||||
</td>
|
||||
<td><span class='label-pri <?php echo 'label-pri-' . $bug2Link->pri?>' title='<?php echo zget($lang->bug->priList, $bug2Link->pri, $bug2Link->pri);?>'><?php echo zget($lang->bug->priList, $bug2Link->pri, $bug2Link->pri);?></span></td>
|
||||
<td><?php echo html::a($this->createLink('product', 'browse', "productID=$bug2Link->product&branch=$bug2Link->branch"), $products[$bug2Link->product], '_blank');?></td>
|
||||
<td class='nobr' title="<?php echo $products[$bug2Link->product]?>"><?php echo html::a($this->createLink('product', 'browse', "productID=$bug2Link->product&branch=$bug2Link->branch"), $products[$bug2Link->product], '_blank');?></td>
|
||||
<td class='text-left nobr' title="<?php echo $bug2Link->title?>"><?php echo html::a($bugLink, $bug2Link->title);?></td>
|
||||
<td><?php echo $this->processStatus('bug', $bug);?></td>
|
||||
<td><?php echo zget($users, $bug2Link->openedBy);?></td>
|
||||
|
||||
@@ -466,7 +466,7 @@ class build extends control
|
||||
$html .= html::a("javascript:loadExecutionBuilds($executionID)", $this->lang->refresh);
|
||||
die($html);
|
||||
}
|
||||
die(html::select('build', array('') + $builds, $build, "class='form-control' onchange='loadTestReports(this.value)'"));
|
||||
die(html::select('build', array('') + $builds, $build, "class='form-control'"));
|
||||
}
|
||||
if($varName == 'dropdownList')
|
||||
{
|
||||
|
||||
@@ -215,8 +215,6 @@ $lang->module = 'Module';
|
||||
$lang->priv = 'Privilege';
|
||||
$lang->other = 'Other';
|
||||
$lang->estimation = 'Estimation';
|
||||
$lang->issue = 'Issue';
|
||||
$lang->risk = 'Risk';
|
||||
$lang->measure = 'Report';
|
||||
$lang->treeView = 'Tree View';
|
||||
$lang->groupView = 'Group View';
|
||||
|
||||
@@ -215,8 +215,6 @@ $lang->module = '模块';
|
||||
$lang->priv = '权限';
|
||||
$lang->other = '其他';
|
||||
$lang->estimation = '估算';
|
||||
$lang->issue = '问题';
|
||||
$lang->risk = '风险';
|
||||
$lang->measure = '度量';
|
||||
$lang->treeView = '树状图';
|
||||
$lang->groupView = '分组视图';
|
||||
|
||||
@@ -210,8 +210,6 @@ $lang->module = '模組';
|
||||
$lang->priv = '權限';
|
||||
$lang->other = '其他';
|
||||
$lang->estimation = '估算';
|
||||
$lang->issue = '問題';
|
||||
$lang->risk = '風險';
|
||||
$lang->measure = '度量';
|
||||
$lang->treeView = '樹狀圖';
|
||||
$lang->groupView = '分組視圖';
|
||||
|
||||
@@ -232,7 +232,7 @@ class company extends control
|
||||
$userIdPairs[''] = $this->lang->company->user;
|
||||
$this->view->userIdPairs = $userIdPairs;
|
||||
|
||||
$accountPairs = $this->user->getPairs('noclosed|nodeleted|noletter|all');
|
||||
$accountPairs = $this->user->getPairs('nodeleted|noletter|all');
|
||||
$accountPairs[''] = '';
|
||||
|
||||
/* The header and position. */
|
||||
|
||||
+88
-59
@@ -263,50 +263,68 @@ class convert extends control
|
||||
/**
|
||||
* Import jira notice.
|
||||
*
|
||||
* @param string $type db|file
|
||||
* @param string $mehotd db|file
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importNotice($type = 'db')
|
||||
public function importNotice($method = 'db')
|
||||
{
|
||||
if($_POST)
|
||||
if($this->server->request_method == 'POST')
|
||||
{
|
||||
$dbName = $this->post->dbName;
|
||||
if(!$dbName)
|
||||
if($method == 'db')
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = $this->lang->convert->jira->dbNameEmpty;
|
||||
return print($this->send($response));
|
||||
$dbName = $this->post->dbName;
|
||||
if(!$dbName)
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = $this->lang->convert->jira->dbNameEmpty;
|
||||
return print($this->send($response));
|
||||
}
|
||||
|
||||
if(!$this->convert->dbExists($dbName))
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = $this->lang->convert->jira->invalidDB;
|
||||
return print($this->send($response));
|
||||
}
|
||||
|
||||
if(!$this->convert->tableExistsOfJira($dbName, 'nodeassociation'))
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = $this->lang->convert->jira->invalidTable;
|
||||
return print($this->send($response));
|
||||
}
|
||||
|
||||
$this->session->set('jiraDB', $dbName);
|
||||
$link = $this->createLink('convert', 'mapJira2Zentao', "method=db&dbName={$this->post->dbName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->convert->splitFile();
|
||||
$link = $this->createLink('convert', 'mapJira2Zentao', "method=file");
|
||||
}
|
||||
|
||||
if(!$this->convert->dbExists($dbName))
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = $this->lang->convert->jira->invalidDB;
|
||||
return print($this->send($response));
|
||||
}
|
||||
|
||||
$this->session->set('jiraDB', $dbName);
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = $this->lang->saveSuccess;
|
||||
$response['locate'] = $this->createLink('convert', 'mapJira2Zentao', "type=db&dbName={$this->post->dbName}");
|
||||
$response['locate'] = $link;
|
||||
return print($this->send($response));
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->convert->jira->method;
|
||||
$this->view->type = $type;
|
||||
$this->view->title = $this->lang->convert->jira->method;
|
||||
$this->view->method = $method;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Map jira objects to zentao.
|
||||
*
|
||||
* @param string $type db|file
|
||||
* @param string $method db|file
|
||||
* @param string $dbName
|
||||
* @param int $step
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function mapJira2Zentao($type = 'db', $dbName = '')
|
||||
public function mapJira2Zentao($method = 'db', $dbName = '', $step = 1)
|
||||
{
|
||||
$this->app->loadLang('story');
|
||||
$this->app->loadLang('bug');
|
||||
@@ -314,40 +332,51 @@ class convert extends control
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
$this->session->set('jiraRelation', $_POST);
|
||||
foreach($_POST as $key => $value) $_SESSION['jiraRelation'][$key] = $value;
|
||||
|
||||
$step = $step + 1;
|
||||
$link = $step == 5 ? $this->createLink('convert', 'initJiraUser', "method=$method") : inlink('mapJira2Zentao', "method=$method&dbName=$dbName&step=$step");
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = $this->lang->saveSuccess;
|
||||
$response['locate'] = $this->createLink('convert', 'initJiraUser', "type=$type");
|
||||
$response['locate'] = $link;
|
||||
return print($this->send($response));
|
||||
}
|
||||
|
||||
if($type == 'db')
|
||||
if($method == 'db')
|
||||
{
|
||||
$dbh = $this->convert->connectDB($dbName);
|
||||
|
||||
$issueTypePairs = $this->dao->dbh($dbh)->select('ID,pname')->from(JIRA_ISSUETYPE)->fetchPairs();
|
||||
$linkTypePairs = $this->dao->dbh($dbh)->select('ID,LINKNAME')->from(JIRA_ISSUELINKTYPE)->fetchPairs();
|
||||
$resolutions = $this->dao->dbh($dbh)->select('ID,pname')->from(JIRA_RESOLUTION)->fetchPairs();
|
||||
$statusList = $this->dao->dbh($dbh)->select('ID,pname')->from(JIRA_ISSUESTATUS)->fetchPairs();
|
||||
$issueTypeList = $this->dao->dbh($dbh)->select('*')->from(JIRA_ISSUETYPE)->fetchAll('ID');
|
||||
$linkTypeList = $this->dao->dbh($dbh)->select('*, LINKNAME as linkname')->from(JIRA_ISSUELINKTYPE)->fetchAll('ID');
|
||||
$resolutionList = $this->dao->dbh($dbh)->select('*')->from(JIRA_RESOLUTION)->fetchAll('ID');
|
||||
$statusList = $this->dao->dbh($dbh)->select('*')->from(JIRA_ISSUESTATUS)->fetchAll('ID');
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$issueTypeList = $this->convert->getJiraDataFromFile('issuetype');
|
||||
$linkTypeList = $this->convert->getJiraDataFromFile('issuelinktype');
|
||||
$resolutionList = $this->convert->getJiraDataFromFile('resolution');
|
||||
$statusList = $this->convert->getJiraDataFromFile('status');
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->convert->jira->mapJira2Zentao;
|
||||
$this->view->issueTypePairs = $issueTypePairs;
|
||||
$this->view->linkTypePairs = $linkTypePairs;
|
||||
$this->view->resolutions = $resolutions;
|
||||
$this->view->issueTypeList = $issueTypeList;
|
||||
$this->view->linkTypeList = $linkTypeList;
|
||||
$this->view->resolutionList = $resolutionList;
|
||||
$this->view->statusList = $statusList;
|
||||
$this->view->method = $method;
|
||||
$this->view->step = $step;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init jira user.
|
||||
*
|
||||
* @param string $type db|file
|
||||
* @param string $method db|file
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function initJiraUser($type = 'db')
|
||||
public function initJiraUser($method = 'db')
|
||||
{
|
||||
$this->app->loadLang('user');
|
||||
|
||||
@@ -360,6 +389,13 @@ class convert extends control
|
||||
return print($this->send($response));
|
||||
}
|
||||
|
||||
if(strlen(trim($this->post->password1)) < 6)
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = $this->lang->convert->jira->passwordLess;
|
||||
return print($this->send($response));
|
||||
}
|
||||
|
||||
if($this->post->password1 != $this->post->password2)
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
@@ -373,7 +409,7 @@ class convert extends control
|
||||
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = $this->lang->saveSuccess;
|
||||
$response['locate'] = $this->createLink('convert', 'importJira', "type=$type");
|
||||
$response['locate'] = $this->createLink('convert', 'importJira', "method=$method");
|
||||
return print($this->send($response));
|
||||
}
|
||||
|
||||
@@ -395,32 +431,25 @@ class convert extends control
|
||||
{
|
||||
set_time_limit(0);
|
||||
|
||||
if($method = 'db')
|
||||
{
|
||||
if(helper::isAjaxRequest())
|
||||
if(helper::isAjaxRequest())
|
||||
{
|
||||
$result = $method == 'db' ? $this->convert->importJiraFromDB($type, $lastID, $createTable) : $this->convert->importJiraFromFile($type, $lastID, $createTable);
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
if(isset($result['finished']) and $result['finished'])
|
||||
{
|
||||
$result = $this->convert->importJiraFromDB($type, $lastID, $createTable);
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
if(isset($result['finished']) and $result['finished'])
|
||||
{
|
||||
return print $this->send(array('result' => 'finished', 'message' => $this->lang->convert->jira->importSuccessfully));
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = zget($this->lang->convert->jira->objectList, $result['type'], $result['type']);
|
||||
return print $this->send(array('result' => 'finished', 'message' => $this->lang->convert->jira->importSuccessfully));
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = zget($this->lang->convert->jira->objectList, $result['type'], $result['type']);
|
||||
|
||||
$response['result'] = 'unfinished';
|
||||
$response['message'] = sprintf($this->lang->convert->jira->importResult, $type, $type, $result['count']);
|
||||
$response['type'] = $type;
|
||||
$response['count'] = $result['count'];
|
||||
$response['next'] = inlink('importJira', "method=$method&type={$result['type']}&lastID={$result['lastID']}");
|
||||
return print $this->send($response);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//$this->convert->importJiraFromFile();
|
||||
$response['result'] = 'unfinished';
|
||||
$response['message'] = sprintf($this->lang->convert->jira->importResult, $type, $type, $result['count']);
|
||||
$response['type'] = $type;
|
||||
$response['count'] = $result['count'];
|
||||
$response['next'] = inlink('importJira', "method=$method&type={$result['type']}&lastID={$result['lastID']}");
|
||||
return print $this->send($response);
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->type = $type;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
.main-header > ul {display: inline-block; padding: 0; margin: 0;}
|
||||
.main-header > ul > li {position: relative;}
|
||||
.main-header > ul > li.active > a {background-color: #1CA5FF; color: #fff}
|
||||
.main-header > ul > li > a {min-width: 120px; padding: 5px 20px; text-align: center; transition: none; color: #838a9d}
|
||||
.main-header > ul > li.active > a:hover,
|
||||
.main-header > ul > li.active > a:focus {background-color: #1CA5FF;}
|
||||
.main-header > ul > li .step-number {display: inline-block; width: 14px; height: 14px; border-radius: 7px; text-align: center; line-height: 12px; border: 1px solid #A6AAB8; color: #A6AAB8; font-size: 12px; font-weight: bold; margin-right: 3px;}
|
||||
.main-header > ul > li + li > a {padding-left: 35px;}
|
||||
.main-header > ul > li + li:before,
|
||||
.main-header > ul > li + li:after {content: ' '; width: 0; height: 0; border-style: solid; border-width: 15px 0 15px 15px; border-color: transparent transparent transparent #a6aab8; position: absolute; left: 0; top: 0;}
|
||||
.main-header > ul > li + li:after {border-left-color: #fff; left: -1px;}
|
||||
.main-header > ul > li.active + li:after {border-left-color: #1ca5ff;}
|
||||
.main-header > ul > li:hover + li:after {border-left-color: #eceef4;}
|
||||
.main-header > ul > li.active:hover + li:after {border-left-color: #1CA5FF;}
|
||||
.nav-primary>li.active>a:hover {color: #fff}
|
||||
.main-header {margin-top: -15px !important;}
|
||||
@@ -116,4 +116,77 @@ $lang->convert->issue->zentao = 'ZenTao';
|
||||
$lang->convert->issue->goto = 'Convert To';
|
||||
|
||||
$lang->convert->jira = new stdclass();
|
||||
$lang->convert->jira->import = 'Import Jira';
|
||||
$lang->convert->jira->method = 'Chose Import Method';
|
||||
$lang->convert->jira->next = 'Next';
|
||||
$lang->convert->jira->importFromDB = 'Import From Database';
|
||||
$lang->convert->jira->importFromFile = 'Import From File';
|
||||
$lang->convert->jira->mapJira2Zentao = 'Map Jira To Zentao';
|
||||
$lang->convert->jira->dbNameNotice = 'Please type jira database';
|
||||
$lang->convert->jira->importNotice = 'Notice: Importing data is risky! Make sure to complete the following steps in sequence before merging.';
|
||||
$lang->convert->jira->dbDesc = '<p>If your Jira uses MySQL database, please choose this way.</p>';
|
||||
$lang->convert->jira->fileDesc = '<p>Choose this method if your Jira uses a non-MySQL database.</p>';
|
||||
$lang->convert->jira->jiraObject = 'Jira Issues';
|
||||
$lang->convert->jira->zentaoObject = 'Zentao Object';
|
||||
$lang->convert->jira->jiraLinkType = 'Jira Relates';
|
||||
$lang->convert->jira->zentaoLinkType = 'Zentao Link Type';
|
||||
$lang->convert->jira->jiraResolution = 'Jira Resolution';
|
||||
$lang->convert->jira->zentaoResolution = 'Zentao Resolution';
|
||||
$lang->convert->jira->zentaoReason = 'Zentao Story Closed Reason';
|
||||
$lang->convert->jira->jiraStatus = 'Jira Issues Status';
|
||||
$lang->convert->jira->storyStatus = 'Zentao Story Status';
|
||||
$lang->convert->jira->storyStage = 'Zentao Story Stage';
|
||||
$lang->convert->jira->bugStatus = 'Zentao Bug Status';
|
||||
$lang->convert->jira->taskStatus = 'Zentao Task Status';
|
||||
$lang->convert->jira->initJiraUser = 'Init Jira User';
|
||||
$lang->convert->jira->importJira = 'Import Jira';
|
||||
$lang->convert->jira->start = 'Start';
|
||||
|
||||
$lang->convert->jira->dbNameEmpty = 'Jira database name cannot be empty!';
|
||||
$lang->convert->jira->invalidDB = 'Invalid database name!';
|
||||
$lang->convert->jira->invalidTable = 'This database is not a Jira database!';
|
||||
$lang->convert->jira->passwordNotice = "<span class='text-red'>Set the default password of Jira users after they are imported into ZenTao. Users can modify the password in ZenTao later.</span>";
|
||||
$lang->convert->jira->groupNotice = "<span class='text-red'>Set the default permission grouping of Jira users after importing into ZenTao.</span>";
|
||||
$lang->convert->jira->passwordDifferent = 'Password do not match!';
|
||||
$lang->convert->jira->passwordEmpty = 'Password can not be empty!';
|
||||
$lang->convert->jira->passwordLess = 'Password must not be less than six characters!';
|
||||
$lang->convert->jira->importSuccessfully = 'Done!';
|
||||
$lang->convert->jira->importResult = "Import <strong class='text-red'>%s</strong> data, <strong class='%scount'>%s</strong> pieces of data processed;";
|
||||
$lang->convert->jira->importing = 'Data is being imported, please do not switch to other pages.';
|
||||
$lang->convert->jira->importingAB = 'Data Import';
|
||||
$lang->convert->jira->imported = 'Data Import Complete';
|
||||
|
||||
$lang->convert->jira->zentaoObjectList[''] = '';
|
||||
$lang->convert->jira->zentaoObjectList['task'] = 'Task';
|
||||
$lang->convert->jira->zentaoObjectList['requirement'] = 'Requirement';
|
||||
$lang->convert->jira->zentaoObjectList['story'] = 'Story';
|
||||
$lang->convert->jira->zentaoObjectList['bug'] = 'Bug';
|
||||
|
||||
$lang->convert->jira->zentaoLinkTypeList['subTaskLink'] = 'Parent-Child Task';
|
||||
$lang->convert->jira->zentaoLinkTypeList['subStoryLink'] = 'Parent-Child Story';
|
||||
$lang->convert->jira->zentaoLinkTypeList['duplicate'] = 'Duplicate';
|
||||
$lang->convert->jira->zentaoLinkTypeList['relates'] = 'Relates';
|
||||
|
||||
$lang->convert->jira->steps[1] = 'Objects';
|
||||
$lang->convert->jira->steps[2] = 'Relates';
|
||||
$lang->convert->jira->steps[3] = 'Resolution';
|
||||
$lang->convert->jira->steps[4] = 'Status';
|
||||
|
||||
$lang->convert->jira->importSteps['db'][1] = 'Backup ZenTao database, backup Jira database.';
|
||||
$lang->convert->jira->importSteps['db'][2] = 'Using ZenTao when importing data will cause performance pressure on the server, please try to ensure that no one is using ZenTao when importing data.';
|
||||
$lang->convert->jira->importSteps['db'][3] = 'Import the Jira database into the Mysql used by ZenTao, the name is distinguished from the ZenTao database.';
|
||||
$lang->convert->jira->importSteps['db'][4] = "Put the Jira <strong class='text-red'> attachments</strong> directory under <strong class='text-red'>%s</strong>, Make sure you have enough disk space on the ZenTao server.";
|
||||
$lang->convert->jira->importSteps['db'][5] = "After the above steps are completed, please enter the Jira database name to proceed to the next step.";
|
||||
|
||||
$lang->convert->jira->importSteps['file'][1] = 'Backup ZenTao database, backup Jira database.';
|
||||
$lang->convert->jira->importSteps['file'][2] = 'Using ZenTao when importing data will cause performance pressure on the server, please try to ensure that no one is using ZenTao when importing data.';
|
||||
$lang->convert->jira->importSteps['file'][3] = "Put the Jira backup file <strong class='text-red'>entities.xml</strong> under <strong class='text-red'>%s</strong>.";
|
||||
$lang->convert->jira->importSteps['file'][4] = "Put the Jira <strong class='text-red'> attachments</strong> directory under <strong class='text-red'>%s</strong>, Make sure you have enough disk space on the ZenTao server.";
|
||||
$lang->convert->jira->importSteps['file'][5] = "After the above steps are completed, click Next.";
|
||||
|
||||
$lang->convert->jira->objectList['user'] = 'User';
|
||||
$lang->convert->jira->objectList['project'] = 'Project';
|
||||
$lang->convert->jira->objectList['issue'] = 'Issue';
|
||||
$lang->convert->jira->objectList['build'] = 'Build';
|
||||
$lang->convert->jira->objectList['issuelink'] = 'Issue Link';
|
||||
$lang->convert->jira->objectList['action'] = 'Action';
|
||||
$lang->convert->jira->objectList['file'] = 'File';
|
||||
|
||||
@@ -120,7 +120,7 @@ $lang->convert->jira->method = '选择导入方式';
|
||||
$lang->convert->jira->next = '下一步';
|
||||
$lang->convert->jira->importFromDB = '从数据库导入';
|
||||
$lang->convert->jira->importFromFile = '从文件导入';
|
||||
$lang->convert->jira->mapJira2Zentao = '设置对应关系';
|
||||
$lang->convert->jira->mapJira2Zentao = '设置Jira与禅道数据对应关系';
|
||||
$lang->convert->jira->dbNameNotice = '请输入Jira数据库名字';
|
||||
$lang->convert->jira->importNotice = '注意:导入数据有风险!请务必确保如下操作步骤依次完成,再进行合并。';
|
||||
$lang->convert->jira->dbDesc = '<p>如果您的Jira使用Mysql数据库, 请选择此方式</p>';
|
||||
@@ -143,13 +143,19 @@ $lang->convert->jira->start = '开始导入';
|
||||
|
||||
$lang->convert->jira->dbNameEmpty = 'Jira数据库名字不能为空!';
|
||||
$lang->convert->jira->invalidDB = '无效的数据库名!';
|
||||
$lang->convert->jira->invalidTable = '本数据库非Jira数据库!';
|
||||
$lang->convert->jira->passwordNotice = "<span class='text-red'>设置Jira用户导入到禅道后的默认密码,用户后续可以在禅道中自行修改密码。</span>";
|
||||
$lang->convert->jira->groupNotice = "<span class='text-red'>设置Jira用户导入到禅道后的默认权限分组。</span>";
|
||||
$lang->convert->jira->passwordDifferent = '两次密码不一致!';
|
||||
$lang->convert->jira->passwordEmpty = '密码不能为空!';
|
||||
$lang->convert->jira->passwordLess = '密码不能少于六位!';
|
||||
$lang->convert->jira->importSuccessfully = 'Jira导入完成!';
|
||||
$lang->convert->jira->importResult = "导入 <strong class='text-red'>%s</strong> 数据, 已处理 <strong class='%scount'>%s</strong> 条记录;";
|
||||
$lang->convert->jira->importing = '数据导入中,请不要切换其它页面';
|
||||
$lang->convert->jira->importingAB = '数据导入中';
|
||||
$lang->convert->jira->imported = '数据导入完成';
|
||||
|
||||
$lang->convert->jira->zentaoObjectList[''] = '';
|
||||
$lang->convert->jira->zentaoObjectList['task'] = '任务';
|
||||
$lang->convert->jira->zentaoObjectList['requirement'] = '用户需求';
|
||||
$lang->convert->jira->zentaoObjectList['story'] = '软件需求';
|
||||
@@ -160,14 +166,20 @@ $lang->convert->jira->zentaoLinkTypeList['subStoryLink'] = '父-子需求';
|
||||
$lang->convert->jira->zentaoLinkTypeList['duplicate'] = '重复对象';
|
||||
$lang->convert->jira->zentaoLinkTypeList['relates'] = '互相关联';
|
||||
|
||||
$lang->convert->jira->steps[1] = '对象';
|
||||
$lang->convert->jira->steps[2] = '对象关联关系';
|
||||
$lang->convert->jira->steps[3] = '解决方案';
|
||||
$lang->convert->jira->steps[4] = '状态';
|
||||
|
||||
$lang->convert->jira->importSteps['db'][1] = '备份禅道数据库,备份Jira数据库。';
|
||||
$lang->convert->jira->importSteps['db'][2] = '导入数据时使用禅道会给服务器造成性能压力,请尽量保证导入数据时无人使用禅道。';
|
||||
$lang->convert->jira->importSteps['db'][3] = '将Jira数据库导入到禅道使用的Mysql中,名字和禅道数据库区别开来。';
|
||||
$lang->convert->jira->importSteps['db'][4] = "将Jira附件目录<strong class='text-red'> attachments</strong> 放到 <strong class='text-red'>%s</strong> 下,确保禅道服务器磁盘空间足够。";
|
||||
|
||||
$lang->convert->jira->importSteps['db'][5] = "上述步骤完成后,请输入Jira数据库名字进行下一步。";
|
||||
$lang->convert->jira->importSteps['file'][1] = '备份禅道数据库,备份Jira数据库。';
|
||||
$lang->convert->jira->importSteps['file'][2] = '导入数据时使用禅道会给服务器造成性能压力,请尽量保证导入数据时无人使用禅道。';
|
||||
$lang->convert->jira->importSteps['file'][3] = "将Jira的备份文件 <strong class='text-red'>entities.xml</strong> 放到 <strong class='text-red'>%s</strong> 下。";
|
||||
$lang->convert->jira->importSteps['file'][3] = "将Jira的备份文件 <strong class='text-red'>entities.xml</strong> 放到 <strong class='text-red'>%s</strong> 下,并给该目录读写权限。";
|
||||
$lang->convert->jira->importSteps['file'][4] = "将Jira附件目录<strong class='text-red'> attachments</strong> 放到 <strong class='text-red'>%s</strong> 下,确保禅道服务器磁盘空间足够。";
|
||||
$lang->convert->jira->importSteps['file'][5] = "上述步骤完成后,点击下一步。";
|
||||
|
||||
|
||||
+449
-40
@@ -52,6 +52,7 @@ class convertModel extends model
|
||||
/**
|
||||
* Check table exits or not.
|
||||
*
|
||||
* @param string $table
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
@@ -61,6 +62,21 @@ class convertModel extends model
|
||||
return $this->dbh->query($sql)->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check table of jira databases exits or not.
|
||||
*
|
||||
* @param string $dbName
|
||||
* @param string $table
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function tableExistsOfJira($dbName, $table)
|
||||
{
|
||||
$this->connectDB($dbName);
|
||||
$sql = "SHOW tables like '$table'";
|
||||
return $this->dao->dbh($this->sourceDBH)->query($sql)->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the max id of every table. Thus when we convert again, when can delete id larger then the saved max id.
|
||||
*
|
||||
@@ -95,13 +111,15 @@ class convertModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jira data.
|
||||
* Get jira data from db.
|
||||
*
|
||||
* @param int $module
|
||||
* @param string $module
|
||||
* @param int $lastID
|
||||
* @param int $limit
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getJiraData($module = '', $lastID = 0, $limit = 0)
|
||||
public function getJiraDataFromDB($module = '', $lastID = 0, $limit = 0)
|
||||
{
|
||||
$dataList = array();
|
||||
if($module == 'user')
|
||||
@@ -165,6 +183,207 @@ class convertModel extends model
|
||||
return $dataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jira data from file.
|
||||
*
|
||||
* @param sting $module
|
||||
* @param int $lastID
|
||||
* @param int $limit
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getJiraDataFromFile($module, $lastID = 0, $limit = 0)
|
||||
{
|
||||
$fileName = $module;
|
||||
if($module == 'build') $filename = 'version';
|
||||
if($module == 'file') $filename = 'fileattachment';
|
||||
|
||||
$filePath = $this->app->getTmpRoot() . 'jirafile/' . $fileName . '.xml';
|
||||
if(!file_exists($filePath)) return array();
|
||||
|
||||
$xmlContent = file_get_contents($filePath);
|
||||
$xmlContent = preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $xmlContent);
|
||||
$parsedXML = simplexml_load_string($xmlContent, SimpleXMLElement::class, LIBXML_NOCDATA);
|
||||
|
||||
$dataList = array();
|
||||
$parsedXML = $this->object2Array($parsedXML);
|
||||
foreach($parsedXML as $key => $xmlArray)
|
||||
{
|
||||
if(strtolower($key) != strtolower($fileName)) continue;
|
||||
foreach($xmlArray as $key => $attributes)
|
||||
{
|
||||
$desc = isset($attributes['description']) ? $attributes['description'] : '';
|
||||
$summary = isset($attributes['summary']) ? $attributes['summary'] : '';
|
||||
$body = isset($attributes['body']) ? $attributes['body'] : '';
|
||||
|
||||
if(is_numeric($key))
|
||||
{
|
||||
foreach($attributes as $value)
|
||||
{
|
||||
if(!is_array($value)) continue;
|
||||
if(!empty($desc)) $value['description'] = $desc;
|
||||
if(!empty($summary)) $value['summary'] = $summary;
|
||||
if(!empty($body)) $value['body'] = $body;
|
||||
$dataList[$value['id']] = $value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$dataList[$attributes['id']] = $attributes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($limit)
|
||||
{
|
||||
$dataList = array_slice($dataList, $lastID, $limit, true);
|
||||
if(empty($dataList)) return array();
|
||||
}
|
||||
|
||||
foreach($dataList as $key => $data)
|
||||
{
|
||||
if($module == 'user')
|
||||
{
|
||||
$user = new stdclass();
|
||||
$user->account = $data['lowerUserName'];
|
||||
$user->realname = $data['lowerDisplayName'];
|
||||
$user->email = $data['emailAddress'];
|
||||
$user->join = $data['createdDate'];
|
||||
|
||||
$dataList[$key] = $user;
|
||||
}
|
||||
elseif($module == 'project')
|
||||
{
|
||||
$project = new stdclass();
|
||||
$project->ID = $data['id'];
|
||||
$project->pname = $data['name'];
|
||||
$project->pkey = $data['key'];
|
||||
$project->ORIGINALKEY = $data['originalkey'];
|
||||
$project->DESCRIPTION = $data['description'];
|
||||
$project->LEAD = $data['lead'];
|
||||
|
||||
$dataList[$key] = $project;
|
||||
}
|
||||
elseif($module == 'issue')
|
||||
{
|
||||
$issue = new stdclass();
|
||||
$issue->ID = $data['id'];
|
||||
$issue->SUMMARY = $data['summary'];
|
||||
$issue->PRIORITY = $data['priority'];
|
||||
$issue->PROJECT = $data['project'];
|
||||
$issue->issuestatus = $data['status'];
|
||||
$issue->CREATED = $data['created'];
|
||||
$issue->CREATOR = $data['creator'];
|
||||
$issue->issuetype = $data['type'];
|
||||
$issue->ASSIGNEE = isset($data['assignee']) ? $data['assignee'] : '';
|
||||
$issue->RESOLUTION = isset($data['resolution']) ? $data['resolution'] : '';
|
||||
$issue->issuenum = $data['number'];
|
||||
$issue->DESCRIPTION = isset($data['description']) ? $data['description'] : '';
|
||||
|
||||
$dataList[$key] = $issue;
|
||||
}
|
||||
elseif($module == 'build')
|
||||
{
|
||||
$build = new stdclass();
|
||||
$build->ID = $data['id'];
|
||||
$build->PROJECT = $data['project'];
|
||||
$build->vname = $data['name'];
|
||||
$build->RELEASEDATE = isset($data['releasedate']) ? $data['releasedate'] : '';
|
||||
$build->DESCRIPTION = isset($data['description']) ? $data['description'] : '';
|
||||
|
||||
$dataList[$key] = $build;
|
||||
}
|
||||
elseif($module == 'issuelink')
|
||||
{
|
||||
$issueLink = new stdclass();
|
||||
$issueLink->LINKTYPE = $data['linktype'];
|
||||
$issueLink->SOURCE = $data['source'];
|
||||
$issueLink->DESTINATION = $data['destination'];
|
||||
|
||||
$dataList[$key] = $issueLink;
|
||||
}
|
||||
elseif($module == 'action')
|
||||
{
|
||||
$action = new stdclass();
|
||||
$action->issueid = $data['issue'];
|
||||
$action->actionbody = $data['body'];
|
||||
$action->AUTHOR = $data['author'];
|
||||
$action->CREATED = $data['created'];
|
||||
|
||||
$dataList[$key] = $action;
|
||||
}
|
||||
elseif($module == 'file')
|
||||
{
|
||||
$file = new stdclass();
|
||||
$file->issueid = $data['issue'];
|
||||
$file->ID = $data['id'];
|
||||
$file->FILENAME = $data['filename'];
|
||||
$file->MIMETYPE = $data['mimetype'];
|
||||
$file->FILESIZE = $data['filesize'];
|
||||
$file->CREATED = $data['created'];
|
||||
$file->AUTHOR = $data['author'];
|
||||
|
||||
$dataList[$key] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
return $dataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get version group from jira file.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getVersionGroup()
|
||||
{
|
||||
$xmlContent = file_get_contents($this->app->getTmpRoot() . 'jirafile/nodeassociation.xml');
|
||||
$xmlContent = preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $xmlContent);
|
||||
$parsedXML = simplexml_load_string($xmlContent, SimpleXMLElement::class, LIBXML_NOCDATA);
|
||||
|
||||
$dataList = array();
|
||||
$parsedXML = $this->object2Array($parsedXML);
|
||||
foreach($parsedXML as $key => $xmlArray)
|
||||
{
|
||||
if(strtolower($key) != 'nodeassociation') continue;
|
||||
foreach($xmlArray as $key => $attributes)
|
||||
{
|
||||
foreach($attributes as $value)
|
||||
{
|
||||
if(!is_array($value)) continue;
|
||||
if($value['sinkNodeEntity'] != 'Version') continue;
|
||||
$dataList[$value['sinkNodeId']][] = $value['sinkNodeId'];
|
||||
$dataList[$value['sinkNodeId']][] = $value['sourceNodeId'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert object to array.
|
||||
*
|
||||
* @param object $parsedXML
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function object2Array($parsedXML)
|
||||
{
|
||||
if(is_object($parsedXML))
|
||||
{
|
||||
$parsedXML = (array)$parsedXML;
|
||||
}
|
||||
|
||||
if(is_array($parsedXML))
|
||||
{
|
||||
foreach($parsedXML as $key => $value) $parsedXML[$key] = $this->object2Array($value);
|
||||
}
|
||||
|
||||
return $parsedXML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import jira from db.
|
||||
*
|
||||
@@ -190,7 +409,7 @@ class convertModel extends model
|
||||
|
||||
while(true)
|
||||
{
|
||||
$dataList = $this->getJiraData($module, $lastID, $limit);
|
||||
$dataList = $this->getJiraDataFromDB($module, $lastID, $limit);
|
||||
|
||||
if(empty($dataList))
|
||||
{
|
||||
@@ -210,17 +429,56 @@ class convertModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
/* Set project min start date. */
|
||||
$executionProject = $this->dao->dbh($this->dbh)->select('id,project')->from(TABLE_PROJECT)->where('type')->eq('sprint')->andWhere('project')->ne(0)->fetchPairs();
|
||||
$minOpenedDateList = $this->dao->dbh($this->dbh)->select('id,execution,min(openedDate) as minOpenedDate')->from(TABLE_TASK)->where('execution')->in(array_keys($executionProject))->groupBy('execution')->fetchPairs('execution', 'minOpenedDate');
|
||||
$this->afterExec();
|
||||
return array('finished' => true);
|
||||
}
|
||||
|
||||
foreach($minOpenedDateList as $executionID => $minOpenedDate)
|
||||
/**
|
||||
* Import jira from file.
|
||||
*
|
||||
* @param string $type
|
||||
* @param int $lastID
|
||||
* @param bool $createTable
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importJiraFromFile($type = '', $lastID = 0, $createTable = false)
|
||||
{
|
||||
if($createTable) $this->createTmpTable4Jira();
|
||||
|
||||
$limit = 1000;
|
||||
$nextObject = false;
|
||||
if(empty($type)) $type = key($this->lang->convert->jira->objectList);
|
||||
|
||||
foreach($this->lang->convert->jira->objectList as $module => $moduleName)
|
||||
{
|
||||
$projectID = $executionProject[$executionID];
|
||||
$this->dao->update(TABLE_PROJECT)->set('begin')->eq($minOpenedDate)->where('id')->eq($projectID)->orWhere('id')->eq($executionID)->exec();
|
||||
if($module != $type and !$nextObject) continue;
|
||||
if($module == $type) $nextObject = true;
|
||||
|
||||
while(true)
|
||||
{
|
||||
$dataList = $this->getJiraDataFromFile($module, $lastID, $limit);
|
||||
|
||||
if(empty($dataList))
|
||||
{
|
||||
$lastID = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if($module == 'user') $this->importJiraUser($dataList, 'file');
|
||||
if($module == 'project') $this->importJiraProject($dataList, 'file');
|
||||
if($module == 'issue') $this->importJiraIssue($dataList, 'file');
|
||||
if($module == 'build') $this->importJiraBuild($dataList, 'file');
|
||||
if($module == 'issuelink') $this->importJiraIssueLink($dataList, 'file');
|
||||
if($module == 'action') $this->importJiraAction($dataList, 'file');
|
||||
if($module == 'file') $this->importJiraFile($dataList, 'file');
|
||||
|
||||
$offset = $lastID + $limit;
|
||||
return array('type' => $module, 'count' => count($dataList), 'lastID' => $offset);
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbh->exec("DROP TABLE" . JIRA_TMPRELATION);
|
||||
$this->afterExec();
|
||||
return array('finished' => true);
|
||||
}
|
||||
|
||||
@@ -228,10 +486,11 @@ class convertModel extends model
|
||||
* Import jira user.
|
||||
*
|
||||
* @param object $dataList
|
||||
* @param string $method
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importJiraUser($dataList)
|
||||
public function importJiraUser($dataList, $method = 'db')
|
||||
{
|
||||
$localUsers = $this->dao->dbh($this->dbh)->select('account')->from(TABLE_USER)->where('deleted')->eq('0')->fetchPairs();
|
||||
$userConfig = $this->session->jiraUser;
|
||||
@@ -250,7 +509,7 @@ class convertModel extends model
|
||||
$user->type = 'inside';
|
||||
$user->join = $data->join;
|
||||
|
||||
$this->dao->dbh($this->dbh)->insert(TABLE_USER)->data($user, 'group')->exec();
|
||||
$this->dao->dbh($this->dbh)->replace(TABLE_USER)->data($user, 'group')->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
@@ -267,10 +526,11 @@ class convertModel extends model
|
||||
* Import jira project.
|
||||
*
|
||||
* @param object $dataList
|
||||
* @param string $method
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importJiraProject($dataList)
|
||||
public function importJiraProject($dataList, $method = 'db')
|
||||
{
|
||||
global $app;
|
||||
$app->loadConfig('execution');
|
||||
@@ -295,8 +555,8 @@ class convertModel extends model
|
||||
$project->acl = 'open';
|
||||
$project->end = date('Y-m-d', time() + 24 * 3600);
|
||||
|
||||
$project->PM = $this->getJiraAccount($data->LEAD);
|
||||
$project->openedBy = $this->getJiraAccount($data->LEAD);
|
||||
$project->PM = $this->getJiraAccount($data->LEAD, $method);
|
||||
$project->openedBy = $this->getJiraAccount($data->LEAD, $method);
|
||||
$project->openedDate = $now;
|
||||
$project->openedVersion = $this->config->version;
|
||||
|
||||
@@ -398,15 +658,20 @@ class convertModel extends model
|
||||
$projectRelation['BType'] = 'zproject';
|
||||
$projectRelation['AID'] = $id;
|
||||
$projectRelation['BID'] = $projectID;
|
||||
|
||||
$this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($projectRelation)->exec();
|
||||
|
||||
$executionRelation['AType'] = 'jproject';
|
||||
$executionRelation['BType'] = 'zexecution';
|
||||
$executionRelation['AID'] = $id;
|
||||
$executionRelation['BID'] = $executionID;
|
||||
|
||||
$this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($executionRelation)->exec();
|
||||
|
||||
$keyRelation['AType'] = 'joldkey';
|
||||
$keyRelation['BType'] = 'jnewkey';
|
||||
$keyRelation['AID'] = $data->ORIGINALKEY;
|
||||
$keyRelation['BID'] = $data->pkey;
|
||||
$keyRelation['extra'] = $data->ID;
|
||||
$this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($keyRelation)->exec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,10 +679,11 @@ class convertModel extends model
|
||||
* Import jira issue.
|
||||
*
|
||||
* @param object $dataList
|
||||
* @param string $method
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importJiraIssue($dataList)
|
||||
public function importJiraIssue($dataList, $method = 'db')
|
||||
{
|
||||
$relations = $this->session->jiraRelation;
|
||||
|
||||
@@ -430,6 +696,11 @@ class convertModel extends model
|
||||
->andWhere('BType')->eq('zproject')
|
||||
->fetchPairs();
|
||||
|
||||
$projectKeys = $this->dao->dbh($this->dbh)->select('extra as ID, AID as oldKey, BID as newKey')->from(JIRA_TMPRELATION)
|
||||
->where('AType')->eq('joldkey')
|
||||
->andWhere('BType')->eq('jnewkey')
|
||||
->fetchAll('ID');
|
||||
|
||||
$projectProduct = $this->dao->dbh($this->dbh)->select('project,product')->from(TABLE_PROJECTPRODUCT)
|
||||
->where('project')->in(array_values($projectRelation))
|
||||
->fetchPairs();
|
||||
@@ -452,8 +723,6 @@ class convertModel extends model
|
||||
if(!empty($relations['zentaoResolution'][$id])) $resolutionList[$jiraCode] = $relations['zentaoResolution'][$id];
|
||||
}
|
||||
|
||||
$projectKeys = $this->dao->dbh($this->sourceDBH)->select('ID, ORIGINALKEY as oldKey, pkey as newKey')->from(JIRA_PROJECT)->fetchAll('ID');
|
||||
|
||||
foreach($dataList as $id => $data)
|
||||
{
|
||||
$issueType = isset($issueTypeList[$data->issuetype]) ? $issueTypeList[$data->issuetype] : 'task';
|
||||
@@ -476,9 +745,9 @@ class convertModel extends model
|
||||
$story->version = 1;
|
||||
$story->stage = $this->convertStage($data->issuestatus);
|
||||
$story->status = $this->convertStatus('story', $data->issuestatus);
|
||||
$story->openedBy = $this->getJiraAccount($data->CREATOR);
|
||||
$story->openedBy = $this->getJiraAccount($data->CREATOR, $method);
|
||||
$story->openedDate = substr($data->CREATED, 0, 19);
|
||||
$story->assignedTo = $this->getJiraAccount($data->ASSIGNEE);
|
||||
$story->assignedTo = $this->getJiraAccount($data->ASSIGNEE, $method);
|
||||
|
||||
if($data->RESOLUTION)
|
||||
{
|
||||
@@ -543,9 +812,9 @@ class convertModel extends model
|
||||
$task->pri = $data->PRIORITY;
|
||||
$task->status = $this->convertStatus('task', $data->issuestatus);
|
||||
$task->desc = $data->DESCRIPTION;
|
||||
$task->openedBy = $this->getJiraAccount($data->CREATOR);
|
||||
$task->openedBy = $this->getJiraAccount($data->CREATOR, $method);
|
||||
$task->openedDate = substr($data->CREATED, 0, 19);
|
||||
$task->assignedTo = $this->getJiraAccount($data->ASSIGNEE);
|
||||
$task->assignedTo = $this->getJiraAccount($data->ASSIGNEE, $method);
|
||||
if($data->RESOLUTION)
|
||||
{
|
||||
$task->closedReason = zget($reasonList, $data->RESOLUTION, '');
|
||||
@@ -585,10 +854,10 @@ class convertModel extends model
|
||||
$bug->pri = $data->PRIORITY;
|
||||
$bug->status = $this->convertStatus('bug', $data->issuestatus);
|
||||
$bug->steps = $data->DESCRIPTION;
|
||||
$bug->openedBy = $this->getJiraAccount($data->CREATOR);
|
||||
$bug->openedBy = $this->getJiraAccount($data->CREATOR, $method);
|
||||
$bug->openedDate = substr($data->CREATED, 0, 19);
|
||||
$bug->openedBuild = 'trunk';
|
||||
$bug->assignedTo = $this->getJiraAccount($data->ASSIGNEE);
|
||||
$bug->assignedTo = $this->getJiraAccount($data->ASSIGNEE, $method);
|
||||
|
||||
if($data->RESOLUTION)
|
||||
{
|
||||
@@ -638,10 +907,11 @@ class convertModel extends model
|
||||
* Import jira build.
|
||||
*
|
||||
* @param object $dataList
|
||||
* @param string $method
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importJiraBuild($dataList)
|
||||
public function importJiraBuild($dataList, $method = 'db')
|
||||
{
|
||||
$issueObjectType = $this->dao->dbh($this->dbh)->select('AID,extra')->from(JIRA_TMPRELATION)
|
||||
->where('AType')->eq('jissueid')
|
||||
@@ -667,7 +937,7 @@ class convertModel extends model
|
||||
->where('project')->in(array_values($projectRelation))
|
||||
->fetchPairs();
|
||||
|
||||
$versionGroup = $this->dao->dbh($this->sourceDBH)->select('SINK_NODE_ID as versionID, SOURCE_NODE_ID as issueID')->from(JIRA_NODEASSOCIATION)->where('SINK_NODE_ENTITY')->eq('Version')->fetchGroup('versionID');
|
||||
$versionGroup = $method == 'db' ? $this->dao->dbh($this->sourceDBH)->select('SINK_NODE_ID as versionID, SOURCE_NODE_ID as issueID')->from(JIRA_NODEASSOCIATION)->where('SINK_NODE_ENTITY')->eq('Version')->fetchGroup('versionID') : $this->getVersionGroup();
|
||||
|
||||
foreach($dataList as $data)
|
||||
{
|
||||
@@ -704,9 +974,10 @@ class convertModel extends model
|
||||
{
|
||||
foreach($versionGroup[$versionID] as $issue)
|
||||
{
|
||||
$issueType = zget($issueObjectType, $issue->issueID, '');
|
||||
$issueID = $method == 'db' ? $issue->issueID : $issue;
|
||||
$issueType = zget($issueObjectType, $issueID, '');
|
||||
if(!$issueType || ($issueType != 'story' and $issueType != 'bug')) continue;
|
||||
$objectID = $issueType == 'bug' ? zget($issueBugs, $issue->issueID) : zget($issueStories, $issue->issueID);
|
||||
$objectID = $issueType == 'bug' ? zget($issueBugs, $issueID) : zget($issueStories, $issueID);
|
||||
|
||||
$field = $issueType == 'story' ? 'stories' : 'bugs';
|
||||
if($issueType == 'story')
|
||||
@@ -726,10 +997,11 @@ class convertModel extends model
|
||||
* Import jira issue link.
|
||||
*
|
||||
* @param object $dataList
|
||||
* @param string $method
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importJiraIssueLink($dataList)
|
||||
public function importJiraIssueLink($dataList, $method = 'db')
|
||||
{
|
||||
$issueLinkTypeList = array();
|
||||
$relations = $this->session->jiraRelation;
|
||||
@@ -849,10 +1121,11 @@ class convertModel extends model
|
||||
* Import jira action.
|
||||
*
|
||||
* @param object $dataList
|
||||
* @param string $method
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importJiraAction($dataList)
|
||||
public function importJiraAction($dataList, $method = 'db')
|
||||
{
|
||||
$issueStories = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION)
|
||||
->where('AType')->eq('jstory')
|
||||
@@ -891,6 +1164,8 @@ class convertModel extends model
|
||||
$comment = $data->actionbody;
|
||||
if(empty($comment)) continue;
|
||||
|
||||
if(!isset($issueObjectType[$issueID])) continue;
|
||||
|
||||
$objectType = $issueObjectType[$issueID];
|
||||
if($objectType == 'task') $objectID = $issueTasks[$issueID];
|
||||
if($objectType == 'bug') $objectID = $issueBugs[$issueID];
|
||||
@@ -901,7 +1176,7 @@ class convertModel extends model
|
||||
$action = new stdclass();
|
||||
$action->objectType = $objectType;
|
||||
$action->objectID = $objectID;
|
||||
$action->actor = $this->getJiraAccount($data->AUTHOR);
|
||||
$action->actor = $this->getJiraAccount($data->AUTHOR, $method);
|
||||
$action->action = 'commented';
|
||||
$action->date = substr($data->CREATED, 0, 19);
|
||||
$action->comment = $comment;
|
||||
@@ -913,10 +1188,11 @@ class convertModel extends model
|
||||
* Import jira file.
|
||||
*
|
||||
* @param object $dataList
|
||||
* @param string $method
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importJiraFile($dataList)
|
||||
public function importJiraFile($dataList, $method = 'db')
|
||||
{
|
||||
$this->loadModel('file');
|
||||
|
||||
@@ -948,6 +1224,8 @@ class convertModel extends model
|
||||
foreach($dataList as $fileAttachment)
|
||||
{
|
||||
$issueID = $fileAttachment->issueid;
|
||||
if(!isset($issueObjectType[$issueID])) continue;
|
||||
|
||||
$objectType = $issueObjectType[$issueID];
|
||||
if($objectType != 'bug' and $objectType != 'task' and $objectType != 'story') continue;
|
||||
|
||||
@@ -967,7 +1245,7 @@ class convertModel extends model
|
||||
$file->size = $fileAttachment->FILESIZE;
|
||||
$file->objectType = $objectType;
|
||||
$file->objectID = $objectID;
|
||||
$file->addedBy = $this->getJiraAccount($fileAttachment->AUTHOR);
|
||||
$file->addedBy = $this->getJiraAccount($fileAttachment->AUTHOR, $method);
|
||||
$file->addedDate = substr($fileAttachment->CREATED, 0, 19);
|
||||
$this->dao->dbh($this->dbh)->insert(TABLE_FILE)->data($file)->exec();
|
||||
|
||||
@@ -1023,25 +1301,135 @@ class convertModel extends model
|
||||
* Get jira account.
|
||||
*
|
||||
* @param string $userKey
|
||||
* @param string $method
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getJiraAccount($userKey)
|
||||
public function getJiraAccount($userKey, $method = 'db')
|
||||
{
|
||||
if(strpos($userKey, 'JIRAUSER') === false) return $userKey;
|
||||
|
||||
return $this->dao->dbh($this->sourceDBH)->select('lower_user_name')->from(JIRA_USER)->where('user_key')->eq($userKey)->fetch('lower_user_name');
|
||||
if($method == 'db')
|
||||
{
|
||||
return $this->dao->dbh($this->sourceDBH)->select('lower_user_name')->from(JIRA_USER)->where('user_key')->eq($userKey)->fetch('lower_user_name');
|
||||
}
|
||||
else
|
||||
{
|
||||
$appUsers = $this->getJiraAppUser();
|
||||
return zget($appUsers, $userKey, $userKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jira app user pairs.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getJiraAppUser()
|
||||
{
|
||||
$xmlContent = file_get_contents($this->app->getTmpRoot() . 'jirafile/applicationuser.xml');
|
||||
$xmlContent = preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $xmlContent);
|
||||
$parsedXML = simplexml_load_string($xmlContent, SimpleXMLElement::class, LIBXML_NOCDATA);
|
||||
|
||||
$pairs = array();
|
||||
$parsedXML = $this->object2Array($parsedXML);
|
||||
foreach($parsedXML as $key => $xmlArray)
|
||||
{
|
||||
if(strtolower($key) != 'applicationuser') continue;
|
||||
foreach($xmlArray as $key => $attributes)
|
||||
{
|
||||
if(is_numeric($key))
|
||||
{
|
||||
foreach($attributes as $value)
|
||||
{
|
||||
if(!is_array($value)) continue;
|
||||
if(!isset($value['userKey'])) continue;
|
||||
$pairs[$value['userKey']] = $value['lowerUserName'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$pairs[$attributes['userKey']] = $attributes['lowerUserName'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $pairs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split jira file.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function splitFile()
|
||||
{
|
||||
$filePath = $this->app->getTmpRoot() . 'jirafile/';
|
||||
$fileName = 'entities.xml';
|
||||
$file = $filePath . $fileName;
|
||||
$handle = fopen($file, "r");
|
||||
|
||||
$usingData = array();
|
||||
$headerList = array('<Action', '<Project', '<Status', '<Resolution', '<User', '<Issue', '<ChangeGroup', '<ChangeItem', '<IssueLink', '<IssueLinkType', '<FileAttachment', '<Version', '<IssueType', '<NodeAssociation', '<ApplicationUser');
|
||||
$footerList = array('<Action' => '</Action>', '<Project' => '</Project>', '<Status' => '</Status>', '<Resolution' => '</Resolution>', '<User' => '</User>', '<Issue' => '</Issue>', '<ChangeGroup' => '</ChangeGroup>', '<ChangeItem' => '</ChangeItem>', '<IssueLink' => '</IssueLink>', '<IssueLinkType' => '</IssueLinkType>', '<FileAttachment' => '</FileattAchment>', '<Version' => '</Version>', '<IssueType' => '</IssueType>', '<NodeAssociation' => '</NodeAssociation>', '<ApplicationUser' => '</ApplicationUser>');
|
||||
|
||||
while(!feof($handle))
|
||||
{
|
||||
$itemStr = fgets($handle);
|
||||
foreach($headerList as $object)
|
||||
{
|
||||
$itemName = $object;
|
||||
$itemName .= ' ';
|
||||
|
||||
if(strpos($itemStr, $itemName) === false) continue;
|
||||
|
||||
if(strpos($itemStr, '/>') === false)
|
||||
{
|
||||
$end = $footerList[$object];
|
||||
while(true)
|
||||
{
|
||||
$followItemStr = fgets($handle);
|
||||
$itemStr .= $followItemStr;
|
||||
if(strpos($itemStr, $end) !== false) break;
|
||||
}
|
||||
}
|
||||
|
||||
$object = str_replace('<', '', $object);
|
||||
$object = strtolower($object);
|
||||
$data = preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $itemStr);
|
||||
if(!file_exists($filePath . $object . '.xml')) $data = "<?xml version='1.0' encoding='UTF-8'?>\n <entity-engine-xml>\n" . $data;
|
||||
file_put_contents($filePath . $object . '.xml', $data, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($headerList as $object)
|
||||
{
|
||||
$object = str_replace('<', '', $object);
|
||||
$object = strtolower($object);
|
||||
$filename = $filePath . $object . '.xml';
|
||||
if(file_exists($filename)) file_put_contents($filename, '</entity-engine-xml>', FILE_APPEND);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create tmp table for import jira.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createTmpTable4Jira()
|
||||
{
|
||||
$sql = <<<EOT
|
||||
CREATE TABLE `jiratmprelation`(
|
||||
`id` int(8) NOT NULL AUTO_INCREMENT,
|
||||
`AType` char(30) NOT NULL,
|
||||
`AID` mediumint(8) NOT NULL,
|
||||
`AID` char(30) NOT NULL,
|
||||
`BType` char(30) NOT NULL,
|
||||
`BID` mediumint(8) NOT NULL,
|
||||
`BID` char(30) NOT NULL,
|
||||
`extra` char(30) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `relation` (`AType`,`BType`,`AID`,`BID`)
|
||||
@@ -1054,4 +1442,25 @@ EOT;
|
||||
}
|
||||
catch(Exception $e){}
|
||||
}
|
||||
|
||||
/**
|
||||
* After exec.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function afterExec()
|
||||
{
|
||||
/* Set project min start date. */
|
||||
$executionProject = $this->dao->dbh($this->dbh)->select('id,project')->from(TABLE_PROJECT)->where('type')->eq('sprint')->andWhere('project')->ne(0)->fetchPairs();
|
||||
$minOpenedDateList = $this->dao->dbh($this->dbh)->select('id,execution,min(openedDate) as minOpenedDate')->from(TABLE_TASK)->where('execution')->in(array_keys($executionProject))->groupBy('execution')->fetchPairs('execution', 'minOpenedDate');
|
||||
|
||||
foreach($minOpenedDateList as $executionID => $minOpenedDate)
|
||||
{
|
||||
$projectID = $executionProject[$executionID];
|
||||
$this->dao->update(TABLE_PROJECT)->set('begin')->eq($minOpenedDate)->where('id')->eq($projectID)->orWhere('id')->eq($executionID)->exec();
|
||||
}
|
||||
|
||||
$this->dbh->exec("DROP TABLE" . JIRA_TMPRELATION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,28 +13,33 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='main-header'>
|
||||
<h2><i class='icon-import'></i> <?php echo $lang->convert->jira->importJira;?></h2>
|
||||
<h2 class="importData"><i class='icon-import'></i> <?php echo $lang->convert->jira->importJira;?></h2>
|
||||
</div>
|
||||
<div>
|
||||
<div class='form-group'>
|
||||
<ul id='resultBox'></ul>
|
||||
<ul id='resultBox'>
|
||||
<li class='text-red hidden'><strong><?php echo $lang->convert->jira->importing;?></strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='from-group'><?php echo html::a(inlink('importJira', "method=db&type=user&lastID=0&createTable=true"), $lang->convert->jira->start, '', "class='btn btn-primary' id='execButton'");?></div>
|
||||
<div class='from-group'><?php echo html::a(inlink('importJira', "method=$method&type=user&lastID=0&createTable=true"), $lang->convert->jira->start, '', "class='btn btn-primary' id='execButton'");?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function()
|
||||
{
|
||||
$('#execButton').click(function()
|
||||
{
|
||||
$('#execButton').hide();
|
||||
$('#resultBox .text-red').removeClass('hidden');
|
||||
$('.importData').html('<?php echo $lang->convert->jira->importingAB;?>');
|
||||
|
||||
$.getJSON($(this).attr('href'), function(response)
|
||||
{
|
||||
if(response.result == 'finished')
|
||||
{
|
||||
$('#resultBox').append("<li class='text-success'>" + response.message + "</li>");
|
||||
$('#resultBox li.text-red').hide();
|
||||
$('.importData').html('<?php echo $lang->convert->jira->imported;?>');
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -17,24 +17,24 @@ li .form-control {margin-top: 10px}
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='main-header'>
|
||||
<h2>
|
||||
<?php echo $type == 'db' ? $lang->convert->jira->importFromDB : $lang->convert->jira->importFromFile;?>
|
||||
<?php echo $method == 'db' ? $lang->convert->jira->importFromDB : $lang->convert->jira->importFromFile;?>
|
||||
</h2>
|
||||
</div>
|
||||
<form class='form-ajax' method='post'>
|
||||
<div class='panel-title text-center text-red'><?php echo $lang->convert->jira->importNotice;?></div>
|
||||
<div class='panel-body'>
|
||||
<ol>
|
||||
<li><?php echo $lang->convert->jira->importSteps[$type][1];?></li>
|
||||
<li><?php echo $lang->convert->jira->importSteps[$type][2];?></li>
|
||||
<?php if($type == 'db'):?>
|
||||
<li><?php echo $lang->convert->jira->importSteps[$type][3];?></li>
|
||||
<li><?php echo $lang->convert->jira->importSteps[$method][1];?></li>
|
||||
<li><?php echo $lang->convert->jira->importSteps[$method][2];?></li>
|
||||
<?php if($method == 'db'):?>
|
||||
<li><?php echo $lang->convert->jira->importSteps[$method][3];?></li>
|
||||
<?php else:?>
|
||||
<li><?php echo sprintf($lang->convert->jira->importSteps[$type][3], $app->getTmpRoot() . 'jirafile');?></li>
|
||||
<li><?php echo sprintf($lang->convert->jira->importSteps[$method][3], $app->getTmpRoot() . 'jirafile');?></li>
|
||||
<?php endif;?>
|
||||
<li><?php echo sprintf($lang->convert->jira->importSteps[$type][4], $app->getTmpRoot());?></li>
|
||||
<li><?php echo sprintf($lang->convert->jira->importSteps[$method][4], $app->getTmpRoot());?></li>
|
||||
<li>
|
||||
<?php echo $lang->convert->jira->importSteps[$type][5];?>
|
||||
<?php if($type == 'db'):?>
|
||||
<?php echo $lang->convert->jira->importSteps[$method][5];?>
|
||||
<?php if($method == 'db'):?>
|
||||
<?php echo html::input('dbName', '', "class='form-control w-200px' placeholder={$lang->convert->jira->dbNameNotice}");?>
|
||||
<?php endif;?>
|
||||
</li>
|
||||
|
||||
@@ -46,5 +46,4 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -10,13 +10,27 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='main-header'>
|
||||
<h2>
|
||||
<?php echo $lang->convert->jira->mapJira2Zentao;?>
|
||||
</h2>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div class="btn-toolbar pull-left">
|
||||
<?php echo html::a("javascript::void(0);", "<span class='text'>" . $lang->convert->jira->mapJira2Zentao . '</span>', '', "class='btn btn-link btn-active-text'");?>
|
||||
</div>
|
||||
</div>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<form class='main-form form-ajax' method='post'>
|
||||
<div class='main-header text-center'>
|
||||
<ul class='nav nav-primary'>
|
||||
<?php foreach($lang->convert->jira->steps as $key => $label):?>
|
||||
<?php $active = $step == $key ? 'class="active"' : '';?>
|
||||
<li <?php echo $active;?>>
|
||||
<a><?php echo $label;?></a>
|
||||
</li>
|
||||
<?php endforeach;?>
|
||||
</ul>
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<?php echo html::submitButton($lang->convert->jira->next);?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if($step == 1):?>
|
||||
<table class='table table-form'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
@@ -25,15 +39,18 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($issueTypePairs as $id => $name):?>
|
||||
<?php foreach($issueTypeList as $id => $issueType):?>
|
||||
<?php $value = $method == 'db' ? $issueType->pname : $issueType['name'];?>
|
||||
<tr>
|
||||
<td><?php echo html::select('jiraObject[]', $issueTypePairs, $id, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('jiraObject[]', array($id => $value), $id, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('zentaoObject[]', $lang->convert->jira->zentaoObjectList, '', "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<?php endif;?>
|
||||
<?php if($step == 2):?>
|
||||
<table class='table table-form'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
@@ -42,15 +59,18 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($linkTypePairs as $id => $name):?>
|
||||
<?php foreach($linkTypeList as $id => $linkType):?>
|
||||
<?php $value = $method == 'db' ? $linkType->linkname : $linkType['linkname'];?>
|
||||
<tr>
|
||||
<td><?php echo html::select('jiraLinkType[]', $linkTypePairs, $id, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('jiraLinkType[]', array($id => $value), $id, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('zentaoLinkType[]', $lang->convert->jira->zentaoLinkTypeList, '', "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<?php endif;?>
|
||||
<?php if($step == 3):?>
|
||||
<table class='table table-form'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
@@ -60,9 +80,10 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($resolutions as $id => $name):?>
|
||||
<?php foreach($resolutionList as $id => $resolution):?>
|
||||
<?php $value = $method == 'db' ? $resolution->pname : $resolution['name'];?>
|
||||
<tr>
|
||||
<td><?php echo html::select('jiraResolution[]', $resolutions, $id, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('jiraResolution[]', array($id => $value), $id, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('zentaoResolution[]', $lang->bug->resolutionList, '', "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('zentaoReason[]', $lang->story->reasonList, '', "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
@@ -70,6 +91,8 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<?php endif;?>
|
||||
<?php if($step == 4):?>
|
||||
<table class='table table-form'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
@@ -81,9 +104,10 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($statusList as $id => $name):?>
|
||||
<?php foreach($statusList as $id => $status):?>
|
||||
<?php $value = $method == 'db' ? $status->pname : $status['name'];?>
|
||||
<tr>
|
||||
<td><?php echo html::select('jiraStatus[]', $statusList, $id, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('jiraStatus[]', array($id => $value), $id, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('storyStatus[]', $lang->story->statusList, '', "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('storyStage[]', $lang->story->stageList, '', "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('taskStatus[]', $lang->task->statusList, '', "class='form-control chosen'");?></td>
|
||||
@@ -91,11 +115,7 @@
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="5" class="text-center form-actions"><?php echo html::submitButton($lang->convert->jira->next);?></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<?php endif;?>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</style>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='pull-right'>
|
||||
<?php if(common::hasPriv('custom', 'setstoryconcept')) echo html::a($this->createLink('custom', 'setstoryconcept', '', '', true), $lang->custom->setStoryConcept, '', "class='btn btn-primary iframe' data-width=50%");?>
|
||||
<?php if(common::hasPriv('custom', 'setstoryconcept')) echo html::a($this->createLink('custom', 'setstoryconcept', '', '', true), $lang->custom->setStoryConcept, '', "class='btn btn-primary iframe' data-width=" . ($this->config->URAndSR ? "590px" : "405px"));?>
|
||||
</div>
|
||||
</div>
|
||||
<div id='mainContent' class='main-row'>
|
||||
@@ -45,7 +45,7 @@
|
||||
<td class='text-left SRBox'><?php echo $URSR['SRName'];?></td>
|
||||
<td class='c-actions'>
|
||||
<?php $disabled = $key == $config->custom->URSR ? "disabled=disabled" : '';?>
|
||||
<?php if(common::hasPriv('custom', 'editStoryConcept')) echo html::a($this->createLink('custom', 'editStoryConcept', "id=$key", '', true), "<i class='icon icon-edit'></i>", '', "class='btn iframe' data-width=50% title={$lang->edit}");?>
|
||||
<?php if(common::hasPriv('custom', 'editStoryConcept')) echo html::a($this->createLink('custom', 'editStoryConcept', "id=$key", '', true), "<i class='icon icon-edit'></i>", '', "class='btn iframe' data-width=" . ($this->config->URAndSR ? "480px" : "330px") . " title={$lang->edit}");?>
|
||||
<?php if(common::hasPriv('custom', 'deleteStoryConcept')) echo html::a($this->createLink('custom', 'deleteStoryConcept', "id=$key"), "<i class='icon icon-trash'></i>", 'hiddenwin', "class='btn' $disabled title={$lang->delete} data-group='admin'");?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<?php if($this->config->URAndSR):?>
|
||||
<td class='w-200px'><strong><?php echo $lang->custom->URConcept;?></strong></th>
|
||||
<?php endif;?>
|
||||
<td class='w-200px'><strong><?php echo $lang->custom->SRConcept;?></strong></th>
|
||||
<td class='<?php echo $this->config->URAndSR ? "w-200px" : "w-250px";?>'><strong><?php echo $lang->custom->SRConcept;?></strong></th>
|
||||
<td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -52,8 +52,7 @@ EOT;
|
||||
<?php if($this->config->URAndSR):?>
|
||||
<td class='w-200px'><strong><?php echo $lang->custom->URConcept;?></strong></th>
|
||||
<?php endif;?>
|
||||
<td class='w-200px'><strong><?php echo $lang->custom->SRConcept;?></strong></th>
|
||||
<td></td><td></td>
|
||||
<td<?php echo $this->config->URAndSR ? " class='w-200px'": " class='w-250px'";?>><strong><?php echo $lang->custom->SRConcept;?></strong></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<?php if($this->config->URAndSR):?>
|
||||
@@ -65,7 +64,8 @@ EOT;
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='text-center' colspan='4'><?php echo html::submitButton();?></td>
|
||||
<?php if ($this->config->URAndSR) echo "<td></td>";?>
|
||||
<td class=<?php echo !$this->config->URAndSR ? "'text-center' colspan='2'" : "text-left";?>><?php echo html::submitButton();?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -2024,7 +2024,7 @@ class execution extends control
|
||||
{
|
||||
if($this->execution->isClickable($execution, $action)) $executionActions[] = $action;
|
||||
}
|
||||
|
||||
|
||||
$userList = array();
|
||||
$users = $this->loadModel('user')->getPairs('noletter|nodeleted');
|
||||
$avatarPairs = $this->user->getAvatarPairs();
|
||||
@@ -2066,6 +2066,7 @@ class execution extends control
|
||||
$this->view->allPlans = $allPlans;
|
||||
$this->view->kanbanData = $kanbanData;
|
||||
$this->view->executionActions = $executionActions;
|
||||
$this->view->kanban = $this->lang->execution->kanban;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,4 +11,4 @@ th.c-pri{width:50px;}
|
||||
.c-status, .c-user {width: 70px;}
|
||||
.c-category {width: 80px;}
|
||||
.c-actions-7 {width: 190px;}
|
||||
.closed-story {color:#e5e5e5;}
|
||||
.closed-story {color: #e5e5e5;}
|
||||
|
||||
@@ -363,7 +363,7 @@ class executionModel extends model
|
||||
$this->dao->insert(TABLE_EXECUTION)->data($sprint)
|
||||
->autoCheck($skipFields = 'begin,end')
|
||||
->batchcheck($this->config->execution->create->requiredFields, 'notempty')
|
||||
->checkIF((!empty($sprint->name) and $this->config->systemMode == 'new'), 'name', 'unique', "`type` in ('sprint','stage') and `project` = $sprintProject")
|
||||
->checkIF((!empty($sprint->name) and $this->config->systemMode == 'new'), 'name', 'unique', "`type` in ('sprint','stage', 'kanban') and `project` = $sprintProject")
|
||||
->checkIF(!empty($sprint->code), 'code', 'unique', "`type` in ('sprint','stage')")
|
||||
->checkIF($sprint->begin != '', 'begin', 'date')
|
||||
->checkIF($sprint->end != '', 'end', 'date')
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
</td>
|
||||
<td class='text-left c-name <?php if(!empty($execution->children)) echo 'has-child';?> flex' title='<?php echo $execution->name?>'>
|
||||
<?php if($config->systemMode == 'new'):?>
|
||||
<span class='project-type-label label label-outline <?php echo $execution->type == 'stage' ? 'label-warning' : 'label-info';?>'><?php echo $lang->execution->typeList[$execution->type]?></span>
|
||||
<span class='project-type-label label label-outline <?php echo $execution->type == 'stage' ? 'label-warning' : 'label-info';?>'><?php echo $lang->execution->typeList[$execution->type]?></span>
|
||||
<?php endif;?>
|
||||
<?php
|
||||
$executionLink = $execution->projectModel == 'kanban' ? html::a($this->createLink('execution', 'kanban', 'executionID=' . $execution->id), $execution->name, '', "class='text-ellipsis'") : html::a($this->createLink('execution', 'task', 'execution=' . $execution->id), $execution->name, '', "class='text-ellipsis'");
|
||||
|
||||
@@ -201,7 +201,7 @@ js::set('hasTaskButton', $hasTaskButton);
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="icon icon-close"></i></button>
|
||||
<h4 class="modal-title"><?php echo $lang->execution->linkStoryByPlan;?></h4><?php echo '(' . $lang->execution->linkStoryByPlanTips . ')';?>
|
||||
<h4 class="modal-title"><?php echo $lang->execution->linkStoryByPlan;?></h4><?php echo str_replace($lang->executionCommon, $kanban, $lang->execution->linkStoryByPlanTips);?>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class='input-group'>
|
||||
|
||||
@@ -610,7 +610,7 @@ class gitlabModel extends model
|
||||
{
|
||||
$url .= '&owned=true';
|
||||
}
|
||||
elseif(!empty($minRole))
|
||||
elseif(!empty($minRole) and isset($this->config->gitlab->accessLevel[$minRole]))
|
||||
{
|
||||
$url .= '&min_access_level=' . $this->config->gitlab->accessLevel[$minRole];
|
||||
}
|
||||
@@ -625,7 +625,7 @@ class gitlabModel extends model
|
||||
$results = json_decode(commonModel::http($url . "&statistics=true&order_by={$order}&sort={$sort}&page={$page}&per_page=100&all_available=true"));
|
||||
if(!is_array($results)) break;
|
||||
if(!empty($results)) $allResults = array_merge($allResults, $results);
|
||||
if(count($results) < 100 or $page > 10) break;
|
||||
if(count($results) < 100) break;
|
||||
}
|
||||
|
||||
return $allResults;
|
||||
@@ -701,7 +701,7 @@ class gitlabModel extends model
|
||||
$results = json_decode(commonModel::http($url . "&simple={$simple}&page={$page}&per_page=100"));
|
||||
if(!is_array($results)) break;
|
||||
if(!empty($results)) $allResults = array_merge($allResults, $results);
|
||||
if(count($results) < 100 or $page > 10) break;
|
||||
if(count($results) < 100) break;
|
||||
}
|
||||
|
||||
return $allResults;
|
||||
|
||||
@@ -33,6 +33,7 @@ class kanban extends control
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted');
|
||||
$this->view->userIdPairs = $this->user->getPairs('noletter|nodeleted|showid');
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs();
|
||||
|
||||
$this->display();
|
||||
@@ -1299,6 +1300,7 @@ class kanban extends control
|
||||
{
|
||||
$this->view->cards = $this->kanban->getCardsByObject('region', $regionID, 1);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted');
|
||||
$this->view->userIdPairs = $this->user->getPairs('noletter|nodeleted|showid');
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs();
|
||||
|
||||
$this->display();
|
||||
|
||||
@@ -206,10 +206,10 @@ $lang->kanban->defaultColumn['doing'] = 'doing';
|
||||
$lang->kanban->defaultColumn['done'] = 'done';
|
||||
$lang->kanban->defaultColumn['closed'] = 'close';
|
||||
|
||||
$this->lang->kanban->laneTypeList = array();
|
||||
$this->lang->kanban->laneTypeList['story'] = $lang->SRCommon;
|
||||
$this->lang->kanban->laneTypeList['bug'] = 'Bug';
|
||||
$this->lang->kanban->laneTypeList['task'] = 'Task';
|
||||
$lang->kanban->laneTypeList = array();
|
||||
$lang->kanban->laneTypeList['story'] = $lang->SRCommon;
|
||||
$lang->kanban->laneTypeList['bug'] = 'Bug';
|
||||
$lang->kanban->laneTypeList['task'] = 'Task';
|
||||
|
||||
$lang->kanban->storyColumn = array();
|
||||
$lang->kanban->storyColumn['backlog'] = 'Backlog';
|
||||
|
||||
@@ -206,10 +206,10 @@ $lang->kanban->defaultColumn['doing'] = '进行中';
|
||||
$lang->kanban->defaultColumn['done'] = '已完成';
|
||||
$lang->kanban->defaultColumn['closed'] = '已关闭';
|
||||
|
||||
$this->lang->kanban->laneTypeList = array();
|
||||
$this->lang->kanban->laneTypeList['story'] = $lang->SRCommon;
|
||||
$this->lang->kanban->laneTypeList['bug'] = 'Bug';
|
||||
$this->lang->kanban->laneTypeList['task'] = '任务';
|
||||
$lang->kanban->laneTypeList = array();
|
||||
$lang->kanban->laneTypeList['story'] = $lang->SRCommon;
|
||||
$lang->kanban->laneTypeList['bug'] = 'Bug';
|
||||
$lang->kanban->laneTypeList['task'] = '任务';
|
||||
|
||||
$lang->kanban->storyColumn = array();
|
||||
$lang->kanban->storyColumn['backlog'] = 'Backlog';
|
||||
|
||||
@@ -157,10 +157,10 @@ $lang->kanban->error->childLimitNote = '子列在製品數量之和不能大於
|
||||
|
||||
$lang->kanban->defaultColumn = array('未開始', '進行中', '已完成', '已關閉');
|
||||
|
||||
$this->lang->kanban->laneTypeList = array();
|
||||
$this->lang->kanban->laneTypeList['story'] = $lang->SRCommon;
|
||||
$this->lang->kanban->laneTypeList['bug'] = 'Bug';
|
||||
$this->lang->kanban->laneTypeList['task'] = '任務';
|
||||
$lang->kanban->laneTypeList = array();
|
||||
$lang->kanban->laneTypeList['story'] = $lang->SRCommon;
|
||||
$lang->kanban->laneTypeList['bug'] = 'Bug';
|
||||
$lang->kanban->laneTypeList['task'] = '任務';
|
||||
|
||||
$lang->kanban->storyColumn = array();
|
||||
$lang->kanban->storyColumn['backlog'] = 'Backlog';
|
||||
|
||||
@@ -2036,7 +2036,7 @@ class kanbanModel extends model
|
||||
$lane->type = $type;
|
||||
$lane->execution = $executionID;
|
||||
$this->dao->insert(TABLE_KANBANLANE)->data($lane)->exec();
|
||||
|
||||
|
||||
$laneID = $this->dao->lastInsertId();
|
||||
$this->createExecutionColumns($laneID, $type, $executionID);
|
||||
}
|
||||
|
||||
@@ -127,13 +127,13 @@
|
||||
$count ++;
|
||||
?>
|
||||
<div title="<?php echo $users[$member];?>">
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$member], 'account' => $member)); ?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$member], 'account' => $member), 'avatar-circle avatar-' . zget($userIdPairs, $member)); ?>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
<?php if($teamCount > 3):?>
|
||||
<?php if($teamCount > 4) echo '<span>…</span>';?>
|
||||
<div title="<?php echo $users[end($teamPairs)];?>">
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[end($teamPairs)], 'account' => end($teamPairs))); ?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[end($teamPairs)], 'account' => end($teamPairs)), 'avatar-circle avatar-' . zget($userIdPairs, end($teamPairs))); ?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
foreach($assignedToList as $account)
|
||||
{
|
||||
if($count > 2) continue;
|
||||
echo html::smallAvatar(array('avatar' => $usersAvatar[$account], 'account' => $account));
|
||||
echo html::smallAvatar(array('avatar' => $usersAvatar[$account], 'account' => $account), 'avatar-circle avatar-' . zget($userIdPairs, $account));
|
||||
$count ++;
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -94,6 +94,7 @@ $lang->misc->feature->downloadFile = 'Download introduction';
|
||||
$lang->misc->feature->tutorialDesc = '<p>ZenTao 15.0 has new functions, and you know how to use it through the "<strong>Tutorial</strong>".</p><p>Click your [<span style="color: #0c60e1">Avatar-Theme-Young Blue</span>] to set it.</p>';
|
||||
$lang->misc->feature->themeDesc = '<p>ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.</p><p>Click your [<span style="color: #0c60e1">Avatar-Theme-Young Blue</span>] to set it.</p>';
|
||||
|
||||
$lang->misc->releaseDate['16.4'] = '2022-02-15';
|
||||
$lang->misc->releaseDate['16.3'] = '2022-01-26';
|
||||
$lang->misc->releaseDate['16.2'] = '2022-01-17';
|
||||
$lang->misc->releaseDate['16.1'] = '2022-01-11';
|
||||
@@ -167,6 +168,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['16.4'][] = array('title' => 'Implement JIRA import function and improve plug-in extension mechanism.', 'desc' => '');
|
||||
$lang->misc->feature->all['16.3'][] = array('title' => 'Kanban adds related plan/release/version/iteration functions, and the detail experience is optimized, fix bugs.', 'desc' => '');
|
||||
$lang->misc->feature->all['16.2'][] = array('title' => 'Add kanban model project, fix bugs.', 'desc' => '');
|
||||
$lang->misc->feature->all['16.1'][] = array('title' => 'Plan to add status management and Kanban view, upgrade process optimization, fix bugs.', 'desc' => '');
|
||||
|
||||
@@ -94,6 +94,7 @@ $lang->misc->feature->downloadFile = '下载新版本功能介绍文档';
|
||||
$lang->misc->feature->tutorialDesc = "<p>禅道15系列新增了多项功能,您可以通过“<strong>新手引导教程</strong>”快速了解禅道的基本使用方法。</p><p>通过鼠标经过 [<span style='color: #0c60e1'>头像-新手引导</span>],点击新手引导,即可进入新手引导教程。</p>";
|
||||
$lang->misc->feature->themeDesc = "<p>禅道15系列上线了全新的“青春蓝”主题,页面呈现更加美观,体验更加友好。</p><p>通过鼠标经过 [<span style='color: #0c60e1'>头像-主题-青春蓝</span>],点击青春蓝,即可设置成功。</p>";
|
||||
|
||||
$lang->misc->releaseDate['16.4'] = '2022-02-15';
|
||||
$lang->misc->releaseDate['16.3'] = '2022-01-26';
|
||||
$lang->misc->releaseDate['16.2'] = '2022-01-17';
|
||||
$lang->misc->releaseDate['16.1'] = '2022-01-11';
|
||||
@@ -167,6 +168,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
|
||||
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
|
||||
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
|
||||
|
||||
$lang->misc->feature->all['16.4'][] = array('title' => '实现JIRA导入功能,完善插件扩展机制。', 'desc' => '');
|
||||
$lang->misc->feature->all['16.3'][] = array('title' => '看板增加关联计划/发布/版本/迭代功能,细节体验优化。', 'desc' => '');
|
||||
$lang->misc->feature->all['16.2'][] = array('title' => '新增专业研发看板,可以创建看板模型项目,修复Bug。', 'desc' => '');
|
||||
$lang->misc->feature->all['16.1'][] = array('title' => '计划增加状态管理和看板视图,升级流程优化,修复Bug。', 'desc' => '');
|
||||
|
||||
@@ -163,7 +163,7 @@ class mr extends control
|
||||
if(!$this->app->user->admin)
|
||||
{
|
||||
$groupIDList = array(0 => 0);
|
||||
$groups = $this->gitlab->apiGetGroups($MR->gitlabID, 'name_asc', $this->config->gitlab->accessLevel['developer']);
|
||||
$groups = $this->gitlab->apiGetGroups($MR->gitlabID, 'name_asc', 'developer');
|
||||
foreach($groups as $group) $groupIDList[] = $group->id;
|
||||
$sourceProject = $this->gitlab->apiGetSingleProject($MR->gitlabID, $MR->sourceProject);
|
||||
$isDeveloper = $this->gitlab->checkUserAccess($MR->gitlabID, 0, $sourceProject, $groupIDList, 'developer');
|
||||
@@ -919,7 +919,7 @@ class mr extends control
|
||||
}
|
||||
|
||||
$groupIDList = array(0 => 0);
|
||||
$groups = $this->gitlab->apiGetGroups($gitlabID, 'name_asc', $this->config->gitlab->accessLevel['developer']);
|
||||
$groups = $this->gitlab->apiGetGroups($gitlabID, 'name_asc', 'developer');
|
||||
foreach($groups as $group) $groupIDList[] = $group->id;
|
||||
foreach($projects as $key => $project)
|
||||
{
|
||||
|
||||
+1
-1
@@ -118,7 +118,7 @@ class mrModel extends model
|
||||
$groupIDList = array(0 => 0);
|
||||
if(!$this->app->user->admin)
|
||||
{
|
||||
$groups = $this->gitlab->apiGetGroups($gitlabID, 'name_asc', $this->config->gitlab->accessLevel['reporter']);
|
||||
$groups = $this->gitlab->apiGetGroups($gitlabID, 'name_asc', 'reporter');
|
||||
foreach($groups as $group) $groupIDList[] = $group->id;
|
||||
}
|
||||
$allGroups[$gitlabID] = $groupIDList;
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
.c-hours {width: 80px !important;}
|
||||
.c-progress {width: 80px;}
|
||||
.c-hours, .c-progress {width: 80px !important;}
|
||||
|
||||
@@ -14,7 +14,7 @@ $(document).ready(function()
|
||||
{
|
||||
window.parent.$('#userNav .avatar, #menu-avatar').html('<img src="' + avatar + '"/>');
|
||||
window.parent.$('#mainContent>.cell>.main-header>.avatar').html('<img src="' + avatar + '"/>');
|
||||
window.parent.$('#mainContent .avatar-' + account).html('<img src="' + avatar + '"/>');
|
||||
window.parent.$('#mainContent .avatar-' + userID).html('<img src="' + avatar + '"/>');
|
||||
}
|
||||
|
||||
$('#avatarUploadBtn').tooltip();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php js::set('avatar', $this->app->user->avatar);?>
|
||||
<?php js::set('account', $this->app->user->account);?>
|
||||
<?php js::set('userID', $this->app->user->id);?>
|
||||
<div id='mainContent'>
|
||||
<div class='cell'>
|
||||
<div class='main-header text-center'>
|
||||
|
||||
@@ -366,10 +366,25 @@ function renderKanbanItem(item, $item)
|
||||
'</div>'
|
||||
].join('')).appendTo($item);
|
||||
|
||||
var $time = $dateBox.children('.time');
|
||||
if(item.begin != '2030-01-01' && item.end != '2030-01-01')
|
||||
var $time = $dateBox.children('.time');
|
||||
var beginTimeShort = $.zui.formatDate(begin, 'MM-dd');
|
||||
var beginTimeLong = $.zui.formatDate(begin, 'yyyy-MM-dd');
|
||||
var endTimeShort = $.zui.formatDate(end, 'MM-dd');
|
||||
var endTimeLong = $.zui.formatDate(end, 'yyyy-MM-dd')
|
||||
var to = productplanLang.to;
|
||||
var undetermined = productplanLang.future;
|
||||
var undetermindeDate = '2030-01-01';
|
||||
if(item.begin != undetermindeDate && item.end != undetermindeDate)
|
||||
{
|
||||
$time.text($.zui.formatDate(begin, 'MM-dd') + ' ' + productplanLang.to + ' ' + $.zui.formatDate(end, 'MM-dd')).attr('title', $.zui.formatDate(begin, 'yyyy-MM-dd') + productplanLang.to + $.zui.formatDate(end, 'yyyy-MM-dd')).show();
|
||||
$time.text(beginTimeShort + ' ' + to + ' ' + endTimeShort).attr('title', beginTimeLong + to + endTimeLong).show();
|
||||
}
|
||||
else if(item.begin != undetermindeDate && item.end == undetermindeDate)
|
||||
{
|
||||
$time.text(beginTimeShort + ' ' + to + ' ' + undetermined).attr('title', beginTimeLong + to).show();
|
||||
}
|
||||
else if(item.begin == undetermindeDate && item.end != undetermindeDate)
|
||||
{
|
||||
$time.text(undetermined + ' ' + to + ' ' + endTimeShort).attr('title', to + endTimeLong).show();
|
||||
}
|
||||
else if(item.begin != '2030-01-01' && item.end == '2030-01-01')
|
||||
{
|
||||
@@ -381,7 +396,7 @@ function renderKanbanItem(item, $item)
|
||||
}
|
||||
else
|
||||
{
|
||||
$time.text(productplanLang.future).attr('title', productplanLang.future).show();
|
||||
$time.text(undetermined).attr('title', undetermined).show();
|
||||
}
|
||||
|
||||
/* Output plan desc information. */
|
||||
|
||||
@@ -59,6 +59,7 @@ class program extends control
|
||||
$this->view->status = $status;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->users = $this->user->getPairs('noletter');
|
||||
$this->view->userIdPairs = $this->user->getPairs('noletter|showid');
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs();
|
||||
$this->view->programType = $programType;
|
||||
$this->view->PMList = $PMList;
|
||||
@@ -489,35 +490,9 @@ class program extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createStakeholder($programID = 0, $dept = '', $parentIdList = '')
|
||||
public function createStakeholder($programID = 0)
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$this->program->createStakeholder($programID);
|
||||
die(js::locate($this->createLink('program', 'stakeholder', "programID=$programID"), 'parent'));
|
||||
}
|
||||
|
||||
$this->program->setMenu($programID);
|
||||
|
||||
$this->loadModel('user');
|
||||
$this->lang->program->switcherMenu = $this->program->getSwitcher($programID, true);
|
||||
|
||||
$this->loadModel('dept');
|
||||
$deptUsers = $dept === '' ? array() : $this->dept->getDeptUserPairs($dept);
|
||||
|
||||
$this->view->title = $this->lang->program->createStakeholder;
|
||||
$this->view->position[] = $this->lang->program->createStakeholder;
|
||||
|
||||
$this->view->programID = $programID;
|
||||
$this->view->program = $this->program->getByID($programID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noclosed');
|
||||
$this->view->deptUsers = $deptUsers;
|
||||
$this->view->dept = $dept;
|
||||
$this->view->depts = array('' => '') + $this->dept->getOptionMenu();
|
||||
$this->view->stakeholders = $this->program->getStakeholders($programID, 't1.id_desc');
|
||||
$this->view->parentStakeholders = $this->program->getStakeholdersByPrograms($parentIdList);
|
||||
|
||||
$this->display();
|
||||
return print($this->fetch('stakeholder', 'create', "objectID=$programID"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<td class='c-status'><span class="status-program status-<?php echo $program->status?>"><?php echo zget($lang->project->statusList, $program->status, '');?></span></td>
|
||||
<td>
|
||||
<?php if(!empty($program->PM)):?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$program->PM], 'account' => $program->PM)); ?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$program->PM], 'account' => $program->PM), 'avatar-circle avatar-' . zget($userIdPairs, $program->PM)); ?>
|
||||
<?php $userID = isset($PMList[$program->PM]) ? $PMList[$program->PM]->id : '';?>
|
||||
<?php $userName = zget($users, $program->PM);?>
|
||||
<?php echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");?>
|
||||
|
||||
@@ -262,9 +262,10 @@ class project extends control
|
||||
$this->view->executionActions = $executionActions;
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->project->common . $this->lang->colon . $this->lang->project->index;
|
||||
$this->view->position[] = $this->lang->project->index;
|
||||
$this->view->project = $project;
|
||||
$this->view->title = $this->lang->project->common . $this->lang->colon . $this->lang->project->index;
|
||||
$this->view->position[] = $this->lang->project->index;
|
||||
$this->view->project = $project;
|
||||
$this->view->userIdPairs = $this->loadModel('user')->getPairs('nodeleted|showid');
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -308,6 +309,7 @@ class project extends control
|
||||
$this->view->programTree = $this->project->getTreeMenu(0, array('projectmodel', 'createManageLink'), 0, 'list');
|
||||
$this->view->programs = array('0' => '') + $this->program->getParentPairs();
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter|pofirst|nodeleted');
|
||||
$this->view->userIdPairs = $this->loadModel('user')->getPairs('nodeleted|showid');
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs();
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->projectType = $projectType;
|
||||
|
||||
@@ -155,13 +155,13 @@
|
||||
$count ++;
|
||||
?>
|
||||
<a href='<?php echo helper::createLink('project', 'team', "projectID=$projectID");?>' title="<?php echo $users[$member];?>">
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$member], 'account' => $member)); ?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$member], 'account' => $member), 'avatar-circle avatar-' . zget($userIdPairs, $member)); ?>
|
||||
</a>
|
||||
<?php endforeach;?>
|
||||
<?php if($project->teamCount > 3):?>
|
||||
<?php if($project->teamCount > 4) echo '<span>…</span>';?>
|
||||
<a href='<?php echo helper::createLink('project', 'team', "projectID=$projectID");?>' title="<?php echo $users[$member];?>">
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[end($project->teamMembers)], 'account' => $member)); ?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[end($project->teamMembers)], 'account' => $member), 'avatar-circle avatar-' . zget($userIdPairs, $member)); ?>
|
||||
</a>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<?php if($count > 2) break;?>
|
||||
<?php $count ++;?>
|
||||
<div title="<?php echo $member->realname;?>">
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$member->account], 'account' => $member->account)); ?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$member->account], 'account' => $member->account), 'avatar-circle avatar-' . zget($userIdPairs, $member->account)); ?>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
<?php if(count($members) > 4):?>
|
||||
@@ -102,7 +102,7 @@
|
||||
<?php if(count($members) > 3):?>
|
||||
<?php $lastMember = end($members);?>
|
||||
<div title="<?php echo $lastMember->realname;?>">
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$lastMember->account], 'account' => $lastMember->account)); ?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$lastMember->account], 'account' => $lastMember->account), 'avatar-circle avatar-' . zget($userIdPairs, $lastMember->account)); ?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
|
||||
@@ -1146,7 +1146,7 @@ class repo extends control
|
||||
|
||||
$projects = $this->gitlab->apiGetProjects($gitlabID, $filter ? 'false' : 'true');
|
||||
$groupIDList = array(0 => 0);
|
||||
$groups = $this->gitlab->apiGetGroups($gitlabID, 'name_asc', $this->config->gitlab->accessLevel['developer']);
|
||||
$groups = $this->gitlab->apiGetGroups($gitlabID, 'name_asc', 'developer');
|
||||
foreach($groups as $group) $groupIDList[] = $group->id;
|
||||
if($filter == 'IS_DEVELOPER')
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
.modal-iframe .modal-content .modal-header .modal-title .icon-eye-open {display: none;}
|
||||
.modal-iframe .modal-content .modal-header .modal-title a.btn {border-color: transparent; background: none; padding: 0px; border-radius: 2px; color: #036; padding: 4px 7px;}
|
||||
.modal-iframe .modal-content .modal-header .modal-title a.btn .icon-eye-open {display: inline;}
|
||||
.modal-iframe .modal-header .close {top: 17px !important;}
|
||||
.input-group-btn.goback {padding-left: 10px;}
|
||||
.input-group-btn.select {min-width: 60px; margin-left: -2px;}
|
||||
.input-group .chosen-container {min-width: 250px;}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.table-report .table-nest-icon {color: #000; font-weight: 700;}
|
||||
.table-report .label-pri {border: 4px solid #D4333F; height: 25px; width: 25px; border-radius: 25px; margin-left: 5px;}
|
||||
.table-report .label-pri .label-full {display: block; transform: translate(-20%, 6%); background-color: #D4333F; width: 15px; height: 15px; border-radius: 15px;}
|
||||
@@ -67,8 +67,10 @@ $lang->sonarqube->qualitygateList['WARN'] = 'Warning';
|
||||
$lang->sonarqube->qualitygateList['ERROR'] = 'Failed';
|
||||
|
||||
$lang->sonarqube->apiErrorMap[1] = "/Malformed key for Project: '([\s\S]+)'. Allowed characters are alphanumeric, '-', '_', '\.' and ':', with at least one non-digit\./";
|
||||
$lang->sonarqube->apiErrorMap[2] = "/Could not create Project, key already exists: ([\s\S]+)/";
|
||||
|
||||
$lang->sonarqube->errorLang[1] = "Malformed key for Project Key,Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.";
|
||||
$lang->sonarqube->errorLang[2] = "Could not create Project, key already exists: %s";
|
||||
|
||||
$lang->sonarqube->issue = new stdclass();
|
||||
$lang->sonarqube->issue->message = 'Issue Name';
|
||||
|
||||
@@ -30,26 +30,33 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-data">
|
||||
<table class="table table-data table-report">
|
||||
<thead>
|
||||
<tr class="text-center">
|
||||
<th><?php echo $lang->sonarqube->report->bugs;?></th>
|
||||
<th><?php echo $lang->sonarqube->report->vulnerabilities;?></th>
|
||||
<th class="w-150px"><?php echo $lang->sonarqube->report->security_hotspots_reviewed;?></th>
|
||||
<th><?php echo $lang->sonarqube->report->code_smells;?></th>
|
||||
<th><?php echo "<span class='table-nest-icon icon icon-bug'></span>" . $lang->sonarqube->report->bugs;?></th>
|
||||
<th class="w-140px"><?php echo "<span class='table-nest-icon icon icon-unlock'></span>" . $lang->sonarqube->report->vulnerabilities;?></th>
|
||||
<th class="w-180px"><?php echo "<span class='table-nest-icon icon icon-shield'></span>" . $lang->sonarqube->report->security_hotspots_reviewed;?></th>
|
||||
<th class="w-130px"><?php echo "<span class='table-nest-icon icon icon-frown'></span>" . $lang->sonarqube->report->code_smells;?></th>
|
||||
<th><?php echo $lang->sonarqube->report->coverage;?></th>
|
||||
<th><?php echo $lang->sonarqube->report->duplicated_lines_density;?></th>
|
||||
<th><?php echo $lang->sonarqube->report->ncloc;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$emptyRing = "<span class='label-pri'></span>";
|
||||
$fullRing = "<span class='label-pri'><span class='label-full'></span></span>";
|
||||
|
||||
$coverageIcon = $measures['coverage'] != '0.0%' ? $fullRing : $emptyRing;
|
||||
$duplicationIcon = $measures['duplicated_lines_density'] != '0.0%' ? $fullRing : $emptyRing;
|
||||
?>
|
||||
<tr class="text-center">
|
||||
<td><?php echo $measures['bugs'];?></td>
|
||||
<td><?php echo $measures['vulnerabilities'];?></td>
|
||||
<td><?php echo $measures['security_hotspots_reviewed'];?></td>
|
||||
<td><?php echo $measures['code_smells'];?></td>
|
||||
<td><?php echo $measures['coverage'];?></td>
|
||||
<td><?php echo $measures['duplicated_lines_density'];?></td>
|
||||
<td><?php echo $measures['coverage'] . $coverageIcon;?></td>
|
||||
<td><?php echo $measures['duplicated_lines_density'] . $duplicationIcon;?></td>
|
||||
<td><?php echo $measures['ncloc'];?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -334,7 +334,7 @@ class story extends control
|
||||
$this->view->users = $users;
|
||||
$this->view->moduleID = $moduleID ? $moduleID : (int)$this->cookie->lastStoryModule;
|
||||
$this->view->moduleOptionMenu = $moduleOptionMenu;
|
||||
$this->view->plans = $this->loadModel('productplan')->getPairsForStory($productID, $branch, 'skipParent|unexpired');
|
||||
$this->view->plans = str_replace('2030-01-01', $this->lang->story->undetermined, $this->loadModel('productplan')->getPairsForStory($productID, $branch, 'skipParent|unexpired'));
|
||||
$this->view->planID = $planID;
|
||||
$this->view->source = $source;
|
||||
$this->view->sourceNote = $sourceNote;
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
*/
|
||||
global $config;
|
||||
$lang->story->create = "Story hinzufügen";
|
||||
$lang->story->createStory = "Story hinzufügen";
|
||||
$lang->story->createRequirement = 'Create Requirement';
|
||||
|
||||
$lang->story->requirement = zget($lang, 'URCommon', "Requirement");
|
||||
$lang->story->story = zget($lang, 'SRCommon', "Story");
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
*/
|
||||
global $config;
|
||||
$lang->story->create = "Create Story";
|
||||
$lang->story->createStory = 'Create Story';
|
||||
$lang->story->createRequirement = 'Create Requirement';
|
||||
|
||||
$lang->story->requirement = zget($lang, 'URCommon', "Requirement");
|
||||
$lang->story->story = zget($lang, 'SRCommon', "Story");
|
||||
@@ -68,6 +66,7 @@ $lang->story->viewAll = "See All";
|
||||
$lang->story->toTask = 'Convert to Task';
|
||||
$lang->story->batchToTask = 'Batch Convert to Task';
|
||||
$lang->story->convertRelations = 'Convert Relations';
|
||||
$lang->story->undetermined = 'undetermined';
|
||||
|
||||
$lang->story->editAction = "Edit {$lang->SRCommon}";
|
||||
$lang->story->changeAction = "Change {$lang->SRCommon}";
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
*/
|
||||
global $config;
|
||||
$lang->story->create = "Créer Story";
|
||||
$lang->story->createStory = "Créer Story";
|
||||
$lang->story->createRequirement = 'Create Requirement';
|
||||
|
||||
$lang->story->requirement = zget($lang, 'URCommon', "Requirement");
|
||||
$lang->story->story = zget($lang, 'SRCommon', "Story");
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
*/
|
||||
global $config;
|
||||
$lang->story->create = "Create Story";
|
||||
$lang->story->createStory = 'Create Story';
|
||||
$lang->story->createRequirement = 'Create Requirement';
|
||||
|
||||
$lang->story->requirement = zget($lang, 'UrCommon', "Requirement");
|
||||
$lang->story->story = zget($lang, 'SrCommon', "Story");
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
*/
|
||||
global $config;
|
||||
$lang->story->create = "提{$lang->SRCommon}";
|
||||
$lang->story->createStory = "提{$lang->SRCommon}";
|
||||
$lang->story->createRequirement = "提{$lang->SRCommon}";
|
||||
|
||||
$lang->story->requirement = zget($lang, 'URCommon', "需求");
|
||||
$lang->story->story = zget($lang, 'SRCommon', "故事");
|
||||
@@ -68,6 +66,7 @@ $lang->story->viewAll = '查看全部';
|
||||
$lang->story->toTask = '转任务';
|
||||
$lang->story->batchToTask = '批量转任务';
|
||||
$lang->story->convertRelations = '换算关系';
|
||||
$lang->story->undetermined = '待定';
|
||||
|
||||
$lang->story->editAction = "编辑{$lang->SRCommon}";
|
||||
$lang->story->changeAction = "变更{$lang->SRCommon}";
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
*/
|
||||
global $config;
|
||||
$lang->story->create = "提{$lang->SRCommon}";
|
||||
$lang->story->createStory = "提{$lang->SRCommon}";
|
||||
$lang->story->createRequirement = "提{$lang->SRCommon}";
|
||||
|
||||
$lang->story->requirement = zget($lang, 'URCommon', "需求");
|
||||
$lang->story->story = zget($lang, 'SRCommon', "故事");
|
||||
|
||||
@@ -573,4 +573,19 @@ class testreportModel extends model
|
||||
->andWhere('id')->in(trim($storyIdList, ','))
|
||||
->fetchAll('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get pairs.
|
||||
*
|
||||
* @param int $productID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getPairs($productID = 0)
|
||||
{
|
||||
return $this->dao->select('id,title')->from(TABLE_TESTREPORT)
|
||||
->beginIF($productID)->where('product')->eq($productID)->fi()
|
||||
->orderBy('id_desc')
|
||||
->fetchPairs();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -756,7 +756,7 @@ class testtask extends control
|
||||
$executions = empty($productID) ? array() : $this->product->getExecutionPairsByProduct($productID, 0, 'id_desc', $projectID);
|
||||
$executionID = $task->execution;
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,notrunk', $executionID, 'execution');
|
||||
$testreports = $this->testtask->getTestReportPairsByBuild($task->build);
|
||||
$testreports = $this->loadModel('testreport')->getPairs($task->product);
|
||||
|
||||
$this->view->task = $task;
|
||||
$this->view->executions = $executions;
|
||||
@@ -1435,7 +1435,7 @@ class testtask extends control
|
||||
$testTasks = $this->testtask->getUserTestTaskPairs($account, 0, $status);
|
||||
|
||||
if($id) return print(html::select("testtasks[$id]", $testTasks, '', 'class="form-control"'));
|
||||
return print(html::select('testtask', $testTasks, '', 'class=form-control'));
|
||||
return print(html::select('testtask', $testTasks, '', 'class="form-control"'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1453,16 +1453,16 @@ class testtask extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get test report.
|
||||
* Ajax: Get test report by productID.
|
||||
*
|
||||
* @param int $buildID
|
||||
* @param int $productID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetTestReports($buildID)
|
||||
public function ajaxGetTestReports($productID)
|
||||
{
|
||||
/* Testreport list. */
|
||||
$pairs = $this->testtask->getTestReportPairsByBuild($buildID);
|
||||
return print(html::select('testreport', $pairs, '', "class='form-control chosen'"));
|
||||
$pairs = $this->loadModel('testreport')->getPairs($productID);
|
||||
return print(html::select('testreport', array('') + $pairs, '', "class='form-control chosen'"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,13 +106,13 @@ function loadExecutionBuilds(executionID, selected)
|
||||
/**
|
||||
* Load test report.
|
||||
*
|
||||
* @param int buildID
|
||||
* @param int productID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function loadTestReports(buildID)
|
||||
function loadTestReports(productID)
|
||||
{
|
||||
link = createLink('testtask', 'ajaxGetTestReports', 'buildID=' + buildID);
|
||||
link = createLink('testtask', 'ajaxGetTestReports', 'productID=' + productID);
|
||||
$.get(link, function(data)
|
||||
{
|
||||
if(!data) data = '<select id="testreport" name="testreport" class="form-control"></select>';
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
function loadProductRelated()
|
||||
{
|
||||
loadExecutions($('#product').val());
|
||||
buildData = '<select id="build" name="build" class="form-control" onchange="loadTestReports(this.value)"></select>';
|
||||
loadTestReports($('#product').val());
|
||||
buildData = '<select id="build" name="build" class="form-control"></select>';
|
||||
$('#build').replaceWith(buildData);
|
||||
$('#build_chosen').remove();
|
||||
$("#build").chosen();
|
||||
@@ -37,5 +38,6 @@ function loadExecutions(productID)
|
||||
$(function()
|
||||
{
|
||||
adjustPriBoxWidth();
|
||||
loadTestReports($('#product').val());
|
||||
if($('#execution').val() != 0) loadExecutionBuilds($('#execution').val());
|
||||
});
|
||||
|
||||
@@ -1069,7 +1069,8 @@ class testtaskModel extends model
|
||||
$testtaskPairs = array();
|
||||
while($testtask = $stmt->fetch())
|
||||
{
|
||||
$testtaskPairs[$testtask->id] = $testtask->execution . ' / ' . $testtask->name;
|
||||
if($testtask->execution) $testtask->execution .= " / ";
|
||||
$testtaskPairs[$testtask->id] = $testtask->execution . $testtask->name;
|
||||
}
|
||||
return $testtaskPairs;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<?php else:?>
|
||||
<tr class='hide'>
|
||||
<th class='w-80px'><?php echo $lang->testtask->product;?></th>
|
||||
<td class='w-p35-f'><?php echo html::input('product', $productID, "class='form-control'");?></td><td></td>
|
||||
<td class='w-p35-f'><?php echo html::input('product', $productID, "class='form-control' onchange='loadTestReports(this.value)'");?></td><td></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
@@ -41,7 +41,7 @@
|
||||
<th class='w-80px'><?php echo $lang->testtask->build;?></th>
|
||||
<td class='w-p35-f'>
|
||||
<div class='input-group' id='buildBox'>
|
||||
<?php echo html::select('build', empty($builds) ? '' : $builds, $build, "class='form-control chosen' onchange='loadTestReports(this.value)'");?>
|
||||
<?php echo html::select('build', empty($builds) ? '' : $builds, $build, "class='form-control chosen'");?>
|
||||
<?php if(isset($executionID) and $executionID and empty($builds)):?>
|
||||
<span class='input-group-addon'><?php echo html::a(helper::createLink('build', 'create', "executionID=$executionID&productID=$productID&projectID=$projectID", '', true), $lang->build->create, '', "data-toggle='modal' data-type='iframe' data-width='95%'")?> </span>
|
||||
</div>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->testtask->build;?></th>
|
||||
<td class='w-p35-f'><span id='buildBox'><?php echo html::select('build', $builds, $task->build, "class='form-control chosen' onchange='loadTestReports(this.value)'");?></span></td>
|
||||
<td class='w-p35-f'><span id='buildBox'><?php echo html::select('build', $builds, $task->build, "class='form-control chosen'");?></span></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -69,7 +69,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->testtask->testreport;?></th>
|
||||
<td><?php echo html::select('testreport', $testreports, $task->testreport, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('testreport', array('') + $testreports, $task->testreport, "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->testtask->name;?></th>
|
||||
|
||||
@@ -151,3 +151,4 @@ $lang->upgrade->fromVersions['16_0_beta1'] = '16.0.beta1';
|
||||
$lang->upgrade->fromVersions['16_0'] = '16.0';
|
||||
$lang->upgrade->fromVersions['16_1'] = '16.1';
|
||||
$lang->upgrade->fromVersions['16_2'] = '16.2';
|
||||
$lang->upgrade->fromVersions['16_3'] = '16.3';
|
||||
|
||||
@@ -756,6 +756,10 @@ class upgradeModel extends model
|
||||
$this->updateSpaceTeam();
|
||||
$this->updateDocField();
|
||||
$this->appendExec('16_2');
|
||||
case '16_3':
|
||||
$this->saveLogs('Execute 16_3');
|
||||
$this->execSQL($this->getUpgradeFile('16.3'));
|
||||
$this->appendExec('16_3');
|
||||
}
|
||||
|
||||
$this->deletePatch();
|
||||
@@ -966,6 +970,7 @@ class upgradeModel extends model
|
||||
case '16_0': $confirmContent .= file_get_contents($this->getUpgradeFile('16.0'));
|
||||
case '16_1': $confirmContent .= file_get_contents($this->getUpgradeFile('16.1'));
|
||||
case '16_2': $confirmContent .= file_get_contents($this->getUpgradeFile('16.2'));
|
||||
case '16_3': $confirmContent .= file_get_contents($this->getUpgradeFile('16.3'));
|
||||
}
|
||||
return str_replace('zt_', $this->config->db->prefix, $confirmContent);
|
||||
}
|
||||
|
||||
+10
-3
@@ -119,9 +119,16 @@ class userModel extends model
|
||||
/* Cycle the user records to append the first letter of his account. */
|
||||
foreach($users as $account => $user)
|
||||
{
|
||||
$firstLetter = ucfirst(substr($user->account, 0, 1)) . ':';
|
||||
if(strpos($params, 'noletter') !== false or !empty($this->config->isINT)) $firstLetter = '';
|
||||
$users[$account] = $firstLetter . (($user->deleted and strpos($params, 'realname') === false) ? $user->account : ($user->realname ? $user->realname : $user->account));
|
||||
if(strpos($params, 'showid') !== false)
|
||||
{
|
||||
$users[$account] = $user->id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$firstLetter = ucfirst(substr($user->account, 0, 1)) . ':';
|
||||
if(strpos($params, 'noletter') !== false or !empty($this->config->isINT)) $firstLetter = '';
|
||||
$users[$account] = $firstLetter . (($user->deleted and strpos($params, 'realname') === false) ? $user->account : ($user->realname ? $user->realname : $user->account));
|
||||
}
|
||||
}
|
||||
|
||||
/* Append empty, closed, and guest users. */
|
||||
|
||||
@@ -21,22 +21,22 @@ if(!$result) $result = 'return null';
|
||||
r($result) && p() && e('return null'); //使用空的数据查询群组
|
||||
|
||||
$gitlabID = 1;
|
||||
$result = $gitlab->apiGetGroups($gitlabID, $orderBy, $minRole);
|
||||
$result = $gitlab->apiGetGroups($gitlabID, $orderBy, $minRole);
|
||||
if($result) $result = 'return true';
|
||||
r($result) && p() && e('return true'); //使用正确的gitlabID查询群组
|
||||
|
||||
$orderBy = 'abc';
|
||||
$result = $gitlab->apiGetGroups($gitlabID, $orderBy, $minRole);
|
||||
$result = $gitlab->apiGetGroups($gitlabID, $orderBy, $minRole);
|
||||
if(is_array($result)) $result = 'return true';
|
||||
r($result) && p() && e('return true'); //使用错误的orderBy查询群组
|
||||
|
||||
$orderBy = 'name_asc';
|
||||
$minRole = 'owner';
|
||||
$result = $gitlab->apiGetGroups($gitlabID, $orderBy, $minRole);
|
||||
$result = $gitlab->apiGetGroups($gitlabID, $orderBy, $minRole);
|
||||
if(is_array($result)) $result = 'return true';
|
||||
r($result) && p() && e('return true'); //通过gitlabID,orderBy查询群组
|
||||
|
||||
$minRole = 'abc';
|
||||
$result = $gitlab->apiGetGroups($gitlabID, $orderBy, $minRole);
|
||||
if(is_array($result) && empty($result)) $result = 'return true';
|
||||
$result = $gitlab->apiGetGroups($gitlabID, $orderBy, $minRole);
|
||||
if(is_array($result)) $result = 'return true';
|
||||
r($result) && p() && e('return true'); //通过错误的minRole查询群组
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 sonarqubeModel::apiCreateProject();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
使用空的sonarqubeID、项目对象创建sonarqube项目 >> return false
|
||||
使用空的sonarqubeID、正确的项目对象创建sonarqube项目 >> return false
|
||||
使用正确的sonarqubeID,项目对象创建sonarqube项目 >> unit_test
|
||||
使用重复的项目对象创建sonarqube项目 >> Could not create Project, key already exists: unit_test
|
||||
|
||||
*/
|
||||
|
||||
$sonarqube = $tester->loadModel('sonarqube');
|
||||
|
||||
$sonarqubeID = 0;
|
||||
$project = new stdclass();
|
||||
|
||||
$result = $sonarqube->apiCreateProject($sonarqubeID, $project);
|
||||
if($result === false) $result = 'return false';
|
||||
r($result) && p() && e('return false'); //使用空的sonarqubeID、项目对象创建sonarqube项目
|
||||
|
||||
$project->projectName = 'unit_test';
|
||||
$project->projectKey = 'unit_test';
|
||||
$result = $sonarqube->apiCreateProject($sonarqubeID, $project);
|
||||
if($result === false) $result = 'return false';
|
||||
r($result) && p() && e('return false'); //使用空的sonarqubeID、正确的项目对象创建sonarqube项目
|
||||
|
||||
$sonarqubeID = 2;
|
||||
$sonarqube->apiDeleteProject($sonarqubeID, $project->projectKey);
|
||||
$result = $sonarqube->apiCreateProject($sonarqubeID, $project);
|
||||
r($result) && p('project:key') && e('unit test'); //使用正确的sonarqubeID,项目对象创建sonarqube项目
|
||||
$result = $sonarqube->apiCreateProject($sonarqubeID, $project);
|
||||
r($result->errors) && p('0:msg') && e("Could not create Project, key already exists: unit_test"); //使用重复的项目对象创建sonarqube项目
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 sonarqubeModel::apiGetIssues();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
通过sonarqubeID,获取SonarQube问题列表 >> 1
|
||||
通过sonarqubeID,项目key获取SonarQube问题列表 >> 1
|
||||
当sonarqubeID为0时,获取SonarQube问题列表 >> return empty
|
||||
|
||||
*/
|
||||
|
||||
$sonarqube = $tester->loadModel('sonarqube');
|
||||
|
||||
$sonarqubeID = 2;
|
||||
$result = $sonarqube->apiGetIssues($sonarqubeID);
|
||||
r(isset($result[0]->message)) && p() && e('1'); //通过sonarqubeID,获取SonarQube问题列表
|
||||
|
||||
$projectKey = 'zentaopms';
|
||||
$result = $sonarqube->apiGetIssues($sonarqubeID, $projectKey);
|
||||
r(isset($result[0]->message)) && p() && e('1'); //通过sonarqubeID,项目key获取SonarQube问题列表
|
||||
|
||||
$sonarqubeID = 0;
|
||||
$result = $sonarqube->apiGetIssues($sonarqubeID);
|
||||
if(empty($result)) $result = 'return empty';
|
||||
r($result) && p() && e('return empty'); //当sonarqubeID为0时,获取SonarQube问题列表
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 sonarqubeModel::createProject();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
使用空的项目数据,空的sonarqubeID创建Sonarqube项目 >> 『项目名称』不能为空
|
||||
使用错误项目数据,正确的sonarqubeID创建Sonarqube项目 >> return error
|
||||
使用正确的项目数据,空的sonarqubeID创建Sonarqube项目 >> return false
|
||||
使用正确的sonarqubeID和Sonarqube项目信息创建Sonarqube项目 >> 1
|
||||
|
||||
*/
|
||||
|
||||
$sonarqube = $tester->loadModel('sonarqube');
|
||||
|
||||
$sonarqubeID = 0;
|
||||
$_POST['projectName'] = '';
|
||||
$_POST['projectKey'] = '';
|
||||
$sonarqube->createProject($sonarqubeID);
|
||||
r(dao::getError()) && p('projectName:0') && e('『项目名称』不能为空'); //使用空的项目数据,空的sonarqubeID创建Sonarqube项目
|
||||
|
||||
$sonarqubeID = 2;
|
||||
$_POST['projectName'] = 'unit_test';
|
||||
$_POST['projectKey'] = '@#';
|
||||
$sonarqube->createProject($sonarqubeID);
|
||||
$errors = dao::getError();
|
||||
if(array_shift($errors) == "项目标识的格式不正确。允许的字符为字母、数字、'-'、''、'.'和“:”,至少有一个非数字。") $result = 'return error';
|
||||
r($result) && p() && e("return error"); //使用错误项目数据,正确的sonarqubeID创建Sonarqube项目
|
||||
|
||||
$sonarqubeID = 0;
|
||||
$_POST['projectName'] = 'unit_test';
|
||||
$_POST['projectKey'] = 'unit_test';
|
||||
$result = $sonarqube->createProject($sonarqubeID);
|
||||
if(empty($result)) $result = 'return false';
|
||||
r($result) && p() && e('return false'); //使用正确的项目数据,空的sonarqubeID创建Sonarqube项目
|
||||
|
||||
dao::getError();
|
||||
$sonarqubeID = 2;
|
||||
$sonarqube->apiDeleteProject($sonarqubeID, $_POST['projectKey']);
|
||||
$result = $sonarqube->createProject($sonarqubeID);
|
||||
r($result) && p() && e(1); //使用正确的sonarqubeID和Sonarqube项目信息创建Sonarqube项目
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 sonarqubeModel::getCacheFile();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
使用正确的sonarqubeID,项目key获取缓存文件 >> 1
|
||||
|
||||
*/
|
||||
|
||||
$sonarqube = $tester->loadModel('sonarqube');
|
||||
|
||||
$sonarqubeID = 2;
|
||||
$projectKey = 'unit_test';
|
||||
$result = $sonarqube->getCacheFile($sonarqubeID, $projectKey);
|
||||
r(strPos($result, '/' . $sonarqubeID . '-' ) !== false) && p('') && e(1); //使用正确的sonarqubeID,项目key获取缓存文件
|
||||
@@ -84,4 +84,4 @@ a.showMoreImage:hover {opacity: 1;}
|
||||
#headerActions .dropdown-menu {top: 35px; z-index: 2000;}
|
||||
#headerActions .dropdown-menu:before, #headerActions .dropdown-menu:hover:before {position: absolute; top: -9px; right: 50%; width: 0; height: 0; content: ' '; border-color: transparent transparent #fff transparent; border-style: solid; border-width: 0 10px 10px 10px;}
|
||||
|
||||
.icon-size-width:before {content: "\e9c5"; transform: rotate(90deg); -ms-transform: rotate(90deg); -moz-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg);
|
||||
.icon-size-width:before {content: "\e9c5"; transform: rotate(90deg); -ms-transform: rotate(90deg); -moz-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg)};
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -222,9 +222,15 @@
|
||||
<glyph unicode="" glyph-name="publish, send" d="M450.158-149.754c-2.8 0-5.7 0.5-8.3 1.5-9.799 3.4-16.599 12.299-17.299 22.599l-13.8 259.386-375.179 113.693c-20.199 5.9-34.398 23.998-35.498 44.997-1.2 21.099 10.699 40.697 30.099 49.297l958.646 391.278c3.1 1.3 6.399 1.9 9.699 1.9 5.9 0 11.699-2.1 16.199-5.9 7.2-6 10.599-15.499 8.799-24.699l-155.991-797.455c-2.4-11.3-8.599-21.499-17.599-28.898-8.9-7.299-19.999-11.3-31.499-11.3-10.2 0-20.099 3.1-28.398 9l-188.089 130.493-132.592-147.292c-4.9-5.5-11.899-8.599-19.199-8.599zM955.13 621.803l-479.673-465.474 342.081-237.586 137.593 703.060zM463.557 102.332l8.599-163.591 87.495 96.994-96.094 66.596zM902.532 642.302l-848.953-346.681 374.679-113.493 474.273 460.174z" />
|
||||
<glyph unicode="" glyph-name="college" d="M528-206.629c-0.441-0.027-0.953-0.041-1.472-0.041-5.431 0-10.469 1.691-14.613 4.576l0.085-0.055-432.64 245.12c-4.754 2.64-8.64 6.32-11.445 10.752l-0.075 0.128c-21.561 36.718-34.297 80.871-34.297 128s12.736 91.282 34.951 129.207l-0.654-1.209c3.001 3.835 6.608 7.033 10.704 9.502l0.176 0.098 433.28 247.68c4.373 2.715 9.678 4.325 15.36 4.325s10.987-1.609 15.486-4.398l-0.126 0.073 432.64-245.12c7.451-3.87 12.878-10.763 14.686-19.015l0.034-0.185c0.549-2.126 0.864-4.565 0.864-7.077 0-5.931-1.753-11.454-4.773-16.075l0.069 0.112c-16.869-27.993-26.848-61.792-26.848-97.92s9.979-69.927 27.33-98.789l-0.485 0.869c2.544-4.377 4.046-9.632 4.046-15.239 0-2.542-0.309-5.010-0.889-7.371l0.043 0.21c-2.315-8.039-7.602-14.576-14.565-18.48l-0.155-0.080-431.36-245.12c-4.306-2.809-9.577-4.48-15.239-4.48-0.041 0-0.085 0-0.128 0h0.007zM117.12 90.971l410.88-232.32 392.32 222.080c-13.55 29.947-21.445 64.933-21.445 101.76s7.895 71.813 22.085 103.353l-0.64-1.593-392.32 222.080-410.88-232.32c-14.615-26.448-23.216-57.979-23.216-91.52s8.601-65.072 23.717-92.512l-0.501 0.992zM501.12-191.269c-21.934 36.624-34.903 80.798-34.903 128s12.969 91.376 35.541 129.152l-0.638-1.152 51.84-32.64-25.6 16.64 25.6-16c-16.869-27.993-26.848-61.792-26.848-97.92s9.979-69.927 27.33-98.789l-0.485 0.869zM528 247.131c-0.327-0.011-0.709-0.018-1.093-0.018-5.472 0-10.61 1.431-15.061 3.938l0.153-0.080-432.64 245.76c-9.287 5.074-15.481 14.775-15.481 25.92s6.194 20.846 15.328 25.842l0.153 0.078 432.64 245.76c4.446 2.418 9.737 3.84 15.36 3.84s10.914-1.422 15.531-3.925l-0.171 0.085 433.28-245.76c9.287-5.074 15.481-14.775 15.481-25.92s-6.194-20.846-15.328-25.842l-0.153-0.078-432.64-245.76c-4.457-2.37-9.737-3.785-15.344-3.84h-0.016zM156.16 522.971l371.84-210.56 371.2 210.56-371.2 209.92zM501.12 36.571c-21.561 36.718-34.297 80.871-34.297 128s12.736 91.282 34.951 129.207l-0.654-1.207 51.84-32.64c-16.869-27.993-26.848-61.792-26.848-97.92s9.979-69.927 27.33-98.789l-0.485 0.869zM528 20.571c-0.327-0.011-0.709-0.018-1.093-0.018-5.472 0-10.61 1.431-15.061 3.938l0.153-0.080-432.64 245.12c-4.894 2.699-8.821 6.626-11.445 11.371l-0.075 0.149c-21.934 36.624-34.903 80.798-34.903 128s12.969 91.376 35.541 129.152l-0.638-1.152 51.84-32.64c-16.171-27.538-25.723-60.654-25.723-96s9.552-68.462 26.215-96.905l-0.491 0.905 410.88-232.32 392.32 222.72c-13.465 29.824-21.312 64.656-21.312 101.321 0 47.92 13.401 92.709 36.658 130.825l-0.626-1.106 25.6-16 26.24-16.64c-16.752-27.918-26.656-61.602-26.656-97.6s9.906-69.682 27.143-98.473l-0.485 0.873c2.562-4.498 4.071-9.883 4.071-15.621 0-2.631-0.318-5.191-0.917-7.639l0.046 0.219c-2.715-7.842-7.886-14.254-14.576-18.473l-0.144-0.087-434.56-240c-4.457-2.37-9.737-3.785-15.344-3.84h-0.016z" />
|
||||
<glyph unicode="" glyph-name="tree" d="M783.988 725.523h-350.156v-62.111h1.034v-339.283h-192.268c2.628-10.143 3.955-20.578 3.948-31.056 0-10.727-1.373-21.134-3.948-31.056h192.268v-343.422h-1.034v-62.111h351.033c-2.879 9.759-4.337 19.881-4.33 30.055 0 11.174 1.735 21.943 4.941 32.057h-288.499v343.424h288.186c-3.077 10.065-4.636 20.532-4.628 31.056v0c-0.008 10.524 1.552 20.991 4.628 31.056h-288.186v339.283h289.551c-3.977 11.308-6.004 23.209-5.994 35.196 0 9.298 1.203 18.318 3.453 26.913v0zM242.598 324.13c-13.768 53.047-61.971 92.218-119.326 92.218-68.082 0-123.273-55.191-123.273-123.273s55.191-123.273 123.273-123.273c57.354 0 105.558 39.169 119.326 92.218v0c2.628 10.143 3.955 20.578 3.948 31.056 0 10.725-1.372 21.131-3.948 31.054v0zM784.866-143.516c12.957-43.884 53.554-75.913 101.637-75.913 58.525 0 105.967 47.443 105.967 105.967s-47.443 105.967-105.967 105.967c-47.349 0-87.441-31.057-101.026-73.91v0c-3.284-10.368-4.95-21.181-4.941-32.057v-0.003c-0.007-10.174 1.452-20.296 4.331-30.054l-0.001 0.003zM785.163 262.019c13.275-43.37 53.622-74.912 101.339-74.912 58.525 0 105.967 47.443 105.967 105.967s-47.443 105.967-105.967 105.967c-47.717 0-88.064-31.542-101.339-74.912v0c-3.077-10.065-4.636-20.532-4.628-31.056v0c-0.008-10.524 1.552-20.99 4.628-31.054v0zM783.988 725.523v0c-2.298-8.787-3.459-17.833-3.453-26.915v-0.005c-0.010-11.987 2.017-23.888 5.995-35.196 14.513-41.222 53.789-70.771 99.974-70.771 58.525 0 105.967 47.443 105.967 105.967s-47.443 105.967-105.967 105.967c-49.223 0-90.604-33.563-102.514-79.052l-0.002 0.004z" />
|
||||
<glyph unicode="" glyph-name="shield" d="M498.592 802.026c8.616 3.393 18.198 3.393 26.811 0l402.286-158.475c14.609-5.755 23.914-20.193 23.12-35.874l-15.913-314.552c-7.393-146.117-81.65-280.697-201.325-364.862l-200.533-141.034c-12.624-8.877-29.462-8.877-42.083 0.005l-200.521 141.061c-119.621 84.151-193.858 218.679-201.271 364.745l-15.974 314.634c-0.797 15.683 8.507 30.125 23.12 35.881l402.282 158.472zM861.846 296.821l14.586 288.307-364.433 143.563v-866.839l179.496 126.237c101.263 71.216 164.096 185.088 170.351 308.729v0.002z" />
|
||||
<glyph unicode="" glyph-name="list" d="M345.841 658.312h629.406c26.925 0 48.753 21.828 48.753 48.753s-21.828 48.753-48.753 48.753h-629.406c-26.925 0-48.753-21.828-48.753-48.753s21.828-48.753 48.753-48.753zM345.827 269.482h627.096c26.925 0 48.753 21.828 48.753 48.753s-21.828 48.753-48.753 48.753h-627.096c-26.925 0-48.753-21.828-48.753-48.753s21.828-48.753 48.753-48.753zM975.247-23.998h-629.406c-26.925 0-48.753-21.828-48.753-48.753s21.828-48.753 48.753-48.753h629.406c26.925 0 48.753 21.828 48.753 48.753s-21.828 48.753-48.753 48.753zM0 707.065v0c0-53.851 43.655-97.506 97.506-97.506s97.506 43.655 97.506 97.506v0c0 53.851-43.655 97.506-97.506 97.506s-97.506-43.655-97.506-97.506v0zM0 318.818v0c0-53.851 43.655-97.506 97.506-97.506s97.506 43.655 97.506 97.506v0c0 53.851-43.655 97.506-97.506 97.506s-97.506-43.655-97.506-97.506v0zM0-72.476v0c0-53.851 43.655-97.506 97.506-97.506s97.506 43.655 97.506 97.506v0c0 53.851-43.655 97.506-97.506 97.506s-97.506-43.655-97.506-97.506v0z" />
|
||||
<glyph unicode="" glyph-name="gantt" d="M217.356 638.873h424.226c29.549 0 44.324-14.774 44.324-44.324v-81.392c0-29.549-14.774-44.324-44.324-44.324h-424.226c-29.549 0-44.324 14.774-44.324 44.324v81.392c0 29.549 14.774 44.324 44.324 44.324zM217.356 119.902h424.226c29.549 0 44.324-14.774 44.324-44.324v-81.392c0-29.549-14.774-44.324-44.324-44.324h-424.226c-29.549 0-44.324 14.774-44.324 44.324v81.392c0 29.549 14.774 44.324 44.324 44.324zM440.436 379.393h357.253c32.723 0 49.085-16.362 49.085-49.085v-71.87c0-32.723-16.362-49.085-49.085-49.085h-357.253c-32.723 0-49.085 16.362-49.085 49.085v71.87c0 32.723 16.362 49.085 49.085 49.085v0zM927.656-219.429h-831.3c-53.19 0.062-96.293 43.166-96.356 96.356v831.286c0.061 53.19 43.163 96.294 96.353 96.358h831.302c53.19-0.062 96.293-43.166 96.356-96.356v-831.286c-0.061-53.19-43.163-96.294-96.353-96.359h-0.002zM96.356 725.219v0c-9.391 0-17.004-7.613-17.004-17.004 0 0 0 0 0 0v-831.289c0-9.391 7.613-17.004 17.004-17.004h831.3c9.391 0 17.004 7.613 17.004 17.004v831.289c0 9.391-7.613 17.004-17.004 17.004h-831.3z" />
|
||||
<glyph unicode="" glyph-name="group-view" d="M101.777 625.942h90.353c25.963 0 46.734 20.771 46.734 46.734s-20.771 46.734-46.734 46.734h-90.353c-56.081 0-101.777-45.696-101.777-101.777v-595.083c0-56.081 45.696-101.777 101.777-101.777h90.353c25.963 0 46.734 20.771 46.734 46.734s-20.771 46.734-46.734 46.734h-90.353c-5.193 0-8.308 4.154-8.308 8.308v250.288h98.661c25.963 0 46.734 20.771 46.734 46.734s-20.771 46.734-46.734 46.734h-98.661v251.327c0 4.154 3.116 8.308 8.308 8.308zM981.42 444.198h-638.702c-23.886 0-43.619-19.732-43.619-43.619v-163.051c0-23.886 19.732-43.619 43.619-43.619h637.663c23.886 0 43.619 19.732 43.619 43.619v163.051c0 23.886-18.694 43.619-42.58 43.619v0zM421.647 287.378c0-9.347-8.308-16.617-18.694-16.617h-2.077c-9.347 0-16.617 7.27-16.617 16.617v64.389c0 9.347 7.27 16.617 16.617 16.617h2.077c10.385 0 18.694-7.27 18.694-16.617v-64.389zM940.917 311.265c0-22.848-17.655-40.503-40.503-40.503h-352.065c-22.848 0-40.503 17.655-40.503 40.503v16.617c0 22.848 17.655 40.503 40.503 40.503h352.065c22.848 0 40.503-17.655 40.503-40.503v-16.617zM981.42 804.571h-638.702c-23.886 0-43.619-19.732-43.619-43.619v-163.051c0-23.886 19.732-43.619 43.619-43.619h637.663c23.886 0 43.619 19.732 43.619 43.619v164.089c0 23.886-18.694 42.58-42.58 42.58zM421.647 647.752c0-9.347-8.308-16.617-18.694-16.617h-2.077c-9.347 0-16.617 7.27-16.617 16.617v64.389c0 9.347 7.27 16.617 16.617 16.617h2.077c10.385 0 18.694-7.27 18.694-16.617v-64.389zM940.917 671.638c0-22.848-17.655-40.503-40.503-40.503h-352.065c-22.848 0-40.503 17.655-40.503 40.503v16.617c0 22.848 17.655 40.503 40.503 40.503h352.065c22.848 0 40.503-17.655 40.503-40.503v-16.617zM981.42 82.786h-638.702c-23.886 0-43.619-19.732-43.619-43.619v-163.051c0-23.886 19.732-43.619 43.619-43.619h637.663c23.886 0 43.619 19.732 43.619 43.619v164.089c0 23.886-18.694 42.58-42.58 42.58zM421.647-74.033c0-9.347-8.308-16.617-18.694-16.617h-2.077c-9.347 0-16.617 7.27-16.617 16.617v64.389c0 9.347 7.27 16.617 16.617 16.617h2.077c10.385 0 18.694-7.27 18.694-16.617v-64.389zM940.917-50.147c0-22.848-17.655-40.503-40.503-40.503h-352.065c-22.848 0-40.503 17.655-40.503 40.503v16.617c0 22.848 17.655 40.503 40.503 40.503h352.065c22.848 0 40.503-17.655 40.503-40.503v-16.617z" />
|
||||
<glyph unicode="" glyph-name="meh" d="M731.429 182.857c0-20-16.571-36.571-36.571-36.571h-365.714c-20 0-36.571 16.571-36.571 36.571s16.571 36.571 36.571 36.571h365.714c20 0 36.571-16.571 36.571-36.571zM438.857 438.857c0-40.571-32.571-73.143-73.143-73.143s-73.143 32.571-73.143 73.143 32.571 73.143 73.143 73.143 73.143-32.571 73.143-73.143zM731.429 438.857c0-40.571-32.571-73.143-73.143-73.143s-73.143 32.571-73.143 73.143 32.571 73.143 73.143 73.143 73.143-32.571 73.143-73.143zM877.714 292.571c0 201.714-164 365.714-365.714 365.714s-365.714-164-365.714-365.714 164-365.714 365.714-365.714 365.714 164 365.714 365.714zM950.857 292.571c0-242.286-196.571-438.857-438.857-438.857s-438.857 196.571-438.857 438.857 196.571 438.857 438.857 438.857 438.857-196.571 438.857-438.857z" />
|
||||
<glyph unicode="" glyph-name="frown" d="M721.143 102.285c6.286-19.429-4.571-39.429-23.429-45.714-19.429-6.286-40 4.571-46.286 24-18.857 61.143-75.429 102.286-139.429 102.286s-120.571-41.143-139.429-102.286c-6.286-19.429-26.857-30.286-45.714-24-19.429 6.286-30.286 26.286-24 45.714 28.571 92 112.571 153.714 209.143 153.714s180.571-61.714 209.143-153.714zM438.857 438.857c0-40.571-32.571-73.143-73.143-73.143s-73.143 32.571-73.143 73.143 32.571 73.143 73.143 73.143 73.143-32.571 73.143-73.143zM731.429 438.857c0-40.571-32.571-73.143-73.143-73.143s-73.143 32.571-73.143 73.143 32.571 73.143 73.143 73.143 73.143-32.571 73.143-73.143zM877.714 292.571c0 201.714-164 365.714-365.714 365.714s-365.714-164-365.714-365.714 164-365.714 365.714-365.714 365.714 164 365.714 365.714zM950.857 292.571c0-242.286-196.571-438.857-438.857-438.857s-438.857 196.571-438.857 438.857 196.571 438.857 438.857 438.857 438.857-196.571 438.857-438.857z" />
|
||||
<glyph unicode="" glyph-name="smile" d="M721.143 190.285c-28.571-92-112.571-153.714-209.143-153.714s-180.571 61.714-209.143 153.714c-6.286 19.429 4.571 39.429 24 45.714 18.857 6.286 39.429-4.571 45.714-24 18.857-61.143 75.429-102.286 139.429-102.286s120.571 41.143 139.429 102.286c6.286 19.429 26.857 30.286 46.286 24 18.857-6.286 29.714-26.286 23.429-45.714zM438.857 438.857c0-40.571-32.571-73.143-73.143-73.143s-73.143 32.571-73.143 73.143 32.571 73.143 73.143 73.143 73.143-32.571 73.143-73.143zM731.429 438.857c0-40.571-32.571-73.143-73.143-73.143s-73.143 32.571-73.143 73.143 32.571 73.143 73.143 73.143 73.143-32.571 73.143-73.143zM877.714 292.571c0 201.714-164 365.714-365.714 365.714s-365.714-164-365.714-365.714 164-365.714 365.714-365.714 365.714 164 365.714 365.714zM950.857 292.571c0-242.286-196.571-438.857-438.857-438.857s-438.857 196.571-438.857 438.857 196.571 438.857 438.857 438.857 438.857-196.571 438.857-438.857z" />
|
||||
<glyph unicode="" glyph-name="unlock-solid" d="M365.714 606.040v-20.898c0-20.198-16.374-36.571-36.571-36.571s-36.571 16.374-36.571 36.571v20.898c0 89.447 72.512 161.959 161.96 161.959h114.937c89.45 0 161.96-72.512 161.96-161.959v-167.184h120.163c54.824 0 99.266-44.442 99.266-99.266v-423.183c0-54.824-44.442-99.266-99.266-99.266h-679.183c-54.822 0-99.265 44.442-99.265 99.266v423.183c0 54.824 44.443 99.266 99.265 99.266h485.877v167.184c0 49.053-39.763 88.816-88.817 88.816h-114.937c-49.053 0-88.817-39.763-88.817-88.816zM512 256c-20.198 0-36.571-16.373-36.571-36.571v-182.857c0-20.198 16.373-36.571 36.571-36.571s36.571 16.373 36.571 36.571v182.857c0 20.198-16.373 36.571-36.571 36.571z" />
|
||||
<glyph unicode="" glyph-name="lock-solid" d="M585.143 768c80.79 0 146.286-65.494 146.286-146.286v-182.857h109.714c60.595 0 109.714-49.119 109.714-109.714v-402.286c0-60.595-49.119-109.714-109.714-109.714h-658.286c-60.594 0-109.714 49.119-109.714 109.714v402.286c0 60.595 49.121 109.714 109.714 109.714h109.714v182.857c0 80.791 65.494 146.286 146.286 146.286h146.286zM512 256c-20.199 0-36.571-16.374-36.571-36.571v0-182.857c0-20.199 16.373-36.571 36.571-36.571s36.571 16.374 36.571 36.571v0 182.857c0 20.199-16.374 36.571-36.571 36.571zM365.714 621.714v-182.857h292.571v182.857c0 40.395-32.746 73.143-73.143 73.143h-146.286c-40.397 0-73.143-32.747-73.143-73.143z" />
|
||||
<glyph unicode="" glyph-name="file, file-empty" horiz-adv-x="878" d="M838.857 587.428c21.143-21.143 38.857-63.429 38.857-93.714v-658.286c0-30.286-24.571-54.857-54.857-54.857h-768c-30.286 0-54.857 24.571-54.857 54.857v914.286c0 30.286 24.571 54.857 54.857 54.857h512c30.286 0 72.571-17.714 93.714-38.857zM585.143 726.857v-214.857h214.857c-3.429 9.714-8.571 19.429-12.571 23.429l-178.857 178.857c-4 4-13.714 9.143-23.429 12.571zM804.571-146.286v585.143h-237.714c-30.286 0-54.857 24.571-54.857 54.857v237.714h-438.857v-877.714h731.429z" />
|
||||
<glyph unicode="" glyph-name="book" d="M948.764 510.653c13.529-19.482 17.318-44.918 9.741-69.81l-148.822-490.3c-13.529-45.999-61.152-81.716-107.693-81.716h-499.501c-55.199 0-114.186 43.835-134.21 100.116-8.658 24.352-8.658 48.165-1.083 68.728 1.083 10.823 3.248 21.647 3.789 34.635 0.541 8.658-4.329 15.694-3.248 22.188 2.165 12.988 13.529 22.188 22.188 36.799 16.235 27.058 34.635 70.893 40.587 99.033 2.706 10.281-2.706 22.188 0 31.388 2.706 10.281 12.988 17.859 18.401 27.6 14.612 24.894 33.554 73.058 36.259 98.493 1.083 11.364-4.329 23.811-1.083 32.471 3.789 12.447 15.694 17.859 23.811 28.682 12.988 17.859 34.635 69.269 37.881 97.952 1.083 9.199-4.329 18.401-2.706 28.14 2.165 10.281 15.153 21.106 23.811 33.554 22.728 33.554 27.058 107.693 95.787 88.211l-0.541-1.623c9.199 2.165 18.401 4.871 27.6 4.871h411.831c25.434 0 48.165-11.364 61.694-30.306 14.070-19.482 17.318-44.918 9.741-70.352l-148.281-490.3c-25.434-83.34-39.505-101.74-108.235-101.74h-470.277c-7.035 0-15.694-1.623-20.565-8.117-4.329-6.495-4.871-11.364-0.541-23.269 10.823-31.388 48.165-37.881 77.93-37.881h499.501c20.024 0 43.293 11.364 49.247 30.846l162.352 534.135c3.248 10.281 3.248 21.106 2.706 30.846 12.447-4.871 23.811-12.447 31.929-23.269zM372.959 509.57c-3.248-9.741 2.165-17.318 11.905-17.318h329.032c9.199 0 19.482 7.576 22.728 17.318l11.364 34.635c3.248 9.741-2.165 17.318-11.905 17.318h-329.032c-9.199 0-19.482-7.576-22.728-17.318zM328.043 371.031c-3.248-9.741 2.165-17.318 11.905-17.318h329.032c9.199 0 19.482 7.576 22.728 17.318l11.364 34.635c3.248 9.741-2.165 17.318-11.905 17.318h-329.032c-9.199 0-19.482-7.576-22.728-17.318z" />
|
||||
<glyph unicode="" glyph-name="share" d="M960.285 412.526c0-8.506-3.502-16.511-9.505-22.514l-256.163-256.163c-6.003-6.003-14.008-9.505-22.514-9.505-17.512 0-32.020 14.509-32.020 32.020v128.082h-112.072c-215.638 0-357.227-41.527-357.227-280.178 0-20.513 1.001-41.025 2.501-61.54 0.5-8.005 2.501-17.011 2.501-25.015 0-9.505-6.003-17.512-16.010-17.512-7.004 0-10.506 3.502-14.008 8.506-7.505 10.506-13.009 26.518-18.511 38.025-28.517 64.041-63.54 155.598-63.54 225.643 0 56.036 5.504 113.572 26.518 166.606 69.545 172.609 273.673 201.628 437.778 201.628h112.072v128.082c0 17.512 14.509 32.020 32.020 32.020 8.506 0 16.511-3.502 22.514-9.505l256.163-256.163c6.003-6.003 9.505-14.008 9.505-22.514z" />
|
||||
|
||||
|
Before Width: | Height: | Size: 240 KiB After Width: | Height: | Size: 244 KiB |
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user