Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
declare(strict_types=1);
4
 
5
namespace GeoIp2\WebService;
6
 
7
use GeoIp2\Exception\AddressNotFoundException;
8
use GeoIp2\Exception\AuthenticationException;
9
use GeoIp2\Exception\GeoIp2Exception;
10
use GeoIp2\Exception\HttpException;
11
use GeoIp2\Exception\InvalidRequestException;
12
use GeoIp2\Exception\OutOfQueriesException;
13
use GeoIp2\Model\City;
14
use GeoIp2\Model\Country;
15
use GeoIp2\Model\Insights;
16
use GeoIp2\ProviderInterface;
17
use MaxMind\Exception\InsufficientFundsException;
18
use MaxMind\Exception\IpAddressNotFoundException;
19
use MaxMind\Exception\WebServiceException;
20
use MaxMind\WebService\Client as WsClient;
21
 
22
/**
23
 * This class provides a client API for all the GeoIP2 web services.
24
 * The services are Country, City Plus, and Insights. Each service returns
25
 * a different set of data about an IP address, with Country returning the
26
 * least data and Insights the most.
27
 *
28
 * Each web service is represented by a different model class, and these model
29
 * classes in turn contain multiple record classes. The record classes have
30
 * attributes which contain data about the IP address.
31
 *
32
 * If the web service does not return a particular piece of data for an IP
33
 * address, the associated attribute is not populated.
34
 *
35
 * The web service may not return any information for an entire record, in
36
 * which case all of the attributes for that record class will be empty.
37
 *
38
 * ## Usage ##
39
 *
40
 * The basic API for this class is the same for all of the web service end
41
 * points. First you create a web service object with your MaxMind `$accountId`
42
 * and `$licenseKey`, then you call the method corresponding to a specific end
43
 * point, passing it the IP address you want to look up.
44
 *
45
 * If the request succeeds, the method call will return a model class for
46
 * the service you called. This model in turn contains multiple record
47
 * classes, each of which represents part of the data returned by the web
48
 * service.
49
 *
50
 * If the request fails, the client class throws an exception.
51
 */
