From 94ccf64354a5d00a471833da9d1332f4a414aaa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Wed, 9 Feb 2022 13:23:28 +0800 Subject: [PATCH 01/24] * Add merge jira. --- module/common/lang/en.php | 2 + module/common/lang/menu.php | 4 +- module/common/lang/zh-cn.php | 2 + module/convert/config.php | 12 +++++ module/convert/control.php | 56 +++++++++++++++++++ module/convert/lang/en.php | 3 ++ module/convert/lang/zh-cn.php | 36 +++++++++++++ module/convert/model.php | 22 +++++--- module/convert/view/importnotice.html.php | 42 +++++++++++++++ module/convert/view/jira.html.php | 50 +++++++++++++++++ module/convert/view/mapjira2zentao.html.php | 59 +++++++++++++++++++++ 11 files changed, 281 insertions(+), 7 deletions(-) create mode 100644 module/convert/config.php create mode 100644 module/convert/view/importnotice.html.php create mode 100644 module/convert/view/jira.html.php create mode 100644 module/convert/view/mapjira2zentao.html.php diff --git a/module/common/lang/en.php b/module/common/lang/en.php index d48b8d0d94..7506af29fe 100644 --- a/module/common/lang/en.php +++ b/module/common/lang/en.php @@ -280,6 +280,8 @@ $lang->admin->data = 'Data'; $lang->admin->cron = 'Cron'; $lang->admin->buildIndex = 'Full Text Search'; +$lang->convert->importJira = 'Import Jira'; + $lang->storyConcept = 'Story Concpet'; $lang->searchTips = ''; diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php index 06031c105c..04ab7a34d0 100644 --- a/module/common/lang/menu.php +++ b/module/common/lang/menu.php @@ -480,7 +480,7 @@ $lang->admin->menu->custom = array('link' => "{$lang->custom->common}|custom| $lang->admin->menu->extension = array('link' => "{$lang->extension->common}|extension|browse", 'subModule' => 'extension'); $lang->admin->menu->dev = array('link' => "$lang->redev|dev|api", 'alias' => 'db', 'subModule' => 'dev,editor,entry'); $lang->admin->menu->message = array('link' => "{$lang->message->common}|message|index", 'subModule' => 'message,mail,webhook'); -$lang->admin->menu->system = array('link' => "{$lang->admin->system}|backup|index", 'subModule' => 'cron,backup,action,admin,search', 'exclude' => 'admin-index,admin-xuanxuan,admin-register,admin-ztcompany'); +$lang->admin->menu->system = array('link' => "{$lang->admin->system}|backup|index", 'subModule' => 'cron,backup,action,admin,search,convert', 'exclude' => 'admin-index,admin-xuanxuan,admin-register,admin-ztcompany'); $lang->admin->menu->model['dropMenu'] = new stdclass(); $lang->admin->menu->model['dropMenu']->allModel = array('link' => "{$lang->globalSetting}|custom|browsestoryconcept|", 'subModule' => 'measurement,report,sqlbuilder,subject,custom,meetingroom,baseline'); @@ -540,6 +540,7 @@ $lang->admin->menu->system['subMenu']->safe = array('link' => "$lang->secu $lang->admin->menu->system['subMenu']->cron = array('link' => "{$lang->admin->cron}|cron|index", 'subModule' => 'cron'); $lang->admin->menu->system['subMenu']->timezone = array('link' => "$lang->timezone|custom|timezone"); $lang->admin->menu->system['subMenu']->buildIndex = array('link' => "{$lang->admin->buildIndex}|search|buildindex|"); +$lang->admin->menu->system['subMenu']->jira = array('link' => "{$lang->convert->importJira}|convert|jira|", 'subModule' => 'convert'); $lang->admin->dividerMenu = ',company,message,system,'; @@ -660,6 +661,7 @@ $lang->navGroup->dev = 'admin'; $lang->navGroup->entry = 'admin'; $lang->navGroup->extension = 'admin'; $lang->navGroup->action = 'admin'; +$lang->navGroup->convert = 'admin'; $lang->navGroup->search = 'search'; $lang->navGroup->index = 'index'; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index c6c8dada3c..b7212e328e 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -280,6 +280,8 @@ $lang->admin->data = '数据'; $lang->admin->cron = '定时'; $lang->admin->buildIndex = '重建索引'; +$lang->convert->importJira = '导入Jira数据'; + $lang->storyConcept = '需求概念'; $lang->searchTips = ''; diff --git a/module/convert/config.php b/module/convert/config.php new file mode 100644 index 0000000000..de99977d0a --- /dev/null +++ b/module/convert/config.php @@ -0,0 +1,12 @@ +view->info = redmineConvertModel::$info; $this->display(); } + + public function jira() + { + $this->view->title = $this->lang->convert->jira->method; + $this->display(); + } + + public function importNotice($type = 'db') + { + if($_POST) + { + $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)); + } + + $response['result'] = 'success'; + $response['message'] = $this->lang->saveSuccess; + $response['locate'] = $this->createLink('convert', 'mapJira2Zentao', "type=db&dbName={$this->post->dbName}"); + return print($this->send($response)); + } + + $this->view->title = $this->lang->convert->jira->method; + $this->view->type = $type; + $this->display(); + } + + public function mapJira2Zentao($type = 'db', $dbName = '') + { + if($_POST) + { + a($_POST);die; + } + + if($type == 'db') + { + $this->convert->connectDB($dbName); + $issueTypePairs = $this->convert->getIssueTypePairs(); + $linkTypePairs = $this->convert->getLinkTypePairs(); + } + + $this->view->title = $this->lang->convert->jira->mapJira2Zentao; + $this->view->issueTypePairs = $issueTypePairs; + $this->view->linkTypePairs = $linkTypePairs; + $this->display(); + } } diff --git a/module/convert/lang/en.php b/module/convert/lang/en.php index cf993dbd6f..065d9fda22 100644 --- a/module/convert/lang/en.php +++ b/module/convert/lang/en.php @@ -114,3 +114,6 @@ $lang->convert->issue = new stdclass(); $lang->convert->issue->redmine = 'Redmine'; $lang->convert->issue->zentao = 'ZenTao'; $lang->convert->issue->goto = 'Convert To'; + +$lang->convert->jira = new stdclass(); +$lang->convert->jira->import = 'Import Jira'; diff --git a/module/convert/lang/zh-cn.php b/module/convert/lang/zh-cn.php index 1326aa2751..f586548793 100644 --- a/module/convert/lang/zh-cn.php +++ b/module/convert/lang/zh-cn.php @@ -114,3 +114,39 @@ $lang->convert->issue = new stdclass(); $lang->convert->issue->redmine = 'Redmine'; $lang->convert->issue->zentao = '禅道'; $lang->convert->issue->goto = '转换为'; + +$lang->convert->jira = new stdclass(); +$lang->convert->jira->method = '选择导入方式'; +$lang->convert->jira->next = '下一步'; +$lang->convert->jira->importFromDB = '从数据库导入'; +$lang->convert->jira->importFromFile = '从文件导入'; +$lang->convert->jira->mapJira2Zentao = '设置对应关系'; +$lang->convert->jira->dbNameNotice = '请输入Jira数据库名字'; +$lang->convert->jira->importNotice = '注意:导入数据有风险!请务必确保如下操作步骤依次完成,再进行合并。'; +$lang->convert->jira->dbDesc = '

如果您的Jira使用Mysql数据库, 请选择此方式

'; +$lang->convert->jira->fileDesc = '

如果您的Jira使用非Mysql数据库, 请选择此方式

'; +$lang->convert->jira->jiraObject = 'Jira Issues'; +$lang->convert->jira->zentaoObject = '禅道对象'; +$lang->convert->jira->jiraLinkType = 'Jira 关联关系'; +$lang->convert->jira->zentaoLinkType = '禅道关联关系'; + +$lang->convert->jira->dbNameEmpty = 'Jira数据库名字不能为空!'; +$lang->convert->jira->invalidDB = '无效的数据库名!'; + +$lang->convert->jira->zentaoObjectList['task'] = '任务'; +$lang->convert->jira->zentaoObjectList['requirement'] = '用户需求'; +$lang->convert->jira->zentaoObjectList['story'] = '软件需求'; +$lang->convert->jira->zentaoObjectList['bug'] = 'Bug'; + +$lang->convert->jira->zentaoLinkTypeList['subTaskLink'] = '父-子任务'; +$lang->convert->jira->zentaoLinkTypeList['subStoryLink'] = '父-子需求'; +$lang->convert->jira->zentaoLinkTypeList['duplicate'] = '重复对象'; +$lang->convert->jira->zentaoLinkTypeList['relates'] = '互相关联'; + +$lang->convert->jira->importSteps['db'][1] = '备份禅道数据库,备份Jira数据库。'; +$lang->convert->jira->importSteps['db'][2] = '将Jira数据库导入到禅道使用的Mysql中,名字和禅道数据库区别开来。'; +$lang->convert->jira->importSteps['db'][3] = "将Jira附件目录 attachment 放到 %s 下,确保禅道服务器磁盘空间足够。"; +$lang->convert->jira->importSteps['db'][4] = "上述步骤完成后,请输入Jira数据库名字进行下一步。"; +$lang->convert->jira->importSteps['file'][1] = '备份禅道数据库,备份Jira数据库。'; +$lang->convert->jira->importSteps['file'][2] = '将Jira数据库导入到禅道使用的Mysql中,名字和禅道数据库区别开来。'; +$lang->convert->jira->importSteps['file'][3] = "将Jira附件目录放到 %s 下。"; diff --git a/module/convert/model.php b/module/convert/model.php index 99f357bbd7..6776fad133 100644 --- a/module/convert/model.php +++ b/module/convert/model.php @@ -19,15 +19,15 @@ class convertModel extends model * @access public * @return void */ - public function connectDB() + public function connectDB($dbName = '') { - $dsn = "mysql:host={$this->post->dbHost}; port={$this->post->dbPort};dbname={$this->post->dbName}"; + $dsn = "mysql:host={$this->config->db->host}; port={$this->config->db->port};dbname={$dbName}"; try { - $dbh = new PDO($dsn, $this->post->dbUser, $this->post->dbPassword); + $dbh = new PDO($dsn, $this->config->db->user, $this->config->db->password); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $dbh->exec("SET NAMES {$this->post->dbCharset}"); + $dbh->exec("SET NAMES {$this->config->db->encoding}"); $this->sourceDBH = $dbh; return $dbh; } @@ -43,9 +43,9 @@ class convertModel extends model * @access public * @return bool */ - public function dbExists() + public function dbExists($dbName = '') { - $sql = "SHOW DATABASES like '{$this->post->db->name}'"; + $sql = "SHOW DATABASES like '{$dbName}'"; return $this->dbh->query($sql)->fetch(); } @@ -93,4 +93,14 @@ class convertModel extends model } $this->session->set('state', $state); } + + public function getIssueTypePairs() + { + return $this->dao->dbh($this->sourceDBH)->select('ID,pname')->from(JIRA_ISSUETYPE)->fetchPairs(); + } + + public function getLinkTypePairs() + { + return $this->dao->dbh($this->sourceDBH)->select('ID,LINKNAME')->from(JIRA_ISSUELINKTYPE)->fetchPairs(); + } } diff --git a/module/convert/view/importnotice.html.php b/module/convert/view/importnotice.html.php new file mode 100644 index 0000000000..095041622e --- /dev/null +++ b/module/convert/view/importnotice.html.php @@ -0,0 +1,42 @@ + + * @package convert + * @version $Id: execute.html.php 4129 2013-01-18 01:58:14Z wwccss $ + */ +?> + + +
+
+

+ convert->jira->importFromDB : $lang->convert->jira->importFromFile;?> +

+
+
+
convert->jira->importNotice;?>
+
+
    +
  1. convert->jira->importSteps[$type][1];?>
  2. +
  3. convert->jira->importSteps[$type][2];?>
  4. +
  5. convert->jira->importSteps[$type][3], $this->app->getTmpRoot());?>
  6. +
  7. + convert->jira->importSteps[$type][4];?> + convert->jira->dbNameNotice}");?> +
  8. +
+
+
+ +
+
+ diff --git a/module/convert/view/jira.html.php b/module/convert/view/jira.html.php new file mode 100644 index 0000000000..35d3bcd4b6 --- /dev/null +++ b/module/convert/view/jira.html.php @@ -0,0 +1,50 @@ + + * @package convert + * @version $Id: execute.html.php 4129 2013-01-18 01:58:14Z wwccss $ + */ +?> + + +
+
+
+
+

convert->jira->method;?>

+
+
+
+
+
"> +

convert->jira->importFromDB;?>

+ convert->jira->dbDesc;?> +
+
+
+
"> +

