1 <?php
2 /**
3 * HawkApi.php
4 *
5 * @author Elvyrra SAS
6 * @license http://rem.mit-license.org/ MIT
7 */
8
9 namespace Hawk;
10
11 /**
12 * This class treats the interface with the Hawk site, to get the informations from the site database via an Restful API
13 *
14 * @package Network
15 */
16 class HawkApi{
17 /**
18 * The pattern for a plugin / theme version
19 */
20 const VERSION_PATTERN = '/^(\d{1,2}\.){2,3}\d{1,2}$/';
21
22 /**
23 * The pattern for a plugin or theme version, in a URI
24 */
25 const VERSION_PATTERN_URI = '(?:\d{1,2}\.){2,3}\d{1,2}';
26
27
28 /**
29 * The callable routes on the API, with their parameters
30 *
31 * @var array
32 */
33 public static $routes = array(
34 // Search plugins
35 'api-search-plugins' => array(
36 'method' => 'get',
37 'uri' => '/plugins/search',
38 'where' => array(
39 'params' => array(
40 'search' => array(
41 'required' => true,
42 )
43 )
44 )
45 ),
46
47 // Install a plugin
48 'api-install-plugin' => array(
49 'method' => 'get',
50 'uri' => '/plugins/{name}/install',
51 'where' => array(
52 'path' => array(
53 'name' => Plugin::NAME_PATTERN
54 )
55 ),
56 'dataType' => 'application/octet-stream'
57 ),
58
59 // Get the available updates on plugins
60 'api-plugins-available-updates' => array(
61 'method' => 'get',
62 'uri' => '/plugins/available-updates',
63 'where' => array(
64 'params' => array(
65 'plugins' => array(
66 'required' => true,
67 )
68 )
69 )
70 ),
71
72 // Search themes
73 'api-search-themes' => array(
74 'method' => 'get',
75 'uri' => '/themes/search',
76 'where' => array(
77 'params' => array(
78 'search' => array(
79 'required' => true,
80 )
81 )
82 )
83 ),
84
85 // Install a theme
86 'api-install-theme' => array(
87 'method' => 'get',
88 'uri' => '/themes/{name}/install',
89 'where' => array(
90 'path' => array(
91 'name' => Theme::NAME_PATTERN
92 )
93 ),
94 'dataType' => 'application/octet-stream'
95 ),
96
97 // Get the available updates on themes
98 'api-themes-available-updates' => array(
99 'method' => 'get',
100 'uri' => '/themes/available-updates',
101 'where' => array(
102 'params' => array(
103 'themes' => array(
104 'required' => true,
105 )
106 )
107 )
108 ),
109
110 // Search for available updates on the core
111 'api-core-available-updates' => array(
112 'method' => 'get',
113 'uri' => '/hawk/updates',
114 'where' => array(
115 'params' => array(
116 'version' => array(
117 'required' => true,
118 'pattern' => self::VERSION_PATTERN
119 )
120 )
121 )
122 ),
123
124 // Update Hawk
125 'api-core-update' => array(
126 'method' => 'get',
127 'uri' => '/hawk/update/{to}',
128 'where' => array(
129 'path' => array(
130 'to' => self::VERSION_PATTERN_URI
131 )
132 ),
133 'dataType' => 'application/octet-stream'
134 ),
135
136 // Search for updates on Hawk, plugins and theme in one request
137 'api-all-updates' => array(
138 'method' => 'post',
139 'uri' => '/updates',
140 'where' => array(
141 'body' => array(
142 'hawk' => array(
143 'required' => true,
144 'pattern' => self::VERSION_PATTERN
145 ),
146 'plugins' => array(
147 'required' => true
148 ),
149 'themes' => array(
150 'required' => true
151 )
152 )
153 )
154 )
155 );
156
157
158 /**
159 * Call the API
160 *
161 * @param string $routeName The route name to call
162 * @param array $param The URL parameter to set
163 * @param array $data An associative array of the data to send in the request : 'params', 'body', 'files'
164 *
165 * @return mixed The API response body
166 */
167 private function callApi($routeName, $param = array(), $data = array()){
168 $route = self::$routes[$routeName];
169
170 $data = array_merge(
171 array(
172 'params' => array(),
173 'body' => array(),
174 'files' => array()
175 ),
176 $data
177 );
178
179 $uri = $route['uri'];
180 foreach($param as $key => $value){
181 $uri = str_replace('{' . $key . '}', $value, $uri);
182 }
183
184 if(!empty($data['params'])) {
185 $uri .= '?' . http_build_query($data['params']);
186 }
187
188 $request = new HTTPRequest(
189 array(
190 'url' => HAWK_SITE_URL . '/api' . $uri,
191 'headers' => array(
192 'X-Requested-With' => 'XMLHttpRequest'
193 ),
194 'method' => $route['method'],
195 'contentType' => 'json',
196 'dataType' => isset($route['dataType']) ? $route['dataType'] : 'json',
197 'body' => $data['body'],
198 'files' => $data['files']
199 )
200 );
201
202 $request->send();
203
204 if($request->getStatusCode() === 200) {
205 $result = $request->getResponse();
206 $contentType = $request->getResponseHeaders('Content-Type');
207
208 if($contentType == 'application/octet-stream') {
209
210 $tmpName = TMP_DIR . uniqid() . '.zip' ;
211
212 file_put_contents($tmpName, base64_decode($result));
213
214 return $tmpName;
215 }
216 else{
217 return $result;
218 }
219 }
220 else{
221 throw new HawkApiException((string) $request->getResponse(), (int) $request->getStatusCode());
222 }
223 }
224
225
226 /**
227 * Get the available updates of Hawk
228 *
229 * @return array The list of available version newer than the current one
230 */
231 public function getCoreAvailableUpdates(){
232 return $this->callApi(
233 'api-core-available-updates',
234 array(),
235 array(
236 'params' => array(
237 'version' => HAWK_VERSION
238 )
239 )
240 );
241 }
242
243
244 /**
245 * Download an update file for the core
246 *
247 * @param string $version The version update to get
248 *
249 * @return string The filename of the temporary file created by the downloaded content
250 */
251 public function getCoreUpdateArchive($version){
252 return $this->callApi(
253 'api-core-update',
254 array('to' => $version)
255 );
256 }
257
258
259 /**
260 * Search plugins
261 *
262 * @param string $search The search term
263 *
264 * @return array The list of found plugins
265 */
266 public function searchPlugins($search){
267 return $this->callApi(
268 'api-search-plugins',
269 array(),
270 array(
271 'params' => array(
272 'search' => $search
273 )
274 )
275 );
276 }
277
278
279 /**
280 * Download a plugin file
281 *
282 * @param string $name The plugin name to download
283 *
284 * @return string The filename of the temporary file created by the downloaded content
285 */
286 public function downloadPlugin($name){
287 return $this->callApi(
288 'api-install-plugin',
289 array('name' => $name)
290 );
291 }
292
293
294 /**
295 * Search for updates on a list of plugins
296 *
297 * @param array $plugins The list of plugins to search available updates for,
298 * where keys are plugin names, and values their current version
299 *
300 * @return array The list of the available updates on plugins
301 */
302 public function getPluginsAvailableUpdates($plugins){
303 return $this->callApi(
304 'api-plugins-available-updates',
305 array(),
306 array(
307 'params' => array(
308 'plugins' => json_encode($plugins)
309 )
310 )
311 );
312 }
313
314
315 /**
316 * Search themes
317 *
318 * @param string $search The search term
319 *
320 * @return array The list of found themes
321 */
322 public function searchThemes($search){
323 return $this->callApi(
324 'api-search-themes',
325 array(),
326 array(
327 'params' => array(
328 'search' => $search
329 )
330 )
331 );
332 }
333
334
335 /**
336 * Download a theme file
337 *
338 * @param string $name The theme name to download
339 *
340 * @return string The filename of the temporary file created by the downloaded content
341 */
342 public function downloadTheme($name){
343 return $this->callApi(
344 'api-install-theme',
345 array(
346 'name' => $name
347 )
348 );
349 }
350
351
352 /**
353 * Search for updates on a list of themes
354 *
355 * @param array $themes The list of themes to search available updates for,
356 * where keys are themes names, and values their current version
357 *
358 * @return array The list of available updates on themes
359 */
360 public function getThemesAvailableUpdates($themes){
361 return $this->callApi(
362 'api-themes-available-updates',
363 array(),
364 array(
365 'params' => array(
366 'themes' => json_encode($themes)
367 )
368 )
369 );
370 }
371
372 /**
373 * Get all available updates on Hawk, plugins and themes
374 *
375 * @param array $plugins The list of plugins to search available updates for,
376 * where keys are plugin names, and values their current version
377 * @param array $themes The list of themes to search available updates for,
378 * where keys are themes names, and values their current version
379 *
380 * @return array The available udpates, in an array in the following format :
381 * <code>
382 * array(
383 * 'hawk' => 'v1.0.0',
384 * 'plugins' => array(
385 * 'pluginName' => 'v1.2.3.0',
386 * ...
387 * ),
388 * 'themes' => array(
389 * 'themeName' => 'v0.0.5.1',
390 * ...
391 * )
392 * )
393 * </code>
394 */
395 public function getAllAvailableUpdates($plugins, $themes){
396 return $this->callApi(
397 'api-all-updates',
398 array(),
399 array(
400 'body' => array(
401 'hawk' => HAWK_VERSION,
402 'plugins' => $plugins,
403 'themes' => $themes
404 )
405 )
406 );
407 }
408 }
409
410 /**
411 * This class describes Exceptions throwed by a request to the A.P.I
412 *
413 * @package Exceptions
414 */
415 class HawkApiException extends \Exception{
416 }