fix saveToCache() usage; move hook controllers around
authorMichael Wallner <mike@php.net>
Mon, 11 May 2015 09:38:17 +0000 (11:38 +0200)
committerMichael Wallner <mike@php.net>
Mon, 11 May 2015 09:38:17 +0000 (11:38 +0200)
app/Controller/Github.php
app/Controller/Github/Hook.php [deleted file]
app/Controller/Github/Hook/Receive.php [new file with mode: 0644]
app/Controller/Github/Repo/Hook.php [deleted file]
app/Controller/Github/RepoHook.php [new file with mode: 0644]
app/Github/API/Call.php
app/Github/API/Repos/ReadContents.php
app/Github/API/Repos/ReadRepo.php
app/Github/API/Users/ReadAuthUser.php
app/views/github/repo.phtml
config/routes.ini

index 5933fcd2ffc12aee7ccf5ef74a79daaea9e6e3dd..0c38bd7721cb3daf40f36e65ac8dbcf9a389e271 100644 (file)
@@ -58,7 +58,7 @@ abstract class Github implements Controller
                if ($repo->hooks) {
                        foreach ($repo->hooks as $hook) {
                                if ($hook->name === "web" && $hook->config->url === $this->github->getConfig()->hook->url) {
-                                       return $hook->id;
+                                       return $hook;
                                }
                        }
                }
