refactor guthub api
[pharext/pharext.org] / app / Github / API.php
1 <?php
2
3 namespace app\Github;
4
5 use app\Github\API;
6 use app\Github\Storage;
7 use app\Github\Exception;
8
9 use merry\Config;
10
11 use http\Client;
12 use http\QueryString;
13 use http\Url;
14
15 class API
16 {
17 /**
18 * @var Client
19 */
20 private $client;
21
22 /**
23 * @var Storage
24 */
25 private $tokens;
26
27 /**
28 * @var Storage
29 */
30 private $cache;
31
32 /**
33 * @var merry\Config
34 */
35 private $config;
36
37 function __construct(Config $config, Storage $tokens = null, Storage $cache = null) {
38 $this->config = $config;
39 $this->client = new Client;
40 $this->tokens = $tokens ?: new Storage\Session;
41 $this->cache = $cache;
42 }
43
44 function getConfig() {
45 return $this->config;
46 }
47
48 function getClient() {
49 return $this->client;
50 }
51
52 function getTokenStorage() {
53 return $this->tokens;
54 }
55
56 function getCacheStorage() {
57 return $this->cache;
58 }
59
60 function getCacheKey($ident, $page = null) {
61 return sprintf("%s:%s:%s", $this->getToken(), $ident, $page ?: 1);
62 }
63
64 function hasToken() {
65 return $this->tokens->get("access_token");
66 }
67
68 function setToken($token) {
69 $this->tokens->set("access_token", $token,
70 $this->config->storage->token->ttl);
71 }
72
73 function getToken() {
74 if ($this->tokens->get("access_token", $token, $ttl, true)) {
75 return $token;
76 }
77 if (isset($ttl)) {
78 throw new Exception\TokenExpired($ttl);
79 }
80 throw new Exception\TokenNotSet;
81 }
82
83 function dropToken() {
84 $this->tokens->del("access_token");
85 }
86
87 function getAuthUrl($callback_url) {
88 $state = base64_encode(openssl_random_pseudo_bytes(24));
89 $this->tokens->set("state", $state, 5*60);
90 $param = [
91 "state" => $state,
92 "client_id" => $this->config->client->id,
93 "scope" => $this->config->client->scope,
94 "redirect_uri" => $callback_url,
95 ];
96 return new Url("https://github.com/login/oauth/authorize", [
97 "query" => new QueryString($param)
98 ], 0);
99 }
100
101 function fetchToken($code, $state, callable $callback) {
102 if (!$this->tokens->get("state", $orig_state, $ttl, true)) {
103 if (isset($ttl)) {
104 throw new Exception\StateExpired($ttl);
105 }
106 throw new Exception\StateNotSet;
107 }
108 if ($state !== $orig_state) {
109 throw new Exception\StateMismatch($orig_state, $state);
110 }
111
112 $call = new API\Users\ReadAuthToken($this, [
113 "code" => $code,
114 "client_id" => $this->config->client->id,
115 "client_secret" => $this->config->client->secret,
116 ]);
117 return $call($callback);
118 }
119
120 function fetchUser(callable $callback) {
121 $call = new API\Users\ReadAuthUser($this);
122 return $call($callback);
123 }
124
125 function fetchRepos($page, callable $callback) {
126 $call = new API\Repos\ListRepos($this, compact("page"));
127 return $call($callback);
128 }
129
130 function fetchRepo($repo, callable $callback) {
131 $call = new API\Repos\ReadRepo($this, compact("repo"));
132 return $call($callback);
133 }
134
135 function fetchHooks($repo, callable $callback) {
136 $call = new API\Hooks\ListHooks($this, compact("repo"));
137 return $call($callback);
138 }
139
140 function fetchReleases($repo, $page, callable $callback) {
141 $call = new API\Releases\ListReleases($this, compact("repo", "page"));
142 return $call($callback);
143 }
144
145 function fetchTags($repo, $page, callable $callback) {
146 $call = new API\Tags\ListTags($this, compact("repo", "page"));
147 return $call($callback);
148 }
149
150 function fetchContents($repo, $path, callable $callback) {
151 $call = new API\Repos\ReadContents($this, compact("repo", "path"));
152 return $call($callback);
153 }
154
155 function createRepoHook($repo, $conf, callable $callback) {
156 $call = new API\Hooks\CreateHook($this, compact("repo", "conf"));
157 return $call($callback);
158 }
159
160 function updateRepoHook($repo, $id, $conf, callable $callback) {
161 $call = new API\Hooks\UpdateHook($this, compact("repo", "id", "conf"));
162 return $call($callback);
163 }
164
165 function deleteRepoHook($repo, $id, callable $callback) {
166 $call = new API\Hooks\DeleteHook($this, compact("repo", "id"));
167 return $call($callback);
168 }
169
170 function createRelease($repo, $tag, callable $callback) {
171 $call = new API\Releases\CreateRelease($this, compact("repo", "tag"));
172 return $call($callback);
173 }
174
175 function createReleaseAsset($url, $asset, $type, callable $callback) {
176 $call = new API\Releases\CreateReleaseAsset($this, compact("url", "asset", "type"));
177 return $call($callback);
178 }
179 }