diff --git a/module/mr/lang/en.php b/module/mr/lang/en.php
index 981fba87a3..6f0481758e 100644
--- a/module/mr/lang/en.php
+++ b/module/mr/lang/en.php
@@ -29,6 +29,7 @@ $lang->mr->approval = 'Approval';
$lang->mr->approve = 'Approve';
$lang->mr->reject = 'Reject';
$lang->mr->close = 'Close';
+$lang->mr->reopen = 'Reopen';
$lang->mr->approvalResult = 'Approval result';
$lang->mr->approvalResultList = array();
diff --git a/module/mr/lang/zh-cn.php b/module/mr/lang/zh-cn.php
index 359efd5d42..1c6f42ee60 100644
--- a/module/mr/lang/zh-cn.php
+++ b/module/mr/lang/zh-cn.php
@@ -29,6 +29,7 @@ $lang->mr->approval = '评审';
$lang->mr->approve = '通过';
$lang->mr->reject = '拒绝';
$lang->mr->close = '关闭';
+$lang->mr->reopen = '重新打开';
$lang->mr->approvalResult = '评审意见';
$lang->mr->approvalResultList = array();
diff --git a/module/mr/lang/zh-tw.php b/module/mr/lang/zh-tw.php
index fd8e461842..abcbb01875 100644
--- a/module/mr/lang/zh-tw.php
+++ b/module/mr/lang/zh-tw.php
@@ -29,6 +29,7 @@ $lang->mr->approval = '評審';
$lang->mr->approve = '通過';
$lang->mr->reject = '拒絕';
$lang->mr->close = '關閉';
+$lang->mr->reopen = '重新打開';
$lang->mr->approvalResult = '評審意見';
$lang->mr->approvalResultList = array();
diff --git a/module/mr/model.php b/module/mr/model.php
index f8dd1d001b..76776302ef 100644
--- a/module/mr/model.php
+++ b/module/mr/model.php
@@ -445,6 +445,38 @@ class mrModel extends model
return json_decode(commonModel::http($url, null, array(CURLOPT_CUSTOMREQUEST => 'DELETE')));
}
+ /**
+ * Close MR by API.
+ *
+ * @docs https://docs.gitlab.com/ee/api/merge_requests.html#update-mr
+ * @param int $gitlabID
+ * @param int $projectID
+ * @param int $MRID
+ * @access public
+ * @return object
+ */
+ public function apiCloseMR($gitlabID, $projectID, $MRID)
+ {
+ $url = sprintf($this->gitlab->getApiRoot($gitlabID), "/projects/$projectID/merge_requests/$MRID") . '&state_event=close';
+ return json_decode(commonModel::http($url, null, array(CURLOPT_CUSTOMREQUEST => 'PUT')));
+ }
+
+ /**
+ * Reopen MR by API.
+ *
+ * @docs https://docs.gitlab.com/ee/api/merge_requests.html#update-mr
+ * @param int $gitlabID
+ * @param int $projectID
+ * @param int $MRID
+ * @access public
+ * @return object
+ */
+ public function apiReopenMR($gitlabID, $projectID, $MRID)
+ {
+ $url = sprintf($this->gitlab->getApiRoot($gitlabID), "/projects/$projectID/merge_requests/$MRID") . '&state_event=reopen';
+ return json_decode(commonModel::http($url, null, array(CURLOPT_CUSTOMREQUEST => 'PUT')));
+ }
+
/**
* Accept MR by API.
*
@@ -653,4 +685,40 @@ class mrModel extends model
}
return array('result' => 'fail', 'message' => $this->lang->mr->repeatedOperation, 'locate' => helper::createLink('mr', 'view', "mr={$MR->id}"));
}
+
+ /**
+ * Close this MR.
+ *
+ * @param mixed $MR
+ * @return void
+ */
+ public function close($MR)
+ {
+ $this->loadModel('action');
+ $actionID = $this->action->create('mr', $MR->id, 'close');
+ $rawMR = $this->apiCloseMR($MR->gitlabID, $MR->targetProject, $MR->mriid);
+ $changes = common::createChanges($MR, $rawMR);
+ $this->action->logHistory($actionID, $changes);
+ if(isset($rawMR->state) and $rawMR->state == 'closed') return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => helper::createLink('mr', 'view', "mr={$MR->id}"));
+ return array('result' => 'fail', 'message' => $this->lang->fail, 'locate' => helper::createLink('mr', 'view', "mr={$MR->id}"));
+ }
+
+ /**
+ * Reopen this MR.
+ *
+ * @param mixed $MR
+ * @return void
+ */
+ public function reopen($MR)
+ {
+ $this->loadModel('action');
+ $actionID = $this->action->create('mr', $MR->id, 'reopen');
+ $rawMR = $this->apiReopenMR($MR->gitlabID, $MR->targetProject, $MR->mriid);
+ $changes = common::createChanges($MR, $rawMR);
+ $this->action->logHistory($actionID, $changes);
+ if(isset($rawMR->state) and $rawMR->state == 'opened') return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => helper::createLink('mr', 'view', "mr={$MR->id}"));
+ return array('result' => 'fail', 'message' => $this->lang->fail, 'locate' => helper::createLink('mr', 'view', "mr={$MR->id}"));
+ }
+
}
+
diff --git a/module/mr/view/view.html.php b/module/mr/view/view.html.php
index cec441fd2f..3a5d4ba74d 100644
--- a/module/mr/view/view.html.php
+++ b/module/mr/view/view.html.php
@@ -48,13 +48,14 @@
- state == 'opened' and !$rawMR->has_conflicts) : ?>
- id"), ' ' . $lang->mr->acceptMR, '', "id='mergeButton' class='btn'"); ?>
+ state == 'opened' and !$rawMR->has_conflicts) echo html::a(inlink('accept', "mr=$MR->id"), ' ' . $lang->mr->acceptMR, '', "id='mergeButton' class='btn'"); ?>
+ state == 'opened'): ?>
id&action=approve&onlybody=yes"), ' ' . $lang->mr->approve, '', "id='mergeButton' class='btn'"); ?>
id&action=reject&onlybody=yes"), ' ' . $lang->mr->reject, '', "id='mergeButton' class='btn'"); ?>
id"), ' ' . $lang->mr->close, '', "id='mergeButton' class='btn'"); ?>
id"), ' ' . str_replace($lang->mr->common, '', $lang->mr->edit), '', "id='mergeButton' class='btn'"); ?>
+ state == 'closed') echo html::a(inlink('reopen', "mr=$MR->id"), ' ' . $lang->mr->reopen, '', "id='mergeButton' class='btn'"); ?>
id"), ' ' . str_replace($lang->mr->common, '', $lang->mr->delete), '', "id='mergeButton' class='btn'"); ?>