* Import gitlab issue to task(staging).

This commit is contained in:
dingguodong
2021-07-06 16:31:43 +08:00
parent ec86c142ef
commit 9ab1e4541f
7 changed files with 195 additions and 45 deletions
+1
View File
@@ -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';
+82 -10
View File
@@ -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 = '&not[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 = "<option value=''></option>";
foreach($executions as $index =>$execution)
{
$options .= "<option value='{$index}' data-name='{$execution}'>{$execution}</option>";
}
die($options);
}
}
+18
View File
@@ -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");
});
});
});
-19
View File
@@ -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");
});
});
});
+37 -9
View File
@@ -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;
}
+5 -6
View File
@@ -21,21 +21,20 @@
<thead>
<tr>
<th width='60px'><?php echo $lang->gitlab->gitlabIssue;?></th>
<th width='30px'><?php echo $lang->gitlab->objectType;?></th>
<th width='30px'><?php echo $lang->product->common;?></th>
<th width='30px'><?php echo $lang->execution->common;?></th>
<th width='30px'><?php echo $lang->gitlab->objectType;?></th>
</tr>
</thead>
<tbody>
<?php foreach($gitlabIssues as $issue):?>
<tr>
<td><?php echo $issue->title; ?></td>
<td><?php echo $productName; ?></td>
<input type='hidden' name='productID' value='<?php echo $productID;?>' />
<td><?php echo "<a href='{$issue->web_url}' target='_blank'>$issue->title</a>"; ?></td>
<td><?php echo html::select("objectTypeList[{$issue->iid}]", $objectTypes, '', "class='form-control select chosen'" );?></td>
<td><?php echo html::select("productList[{$issue->iid}]", $products, '', "class='form-control select chosen'" );?></td>
<td><?php echo html::select("executionList[{$issue->iid}]", '', '', "class='form-control select chosen'" );?></td>
<input type='hidden' name='gitlabID' value='<?php echo $gitlabID;?>' />
<input type='hidden' name='gitlabProjectID' value='<?php echo $gitlabProjectID;?>' />
<td><?php echo html::select("mappedIssues", $executions, '', "class='form-control select chosen'" );?></td>
<td><?php echo html::select("objectType", $objectTypes, '', "class='form-control select chosen'" );?></td>
</tr>
<?php endforeach; ?>
</tbody>
+52 -1
View File
@@ -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.
*