github: fix notices
[pharext/pharext.org] / app / Github / API / Call.php
1 <?php
2
3 namespace app\Github\API;
4
5 use app\Github\API;
6 use app\Github\Storage\Item;
7 use http\Client\Response;
8 use http\QueryString;
9 use http\Url;
10 use merry\Config;
11
12 use React\Promise;
13
14 abstract class Call
15 {
16 /**
17 * @var Config
18 */
19 protected $config;
20
21 /**
22 * @var \app\Gituhub\API
23 */
24 protected $api;
25
26 /**
27 * @var array
28 */
29 protected $args = [];
30
31 /**
32 * @var \http\Url
33 */
34 protected $url;
35
36 /**
37 * @var QueryString
38 */
39 protected $query;
40
41 /**
42 * @var \React\Promise\Deferred
43 */
44 protected $deferred;
45
46 /**
47 * @return Request
48 */
49 abstract protected function request();
50
51 /**
52 * @return array
53 */
54 abstract protected function response(Response $response);
55
56 /**
57 * @param API $api
58 * @param array $args
59 */
60 function __construct(API $api, array $args = null) {
61 $this->api = $api;
62 $this->config = $this->api->getConfig();
63 $this->url = new Url($this->config->api->url, null, 0);
64 $this->deferred = new Promise\Deferred;
65
66 if ($args) {
67 $this->args = $args;
68 }
69 if (isset($this->config->api->call->{$this}->args)) {
70 $this->args += $this->config->api->call->{$this}->args->toArray();
71 }
72 }
73
74 /**
75 * @return \React\Promise\Promise
76 */
77 function __invoke() {
78 if ($this->readFromCache($this->result)) {
79 return new Promise\FulfilledPromise($this->result);
80 } else {
81 $this->api->getClient()->enqueue(
82 $this->request(),
83 function($response) {
84 try {
85 $result = $this->response($response);
86 if (!($result instanceof Promise\PromiseInterface)) {
87 $this->deferred->resolve($result);
88 }
89 } catch (\Exception $e) {
90 $this->deferred->reject($e);
91 }
92 return true;
93 }
94 );
95 return $this->deferred->promise();
96 }
97 }
98
99 /**
100 * Get type of call
101 * @return string
102 */
103 function __toString() {
104 $parts = explode("\\", get_class($this));
105 return strtolower(end($parts));
106 }
107
108 /**
109 * Get associated cache storage
110 * @param int $ttl out param of configure ttl
111 * @return Storage
112 */
113 function getCache(&$ttl = null) {
114 if (isset($this->config->storage->cache->{$this}->ttl)) {
115 $ttl = $this->config->storage->cache->{$this}->ttl;
116 }
117 return $this->api->getCacheStorage();
118 }
119
120 function getCacheKey() {
121 $args = $this->args;
122 unset($args["fresh"]);
123 if (isset($args["page"]) && !strcmp($args["page"], "1")) {
124 unset($args["page"]);
125 }
126 ksort($args);
127 return sprintf("%s:%s:%s", $this->api->getToken(), $this,
128 new QueryString($args));
129 }
130
131 function readFromCache(array &$value = null) {
132 if (!empty($this->args["fresh"])) {
133 return false;
134 }
135 if (!($cache = $this->api->getCacheStorage())) {
136 return false;
137 }
138 if (!strlen($key = $this->getCacheKey())) {
139 return false;
140 }
141 if (!$cache->get($key, $cached)) {
142 if ($cached) {
143 $this->api->getLogger()->debug(
144 sprintf("Cache-Stale: $this [TTL=%d]", $cached->getTTL()),
145 $this->args);
146 } else {
147 $this->api->getLogger()->debug("Cache-Miss: $this", $this->args);
148 }
149 return false;
150 }
151 if (null !== $this->api->getMaxAge() && $cached->getAge() > $this->api->getMaxAge()) {
152 $this->api->getLogger()->debug("Cache-Refresh: $this", $this->args);
153 return false;
154 }
155 $this->api->getLogger()->debug("Cache-Hit: $this", $this->args);
156 $value = $cached->getValue();
157 return true;
158 }
159
160 function saveToCache(array $fresh) {
161 if (($cache = $this->api->getCacheStorage())) {
162 if (isset($this->config->storage->cache->{$this}->ttl)) {
163 $ttl = $this->config->storage->cache->{$this}->ttl;
164 } else {
165 $ttl = null;
166 }
167
168 $key = $this->getCacheKey();
169 $cache->set($key, new Item($fresh, $ttl));
170 $this->api->getLogger()->debug("Cache-Push: $this", $this->args);
171 }
172 }
173
174 function dropFromCache() {
175 if (($cache = $this->api->getCacheStorage())) {
176 $key = $this->getCacheKey();
177 $cache->del($key);
178 $this->api->getLogger()->debug("Cache-Drop: $this", $this->args);
179 }
180 }
181 }