Merge branch 'jihu' of https://gitlab.zcorp.cc/easycorp/zentaopms into jihu
This commit is contained in:
@@ -55,6 +55,7 @@ $config->gitlab->maps->bug = array();
|
||||
$config->gitlab->maps->bug['title'] = 'title|field|';
|
||||
$config->gitlab->maps->bug['steps'] = 'description|field|';
|
||||
$config->gitlab->maps->bug['openedDate'] = 'created_at|field|datetime';
|
||||
$config->gitlab->maps->bug['deadline'] = 'due_date|field|date';
|
||||
$config->gitlab->maps->bug['assignedTo'] = 'assignee_id|userPairs|';
|
||||
$config->gitlab->maps->bug['status'] = 'state|configItems|bugStateMap';
|
||||
$config->gitlab->maps->bug['pri'] = 'weight|configItems|bugWeightMap';
|
||||
|
||||
+43
-26
@@ -247,28 +247,31 @@ class gitlab extends control
|
||||
a($relations);exit;
|
||||
$issue = $this->gitlab->taskToIssue($gitlabID, $projectID, $task);
|
||||
$issue = $this->gitlab->apiCreateIssue($gitlabID, $projectID, $issue);
|
||||
$this->gitlab->saveSyncedIssue('task', $task, $gitlabID, $issue);
|
||||
$this->gitlab->saveIssueRelation('task', $task, $gitlabID, $issue);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import gitlab issue to zentaopms.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function importIssue()
|
||||
public function importIssue($repoID)
|
||||
{
|
||||
$productIDList = explode(',', $this->get->product);
|
||||
$gitlabID = $this->get->gitlab;
|
||||
$projectID = $this->get->project;
|
||||
|
||||
$repo = $this->loadModel('repo')->getRepoByID($repoID);
|
||||
$productIDList = explode(',', $repo->product);
|
||||
$gitlabID = $repo->gitlab;
|
||||
$projectID = $repo->project;
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
$executionList = $this->post->executionList;
|
||||
$objectTypeList = $this->post->objectTypeList;
|
||||
$productList = $this->post->productList;
|
||||
|
||||
$failedIssues = array();
|
||||
foreach($executionList as $issueID => $executionID)
|
||||
{
|
||||
if($executionID)
|
||||
@@ -281,41 +284,54 @@ class gitlab extends control
|
||||
$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;
|
||||
$object->product = $productList[$issueID];
|
||||
$object->execution = $executionID;
|
||||
$this->gitlab->saveImportedIssue($gitlabID, $projectID, $objectType, $objectID, $issue, $object);
|
||||
$clonedObject = clone $object;
|
||||
|
||||
if($objectType == 'task') $objectID = $this->loadModel('task')->createTaskFromGitlabIssue($clonedObject, $executionID);
|
||||
if($objectType == 'bug') $objectID = $this->loadModel('bug')->createBugFromGitlabIssue($clonedObject, $executionID);
|
||||
if($objectType == 'story') $objectID = $this->loadModel('story')->createStoryFromGitlabIssue($clonedObject, $executionID);
|
||||
|
||||
if($objectID)
|
||||
{
|
||||
$object->id = $objectID;
|
||||
$this->gitlab->saveImportedIssue($gitlabID, $projectID, $objectType, $objectID, $issue, $object);
|
||||
}
|
||||
else
|
||||
{
|
||||
$failedIssues[] = $issue->iid;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($productList[$issueID] != 0) $this->send(array('result' => 'fail', 'message' => $this->lang->gitlab->importIssueError, 'locate' => $this->server->http_referer));
|
||||
}
|
||||
}
|
||||
|
||||
if($failedIssues) $this->send(array('result' => 'success', 'message' => $this->lang->gitlab->importIssueWarn, 'locate' => $this->server->http_referer));
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->server->http_referer));
|
||||
}
|
||||
|
||||
$savedIssueIDList = $this->dao->select('BID as issueID')->from(TABLE_RELATION)
|
||||
->where('relation')->eq('gitlab')
|
||||
->andWhere('product')->in($productIDList)
|
||||
->andWhere('BType')->eq('issue')
|
||||
->andWhere('BVersion')->eq($projectID)
|
||||
->andWhere('extra')->eq($gitlabID)
|
||||
->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?
|
||||
|
||||
/* 'not[iids]' option in gitlab API has a issue when iids is too long. */
|
||||
$gitlabIssues = $this->gitlab->apiGetIssues($gitlabID, $projectID, '&state=opened');
|
||||
foreach($gitlabIssues as $index => $issue)
|
||||
{
|
||||
foreach($savedIssueIDList as $savedIssueID)
|
||||
{
|
||||
if($issue->iid == $savedIssueID->issueID)
|
||||
{
|
||||
unset($gitlabIssues[$index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$products = array();
|
||||
$products[] = '';
|
||||
@@ -324,6 +340,7 @@ class gitlab extends control
|
||||
$products[$productID] = $this->loadModel("product")->getByID($productID)->name;
|
||||
}
|
||||
|
||||
$this->view->importable = empty($gitlabIssues) ? false : true;
|
||||
$this->view->products = $products;
|
||||
$this->view->gitlabID = $gitlabID;
|
||||
$this->view->gitlabProjectID = $projectID;
|
||||
|
||||
@@ -6,7 +6,7 @@ $lang->gitlab->create = '添加gitlab';
|
||||
$lang->gitlab->edit = '编辑gitlab';
|
||||
$lang->gitlab->bindUser = '绑定用户';
|
||||
$lang->gitlab->bindProduct = '关联产品';
|
||||
$lang->gitlab->importIssue = '关联议题';
|
||||
$lang->gitlab->importIssue = '关联issue';
|
||||
$lang->gitlab->delete = '删除';
|
||||
$lang->gitlab->confirmDelete = '确认删除该gitlab吗?';
|
||||
$lang->gitlab->gitlabAccount = 'gitlab用户';
|
||||
@@ -15,7 +15,7 @@ $lang->gitlab->zentaoAccount = '禅道用户';
|
||||
$lang->gitlab->browseAction = 'gitlab列表';
|
||||
$lang->gitlab->deleteAction = '删除gitlab';
|
||||
$lang->gitlab->gitlabProject = "{$lang->gitlab->common}项目";
|
||||
$lang->gitlab->gitlabIssue = "{$lang->gitlab->common}议题";
|
||||
$lang->gitlab->gitlabIssue = "{$lang->gitlab->common}issue";
|
||||
$lang->gitlab->zentaoProduct = '禅道产品';
|
||||
$lang->gitlab->objectType = '类型'; // task, bug, story
|
||||
|
||||
@@ -36,7 +36,9 @@ $lang->gitlab->placeholder->name = '';
|
||||
$lang->gitlab->placeholder->url = "请填写Gitlab Server首页的访问地址,如:https://gitlab.zentao.net。";
|
||||
$lang->gitlab->placeholder->token = "请填写具有admin权限账户的access token";
|
||||
|
||||
$lang->gitlab->tokenError = "当前token非管理员权限。";
|
||||
$lang->gitlab->hostError = "无效的gitlab服务地址。";
|
||||
$lang->gitlab->bindUserError = "不能重复绑定用户 %s";
|
||||
$lang->gitlab->importIssueError = "未选择该议题所属的执行。";
|
||||
$lang->gitlab->noImportableIssues = "目前没有可供导入的issue。";
|
||||
$lang->gitlab->tokenError = "当前token非管理员权限。";
|
||||
$lang->gitlab->hostError = "无效的gitlab服务地址。";
|
||||
$lang->gitlab->bindUserError = "不能重复绑定用户 %s";
|
||||
$lang->gitlab->importIssueError = "未选择该issue所属的执行。";
|
||||
$lang->gitlab->importIssueWarn = "存在导入失败的issue,可再次尝试导入。";
|
||||
|
||||
+62
-11
@@ -564,16 +564,25 @@ class gitlabModel extends model
|
||||
return json_decode(commonModel::http($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gitlab issues by api.
|
||||
*
|
||||
* @param int $gitlabID
|
||||
* @param int $projectID
|
||||
* @param string $options
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function apiGetIssues($gitlabID, $projectID, $options = null)
|
||||
{
|
||||
// TODO(dingguodong) not pagination yet.
|
||||
if($options)
|
||||
{
|
||||
$url = sprintf($this->getApiRoot($gitlabID), "/projects/{$projectID}/issues") . '&per_page=100' . $options;
|
||||
$url = sprintf($this->getApiRoot($gitlabID), "/projects/{$projectID}/issues") . '&per_page=20' . $options;
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = sprintf($this->getApiRoot($gitlabID), "/projects/{$projectID}/issues") . '&per_page=100';
|
||||
$url = sprintf($this->getApiRoot($gitlabID), "/projects/{$projectID}/issues") . '&per_page=20';
|
||||
}
|
||||
return json_decode(commonModel::http($url));
|
||||
}
|
||||
@@ -592,7 +601,7 @@ class gitlabModel extends model
|
||||
public function apiCreateIssue($gitlabID, $projectID, $objectType, $objectID, $object)
|
||||
{
|
||||
$label = $this->createZentaoObjectLabel($gitlabID, $projectID, $objectType, $objectID);
|
||||
|
||||
if(!isset($object->id)) $object->id = $objectID;
|
||||
$issue = $this->loadModel('gitlab')->parseObjectToIssue($gitlabID, $projectID, $objectType, $object);
|
||||
if(isset($label->name)) $issue->labels = $label->name;
|
||||
foreach($this->config->gitlab->skippedFields->issueCreate[$objectType] as $field)
|
||||
@@ -606,7 +615,7 @@ class gitlabModel extends model
|
||||
$response = json_decode(commonModel::http($url, $issue));
|
||||
if(!$response) return false;
|
||||
|
||||
return $this->saveSyncedIssue($objectType, $object, $gitlabID, $response);
|
||||
return $this->saveIssueRelation($objectType, $object, $gitlabID, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -619,8 +628,17 @@ class gitlabModel extends model
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function apiUpdateIssue($gitlabID, $projectID, $issueID, $objectType, $object)
|
||||
public function apiUpdateIssue($gitlabID, $projectID, $issueID, $objectType, $object, $objectID = null)
|
||||
{
|
||||
$oldObject = clone $object;
|
||||
/* Get full object when desc is empty. */
|
||||
if(!isset($object->description) || (isset($object->description) && $object->description == '')) $object = $this->loadModel($objectType)->getByID($objectID);
|
||||
foreach($oldObject as $index => $attribute)
|
||||
{
|
||||
if($index != 'description') $object->$index = $attribute;
|
||||
}
|
||||
|
||||
if(!isset($object->id) && !empty($objectID)) $object->id = $objectID;
|
||||
$issue = $this->parseObjectToIssue($gitlabID, $projectID, $objectType, $object);
|
||||
$apiRoot = $this->getApiRoot($gitlabID);
|
||||
$url = sprintf($apiRoot, "/projects/{$projectID}/issues/{$issueID}");
|
||||
@@ -868,6 +886,37 @@ class gitlabModel extends model
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete project relation.
|
||||
*
|
||||
* condition: when user deleting a repo.
|
||||
*
|
||||
* @param int $repoID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function deleteProjectRelation($repoID)
|
||||
{
|
||||
$repo = $this->dao->select('product,path as gitlabProjectID,client as gitlabID')->from(TABLE_REPO)
|
||||
->where('id')->eq($repoID)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetch();
|
||||
if(empty($repo)) return false;
|
||||
|
||||
$productIDList = explode(',', $repo->product);
|
||||
foreach($productIDList as $product)
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_RELATION)
|
||||
->where('product')->eq($product)
|
||||
->andWhere('AType')->eq('gitlab')
|
||||
->andWhere('BType')->eq('gitlabProject')
|
||||
->andWhere('relation')->eq('interrated')
|
||||
->andWhere('AID')->eq($repo->gitlabID)
|
||||
->andWhere('BID')->eq($repo->gitlabProjectID)
|
||||
->exec();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create webhook for zentao.
|
||||
*
|
||||
@@ -919,7 +968,7 @@ class gitlabModel extends model
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function saveSyncedIssue($objectType, $object, $gitlabID, $issue)
|
||||
public function saveIssueRelation($objectType, $object, $gitlabID, $issue)
|
||||
{
|
||||
if(empty($issue->iid) or empty($issue->project_id)) return false;
|
||||
|
||||
@@ -957,7 +1006,7 @@ class gitlabModel extends model
|
||||
$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);
|
||||
$this->saveIssueRelation($objectType, $object, $gitlabID, $issue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1133,7 +1182,7 @@ class gitlabModel extends model
|
||||
|
||||
/* Append this object link in zentao to gitlab issue description */
|
||||
$zentaoLink = common::getSysURL() . helper::createLink($objectType, 'view', "id={$object->id}");
|
||||
$issue->description = $issue->description . "\n\n" . $zentaoLink;
|
||||
if(strpos($issue->description, $zentaoLink) == false) $issue->description = $issue->description . "\n\n" . $zentaoLink;
|
||||
|
||||
return $issue;
|
||||
}
|
||||
@@ -1162,12 +1211,14 @@ class gitlabModel extends model
|
||||
list($gitlabField, $optionType, $options) = explode('|', $config);
|
||||
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 == 'fields') $value = $issue->$gitlabField; // TODO(dingguodong) not implemented.
|
||||
if($options == 'date') $value = $value ? date('Y-m-d', strtotime($value)) : '0000-00-00';
|
||||
if($options == 'datetime') $value = $value ? date('Y-m-d H:i:s', strtotime($value)) : '0000-00-00 00:00:00';
|
||||
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;
|
||||
|
||||
if($gitlabField == "description") $object->$zentaoField .= "<br>" . $issue->web_url;
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<td class='c-actions text-left'>
|
||||
<?php
|
||||
common::printIcon('gitlab', 'edit', "gitlabID=$id", '', 'list', 'edit');
|
||||
common::printIcon('gitlab', 'binduser', "id=$id", '', 'list', 'group');
|
||||
common::printIcon('gitlab', 'bindUser', "id=$id", '', 'list', 'group');
|
||||
if(common::hasPriv('gitlab', 'delete')) echo html::a($this->createLink('gitlab', 'delete', "gitlabID=$id"), '<i class="icon-trash"></i>', 'hiddenwin', "title='{$lang->gitlab->delete}' class='btn'");
|
||||
?>
|
||||
</td>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<div class="main-header">
|
||||
<h2><?php echo $lang->gitlab->importIssue;?></h2>
|
||||
</div>
|
||||
<?php if($importable): ?>
|
||||
<form method='post' class='load-indicator main-form form-ajax' enctype='multipart/form-data'>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-borderless">
|
||||
@@ -46,8 +47,11 @@
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
<?php else:?>
|
||||
<?php echo $lang->gitlab->noImportableIssues; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
Reference in New Issue
Block a user