diff options
Diffstat (limited to 'bridges/BugzillaBridge.php')
-rw-r--r-- | bridges/BugzillaBridge.php | 364 |
1 files changed, 187 insertions, 177 deletions
diff --git a/bridges/BugzillaBridge.php b/bridges/BugzillaBridge.php index 16ce4a28..a7fc75b8 100644 --- a/bridges/BugzillaBridge.php +++ b/bridges/BugzillaBridge.php @@ -1,180 +1,190 @@ <?php -class BugzillaBridge extends BridgeAbstract { - const NAME = 'Bugzilla Bridge'; - const URI = 'https://www.bugzilla.org/'; - const DESCRIPTION = 'Bridge for any Bugzilla instance'; - const MAINTAINER = 'Yaman Qalieh'; - const PARAMETERS = array( - 'global' => array( - 'instance' => array( - 'name' => 'Instance URL', - 'required' => true, - 'exampleValue' => 'https://bugzilla.mozilla.org' - ) - ), - 'Bug comments' => array( - 'id' => array( - 'name' => 'Bug tracking ID', - 'type' => 'number', - 'required' => true, - 'title' => 'Insert bug tracking ID', - 'exampleValue' => 121241 - ), - 'limit' => array( - 'name' => 'Number of comments to return', - 'type' => 'number', - 'required' => false, - 'title' => 'Specify number of comments to return', - 'defaultValue' => -1 - ), - 'skiptags' => array( - 'name' => 'Skip offtopic comments', - 'type' => 'checkbox', - 'title' => 'Excludes comments tagged as advocacy, metoo, or offtopic from the feed' - ) - ) - ); - - const SKIPPED_ACTIVITY = array( - 'cc' => true, - 'comment_tag' => true - ); - - const SKIPPED_TAGS = array('advocacy', 'metoo', 'offtopic'); - - private $instance; - private $bugid; - private $buguri; - private $title; - - public function getName() { - if (!is_null($this->title)) { - return $this->title; - } - return parent::getName(); - } - - public function getURI() { - return $this->buguri ?? parent::getURI(); - } - - public function collectData() { - $this->instance = rtrim($this->getInput('instance'), '/'); - $this->bugid = $this->getInput('id'); - $this->buguri = $this->instance . '/show_bug.cgi?id=' . $this->bugid; - - $url = $this->instance . '/rest/bug/' . $this->bugid; - $this->getTitle($url); - $this->collectComments($url . '/comment'); - $this->collectUpdates($url . '/history'); - - usort($this->items, function($a, $b) { - return $b['timestamp'] <=> $a['timestamp']; - }); - - if ($this->getInput('limit') > 0) { - $this->items = array_slice($this->items, 0, $this->getInput('limit')); - } - } - - protected function getTitle($url) { - // Only request the summary for a faster request - $json = json_decode(getContents($url . '?include_fields=summary'), true); - $this->title = 'Bug ' . $this->bugid . ' - ' . - $json['bugs'][0]['summary'] . ' - ' . - // Remove https:// - substr($this->instance, 8); - } - - protected function collectComments($url) { - $json = json_decode(getContents($url), true); - - // Array of comments is here - if (!isset($json['bugs'][$this->bugid]['comments'])) { - returnClientError('Cannot find REST endpoint'); - } - - foreach($json['bugs'][$this->bugid]['comments'] as $comment) { - $item = array(); - if ($this->getInput('skiptags') and - array_intersect(self::SKIPPED_TAGS, $comment['tags'])) { - continue; - } - $item['categories'] = $comment['tags']; - $item['uri'] = $this->buguri . '#c' . $comment['count']; - $item['title'] = 'Comment ' . $comment['count']; - $item['timestamp'] = $comment['creation_time']; - $item['author'] = $this->getUser($comment['creator']); - $item['content'] = $comment['text']; - if (isset($comment['is_markdown']) and $comment['is_markdown']) { - $item['content'] = markdownToHtml($item['content']); - } - if (!is_null($comment['attachment_id'])) { - $item['enclosures'] = array($this->instance . '/attachment.cgi?id=' . $comment['attachment_id']); - } - $this->items[] = $item; - } - } - - protected function collectUpdates($url) { - $json = json_decode(getContents($url), true); - - // Array of changesets which contain an array of changes - if (!isset($json['bugs']['0']['history'])) { - returnClientError('Cannot find REST endpoint'); - } - - foreach($json['bugs']['0']['history'] as $changeset) { - $author = $this->getUser($changeset['who']); - $timestamp = $changeset['when']; - foreach($changeset['changes'] as $change) { - // Skip updates to the cc list and comment tagging - if (isset(self::SKIPPED_ACTIVITY[$change['field_name']])) { - continue; - } - - $item = array(); - $item['uri'] = $this->buguri; - $item['title'] = 'Updated'; - $item['timestamp'] = $timestamp; - $item['author'] = $author; - $item['content'] = ucfirst($change['field_name']) . ': ' . - ($change['removed'] === '' ? '[nothing]' : $change['removed']) . ' -> ' . - ($change['added'] === '' ? '[nothing]' : $change['added']); - $this->items[] = $item; - } - } - } - - protected function getUser($user) { - // Check if the user endpoint is available - if ($this->loadCacheValue($this->instance . 'userEndpointClosed')) { - return $user; - } - - $cache = $this->loadCacheValue($this->instance . $user); - if (!is_null($cache)) { - return $cache; - } - - $url = $this->instance . '/rest/user/' . $user . '?include_fields=real_name'; - try { - $json = json_decode(getContents($url), true); - if (isset($json['error']) and $json['error']) { - throw new Exception; - } - } catch (Exception $e) { - $this->saveCacheValue($this->instance . 'userEndpointClosed', true); - return $user; - } - - $username = $json['users']['0']['real_name']; - - if (empty($username)) { - $username = $user; - } - $this->saveCacheValue($this->instance . $user, $username); - return $username; - } +class BugzillaBridge extends BridgeAbstract +{ + const NAME = 'Bugzilla Bridge'; + const URI = 'https://www.bugzilla.org/'; + const DESCRIPTION = 'Bridge for any Bugzilla instance'; + const MAINTAINER = 'Yaman Qalieh'; + const PARAMETERS = [ + 'global' => [ + 'instance' => [ + 'name' => 'Instance URL', + 'required' => true, + 'exampleValue' => 'https://bugzilla.mozilla.org' + ] + ], + 'Bug comments' => [ + 'id' => [ + 'name' => 'Bug tracking ID', + 'type' => 'number', + 'required' => true, + 'title' => 'Insert bug tracking ID', + 'exampleValue' => 121241 + ], + 'limit' => [ + 'name' => 'Number of comments to return', + 'type' => 'number', + 'required' => false, + 'title' => 'Specify number of comments to return', + 'defaultValue' => -1 + ], + 'skiptags' => [ + 'name' => 'Skip offtopic comments', + 'type' => 'checkbox', + 'title' => 'Excludes comments tagged as advocacy, metoo, or offtopic from the feed' + ] + ] + ]; + + const SKIPPED_ACTIVITY = [ + 'cc' => true, + 'comment_tag' => true + ]; + + const SKIPPED_TAGS = ['advocacy', 'metoo', 'offtopic']; + + private $instance; + private $bugid; + private $buguri; + private $title; + + public function getName() + { + if (!is_null($this->title)) { + return $this->title; + } + return parent::getName(); + } + + public function getURI() + { + return $this->buguri ?? parent::getURI(); + } + + public function collectData() + { + $this->instance = rtrim($this->getInput('instance'), '/'); + $this->bugid = $this->getInput('id'); + $this->buguri = $this->instance . '/show_bug.cgi?id=' . $this->bugid; + + $url = $this->instance . '/rest/bug/' . $this->bugid; + $this->getTitle($url); + $this->collectComments($url . '/comment'); + $this->collectUpdates($url . '/history'); + + usort($this->items, function ($a, $b) { + return $b['timestamp'] <=> $a['timestamp']; + }); + + if ($this->getInput('limit') > 0) { + $this->items = array_slice($this->items, 0, $this->getInput('limit')); + } + } + + protected function getTitle($url) + { + // Only request the summary for a faster request + $json = json_decode(getContents($url . '?include_fields=summary'), true); + $this->title = 'Bug ' . $this->bugid . ' - ' . + $json['bugs'][0]['summary'] . ' - ' . + // Remove https:// + substr($this->instance, 8); + } + + protected function collectComments($url) + { + $json = json_decode(getContents($url), true); + + // Array of comments is here + if (!isset($json['bugs'][$this->bugid]['comments'])) { + returnClientError('Cannot find REST endpoint'); + } + + foreach ($json['bugs'][$this->bugid]['comments'] as $comment) { + $item = []; + if ( + $this->getInput('skiptags') and + array_intersect(self::SKIPPED_TAGS, $comment['tags']) + ) { + continue; + } + $item['categories'] = $comment['tags']; + $item['uri'] = $this->buguri . '#c' . $comment['count']; + $item['title'] = 'Comment ' . $comment['count']; + $item['timestamp'] = $comment['creation_time']; + $item['author'] = $this->getUser($comment['creator']); + $item['content'] = $comment['text']; + if (isset($comment['is_markdown']) and $comment['is_markdown']) { + $item['content'] = markdownToHtml($item['content']); + } + if (!is_null($comment['attachment_id'])) { + $item['enclosures'] = [$this->instance . '/attachment.cgi?id=' . $comment['attachment_id']]; + } + $this->items[] = $item; + } + } + + protected function collectUpdates($url) + { + $json = json_decode(getContents($url), true); + + // Array of changesets which contain an array of changes + if (!isset($json['bugs']['0']['history'])) { + returnClientError('Cannot find REST endpoint'); + } + + foreach ($json['bugs']['0']['history'] as $changeset) { + $author = $this->getUser($changeset['who']); + $timestamp = $changeset['when']; + foreach ($changeset['changes'] as $change) { + // Skip updates to the cc list and comment tagging + if (isset(self::SKIPPED_ACTIVITY[$change['field_name']])) { + continue; + } + + $item = []; + $item['uri'] = $this->buguri; + $item['title'] = 'Updated'; + $item['timestamp'] = $timestamp; + $item['author'] = $author; + $item['content'] = ucfirst($change['field_name']) . ': ' . + ($change['removed'] === '' ? '[nothing]' : $change['removed']) . ' -> ' . + ($change['added'] === '' ? '[nothing]' : $change['added']); + $this->items[] = $item; + } + } + } + + protected function getUser($user) + { + // Check if the user endpoint is available + if ($this->loadCacheValue($this->instance . 'userEndpointClosed')) { + return $user; + } + + $cache = $this->loadCacheValue($this->instance . $user); + if (!is_null($cache)) { + return $cache; + } + + $url = $this->instance . '/rest/user/' . $user . '?include_fields=real_name'; + try { + $json = json_decode(getContents($url), true); + if (isset($json['error']) and $json['error']) { + throw new Exception(); + } + } catch (Exception $e) { + $this->saveCacheValue($this->instance . 'userEndpointClosed', true); + return $user; + } + + $username = $json['users']['0']['real_name']; + + if (empty($username)) { + $username = $user; + } + $this->saveCacheValue($this->instance . $user, $username); + return $username; + } } |