Skip to content

Commit cd6e7b3

Browse files
committed
1 parent 880dd56 commit cd6e7b3

File tree

5 files changed

+217
-0
lines changed

5 files changed

+217
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
/**
3+
* Class ApiClientException
4+
*
5+
* @filesource ApiClientException.php
6+
* @created 01.09.2018
7+
* @package chillerlan\HTTP\MagicAPI
8+
* @author smiley <smiley@chillerlan.net>
9+
* @copyright 2018 smiley
10+
* @license MIT
11+
*/
12+
13+
namespace chillerlan\HTTP\MagicAPI;
14+
15+
class ApiClientException extends \Exception{}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
/**
3+
* Interface ApiClientInterface
4+
*
5+
* @filesource ApiClientInterface.php
6+
* @created 01.09.2018
7+
* @package chillerlan\HTTP\MagicAPI
8+
* @author smiley <smiley@chillerlan.net>
9+
* @copyright 2018 smiley
10+
* @license MIT
11+
*/
12+
13+
namespace chillerlan\HTTP\MagicAPI;
14+
15+
use Psr\Http\Message\ResponseInterface;
16+
17+
interface ApiClientInterface{
18+
19+
/**
20+
* @param string $endpointMap
21+
*
22+
* @return \chillerlan\HTTP\MagicAPI\ApiClientInterface
23+
* @throws \chillerlan\HTTP\MagicAPI\ApiClientException
24+
*/
25+
public function loadEndpoints(string $endpointMap):ApiClientInterface;
26+
27+
/**
28+
* @param string $name
29+
* @param array $arguments
30+
*
31+
* @return \Psr\Http\Message\ResponseInterface
32+
*
33+
*/
34+
public function __call(string $name, array $arguments):ResponseInterface;
35+
36+
}

src/MagicAPI/ApiClientTrait.php

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?php
2+
/**
3+
* Trait ApiClientTrait
4+
*
5+
* @filesource ApiClientTrait.php
6+
* @created 07.04.2018
7+
* @package chillerlan\HTTP\MagicAPI
8+
* @author smiley <smiley@chillerlan.net>
9+
* @copyright 2018 smiley
10+
* @license MIT
11+
*/
12+
13+
namespace chillerlan\HTTP\MagicAPI;
14+
15+
use chillerlan\HTTP\Psr7;
16+
use Psr\Http\Message\ResponseInterface;
17+
use Psr\Log\LoggerInterface;
18+
use ReflectionClass;
19+
20+
/**
21+
* @link http://php.net/manual/language.oop5.magic.php#118617
22+
*
23+
* @implements chillerlan\MagicAPI\ApiClientInterface
24+
*
25+
* from \chillerlan\HTTP\HTTPClientInterface:
26+
* @method request(string $url, string $method = null, array $params = null, $body = null, array $headers = null):ResponseInterface
27+
*/
28+
trait ApiClientTrait{
29+
30+
/**
31+
* The logger instance.
32+
*
33+
* @var \Psr\Log\LoggerInterface
34+
*/
35+
protected $logger;
36+
37+
/**
38+
* @var \chillerlan\HTTP\MagicAPI\EndpointMapInterface
39+
*
40+
* method => [url, method, mandatory_params, params_in_url, ...]
41+
*/
42+
protected $endpoints;
43+
44+
/**
45+
* @param string $endpointMap
46+
*
47+
* @return \chillerlan\HTTP\MagicAPI\ApiClientInterface
48+
* @throws \chillerlan\HTTP\MagicAPI\ApiClientException
49+
*/
50+
public function loadEndpoints(string $endpointMap):ApiClientInterface{
51+
52+
if(class_exists($endpointMap)){
53+
$this->endpoints = new $endpointMap;
54+
55+
if(!$this->endpoints instanceof EndpointMapInterface){
56+
throw new ApiClientException('invalid endpoint map');
57+
}
58+
}
59+
60+
/** @noinspection PhpIncompatibleReturnTypeInspection */
61+
return $this;
62+
}
63+
64+
/**
65+
* ugly, isn't it?
66+
* @todo WIP
67+
*
68+
* @param string $name
69+
* @param array $arguments
70+
*
71+
* @return \Psr\Http\Message\ResponseInterface
72+
* @throws \chillerlan\HTTP\MagicAPI\APIClientException
73+
*/
74+
public function __call(string $name, array $arguments):ResponseInterface{
75+
76+
if(!$this->endpoints instanceof EndpointMapInterface || !$this->endpoints->__isset($name)){
77+
throw new ApiClientException('endpoint not found');
78+
}
79+
80+
$m = $this->endpoints->{$name};
81+
82+
$endpoint = $this->endpoints->API_BASE.$m['path'];
83+
$method = $m['method'] ?? 'GET';
84+
$body = null;
85+
$headers = isset($m['headers']) && is_array($m['headers']) ? $m['headers'] : [];
86+
$path_elements = $m['path_elements'] ?? [];
87+
$params_in_url = count($path_elements);
88+
$params = $arguments[$params_in_url] ?? [];
89+
$urlparams = array_slice($arguments, 0, $params_in_url);
90+
91+
if($params_in_url > 0){
92+
93+
if(count($urlparams) < $params_in_url){
94+
throw new APIClientException('too few URL params, required: '.implode(', ', $path_elements));
95+
}
96+
97+
$endpoint = sprintf($endpoint, ...$urlparams);
98+
}
99+
100+
if(in_array($method, ['DELETE', 'POST', 'PATCH', 'PUT'], true)){
101+
$body = $arguments[$params_in_url + 1] ?? $params;
102+
103+
if($params === $body){
104+
$params = [];
105+
}
106+
107+
if(is_iterable($body)){
108+
$body = Psr7\clean_query_params($body);
109+
}
110+
111+
}
112+
113+
$params = Psr7\clean_query_params($params);
114+
115+
if($this->logger instanceof LoggerInterface){
116+
117+
$this->logger->debug(get_called_class().'::__call() -> '.(new ReflectionClass($this))->getShortName().'::'.$name.'()', [
118+
'$endpoint' => $endpoint, '$method' => $method, '$params' => $params, '$body' => $body, '$headers' => $headers,
119+
]);
120+
121+
}
122+
123+
return $this->request($endpoint, $method, $params, $body, $headers);
124+
}
125+
126+
}

src/MagicAPI/EndpointMap.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/**
3+
* Class EndpointMap
4+
*
5+
* @filesource EndpointMap.php
6+
* @created 01.09.2018
7+
* @package chillerlan\HTTP\MagicAPI
8+
* @author smiley <smiley@chillerlan.net>
9+
* @copyright 2018 smiley
10+
* @license MIT
11+
*/
12+
13+
namespace chillerlan\HTTP\MagicAPI;
14+
15+
use chillerlan\Settings\SettingsContainerAbstract;
16+
17+
abstract class EndpointMap extends SettingsContainerAbstract implements EndpointMapInterface{
18+
19+
protected $API_BASE = '';
20+
21+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
/**
3+
* Interface EndpointMapInterface
4+
*
5+
* @filesource EndpointMapInterface.php
6+
* @created 01.09.2018
7+
* @package chillerlan\HTTP\MagicAPI
8+
* @author smiley <smiley@chillerlan.net>
9+
* @copyright 2018 smiley
10+
* @license MIT
11+
*/
12+
13+
namespace chillerlan\HTTP\MagicAPI;
14+
15+
use chillerlan\Settings\SettingsContainerInterface;
16+
17+
interface EndpointMapInterface extends SettingsContainerInterface{
18+
19+
}

0 commit comments

Comments
 (0)