From c05a8f703d5a097355b5813154c264c87e3f71fe Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 9 Jun 2015 11:42:39 +0200 Subject: [PATCH] start refactoring to promises --- app/Controller/Github/Callback.php | 49 ++++++++++++++------------ app/Github/API.php | 8 ++--- app/Github/API/Call.php | 39 ++++++++++++++++---- app/Github/API/Users/ReadAuthToken.php | 19 +++++----- app/Github/API/Users/ReadAuthUser.php | 21 +++++------ composer.json | 3 +- composer.lock | 48 +++++++++++++++++++++++-- 7 files changed, 133 insertions(+), 54 deletions(-) diff --git a/app/Controller/Github/Callback.php b/app/Controller/Github/Callback.php index e6429fc..fefc12c 100644 --- a/app/Controller/Github/Callback.php +++ b/app/Controller/Github/Callback.php @@ -29,11 +29,33 @@ class Callback extends Github } else { $this->github->fetchToken( $this->app->getRequest()->getQuery("code"), - $this->app->getRequest()->getQuery("state"), - function($token) { - $this->github->setToken($token->access_token); - $this->github->readAuthUser($this->createUserCallback($token)); - })->send(); + $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(); + if (isset($this->session->returnto)) { $returnto = $this->session->returnto; unset($this->session->returnto); @@ -46,21 +68,4 @@ class Callback extends Github $this->app->display("github/callback"); } - function createUserCallback($oauth) { - return function($user) use($oauth) { - $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); - }; - } } diff --git a/app/Github/API.php b/app/Github/API.php index 9f37c4f..8e51489 100644 --- a/app/Github/API.php +++ b/app/Github/API.php @@ -134,7 +134,7 @@ class API ], 0); } - function fetchToken($code, $state, callable $callback) { + function fetchToken($code, $state) { if (!$this->tokens->get("state", $orig_state, true)) { if (isset($orig_state)) { $this->logger->notice("State expired", $orig_state); @@ -152,12 +152,12 @@ class API "client_id" => $this->config->client->id, "client_secret" => $this->config->client->secret, ]); - return $call($callback); + return $call(); } - function readAuthUser(callable $callback) { + function readAuthUser() { $call = new API\Users\ReadAuthUser($this); - return $call($callback); + return $call(); } function listRepos($page, callable $callback) { diff --git a/app/Github/API/Call.php b/app/Github/API/Call.php index 22a6951..0e8bd62 100644 --- a/app/Github/API/Call.php +++ b/app/Github/API/Call.php @@ -4,10 +4,13 @@ namespace app\Github\API; use app\Github\API; use app\Github\Storage\Item; +use http\Client\Response; use http\QueryString; use http\Url; use merry\Config; +use React\Promise; + abstract class Call { /** @@ -41,9 +44,19 @@ abstract class Call protected $result; /** - * Queue this call to the API client + * @var \React\Promise\Deferred */ - abstract function enqueue(callable $callback); + protected $deferred; + + /** + * @return Request + */ + abstract protected function request(); + + /** + * @return array + */ + abstract protected function response(Response $response); /** * @param API $api @@ -53,6 +66,7 @@ abstract class Call $this->api = $api; $this->config = $this->api->getConfig(); $this->url = new Url($this->config->api->url, null, 0); + $this->deferred = new Promise\Deferred; if ($args) { $this->args = $args; @@ -62,13 +76,26 @@ abstract class Call } } - function __invoke(callable $callback) { + /** + * @return \React\Promise\Promise + */ + function __invoke() { if ($this->readFromCache($this->result)) { - call_user_func_array($callback, $this->result); + return new Promise\FulfilledPromise($this->result); } else { - $this->enqueue($callback); + $this->api->getClient()->enqueue( + $this->request(), + function($response) { + try { + $this->deferred->resolve($this->response($response)); + } catch (\Exception $e) { + $this->deferred->reject($e); + } + return true; + } + ); + return $this->deferred->promise(); } - return $this; } /** diff --git a/app/Github/API/Users/ReadAuthToken.php b/app/Github/API/Users/ReadAuthToken.php index e167eef..5959e3d 100644 --- a/app/Github/API/Users/ReadAuthToken.php +++ b/app/Github/API/Users/ReadAuthToken.php @@ -5,23 +5,24 @@ namespace app\Github\API\Users; use app\Github\API\Call; use app\Github\Exception\RequestException; use http\Client\Request; +use http\Client\Response; use http\QueryString; class ReadAuthToken extends Call { - function enqueue(callable $callback) { + protected function request() { $request = new Request("POST", "https://github.com/login/oauth/access_token", [ "Accept" => "application/json", ]); $request->getBody()->append(new QueryString($this->args)); - $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]; - $callback($json); - return true; - }); + return $request; + } + + protected function response(Response $response) { + if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { + throw new RequestException($response); + } + return $json; } function getCacheKey() { diff --git a/app/Github/API/Users/ReadAuthUser.php b/app/Github/API/Users/ReadAuthUser.php index b5c4fa9..01bd78c 100644 --- a/app/Github/API/Users/ReadAuthUser.php +++ b/app/Github/API/Users/ReadAuthUser.php @@ -5,23 +5,24 @@ namespace app\Github\API\Users; use app\Github\API\Call; use app\Github\Exception\RequestException; use http\Client\Request; +use http\Client\Response; class ReadAuthUser extends Call { - function enqueue(callable $callback) { + function request() { $url = $this->url->mod("./user"); $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); + } + $this->saveToCache([$json]); + return [$json]; } } diff --git a/composer.json b/composer.json index e456abe..6917945 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "rdlowrey/auryn": "dev-master", "m6w6/pharext.wiki": "dev-master", "m6w6/pq-gateway": "~2.1", - "monolog/monolog": "^1.13" + "monolog/monolog": "^1.13", + "react/promise": "^2.2" } } diff --git a/composer.lock b/composer.lock index 4efa5ae..e7d8ff2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "dd47dcfb975d0ad4b92b940fc58e1eaf", + "hash": "677e6adb8d6fb297c9c04630b5fc2f61", "packages": [ { "name": "league/plates", @@ -352,7 +352,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rdlowrey/Auryn/zipball/d0d875868e1d7d241983c88252c07965a65224c1", + "url": "https://api.github.com/repos/rdlowrey/Auryn/zipball/b57a5046cfcefb0cde7fc86f9915e54aa7196cba", "reference": "d0d875868e1d7d241983c88252c07965a65224c1", "shasum": "" }, @@ -400,6 +400,50 @@ "ioc" ], "time": "2015-05-17 18:29:19" + }, + { + "name": "react/promise", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "365fcee430dfa4ace1fbc75737ca60ceea7eeeef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/365fcee430dfa4ace1fbc75737ca60ceea7eeeef", + "reference": "365fcee430dfa4ace1fbc75737ca60ceea7eeeef", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "React\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@googlemail.com" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "time": "2014-12-30 13:32:42" } ], "packages-dev": [], -- 2.30.2