@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at upstream/main 386 lines 9.9 kB view raw
1<?php 2 3final class NuanceGitHubRawEvent extends Phobject { 4 5 private $raw; 6 private $type; 7 8 const TYPE_ISSUE = 'issue'; 9 const TYPE_REPOSITORY = 'repository'; 10 11 public static function newEvent($type, array $raw) { 12 $event = new self(); 13 $event->type = $type; 14 $event->raw = $raw; 15 return $event; 16 } 17 18 public function getRepositoryFullName() { 19 return $this->getRepositoryFullRawName(); 20 } 21 22 public function isIssueEvent() { 23 if ($this->isPullRequestEvent()) { 24 return false; 25 } 26 27 if ($this->type == self::TYPE_ISSUE) { 28 return true; 29 } 30 31 switch ($this->getIssueRawKind()) { 32 case 'IssuesEvent': 33 return true; 34 case 'IssueCommentEvent': 35 if (!$this->getRawPullRequestData()) { 36 return true; 37 } 38 break; 39 } 40 41 return false; 42 } 43 44 public function isPullRequestEvent() { 45 if ($this->type == self::TYPE_ISSUE) { 46 // TODO: This is wrong, some of these are pull events. 47 return false; 48 } 49 50 $raw = $this->raw; 51 52 switch ($this->getIssueRawKind()) { 53 case 'PullRequestEvent': 54 return true; 55 case 'IssueCommentEvent': 56 if ($this->getRawPullRequestData()) { 57 return true; 58 } 59 break; 60 } 61 62 return false; 63 } 64 65 public function getIssueNumber() { 66 if (!$this->isIssueEvent()) { 67 return null; 68 } 69 70 return $this->getRawIssueNumber(); 71 } 72 73 public function getPullRequestNumber() { 74 if (!$this->isPullRequestEvent()) { 75 return null; 76 } 77 78 return $this->getRawIssueNumber(); 79 } 80 81 82 public function getID() { 83 $raw = $this->raw; 84 85 $id = idx($raw, 'id'); 86 if ($id) { 87 return (int)$id; 88 } 89 90 return null; 91 } 92 93 public function getComment() { 94 if (!$this->isIssueEvent() && !$this->isPullRequestEvent()) { 95 return null; 96 } 97 98 $raw = $this->raw; 99 100 return idxv($raw, array('payload', 'comment', 'body')); 101 } 102 103 public function getURI() { 104 $raw = $this->raw; 105 106 if ($this->isIssueEvent() || $this->isPullRequestEvent()) { 107 if ($this->type == self::TYPE_ISSUE) { 108 $uri = idxv($raw, array('issue', 'html_url')); 109 $uri = $uri.'#event-'.$this->getID(); 110 } else { 111 // The format of pull request events varies so we need to fish around 112 // a bit to find the correct URI. 113 $uri = idxv($raw, array('payload', 'pull_request', 'html_url')); 114 $need_anchor = true; 115 116 // For comments, we get a different anchor to link to the comment. In 117 // this case, the URI comes with an anchor already. 118 if (!$uri) { 119 $uri = idxv($raw, array('payload', 'comment', 'html_url')); 120 $need_anchor = false; 121 } 122 123 if (!$uri) { 124 $uri = idxv($raw, array('payload', 'issue', 'html_url')); 125 $need_anchor = true; 126 } 127 128 if ($need_anchor) { 129 $uri = $uri.'#event-'.$this->getID(); 130 } 131 } 132 } else { 133 switch ($this->getIssueRawKind()) { 134 case 'CreateEvent': 135 $ref = idxv($raw, array('payload', 'ref')); 136 137 $repo = $this->getRepositoryFullRawName(); 138 return "https://github.com/{$repo}/commits/{$ref}"; 139 case 'PushEvent': 140 // These don't really have a URI since there may be multiple commits 141 // involved and GitHub doesn't bundle the push as an object on its 142 // own. Just try to find the URI for the log. The API also does 143 // not return any HTML URI for these events. 144 145 $head = idxv($raw, array('payload', 'head')); 146 if ($head === null) { 147 return null; 148 } 149 150 $repo = $this->getRepositoryFullRawName(); 151 return "https://github.com/{$repo}/commits/{$head}"; 152 case 'WatchEvent': 153 // These have no reasonable URI. 154 return null; 155 default: 156 return null; 157 } 158 } 159 160 return $uri; 161 } 162 163 private function getRepositoryFullRawName() { 164 $raw = $this->raw; 165 166 $full = idxv($raw, array('repo', 'name')); 167 if (phutil_nonempty_string($full)) { 168 return $full; 169 } 170 171 // For issue events, the repository is not identified explicitly in the 172 // response body. Parse it out of the URI. 173 174 $matches = null; 175 $ok = preg_match( 176 '(/repos/((?:[^/]+)/(?:[^/]+))/issues/events/)', 177 idx($raw, 'url'), 178 $matches); 179 180 if ($ok) { 181 return $matches[1]; 182 } 183 184 return null; 185 } 186 187 private function getIssueRawKind() { 188 $raw = $this->raw; 189 return idxv($raw, array('type')); 190 } 191 192 private function getRawIssueNumber() { 193 $raw = $this->raw; 194 195 if ($this->type == self::TYPE_ISSUE) { 196 return idxv($raw, array('issue', 'number')); 197 } 198 199 if ($this->type == self::TYPE_REPOSITORY) { 200 $issue_number = idxv($raw, array('payload', 'issue', 'number')); 201 if ($issue_number) { 202 return $issue_number; 203 } 204 205 $pull_number = idxv($raw, array('payload', 'number')); 206 if ($pull_number) { 207 return $pull_number; 208 } 209 } 210 211 return null; 212 } 213 214 private function getRawPullRequestData() { 215 $raw = $this->raw; 216 return idxv($raw, array('payload', 'issue', 'pull_request')); 217 } 218 219 public function getEventFullTitle() { 220 switch ($this->type) { 221 case self::TYPE_ISSUE: 222 $title = $this->getRawIssueEventTitle(); 223 break; 224 case self::TYPE_REPOSITORY: 225 $title = $this->getRawRepositoryEventTitle(); 226 break; 227 default: 228 $title = pht('Unknown Event Type ("%s")', $this->type); 229 break; 230 } 231 232 return pht( 233 'GitHub %s %s (%s)', 234 $this->getRepositoryFullRawName(), 235 $this->getTargetObjectName(), 236 $title); 237 } 238 239 public function getActorGitHubUserID() { 240 $raw = $this->raw; 241 return (int)idxv($raw, array('actor', 'id')); 242 } 243 244 private function getTargetObjectName() { 245 if ($this->isPullRequestEvent()) { 246 $number = $this->getRawIssueNumber(); 247 return pht('Pull Request #%d', $number); 248 } else if ($this->isIssueEvent()) { 249 $number = $this->getRawIssueNumber(); 250 return pht('Issue #%d', $number); 251 } else if ($this->type == self::TYPE_REPOSITORY) { 252 $raw = $this->raw; 253 254 255 $type = idx($raw, 'type'); 256 switch ($type) { 257 case 'CreateEvent': 258 $ref = idxv($raw, array('payload', 'ref')); 259 $ref_type = idxv($raw, array('payload', 'ref_type')); 260 261 switch ($ref_type) { 262 case 'branch': 263 return pht('Branch %s', $ref); 264 case 'tag': 265 return pht('Tag %s', $ref); 266 default: 267 return pht('Ref %s', $ref); 268 } 269 case 'PushEvent': 270 $ref = idxv($raw, array('payload', 'ref')); 271 if (preg_match('(^refs/heads/)', $ref)) { 272 return pht('Branch %s', substr($ref, strlen('refs/heads/'))); 273 } else { 274 return pht('Ref %s', $ref); 275 } 276 case 'WatchEvent': 277 $actor = idxv($raw, array('actor', 'login')); 278 return pht('User %s', $actor); 279 } 280 281 return pht('Unknown Object'); 282 } else { 283 return pht('Unknown Object'); 284 } 285 } 286 287 private function getRawIssueEventTitle() { 288 $raw = $this->raw; 289 290 $action = idxv($raw, array('event')); 291 switch ($action) { 292 case 'assigned': 293 $assignee = idxv($raw, array('assignee', 'login')); 294 $title = pht('Assigned: %s', $assignee); 295 break; 296 case 'closed': 297 $title = pht('Closed'); 298 break; 299 case 'demilestoned': 300 $milestone = idxv($raw, array('milestone', 'title')); 301 $title = pht('Removed Milestone: %s', $milestone); 302 break; 303 case 'labeled': 304 $label = idxv($raw, array('label', 'name')); 305 $title = pht('Added Label: %s', $label); 306 break; 307 case 'locked': 308 $title = pht('Locked'); 309 break; 310 case 'milestoned': 311 $milestone = idxv($raw, array('milestone', 'title')); 312 $title = pht('Added Milestone: %s', $milestone); 313 break; 314 case 'renamed': 315 $title = pht('Renamed'); 316 break; 317 case 'reopened': 318 $title = pht('Reopened'); 319 break; 320 case 'unassigned': 321 $assignee = idxv($raw, array('assignee', 'login')); 322 $title = pht('Unassigned: %s', $assignee); 323 break; 324 case 'unlabeled': 325 $label = idxv($raw, array('label', 'name')); 326 $title = pht('Removed Label: %s', $label); 327 break; 328 case 'unlocked': 329 $title = pht('Unlocked'); 330 break; 331 default: 332 $title = pht('"%s"', $action); 333 break; 334 } 335 336 337 return $title; 338 } 339 340 private function getRawRepositoryEventTitle() { 341 $raw = $this->raw; 342 343 $type = idx($raw, 'type'); 344 switch ($type) { 345 case 'CreateEvent': 346 return pht('Created'); 347 case 'PushEvent': 348 $head = idxv($raw, array('payload', 'head')); 349 $head = substr($head, 0, 12); 350 return pht('Pushed: %s', $head); 351 case 'IssuesEvent': 352 $action = idxv($raw, array('payload', 'action')); 353 switch ($action) { 354 case 'closed': 355 return pht('Closed'); 356 case 'opened': 357 return pht('Created'); 358 case 'reopened': 359 return pht('Reopened'); 360 default: 361 return pht('"%s"', $action); 362 } 363 case 'IssueCommentEvent': 364 $action = idxv($raw, array('payload', 'action')); 365 switch ($action) { 366 case 'created': 367 return pht('Comment'); 368 default: 369 return pht('"%s"', $action); 370 } 371 case 'PullRequestEvent': 372 $action = idxv($raw, array('payload', 'action')); 373 switch ($action) { 374 case 'opened': 375 return pht('Created'); 376 default: 377 return pht('"%s"', $action); 378 } 379 case 'WatchEvent': 380 return pht('Watched'); 381 } 382 383 return pht('"%s"', $type); 384 } 385 386}