From 5c4dd5b1e537e29cf82446eed1b6b8260cff24fd Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Wed, 10 Sep 2014 12:13:09 -0700 Subject: [PATCH] Added checks of database type in lookup method --- CHANGELOG.md | 9 ++- maxmind-db | 2 +- src/GeoIp2/Database/Reader.php | 97 ++++++++++++----------- src/GeoIp2/ProviderInterface.php | 18 ----- tests/GeoIp2/Test/Database/ReaderTest.php | 83 +++++++++++-------- 5 files changed, 112 insertions(+), 97 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0770308..b5924af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,16 @@ CHANGELOG ========= -0.7.x (2014-0X-XX) +0.8.0 (2014-0X-XX) ------------------ +* The `GeoIP2\Database\Reader` lookup methods (e.g., `city()`, `isp()`) now + throw an `BadMethodCallException` if they are used with a database that + does not match the method. In particular, doing a `city()` lookup on a + GeoIP2 Country database will result in an exception, and vice versa. +* A `metadata()` method has been added to the `GeoIP2\Database\Reader` class. + This returns a `MaxMind\Db\Reader\Metadata` class with information about the + database. * The name attribute was missing from the RepresentedCountry class. 0.7.0 (2014-07-22) diff --git a/maxmind-db b/maxmind-db index c57c2cc..1d28147 160000 --- a/maxmind-db +++ b/maxmind-db @@ -1 +1 @@ -Subproject commit c57c2ccf4a0c7b000cd6cd9a4a4463e7b54d7d2c +Subproject commit 1d2814761753aefe32311cb917ab1e4f16d9fd7e diff --git a/src/GeoIp2/Database/Reader.php b/src/GeoIp2/Database/Reader.php index 88d3c59..621194a 100644 --- a/src/GeoIp2/Database/Reader.php +++ b/src/GeoIp2/Database/Reader.php @@ -71,7 +71,11 @@ class Reader implements ProviderInterface */ public function city($ipAddress) { - return $this->modelFor('City', $ipAddress); + return $this->modelFor( + 'City', + array('GeoLite2-City', 'GeoIP2-City'), + $ipAddress + ); } /** @@ -88,64 +92,49 @@ class Reader implements ProviderInterface */ public function country($ipAddress) { - return $this->modelFor('Country', $ipAddress); - } - - /** - * This method returns a GeoIP2 City model. - * - * @param string $ipAddress IPv4 or IPv6 address as a string. - * - * @return \GeoIp2\Model\City - * - * @throws \GeoIp2\Exception\AddressNotFoundException if the address is - * not in the database. - * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database - * is corrupt or invalid - * - * @deprecated deprecated since version 0.7.0 - */ - public function cityIspOrg($ipAddress) - { - return $this->modelFor('City', $ipAddress); - } - - /** - * This method returns a GeoIP2 Insights model. - * - * @param string $ipAddress IPv4 or IPv6 address as a string. - * - * @return \GeoIp2\Model\Insights - * - * @throws \GeoIp2\Exception\AddressNotFoundException if the address is - * not in the database. - * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database - * is corrupt or invalid - * - * @deprecated deprecated since version 0.7.0 - */ - public function omni($ipAddress) - { - return $this->modelFor('Insights', $ipAddress); + return $this->modelFor( + 'Country', + array('GeoLite2-Country', 'GeoIP2-Country'), + $ipAddress + ); } public function connectionType($ipAddress) { - return $this->flatModelFor('ConnectionType', $ipAddress); + return $this->flatModelFor( + 'ConnectionType', + 'GeoIP2-Connection-Type', + $ipAddress + ); } public function domain($ipAddress) { - return $this->flatModelFor('Domain', $ipAddress); + return $this->flatModelFor( + 'Domain', + 'GeoIP2-Domain', + $ipAddress + ); } public function isp($ipAddress) { - return $this->flatModelFor('Isp', $ipAddress); + return $this->flatModelFor( + 'Isp', + 'GeoIP2-ISP', + $ipAddress + ); } - private function modelFor($class, $ipAddress) + private function modelFor($class, $types, $ipAddress) { + if (!in_array($this->metadata()->databaseType, $types)) { + $method = lcfirst($class); + throw new \BadMethodCallException( + "The $method method cannot be used to open a " + . $this->metadata()->databaseType . " database" + ); + } $record = $this->getRecord($ipAddress); $record['traits']['ip_address'] = $ipAddress; @@ -154,8 +143,16 @@ class Reader implements ProviderInterface return new $class($record, $this->locales); } - private function flatModelFor($class, $ipAddress) + private function flatModelFor($class, $type, $ipAddress) { + if ($this->metadata()->databaseType !== $type) { + $method = lcfirst($class); + throw new \BadMethodCallException( + "The $method method cannot be used to open a " + . $this->metadata()->databaseType . " database" + ); + } + $record = $this->getRecord($ipAddress); $record['ip_address'] = $ipAddress; @@ -175,6 +172,16 @@ class Reader implements ProviderInterface return $record; } + /** + * @throws \InvalidArgumentException if arguments are passed to the method. + * @throws \BadMethodCallException if the database has been closed. + * @return \MaxMind\Db\Reader\Metadata object for the database. + */ + public function metadata() + { + return $this->dbReader->metadata(); + } + /** * Closes the GeoIP2 database and returns the resources to the system. */ diff --git a/src/GeoIp2/ProviderInterface.php b/src/GeoIp2/ProviderInterface.php index b32771c..6c3992f 100644 --- a/src/GeoIp2/ProviderInterface.php +++ b/src/GeoIp2/ProviderInterface.php @@ -17,22 +17,4 @@ interface ProviderInterface * @return \GeoIp2\Model\City A City model for the requested IP address. */ public function city($ipAddress); - - /** - * @param ipAddress - * IPv4 or IPv6 address to lookup. - * @return \GeoIp2\Model\City A City model for the requested IP address. - * - * @deprecated deprecated since version 0.7.0 - */ - public function cityIspOrg($ipAddress); - - /** - * @param ipAddress - * IPv4 or IPv6 address to lookup. - * @return \GeoIp2\Model\Insights An Insights model for the requested IP address. - * - * @deprecated deprecated since version 0.7.0 - */ - public function omni($ipAddress); } diff --git a/tests/GeoIp2/Test/Database/ReaderTest.php b/tests/GeoIp2/Test/Database/ReaderTest.php index 476abb3..6a2d859 100644 --- a/tests/GeoIp2/Test/Database/ReaderTest.php +++ b/tests/GeoIp2/Test/Database/ReaderTest.php @@ -8,44 +8,39 @@ class ReaderTest extends \PHPUnit_Framework_TestCase { public function testDefaultLocale() { - $reader = new Reader('maxmind-db/test-data/GeoIP2-City-Test.mmdb'); - // Needed for PHP 5.3 - $that = $this; - $this->checkAllMethods( - function ($method) use (&$that, &$reader) { - $record = $reader->$method('81.2.69.160'); - $that->assertEquals('United Kingdom', $record->country->name); - } - ); + foreach (array('City', 'Country') as $type) { + $reader = new Reader("maxmind-db/test-data/GeoIP2-$type-Test.mmdb"); + $method = lcfirst($type); + $record = $reader->$method('81.2.69.160'); + $this->assertEquals('United Kingdom', $record->country->name); + } $reader->close(); } public function testLocaleList() { - $reader = new Reader( - 'maxmind-db/test-data/GeoIP2-City-Test.mmdb', - array('xx', 'ru', 'pt-BR', 'es', 'en') - ); - $that = $this; - $this->checkAllMethods( - function ($method) use (&$that, &$reader) { - $record = $reader->$method('81.2.69.160'); - $that->assertEquals('Великобритания', $record->country->name); - } - ); + + foreach (array('City', 'Country') as $type) { + $reader = new Reader( + "maxmind-db/test-data/GeoIP2-$type-Test.mmdb", + array('xx', 'ru', 'pt-BR', 'es', 'en') + ); + $method = lcfirst($type); + + $record = $reader->$method('81.2.69.160'); + $this->assertEquals('Великобритания', $record->country->name); + } $reader->close(); } public function testHasIpAddress() { - $reader = new Reader('maxmind-db/test-data/GeoIP2-City-Test.mmdb'); - $that = $this; - $this->checkAllMethods( - function ($method) use (&$that, &$reader) { - $record = $reader->$method('81.2.69.160'); - $that->assertEquals('81.2.69.160', $record->traits->ipAddress); - } - ); + foreach (array('City', 'Country') as $type) { + $reader = new Reader("maxmind-db/test-data/GeoIP2-$type-Test.mmdb"); + $method = lcfirst($type); + $record = $reader->$method('81.2.69.160'); + $this->assertEquals('81.2.69.160', $record->traits->ipAddress); + } $reader->close(); } @@ -60,6 +55,28 @@ class ReaderTest extends \PHPUnit_Framework_TestCase $reader->close(); } + /** + * @expectedException BadMethodCallException + * @expectedExceptionMessage The country method cannot be used to open a GeoIP2-City database + */ + public function testIncorrectDatabase() + { + $reader = new Reader('maxmind-db/test-data/GeoIP2-City-Test.mmdb'); + $reader->country('10.10.10.10'); + $reader->close(); + } + + /** + * @expectedException BadMethodCallException + * @expectedExceptionMessage The domain method cannot be used to open a GeoIP2-City database + */ + public function testIncorrectDatabaseFlat() + { + $reader = new Reader('maxmind-db/test-data/GeoIP2-City-Test.mmdb'); + $reader->domain('10.10.10.10'); + $reader->close(); + } + /** * @expectedException InvalidArgumentException * @expectedExceptionMessage is not a valid IP address @@ -71,6 +88,7 @@ class ReaderTest extends \PHPUnit_Framework_TestCase $reader->close(); } + public function testConnectionType() { $reader = new Reader('maxmind-db/test-data/GeoIP2-Connection-Type-Test.mmdb'); @@ -112,10 +130,11 @@ class ReaderTest extends \PHPUnit_Framework_TestCase $reader->close(); } - public function checkAllMethods($testCb) + public function testMetadata() { - foreach (array('city', 'cityIspOrg', 'country', 'omni') as $method) { - $testCb($method); - } + $reader = new Reader('maxmind-db/test-data/GeoIP2-City-Test.mmdb'); + $this->assertEquals('GeoIP2-City', $reader->metadata()->databaseType); + + $reader->close(); } }