Test Failed
Push — master ( cd83ee...0a7302 )
by Carsten
03:39 queued 11s
created

HttpClientLocationCreator::setNotFoundLoglevel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
namespace Germania\ClientIpLocation;
3
4
use Psr\Http\Client\ClientInterface;
5
use Psr\Http\Client\ClientExceptionInterface;
6
use Psr\Http\Client\RequestExceptionInterface;
7
8
use Psr\Http\Message\RequestInterface;
9
use Psr\Http\Message\RequestFactoryInterface;
10
use Psr\Http\Message\ResponseInterface;
11
12
use Psr\Log\LoggerInterface;
13
use Psr\Log\NullLogger;
14
use Psr\Log\LogLevel;
15
use Psr\Log\LoggerAwareTrait;
16
17
class HttpClientLocationCreator
18
{
19 1
    use LoggerAwareTrait;
20
21
    /**
22
     * @var ClientInterface
23
     */
24
    protected $client;
25
26
27
    /**
28
     * @var RequestFactoryInterface
29
     */
30
    public $request_factory;
31
32
33
    /**
34
     * Geocoder API endpoint.
35
     *
36
     * @var string
37
     */
38
    public $api;
39
40
41
    /**
42
     * IP adress query parameter
43
     *
44
     * @var string
45
     */
46
    public $ip_var_name = "ip";
47
48
49
    /**
50
     * @var callable
51
     */
52
    public $response_decoder;
53
54
55
    /**
56
     * @var mixed
57
     */
58
    public $default_location;
59
60
61
    /**
62
     * @var string
63
     */
64
    protected $error_loglevel = LogLevel::ERROR;
65
66
67
    /**
68
     * @var string
69
     */
70
    protected $notfound_loglevel = LogLevel::NOTICE;
71
72
73 2
    /**
74
     * @param string                  $api              Geocoder API endpoint
75 2
     * @param ClientInterface         $client           PSR-18 HTTP Client
76 2
     * @param RequestFactoryInterface $request_factory  PSR-17 Request factory
77 2
     * @param callable|null           $response_decoder Optional: PSR-7 Response decoder callable
78 2
     */
79 2
    public function __construct( string $api, ClientInterface $client, RequestFactoryInterface $request_factory, callable $response_decoder = null, LoggerInterface $logger = null)
80 2
    {
81
        $this->setApiEndpoint( $api )
82
             ->setClient($client)
83
             ->setRequestFactory($request_factory)
84
             ->setResponseDecoder($response_decoder)
85
             ->setLogger( $logger ?: new NullLogger);
86
    }
87 2
88
89 2
90
    /**
91
     * @param  string $client_ip Client IP address
92 2
     */
93 2
    public function __invoke( string $client_ip )
94
    {
95
        $request = $this->createRequest($client_ip);
96
97
        try {
98
            $response = $this->client->sendRequest( $request);
99
            $response_status = $response->getStatusCode();
100
101
            if ($response_status == 404) {
102
                $this->logger->log( $this->notfound_loglevel, "Could not determine client location, proceed with default location", [
103
                    'request' => $request->getUri()->__toString(),
104
                    'responseStatus' => $response_status,
105
                    'apiEndpoint' => $this->api,
106
                    'clientIp' => $client_ip
107
                ]);
108
                return $this->default_location;
109
            }
110
111
            return $this->decodeResponse($response);
112
        }
113
        catch (\Throwable $e) {
114
            $response_status = (!empty($response) && $response instanceOf ResponseInterface)
115 4
                            ? $response->getStatusCode()
116
                            : null;
117 4
118 4
            $msg = sprintf("Exception caught in HttpClientLocationCreator: %s", $e->getMessage());
119
            $msg_location = sprintf("%s:%s", $e->getFile(), $e->getLine());
120 4
            $this->logger->log( $this->error_loglevel, $msg, [
121
                'type' => get_class($e),
122 4
                'code' => $e->getCode(),
123
                'request' => $request->getUri()->__toString(),
124
                'responseStatus' => $response_status,
125
                'location' => $msg_location,
126
                'apiEndpoint' => $this->api,
127
                'clientIp' => $client_ip
128
            ]);
129
130
            return $this->default_location;
131 4
        }
132
    }
133 4
134 4
135 4
136
    /**
137
     * @param  string $client_ip Client IP address
138
     * @return RequestInterface
139
     */
140
    public function createRequest( string $client_ip ) : RequestInterface
141
    {
142
        $client_ip_urlencoded = urlencode($client_ip);
143
        $query_parameter_field = "{{" . $this->ip_var_name . "}}";
144
145 2
        $api = str_replace($query_parameter_field, $client_ip_urlencoded, $this->api);
146
147 2
        return $this->request_factory->createRequest("GET", $api);
148 2
    }
149
150
151
152
    /**
153
     * @param  ResponseInterface $response
154
     * @return mixed
155
     */
156
    public function decodeResponse(ResponseInterface $response)
157
    {
158 4
        return $this->response_decoder
159
        ? ($this->response_decoder)($response)
160 4
        : json_decode($response->getBody(), "assoc");
161 4
    }
162
163
164
165
    /**
166
     * Sets the default location to return on error
167
     *
168
     * @param mixed $location
169
     */
170
    public function setDefaultLocation( $location ) : self
171 6
    {
172
        $this->default_location = $location;
173 6
        return $this;
174 6
    }
175
176
177
    /**
178
     * @param string $error_loglevel PSR-3 Loglevel name
179
     */
180
    public function setErrorLoglevel( string $error_loglevel ) {
181
        $this->error_loglevel = $error_loglevel;
182
        return $this;
183 4
    }
184
185 4
186 4
187
    /**
188
     * @param string $notfound_loglevel PSR-3 Loglevel name
189
     */
190
    public function setNotFoundLoglevel( string $notfound_loglevel ) {
191
        $this->notfound_loglevel = $notfound_loglevel;
192
        return $this;
193
    }
194
195 4
196
    /**
197 4
     * Sets the API endpoint
198 4
     *
199
     * @param string $api
200
     */
201
    public function setApiEndpoint( string $api ) : self
202
    {
203
        $this->api = $api;
204
        return $this;
205
    }
206
207
208
209
    /**
210
     * Sets the HTTP Client to use.
211
     *
212
     * @param ClientInterface $client
213
     */
214
    public function setClient( ClientInterface $client ) : self
215
    {
216
        $this->client = $client;
217
        return $this;
218
    }
219
220
221
    /**
222
     * Sets the PSR-17 Request factory
223
     *
224
     * @param RequestFactoryInterface $request_factory
225
     */
226
    public function setRequestFactory( RequestFactoryInterface $request_factory ) : self
227
    {
228
        $this->request_factory = $request_factory;
229
        return $this;
230
    }
231
232
233
    /**
234
     * Sets the PSR-7 Response decoder callable.
235
     *
236
     * @param callable $response_decoder
237
     */
238
    public function setResponseDecoder( callable $response_decoder = null ) : self
239
    {
240
        $this->response_decoder = $response_decoder;
241
        return $this;
242
    }
243
244
}
245