1<?php 2 3namespace App\Utils; 4 5/** 6 * GitHub pull requests tracker client. 7 */ 8class GitHub 9{ 10 /** 11 * Database handler. 12 * @var \PDO 13 */ 14 private $dbh; 15 16 /** 17 * API URL. 18 */ 19 private $url = 'https://api.github.com'; 20 21 /** 22 * User agent string when establishing stream context with remote GitHub URL. 23 */ 24 private $userAgent = 'bugs.php.net Pulltracker'; 25 26 /** 27 * Username or organization name on GitHub. 28 */ 29 private $organization = 'php'; 30 31 /** 32 * Class constructor 33 */ 34 public function __construct(\PDO $dbh) 35 { 36 $this->dbh = $dbh; 37 } 38 39 /** 40 * Retrieve data from remote GitHub URL. 41 */ 42 private function getDataFromGithub(string $repo, int $pullId) 43 { 44 $context = stream_context_create([ 45 'http' => [ 46 'ignore_errors' => '1', 47 'user_agent' => $this->userAgent, 48 ] 49 ]); 50 51 $url = $this->url.'/repos/'.$this->organization.'/'.urlencode($repo).'/pulls/'.$pullId; 52 $data = @json_decode(file_get_contents($url, null, $context)); 53 54 if (!is_object($data)) { 55 return false; 56 } 57 58 return $data; 59 } 60 61 /** 62 * Attach a pull request to bug. 63 */ 64 public function attach($bugId, $repo, $pullId, $developer) 65 { 66 $data = $this->getDataFromGithub($repo, (int)$pullId); 67 68 if (!$data) { 69 throw new \Exception('Failed to retrieve pull request from GitHub'); 70 } 71 72 $sql = 'INSERT INTO bugdb_pulls 73 (bugdb_id, github_repo, github_pull_id, github_title, github_html_url, developer) 74 VALUES (?, ?, ?, ?, ?, ?) 75 '; 76 77 $arguments = [ 78 $bugId, 79 $repo, 80 $pullId, 81 $data->title, 82 $data->html_url, 83 $developer, 84 ]; 85 86 $this->dbh->prepare($sql)->execute($arguments); 87 88 return $data; 89 } 90 91 /** 92 * Remove a pull request from given bug. 93 */ 94 public function detach(int $bugId, string $repo, int $pullId) 95 { 96 $sql = 'DELETE FROM bugdb_pulls 97 WHERE bugdb_id = ? AND github_repo = ? AND github_pull_id = ? 98 '; 99 100 $this->dbh->prepare($sql)->execute([$bugId, $repo, $pullId]); 101 } 102} 103