diff --git a/public/lib/maxmind/GeoIp2/CHANGELOG.md b/public/lib/maxmind/GeoIp2/CHANGELOG.md index 7f01bd2c270..ef655e327a9 100644 --- a/public/lib/maxmind/GeoIp2/CHANGELOG.md +++ b/public/lib/maxmind/GeoIp2/CHANGELOG.md @@ -1,6 +1,15 @@ CHANGELOG ========= +3.2.0 (2025-05-05) +------------------ + +* Support for the GeoIP Anonymous Plus database has been added. To do a + lookup in this database, use the `anonymousPlus` method on + `GeoIP2\Database\Reader`. +* `metroCode` on `GeoIp2\Record\Location` has been deprecated. The code + values are no longer being maintained. + 3.1.0 (2024-11-15) ------------------ @@ -15,7 +24,7 @@ CHANGELOG * IMPORTANT: PHP 8.1 or greater is now required. * BREAKING: Read-only properties are now used for the model and record classes rather than magic methods. This significantly improves performance. -* BREAKING: The `raw` property on model classess and the `record` property on +* BREAKING: The `raw` property on model classes and the `record` property on record classes have been removed. * BREAKING: On `GeoIp2\Record\Traits`, the deprecated `isAnonymousProxy` and `isSatelliteProvider` properties have been removed. diff --git a/public/lib/maxmind/GeoIp2/README.md b/public/lib/maxmind/GeoIp2/README.md index 9121b7252bb..e2d6b6e9e08 100644 --- a/public/lib/maxmind/GeoIp2/README.md +++ b/public/lib/maxmind/GeoIp2/README.md @@ -162,6 +162,28 @@ print($record->network . "\n"); // '128.101.101.101/32' ``` +### Anonymous Plus Example ### + +```php +anonymousIp('203.0.113.0'); + +print($record->anonymizerConfidence . "\n"); // 30 +print($record->networkLastSeen . "\n"); // '2025-04-14' +print($record->providerName . "\n"); // 'FooBar VPN' + +print($record->ipAddress . "\n"); // '203.0.113.0' +print($record->network . "\n"); // '203.0.113.0/32' + +``` + ### Connection-Type Example ### ```php @@ -443,6 +465,6 @@ The GeoIP2 PHP API uses [Semantic Versioning](https://semver.org/). ## Copyright and License ## -This software is Copyright (c) 2013-2024 by MaxMind, Inc. +This software is Copyright (c) 2013-2025 by MaxMind, Inc. This is free software, licensed under the Apache License, Version 2.0. diff --git a/public/lib/maxmind/GeoIp2/composer.json b/public/lib/maxmind/GeoIp2/composer.json index 6d1f07bf61a..4c7fbfab37b 100644 --- a/public/lib/maxmind/GeoIp2/composer.json +++ b/public/lib/maxmind/GeoIp2/composer.json @@ -13,7 +13,7 @@ } ], "require": { - "maxmind-db/reader": "^1.12.0", + "maxmind-db/reader": "^1.12.1", "maxmind/web-service-common": "~0.10", "php": ">=8.1", "ext-json": "*" diff --git a/public/lib/maxmind/GeoIp2/src/Database/Reader.php b/public/lib/maxmind/GeoIp2/src/Database/Reader.php index 9e3a128a754..8fcce9b9937 100644 --- a/public/lib/maxmind/GeoIp2/src/Database/Reader.php +++ b/public/lib/maxmind/GeoIp2/src/Database/Reader.php @@ -6,6 +6,7 @@ namespace GeoIp2\Database; use GeoIp2\Exception\AddressNotFoundException; use GeoIp2\Model\AnonymousIp; +use GeoIp2\Model\AnonymousPlus; use GeoIp2\Model\Asn; use GeoIp2\Model\City; use GeoIp2\Model\ConnectionType; @@ -44,14 +45,8 @@ use MaxMind\Db\Reader\Metadata; */ class Reader implements ProviderInterface { - private DbReader $dbReader; - - private string $dbType; - - /** - * @var array - */ - private array $locales; + private readonly DbReader $dbReader; + private readonly string $dbType; /** * Constructor. @@ -64,11 +59,11 @@ class Reader implements ProviderInterface */ public function __construct( string $filename, - array $locales = ['en'] + /** @var array */ + public readonly array $locales = ['en'] ) { $this->dbReader = new DbReader($filename); $this->dbType = $this->dbReader->metadata()->databaseType; - $this->locales = $locales; } /** @@ -78,6 +73,7 @@ class Reader implements ProviderInterface * * @throws AddressNotFoundException if the address is not in the database * @throws InvalidDatabaseException if the database is corrupt or invalid + * @throws \BadMethodCallException if this database type is not supported */ public function city(string $ipAddress): City { @@ -91,6 +87,7 @@ class Reader implements ProviderInterface * * @throws AddressNotFoundException if the address is not in the database * @throws InvalidDatabaseException if the database is corrupt or invalid + * @throws \BadMethodCallException if this database type is not supported */ public function country(string $ipAddress): Country { @@ -104,6 +101,7 @@ class Reader implements ProviderInterface * * @throws AddressNotFoundException if the address is not in the database * @throws InvalidDatabaseException if the database is corrupt or invalid + * @throws \BadMethodCallException if this database type is not supported */ public function anonymousIp(string $ipAddress): AnonymousIp { @@ -114,6 +112,24 @@ class Reader implements ProviderInterface ); } + /** + * This method returns a GeoIP Anonymous Plus model. + * + * @param string $ipAddress an IPv4 or IPv6 address as a string + * + * @throws AddressNotFoundException if the address is not in the database + * @throws InvalidDatabaseException if the database is corrupt or invalid + * @throws \BadMethodCallException if this database type is not supported + */ + public function anonymousPlus(string $ipAddress): AnonymousPlus + { + return $this->flatModelFor( + AnonymousPlus::class, + 'GeoIP-Anonymous-Plus', + $ipAddress + ); + } + /** * This method returns a GeoLite2 ASN model. * @@ -121,6 +137,7 @@ class Reader implements ProviderInterface * * @throws AddressNotFoundException if the address is not in the database * @throws InvalidDatabaseException if the database is corrupt or invalid + * @throws \BadMethodCallException if this database type is not supported */ public function asn(string $ipAddress): Asn { @@ -138,6 +155,7 @@ class Reader implements ProviderInterface * * @throws AddressNotFoundException if the address is not in the database * @throws InvalidDatabaseException if the database is corrupt or invalid + * @throws \BadMethodCallException if this database type is not supported */ public function connectionType(string $ipAddress): ConnectionType { @@ -155,6 +173,7 @@ class Reader implements ProviderInterface * * @throws AddressNotFoundException if the address is not in the database * @throws InvalidDatabaseException if the database is corrupt or invalid + * @throws \BadMethodCallException if this database type is not supported */ public function domain(string $ipAddress): Domain { @@ -172,6 +191,7 @@ class Reader implements ProviderInterface * * @throws AddressNotFoundException if the address is not in the database * @throws InvalidDatabaseException if the database is corrupt or invalid + * @throws \BadMethodCallException if this database type is not supported */ public function enterprise(string $ipAddress): Enterprise { @@ -185,6 +205,7 @@ class Reader implements ProviderInterface * * @throws AddressNotFoundException if the address is not in the database * @throws InvalidDatabaseException if the database is corrupt or invalid + * @throws \BadMethodCallException if this database type is not supported */ public function isp(string $ipAddress): Isp { diff --git a/public/lib/maxmind/GeoIp2/src/Model/AnonymousPlus.php b/public/lib/maxmind/GeoIp2/src/Model/AnonymousPlus.php new file mode 100644 index 00000000000..bfb0c569c6a --- /dev/null +++ b/public/lib/maxmind/GeoIp2/src/Model/AnonymousPlus.php @@ -0,0 +1,66 @@ + $raw + */ + public function __construct(array $raw) + { + parent::__construct($raw); + $this->anonymizerConfidence = $raw['anonymizer_confidence'] ?? null; + $this->networkLastSeen = $raw['network_last_seen'] ?? null; + $this->providerName = $raw['provider_name'] ?? null; + } + + /** + * @return array|null + */ + public function jsonSerialize(): ?array + { + $js = parent::jsonSerialize(); + + if ($this->anonymizerConfidence !== null) { + $js['anonymizer_confidence'] = $this->anonymizerConfidence; + } + + if ($this->networkLastSeen !== null) { + $js['network_last_seen'] = $this->networkLastSeen; + } + + if ($this->providerName !== null) { + $js['provider_name'] = $this->providerName; + } + + return $js; + } +} diff --git a/public/lib/maxmind/GeoIp2/src/Model/Asn.php b/public/lib/maxmind/GeoIp2/src/Model/Asn.php index 5feae2f0f4b..02e16727a02 100644 --- a/public/lib/maxmind/GeoIp2/src/Model/Asn.php +++ b/public/lib/maxmind/GeoIp2/src/Model/Asn.php @@ -45,8 +45,8 @@ class Asn implements \JsonSerializable public function __construct(array $raw) { $this->autonomousSystemNumber = $raw['autonomous_system_number'] ?? null; - $this->autonomousSystemOrganization = - $raw['autonomous_system_organization'] ?? null; + $this->autonomousSystemOrganization + = $raw['autonomous_system_organization'] ?? null; $ipAddress = $raw['ip_address']; $this->ipAddress = $ipAddress; $this->network = Util::cidr($ipAddress, $raw['prefix_len']); diff --git a/public/lib/maxmind/GeoIp2/src/Model/City.php b/public/lib/maxmind/GeoIp2/src/Model/City.php index bf2323ed45a..739a7e1f731 100644 --- a/public/lib/maxmind/GeoIp2/src/Model/City.php +++ b/public/lib/maxmind/GeoIp2/src/Model/City.php @@ -43,18 +43,18 @@ class City extends Country public readonly Postal $postal; /** - * @var array<\GeoIp2\Record\Subdivision> An array of \GeoIp2\Record\Subdivision - * objects representing the country - * subdivisions for the requested IP - * address. The number and type of - * subdivisions varies by country, - * but a subdivision is typically a - * state, province, county, etc. - * Subdivisions are ordered from most - * general (largest) to most specific - * (smallest). If the response did - * not contain any subdivisions, this - * method returns an empty array. + * @var array An array of \GeoIp2\Record\Subdivision + * objects representing the country + * subdivisions for the requested IP + * address. The number and type of + * subdivisions varies by country, + * but a subdivision is typically a + * state, province, county, etc. + * Subdivisions are ordered from most + * general (largest) to most specific + * (smallest). If the response did + * not contain any subdivisions, this + * method returns an empty array. */ public readonly array $subdivisions; @@ -74,22 +74,22 @@ class City extends Country if (!isset($raw['subdivisions'])) { $this->subdivisions = []; - $this->mostSpecificSubdivision = - new Subdivision([], $locales); + $this->mostSpecificSubdivision + = new Subdivision([], $locales); return; } $subdivisions = []; foreach ($raw['subdivisions'] as $sub) { - $subdivisions[] = - new Subdivision($sub, $locales) + $subdivisions[] + = new Subdivision($sub, $locales) ; } // Not using end as we don't want to modify internal pointer. - $this->mostSpecificSubdivision = - $subdivisions[\count($subdivisions) - 1]; + $this->mostSpecificSubdivision + = $subdivisions[\count($subdivisions) - 1]; $this->subdivisions = $subdivisions; } @@ -110,8 +110,8 @@ class City extends Country $js['location'] = $location; } - $postal = - $this->postal->jsonSerialize(); + $postal + = $this->postal->jsonSerialize(); if (!empty($postal)) { $js['postal'] = $postal; } diff --git a/public/lib/maxmind/GeoIp2/src/Model/Isp.php b/public/lib/maxmind/GeoIp2/src/Model/Isp.php index 6b9130510cc..445e056cdb5 100644 --- a/public/lib/maxmind/GeoIp2/src/Model/Isp.php +++ b/public/lib/maxmind/GeoIp2/src/Model/Isp.php @@ -71,8 +71,8 @@ class Isp implements \JsonSerializable public function __construct(array $raw) { $this->autonomousSystemNumber = $raw['autonomous_system_number'] ?? null; - $this->autonomousSystemOrganization = - $raw['autonomous_system_organization'] ?? null; + $this->autonomousSystemOrganization + = $raw['autonomous_system_organization'] ?? null; $this->isp = $raw['isp'] ?? null; $this->mobileCountryCode = $raw['mobile_country_code'] ?? null; $this->mobileNetworkCode = $raw['mobile_network_code'] ?? null; diff --git a/public/lib/maxmind/GeoIp2/src/Record/Location.php b/public/lib/maxmind/GeoIp2/src/Record/Location.php index 6172ac83c64..76dc86d5592 100644 --- a/public/lib/maxmind/GeoIp2/src/Record/Location.php +++ b/public/lib/maxmind/GeoIp2/src/Record/Location.php @@ -43,10 +43,10 @@ class Location implements \JsonSerializable public readonly ?float $longitude; /** - * @var int|null The metro code of the location if the location - * is in the US. MaxMind returns the same metro codes as the - * Google AdWords API. See - * https://developers.google.com/adwords/api/docs/appendix/cities-DMAregions. + * @var int|null the metro code is a no-longer-maintained code for targeting + * advertisements in Google + * + * @deprecated */ public readonly ?int $metroCode; diff --git a/public/lib/maxmind/GeoIp2/src/WebService/Client.php b/public/lib/maxmind/GeoIp2/src/WebService/Client.php index fb3966eff4c..debe8e84fce 100644 --- a/public/lib/maxmind/GeoIp2/src/WebService/Client.php +++ b/public/lib/maxmind/GeoIp2/src/WebService/Client.php @@ -51,14 +51,10 @@ use MaxMind\WebService\Client as WsClient; */ class Client implements ProviderInterface { - /** - * @var array - */ - private array $locales; - private WsClient $client; + private readonly WsClient $client; private static string $basePath = '/geoip/v2.1'; - public const VERSION = 'v3.1.0'; + public const VERSION = 'v3.2.0'; /** * Constructor. @@ -86,11 +82,10 @@ class Client implements ProviderInterface public function __construct( int $accountId, string $licenseKey, - array $locales = ['en'], + /** @var list */ + public readonly array $locales = ['en'], // Promoted and readonly array $options = [] ) { - $this->locales = $locales; - // This is for backwards compatibility. Do not remove except for a // major version bump. // @phpstan-ignore-next-line @@ -98,9 +93,7 @@ class Client implements ProviderInterface $options = ['host' => $options]; } - if (!isset($options['host'])) { - $options['host'] = 'geoip.maxmind.com'; - } + $options['host'] ??= 'geoip.maxmind.com'; $options['userAgent'] = $this->userAgent(); @@ -139,7 +132,6 @@ class Client implements ProviderInterface */ public function city(string $ipAddress = 'me'): City { - // @phpstan-ignore-next-line return $this->responseFor('city', City::class, $ipAddress); } @@ -201,11 +193,29 @@ class Client implements ProviderInterface */ public function insights(string $ipAddress = 'me'): Insights { - // @phpstan-ignore-next-line return $this->responseFor('insights', Insights::class, $ipAddress); } - private function responseFor(string $endpoint, string $class, string $ipAddress): Country + /** + * Generic helper method to call an endpoint and return the corresponding model. + * + * @template TModel of City|Country|Insights + * + * @param 'city'|'country'|'insights' $endpoint the endpoint name + * @param class-string $class The specific model class string (e.g., City::class) + * @param string $ipAddress the IP address or 'me' + * + * @throws AddressNotFoundException + * @throws AuthenticationException + * @throws OutOfQueriesException + * @throws InvalidRequestException + * @throws HttpException + * @throws GeoIp2Exception + * @throws \InvalidArgumentException + * + * @return TModel the corresponding model object, matching the passed class string + */ + private function responseFor(string $endpoint, string $class, string $ipAddress): City|Country|Insights { if ($ipAddress !== 'me' && !filter_var($ipAddress, \FILTER_VALIDATE_IP)) { throw new \InvalidArgumentException( diff --git a/public/lib/maxmind/MaxMind/CHANGELOG.md b/public/lib/maxmind/MaxMind/CHANGELOG.md index 40d89d42ead..f40c1045813 100644 --- a/public/lib/maxmind/MaxMind/CHANGELOG.md +++ b/public/lib/maxmind/MaxMind/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +1.12.1 (2025-05-05) +------------------- + +* The C extension now checks that the database metadata lookup was + successful. + 1.12.0 (2024-11-14) ------------------- diff --git a/public/lib/maxmind/MaxMind/README.md b/public/lib/maxmind/MaxMind/README.md index afefc3fd129..b5e28b65978 100644 --- a/public/lib/maxmind/MaxMind/README.md +++ b/public/lib/maxmind/MaxMind/README.md @@ -180,6 +180,6 @@ The MaxMind DB Reader PHP API uses [Semantic Versioning](https://semver.org/). ## Copyright and License ## -This software is Copyright (c) 2014-2024 by MaxMind, Inc. +This software is Copyright (c) 2014-2025 by MaxMind, Inc. This is free software, licensed under the Apache License, Version 2.0. diff --git a/public/lib/maxmind/MaxMind/src/MaxMind/Db/Reader.php b/public/lib/maxmind/MaxMind/src/MaxMind/Db/Reader.php index 12c6b0950d0..63dc7e12852 100644 --- a/public/lib/maxmind/MaxMind/src/MaxMind/Db/Reader.php +++ b/public/lib/maxmind/MaxMind/src/MaxMind/Db/Reader.php @@ -356,8 +356,8 @@ class Reader } throw new InvalidDatabaseException( - "Error opening database file ($filename). " . - 'Is this a valid MaxMind DB file?' + "Error opening database file ($filename). " + . 'Is this a valid MaxMind DB file?' ); } diff --git a/public/lib/maxmind/MaxMind/src/MaxMind/Db/Reader/Metadata.php b/public/lib/maxmind/MaxMind/src/MaxMind/Db/Reader/Metadata.php index 9cade222118..6cb63329cfd 100644 --- a/public/lib/maxmind/MaxMind/src/MaxMind/Db/Reader/Metadata.php +++ b/public/lib/maxmind/MaxMind/src/MaxMind/Db/Reader/Metadata.php @@ -106,10 +106,10 @@ class Metadata ); } - $this->binaryFormatMajorVersion = - $metadata['binary_format_major_version']; - $this->binaryFormatMinorVersion = - $metadata['binary_format_minor_version']; + $this->binaryFormatMajorVersion + = $metadata['binary_format_major_version']; + $this->binaryFormatMinorVersion + = $metadata['binary_format_minor_version']; $this->buildEpoch = $metadata['build_epoch']; $this->databaseType = $metadata['database_type']; $this->languages = $metadata['languages']; diff --git a/public/lib/thirdpartylibs.xml b/public/lib/thirdpartylibs.xml index c198663e2eb..f375e0b1988 100644 --- a/public/lib/thirdpartylibs.xml +++ b/public/lib/thirdpartylibs.xml @@ -416,7 +416,7 @@ All rights reserved. maxmind/GeoIp2 GeoIP2 PHP API Library for processing of GeoIP data files. - 3.1.0 + 3.2.0 Apache 2.0 https://github.com/maxmind/GeoIP2-php @@ -428,7 +428,7 @@ All rights reserved. maxmind/MaxMind MaxMind DB Reader API PHP API for reading MaxMind DB files. - 1.12.0 + 1.12.1 Apache 2.0 https://github.com/maxmind/MaxMind-DB-Reader-php/