diff options
Diffstat (limited to 'app/Integration/BitbucketWebhook.php')
-rw-r--r-- | app/Integration/BitbucketWebhook.php | 236 |
1 files changed, 225 insertions, 11 deletions
diff --git a/app/Integration/BitbucketWebhook.php b/app/Integration/BitbucketWebhook.php index eced5596..d9dc45b1 100644 --- a/app/Integration/BitbucketWebhook.php +++ b/app/Integration/BitbucketWebhook.php @@ -18,7 +18,12 @@ class BitbucketWebhook extends \Core\Base * * @var string */ - const EVENT_COMMIT = 'bitbucket.webhook.commit'; + const EVENT_COMMIT = 'bitbucket.webhook.commit'; + const EVENT_ISSUE_OPENED = 'bitbucket.webhook.issue.opened'; + const EVENT_ISSUE_CLOSED = 'bitbucket.webhook.issue.closed'; + const EVENT_ISSUE_REOPENED = 'bitbucket.webhook.issue.reopened'; + const EVENT_ISSUE_ASSIGNEE_CHANGE = 'bitbucket.webhook.issue.assignee'; + const EVENT_ISSUE_COMMENT = 'bitbucket.webhook.issue.commented'; /** * Project id @@ -40,19 +45,227 @@ class BitbucketWebhook extends \Core\Base } /** - * Parse events + * Parse incoming events * * @access public - * @param array $payload Gitlab event + * @param string $type Bitbucket event type + * @param array $payload Bitbucket event * @return boolean */ - public function parsePayload(array $payload) + public function parsePayload($type, array $payload) { - if (! empty($payload['commits'])) { + switch ($type) { + case 'issue:comment_created': + return $this->handleCommentCreated($payload); + case 'issue:created': + return $this->handleIssueOpened($payload); + case 'issue:updated': + return $this->handleIssueUpdated($payload); + case 'repo:push': + return $this->handlePush($payload); + } + + return false; + } + + /** + * Parse comment issue events + * + * @access public + * @param array $payload + * @return boolean + */ + public function handleCommentCreated(array $payload) + { + $task = $this->taskFinder->getByReference($this->project_id, $payload['issue']['id']); + + if (! empty($task)) { + + $user = $this->user->getByUsername($payload['actor']['username']); + + if (! empty($user) && ! $this->projectPermission->isMember($this->project_id, $user['id'])) { + $user = array(); + } + + $event = array( + 'project_id' => $this->project_id, + 'reference' => $payload['comment']['id'], + 'comment' => $payload['comment']['content']['raw']."\n\n[".t('By @%s on Bitbucket', $payload['actor']['display_name']).']('.$payload['comment']['links']['html']['href'].')', + 'user_id' => ! empty($user) ? $user['id'] : 0, + 'task_id' => $task['id'], + ); + + $this->container['dispatcher']->dispatch( + self::EVENT_ISSUE_COMMENT, + new GenericEvent($event) + ); + + return true; + } + + return false; + } + + /** + * Handle new issues + * + * @access public + * @param array $payload + * @return boolean + */ + public function handleIssueOpened(array $payload) + { + $event = array( + 'project_id' => $this->project_id, + 'reference' => $payload['issue']['id'], + 'title' => $payload['issue']['title'], + 'description' => $payload['issue']['content']['raw']."\n\n[".t('Bitbucket Issue').']('.$payload['issue']['links']['html']['href'].')', + ); + + $this->container['dispatcher']->dispatch( + self::EVENT_ISSUE_OPENED, + new GenericEvent($event) + ); + + return true; + } + + /** + * Handle issue updates + * + * @access public + * @param array $payload + * @return boolean + */ + public function handleIssueUpdated(array $payload) + { + $task = $this->taskFinder->getByReference($this->project_id, $payload['issue']['id']); + + if (empty($task)) { + return false; + } + + if (isset($payload['changes']['status'])) { + return $this->handleStatusChange($task, $payload); + } + else if (isset($payload['changes']['assignee'])) { + return $this->handleAssigneeChange($task, $payload); + } + + return false; + } + + /** + * Handle issue status change + * + * @access public + * @param array $task + * @param array $payload + * @return boolean + */ + public function handleStatusChange(array $task, array $payload) + { + $event = array( + 'project_id' => $this->project_id, + 'task_id' => $task['id'], + 'reference' => $payload['issue']['id'], + ); + + switch ($payload['issue']['state']) { + case 'closed': + $this->container['dispatcher']->dispatch(self::EVENT_ISSUE_CLOSED, new GenericEvent($event)); + return true; + case 'open': + $this->container['dispatcher']->dispatch(self::EVENT_ISSUE_REOPENED, new GenericEvent($event)); + return true; + } + + return false; + } + + /** + * Handle issue assignee change + * + * @access public + * @param array $task + * @param array $payload + * @return boolean + */ + public function handleAssigneeChange(array $task, array $payload) + { + if (empty($payload['issue']['assignee'])) { + return $this->handleIssueUnassigned($task, $payload); + } + + return $this->handleIssueAssigned($task, $payload); + } + + /** + * Handle issue assigned + * + * @access public + * @param array $task + * @param array $payload + * @return boolean + */ + public function handleIssueAssigned(array $task, array $payload) + { + $user = $this->user->getByUsername($payload['issue']['assignee']['username']); + + if (empty($user)) { + return false; + } + + if (! $this->projectPermission->isMember($this->project_id, $user['id'])) { + return false; + } + + $event = array( + 'project_id' => $this->project_id, + 'task_id' => $task['id'], + 'owner_id' => $user['id'], + 'reference' => $payload['issue']['id'], + ); + + $this->container['dispatcher']->dispatch(self::EVENT_ISSUE_ASSIGNEE_CHANGE, new GenericEvent($event)); + + return true; + } + + /** + * Handle issue unassigned + * + * @access public + * @param array $task + * @param array $payload + * @return boolean + */ + public function handleIssueUnassigned(array $task, array $payload) + { + $event = array( + 'project_id' => $this->project_id, + 'task_id' => $task['id'], + 'owner_id' => 0, + 'reference' => $payload['issue']['id'], + ); + + $this->container['dispatcher']->dispatch(self::EVENT_ISSUE_ASSIGNEE_CHANGE, new GenericEvent($event)); - foreach ($payload['commits'] as $commit) { + return true; + } - if ($this->handleCommit($commit)) { + /** + * Parse push events + * + * @access public + * @param array $payload + * @return boolean + */ + public function handlePush(array $payload) + { + if (isset($payload['push']['changes'])) { + foreach ($payload['push']['changes'] as $change) { + if (isset($change['new']['target']) && $this->handleCommit($change['new']['target'], $payload['actor'])) { return true; } } @@ -65,10 +278,11 @@ class BitbucketWebhook extends \Core\Base * Parse commit * * @access public - * @param array $commit Gitlab commit + * @param array $commit Bitbucket commit + * @param array $actor Bitbucket actor * @return boolean */ - public function handleCommit(array $commit) + public function handleCommit(array $commit, array $actor) { $task_id = $this->task->getTaskIdFromText($commit['message']); @@ -91,8 +305,8 @@ class BitbucketWebhook extends \Core\Base new GenericEvent(array( 'task_id' => $task_id, 'commit_message' => $commit['message'], - 'commit_url' => '', - 'commit_comment' => $commit['message']."\n\n".t('Commit made by @%s on Bitbucket', $commit['author']) + 'commit_url' => $commit['links']['html']['href'], + 'commit_comment' => $commit['message']."\n\n[".t('Commit made by @%s on Bitbucket', $actor['display_name']).']('.$commit['links']['html']['href'].')', ) + $task) ); |