convert->jira->importFromFile;?>

+ convert->jira->fileDesc;?> +
+
+
+
+
+ + diff --git a/module/convert/view/mapjira2zentao.html.php b/module/convert/view/mapjira2zentao.html.php new file mode 100644 index 0000000000..56dc25bbb1 --- /dev/null +++ b/module/convert/view/mapjira2zentao.html.php @@ -0,0 +1,59 @@ + + * @package convert + * @version $Id: execute.html.php 4129 2013-01-18 01:58:14Z wwccss $ + */ +?> + +
+
+

+ convert->jira->mapJira2Zentao;?> +

+
+
+ + + + + + + + + $name):?> + + + + + + +
convert->jira->jiraObject;?>convert->jira->zentaoObject;?>
convert->jira->zentaoObjectList, '', "class='form-control chosen'");?>
+
+ + + + + + + + + $name):?> + + + + + + + + + + + +
convert->jira->jiraLinkType;?>convert->jira->zentaoLinkType;?>
convert->jira->zentaoLinkTypeList, '', "class='form-control chosen'");?>
+
+
From 89d4ae37bbf6eee15d3e5a5cdbe44412a1a55001 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Tue, 8 Feb 2022 10:11:31 +0800 Subject: [PATCH 02/24] * Fix bug #19286. --- module/task/lang/en.php | 2 +- module/task/lang/vi.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/task/lang/en.php b/module/task/lang/en.php index 3bcf8c4d71..75a1df49ca 100644 --- a/module/task/lang/en.php +++ b/module/task/lang/en.php @@ -234,7 +234,7 @@ $lang->task->error->consumedSmall = '"Total Cost" must be > the last number. $lang->task->error->consumedThisTime = 'Please enter "Hours Cost"'; $lang->task->error->left = 'Please enter "Hours Left"'; $lang->task->error->work = '"Comment" must be < %d characters.'; -$lang->task->error->skipClose = 'Task: %s is not "Finished” or “Cancelled”. Do you want to close it?'; +$lang->task->error->skipClose = 'Task: %s is not “Finished” or “Cancelled”. Do you want to close it?'; $lang->task->error->consumed = 'Task: %s hour must be < 0. Ignore changes to this task.'; $lang->task->error->assignedTo = 'Multi-user task in the current status cannot be assigned to a member who is not in the task team.'; $lang->task->error->consumedEmpty = '"Current Cost" should not be 0.'; diff --git a/module/task/lang/vi.php b/module/task/lang/vi.php index 60ea78c65a..e4f03617e6 100644 --- a/module/task/lang/vi.php +++ b/module/task/lang/vi.php @@ -213,7 +213,7 @@ $lang->task->error->consumedSmall = '"Tổng giờ làm" phải là > số c $lang->task->error->consumedThisTime = 'Vui lòng nhập "Số giờ làm"'; $lang->task->error->left = 'Vui lòng nhập "Giờ còn lại"'; $lang->task->error->work = '"Nhận xét" phải là < %d ký tự.'; -$lang->task->error->skipClose = 'Nhiệm vụ: %s không là "Kết thúc” hoặc “Đã hủy”. Bạn có muốn đóng nó?'; +$lang->task->error->skipClose = 'Nhiệm vụ: %s không là “Kết thúc” hoặc “Đã hủy”. Bạn có muốn đóng nó?'; $lang->task->error->consumed = 'Nhiệm vụ: %s giờ phải là < 0. Bỏ qua thay đổi cho nhiệm vụ này.'; $lang->task->error->assignedTo = 'Nhiệm vụ nhiều người dùng trong tình trạng hiện tại không thể giao cho một thành viên người không trong Nhóm nhiệm vụ.'; $lang->task->error->consumedEmpty = '"Giờ làm" không nên 0.'; From 17b5477551d683c034d9b9486dd6cf8adaf49aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Tue, 8 Feb 2022 14:01:40 +0800 Subject: [PATCH 03/24] * Fix bug close modal bug. --- module/bug/control.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module/bug/control.php b/module/bug/control.php index 07fbe4a59c..2393e25f9c 100644 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -1415,8 +1415,7 @@ class bug extends control parse_str($extra, $output); if(isonlybody()) { - $execution = $this->loadModel('execution')->getByID($bug->execution); - if(isset($execution->type) and $execution->type == 'kanban') + if($this->app->tab == 'execution') { $regionID = isset($output['regionID']) ? $output['regionID'] : 0; $kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID); From d4466bc65ad2fab4a52c5dfc73c5e0052089da27 Mon Sep 17 00:00:00 2001 From: tanghucheng Date: Tue, 8 Feb 2022 16:15:13 +0800 Subject: [PATCH 04/24] * Fix bug #19307. --- module/project/view/ajaxgetdropmenu.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/project/view/ajaxgetdropmenu.html.php b/module/project/view/ajaxgetdropmenu.html.php index 648ed20b7f..a21af9ba0b 100644 --- a/module/project/view/ajaxgetdropmenu.html.php +++ b/module/project/view/ajaxgetdropmenu.html.php @@ -97,7 +97,7 @@ foreach($projects as $programID => $programProjects) } else if($project->status == 'done' or $project->status == 'closed') { - $closedProjectsHtml .= '
  • ' . html::a(sprintf($link, $project->id), $projectName, '', "class='$selected projectName' title='$projectName' data-key='" . zget($projectsPinYin, $project->name, '') . "'") . '
  • '; + $closedProjectsHtml .= '
  • ' . html::a(sprintf($link, $project->id), $projectName, '', "class='$selected projectName' title='$project->name' data-key='" . zget($projectsPinYin, $project->name, '') . "'") . '
  • '; if($selected == 'selected') $tabActive = 'closed'; } From b2a2bd26fca5530d94d4ef14281ad30bcc3ca62c Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Tue, 8 Feb 2022 09:08:15 +0800 Subject: [PATCH 05/24] *Fix bug #18593. --- module/execution/view/all.html.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/module/execution/view/all.html.php b/module/execution/view/all.html.php index 9e38e926ea..87d89df26b 100644 --- a/module/execution/view/all.html.php +++ b/module/execution/view/all.html.php @@ -118,7 +118,15 @@ id);?> flex' title='name?>'> - '>execution->typeList[$execution->type]?> + systemMode == 'classic'):?> + 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'");echo !empty($execution->children) ? $execution->name : $executionLink; + if(isset($execution->delay)) echo "{$lang->execution->delayed} ";?> + children)):?> + + + + systemMode == 'new'):?> + '>execution->typeList[$execution->type]?> 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'"); echo !empty($execution->children) ? $execution->name : $executionLink; @@ -127,6 +135,7 @@ children)):?> + systemMode == 'new' and $this->app->tab == 'execution'):?> From 35a28257718f30844325cbc49c9995fcbe5af679 Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Tue, 8 Feb 2022 14:13:24 +0800 Subject: [PATCH 06/24] *Fix bug #18593. --- module/execution/view/all.html.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/module/execution/view/all.html.php b/module/execution/view/all.html.php index 87d89df26b..a23e098fe9 100644 --- a/module/execution/view/all.html.php +++ b/module/execution/view/all.html.php @@ -118,15 +118,9 @@ id);?> flex' title='name?>'> - systemMode == 'classic'):?> - 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'");echo !empty($execution->children) ? $execution->name : $executionLink; - if(isset($execution->delay)) echo "{$lang->execution->delayed} ";?> - children)):?> - - - systemMode == 'new'):?> '>execution->typeList[$execution->type]?> + 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'"); echo !empty($execution->children) ? $execution->name : $executionLink; @@ -135,7 +129,6 @@ children)):?> - systemMode == 'new' and $this->app->tab == 'execution'):?> From bf80ebbc3118e01a64e6be7950bd609488617c75 Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Tue, 8 Feb 2022 13:47:35 +0800 Subject: [PATCH 07/24] *Fix bug #19265. --- module/kanban/model.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/module/kanban/model.php b/module/kanban/model.php index 859f2f177f..ea3893fa03 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1933,6 +1933,7 @@ class kanbanModel extends model $this->dao->insert(TABLE_KANBAN)->data($kanban) ->autoCheck() ->batchCheck($this->config->kanban->create->requiredFields, 'notempty') + ->checkIF(!empty($kanban->name), 'name', 'unique') ->exec(); if(!dao::isError()) @@ -1946,6 +1947,7 @@ class kanbanModel extends model return $kanbanID; } + } /** From d0b19ad953fa0859fad8d2815be6b580da6534da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E6=97=AD=E4=B8=9C?= Date: Tue, 8 Feb 2022 05:49:56 +0000 Subject: [PATCH 08/24] Update model.php --- module/kanban/model.php | 1 - 1 file changed, 1 deletion(-) diff --git a/module/kanban/model.php b/module/kanban/model.php index ea3893fa03..511a9b89c4 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1947,7 +1947,6 @@ class kanbanModel extends model return $kanbanID; } - } /** From c7ac66ea621526d39d62fa33e20abbb86e5e58e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E6=97=AD=E4=B8=9C?= Date: Tue, 8 Feb 2022 06:04:16 +0000 Subject: [PATCH 09/24] Update model.php --- module/kanban/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kanban/model.php b/module/kanban/model.php index 511a9b89c4..6b1e84a888 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1933,7 +1933,7 @@ class kanbanModel extends model $this->dao->insert(TABLE_KANBAN)->data($kanban) ->autoCheck() ->batchCheck($this->config->kanban->create->requiredFields, 'notempty') - ->checkIF(!empty($kanban->name), 'name', 'unique') + ->check('name', 'unique') ->exec(); if(!dao::isError()) From 26156f2810d4cef31393df821cb4e40d89804065 Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Wed, 9 Feb 2022 09:24:26 +0800 Subject: [PATCH 10/24] *Fix bug #19292. --- module/my/css/project.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/my/css/project.css b/module/my/css/project.css index bb863b066c..7dd4be4654 100644 --- a/module/my/css/project.css +++ b/module/my/css/project.css @@ -3,5 +3,5 @@ #projectTableList > tr:last-child .c-actions .dropdown-menu {top: auto; bottom: 100%; margin-bottom: -5px;} .c-budget {width: 100px;} - +.label-warning, .label-info {width: 60px !important;} .project-type-label.label-outline {width: 50px; min-width: 50px;} From cc392110e08f3d8817210a5a8661f4bd2e67b7f0 Mon Sep 17 00:00:00 2001 From: liyuchun Date: Wed, 9 Feb 2022 12:59:50 +0800 Subject: [PATCH 11/24] * Fix bug. --- module/gitlab/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/gitlab/model.php b/module/gitlab/model.php index 3a552325e7..d0c4ebf3e4 100644 --- a/module/gitlab/model.php +++ b/module/gitlab/model.php @@ -612,7 +612,7 @@ class gitlabModel extends model } elseif(!empty($minRole)) { - $url .= "&min_access_level=$this->config->gitlab->accessLevel[$minRole]"; + $url .= '&min_access_level=' . $this->config->gitlab->accessLevel[$minRole]; } $order = 'id'; From 32ce0200ef688e51cde81e38fd175db618119cf1 Mon Sep 17 00:00:00 2001 From: tanghucheng Date: Wed, 9 Feb 2022 13:04:16 +0800 Subject: [PATCH 12/24] * Fix bug. --- module/bug/control.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/bug/control.php b/module/bug/control.php index 2393e25f9c..e780fccbe2 100644 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -1415,7 +1415,8 @@ class bug extends control parse_str($extra, $output); if(isonlybody()) { - if($this->app->tab == 'execution') + $execution = $this->loadModel('execution')->getByID($bug->execution); + if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution') { $regionID = isset($output['regionID']) ? $output['regionID'] : 0; $kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID); From 6783e843f5096c577ce563a9f0ff325dcf53f9b5 Mon Sep 17 00:00:00 2001 From: zhouxudong Date: Wed, 9 Feb 2022 09:10:41 +0800 Subject: [PATCH 13/24] *Fix bug #19293. --- module/my/css/execution.css | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 module/my/css/execution.css diff --git a/module/my/css/execution.css b/module/my/css/execution.css new file mode 100644 index 0000000000..7d5a627e92 --- /dev/null +++ b/module/my/css/execution.css @@ -0,0 +1,3 @@ +.c-hours {width : 80px !important;} +.c-progress {width : 80px;} + From b158a2a7aab4c431a5edf3721a7f4624b12db016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E6=97=AD=E4=B8=9C?= Date: Wed, 9 Feb 2022 01:13:58 +0000 Subject: [PATCH 14/24] Update execution.css --- module/my/css/execution.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/my/css/execution.css b/module/my/css/execution.css index 7d5a627e92..7069de49bc 100644 --- a/module/my/css/execution.css +++ b/module/my/css/execution.css @@ -1,3 +1,3 @@ -.c-hours {width : 80px !important;} -.c-progress {width : 80px;} +.c-hours {width: 80px !important;} +.c-progress {width: 80px;} From 4f26dd32fe86cba79ca9573474e98ae6369a981f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E6=97=AD=E4=B8=9C?= Date: Wed, 9 Feb 2022 02:00:31 +0000 Subject: [PATCH 15/24] Update execution.css --- module/my/css/execution.css | 1 - 1 file changed, 1 deletion(-) diff --git a/module/my/css/execution.css b/module/my/css/execution.css index 7069de49bc..9807fedf2e 100644 --- a/module/my/css/execution.css +++ b/module/my/css/execution.css @@ -1,3 +1,2 @@ .c-hours {width: 80px !important;} .c-progress {width: 80px;} - From 0ce75c876f52f12e49d81371d696f65441893c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Wed, 9 Feb 2022 13:24:25 +0800 Subject: [PATCH 16/24] * Fix bug. --- module/kanban/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kanban/model.php b/module/kanban/model.php index 6b1e84a888..307d5740c7 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -93,7 +93,7 @@ class kanbanModel extends model $region->order = $order; $this->dao->insert(TABLE_KANBANREGION)->data($region) ->batchCheck($this->config->kanban->require->createregion, 'notempty') - ->check('name', 'unique', "kanban = {$kanban->id} AND deleted = '0' AND space = {$kanban->space}") + ->check('name', 'unique', "kanban = {$kanban->id} AND deleted = '0'") ->autoCheck() ->exec(); From e04850e9469fbc1ca78b4a47982003991ba01ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Thu, 10 Feb 2022 08:36:47 +0800 Subject: [PATCH 17/24] * Code for jira. --- module/convert/config.php | 5 +- module/convert/control.php | 88 ++++++++++++++++++++- module/convert/lang/zh-cn.php | 54 +++++++++---- module/convert/model.php | 21 ++++- module/convert/view/mapjira2zentao.html.php | 54 +++++++++++-- 5 files changed, 191 insertions(+), 31 deletions(-) diff --git a/module/convert/config.php b/module/convert/config.php index de99977d0a..8b58f272dc 100644 --- a/module/convert/config.php +++ b/module/convert/config.php @@ -1,7 +1,8 @@ app->loadLang('story'); + $this->app->loadLang('bug'); + $this->app->loadLang('task'); + if($_POST) { - a($_POST);die; + $this->session->set('linkType', $_POST); + + $response['result'] = 'success'; + $response['message'] = $this->lang->saveSuccess; + $response['locate'] = $this->createLink('convert', 'initJiraUser', "type=$type"); + return print($this->send($response)); } if($type == 'db') { - $this->convert->connectDB($dbName); - $issueTypePairs = $this->convert->getIssueTypePairs(); - $linkTypePairs = $this->convert->getLinkTypePairs(); + $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(); } $this->view->title = $this->lang->convert->jira->mapJira2Zentao; $this->view->issueTypePairs = $issueTypePairs; $this->view->linkTypePairs = $linkTypePairs; + $this->view->resolutions = $resolutions; + $this->view->statusList = $statusList; + $this->display(); + } + + public function initJiraUser($type = 'db') + { + $this->app->loadLang('user'); + + if($_POST) + { + if(!$this->post->password1 || !$this->post->password2) + { + $response['result'] = 'fail'; + $response['message'] = $this->lang->convert->jira->passwordEmpty; + return print($this->send($response)); + } + + if($this->post->password1 != $this->post->password2) + { + $response['result'] = 'fail'; + $response['message'] = $this->lang->convert->jira->passwordDifferent; + return print($this->send($response)); + } + + $jiraUser['password'] = md5($this->post->password1); + $jiraUser['group'] = $this->post->group; + $this->session->set('jiraUser', $jiraUser); + + $response['result'] = 'success'; + $response['message'] = $this->lang->saveSuccess; + $response['locate'] = $this->createLink('convert', 'importJira', "type=$type"); + return print($this->send($response)); + } + + $this->view->title = $this->lang->convert->jira->initJiraUser; + $this->view->groups = $this->loadModel('group')->getPairs(); + $this->display(); + } + + public function importJira($method = 'db', $type = 'user', $lastID = 0) + { + set_time_limit(0); + + if($method = 'db') + { + if(helper::isAjaxRequest()) + { + $result = $this->convert->importJiraFromDB($type, $lastID); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + if(isset($result['finished']) and $result['finished']) + { + return $this->send(array('result' => 'finished', 'message' => $this->lang->convert->jira->importSuccessfully)); + } + else + { + $type = zget($this->lang->convert->jira->objectList, $result['type'], $result['type']); + return $this->send(array('result' => 'unfinished', 'message' => sprintf($this->lang->convert->jira->importResult, $type, $type, $result['count']), 'type' => $type, 'count' => $result['count'], 'next' => inlink('importJira', "type={$result['type']}&lastID={$result['lastID']}") )); + } + } + } + else + { + //$this->convert->importJiraFromFile(); + } + + $this->view->type = $type; + $this->view->title = $this->lang->convert->jira->importJira; $this->display(); } } diff --git a/module/convert/lang/zh-cn.php b/module/convert/lang/zh-cn.php index f586548793..3822cc01ba 100644 --- a/module/convert/lang/zh-cn.php +++ b/module/convert/lang/zh-cn.php @@ -116,22 +116,39 @@ $lang->convert->issue->zentao = '禅道'; $lang->convert->issue->goto = '转换为'; $lang->convert->jira = new stdclass(); -$lang->convert->jira->method = '选择导入方式'; -$lang->convert->jira->next = '下一步'; -$lang->convert->jira->importFromDB = '从数据库导入'; -$lang->convert->jira->importFromFile = '从文件导入'; -$lang->convert->jira->mapJira2Zentao = '设置对应关系'; -$lang->convert->jira->dbNameNotice = '请输入Jira数据库名字'; -$lang->convert->jira->importNotice = '注意:导入数据有风险!请务必确保如下操作步骤依次完成,再进行合并。'; -$lang->convert->jira->dbDesc = '

    如果您的Jira使用Mysql数据库, 请选择此方式

    '; -$lang->convert->jira->fileDesc = '

    如果您的Jira使用非Mysql数据库, 请选择此方式

    '; -$lang->convert->jira->jiraObject = 'Jira Issues'; -$lang->convert->jira->zentaoObject = '禅道对象'; -$lang->convert->jira->jiraLinkType = 'Jira 关联关系'; -$lang->convert->jira->zentaoLinkType = '禅道关联关系'; +$lang->convert->jira->method = '选择导入方式'; +$lang->convert->jira->next = '下一步'; +$lang->convert->jira->importFromDB = '从数据库导入'; +$lang->convert->jira->importFromFile = '从文件导入'; +$lang->convert->jira->mapJira2Zentao = '设置对应关系'; +$lang->convert->jira->dbNameNotice = '请输入Jira数据库名字'; +$lang->convert->jira->importNotice = '注意:导入数据有风险!请务必确保如下操作步骤依次完成,再进行合并。'; +$lang->convert->jira->dbDesc = '

    如果您的Jira使用Mysql数据库, 请选择此方式

    '; +$lang->convert->jira->fileDesc = '

    如果您的Jira使用非Mysql数据库, 请选择此方式

    '; +$lang->convert->jira->jiraObject = 'Jira Issues'; +$lang->convert->jira->zentaoObject = '禅道对象'; +$lang->convert->jira->jiraLinkType = 'Jira 关联关系'; +$lang->convert->jira->zentaoLinkType = '禅道关联关系'; +$lang->convert->jira->jiraResolution = 'Jira 解决方案'; +$lang->convert->jira->zentaoResolution = '禅道Bug解决方案'; +$lang->convert->jira->zentaoReason = '禅道需求关闭原因'; +$lang->convert->jira->jiraStatus = 'Jira Issues 状态'; +$lang->convert->jira->storyStatus = '禅道需求状态'; +$lang->convert->jira->storyStage = '禅道需求阶段'; +$lang->convert->jira->bugStatus = '禅道Bug状态'; +$lang->convert->jira->taskStatus = '禅道任务状态'; +$lang->convert->jira->initJiraUser = '设置Jira用户'; +$lang->convert->jira->importJira = '导入Jira'; +$lang->convert->jira->start = '开始导入'; -$lang->convert->jira->dbNameEmpty = 'Jira数据库名字不能为空!'; -$lang->convert->jira->invalidDB = '无效的数据库名!'; +$lang->convert->jira->dbNameEmpty = 'Jira数据库名字不能为空!'; +$lang->convert->jira->invalidDB = '无效的数据库名!'; +$lang->convert->jira->passwordNotice = "设置Jira用户导入到禅道后的默认密码,用户后续可以在禅道中自行修改密码。"; +$lang->convert->jira->groupNotice = "设置Jira用户导入到禅道后的默认权限分组。"; +$lang->convert->jira->passwordDifferent = '两次密码不一致!'; +$lang->convert->jira->passwordEmpty = '密码不能为空!'; +$lang->convert->jira->importSuccessfully = 'Jira导入完成!'; +$lang->convert->jira->importResult = "导入 %s 数据, 已导入 %s 条记录;"; $lang->convert->jira->zentaoObjectList['task'] = '任务'; $lang->convert->jira->zentaoObjectList['requirement'] = '用户需求'; @@ -150,3 +167,10 @@ $lang->convert->jira->importSteps['db'][4] = "上述步骤完成后,请输 $lang->convert->jira->importSteps['file'][1] = '备份禅道数据库,备份Jira数据库。'; $lang->convert->jira->importSteps['file'][2] = '将Jira数据库导入到禅道使用的Mysql中,名字和禅道数据库区别开来。'; $lang->convert->jira->importSteps['file'][3] = "将Jira附件目录放到 %s 下。"; + +$lang->convert->jira->objectList['user'] = '用户'; +$lang->convert->jira->objectList['project'] = '项目'; +$lang->convert->jira->objectList['issue'] = 'Issue'; +$lang->convert->jira->objectList['build'] = '版本'; +//$lang->convert->jira->objectList['relates'] = '关联关系'; +$lang->convert->jira->objectList['file'] = '附件'; diff --git a/module/convert/model.php b/module/convert/model.php index 6776fad133..127d385957 100644 --- a/module/convert/model.php +++ b/module/convert/model.php @@ -94,13 +94,26 @@ class convertModel extends model $this->session->set('state', $state); } - public function getIssueTypePairs() + public function importJiraFromDB($type = '', $lastID = 0) { - return $this->dao->dbh($this->sourceDBH)->select('ID,pname')->from(JIRA_ISSUETYPE)->fetchPairs(); + $limit = 1000; + $nextObject = false; + if(empty($type)) $type = key($this->lang->convert->jira->objectList); + + foreach($this->lang->convert->jira->objectList as $module => $moduleName) + { + if($module != $type and !$nextObject) continue; + if($module == $type) $nextObject = true; + + while(true) + { + $query = $this->buildQuery($module); + } + } } - public function getLinkTypePairs() + public function buildQuery($module) { - return $this->dao->dbh($this->sourceDBH)->select('ID,LINKNAME')->from(JIRA_ISSUELINKTYPE)->fetchPairs(); + if($module == 'user') } } diff --git a/module/convert/view/mapjira2zentao.html.php b/module/convert/view/mapjira2zentao.html.php index 56dc25bbb1..7156708bdc 100644 --- a/module/convert/view/mapjira2zentao.html.php +++ b/module/convert/view/mapjira2zentao.html.php @@ -16,7 +16,7 @@ convert->jira->mapJira2Zentao;?> -
    + @@ -27,8 +27,8 @@ $name):?> - - + + @@ -44,14 +44,56 @@ $name):?> - - + + + + + +
    convert->jira->zentaoObjectList, '', "class='form-control chosen'");?>convert->jira->zentaoObjectList, '', "class='form-control chosen'");?>
    convert->jira->zentaoLinkTypeList, '', "class='form-control chosen'");?>convert->jira->zentaoLinkTypeList, '', "class='form-control chosen'");?>
    +
    + + + + + + + + + + $name):?> + + + + + + + +
    convert->jira->jiraResolution;?>convert->jira->zentaoResolution;?>convert->jira->zentaoReason;?>
    bug->resolutionList, '', "class='form-control chosen'");?>story->reasonList, '', "class='form-control chosen'");?>
    +
    + + + + + + + + + + + + $name):?> + + + + + + - +
    convert->jira->jiraStatus;?>convert->jira->storyStatus;?>convert->jira->storyStage;?>convert->jira->taskStatus;?>convert->jira->bugStatus;?>
    story->statusList, '', "class='form-control chosen'");?>story->stageList, '', "class='form-control chosen'");?>task->statusList, '', "class='form-control chosen'");?>bug->statusList, '', "class='form-control chosen'");?>
    convert->jira->next);?>
    From 1086d07bf4687e9f142fe58740dc64ea4e4bb2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Thu, 10 Feb 2022 08:37:03 +0800 Subject: [PATCH 18/24] * Code for jira. --- module/convert/view/importjira.html.php | 61 +++++++++++++++++++++++ module/convert/view/initjirauser.html.php | 50 +++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 module/convert/view/importjira.html.php create mode 100644 module/convert/view/initjirauser.html.php diff --git a/module/convert/view/importjira.html.php b/module/convert/view/importjira.html.php new file mode 100644 index 0000000000..7182862158 --- /dev/null +++ b/module/convert/view/importjira.html.php @@ -0,0 +1,61 @@ + + * @package article + * @version $Id$ + * @link http://www.chanzhi.org + */ +?> + +
    +
    +

    convert->jira->importJira;?>

    +
    +
    +
    +
      +
      +
      convert->jira->start, '', "class='btn btn-primary' id='execButton'");?>
      +
      +
      + + diff --git a/module/convert/view/initjirauser.html.php b/module/convert/view/initjirauser.html.php new file mode 100644 index 0000000000..98d42a81ad --- /dev/null +++ b/module/convert/view/initjirauser.html.php @@ -0,0 +1,50 @@ + + * @package user + * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +?> + +
      +
      +
      +

      convert->jira->initJiraUser;?>

      +
      + + + + + + + + + + + + + + + + + + + +
      user->password;?> + + + + + convert->jira->passwordNotice;?>
      user->password2;?>
      user->group;?>convert->jira->groupNotice;?>
      + convert->jira->next);?> +
      + +
      +
      + + From efe77ec0fd209547e839693f5f1c407322d94ad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Thu, 10 Feb 2022 11:03:57 +0800 Subject: [PATCH 19/24] * Add merge user. --- module/convert/config.php | 24 ++++++------ module/convert/control.php | 48 ++++++++++++++++++++++- module/convert/lang/zh-cn.php | 2 +- module/convert/model.php | 74 ++++++++++++++++++++++++++++++++++- 4 files changed, 131 insertions(+), 17 deletions(-) diff --git a/module/convert/config.php b/module/convert/config.php index 8b58f272dc..62daea9fcc 100644 --- a/module/convert/config.php +++ b/module/convert/config.php @@ -1,13 +1,13 @@ display(); } + /** + * Import jira index. + * + * @access public + * @return void + */ public function jira() { $this->view->title = $this->lang->convert->jira->method; $this->display(); } + /** + * Import jira notice. + * + * @param string $type db|file + * @access public + * @return void + */ public function importNotice($type = 'db') { if($_POST) @@ -273,6 +286,7 @@ class convert extends control 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}"); @@ -284,6 +298,14 @@ class convert extends control $this->display(); } + /** + * Map jira objects to zentao. + * + * @param string $type db|file + * @param string $dbName + * @access public + * @return void + */ public function mapJira2Zentao($type = 'db', $dbName = '') { $this->app->loadLang('story'); @@ -318,6 +340,13 @@ class convert extends control $this->display(); } + /** + * Init jira user. + * + * @param string $type db|file + * @access public + * @return void + */ public function initJiraUser($type = 'db') { $this->app->loadLang('user'); @@ -353,6 +382,15 @@ class convert extends control $this->display(); } + /** + * Import jira main logic. + * + * @param string $method db|file + * @param string $type user|issue|project|attachment + * @param int $lastID + * @access public + * @return void + */ public function importJira($method = 'db', $type = 'user', $lastID = 0) { set_time_limit(0); @@ -365,12 +403,18 @@ class convert extends control if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); if(isset($result['finished']) and $result['finished']) { - return $this->send(array('result' => 'finished', 'message' => $this->lang->convert->jira->importSuccessfully)); + 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 $this->send(array('result' => 'unfinished', 'message' => sprintf($this->lang->convert->jira->importResult, $type, $type, $result['count']), 'type' => $type, 'count' => $result['count'], 'next' => inlink('importJira', "type={$result['type']}&lastID={$result['lastID']}") )); + + $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); } } } diff --git a/module/convert/lang/zh-cn.php b/module/convert/lang/zh-cn.php index 3822cc01ba..2fbc83933d 100644 --- a/module/convert/lang/zh-cn.php +++ b/module/convert/lang/zh-cn.php @@ -148,7 +148,7 @@ $lang->convert->jira->groupNotice = "设置Jira用 $lang->convert->jira->passwordDifferent = '两次密码不一致!'; $lang->convert->jira->passwordEmpty = '密码不能为空!'; $lang->convert->jira->importSuccessfully = 'Jira导入完成!'; -$lang->convert->jira->importResult = "导入 %s 数据, 已导入 %s 条记录;"; +$lang->convert->jira->importResult = "导入 %s 数据, 已导入 %s 条记录;"; $lang->convert->jira->zentaoObjectList['task'] = '任务'; $lang->convert->jira->zentaoObjectList['requirement'] = '用户需求'; diff --git a/module/convert/model.php b/module/convert/model.php index 127d385957..131657d521 100644 --- a/module/convert/model.php +++ b/module/convert/model.php @@ -94,8 +94,18 @@ class convertModel extends model $this->session->set('state', $state); } + /** + * Import jira from db. + * + * @param string $type + * @param int $lastID + * @access public + * @return void + */ public function importJiraFromDB($type = '', $lastID = 0) { + $this->connectDB($this->session->jiraDB); + $limit = 1000; $nextObject = false; if(empty($type)) $type = key($this->lang->convert->jira->objectList); @@ -107,13 +117,73 @@ class convertModel extends model while(true) { - $query = $this->buildQuery($module); + $dataList = $this->getJiraData($module, $lastID, $limit); + + if(empty($dataList)) + { + $lastID = 0; + break; + } + + if($module == 'user') $this->importJiraUser($dataList); + return array('type' => $module, 'count' => count($dataList), 'lastID' => max(array_keys($dataList))); } + + return array('finished' => true); } } - public function buildQuery($module) + /** + * Get jira data. + * + * @param int $module + * @access public + * @return void + */ + public function getJiraData($module = '', $lastID = 0, $limit = 0) { if($module == 'user') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('t1.`ID`, t1.`lower_user_name` as account, t1.`lower_display_name` as realname, t1.`lower_email_address` as email, t1.created_date as `join`, t2.user_key as userCode')->from(JIRA_USERINFO)->alias('t1') + ->leftJoin(JIRA_USER)->alias('t2')->on('t1.`lower_user_name` = t2.`lower_user_name`') + ->where('t1.active')->eq(1) + ->beginIF($lastID)->andWhere('t1.ID')->gt($lastID)->fi() + ->orderBy('t1.ID asc')->limit($limit) + ->fetchAll('ID'); + } + + return $dataList; + } + + public function importJiraUser($dataList) + { + $localUsers = $this->dao->dbh($this->dbh)->select('account')->from(TABLE_USER)->where('deleted')->eq('0')->fetchPairs(); + $userConfig = $this->session->jiraUser; + + foreach($dataList as $id => $data) + { + if(isset($localUsers[$data->account])) continue; + + $user = new stdclass(); + $user->account = $data->account; + $user->realname = $data->realname; + $user->password = $userConfig['password']; + $user->group = $userConfig['group']; + $user->email = $data->email; + $user->gender = 'f'; + $user->type = 'inside'; + $user->join = $data->join; + + $this->dao->dbh($this->dbh)->insert(TABLE_USER)->data($user, 'group')->exec(); + + if(!dao::isError()) + { + $data = new stdclass(); + $data->account = $user->account; + $data->group = $user->group; + + $this->dao->dbh($this->dbh)->replace(TABLE_USERGROUP)->set('account')->eq($user->account)->set('`group`')->eq($user->group)->exec(); + } + } } } From 63bd6e0c4606b7142d3b0e5242be43f710b32247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Thu, 10 Feb 2022 11:56:50 +0800 Subject: [PATCH 20/24] * Code for jira. --- module/convert/model.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/module/convert/model.php b/module/convert/model.php index 131657d521..3c5bcc52f1 100644 --- a/module/convert/model.php +++ b/module/convert/model.php @@ -125,7 +125,9 @@ class convertModel extends model break; } - if($module == 'user') $this->importJiraUser($dataList); + if($module == 'user') $this->importJiraUser($dataList); + if($module == 'project') $this->importJiraProject($dataList); + return array('type' => $module, 'count' => count($dataList), 'lastID' => max(array_keys($dataList))); } @@ -151,6 +153,13 @@ class convertModel extends model ->orderBy('t1.ID asc')->limit($limit) ->fetchAll('ID'); } + elesif($module == 'project') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from('project') + ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() + ->orderBy('ID asc')->limit($limit) + ->fetchAll('ID'); + } return $dataList; } @@ -186,4 +195,8 @@ class convertModel extends model } } } + + public function importJiraProject($dataList) + { + } } From dc7ced4c876955ecd4adc21b982881d44bcdac71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Thu, 10 Feb 2022 17:30:47 +0800 Subject: [PATCH 21/24] * Code for jira. --- module/convert/config.php | 1 + module/convert/control.php | 11 +- module/convert/model.php | 415 +++++++++++++++++++++++- module/convert/view/importjira.html.php | 2 +- 4 files changed, 417 insertions(+), 12 deletions(-) diff --git a/module/convert/config.php b/module/convert/config.php index 62daea9fcc..9c5aff8f35 100644 --- a/module/convert/config.php +++ b/module/convert/config.php @@ -11,3 +11,4 @@ define('JIRA_RESOLUTION', '`resolution`'); define('JIRA_PROJECTVERSION', '`projectversion`'); define('JIRA_NODEASSOCIATION', '`nodeassociation`'); define('JIRA_FILEATTACHMENT', '`fileattachment`'); +define('JIRA_TMPRELATION', '`jiratmprelation`'); diff --git a/module/convert/control.php b/module/convert/control.php index 837ec388f6..cdf3fd6792 100644 --- a/module/convert/control.php +++ b/module/convert/control.php @@ -314,7 +314,7 @@ class convert extends control if($_POST) { - $this->session->set('linkType', $_POST); + $this->session->set('jiraRelation', $_POST); $response['result'] = 'success'; $response['message'] = $this->lang->saveSuccess; @@ -391,7 +391,7 @@ class convert extends control * @access public * @return void */ - public function importJira($method = 'db', $type = 'user', $lastID = 0) + public function importJira($method = 'db', $type = 'user', $lastID = 0, $createTable = false) { set_time_limit(0); @@ -399,7 +399,7 @@ class convert extends control { if(helper::isAjaxRequest()) { - $result = $this->convert->importJiraFromDB($type, $lastID); + $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']) { @@ -423,8 +423,9 @@ class convert extends control //$this->convert->importJiraFromFile(); } - $this->view->type = $type; - $this->view->title = $this->lang->convert->jira->importJira; + $this->view->type = $type; + $this->view->method = $method; + $this->view->title = $this->lang->convert->jira->importJira; $this->display(); } } diff --git a/module/convert/model.php b/module/convert/model.php index 3c5bcc52f1..1621664b24 100644 --- a/module/convert/model.php +++ b/module/convert/model.php @@ -102,8 +102,10 @@ class convertModel extends model * @access public * @return void */ - public function importJiraFromDB($type = '', $lastID = 0) + public function importJiraFromDB($type = '', $lastID = 0, $createTable = false) { + if($createTable) $this->createTmpTable4Jira(); + $this->connectDB($this->session->jiraDB); $limit = 1000; @@ -127,12 +129,14 @@ class convertModel extends model if($module == 'user') $this->importJiraUser($dataList); if($module == 'project') $this->importJiraProject($dataList); + if($module == 'issue') $this->importJiraIssue($dataList); return array('type' => $module, 'count' => count($dataList), 'lastID' => max(array_keys($dataList))); } - - return array('finished' => true); } + + $this->dbh->exec("DROP TABLE" . JIRA_TMPRELATION); + return array('finished' => true); } /** @@ -144,18 +148,28 @@ class convertModel extends model */ public function getJiraData($module = '', $lastID = 0, $limit = 0) { + $dataList = array(); if($module == 'user') { $dataList = $this->dao->dbh($this->sourceDBH)->select('t1.`ID`, t1.`lower_user_name` as account, t1.`lower_display_name` as realname, t1.`lower_email_address` as email, t1.created_date as `join`, t2.user_key as userCode')->from(JIRA_USERINFO)->alias('t1') ->leftJoin(JIRA_USER)->alias('t2')->on('t1.`lower_user_name` = t2.`lower_user_name`') - ->where('t1.active')->eq(1) + ->where(1) ->beginIF($lastID)->andWhere('t1.ID')->gt($lastID)->fi() ->orderBy('t1.ID asc')->limit($limit) ->fetchAll('ID'); } - elesif($module == 'project') + elseif($module == 'project') { - $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from('project') + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_PROJECT) + ->where(1) + ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() + ->orderBy('ID asc')->limit($limit) + ->fetchAll('ID'); + } + elseif($module == 'issue') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_ISSUE) + ->where(1) ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() ->orderBy('ID asc')->limit($limit) ->fetchAll('ID'); @@ -198,5 +212,394 @@ class convertModel extends model public function importJiraProject($dataList) { + global $app; + $app->loadConfig('execution'); + $app->loadLang('doc'); + $now = helper::now(); + + foreach($dataList as $id => $data) + { + $projectRelation = array(); + $executionRelation = array(); + $productRelation = array(); + + /* Create project. */ + $project = new stdclass(); + $project->name = $data->pname; + $project->code = $data->pkey; + $project->desc = $data->DESCRIPTION; + $project->status = 'wait'; + $project->type = 'project'; + $project->model = 'scrum'; + $project->grade = 1; + $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->openedDate = $now; + $project->openedVersion = $this->config->version; + $this->dao->dbh($this->dbh)->insert(TABLE_PROJECT)->data($project)->exec(); + + $projectID = $this->dao->dbh($this->dbh)->lastInsertID(); + $this->dao->dbh($this->dbh)->update(TABLE_PROJECT)->set('`order`')->eq($projectID * 5)->set('path')->eq(",$projectID,")->where('id')->eq($projectID)->exec(); + + $member = new stdclass(); + $member->root = $projectID; + $member->account = $project->openedBy; + $member->role = ''; + $member->join = ''; + $member->type = 'project'; + $member->days = 0; + $member->hours = $this->config->execution->defaultWorkhours; + $this->dao->dbh($this->dbh)->insert(TABLE_TEAM)->data($member)->exec(); + + /* Create doc lib. */ + $lib = new stdclass(); + $lib->project = $projectID; + $lib->name = $this->lang->doclib->main['project']; + $lib->type = 'project'; + $lib->main = '1'; + $lib->acl = 'default'; + $this->dao->dbh($this->dbh)->insert(TABLE_DOCLIB)->data($lib)->exec(); + + /* Create execution. */ + $execution = new stdclass(); + $execution->name = $data->pname; + $execution->code = $data->pkey; + $execution->desc = $data->DESCRIPTION; + $execution->status = 'wait'; + $execution->project = $projectID; + $execution->parent = $projectID; + $execution->grade = 1; + $execution->type = 'sprint'; + $execution->acl = 'open'; + $execution->end = date('Y-m-d', time() + 24 * 3600); + + $execution->PM = $project->PM; + $execution->openedBy = $project->openedBy; + $execution->openedDate = $now; + $execution->openedVersion = $this->config->version; + $this->dao->dbh($this->dbh)->insert(TABLE_PROJECT)->data($execution)->exec(); + + $executionID = $this->dao->dbh($this->dbh)->lastInsertID(); + $this->dao->dbh($this->dbh)->update(TABLE_PROJECT)->set('`order`')->eq($executionID * 5)->set('path')->eq(",$projectID,$executionID,")->where('id')->eq($executionID)->exec(); + + $member = new stdclass(); + $member->root = $executionID; + $member->account = $execution->openedBy; + $member->role = ''; + $member->join = ''; + $member->type = 'execution'; + $member->days = 0; + $member->hours = $this->config->execution->defaultWorkhours; + $this->dao->dbh($this->dbh)->insert(TABLE_TEAM)->data($member)->exec(); + + /* Create doc lib. */ + $lib = new stdclass(); + $lib->project = $projectID; + $lib->execution = $executionID; + $lib->name = $this->lang->doclib->main['project']; + $lib->type = 'execution'; + $lib->main = '1'; + $lib->acl = 'default'; + $this->dao->dbh($this->dbh)->insert(TABLE_DOCLIB)->data($lib)->exec(); + + /* Create product. */ + $product = new stdclass(); + $product->name = $project->name; + $product->code = $project->code; + $product->type = 'normal'; + $product->status = 'normal'; + $product->acl = 'open'; + + $product->createdBy = $project->openedBy; + $product->createdDate = helper::now(); + $product->createdVersion = $this->config->version; + $this->dao->dbh($this->dbh)->insert(TABLE_PRODUCT)->data($product)->exec(); + + $productID = $this->dao->dbh($this->dbh)->lastInsertID(); + + /* Create doc lib. */ + $lib = new stdclass(); + $lib->product = $productID; + $lib->name = $this->lang->doclib->main['product']; + $lib->type = 'product'; + $lib->main = '1'; + $lib->acl = 'default'; + $this->dao->dbh($this->dbh)->insert(TABLE_DOCLIB)->data($lib)->exec(); + + $this->dao->dbh($this->dbh)->update(TABLE_PRODUCT)->set('`order`')->eq($productID * 5)->where('id')->eq($productID)->exec(); + $this->dao->dbh($this->dbh)->replace(TABLE_PROJECTPRODUCT)->set('project')->eq($projectID)->set('product')->eq($productID)->exec(); + $this->dao->dbh($this->dbh)->replace(TABLE_PROJECTPRODUCT)->set('project')->eq($executionID)->set('product')->eq($productID)->exec(); + + $projectRelation['AType'] = 'jproject'; + $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(); + } + } + + public function importJiraIssue($dataList) + { + $relations = $this->session->jiraRelation; + + $this->app->loadLang('story'); + $this->app->loadLang('task'); + $this->app->loadLang('bug'); + + $projectRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jproject') + ->andWhere('BType')->eq('zproject') + ->fetchPairs(); + + $projectProduct = $this->dao->dbh($this->dbh)->select('project,product')->from(TABLE_PROJECTPRODUCT) + ->where('project')->in(array_values($projectRelation)) + ->fetchPairs(); + + $projectExecution = $this->dao->dbh($this->dbh)->select('project,id')->from(TABLE_PROJECT) + ->where('project')->in(array_values($projectRelation)) + ->fetchPairs(); + + $issueTypeList = array(); + foreach($relations['jiraObject'] as $id => $jiraCode) + { + $issueTypeList[$jiraCode] = $relations['zentaoObject'][$id]; + } + + $reasonList = array(); + $resolutionList = array(); + foreach($relations['jiraResolution'] as $id => $jiraCode) + { + if(!empty($relations['zentaoReason'][$id])) $reasonList[$jiraCode] = $relations['zentaoReason'][$id]; + 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'); + + $issueObjectType = array(); + foreach($dataList as $id => $data) + { + $issueType = isset($issueTypeList[$data->issuetype]) ? $issueTypeList[$data->issuetype] : 'task'; + $issueID = $data->ID; + $issueProject = $data->PROJECT; + + if(!isset($projectRelation[$issueProject])) continue; + + $projectID = $projectRelation[$issueProject]; + $productID = $projectProduct[$projectID]; + $executionID = $projectExecution[$projectID]; + + if($issueType == 'requirement' or $issueType == 'story') + { + $story = new stdclass(); + $story->product = $productID; + $story->title = $data->SUMMARY; + $story->type = $issueType; + $story->pri = $data->PRIORITY; + $story->version = 1; + $story->stage = $this->convertStage($data->issuestatus); + $story->status = $this->convertStatus('story', $data->issuestatus); + $story->openedBy = $this->getJiraAccount($data->CREATOR); + $story->openedDate = substr($data->CREATED, 0, 19); + $story->assignedTo = $this->getJiraAccount($data->ASSIGNEE); + + if($data->RESOLUTION) + { + $story->closedReason = zget($reasonList, $data->RESOLUTION, ''); + if($story->closedReason and !isset($this->lang->story->reasonList[$story->closedReason])) $story->closedReason = 'done'; + } + + $this->dao->dbh($this->dbh)->insert(TABLE_STORY)->data($story)->exec(); + + if(!dao::isError()) + { + $storyID = $this->dao->dbh($this->dbh)->lastInsertID(); + + $storyDesc = new stdclass(); + $storyDesc->story = $storyID; + $storyDesc->version = 1; + $storyDesc->title = $story->title; + $storyDesc->spec = $data->DESCRIPTION; + $this->dao->dbh($this->dbh)->replace(TABLE_STORYSPEC)->data($storyDesc)->exec(); + $this->dao->dbh($this->dbh)->replace(TABLE_PROJECTSTORY)->set('project')->eq($projectID) + ->set('product')->eq($productID) + ->set('story')->eq($storyID) + ->set('version')->eq('1') + ->exec(); + + $this->dao->dbh($this->dbh)->replace(TABLE_PROJECTSTORY)->set('project')->eq($executionID) + ->set('product')->eq($productID) + ->set('story')->eq($storyID) + ->set('version')->eq('1') + ->exec(); + + $storyRelation['AType'] = 'jstory'; + $storyRelation['BType'] = 'zstory'; + $storyRelation['AID'] = $issueID; + $storyRelation['BID'] = $storyID; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($storyRelation)->exec(); + + $issueRelation['AType'] = 'jissueid'; + $issueRelation['BType'] = 'zissuetype'; + $issueRelation['AID'] = $issueID; + $issueRelation['extra'] = 'story'; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($issueRelation)->exec(); + } + } + elseif($issueType == 'task' or $issueType == 'subTask') + { + $task = new stdclass(); + $task->project = $projectID; + $task->execution = $executionID; + $task->name = $data->SUMMARY; + $task->type = 'devel'; + $task->pri = $data->PRIORITY; + $task->status = $this->convertStatus('task', $data->issuestatus); + $task->desc = $data->DESCRIPTION; + $task->openedBy = $this->getJiraAccount($data->CREATOR); + $task->openedDate = substr($data->CREATED, 0, 19); + $task->assignedTo = $this->getJiraAccount($data->ASSIGNEE); + if($data->RESOLUTION) + { + $task->closedReason = zget($reasonList, $data->RESOLUTION, ''); + if($task->closedReason and !isset($this->lang->task->reasonList[$task->closedReason])) $task->closedReason = 'cancel'; + } + + $this->dao->dbh($this->dbh)->insert(TABLE_TASK)->data($task)->exec(); + $taskID = $this->dao->dbh($this->dbh)->lastInsertID(); + + $taskRelation['AType'] = 'jtask'; + $taskRelation['BType'] = 'ztask'; + $taskRelation['AID'] = $issueID; + $taskRelation['BID'] = $taskID; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($taskRelation)->exec(); + + $issueRelation['AType'] = 'jissueid'; + $issueRelation['BType'] = 'zissuetype'; + $issueRelation['AID'] = $issueID; + $issueRelation['extra'] = 'task'; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($issueRelation)->exec(); + } + elseif($issueType == 'bug') + { + $bug = new stdclass(); + $bug->product = $productID; + $bug->project = $projectID; + $bug->title = $data->SUMMARY; + $bug->pri = $data->PRIORITY; + $bug->status = $this->convertStatus('bug', $data->issuestatus); + $bug->steps = $data->DESCRIPTION; + $bug->openedBy = $this->getJiraAccount($data->CREATOR); + $bug->openedDate = substr($data->CREATED, 0, 19); + $bug->openedBuild = 'trunk'; + $bug->assignedTo = $this->getJiraAccount($data->ASSIGNEE); + + if($data->RESOLUTION) + { + $bug->resolution = zget($resolutionList, $data->RESOLUTION, ''); + if($bug->resolution and !isset($this->lang->bug->resolutionList[$bug->resolution])) $bug->resolution = 'fixed'; + } + + $this->dao->dbh($this->dbh)->insert(TABLE_BUG)->data($bug)->exec(); + $bugID = $this->dao->dbh($this->dbh)->lastInsertID(); + + $bugRelation['AType'] = 'jbug'; + $bugRelation['BType'] = 'zbug'; + $bugRelation['AID'] = $issueID; + $bugRelation['BID'] = $bugID; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($bugRelation)->exec(); + + $issueRelation['AType'] = 'jissueid'; + $issueRelation['BType'] = 'zissuetype'; + $issueRelation['AID'] = $issueID; + $issueRelation['extra'] = 'bug'; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($issueRelation)->exec(); + } + + $oldKey = zget($projectKeys[$issueProject], 'oldKey', ''); + $newKey = zget($projectKeys[$issueProject], 'newKey', ''); + $issueKey = $oldKey ? $oldKey . '-' . $data->issuenum : $newKey . '-' . $data->issuenum; + + $fileRelation['AType'] = 'jissueid'; + $fileRelation['BType'] = 'jfilepath'; + $fileRelation['AID'] = $issueID; + $fileRelation['extra'] = "{$oldKey}/10000/{$issueKey}/"; + + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($fileRelation)->exec(); + } + } + + public function convertStatus($objectType, $jiraStatus) + { + $relations = $this->session->jiraRelation; + + $status = 'active'; + if($objectType == 'task') $status = 'wait'; + + $arrayKey = "{$objectType}Status"; + foreach($relations['jiraStatus'] as $id => $jiraCode) + { + if($jiraCode == $jiraStatus) + { + if(!empty($relations[$arrayKey][$id])) $status = $relations[$arrayKey][$id]; + } + } + + return $status; + } + + public function convertStage($jiraStatus) + { + $stage = 'wait'; + $relations = $this->session->jiraRelation; + + foreach($relations['jiraStatus'] as $id => $jiraCode) + { + if($jiraCode == $jiraStatus) + { + if(!empty($relations['storyStage'][$id])) $stage = $relations['storyStage'][$id]; + } + } + + return $stage; + } + + public function getJiraAccount($userKey) + { + 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'); + } + + public function createTmpTable4Jira() + { +$sql = <<dbh->exec($sql); + } + catch(Exception $e){} } } diff --git a/module/convert/view/importjira.html.php b/module/convert/view/importjira.html.php index 7182862158..e764849fd9 100644 --- a/module/convert/view/importjira.html.php +++ b/module/convert/view/importjira.html.php @@ -19,7 +19,7 @@
        -
        convert->jira->start, '', "class='btn btn-primary' id='execButton'");?>
        +
        convert->jira->start, '', "class='btn btn-primary' id='execButton'");?>
        From 47f0ca28d5f0fa0cf6dfbf5aebff828f84b2c774 Mon Sep 17 00:00:00 2001 From: sgm0422 <976204163@qq.com> Date: Thu, 10 Feb 2022 21:25:41 +0800 Subject: [PATCH 22/24] * Code for jira. --- module/common/lang/menu.php | 14 +-- module/convert/config.php | 2 +- module/convert/control.php | 2 +- module/convert/model.php | 118 +++++++++--------- .../{jira.html.php => convertjira.html.php} | 0 5 files changed, 71 insertions(+), 65 deletions(-) rename module/convert/view/{jira.html.php => convertjira.html.php} (100%) diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php index 04ab7a34d0..755a609abf 100644 --- a/module/common/lang/menu.php +++ b/module/common/lang/menu.php @@ -534,13 +534,13 @@ $lang->admin->menu->dev['menuOrder'][10] = 'db'; $lang->admin->menu->dev['menuOrder'][15] = 'editor'; $lang->admin->menu->dev['menuOrder'][20] = 'entry'; -$lang->admin->menu->system['subMenu'] = new stdclass(); -$lang->admin->menu->system['subMenu']->data = array('link' => "{$lang->admin->data}|backup|index", 'subModule' => 'action'); -$lang->admin->menu->system['subMenu']->safe = array('link' => "$lang->security|admin|safe", 'alias' => 'checkweak'); -$lang->admin->menu->system['subMenu']->cron = array('link' => "{$lang->admin->cron}|cron|index", 'subModule' => 'cron'); -$lang->admin->menu->system['subMenu']->timezone = array('link' => "$lang->timezone|custom|timezone"); -$lang->admin->menu->system['subMenu']->buildIndex = array('link' => "{$lang->admin->buildIndex}|search|buildindex|"); -$lang->admin->menu->system['subMenu']->jira = array('link' => "{$lang->convert->importJira}|convert|jira|", 'subModule' => 'convert'); +$lang->admin->menu->system['subMenu'] = new stdclass(); +$lang->admin->menu->system['subMenu']->data = array('link' => "{$lang->admin->data}|backup|index", 'subModule' => 'action'); +$lang->admin->menu->system['subMenu']->safe = array('link' => "$lang->security|admin|safe", 'alias' => 'checkweak'); +$lang->admin->menu->system['subMenu']->cron = array('link' => "{$lang->admin->cron}|cron|index", 'subModule' => 'cron'); +$lang->admin->menu->system['subMenu']->timezone = array('link' => "$lang->timezone|custom|timezone"); +$lang->admin->menu->system['subMenu']->buildIndex = array('link' => "{$lang->admin->buildIndex}|search|buildindex|"); +$lang->admin->menu->system['subMenu']->convertJira = array('link' => "{$lang->convert->importJira}|convert|convertjira|", 'subModule' => 'convert'); $lang->admin->dividerMenu = ',company,message,system,'; diff --git a/module/convert/config.php b/module/convert/config.php index 9c5aff8f35..cf47ac451f 100644 --- a/module/convert/config.php +++ b/module/convert/config.php @@ -8,7 +8,7 @@ define('JIRA_ISSUELINK', '`issuelink`'); define('JIRA_ISSUELINKTYPE', '`issuelinktype`'); define('JIRA_ISSUESTATUS', '`issuestatus`'); define('JIRA_RESOLUTION', '`resolution`'); -define('JIRA_PROJECTVERSION', '`projectversion`'); +define('JIRA_BUILD', '`projectversion`'); define('JIRA_NODEASSOCIATION', '`nodeassociation`'); define('JIRA_FILEATTACHMENT', '`fileattachment`'); define('JIRA_TMPRELATION', '`jiratmprelation`'); diff --git a/module/convert/control.php b/module/convert/control.php index cdf3fd6792..0db409d0fa 100644 --- a/module/convert/control.php +++ b/module/convert/control.php @@ -254,7 +254,7 @@ class convert extends control * @access public * @return void */ - public function jira() + public function convertJira() { $this->view->title = $this->lang->convert->jira->method; $this->display(); diff --git a/module/convert/model.php b/module/convert/model.php index 1621664b24..9c70dc054a 100644 --- a/module/convert/model.php +++ b/module/convert/model.php @@ -94,6 +94,53 @@ class convertModel extends model $this->session->set('state', $state); } + /** + * Get jira data. + * + * @param int $module + * @access public + * @return void + */ + public function getJiraData($module = '', $lastID = 0, $limit = 0) + { + $dataList = array(); + if($module == 'user') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('t1.`ID`, t1.`lower_user_name` as account, t1.`lower_display_name` as realname, t1.`lower_email_address` as email, t1.created_date as `join`, t2.user_key as userCode')->from(JIRA_USERINFO)->alias('t1') + ->leftJoin(JIRA_USER)->alias('t2')->on('t1.`lower_user_name` = t2.`lower_user_name`') + ->where(1) + ->beginIF($lastID)->andWhere('t1.ID')->gt($lastID)->fi() + ->orderBy('t1.ID asc')->limit($limit) + ->fetchAll('ID'); + } + elseif($module == 'project') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_PROJECT) + ->where(1) + ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() + ->orderBy('ID asc')->limit($limit) + ->fetchAll('ID'); + } + elseif($module == 'issue') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_ISSUE) + ->where(1) + ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() + ->orderBy('ID asc')->limit($limit) + ->fetchAll('ID'); + } + elseif($module == 'build') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_BUILD) + ->where(1) + ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() + ->orderBy('ID asc')->limit($limit) + ->fetchAll('ID'); + } + + return $dataList; + } + /** * Import jira from db. * @@ -130,6 +177,7 @@ class convertModel extends model if($module == 'user') $this->importJiraUser($dataList); if($module == 'project') $this->importJiraProject($dataList); if($module == 'issue') $this->importJiraIssue($dataList); + if($module == 'build') $this->importJiraBuild($dataList); return array('type' => $module, 'count' => count($dataList), 'lastID' => max(array_keys($dataList))); } @@ -139,45 +187,6 @@ class convertModel extends model return array('finished' => true); } - /** - * Get jira data. - * - * @param int $module - * @access public - * @return void - */ - public function getJiraData($module = '', $lastID = 0, $limit = 0) - { - $dataList = array(); - if($module == 'user') - { - $dataList = $this->dao->dbh($this->sourceDBH)->select('t1.`ID`, t1.`lower_user_name` as account, t1.`lower_display_name` as realname, t1.`lower_email_address` as email, t1.created_date as `join`, t2.user_key as userCode')->from(JIRA_USERINFO)->alias('t1') - ->leftJoin(JIRA_USER)->alias('t2')->on('t1.`lower_user_name` = t2.`lower_user_name`') - ->where(1) - ->beginIF($lastID)->andWhere('t1.ID')->gt($lastID)->fi() - ->orderBy('t1.ID asc')->limit($limit) - ->fetchAll('ID'); - } - elseif($module == 'project') - { - $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_PROJECT) - ->where(1) - ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() - ->orderBy('ID asc')->limit($limit) - ->fetchAll('ID'); - } - elseif($module == 'issue') - { - $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_ISSUE) - ->where(1) - ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() - ->orderBy('ID asc')->limit($limit) - ->fetchAll('ID'); - } - - return $dataList; - } - public function importJiraUser($dataList) { $localUsers = $this->dao->dbh($this->dbh)->select('account')->from(TABLE_USER)->where('deleted')->eq('0')->fetchPairs(); @@ -539,21 +548,21 @@ class convertModel extends model } } + public function importJiraBuild($dataList) + { + } + public function convertStatus($objectType, $jiraStatus) { - $relations = $this->session->jiraRelation; - $status = 'active'; if($objectType == 'task') $status = 'wait'; + $relations = $this->session->jiraRelation; - $arrayKey = "{$objectType}Status"; - foreach($relations['jiraStatus'] as $id => $jiraCode) - { - if($jiraCode == $jiraStatus) - { - if(!empty($relations[$arrayKey][$id])) $status = $relations[$arrayKey][$id]; - } - } + $arrayKey = "{$objectType}Status"; + $jiraStatusList = array_flip($relations['jiraStatus']); + $statusID = $jiraStatusList[$jiraStatus]; + + if(!empty($relations[$arrayKey][$statusID])) $status = $relations[$arrayKey][$statusID]; return $status; } @@ -563,13 +572,10 @@ class convertModel extends model $stage = 'wait'; $relations = $this->session->jiraRelation; - foreach($relations['jiraStatus'] as $id => $jiraCode) - { - if($jiraCode == $jiraStatus) - { - if(!empty($relations['storyStage'][$id])) $stage = $relations['storyStage'][$id]; - } - } + $jiraStatusList = array_flip($relations['jiraStatus']); + $stageID = $jiraStatusList[$jiraStatus]; + + if(!empty($relations['storyStage'][$stageID])) $stage = $relations['storyStage'][$stageID]; return $stage; } diff --git a/module/convert/view/jira.html.php b/module/convert/view/convertjira.html.php similarity index 100% rename from module/convert/view/jira.html.php rename to module/convert/view/convertjira.html.php From 23411bf8a383e8a6b4df1a0c933e13a63623bbba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Fri, 11 Feb 2022 14:13:16 +0800 Subject: [PATCH 23/24] * Code for jira. --- module/convert/config.php | 3 +- module/convert/lang/zh-cn.php | 28 +- module/convert/model.php | 464 +++++++++++++++++++++- module/convert/view/importnotice.html.php | 11 +- 4 files changed, 482 insertions(+), 24 deletions(-) diff --git a/module/convert/config.php b/module/convert/config.php index cf47ac451f..ee299c8b0e 100644 --- a/module/convert/config.php +++ b/module/convert/config.php @@ -9,6 +9,7 @@ define('JIRA_ISSUELINKTYPE', '`issuelinktype`'); define('JIRA_ISSUESTATUS', '`issuestatus`'); define('JIRA_RESOLUTION', '`resolution`'); define('JIRA_BUILD', '`projectversion`'); +define('JIRA_ACTION', '`jiraaction`'); define('JIRA_NODEASSOCIATION', '`nodeassociation`'); -define('JIRA_FILEATTACHMENT', '`fileattachment`'); +define('JIRA_FILE', '`fileattachment`'); define('JIRA_TMPRELATION', '`jiratmprelation`'); diff --git a/module/convert/lang/zh-cn.php b/module/convert/lang/zh-cn.php index 2fbc83933d..d3146b2994 100644 --- a/module/convert/lang/zh-cn.php +++ b/module/convert/lang/zh-cn.php @@ -148,7 +148,7 @@ $lang->convert->jira->groupNotice = "设置Jira用 $lang->convert->jira->passwordDifferent = '两次密码不一致!'; $lang->convert->jira->passwordEmpty = '密码不能为空!'; $lang->convert->jira->importSuccessfully = 'Jira导入完成!'; -$lang->convert->jira->importResult = "导入 %s 数据, 已导入 %s 条记录;"; +$lang->convert->jira->importResult = "导入 %s 数据, 已处理 %s 条记录;"; $lang->convert->jira->zentaoObjectList['task'] = '任务'; $lang->convert->jira->zentaoObjectList['requirement'] = '用户需求'; @@ -161,16 +161,20 @@ $lang->convert->jira->zentaoLinkTypeList['duplicate'] = '重复对象'; $lang->convert->jira->zentaoLinkTypeList['relates'] = '互相关联'; $lang->convert->jira->importSteps['db'][1] = '备份禅道数据库,备份Jira数据库。'; -$lang->convert->jira->importSteps['db'][2] = '将Jira数据库导入到禅道使用的Mysql中,名字和禅道数据库区别开来。'; -$lang->convert->jira->importSteps['db'][3] = "将Jira附件目录 attachment 放到 %s 下,确保禅道服务器磁盘空间足够。"; -$lang->convert->jira->importSteps['db'][4] = "上述步骤完成后,请输入Jira数据库名字进行下一步。"; +$lang->convert->jira->importSteps['db'][2] = '导入数据时使用禅道会给服务器造成性能压力,请尽量保证导入数据时无人使用禅道。'; +$lang->convert->jira->importSteps['db'][3] = '将Jira数据库导入到禅道使用的Mysql中,名字和禅道数据库区别开来。'; +$lang->convert->jira->importSteps['db'][4] = "将Jira附件目录 attachments 放到 %s 下,确保禅道服务器磁盘空间足够。"; +$lang->convert->jira->importSteps['db'][5] = "上述步骤完成后,请输入Jira数据库名字进行下一步。"; $lang->convert->jira->importSteps['file'][1] = '备份禅道数据库,备份Jira数据库。'; -$lang->convert->jira->importSteps['file'][2] = '将Jira数据库导入到禅道使用的Mysql中,名字和禅道数据库区别开来。'; -$lang->convert->jira->importSteps['file'][3] = "将Jira附件目录放到 %s 下。"; +$lang->convert->jira->importSteps['file'][2] = '导入数据时使用禅道会给服务器造成性能压力,请尽量保证导入数据时无人使用禅道。'; +$lang->convert->jira->importSteps['file'][3] = "将Jira的备份文件 entities.xml 放到 %s 下。"; +$lang->convert->jira->importSteps['file'][4] = "将Jira附件目录 attachments 放到 %s 下,确保禅道服务器磁盘空间足够。"; +$lang->convert->jira->importSteps['file'][5] = "上述步骤完成后,点击下一步。"; -$lang->convert->jira->objectList['user'] = '用户'; -$lang->convert->jira->objectList['project'] = '项目'; -$lang->convert->jira->objectList['issue'] = 'Issue'; -$lang->convert->jira->objectList['build'] = '版本'; -//$lang->convert->jira->objectList['relates'] = '关联关系'; -$lang->convert->jira->objectList['file'] = '附件'; +$lang->convert->jira->objectList['user'] = '用户'; +$lang->convert->jira->objectList['project'] = '项目'; +$lang->convert->jira->objectList['issue'] = 'Issue'; +$lang->convert->jira->objectList['build'] = '版本'; +$lang->convert->jira->objectList['issuelink'] = '关联关系'; +$lang->convert->jira->objectList['action'] = '历史记录'; +$lang->convert->jira->objectList['file'] = '附件'; diff --git a/module/convert/model.php b/module/convert/model.php index 9c70dc054a..3a5f927de6 100644 --- a/module/convert/model.php +++ b/module/convert/model.php @@ -137,6 +137,30 @@ class convertModel extends model ->orderBy('ID asc')->limit($limit) ->fetchAll('ID'); } + elseif($module == 'issuelink') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_ISSUELINK) + ->where(1) + ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() + ->orderBy('ID asc')->limit($limit) + ->fetchAll('ID'); + } + elseif($module == 'action') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_ACTION) + ->where(1) + ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() + ->orderBy('ID asc')->limit($limit) + ->fetchAll('ID'); + } + elseif($module == 'file') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_FILE) + ->where(1) + ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() + ->orderBy('ID asc')->limit($limit) + ->fetchAll('ID'); + } return $dataList; } @@ -174,19 +198,39 @@ class convertModel extends model break; } - if($module == 'user') $this->importJiraUser($dataList); - if($module == 'project') $this->importJiraProject($dataList); - if($module == 'issue') $this->importJiraIssue($dataList); - if($module == 'build') $this->importJiraBuild($dataList); + if($module == 'user') $this->importJiraUser($dataList); + if($module == 'project') $this->importJiraProject($dataList); + if($module == 'issue') $this->importJiraIssue($dataList); + if($module == 'build') $this->importJiraBuild($dataList); + if($module == 'issuelink') $this->importJiraIssueLink($dataList); + if($module == 'action') $this->importJiraAction($dataList); + if($module == 'file') $this->importJiraFile($dataList); return array('type' => $module, 'count' => count($dataList), 'lastID' => max(array_keys($dataList))); } } + /* 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); return array('finished' => true); } + /** + * Import jira user. + * + * @param object $dataList + * @access public + * @return void + */ public function importJiraUser($dataList) { $localUsers = $this->dao->dbh($this->dbh)->select('account')->from(TABLE_USER)->where('deleted')->eq('0')->fetchPairs(); @@ -202,7 +246,7 @@ class convertModel extends model $user->password = $userConfig['password']; $user->group = $userConfig['group']; $user->email = $data->email; - $user->gender = 'f'; + $user->gender = 'm'; $user->type = 'inside'; $user->join = $data->join; @@ -219,6 +263,13 @@ class convertModel extends model } } + /** + * Import jira project. + * + * @param object $dataList + * @access public + * @return void + */ public function importJiraProject($dataList) { global $app; @@ -248,8 +299,8 @@ class convertModel extends model $project->openedBy = $this->getJiraAccount($data->LEAD); $project->openedDate = $now; $project->openedVersion = $this->config->version; - $this->dao->dbh($this->dbh)->insert(TABLE_PROJECT)->data($project)->exec(); + $this->dao->dbh($this->dbh)->insert(TABLE_PROJECT)->data($project)->exec(); $projectID = $this->dao->dbh($this->dbh)->lastInsertID(); $this->dao->dbh($this->dbh)->update(TABLE_PROJECT)->set('`order`')->eq($projectID * 5)->set('path')->eq(",$projectID,")->where('id')->eq($projectID)->exec(); @@ -289,8 +340,8 @@ class convertModel extends model $execution->openedBy = $project->openedBy; $execution->openedDate = $now; $execution->openedVersion = $this->config->version; - $this->dao->dbh($this->dbh)->insert(TABLE_PROJECT)->data($execution)->exec(); + $this->dao->dbh($this->dbh)->insert(TABLE_PROJECT)->data($execution)->exec(); $executionID = $this->dao->dbh($this->dbh)->lastInsertID(); $this->dao->dbh($this->dbh)->update(TABLE_PROJECT)->set('`order`')->eq($executionID * 5)->set('path')->eq(",$projectID,$executionID,")->where('id')->eq($executionID)->exec(); @@ -312,6 +363,7 @@ class convertModel extends model $lib->type = 'execution'; $lib->main = '1'; $lib->acl = 'default'; + $this->dao->dbh($this->dbh)->insert(TABLE_DOCLIB)->data($lib)->exec(); /* Create product. */ @@ -325,8 +377,8 @@ class convertModel extends model $product->createdBy = $project->openedBy; $product->createdDate = helper::now(); $product->createdVersion = $this->config->version; - $this->dao->dbh($this->dbh)->insert(TABLE_PRODUCT)->data($product)->exec(); + $this->dao->dbh($this->dbh)->insert(TABLE_PRODUCT)->data($product)->exec(); $productID = $this->dao->dbh($this->dbh)->lastInsertID(); /* Create doc lib. */ @@ -358,6 +410,13 @@ class convertModel extends model } } + /** + * Import jira issue. + * + * @param object $dataList + * @access public + * @return void + */ public function importJiraIssue($dataList) { $relations = $this->session->jiraRelation; @@ -395,7 +454,6 @@ class convertModel extends model $projectKeys = $this->dao->dbh($this->sourceDBH)->select('ID, ORIGINALKEY as oldKey, pkey as newKey')->from(JIRA_PROJECT)->fetchAll('ID'); - $issueObjectType = array(); foreach($dataList as $id => $data) { $issueType = isset($issueTypeList[$data->issuetype]) ? $issueTypeList[$data->issuetype] : 'task'; @@ -452,6 +510,16 @@ class convertModel extends model ->set('version')->eq('1') ->exec(); + /* Create opened action from openedDate. */ + $action = new stdclass(); + $action->objectType = 'story'; + $action->objectID = $storyID; + $action->actor = $story->openedBy; + $action->action = 'Opened'; + $action->date = $story->openedDate; + $this->dao->dbh($this->dbh)->insert(TABLE_ACTION)->data($action)->exec(); + + /* Record relation. */ $storyRelation['AType'] = 'jstory'; $storyRelation['BType'] = 'zstory'; $storyRelation['AID'] = $issueID; @@ -487,6 +555,15 @@ class convertModel extends model $this->dao->dbh($this->dbh)->insert(TABLE_TASK)->data($task)->exec(); $taskID = $this->dao->dbh($this->dbh)->lastInsertID(); + /* Create opened action from openedDate. */ + $action = new stdclass(); + $action->objectType = 'task'; + $action->objectID = $taskID; + $action->actor = $task->openedBy; + $action->action = 'Opened'; + $action->date = $task->openedDate; + $this->dao->dbh($this->dbh)->insert(TABLE_ACTION)->data($action)->exec(); + $taskRelation['AType'] = 'jtask'; $taskRelation['BType'] = 'ztask'; $taskRelation['AID'] = $issueID; @@ -522,6 +599,15 @@ class convertModel extends model $this->dao->dbh($this->dbh)->insert(TABLE_BUG)->data($bug)->exec(); $bugID = $this->dao->dbh($this->dbh)->lastInsertID(); + /* Create opened action from openedDate. */ + $action = new stdclass(); + $action->objectType = 'bug'; + $action->objectID = $bugID; + $action->actor = $bug->openedBy; + $action->action = 'Opened'; + $action->date = $bug->openedDate; + $this->dao->dbh($this->dbh)->insert(TABLE_ACTION)->data($action)->exec(); + $bugRelation['AType'] = 'jbug'; $bugRelation['BType'] = 'zbug'; $bugRelation['AID'] = $issueID; @@ -548,10 +634,356 @@ class convertModel extends model } } + /** + * Import jira build. + * + * @param object $dataList + * @access public + * @return void + */ public function importJiraBuild($dataList) { + $issueObjectType = $this->dao->dbh($this->dbh)->select('AID,extra')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jissueid') + ->andWhere('BType')->eq('zissuetype') + ->fetchPairs(); + + $issueBugs = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jbug') + ->andWhere('BType')->eq('zbug') + ->fetchPairs(); + + $issueStories = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jstory') + ->andWhere('BType')->eq('zstory') + ->fetchPairs(); + + $projectRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jproject') + ->andWhere('BType')->eq('zproject') + ->fetchPairs(); + + $projectProduct = $this->dao->dbh($this->dbh)->select('project,product')->from(TABLE_PROJECTPRODUCT) + ->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'); + + foreach($dataList as $data) + { + if(empty($data->RELEASEDATE)) continue; + + $versionID = $data->ID; + $buildProject = $data->PROJECT; + $projectID = $projectRelation[$buildProject]; + $productID = $projectProduct[$projectID]; + + $build = new stdclass(); + $build->product = $productID; + $build->project = $projectID; + $build->name = $data->vname; + $build->date = substr($data->RELEASEDATE, 0, 10); + $build->builder = $this->app->user->account; + + $this->dao->dbh($this->dbh)->insert(TABLE_BUILD)->data($build)->exec(); + $buildID = $this->dao->dbh($this->dbh)->lastInsertID(); + + $release = new stdclass(); + $release->product = $build->product; + $release->build = $buildID; + $release->name = $build->name; + $release->date = $build->date; + $release->desc = $data->DESCRIPTION; + $release->status = 'normal'; + + $this->dao->dbh($this->dbh)->insert(TABLE_RELEASE)->data($release)->exec(); + $releaseID = $this->dao->dbh($this->dbh)->lastInsertID(); + + /* Process release data. */ + if(isset($versionGroup[$versionID])) + { + foreach($versionGroup[$versionID] as $issue) + { + $issueType = zget($issueObjectType, $issue->issueID, ''); + if(!$issueType || ($issueType != 'story' and $issueType != 'bug')) continue; + $objectID = $issueType == 'bug' ? zget($issueBugs, $issue->issueID) : zget($issueStories, $issue->issueID); + + $field = $issueType == 'story' ? 'stories' : 'bugs'; + if($issueType == 'story') + { + $this->dao->dbh($this->dbh)->update(TABLE_RELEASE)->set("stories = CONCAT(stories, ',$objectID')")->where('id')->eq($releaseID)->exec(); + } + else + { + $this->dao->dbh($this->dbh)->update(TABLE_RELEASE)->set("bugs = CONCAT(bugs, ',$objectID')")->where('id')->eq($releaseID)->exec(); + } + } + } + } } + /** + * Import jira issue link. + * + * @param object $dataList + * @access public + * @return void + */ + public function importJiraIssueLink($dataList) + { + $issueLinkTypeList = array(); + $relations = $this->session->jiraRelation; + + $issueStories = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jstory') + ->andWhere('BType')->eq('zstory') + ->fetchPairs(); + + $issueTasks = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jtask') + ->andWhere('BType')->eq('ztask') + ->fetchPairs(); + + $issueBugs = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jbug') + ->andWhere('BType')->eq('zbug') + ->fetchPairs(); + + $issueObjectType = $this->dao->dbh($this->dbh)->select('AID,extra')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jissueid') + ->andWhere('BType')->eq('zissuetype') + ->fetchPairs(); + + foreach($relations['jiraLinkType'] as $id => $jiraCode) $issueLinkTypeList[$jiraCode] = $relations['zentaoLinkType'][$id]; + + $storyLink = $taskLink = $duplicateLink = $relatesLink = array(); + foreach($dataList as $issueLink) + { + $linkType = $issueLink->LINKTYPE; + if($issueLinkTypeList[$linkType] == 'subStoryLink') $storyLink[$issueLink->SOURCE][] = $issueLink->DESTINATION; + if($issueLinkTypeList[$linkType] == 'subTaskLink') $taskLink[$issueLink->SOURCE][] = $issueLink->DESTINATION; + if($issueLinkTypeList[$linkType] == 'duplicate') $duplicateLink[$issueLink->SOURCE] = $issueLink->DESTINATION; + if($issueLinkTypeList[$linkType] == 'relates') $relatesLink[$issueLink->SOURCE] = $issueLink->DESTINATION; + } + + foreach($storyLink as $source => $dest) + { + if(!isset($issueStories[$source])) continue; + $parentID = $issueStories[$source]; + $this->dao->dbh($this->dbh)->update(TABLE_STORY)->set('parent')->eq('-1')->where('id')->eq($parentID)->exec(); + foreach($dest as $childID) + { + if(!isset($issueStories[$childID])) continue; + $this->dao->dbh($this->dbh)->update(TABLE_STORY)->set('parent')->eq($parentID)->where('id')->eq($issueStories[$childID])->exec(); + } + } + + foreach($taskLink as $source => $dest) + { + if(!isset($issueTasks[$source])) continue; + $parentID = $issueTasks[$source]; + $this->dao->dbh($this->dbh)->update(TABLE_TASK)->set('parent')->eq('-1')->where('id')->eq($parentID)->exec(); + foreach($dest as $childID) + { + if(!isset($issueTasks[$childID])) continue; + $this->dao->dbh($this->dbh)->update(TABLE_TASK)->set('parent')->eq($parentID)->where('id')->eq($issueTasks[$childID])->exec(); + } + } + + foreach($duplicateLink as $source => $dest) + { + $objectType = $issueObjectType[$source]; + + if($objectType != 'story' and $objectType != 'bug') continue; + if($issueObjectType[$source] != $issueObjectType[$dest]) continue; + + if(!isset($relation[$objectType][$source]) or !isset($relation[$objectType][$dest])) continue; + + if($objectType == 'story') + { + if(empty($issueStories[$dest]) or empty($issueStories[$source])) continue; + $this->dao->dbh($this->dbh)->update(TABLE_STORY)->set('duplicateStory')->eq($$issueStories[$dest])->where('id')->eq($issueStories[$source])->exec(); + } + elseif($objectType == 'bug') + { + if(empty($issueBugs[$dest]) or empty($issueBugs[$source])) continue; + $this->dao->dbh($this->dbh)->update(TABLE_BUG)->set('duplicateBug')->eq($issueBugs[$dest])->where('id')->eq($issueBugs[$source])->exec(); + } + } + + foreach($relatesLink as $source => $dest) + { + if(empty($issueObjectType[$source]) or empty($issueObjectType[$dest])) continue; + + $sourceObjectType = $issueObjectType[$source]; + $destObjectType = $issueObjectType[$dest]; + + if($sourceObjectType == 'task' and $destObjectType == 'story') + { + $this->dao->dbh($this->dbh)->update(TABLE_TASK)->set('story')->eq($issueStories[$dest])->where('id')->eq($issueTasks[$source])->exec(); + } + elseif($sourceObjectType == 'story' and $destObjectType == 'task') + { + $this->dao->dbh($this->dbh)->update(TABLE_TASK)->set('story')->eq($issueStories[$source])->where('id')->eq($issueTasks[$dest])->exec(); + } + elseif($sourceObjectType == 'story' and $destObjectType == 'bug') + { + $this->dao->dbh($this->dbh)->update(TABLE_BUG)->set('story')->eq($issueStories[$source])->set('storyVersion')->eq(1)->where('id')->eq($issueBugs[$dest])->exec(); + } + elseif($sourceObjectType == 'bug' and $destObjectType == 'story') + { + $this->dao->dbh($this->dbh)->update(TABLE_BUG)->set('story')->eq($issueStories[$dest])->set('storyVersion')->eq(1)->where('id')->eq($issueBugs[$source])->exec(); + } + elseif($sourceObjectType == 'story' and $destObjectType == 'story') + { + $this->dao->dbh($this->dbh)->update(TABLE_STORY)->set("linkStories=concat(linkStories, ',{$issueStories[$dest]}')")->where('id')->eq($issueStories[$source])->exec(); + } + elseif($sourceObjectType == 'bug' and $destObjectType == 'bug') + { + $this->dao->dbh($this->dbh)->update(TABLE_BUG)->set("linkBug=concat(linkBug, ',{$issueBugs[$dest]}')")->where('id')->eq($issueBugs[$source])->exec(); + } + } + } + + /** + * Import jira action. + * + * @param object $dataList + * @access public + * @return void + */ + public function importJiraAction($dataList) + { + $issueStories = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jstory') + ->andWhere('BType')->eq('zstory') + ->fetchPairs(); + + $issueTasks = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jtask') + ->andWhere('BType')->eq('ztask') + ->fetchPairs(); + + $issueBugs = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jbug') + ->andWhere('BType')->eq('zbug') + ->fetchPairs(); + + $issueObjectType = $this->dao->dbh($this->dbh)->select('AID,extra')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jissueid') + ->andWhere('BType')->eq('zissuetype') + ->fetchPairs(); + + $projectRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jproject') + ->andWhere('BType')->eq('zproject') + ->fetchPairs(); + + $projectProduct = $this->dao->dbh($this->dbh)->select('project,product')->from(TABLE_PROJECTPRODUCT) + ->where('project')->in(array_values($projectRelation)) + ->fetchPairs(); + + foreach($dataList as $data) + { + $action = new stdclass(); + + $issueID = $data->issueid; + $comment = $data->actionbody; + if(empty($comment)) continue; + + $objectType = $issueObjectType[$issueID]; + if($objectType == 'task') $objectID = $issueTasks[$issueID]; + if($objectType == 'bug') $objectID = $issueBugs[$issueID]; + if($objectType == 'story') $objectID = $issueStories[$issueID]; + + if(empty($objectID)) continue; + + $action = new stdclass(); + $action->objectType = $objectType; + $action->objectID = $objectID; + $action->actor = $this->getJiraAccount($data->AUTHOR); + $action->action = 'commented'; + $action->date = substr($data->CREATED, 0, 19); + $action->comment = $comment; + $this->dao->dbh($this->dbh)->insert(TABLE_ACTION)->data($action)->exec(); + } + } + + /** + * Import jira file. + * + * @param object $dataList + * @access public + * @return void + */ + public function importJiraFile($dataList) + { + $this->loadModel('file'); + + $issueObjectType = $this->dao->dbh($this->dbh)->select('AID,extra')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jissueid') + ->andWhere('BType')->eq('zissuetype') + ->fetchPairs(); + + $issueStories = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jstory') + ->andWhere('BType')->eq('zstory') + ->fetchPairs(); + + $issueTasks = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jtask') + ->andWhere('BType')->eq('ztask') + ->fetchPairs(); + + $issueBugs = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jbug') + ->andWhere('BType')->eq('zbug') + ->fetchPairs(); + + $filePaths = $this->dao->dbh($this->dbh)->select('AID,extra')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jissueid') + ->andWhere('BType')->eq('jfilepath') + ->fetchPairs(); + + foreach($dataList as $fileAttachment) + { + $issueID = $fileAttachment->issueid; + $objectType = $issueObjectType[$issueID]; + if($objectType != 'bug' and $objectType != 'task' and $objectType != 'story') continue; + + $fileID = $fileAttachment->ID; + $fileName = $fileAttachment->FILENAME; + list($mime, $extension) = explode('/', $fileAttachment->MIMETYPE); + + if($objectType == 'bug') $objectID = $issueBugs[$issueID]; + if($objectType == 'task') $objectID = $issueTasks[$issueID]; + if($objectType == 'story') $objectID = $issueStories[$issueID]; + if(empty($objectID)) continue; + + $file = new stdclass(); + $file->pathname = $this->file->setPathName($fileID, $extension); + $file->title = str_ireplace(".{$extension}", '', $fileName); + $file->extension = $extension; + $file->size = $fileAttachment->FILESIZE; + $file->objectType = $objectType; + $file->objectID = $objectID; + $file->addedBy = $this->getJiraAccount($fileAttachment->AUTHOR); + $file->addedDate = substr($fileAttachment->CREATED, 0, 19); + $this->dao->dbh($this->dbh)->insert(TABLE_FILE)->data($file)->exec(); + + $jiraFile = $this->app->getCacheRoot() . 'attachments/' . $filePaths[$issueID] . $fileID; + if(is_file($jiraFile)) copy($jiraFile, $this->file->savePath . $file->pathname); + } + } + + /** + * Convert jira status. + * + * @param string $objectType + * @param string $jiraStatus + * @access public + * @return void + */ public function convertStatus($objectType, $jiraStatus) { $status = 'active'; @@ -567,6 +999,13 @@ class convertModel extends model return $status; } + /** + * Convert stage. + * + * @param string $jiraStatus + * @access public + * @return void + */ public function convertStage($jiraStatus) { $stage = 'wait'; @@ -580,6 +1019,13 @@ class convertModel extends model return $stage; } + /** + * Get jira account. + * + * @param string $userKey + * @access public + * @return void + */ public function getJiraAccount($userKey) { if(strpos($userKey, 'JIRAUSER') === false) return $userKey; diff --git a/module/convert/view/importnotice.html.php b/module/convert/view/importnotice.html.php index 095041622e..f76f35ddfd 100644 --- a/module/convert/view/importnotice.html.php +++ b/module/convert/view/importnotice.html.php @@ -26,10 +26,17 @@ li .form-control {margin-top: 10px}
        1. convert->jira->importSteps[$type][1];?>
        2. convert->jira->importSteps[$type][2];?>
        3. -
        4. convert->jira->importSteps[$type][3], $this->app->getTmpRoot());?>
        5. + +
        6. convert->jira->importSteps[$type][3];?>
        7. + +
        8. convert->jira->importSteps[$type][3], $app->getTmpRoot() . 'jirafile');?>
        9. + +
        10. convert->jira->importSteps[$type][4], $app->getTmpRoot());?>
        11. - convert->jira->importSteps[$type][4];?> + convert->jira->importSteps[$type][5];?> + convert->jira->dbNameNotice}");?> +
        From 0eee64a96301f4ff78c8c959bfe8beb932448436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Fri, 11 Feb 2022 14:45:08 +0800 Subject: [PATCH 24/24] * Fix jira. --- module/convert/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/convert/model.php b/module/convert/model.php index 3a5f927de6..e36c70652d 100644 --- a/module/convert/model.php +++ b/module/convert/model.php @@ -971,7 +971,7 @@ class convertModel extends model $file->addedDate = substr($fileAttachment->CREATED, 0, 19); $this->dao->dbh($this->dbh)->insert(TABLE_FILE)->data($file)->exec(); - $jiraFile = $this->app->getCacheRoot() . 'attachments/' . $filePaths[$issueID] . $fileID; + $jiraFile = $this->app->getTmpRoot() . 'attachments/' . $filePaths[$issueID] . $fileID; if(is_file($jiraFile)) copy($jiraFile, $this->file->savePath . $file->pathname); } }