diff --git a/app/Controller/Github/Hook.php b/app/Controller/Github/Hook.php
deleted file mode 100644 (file)
index bbfab2a..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-
-namespace app\Controller\Github;
-
-use app\Controller;
-use app\Github\API;
-use app\Model\Accounts;
-use app\Web;
-use http\Params;
-use pharext\Task;
-use pharext\SourceDir\Git;
-
-require_once __DIR__."/../../../vendor/m6w6/pharext/src/pharext/Version.php";
-
-class Hook implements Controller
-{
-       private $app;
-       private $github;
-       private $accounts;
-       
-       function __construct(Web $app, API $github, Accounts $accounts) {
-               $this->app = $app;
-               $this->github = $github;
-               $this->accounts = $accounts;
-       }
-       
-       function __invoke(array $args = []) {
-               $request = $this->app->getRequest();
-               $response = $this->app->getResponse();
-               
-               if (!($sig = $request->getHeader("X-Hub-Signature")) || !($evt = $request->getHeader("X-Github-Event"))) {
-                       $response->setResponseCode(400);
-                       $response->setContentType("message/http");
-                       $response->getBody()->append($request);
-               } else {
-                       $key = $this->github->getConfig()->client->secret;
-                       foreach ((new Params($sig))->params as $algo => $mac) {
-                               if ($mac["value"] !== hash_hmac($algo, $request->getBody(), $key)) {
-                                       $response->setResponseCode(403);
-                                       $response->getBody()->append("Invalid signature");
-                                       return;
-                               }
-                       }
-               }
-
-               switch ($evt) {
-                       default:
-                               $response->setResponseCode(202);
-                               $response->getBody()->append("Not a configured event");
-                               break;
-                       case "ping";
-                               $response->setResponseCode(204);
-                               $response->setResponseStatus("PONG");
-                               break;
-                       case "create":
-                       case "release":
-                               if (($json = json_decode($request->getBody()))) {
-                                       $this->$evt($json);
-                               } else {
-                                       $response->setResponseCode(415);
-                                       $response->setContentType($request->getHeader("Content-Type"));
-                                       $response->getBody()->append($request->getBody());
-                               }
-                               break;
-               }
-       }
-       
-       function release($release) {
-               if ($release->action !== "published") {
-                       $response = $this->app->getResponse();
-                       
-                       $response->setResponseCode(202);
-                       $response->getBody()->append("Not published");
-                       return;
-               }
-               
-               $this->uploadAssetForRelease($release->release, $release->repository);
-       }
-       
-       private function uploadAssetForRelease($release, $repo) {
-               $this->setTokenForUser($repo->owner->login);
-               $asset = $this->createReleaseAsset($release, $repo);
-               // FIXME: use uri_template extension
-               $name = sprintf("%s-%s.ext.phar", $repo->name, $release->tag_name);
-               $url = str_replace("{?name}", "?name=$name", $release->upload_url);
-               $this->github->createReleaseAsset($url, $asset, "application/phar", function($json) {
-                       $response = $this->app->getResponse();
-                       $response->setResponseCode(201);
-                       $response->setHeader("Location", $json->url);
-               })->send();
-       }
-       
-       private function createReleaseAsset($release, $repo) {
-               define("STDERR", fopen("/var/log/apache2/php_errors.log", "a"));
-               $source = (new Task\GitClone($repo->clone_url, $release->tag_name))->run();
-               $iterator = new Git($source);
-               $meta = [
-                       "header" => sprintf("pharext v%s (c) Michael Wallner <mike@php.net>", \pharext\VERSION),
-                       "version" => \pharext\VERSION,
-                       "date" => date("Y-m-d"),
-                       "name" => $repo->name,
-                       "release" => $release->tag_name,
-                       "license" => @file_get_contents(current(glob($iterator->getBaseDir()."/LICENSE*"))),
-                       "stub" => "pharext_installer.php",
-                       "type" => false ? "zend_extension" : "extension",
-               ];
-               $file = (new Task\PharBuild($iterator, $meta))->run();
-               return $file;
-       }
-       
-       function create($create) {
-               if ($create->ref_type !== "tag") {
-                       $response = $this->app->getResponse();
-                       
-                       $response->setResponseCode(202);
-                       $response->getBody()->append("Not a tag");
-                       return;
-               }
-               
-               $this->createReleaseFromTag($create->ref, $create->repository);
-       }
-       
-       private function setTokenForUser($login) {
-               $relations = [
-                       $this->accounts->getTokens()->getRelation("accounts"),
-                       $this->accounts->getOwners()->getRelation("accounts")
-               ];
-               $tokens = $this->accounts->getTokens()->with($relations, [
-                       "login=" => $login,
-                       "tokens.authority=" => "github",
-               ]);
-               
-               if (count($tokens)) {
-                       $this->github->setToken($tokens->current()->token->get());
-               }
-       }
-       
-       private function createReleaseFromTag($tag, $repo) {
-               $this->setTokenForUser($repo->owner->login);
-               $this->github->createRelease($repo->full_name, $tag, function($json) {
-                       $response = $this->app->getResponse();
-                       $response->setResponseCode(201);
-                       $response->setHeader("Location", $json->url);
-               })->send();
-       }
-}
diff --git a/app/Controller/Github/Hook/Receive.php b/app/Controller/Github/Hook/Receive.php
new file mode 100644 (file)
index 0000000..48e10ae
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+
+namespace app\Controller\Github\Hook;
+
+use app\Controller;
+use app\Github\API;
+use app\Model\Accounts;
+use app\Web;
+use http\Params;
+use pharext\Task;
+use pharext\SourceDir\Git;
+
+require_once __DIR__."/../../../../vendor/m6w6/pharext/src/pharext/Version.php";
+
+class Receive implements Controller
+{
+       private $app;
+       private $github;
+       private $accounts;
+       
+       function __construct(Web $app, API $github, Accounts $accounts) {
+               $this->app = $app;
+               $this->github = $github;
+               $this->accounts = $accounts;
+       }
+       
+       function __invoke(array $args = []) {
+               $request = $this->app->getRequest();
+               $response = $this->app->getResponse();
+               
+               if (!($sig = $request->getHeader("X-Hub-Signature")) || !($evt = $request->getHeader("X-Github-Event"))) {
+                       $response->setResponseCode(400);
+                       $response->setContentType("message/http");
+                       $response->getBody()->append($request);
+               } else {
+                       $key = $this->github->getConfig()->client->secret;
+                       foreach ((new Params($sig))->params as $algo => $mac) {
+                               if ($mac["value"] !== hash_hmac($algo, $request->getBody(), $key)) {
+                                       $response->setResponseCode(403);
+                                       $response->getBody()->append("Invalid signature");
+                                       return;
+                               }
+                       }
+               }
+
+               switch ($evt) {
+                       default:
+                               $response->setResponseCode(202);
+                               $response->getBody()->append("Not a configured event");
+                               break;
+                       case "ping";
+                               $response->setResponseCode(204);
+                               $response->setResponseStatus("PONG");
+                               break;
+                       case "create":
+                       case "release":
+                               if (($json = json_decode($request->getBody()))) {
+                                       $this->$evt($json);
+                               } else {
+                                       $response->setResponseCode(415);
+                                       $response->setContentType($request->getHeader("Content-Type"));
+                                       $response->getBody()->append($request->getBody());
+                               }
+                               break;
+               }
+       }
+       
+       function release($release) {
+               if ($release->action !== "published") {
+                       $response = $this->app->getResponse();
+                       
+                       $response->setResponseCode(202);
+                       $response->getBody()->append("Not published");
+                       return;
+               }
+               
+               $this->uploadAssetForRelease($release->release, $release->repository);
+       }
+       
+       private function uploadAssetForRelease($release, $repo) {
+               $this->setTokenForUser($repo->owner->login);
+               $asset = $this->createReleaseAsset($release, $repo);
+               // FIXME: use uri_template extension
+               $name = sprintf("%s-%s.ext.phar", $repo->name, $release->tag_name);
+               $url = str_replace("{?name}", "?name=$name", $release->upload_url);
+               $this->github->createReleaseAsset($url, $asset, "application/phar", function($json) {
+                       $response = $this->app->getResponse();
+                       $response->setResponseCode(201);
+                       $response->setHeader("Location", $json->url);
+               })->send();
+       }
+       
+       private function createReleaseAsset($release, $repo) {
+               define("STDERR", fopen("/var/log/apache2/php_errors.log", "a"));
+               $source = (new Task\GitClone($repo->clone_url, $release->tag_name))->run();
+               $iterator = new Git($source);
+               $meta = [
+                       "header" => sprintf("pharext v%s (c) Michael Wallner <mike@php.net>", \pharext\VERSION),
+                       "version" => \pharext\VERSION,
+                       "date" => date("Y-m-d"),
+                       "name" => $repo->name,
+                       "release" => $release->tag_name,
+                       "license" => @file_get_contents(current(glob($iterator->getBaseDir()."/LICENSE*"))),
+                       "stub" => "pharext_installer.php",
+                       "type" => false ? "zend_extension" : "extension",
+               ];
+               $file = (new Task\PharBuild($iterator, $meta))->run();
+               return $file;
+       }
+       
+       function create($create) {
+               if ($create->ref_type !== "tag") {
+                       $response = $this->app->getResponse();
+                       
+                       $response->setResponseCode(202);
+                       $response->getBody()->append("Not a tag");
+                       return;
+               }
+               
+               $this->createReleaseFromTag($create->ref, $create->repository);
+       }
+       
+       private function setTokenForUser($login) {
+               $relations = [
+                       $this->accounts->getTokens()->getRelation("accounts"),
+                       $this->accounts->getOwners()->getRelation("accounts")
+               ];
+               $tokens = $this->accounts->getTokens()->with($relations, [
+                       "login=" => $login,
+                       "tokens.authority=" => "github",
+               ]);
+               
+               if (count($tokens)) {
+                       $this->github->setToken($tokens->current()->token->get());
+               }
+       }
+       
+       private function createReleaseFromTag($tag, $repo) {
+               $this->setTokenForUser($repo->owner->login);
+               $this->github->createRelease($repo->full_name, $tag, function($json) {
+                       $response = $this->app->getResponse();
+                       $response->setResponseCode(201);
+                       $response->setHeader("Location", $json->url);
+               })->send();
+       }
+}
diff --git a/app/Controller/Github/Repo/Hook.php b/app/Controller/Github/Repo/Hook.php
deleted file mode 100644 (file)
index fac6450..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-namespace app\Controller\Github\Repo;
-
-use app\Controller\Github;
-
-class Hook extends Github
-{
-       function __invoke(array $args = null) {
-               if ($this->checkToken()) {
-                       if ($this->app->getRequest()->getRequestMethod() != "POST") {
-                               // user had to re-authenticate, and was redirected here
-                               $this->app->redirect($this->app->getBaseUrl()->mod([
-                                       "path" => "./github/repo/" . $args["owner"] ."/". $args["name"],
-                                       "query" => "modal=hook&hook=" . $args["action"]
-                               ]));
-                       } else switch ($args["action"]) {
-                               case "upd":
-                                       $this->updateHook($args["owner"], $args["name"]);
-                                       break;
-                               
-                               case "add":
-                                       $this->addHook($args["owner"], $args["name"]);
-                                       break;
-
-                               case "del":
-                                       $this->delHook($args["owner"], $args["name"]);
-                                       break;
-                       }
-               }
-       }
-       
-       function addHook($owner, $repo) {
-               $hook_conf = $this->app->getRequest()->getForm();
-               $this->github->createRepoHook("$owner/$repo", $hook_conf, function($hook) use($owner, $repo) {
-                       if (($cache = $this->github->getCacheStorage())) {
-                               $cache->del($this->github->getCacheKey("hooks:$owner/$repo"));
-                       }
-                       if (($back = $this->app->getRequest()->getForm("returnback")) && isset($this->session->previous)) {
-                               $this->app->redirect($this->app->getBaseUrl()->mod($this->session->previous));
-                       } else {
-                               $this->app->redirect($this->app->getBaseUrl()->mod("./github/repo/$owner/$repo"));
-                       }
-               })->send();
-       }
-       
-       function delHook($owner, $repo) {
-               $this->github->fetchRepo("$owner/$repo", function($repo) {
-                       $this->github->fetchHooks($repo->full_name, function($hooks) use($repo) {
-                               $repo->hooks = $hooks;
-                               if (($id = $this->checkRepoHook($repo))) {
-                                       $this->github->deleteRepoHook($repo->full_name, $id, function() use($repo) {
-                                               if (($cache = $this->github->getCacheStorage())) {
-                                                       $cache->del($this->github->getCacheKey("hooks:" . $repo->full_name));
-                                               }
-                                               if (($back = $this->app->getRequest()->getForm("returnback")) && isset($this->session->previous)) {
-                                                       $this->app->redirect($this->app->getBaseUrl()->mod($this->session->previous));
-                                               } else {
-                                                       $this->app->redirect($this->app->getBaseUrl()->mod("./github/repo/" . $repo->full_name));
-                                               }
-                                       });
-                               }
-                       });
-               })->send();
-       }
-}
diff --git a/app/Controller/Github/RepoHook.php b/app/Controller/Github/RepoHook.php
new file mode 100644 (file)
index 0000000..8ab1eed
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+namespace app\Controller\Github;
+
+use app\Controller\Github;
+
+class RepoHook extends Github
+{
+       function __invoke(array $args = null) {
+               if ($this->checkToken()) {
+                       if ($this->app->getRequest()->getRequestMethod() != "POST") {
+                               // user had to re-authenticate, and was redirected here
+                               $this->app->redirect($this->app->getBaseUrl()->mod([
+                                       "path" => "./github/repo/" . $args["owner"] ."/". $args["name"],
+                                       "query" => "modal=hook&hook=" . $args["action"]
+                               ]));
+                       } else {
+                               switch ($args["action"]) {
+                               case "upd":
+                                       $this->updateHook($args["owner"], $args["name"]);
+                                       break;
+                               
+                               case "add":
+                                       $this->addHook($args["owner"], $args["name"]);
+                                       break;
+
+                               case "del":
+                                       $this->delHook($args["owner"], $args["name"]);
+                                       break;
+                               }
+                       }
+               }
+       }
+       
+       function addHook($owner, $repo) {
+               $hook_conf = $this->app->getRequest()->getForm();
+               $this->github->createRepoHook("$owner/$repo", $hook_conf, function($hook) use($owner, $repo) {
+                       if (($cache = $this->github->getCacheStorage())) {
+                               $cache->del($this->github->getCacheKey("hooks:$owner/$repo"));
+                       }
+                       if (($back = $this->app->getRequest()->getForm("returnback")) && isset($this->session->previous)) {
+                               $this->app->redirect($this->app->getBaseUrl()->mod($this->session->previous));
+                       } else {
+                               $this->app->redirect($this->app->getBaseUrl()->mod("./github/repo/$owner/$repo"));
+                       }
+               })->send();
+       }
+       
+       function delHook($owner, $repo) {
+               $this->github->fetchRepo("$owner/$repo", function($repo) {
+                       $this->github->fetchHooks($repo->full_name, function($hooks) use($repo) {
+                               $repo->hooks = $hooks;
+                               if (($hook = $this->checkRepoHook($repo))) {
+                                       $this->github->deleteRepoHook($repo->full_name, $hook->id, function() use($repo) {
+                                               if (($cache = $this->github->getCacheStorage())) {
+                                                       $cache->del($this->github->getCacheKey("hooks:" . $repo->full_name));
+                                               }
+                                               if (($back = $this->app->getRequest()->getForm("returnback")) && isset($this->session->previous)) {
+                                                       $this->app->redirect($this->app->getBaseUrl()->mod($this->session->previous));
+                                               } else {
+                                                       $this->app->redirect($this->app->getBaseUrl()->mod("./github/repo/" . $repo->full_name));
+                                               }
+                                       });
+                               }
+                       });
+               })->send();
+       }
+}
index f40e4866f6b837764b4b999798bca96453f13560..3615851693f1870d2094ea70d8a3a018298326f6 100644 (file)
@@ -96,7 +96,7 @@ abstract class Call
                        new QueryString($this->args));
        }
 
