Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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\WebService\Client as WsClient;
18
 
19
/**
20
 * This class provides a client API for all the GeoIP2 web services.
21
 * The services are Country, City Plus, and Insights. Each service returns
22
 * a different set of data about an IP address, with Country returning the
23
 * least data and Insights the most.
24
 *
25
 * Each web service is represented by a different model class, and these model
26
 * classes in turn contain multiple record classes. The record classes have
27
 * attributes which contain data about the IP address.
28
 *
29
 * If the web service does not return a particular piece of data for an IP
30
 * address, the associated attribute is not populated.
31
 *
32
 * The web service may not return any information for an entire record, in
33
 * which case all of the attributes for that record class will be empty.
34
 *
35
 * ## Usage ##
36
 *
37
 * The basic API for this class is the same for all of the web service end
38
 * points. First you create a web service object with your MaxMind `$accountId`
39
 * and `$licenseKey`, then you call the method corresponding to a specific end
40
 * point, passing it the IP address you want to look up.
41
 *
42
 * If the request succeeds, the method call will return a model class for
43
 * the service you called. This model in turn contains multiple record
44
 * classes, each of which represents part of the data returned by the web
45
 * service.
46
 *
47
 * If the request fails, the client class throws an exception.
48
 */
49
class Client implements ProviderInterface
50
{
51
    /**
52
     * @var array<string>
53
     */
54
    private $locales;
55
 
56
    /**
57
     * @var WsClient
58
     */
59
    private $client;
60
 
61
    /**
62
     * @var string
63
     */
64
    private static $basePath = '/geoip/v2.1';
65
 
66
    public const VERSION = 'v2.13.0';
67
 
68
    /**
69
     * Constructor.
70
     *
71
     * @param int    $accountId  your MaxMind account ID
72
     * @param string $licenseKey your MaxMind license key
73
     * @param array  $locales    list of locale codes to use in name property
74
     *                           from most preferred to least preferred
75
     * @param array  $options    array of options. Valid options include:
76
     *                           * `host` - The host to use when querying the web
77
     *                           service. To query the GeoLite2 web service
78
     *                           instead of the GeoIP2 web service, set the
79
     *                           host to `geolite.info`.
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 \GeoIp2\Exception\AddressNotFoundException if the address you
123
     *                                                    provided is not in our database (e.g., a private address).
124
     * @throws \GeoIp2\Exception\AuthenticationException  if there is a problem
125
     *                                                    with the account ID or license key that you provided
126
     * @throws \GeoIp2\Exception\OutOfQueriesException    if your account is out
127
     *                                                    of queries
128
     * @throws \GeoIp2\Exception\InvalidRequestException} if your request was received by the web service but is
129
     *                                                    invalid for some other reason.  This may indicate an issue
130
     *                                                    with this API. Please report the error to MaxMind.
131
     * @throws \GeoIp2\Exception\HttpException   if an unexpected HTTP error code or message was returned.
132
     *                                           This could indicate a problem with the connection between
133
     *                                           your server and the web service or that the web service
134
     *                                           returned an invalid document or 500 error code
135
     * @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent
136
     *                                           class to the above exceptions. It will be thrown directly
137
     *                                           if a 200 status code is returned but the body is invalid.
138
     */
139
    public function city(string $ipAddress = 'me'): City
140
    {
141
        // @phpstan-ignore-next-line
142
        return $this->responseFor('city', City::class, $ipAddress);
143
    }
144
 
145
    /**
146
     * This method calls the Country service.
147
     *
148
     * @param string $ipAddress IPv4 or IPv6 address as a string. If no
149
     *                          address is provided, the address that the web service is called
150
     *                          from will be used.
151
     *
152
     * @throws \GeoIp2\Exception\AddressNotFoundException if the address you provided is not in our database (e.g.,
153
     *                                                    a private address).
154
     * @throws \GeoIp2\Exception\AuthenticationException  if there is a problem
155
     *                                                    with the account ID or license key that you provided
156
     * @throws \GeoIp2\Exception\OutOfQueriesException    if your account is out of queries
157
     * @throws \GeoIp2\Exception\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 \GeoIp2\Exception\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 \GeoIp2\Exception\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
     */
169
    public function country(string $ipAddress = 'me'): Country
170
    {
171
        return $this->responseFor('country', Country::class, $ipAddress);
172
    }
173
 
174
    /**
175
     * This method calls the Insights service. Insights is only supported by
176
     * the GeoIP2 web service. The GeoLite2 web service does not support it.
177
     *
178
     * @param string $ipAddress IPv4 or IPv6 address as a string. If no
179
     *                          address is provided, the address that the web service is called
180
     *                          from will be used.
181
     *
182
     * @throws \GeoIp2\Exception\AddressNotFoundException if the address you
183
     *                                                    provided is not in our database (e.g., a private address).
184
     * @throws \GeoIp2\Exception\AuthenticationException  if there is a problem
185
     *                                                    with the account ID or license key that you provided
186
     * @throws \GeoIp2\Exception\OutOfQueriesException    if your account is out
187
     *                                                    of queries
188
     * @throws \GeoIp2\Exception\InvalidRequestException} if your request was received by the web service but is
189
     *                                                    invalid for some other reason.  This may indicate an
190
     *                                                    issue with this API. Please report the error to MaxMind.
191
     * @throws \GeoIp2\Exception\HttpException   if an unexpected HTTP error code or message was returned.
192
     *                                           This could indicate a problem with the connection between
193
     *                                           your server and the web service or that the web service
194
     *                                           returned an invalid document or 500 error code
195
     * @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent
196
     *                                           class to the above exceptions. It will be thrown directly
197
     *                                           if a 200 status code is returned but the body is invalid.
198
     */
199
    public function insights(string $ipAddress = 'me'): Insights
200
    {
201
        // @phpstan-ignore-next-line
202
        return $this->responseFor('insights', Insights::class, $ipAddress);
203
    }
204
 
205
    private function responseFor(string $endpoint, string $class, string $ipAddress): Country
206
    {
207
        $path = implode('/', [self::$basePath, $endpoint, $ipAddress]);
208
 
209
        try {
210
            $service = (new \ReflectionClass($class))->getShortName();
211
            $body = $this->client->get('GeoIP2 ' . $service, $path);
212
        } catch (\MaxMind\Exception\IpAddressNotFoundException $ex) {
213
            throw new AddressNotFoundException(
214
                $ex->getMessage(),
215
                $ex->getStatusCode(),
216
                $ex
217
            );
218
        } catch (\MaxMind\Exception\AuthenticationException $ex) {
219
            throw new AuthenticationException(
220
                $ex->getMessage(),
221
                $ex->getStatusCode(),
222
                $ex
223
            );
224
        } catch (\MaxMind\Exception\InsufficientFundsException $ex) {
225
            throw new OutOfQueriesException(
226
                $ex->getMessage(),
227
                $ex->getStatusCode(),
228
                $ex
229
            );
230
        } catch (\MaxMind\Exception\InvalidRequestException $ex) {
231
            throw new InvalidRequestException(
232
                $ex->getMessage(),
233
                $ex->getErrorCode(),
234
                $ex->getStatusCode(),
235
                $ex->getUri(),
236
                $ex
237
            );
238
        } catch (\MaxMind\Exception\HttpException $ex) {
239
            throw new HttpException(
240
                $ex->getMessage(),
241
                $ex->getStatusCode(),
242
                $ex->getUri(),
243
                $ex
244
            );
245
        } catch (\MaxMind\Exception\WebServiceException $ex) {
246
            throw new GeoIp2Exception(
247
                $ex->getMessage(),
248
                $ex->getCode(),
249
                $ex
250
            );
251
        }
252
 
253
        return new $class($body, $this->locales);
254
    }
255
}