12 * @var \app\Github\API
36 function __construct(API
$api, array $args = []) {
38 $this->config
= $api->getConfig();
40 $this->url
= new Url("https://api.github.com/", null, 0);
41 if (isset($this->config
->fetch
->{$this}->per_page
)) {
42 header("X-Fetch-{$this}: ".$this->config
->fetch
->{$this}->per_page
, false);
43 $this->url
->query
= "per_page=" . $this->config
->fetch
->{$this}->per_page
;
47 function setPage($page) {
56 function __toString() {
57 $parts = explode("\\", get_class($this));
58 return strtolower(end($parts));
61 function getStorage(&$ttl = null) {
62 if (isset($this->config
->storage
->cache
->{$this}->ttl
)) {
63 $ttl = $this->config
->storage
->cache
->{$this}->ttl
;
65 return $this->api
->getCacheStorage();
68 abstract function getRequest();
69 abstract function getException($message, $code, $previous = null);
70 abstract function getCacheKey();
72 function parseLinks(Header
$header) {
73 $params = new Params($header->value
, ",", ";", "=",
74 Params
::PARSE_RFC5988 | Params
::PARSE_ESCAPED
);
76 foreach ($params->params
as $link => $param) {
77 // strip enclosing brackets
78 $links[$param["arguments"]["rel"]] = $link;
83 function __invoke(callable
$callback) {
85 $key = $this->getCacheKey();
86 if (($cache = $this->api
->getCacheStorage())
87 && $cache->get($key, $cached, $ttl)) {
88 call_user_func_array($callback, $cached);
90 $this->enqueue($callback);
92 return $this->api
->getClient();
95 protected function wrap(callable
$callback) {
96 return function($response) use($callback) {
97 $rc = $response->getResponseCode();
100 if ($response->getHeader("Content-Type", Header
::class)->match("application/json", Header
::MATCH_WORD
)) {
101 $message = json_decode($response->getBody())->message
;
103 $message = $response->getBody();
105 throw $this->getException($message, $rc);
108 $json = json_decode($response->getBody());
109 if (($link = $response->getHeader("Link", Header
::class))) {
110 $links = $this->parseLinks($link);
115 if (isset($json->error
)) {
116 throw $this->getException($json->error_description
, $rc);
117 } elseif (($cache = $this->getStorage($ttl))) {
118 $cache->set($this->getCacheKey(), [$json, $links], $ttl);
121 $callback($json, $links);
127 function enqueue(callable
$callback) {
128 $request = $this->getRequest();
129 $wrapper = $this->wrap($callback);
130 return $this->api
->getClient()->enqueue($request, $wrapper);