-       function readFromCache(&$cached = null, &$ttl = null) {
+       function readFromCache(array &$cached = null, &$ttl = null) {
                if (empty($this->args["fresh"]) && ($cache = $this->api->getCacheStorage())) {
                        $key = $this->getCacheKey();
                        return $cache->get($key, $cached, $ttl);
@@ -104,7 +104,7 @@ abstract class Call
                return false;
        }
        
-       function saveToCache($fresh) {
+       function saveToCache(array $fresh) {
                if (($cache = $this->api->getCacheStorage())) {
                        if (isset($this->config->storage->cache->{$this}->ttl)) {
                                $ttl = $this->config->storage->cache->{$this}->ttl;
index 02b28fb55bcb514a1016fb3b693a57b97c9b62fc..fde19b88a664cb6bfb462faa3a5f88039e39d001 100644 (file)
@@ -18,7 +18,7 @@ class ReadContents extends Call
                        if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
                                throw new RequestException($response);
                        }
-                       $this->saveToCache($json);
+                       $this->saveToCache([$json]);
                        $callback($json);
                        return true;
                });
index e432d2a2a8557a2eba98d10caf5b5ea6e64b783c..775a9ee6fb73cecff7a4a2cf1e4b078621f24c6f 100644 (file)
@@ -18,7 +18,7 @@ class ReadRepo extends Call
                        if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
                                throw new RequestException($response);
                        }
-                       $this->saveToCache($json);
+                       $this->saveToCache([$json]);
                        $callback($json);
                        return true;
                });