52
class Client implements ProviderInterface
53
{
54
    /**
55
     * @var array<string>
56
     */
57
    private array $locales;
58
    private WsClient $client;
59
    private static string $basePath = '/geoip/v2.1';
60
 
61
    public const VERSION = 'v3.1.0';
62
 
63
    /**
64
     * Constructor.
65
     *
66
     * @param int                  $accountId  your MaxMind account ID
67
     * @param string               $licenseKey your MaxMind license key
68
     * @param list<string>         $locales    list of locale codes to use in name property
69
     *                                         from most preferred to least preferred
70
     * @param array<string, mixed> $options    array of options. Valid options include:
71
     *                                         * `host` - The host to use when querying the web
72
     *                                         service. To query the GeoLite2 web service
73
     *                                         instead of the GeoIP2 web service, set the
74
     *                                         host to `geolite.info`. To query the Sandbox
75
     *                                         GeoIP2 web service instead of the production
76
     *                                         GeoIP2 web service, set the host to
77
     *                                         `sandbox.maxmind.com`. The sandbox allows you to
78
     *                                         experiment with the API without affecting your
79
     *                                         production data.
80
     *                                         * `timeout` - Timeout in seconds.
81
     *                                         * `connectTimeout` - Initial connection timeout in seconds.
82
     *                                         * `proxy` - The HTTP proxy to use. May include a schema, port,
83
     *                                         username, and password, e.g.,
84
     *                                         `http://username:password@127.0.0.1:10`.
85
     */
86
    public function __construct(
87
        int $accountId,
88
        string $licenseKey,
89
        array $locales = ['en'],
90
        array $options = []
91
    ) {
92
        $this->locales = $locales;
93
 
94
        // This is for backwards compatibility. Do not remove except for a
95
        // major version bump.
96
        // @phpstan-ignore-next-line
97
        if (\is_string($options)) {
98
            $options = ['host' => $options];
99
        }
100
 
101
        if (!isset($options['host'])) {
102
            $options['host'] = 'geoip.maxmind.com';
103
        }
104
 
105
        $options['userAgent'] = $this->userAgent();
106
 
107
        $this->client = new WsClient($accountId, $licenseKey, $options);
108
    }
109
 
110
    private function userAgent(): string
111
    {
112
        return 'GeoIP2-API/' . self::VERSION;
113
    }
114
 
115
    /**
116
     * This method calls the City Plus service.
117
     *
118
     * @param string $ipAddress IPv4 or IPv6 address as a string. If no
119
     *                          address is provided, the address that the web service is called
120
     *                          from will be used.
121
     *
122
     * @throws AddressNotFoundException  if the address you provided is not in our database (e.g.,
123
     *                                   a private address).
124
     * @throws AuthenticationException   if there is a problem with the account ID or license key
125
     *                                   that you provided
126
     * @throws OutOfQueriesException     if your account is out of queries
127
     * @throws InvalidRequestException   if your request was received by the web service but is
128
     *                                   invalid for some other reason.  This may indicate an issue
129
     *                                   with this API. Please report the error to MaxMind.
130
     * @throws HttpException             if an unexpected HTTP error code or message was returned.
131
     *                                   This could indicate a problem with the connection between
132
     *                                   your server and the web service or that the web service
133
     *                                   returned an invalid document or 500 error code
134
     * @throws GeoIp2Exception           This serves as the parent
135
     *                                   class to the above exceptions. It will be thrown directly
136
     *                                   if a 200 status code is returned but the body is invalid.
137
     * @throws \InvalidArgumentException if something other than a single IP address or "me" is
138
     *                                   passed to the method
139
     */
140
    public function city(string $ipAddress = 'me'): City
141
    {
142
        // @phpstan-ignore-next-line
143
        return $this->responseFor('city', City::class, $ipAddress);
144
    }
145
 
146
    /**
147
     * This method calls the Country service.
148
     *
149
     * @param string $ipAddress IPv4 or IPv6 address as a string. If no
150
     *                          address is provided, the address that the web service is called
151
     *                          from will be used.
152
     *
153
     * @throws AddressNotFoundException  if the address you provided is not in our database (e.g.,
154
     *                                   a private address).
155
     * @throws AuthenticationException   if there is a problem with the account ID or license key that you provided
156
     * @throws OutOfQueriesException     if your account is out of queries
157
     * @throws InvalidRequestException   if your request was received by the web service but is
158
     *                                   invalid for some other reason.  This may indicate an
159
     *                                   issue with this API. Please report the error to MaxMind.
160
     * @throws HttpException             if an unexpected HTTP error
161
     *                                   code or message was returned. This could indicate a problem
162
     *                                   with the connection between your server and the web service
163
     *                                   or that the web service returned an invalid document or 500
164
     *                                   error code.
165
     * @throws GeoIp2Exception           This serves as the parent class to the above exceptions. It
166
     *                                   will be thrown directly if a 200 status code is returned but
167
     *                                   the body is invalid.
168
     * @throws \InvalidArgumentException if something other than a single IP address or "me" is
169
     *                                   passed to the method
170
     */
171
    public function country(string $ipAddress = 'me'): Country
172
    {
173
        return $this->responseFor('country', Country::class, $ipAddress);
174
    }
175
 
176
    /**
177
     * This method calls the Insights service. Insights is only supported by
178
     * the GeoIP2 web service. The GeoLite2 web service does not support it.
179
     *
180
     * @param string $ipAddress IPv4 or IPv6 address as a string. If no
181
     *                          address is provided, the address that the web service is called
182
     *                          from will be used.
183
     *
184
     * @throws AddressNotFoundException  if the address you provided is not in our database (e.g.,
185
     *                                   a private address).
186
     * @throws AuthenticationException   if there is a problem with the account ID or license key
187
     *                                   that you provided
188
     * @throws OutOfQueriesException     if your account is out of queries
189
     * @throws InvalidRequestException   if your request was received by the web service but is
190
     *                                   invalid for some other reason.  This may indicate an
191
     *                                   issue with this API. Please report the error to MaxMind.
192
     * @throws HttpException             if an unexpected HTTP error code or message was returned.
193
     *                                   This could indicate a problem with the connection between
194
     *                                   your server and the web service or that the web service
195
     *                                   returned an invalid document or 500 error code
196
     * @throws GeoIp2Exception           This serves as the parent
197
     *                                   class to the above exceptions. It will be thrown directly
198
     *                                   if a 200 status code is returned but the body is invalid.
199
     * @throws \InvalidArgumentException if something other than a single IP address or "me" is
200
     *                                   passed to the method
201
     */
202
    public function insights(string $ipAddress = 'me'): Insights
203
    {
204
        // @phpstan-ignore-next-line
205
        return $this->responseFor('insights', Insights::class, $ipAddress);
206
    }
207
 
208
    private function responseFor(string $endpoint, string $class, string $ipAddress): Country
209
    {
210
        if ($ipAddress !== 'me' && !filter_var($ipAddress, \FILTER_VALIDATE_IP)) {
211
            throw new \InvalidArgumentException(
212
                "The value \"$ipAddress\" is not a valid IP address."
213
            );
214
        }
215
        $path = implode('/', [self::$basePath, $endpoint, $ipAddress]);
216
 
217
        try {
218
            $service = (new \ReflectionClass($class))->getShortName();
219
            $body = $this->client->get('GeoIP2 ' . $service, $path);
220
        } catch (IpAddressNotFoundException $ex) {
221
            throw new AddressNotFoundException(
222
                $ex->getMessage(),
223
                $ex->getStatusCode(),
224
                $ex
225
            );
226
        } catch (\MaxMind\Exception\AuthenticationException $ex) {
227
            throw new AuthenticationException(
228
                $ex->getMessage(),
229
                $ex->getStatusCode(),
230
                $ex
231
            );
232
        } catch (InsufficientFundsException $ex) {
233
            throw new OutOfQueriesException(
234
                $ex->getMessage(),
235
                $ex->getStatusCode(),
236
                $ex
237
            );
238
        } catch (\MaxMind\Exception\InvalidRequestException $ex) {
239
            throw new InvalidRequestException(
240
                $ex->getMessage(),
241
                $ex->getErrorCode(),
242
                $ex->getStatusCode(),
243
                $ex->getUri(),
244
                $ex
245
            );
246
        } catch (\MaxMind\Exception\HttpException $ex) {
247
            throw new HttpException(
248
                $ex->getMessage(),
249
                $ex->getStatusCode(),
250
                $ex->getUri(),
251
                $ex
252
            );
253
        } catch (WebServiceException $ex) {
254
            throw new GeoIp2Exception(
255
                $ex->getMessage(),
256
                $ex->getCode(),
257
                $ex
258
            );
259
        }
260
 
261
        return new $class($body, $this->locales);
262
    }
263
}