6 use app\Github\Storage
;
7 use app\Github\Exception
;
16 use Psr\Log\LoggerInterface
;
46 * @var \Psr\Log\LoggerInterface;
56 function __construct(Config
$config, LoggerInterface
$logger, Storage
$tokens = null, Storage
$cache = null) {
57 $this->logger
= $logger;
58 $this->config
= $config;
59 $this->client
= new Client("curl", "github");
60 $this->client
->configure($config->http
->configure
->toArray());
61 $this->client
->attach(new ClientObserver($logger));
62 $this->tokens
= $tokens ?
: new Storage\Session
;
63 $this->cache
= $cache;
67 * Set maximum acceptable age of cache items
70 function setMaxAge($seconds) {
71 $this->maxAge
= $seconds;
75 function getMaxAge() {
79 function getLogger() {
83 function getConfig() {
87 function getClient() {
91 function getTokenStorage() {
95 function getCacheStorage() {
99 function getCacheKey($ident, $page = null) {
100 return sprintf("%s:%s:%s", $this->getToken(), $ident, $page ?
: 1);
103 function hasToken() {
104 if ($this->tokens
->get("access_token", $token)) {
105 $access_token = $token->getValue();
106 if (isset($access_token)) {
114 function setToken($token) {
115 $this->tokens
->set("access_token", new Storage\
Item(
117 $this->config
->storage
->token
->ttl
121 function getToken() {
122 if ($this->tokens
->get("access_token", $token, true)) {
123 return $token->getValue();
126 $this->logger
->notice("Token expired", $token);
127 throw new Exception\
TokenExpired($token->getLTL());
129 throw new Exception\TokenNotSet
;
132 function dropToken() {
133 $this->tokens
->del("access_token");
136 function getAuthUrl($callback_url) {
137 $state = base64_encode(openssl_random_pseudo_bytes(24));
138 $this->tokens
->set("state", new Storage\
Item($state, 5*60));
141 "client_id" => $this->config
->client
->id
,
142 "scope" => $this->config
->client
->scope
,
143 "redirect_uri" => (string) $callback_url,
145 return new Url("https://github.com/login/oauth/authorize", [
146 "query" => new QueryString($param)
150 function fetchToken($code, $state) {
151 if (!$this->tokens
->get("state", $orig_state, true)) {
152 if (isset($orig_state)) {
153 $this->logger
->notice("State expired", compact("state", "orig_state"));
154 throw new Exception\
StateExpired($orig_state->getLTL());
156 throw new Exception\StateNotSet
;
158 if ($state !== $orig_state->getValue()) {
159 $this->logger
->warning("State mismatch", compact("state", "orig_state"));
160 throw new Exception\
StateMismatch($orig_state->getValue(), $state);
163 return $this->queue(new API\Users\
ReadAuthToken($this, [
165 "client_id" => $this->config
->client
->id
,
166 "client_secret" => $this->config
->client
->secret
,
170 function queue(API\Call
$call) {
171 return $this->queue
[] = $call();
175 $queue = $this->queue
;
176 $this->queue
= array();
177 $this->client
->send();
181 function readAuthUser() {
182 return $this->queue(new API\Users\
ReadAuthUser($this));
185 function listRepos($page) {
186 return $this->queue(new API\Repos\
ListRepos($this, compact("page")));
189 function readRepo($repo) {
190 return $this->queue(new API\Repos\
ReadRepo($this, compact("repo")));
194 * Check if the pharext webhook is set and return it
195 * @param array $hooks
196 * @return stdClass hook
198 function checkHook($hooks) {
199 if (!empty($hooks)) {
200 foreach ($hooks as $hook) {
201 if ($hook->name
=== "web" && $hook->config
->url
=== $this->config
->hook
->url
) {
210 * Check if the pharext webhook is set for the repo and return it
211 * @param object $repo
212 * @return stdClass hook
214 function checkRepoHook($repo) {
215 if (!empty($repo->hooks
)) {
216 return $this->checkHook($repo->hooks
);
221 function listHooks($repo) {
222 return $this->queue(new API\Hooks\
ListHooks($this, compact("repo")));
225 function listReleases($repo, $page) {
226 return $this->queue(new API\Releases\
ListReleases($this, compact("repo", "page")));
229 function listTags($repo, $page) {
230 return $this->queue(new API\Tags\
ListTags($this, compact("repo", "page")));
233 function readContents($repo, $path = null) {
234 return $this->queue(new API\Repos\
ReadContents($this, compact("repo", "path")));
237 function createRepoHook($repo, $conf) {
238 return $this->queue(new API\Hooks\
CreateHook($this, compact("repo", "conf")));
241 function updateRepoHook($repo, $id, $conf) {
242 return $this->queue(new API\Hooks\
UpdateHook($this, compact("repo", "id", "conf")));
245 function deleteRepoHook($repo, $id) {
246 return $this->queue(new API\Hooks\
DeleteHook($this, compact("repo", "id")));
249 function createRelease($repo, $tag) {
250 return $this->queue(new API\Releases\
CreateRelease($this, compact("repo", "tag")));
253 function publishRelease($repo, $id, $tag) {
254 return $this->queue(new API\Releases\
PublishRelease($this, compact("repo", "id", "tag")));
257 function createReleaseAsset($url, $asset, $type) {
258 return $this->queue(new API\Releases\
CreateReleaseAsset($this, compact("url", "asset", "type")));
261 function listReleaseAssets($repo, $id) {
262 return $this->queue(new API\Releases\
ListReleaseAssets($this, compact("repo", "id")));
265 function uploadAssetForRelease($repo, $release, $config = null) {
266 return $this->listHooks($repo->full_name
)->then(function($result) use($release, $repo, $config) {
267 list($repo->hooks
) = $result;
268 $phar = new Pharext\
Package(
272 $config ?
: (array) $this->checkRepoHook($repo)->config
274 $name = $phar->build();
275 $url = uri_template($release->upload_url
, compact("name"));
276 $promise = $this->createReleaseAsset($url, $phar, "application/phar");
277 if ($release->draft
) {
278 return $promise->then(function($result) use($release, $repo) {
279 return $this->publishRelease($repo->full_name
, $release->id
, $release->tag_name
);
286 function createReleaseFromTag($repo, $tag_name, $config = null) {
287 return $this->createRelease($repo->full_name
, $tag_name)->then(function($result) use($repo, $config) {
288 list($release) = $result;
289 return $this->uploadAssetForRelease($repo, $release, $config);