index 5feb7c8cfd62979786561f1bff260f4718e08a28..6cb6de098a86f38b5cd3cb57dd1e720b599bf62e 100644 (file)
@@ -18,7 +18,7 @@ class ReadAuthUser extends Call
                        if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) {
                                throw new RequestException($response);
                        }
-                       $this->saveToCache($json);
+                       $this->saveToCache([$json]);
                        $callback($json);
                        return true;
                });
index 1b7a640bcc76297866c489d337479ade12980210..6000cf7e976f563952a949c8dd70876c70817960 100644 (file)
                                <div class="col-md-12">
                                                <div class="checkbox">
                                                        <label for="hook-tag">
-                                                               <input id="hook-tag" type="checkbox" name="tag" value="1">
+                                                               <input id="hook-tag" type="checkbox" name="tag" value="1" <?= ($hook = $this->check($repo)) && in_array("create", $hook->events) ? "checked":"" ?>>
                                                                Automatically create a release when I push a tag.
                                                        </label>
                                                </div>
                                                <div class="checkbox">
                                                        <label for="hook-release">
-                                                               <input id="hook-release" type="checkbox" name="release" value="1">
+                                                               <input id="hook-release" type="checkbox" name="release" value="1" <?= ($hook = $this->check($repo)) && in_array("release", $hook->events) ? "checked":"" ?>>
                                                                Automatically upload a PHARext package as an asset to a release.
                                                        </label>
                                                </div>
index ad01201599864f1a5fe54a4be4ac40fb7a57abe7..cb28b1e9846b285a1e915178685111eccdb05006 100644 (file)
@@ -7,7 +7,7 @@ GET[] = /pages/{page}
 [Github\Callback]
 GET[] = /github/callback
 
-[Github\Hook]
+[Github\Hook\Receive]
 POST[] = /github/hook
 
 [Github\Index]
@@ -17,7 +17,7 @@ GET[] = /github
 GET[] = /github/repo/{owner}/{name}
 GET[] = /github/repo/{owner}/{name}/{page}
 
-[Github\Repo\Hook]
+[Github\RepoHook]
 POST[] = /github/repo/{owner}/{name}/hook/{action}
 ; if the user has to re-authenticate, we'll receive a GET because of a redirect
 GET[] = /github/repo/{owner}/{name}/hook/{action}