Completed
Push — master ( 78d4e7...979ecb )
by smiley
02:57
created

ApiClientTrait::__call()   C

Complexity

Conditions 11
Paths 85

Size

Total Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
nc 85
nop 2
dl 0
loc 51
rs 6.9224
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Trait ApiClientTrait
4
 *
5
 * @filesource   ApiClientTrait.php
6
 * @created      07.04.2018
7
 * @package      chillerlan\HTTP\MagicAPI
8
 * @author       smiley <[email protected]>
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
0 ignored issues
show
Documentation introduced by
Should the return type not be ApiClientTrait?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
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
}
127