Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]

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