"error" => $this->app->getRequest()->getQuery("error_description")
]);
} else {
- $this->github->fetchToken(
- $this->app->getRequest()->getQuery("code"),
- $this->app->getRequest()->getQuery("state")
- )->then(function($result) {
- list($oauth) = $result;
- $this->github->setToken($oauth->access_token);
- return $this->github->readAuthUser()->then(function($result) use($oauth) {
- list($user) = $result;
- return [$oauth, $user];
- });
- })->then(function($result) {
- list($oauth, $user) = $result;
- $tx = $this->accounts->getConnection()->startTransaction();
-
- if (($cookie = $this->app->getRequest()->getCookie("account"))) {
- $account = $this->accounts->find(["account=" => $cookie])->current();
- } elseif (!($account = $this->accounts->byOAuth("github", $oauth->access_token, $user->login))) {
- $account = $this->accounts->createOAuthAccount("github", $oauth->access_token, $user->login);
- }
- $token = $account->updateToken("github", $oauth->access_token, $oauth);
- $owner = $account->updateOwner("github", $user->login, $user);
-
- $tx->commit();
-
- $this->login($account, $token, $owner);
- })->done();
-
- $this->github->getClient()->send();
+ $this->validateUser();
if (isset($this->session->returnto)) {
$returnto = $this->session->returnto;
$this->app->display("github/callback");
}
+ private function validateUser() {
+ $this->github->fetchToken(
+ $this->app->getRequest()->getQuery("code"),
+ $this->app->getRequest()->getQuery("state")
+ )->then(function($result) {
+ list($oauth) = $result;
+ $this->github->setToken($oauth->access_token);
+ return $this->github->readAuthUser()->then(function($result) use($oauth) {
+ list($user) = $result;
+ return $this->persistUser($oauth, $user);
+ });
+ })->done(function($result) {
+ $this->login(...$result);
+ });
+
+ $this->github->getClient()->send();
+ }
+
+ private function persistUser($oauth, $user) {
+ $tx = $this->accounts->getConnection()->startTransaction();
+
+ if (($cookie = $this->app->getRequest()->getCookie("account"))) {
+ $account = $this->accounts->find(["account=" => $cookie])->current();
+ } elseif (!($account = $this->accounts->byOAuth("github", $oauth->access_token, $user->login))) {
+ $account = $this->accounts->createOAuthAccount("github", $oauth->access_token, $user->login);
+ }
+ $token = $account->updateToken("github", $oauth->access_token, $oauth);
+ $owner = $account->updateOwner("github", $user->login, $user);
+
+ $tx->commit();
+
+ return [$account, $token, $owner];
+ }
}
namespace app\Controller\Github;
use app\Controller\Github;
+use app\Github\API\Repos\ReposCallback;
class Index extends Github
{
function __invoke(array $args = null) {
if ($this->checkToken()) {
- list($repos, $links) = $this->github->listRepos(
- $this->app->getRequest()->getQuery("page"),
- new \app\Github\API\Repos\ReposCallback($this->github)
- )->send();
- $this->app->display("github/index", compact("repos", "links"));
+ $this->github->listRepos(
+ $this->app->getRequest()->getQuery("page")
+ )->then(
+ new ReposCallback($this->github)
+ )->done(function($results) {
+ list(list($repos, $links)) = $results;
+ $this->app->display("github/index", compact("repos", "links"));
+ });
+ $this->github->drain();
}
}
}
function __invoke(array $args = null) {
extract($args);
if ($this->checkToken()) {
- list($repo) = $this->github->readRepo("$owner/$name", new RepoCallback($this->github))->send();
- $hook = $this->github->checkRepoHook($repo);
-
- $this->app->getView()->addData(compact("owner", "name", "repo", "hook"));
-
- if (($modal = $this->app->getRequest()->getQuery("modal"))) {
- $action = $this->app->getRequest()->getQuery($modal);
- $this->app->getView()->addData(compact("modal", "action"));
- }
-
- $this->app->display("github/repo");
+ $this->github->readRepo("$owner/$name")->then(
+ new RepoCallback($this->github)
+ )->done(function($result) use($owner, $name) {
+ list($repo) = $result;
+ $hook = $this->github->checkRepoHook($repo);
+
+ $this->app->getView()->addData(compact("owner", "name", "repo", "hook"));
+ });
+ $this->github->drain();
+ }
+
+ if (($modal = $this->app->getRequest()->getQuery("modal"))) {
+ $action = $this->app->getRequest()->getQuery($modal);
+ $this->app->getView()->addData(compact("modal", "action"));
}
+
+ $this->app->display("github/repo");
}
}
* @var \Psr\Log\LoggerInterface;
*/
private $logger;
+
+ /**
+ * Queued promises
+ * @var array
+ */
+ private $queue;
function __construct(Config $config, LoggerInterface $logger, Storage $tokens = null, Storage $cache = null) {
$this->logger = $logger;
throw new Exception\StateMismatch($orig_state->getValue(), $state);
}
- $call = new API\Users\ReadAuthToken($this, [
+ return $this->queue(new API\Users\ReadAuthToken($this, [
"code" => $code,
"client_id" => $this->config->client->id,
"client_secret" => $this->config->client->secret,
- ]);
- return $call();
+ ]));
+ }
+
+ function queue(API\Call $call) {
+ return $this->queue[] = $call();
+ }
+
+ function drain() {
+ $queue = $this->queue;
+ $this->queue = array();
+ $this->client->send();
+ return $queue;
}
function readAuthUser() {
- $call = new API\Users\ReadAuthUser($this);
- return $call();
+ return $this->queue(new API\Users\ReadAuthUser($this));
}
- function listRepos($page, callable $callback) {
- $call = new API\Repos\ListRepos($this, compact("page"));
- return $call($callback);
+ function listRepos($page) {
+ return $this->queue(new API\Repos\ListRepos($this, compact("page")));
}
- function readRepo($repo, callable $callback) {
- $call = new API\Repos\ReadRepo($this, compact("repo"));
- return $call($callback);
+ function readRepo($repo) {
+ return $this->queue(new API\Repos\ReadRepo($this, compact("repo")));
}
/**
* @return stdClass hook
*/
function checkRepoHook($repo) {
- if ($repo->hooks) {
+ if (!empty($repo->hooks)) {
foreach ($repo->hooks as $hook) {
if ($hook->name === "web" && $hook->config->url === $this->config->hook->url) {
return $hook;
return null;
}
- function listHooks($repo, callable $callback) {
- $call = new API\Hooks\ListHooks($this, compact("repo"));
- return $call($callback);
+ function listHooks($repo) {
+ return $this->queue(new API\Hooks\ListHooks($this, compact("repo")));
}
- function listReleases($repo, $page, callable $callback) {
- $call = new API\Releases\ListReleases($this, compact("repo", "page"));
- return $call($callback);
+ function listReleases($repo, $page) {
+ return $this->queue(new API\Releases\ListReleases($this, compact("repo", "page")));
}
- function listTags($repo, $page, callable $callback) {
- $call = new API\Tags\ListTags($this, compact("repo", "page"));
- return $call($callback);
+ function listTags($repo, $page) {
+ return $this->queue(new API\Tags\ListTags($this, compact("repo", "page")));
}
- function readContents($repo, $path, callable $callback) {
- $call = new API\Repos\ReadContents($this, compact("repo", "path"));
- return $call($callback);
+ function readContents($repo, $path = null) {
+ return $this->queue(new API\Repos\ReadContents($this, compact("repo", "path")));
}
- function createRepoHook($repo, $conf, callable $callback) {
- $call = new API\Hooks\CreateHook($this, compact("repo", "conf"));
- return $call($callback);
+ function createRepoHook($repo, $conf) {
+ return $this->queue(new API\Hooks\CreateHook($this, compact("repo", "conf")));
}
- function updateRepoHook($repo, $id, $conf, callable $callback) {
- $call = new API\Hooks\UpdateHook($this, compact("repo", "id", "conf"));
- return $call($callback);
+ function updateRepoHook($repo, $id, $conf) {
+ return $this->queue(new API\Hooks\UpdateHook($this, compact("repo", "id", "conf")));
}
- function deleteRepoHook($repo, $id, callable $callback) {
- $call = new API\Hooks\DeleteHook($this, compact("repo", "id"));
- return $call($callback);
+ function deleteRepoHook($repo, $id) {
+ return $this->queue(new API\Hooks\DeleteHook($this, compact("repo", "id")));
}
- function createRelease($repo, $tag, callable $callback) {
- $call = new API\Releases\CreateRelease($this, compact("repo", "tag"));
- return $call($callback);
+ function createRelease($repo, $tag) {
+ return $this->queue(new API\Releases\CreateRelease($this, compact("repo", "tag")));
}
- function publishRelease($repo, $id, $tag, callable $callback) {
- $call = new API\Releases\PublishRelease($this, compact("repo", "id", "tag"));
- return $call($callback);
+ function publishRelease($repo, $id, $tag) {
+ return $this->queue(new API\Releases\PublishRelease($this, compact("repo", "id", "tag")));
}
- function createReleaseAsset($url, $asset, $type, callable $callback) {
- $call = new API\Releases\CreateReleaseAsset($this, compact("url", "asset", "type"));
- return $call($callback);
+ function createReleaseAsset($url, $asset, $type) {
+ return $this->queue(new API\Releases\CreateReleaseAsset($this, compact("url", "asset", "type")));
}
- function listReleaseAssets($repo, $id, callable $callback) {
- $call = new API\Releases\ListReleaseAssets($this, compact("repo", "id"));
- return $call($callback);
+ function listReleaseAssets($repo, $id) {
+ return $this->queue(new API\Releases\ListReleaseAssets($this, compact("repo", "id")));
}
- function uploadAssetForRelease($repo, $release, $config, callable $callback) {
- return $this->listHooks($repo->full_name, function($hooks) use($release, $repo, $config, $callback) {
- $repo->hooks = $hooks;
+ function uploadAssetForRelease($repo, $release, $config) {
+ return $this->listHooks($repo->full_name)->then(function($result) use($release, $repo, $config) {
+ list($repo->hooks) = $result;
$hook = $this->checkRepoHook($repo);
$phar = new Pharext\Package($repo->clone_url, $release->tag_name, $repo->name, $config ?: $hook->config);
$name = sprintf("%s-%s.ext.phar", $repo->name, $release->tag_name);
$url = uri_template($release->upload_url, compact("name"));
- $this->createReleaseAsset($url, $phar, "application/phar", function($json) use($release, $repo, $callback) {
- if ($release->draft) {
- $this->publishRelease($repo->full_name, $release->id, $release->tag_name, function($json) use($callback) {
- $callback($json);
- });
- } else {
- $callback($json);
- }
- });
+ $promise = $this->createReleaseAsset($url, $phar, "application/phar");
+ if ($release->draft) {
+ return $promise->then(function($result) use($release, $repo) {
+ return $this->publishRelease($repo->full_name, $release->id, $release->tag_name);
+ });
+ }
+ return $promise;
});
}
- function createReleaseFromTag($repo, $tag_name, $config, callable $callback) {
- return $this->createRelease($repo->full_name, $tag_name, function($json) use($repo, $callback) {
- $this->uploadAssetForRelease($repo, $json, $config, $callback);
+ function createReleaseFromTag($repo, $tag_name, $config) {
+ return $this->createRelease($repo->full_name, $tag_name)->then(function($result) use($repo, $config) {
+ list($release) = $result;
+ return $this->uploadAssetForRelease($repo, $release, $config);
});
}
*/
protected $query;
- /**
- * @var array
- */
- protected $result;
-
/**
* @var \React\Promise\Deferred
*/
return strtolower(end($parts));
}
- /**
- * Call Client::send()
- */
- function send() {
- $this->api->getClient()->send();
- return $this->result;
- }
-
/**
* Get associated cache storage
* @param int $ttl out param of configure ttl
{
protected $api;
- abstract function __invoke($json, $links = null);
+ abstract protected function exec($json, $links = null);
function __construct(API $api) {
$this->api = $api;
}
+
+ function __invoke($result) {
+ return $this->exec(...$result);
+ }
}
$this->repo = $repo;
}
- function __invoke($json, $links = null) {
- $this->repo->hooks = $json;
+ function exec($json, $links = null) {
+ return $this->repo->hooks = $json;
}
}
use app\Github\Exception\RequestException;
use app\Github\Links;
use http\Client\Request;
+use http\Client\Response;
class ListHooks extends Call
{
- function enqueue(callable $callback) {
+ function request() {
$url = $this->url->mod(uri_template("./repos/{+repo}/hooks{?page,per_page}", $this->args));
$request = new Request("GET", $url, [
"Authorization" => "token ". $this->api->getToken(),
"Accept" => $this->config->api->accept,
]);
- $this->api->getClient()->enqueue($request, function($response) use($callback) {
- if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
- throw new RequestException($response);
- }
- $links = new Links($response->getHeader("Link"));
- $this->result = [$json, $links];
- $this->saveToCache($this->result);
- $callback($json, $links);
- return true;
- });
+ return $request;
+ }
+
+ function response(Response $response) {
+ if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
+ throw new RequestException($response);
+ }
+ $links = new Links($response->getHeader("Link"));
+ $result = [$json, $links];
+ $this->saveToCache($result);
+ return $result;
}
}
use app\Github\Exception\RequestException;
use app\Github\Links;
use http\Client\Request;
+use http\Client\Response;
class ListReleaseAssets extends Call
{
- function enqueue(callable $callback) {
+ function request() {
$url = $this->url->mod(uri_template("./repos/{+repo}/releases{/id}/assets", $this->args));
$request = new Request("GET", $url, [
"Authorization" => "token ". $this->api->getToken(),
"Accept" => $this->config->api->accept,
]);
- $this->api->getClient()->enqueue($request, function($response) use($callback) {
- if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
- throw new RequestException($response);
- }
- $links = new Links($response->getHeader("Link"));
- $this->result = [$json, $links];
- $this->saveToCache($this->result);
- $callback($json, $links);
- return true;
- });
+ return $request;
+ }
+
+ function response(Response $response) {
+ if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
+ throw new RequestException($response);
+ }
+ $links = new Links($response->getHeader("Link"));
+ $result = [$json, $links];
+ $this->saveToCache($result);
+ return $result;
}
}
use app\Github\Exception\RequestException;
use app\Github\Links;
use http\Client\Request;
+use http\Client\Response;
class ListReleases extends Call
{
- function enqueue(callable $callback) {
+ function request() {
$url = $this->url->mod(uri_template("./repos/{+repo}/releases{?page,per_page}", $this->args));
$request = new Request("GET", $url, [
"Authorization" => "token ". $this->api->getToken(),
"Accept" => $this->config->api->accept,
]);
- $this->api->getClient()->enqueue($request, function($response) use($callback) {
- if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
- throw new RequestException($response);
- }
- $links = new Links($response->getHeader("Link"));
- $this->result = [$json, $links];
- $this->saveToCache($this->result);
- $callback($json, $links);
- return true;
- });
+ return $request;
+ }
+
+ function response(Response $response) {
+ if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
+ throw new RequestException($response);
+ }
+ $links = new Links($response->getHeader("Link"));
+ $result = [$json, $links];
+ $this->saveToCache($result);
+ return $result;
}
}
$this->repo = $repo;
}
- function __invoke($json, $links = null) {
+ protected function exec($json, $links = null) {
foreach ($json as $entry) {
if ($entry->type !== "file" || $entry->size <= 0) {
continue;
$this->repo->pharext_package_php = $entry->name;
}
}
+ return $json;
}
}
use app\Github\Exception\RequestException;
use app\Github\Links;
use http\Client\Request;
+use http\Client\Response;
class ListRepos extends Call
{
- function enqueue(callable $callback) {
+ function request() {
$url = $this->url->mod(uri_template("./user/repos{?page,per_page}", $this->args));
$request = new Request("GET", $url, [
"Authorization" => "token ". $this->api->getToken(),
"Accept" => $this->config->api->accept,
]);
- $this->api->getClient()->enqueue($request, function($response) use($callback) {
- if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
- throw new RequestException($response);
- }
- $links = new Links($response->getHeader("Link"));
- $this->result = [$json, $links];
- $this->saveToCache($this->result);
- $callback($json, $links);
- return true;
- });
+ return $request;
}
-}
\ No newline at end of file
+
+ function response(Response $response) {
+ if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
+ throw new RequestException($response);
+ }
+ $links = new Links($response->getHeader("Link"));
+ $result = [$json, $links];
+ $this->saveToCache($result);
+ return $result;
+ }
+}
use app\Github\API\Call;
use app\Github\Exception\RequestException;
use http\Client\Request;
+use http\Client\Response;
class ReadContents extends Call
{
- function enqueue(callable $callback) {
+ function request() {
$url = $this->url->mod(uri_template("./repos/{+repo}/contents/{+path}", $this->args));
$request = new Request("GET", $url, [
"Authorization" => "token ". $this->api->getToken(),
"Accept" => $this->config->api->accept,
]);
- $this->api->getClient()->enqueue($request, function($response) use($callback) {
- if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
- throw new RequestException($response);
- }
- $this->result = [$json];
- $this->saveToCache($this->result);
- $callback($json);
- return true;
- });
+ return $request;
+ }
+
+ function response(Response $response) {
+ if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
+ throw new RequestException($response);
+ }
+ $result = [$json];
+ $this->saveToCache($result);
+ return $result;
}
}
use app\Github\API\Call;
use app\Github\Exception\RequestException;
use http\Client\Request;
+use http\Client\Response;
class ReadRepo extends Call
{
- function enqueue(callable $callback) {
+ function request() {
$url = $this->url->mod(uri_template("./repos/{+repo}", $this->args));
$request = new Request("GET", $url, [
"Authorization" => "token " . $this->api->getToken(),
"Accept" => $this->config->api->accept,
]);
- $this->api->getClient()->enqueue($request, function($response) use($callback) {
- if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
- throw new RequestException($response);
- }
- $this->result = [$json];
- $this->saveToCache($this->result);
- $callback($json);
- return true;
- });
+ return $request;
+ }
+
+ function response(Response $response) {
+ if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
+ throw new RequestException($response);
+ }
+ $result = [$json];
+ $this->saveToCache($result);
+ return $result;
}
}
$this->repo = $repo;
}
- function __invoke($json, $links = null) {
+ protected function exec($json, $links = null) {
settype($this->repo->tags, "object");
foreach ($json as $release) {
$tag = $release->tag_name;
settype($this->repo->tags->$tag, "object");
$this->repo->tags->$tag->release = $release;
- $this->api->listReleaseAssets($this->repo->full_name, $release->id, function($assets) use($release) {
- $release->assets = $assets;
+ $this->api->listReleaseAssets(
+ $this->repo->full_name,
+ $release->id
+ )->done(function($result) use($release) {
+ list($release->assets) = $result;
});
}
+ return $json;
}
}
use app\Github\API\Hooks\HooksCallback;
use app\Github\API\Tags\TagsCallback;
+use React\Promise;
+
class RepoCallback extends Callback
{
- function __invoke($repo, $links = null) {
- $this->api->listHooks($repo->full_name, new HooksCallback($this->api, $repo));
- $this->api->listTags($repo->full_name, 1, new TagsCallback($this->api, $repo));
- $this->api->listReleases($repo->full_name, 1, new ReleasesCallback($this->api, $repo));
- $this->api->readContents($repo->full_name, null, new ContentsCallback($this->api, $repo));;
+ protected function exec($repo, $links = null) {
+ return Promise\all([
+ $repo,
+ $this->api->listHooks($repo->full_name)->then(new HooksCallback($this->api, $repo)),
+ $this->api->listTags($repo->full_name, 1)->then(new TagsCallback($this->api, $repo)),
+ $this->api->listReleases($repo->full_name, 1)->then(new ReleasesCallback($this->api, $repo)),
+ $this->api->readContents($repo->full_name)->then(new ContentsCallback($this->api, $repo)),
+ ]);
}
}
use app\Github\API\Callback;
use app\Github\API\Hooks\HooksCallback;
+use React\Promise;
+
class ReposCallback extends Callback
{
- function __invoke($json, $links = null) {
+ protected function exec($json, $links = null) {
+ $promises = array([$json, $links]);
foreach ($json as $repo) {
- $this->api->listHooks($repo->full_name, new HooksCallback($this->api, $repo));
+ $promises[] = $this->api
+ ->listHooks($repo->full_name)
+ ->then(new HooksCallback($this->api, $repo));
}
+ return Promise\all($promises);
}
}
use app\Github\Exception\RequestException;
use app\Github\Links;
use http\Client\Request;
+use http\Client\Response;
class ListTags extends Call
{
- function enqueue(callable $callback) {
+ function request() {
$url = $this->url->mod(uri_template("./repos/{+repo}/tags{?page,per_page}", $this->args));
$request = new Request("GET", $url, [
"Authorization" => "token ". $this->api->getToken(),
"Accept" => $this->config->api->accept,
]);
- $this->api->getClient()->enqueue($request, function($response) use($callback) {
- if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
- throw new RequestException($response);
- }
- $links = new Links($response->getHeader("Link"));
- $this->result = [$json, $links];
- $this->saveToCache($this->result);
- $callback($json, $links);
- return true;
- });
+ return $request;
+ }
+
+ function response(Response $response) {
+ if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
+ throw new RequestException($response);
+ }
+ $links = new Links($response->getHeader("Link"));
+ $result = [$json, $links];
+ $this->saveToCache($result);
+ return $result;
}
}
$this->repo = $repo;
}
- function __invoke($json, $links = null) {
+ protected function exec($json, $links = null) {
settype($this->repo->tags, "object");
foreach ($json as $tag) {
$name = $tag->name;
settype($this->repo->tags->$name, "object");
$this->repo->tags->$name->tag = $tag;
}
+ return $json;
}
}