From 9ab1e4541f59b94d33ee8ed526cd320deba8e71f Mon Sep 17 00:00:00 2001 From: dingguodong Date: Tue, 6 Jul 2021 16:31:43 +0800 Subject: [PATCH] * Import gitlab issue to task(staging). --- config/filter.php | 1 + module/gitlab/control.php | 92 ++++++++++++++++++++++--- module/gitlab/js/importissue.js | 18 +++++ module/gitlab/js/mapissue.js | 19 ----- module/gitlab/model.php | 46 ++++++++++--- module/gitlab/view/importissue.html.php | 11 ++- module/task/model.php | 53 +++++++++++++- 7 files changed, 195 insertions(+), 45 deletions(-) create mode 100644 module/gitlab/js/importissue.js delete mode 100644 module/gitlab/js/mapissue.js diff --git a/config/filter.php b/config/filter.php index a4125b9da5..7460c2a0da 100644 --- a/config/filter.php +++ b/config/filter.php @@ -319,5 +319,6 @@ $filter->gitlab->webhook->get['token'] = 'reg::any'; $filter->gitlab->importissue->get['gitlab'] = 'int'; $filter->gitlab->importissue->get['product'] = 'int'; +$filter->gitlab->importissue->get['product'] = 'string'; $filter->gitlab->importissue->get['project'] = 'int'; diff --git a/module/gitlab/control.php b/module/gitlab/control.php index c39a7729ce..744927264d 100644 --- a/module/gitlab/control.php +++ b/module/gitlab/control.php @@ -251,29 +251,101 @@ class gitlab extends control exit; } + /** + * Import gitlab issue to zentaopms. + * + * @access public + * @return void + */ public function importIssue() { - $productID = $this->get->product; - $gitlabID = $this->get->gitlab; - $projectID = $this->get->project; + $productIDList = explode(',', $this->get->product); + $gitlabID = $this->get->gitlab; + $projectID = $this->get->project; - $executions = $this->loadModel('product')->getAllExecutionPairsByProduct($productID); if($_POST) { - $this->post->a(); + $executionList = $this->post->executionList; + $objectTypeList = $this->post->objectTypeList; + $productList = $this->post->productList; + foreach($executionList as $issueID => $executionID) + { + if($executionID) + { + $objectType = $this->config->gitlab->objectTypes[$objectTypeList[$issueID]]; + + $issue = $this->gitlab->apiGetSingleIssue($gitlabID, $projectID, $issueID); + $originalIssue = $issue; + $issue->objectType = $objectType; + $issue->objectID = 0; // meet the required parameters for issueToZentaoObject. + if(isset($issue->assignee)) $issue->assignee_id = $issue->assignee->id; + $issue->updated_by_id = $issue->author->id; // here can be replaced by current zentao user. + + $object = $this->gitlab->issueToZentaoObject($issue, $gitlabID); + if($objectType == 'task') + { + $objectID = $this->loadModel('task')->createTaskFromGitlabIssue($object, $executionID); + } + + if($objectType == 'bug') + { + } + + if($objectType == 'story') + { + } + + $object->id = $objectID; + $this->gitlab->saveImportedIssue($gitlabID, $projectID, $objectType, $objectID, $originalIssue, $object); + + } + } + $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->server->http_referer)); } - $gitlabIssues = $this->gitlab->apiGetIssues($gitlabID, $projectID); - - $this->view->productName = $this->loadModel("product")->getByID($productID)->name; - $this->view->productID = $productID; + $savedIssueIDList = $this->dao->select('BID as issueID')->from(TABLE_RELATION) + ->where('relation')->eq('gitlab') + ->fetchAll('issueID'); + $iids = ''; + foreach($savedIssueIDList as $savedIssueID) $iids = $iids . $savedIssueID->issueID . ','; + $options = '¬[iids]=' . trim($iids, ','); + $gitlabIssues = $this->gitlab->apiGetIssues($gitlabID, $projectID, $options); //TODO(dingguodong) when no issues here? + + $products = array(); + $products[] = ''; + foreach($productIDList as $productID) + { + $products[$productID] = $this->loadModel("product")->getByID($productID)->name; + } + + $this->view->products = $products; $this->view->gitlabID = $gitlabID; $this->view->gitlabProjectID = $projectID; - $this->view->executions = $executions; $this->view->objectTypes = $this->config->gitlab->objectTypes; $this->view->gitlabIssues = $gitlabIssues; $this->display(); } + + /** + * Ajax get executions by productID. + * + * @param int $productID + * @access public + * @return string + */ + public function ajaxGetExecutionsByProduct($productID) + { + if(!$productID) $this->send(array('message' => array())); + + $executions = $this->loadModel('product')->getAllExecutionPairsByProduct($productID); + $options = ""; + foreach($executions as $index =>$execution) + { + $options .= ""; + } + die($options); + } + } diff --git a/module/gitlab/js/importissue.js b/module/gitlab/js/importissue.js new file mode 100644 index 0000000000..d48d5a6028 --- /dev/null +++ b/module/gitlab/js/importissue.js @@ -0,0 +1,18 @@ +$(document).ready(function() +{ + $('[name^=productList').change(function() + { + var execution = $(this); + host = execution.val(); + if(host == '') return false; + executions = ''; + url = createLink('gitlab', 'ajaxGetExecutionsByProduct', "host=" + host); + + $.get(url, function(response) + { + execution = execution.parent().next().find('select'); + execution.html('').append(response); + execution.chosen().trigger("chosen:updated"); + }); + }); +}); diff --git a/module/gitlab/js/mapissue.js b/module/gitlab/js/mapissue.js deleted file mode 100644 index a8be522002..0000000000 --- a/module/gitlab/js/mapissue.js +++ /dev/null @@ -1,19 +0,0 @@ -$(document).ready(function() -{ - $('[name^=gitlabID').change(function() - { - var gitlab = $(this); - host = gitlab.val(); - if(host == '') return false; - projects = ''; - url = createLink('repo', 'ajaxgetgitlabprojects', "host=" + host); - - $.get(url, function(response) - { - project = gitlab.parent().next().find('select'); - project.html('').append(response); - project.chosen().trigger("chosen:updated"); - }); - - }); -}); diff --git a/module/gitlab/model.php b/module/gitlab/model.php index 7eea1cc937..d972f2ffaa 100644 --- a/module/gitlab/model.php +++ b/module/gitlab/model.php @@ -271,13 +271,11 @@ class gitlabModel extends model if(is_numeric($host)) $host = $this->getApiRoot($host); if(strpos($host, 'http://') !== 0 and strpos($host, 'https://') !== 0) return false; - $url = sprintf($apiRoot, $api); + $url = sprintf($host, $api); return json_decode(commonModel::http($url, $data, $options)); } /** -<<<<<<< HEAD -======= * Send an api post request. * * @param int|string $host gitlab server ID | gitlab host url. @@ -549,10 +547,17 @@ class gitlabModel extends model return json_decode(commonModel::http($url)); } - public function apiGetIssues($gitlabID, $projectID) + public function apiGetIssues($gitlabID, $projectID, $options = null) { // TODO(dingguodong) not pagination yet. - $url = sprintf($this->getApiRoot($gitlabID), "/projects/{$projectID}/issues") . '&per_page=100'; + if($options) + { + $url = sprintf($this->getApiRoot($gitlabID), "/projects/{$projectID}/issues") . '&per_page=100' . $options; + } + else + { + $url = sprintf($this->getApiRoot($gitlabID), "/projects/{$projectID}/issues") . '&per_page=100'; + } return json_decode(commonModel::http($url)); } @@ -893,7 +898,7 @@ class gitlabModel extends model * @access public * @return void */ - public function saveSyncedIssue($objectType, $object, $gitlab, $issue) + public function saveSyncedIssue($objectType, $object, $gitlabID, $issue) { if(empty($issue->iid) or empty($issue->project_id)) return false; @@ -906,10 +911,33 @@ class gitlabModel extends model $relation->BType = 'issue'; $relation->BID = $issue->iid; $relation->BVersion = $issue->project_id; - $relation->extra = $gitlab; + $relation->extra = $gitlabID; $this->dao->replace(TABLE_RELATION)->data($relation)->exec(); } + /** + * Save imported issue. + * + * @param int $gitlabID + * @param int $projectID + * @param string $objectType + * @param int $objectID + * @param object $issue + * @access public + * @return void + */ + public function saveImportedIssue($gitlabID, $projectID, $objectType, $objectID, $issue, $object) + { + $label = $this->createZentaoObjectLabel($gitlabID, $projectID, $objectType, $objectID); + $data = new stdclass; + if(isset($label->name)) $data->labels = $label->name; + + $apiRoot = $this->getApiRoot($gitlabID); + $url = sprintf($apiRoot, "/projects/{$projectID}/issues/{$issue->iid}"); + commonModel::http($url, $data, $options = array(CURLOPT_CUSTOMREQUEST => 'PUT')); + $this->saveSyncedIssue($objectType, $object, $gitlabID, $issue); + } + /** * Parse task to issue. * @@ -1110,12 +1138,12 @@ class gitlabModel extends model { $value = ''; list($gitlabField, $optionType, $options) = explode('|', $config); - if(!isset($changes->$gitlabField)) continue; + if(!isset($changes->$gitlabField) and $object->id != 0) continue; if($optionType == 'field') $value = $issue->$gitlabField; if($optionType == 'field') $value = $issue->$gitlabField; if($options == 'date') $value = date('Y-m-d', strtotime($value)); if($options == 'datetime') $value = date('Y-m-d H:i:s', strtotime($value)); - if($optionType == 'userPairs') $value = zget($gitlabUsers, $issue->$gitlabField); + if($optionType == 'userPairs' and isset($issue->$gitlabField)) $value = zget($gitlabUsers, $issue->$gitlabField); if($optionType == 'configItems' and isset($issue->$gitlabField)) $value = array_search($issue->$gitlabField, $this->config->gitlab->$options); if($value) $object->$zentaoField = $value; } diff --git a/module/gitlab/view/importissue.html.php b/module/gitlab/view/importissue.html.php index e1a53be93c..c43fcc2e24 100644 --- a/module/gitlab/view/importissue.html.php +++ b/module/gitlab/view/importissue.html.php @@ -21,21 +21,20 @@ gitlab->gitlabIssue;?> + gitlab->objectType;?> product->common;?> execution->common;?> - gitlab->objectType;?> - title; ?> - - + web_url}' target='_blank'>$issue->title"; ?> + iid}]", $objectTypes, '', "class='form-control select chosen'" );?> + iid}]", $products, '', "class='form-control select chosen'" );?> + iid}]", '', '', "class='form-control select chosen'" );?> - - diff --git a/module/task/model.php b/module/task/model.php index 55dd236b04..a4032ee589 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -122,7 +122,6 @@ class taskModel extends model $taskID = $this->dao->lastInsertID(); /* Sync this task to gitlab issue. */ - $object = $this->getByID($taskID); $this->loadModel('gitlab')->apiCreateIssue($this->post->gitlab, $this->post->gitlabProject, 'task', $taskID, $object); @@ -455,6 +454,58 @@ class taskModel extends model return $mails; } + /** + * Create task from gitlab issue. + * + * @param object $task + * @param int $executionID + * @access public + * @return int + */ + public function createTaskFromGitlabIssue($task, $executionID) + { + foreach($task as $feild => $value) $_POST[$feild] = $value; + $requiredFields = ',' . $this->config->task->create->requiredFields . ','; + $requiredFields = trim($requiredFields, ','); + $task = fixer::input('post') + ->setDefault('execution', $executionID) + ->setDefault('estimate,left,story', 0) + ->setDefault('status', 'wait') + ->setIF($this->config->systemMode == 'new', 'project', $this->getProjectID($executionID)) + ->setIF($this->post->estimate != false, 'left', $this->post->estimate) + ->setIF($this->post->story != false, 'storyVersion', $this->loadModel('story')->getVersion($this->post->story)) + ->setDefault('estStarted', '0000-00-00') + ->setDefault('deadline', '0000-00-00') + ->setIF(strpos($requiredFields, 'estStarted') !== false, 'estStarted', helper::isZeroDate($this->post->estStarted) ? '' : $this->post->estStarted) + ->setIF(strpos($requiredFields, 'deadline') !== false, 'deadline', helper::isZeroDate($this->post->deadline) ? '' : $this->post->deadline) + ->setIF(strpos($requiredFields, 'estimate') !== false, 'estimate', $this->post->estimate) + ->setIF(strpos($requiredFields, 'left') !== false, 'left', $this->post->left) + ->setIF(strpos($requiredFields, 'story') !== false, 'story', $this->post->story) + ->setIF(is_numeric($this->post->estimate), 'estimate', (float)$this->post->estimate) + ->setIF(is_numeric($this->post->consumed), 'consumed', (float)$this->post->consumed) + ->setIF(is_numeric($this->post->left), 'left', (float)$this->post->left) + ->setDefault('openedBy', $this->app->user->account) + ->setDefault('openedDate', helper::now()) + ->cleanINT('execution,story,module') + ->stripTags($this->config->task->editor->create['id'], $this->config->allowedTags) + ->join('mailto', ',') + ->remove('objectTypeList,productList,executionList,gitlabID,gitlabProjectID,after,files,labels,assignedTo,uid,storyEstimate,storyDesc,storyPri,team,teamEstimate,teamMember,multiple,teams,contactListMenu,selectTestStory,testStory,testPri,testEstStarted,testDeadline,testAssignedTo,testEstimate,sync') + ->add('version', 1) + ->get(); + + $this->dao->insert(TABLE_TASK)->data($task, $skip = 'id') + ->autoCheck() + ->batchCheck($requiredFields, 'notempty') + ->checkIF($task->estimate != '', 'estimate', 'float') + ->checkIF(!helper::isZeroDate($task->deadline), 'deadline', 'ge', $task->estStarted) + ->exec(); + + if(dao::isError()) return false; + + $taskID = $this->dao->lastInsertID(); + return $taskID; + } + /** * Compute parent task working hours. *