From 062b9c6aea607a77cd48f406df6593a454536260 Mon Sep 17 00:00:00 2001 From: Dan Ursu <10077734@brookes.ac.uk> Date: Tue, 26 Feb 2019 21:56:12 +0000 Subject: [PATCH 1/4] Use a gateway interface --- src/Gateways/GatewayInterface.php | 17 +++++ src/{ => Gateways}/GoogleApi.php | 6 +- src/Postcode.php | 10 ++- src/PostcodeServiceProvider.php | 113 +++++++++++++++--------------- tests/PostcodeLookupTest.php | 17 +---- 5 files changed, 89 insertions(+), 74 deletions(-) create mode 100644 src/Gateways/GatewayInterface.php rename src/{ => Gateways}/GoogleApi.php (90%) diff --git a/src/Gateways/GatewayInterface.php b/src/Gateways/GatewayInterface.php new file mode 100644 index 0000000..91b3475 --- /dev/null +++ b/src/Gateways/GatewayInterface.php @@ -0,0 +1,17 @@ +api = new GoogleApi($apiKey); + $this->api = $apiGateway; } /** diff --git a/src/PostcodeServiceProvider.php b/src/PostcodeServiceProvider.php index ff6b795..d554774 100644 --- a/src/PostcodeServiceProvider.php +++ b/src/PostcodeServiceProvider.php @@ -1,55 +1,58 @@ -app->runningInConsole()) { - $this->publishes([ - __DIR__.'/../config/postcode.php' => config_path('postcode.php'), - ], 'postcode-config'); - } - } - - /** - * Register the service provider. - * - * @return void - */ - public function register() - { - $this->mergeConfigFrom( - __DIR__.'/../config/postcode.php', 'postcode' - ); - - $this->app->singleton('postcode', function () { - return new Postcode(config('postcode.google_api_key')); - }); - } - - /** - * Get the services provided by the provider. - * - * @return array - */ - public function provides() - { - return ['postcode']; - } -} +app->runningInConsole()) { + $this->publishes([ + __DIR__.'/../config/postcode.php' => config_path('postcode.php'), + ], 'postcode-config'); + } + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { + $this->mergeConfigFrom( + __DIR__.'/../config/postcode.php', 'postcode' + ); + + $this->app->singleton('postcode', function () { + return new Postcode( + new GoogleApi(config('postcode.google_api_key')) + ); + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return ['postcode']; + } +} diff --git a/tests/PostcodeLookupTest.php b/tests/PostcodeLookupTest.php index 971f04b..f28f265 100644 --- a/tests/PostcodeLookupTest.php +++ b/tests/PostcodeLookupTest.php @@ -2,7 +2,7 @@ namespace Lodge\Postcode\Tests; -use Lodge\Postcode\GoogleApi; +use Lodge\Postcode\Gateways\GoogleApi; use Lodge\Postcode\Postcode; use PHPUnit\Framework\TestCase; @@ -13,18 +13,6 @@ class PostcodeLookupTest extends TestCase */ private $postcode; - /** - * Instantiate the postcode class before each test - * - * @return void - */ - public function setUp() - { - parent::setUp(); - - $this->postcode = new Postcode(); - } - /** @test */ public function it_returns_an_array_with_the_address_coordinates() { @@ -40,6 +28,7 @@ public function it_returns_an_array_with_the_address_coordinates() /** @test */ public function it_mutates_the_postcode_so_that_it_doesnt_contain_spaces() { + $this->postcode = new Postcode($this->createMock(GoogleApi::class)); $postcode = $this->postcode->mutatePostcode('sw3 4sz'); // It contains uppercase letters and no spaces @@ -75,6 +64,6 @@ private function googleApiWillReturn($json) { $googleMock = $this->createMock(GoogleApi::class); $googleMock->method('fetch')->willReturn(json_decode(file_get_contents($json))); - $this->postcode->setApi($googleMock); + $this->postcode = new Postcode($googleMock); } } From a443b498d7a942cb19c0d0fdb96ea3c02ae5e4a0 Mon Sep 17 00:00:00 2001 From: Dan Ursu <10077734@brookes.ac.uk> Date: Tue, 26 Feb 2019 23:28:16 +0000 Subject: [PATCH 2/4] Refactor to use a gateway --- composer.json | 59 +++--- src/Address.php | 188 ++++++++++++++++++++ src/Coordinates.php | 44 +++++ src/Exceptions/AddressNotFoundException.php | 7 + src/Exceptions/PostcodeException.php | 7 + src/Gateways/GatewayInterface.php | 23 ++- src/Gateways/GoogleApi.php | 103 ++++++++++- src/Postcode.php | 133 ++------------ src/PostcodeUtils.php | 18 ++ tests/Gateways/GoogleApiTest.php | 53 ++++++ tests/PostcodeLookupTest.php | 42 ++--- tests/PostcodeUtilsTest.php | 21 +++ 12 files changed, 509 insertions(+), 189 deletions(-) create mode 100644 src/Address.php create mode 100644 src/Coordinates.php create mode 100644 src/Exceptions/AddressNotFoundException.php create mode 100644 src/Exceptions/PostcodeException.php create mode 100644 src/PostcodeUtils.php create mode 100644 tests/Gateways/GoogleApiTest.php create mode 100644 tests/PostcodeUtilsTest.php diff --git a/composer.json b/composer.json index c74662f..85b8805 100644 --- a/composer.json +++ b/composer.json @@ -1,29 +1,30 @@ -{ - "name": "lodge/postcode-lookup", - "description": "A postcode lookup utility using the Google Maps API, ready to use with Laravel 5.", - "license": "MIT", - "authors": [ - { - "name": "Dan Ursu", - "email": "dan@schoolsup.com" - } - ], - "require": { - "php": ">=5.4.0", - "illuminate/support": "4.x|~5.0" - }, - "require-dev": { - "phpunit/phpunit": "~7.0" - }, - "autoload": { - "psr-4": { - "Lodge\\Postcode\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Lodge\\Postcode\\Tests\\": "tests/" - } - }, - "minimum-stability": "stable" -} +{ + "name": "lodge/postcode-lookup", + "description": "A postcode lookup utility using the Google Maps API, ready to use with Laravel 5.", + "license": "MIT", + "authors": [ + { + "name": "Dan Ursu", + "email": "dan@schoolsup.com" + } + ], + "require": { + "ext-json": "*", + "php": ">=7.1", + "illuminate/support": "4.x|~5.0" + }, + "require-dev": { + "phpunit/phpunit": "~7.0" + }, + "autoload": { + "psr-4": { + "Lodge\\Postcode\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Lodge\\Postcode\\Tests\\": "tests/" + } + }, + "minimum-stability": "stable" +} diff --git a/src/Address.php b/src/Address.php new file mode 100644 index 0000000..cb57d1f --- /dev/null +++ b/src/Address.php @@ -0,0 +1,188 @@ +coordinates = $coordinates; + $this->postcode = $postcode; + } + + /** + * @return string + */ + public function getPostcode() + { + return $this->postcode; + } + + /** + * @return string + */ + public function getStreetNumber() + { + return $this->streetNumber; + } + + /** + * @param string $streetNumber + */ + public function setStreetNumber($streetNumber) + { + $this->streetNumber = $streetNumber; + } + + /** + * @param string $county + */ + public function setCounty($county) + { + $this->county = $county; + } + + /** + * @param string $country + */ + public function setCountry($country) + { + $this->country = $country; + } + + /** + * @return string + */ + public function getStreet() + { + return $this->street; + } + + /** + * @param string $street + */ + public function setStreet($street) + { + $this->street = $street; + } + + /** + * @return string + */ + public function getSublocality() + { + return $this->sublocality; + } + + /** + * @param string $sublocality + */ + public function setSublocality($sublocality) + { + $this->sublocality = $sublocality; + } + + /** + * @return string + */ + public function getTown() + { + return $this->town; + } + + /** + * @param string $town + */ + public function setTown($town) + { + $this->town = $town; + } + + /** + * @return string + */ + public function getCounty() + { + return $this->county; + } + + /** + * @return string + */ + public function getCountry() + { + return $this->country; + } + + /** + * @return \Lodge\Postcode\Coordinates + */ + public function getCoordinates() + { + return $this->coordinates; + } + + /** + * @return array + */ + public function toArray() + { + return [ + 'postcode' => $this->postcode, + 'street_number' => $this->streetNumber, + 'street' => $this->street, + 'sublocality' => $this->sublocality, + 'town' => $this->town, + 'county' => $this->county, + 'country' => $this->country, + 'latitude' => $this->coordinates->getLatitude(), + 'longitude' => $this->coordinates->getLongitude(), + ]; + } +} diff --git a/src/Coordinates.php b/src/Coordinates.php new file mode 100644 index 0000000..b43d681 --- /dev/null +++ b/src/Coordinates.php @@ -0,0 +1,44 @@ +latitude = $latitude; + $this->longitude = $longitude; + } + + /** + * @return float + */ + public function getLatitude() + { + return $this->latitude; + } + + /** + * @return float + */ + public function getLongitude() + { + return $this->longitude; + } +} diff --git a/src/Exceptions/AddressNotFoundException.php b/src/Exceptions/AddressNotFoundException.php new file mode 100644 index 0000000..d640b78 --- /dev/null +++ b/src/Exceptions/AddressNotFoundException.php @@ -0,0 +1,7 @@ +fetch($url); + + if (!empty($json->results)) { + $lat = $json->results[0]->geometry->location->lat; + $lng = $json->results[0]->geometry->location->lng; + + return new Coordinates($lat, $lng); + } + + throw new AddressNotFoundException($address); + } + + /** + * Returns the best address found at the given coordinates. + * + * @param \Lodge\Postcode\Coordinates $coordinates + * @param string $postcode + * @return \Lodge\Postcode\Address + * @throws \Lodge\Postcode\Exceptions\AddressNotFoundException + */ + public function geocodeLatLng(Coordinates $coordinates, $postcode) + { + $address_json = $this->fetch(sprintf( + 'latlng=%s,%s&sensor=false', + $coordinates->getLatitude(), + $coordinates->getLongitude() + )); + + // The correct result is not always the first one, so loop through results here + foreach ($address_json->results as $current_address) { + foreach ($current_address->address_components as $component) { + // If this address_component is a postcode and matches... + if (array_search('postal_code', $component->types) !== FALSE + && $postcode == $this->mutatePostcode($component->long_name) + ) { + $address_data = $current_address->address_components; + break 2; + } + } + } + + // If no exact match found, use the first as a closest option + if (!isset($address_data) + && !empty($address_json->results) + ) { + $address_data = $address_json->results[0]->address_components; + } + + // If still nothing, return empty array + if (!isset($address_data)) { + throw new AddressNotFoundException(); + } + + $address = new Address($coordinates, $postcode); + + // Process the return + foreach ($address_data as $value) { + if (array_search('street_number', $value->types) !== FALSE) { + $address->setStreetNumber($value->long_name); + } elseif (array_search('route', $value->types) !== FALSE) { + $address->setStreet($value->long_name); + } elseif (array_search('sublocality', $value->types) !== FALSE) { + $address->setSublocality($value->long_name); + } elseif (array_search('locality', $value->types) !== FALSE) { + $address->setTown($value->long_name); + } elseif (array_search('administrative_area_level_2', $value->types) !== FALSE) { + $address->setCounty($value->long_name); + } elseif (array_search('country', $value->types) !== FALSE) { + $address->setCountry($value->long_name); + } + } + + return $address; + } + /** * Calls the Google API. * - * @param string $url + * @param string $path * @return \stdClass * @throws ServiceUnavailableException */ - public function fetch($url) + public function fetch($path) { + $url = 'https://maps.googleapis.com/maps/api/geocode/json?'.$path; + if ($this->apiKey) { $url .= '&key='.$this->apiKey; } diff --git a/src/Postcode.php b/src/Postcode.php index a3fe0c6..9445182 100644 --- a/src/Postcode.php +++ b/src/Postcode.php @@ -7,6 +7,8 @@ class Postcode { + use PostcodeUtils; + /** * Default country to search in. * @@ -34,95 +36,29 @@ public function __construct(GatewayInterface $apiGateway) /** * Retrieves the full address for a given postcode. * - * @param $postcode - * @return array + * @param string $postcode + * @return \Lodge\Postcode\Address + * @throws \Lodge\Postcode\Exceptions\AddressNotFoundException */ public function lookup($postcode) { // Mutate the postcode $postcode = $this->mutatePostcode($postcode); - // Sanitize the postcode: + // Retrieve the lat/lng from the address $coords = $this->getCoordinates($postcode); - // If empty, we must have no results - if (empty($coords)) { - return []; - } - - // A second call will now retrieve the address - $address_url = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' . $coords['latitude'] . ',' . $coords['longitude'] . '&sensor=false'; - - $address_json = $this->api->fetch($address_url); - - // The correct result is not always the first one, so loop through results here - foreach ($address_json->results as $current_address) { - foreach ($current_address->address_components as $component) { - // If this address_component is a postcode and matches... - if(array_search('postal_code', $component->types) !== FALSE - && $postcode == $this->mutatePostcode($component->long_name) - ) { - $address_data = $current_address->address_components; - break 2; - } - } - } - - // If no exact match found, use the first as a closest option - if (!isset($address_data) - && !empty($address_json->results) - ) { - $address_data = $address_json->results[0]->address_components; - } - - // If still nothing, return empty array - if (!isset($address_data)) { - return []; - } - - // Initialize all values as empty - $street_number = ''; - $street = ''; - $sublocality = ''; - $town = ''; - $county = ''; - $country = ''; - - // Process the return - foreach ($address_data as $value) { - if (array_search('street_number', $value->types) !== FALSE) { - $street_number = $value->long_name; - } elseif (array_search('route', $value->types) !== FALSE) { - $street = $value->long_name; - } elseif (array_search('sublocality', $value->types) !== FALSE) { - $sublocality = $value->long_name; - } elseif (array_search('locality', $value->types) !== FALSE) { - $town = $value->long_name; - } elseif (array_search('administrative_area_level_2', $value->types) !== FALSE) { - $county = $value->long_name; - } elseif (array_search('country', $value->types) !== FALSE) { - $country = $value->long_name; - } - } - - return [ - 'postcode' => $postcode, - 'street_number' => $street_number, - 'street' => $street, - 'sublocality' => $sublocality, - 'town' => $town, - 'county' => $county, - 'country' => $country, - 'latitude' => $coords['latitude'], - 'longitude' => $coords['longitude'] - ]; + // Attempt to reverse geocode the lat/lng + return $this->api->geocodeLatLng($coords, $postcode); } /** * Returns the lat/lng for the given address. * * @param string $address - * @return array + * @return \Lodge\Postcode\Coordinates + * @throws \Lodge\Postcode\Exceptions\AddressNotFoundException + * @throws \Lodge\Postcode\ServiceUnavailableException */ public function getCoordinates($address) { @@ -130,27 +66,7 @@ public function getCoordinates($address) $address = trim($address) . ' ' . $this->country; } - // Sanitize the address: - $search_code = urlencode($address); - - // Retrieve the latitude and longitude - $url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' . $search_code . '&sensor=false'; - - // If Google Maps API fails, catch it and throw a better error - $json = $this->api->fetch($url); - - if(!empty($json->results)) { - $lat = $json->results[0]->geometry->location->lat; - $lng = $json->results[0]->geometry->location->lng; - - return [ - 'latitude' => $lat, - 'longitude' => $lng - ]; - } - - // We must have nothing if we've got here - return []; + return $this->api->geocodeFromAddress($address); } /** @@ -166,31 +82,6 @@ public function setCountry($country = null) return $this; } - /** - * Remove all spaces from postcode. - * - * @param $postcode - * @return string - */ - public function mutatePostcode($postcode) - { - // Ensure the postcode is all upper case with no spaces - return preg_replace('/ /', '', strtoupper($postcode)); - } - - /** - * Replaces the Google API. - * - * @param mixed $api - * @return $this - */ - public function setApi($api) - { - $this->api = $api; - - return $this; - } - /** * Sets the Google API key. * diff --git a/src/PostcodeUtils.php b/src/PostcodeUtils.php new file mode 100644 index 0000000..f613304 --- /dev/null +++ b/src/PostcodeUtils.php @@ -0,0 +1,18 @@ +getGateway(); + $gateway->method('fetch')->willReturn(json_decode(file_get_contents(__DIR__.'/../stubs/coordinates.json'))); + + $response = $gateway->geocodeFromAddress('test'); + $this->assertInstanceOf(Coordinates::class, $response); + $this->assertEquals(51.4891175, $response->getLatitude()); + $this->assertEquals(-0.1579016, $response->getLongitude()); + } + + public function test_it_throws_address_not_found() + { + /** @var \Lodge\Postcode\Gateways\GoogleApi $gateway */ + $gateway = $this->getGateway(); + $gateway->method('fetch')->willReturn([]); + + $this->expectException(AddressNotFoundException::class); + $gateway->geocodeFromAddress('test'); + } + + public function test_it_returns_an_address() + { + /** @var \Lodge\Postcode\Gateways\GoogleApi $gateway */ + $gateway = $this->getGateway(); + $gateway->method('fetch')->willReturn(json_decode(file_get_contents(__DIR__.'/../stubs/lookup.json'))); + $response = $gateway->geocodeLatLng(new Coordinates(50, -1), 'sw3 4sz'); + + $this->assertEquals('sw3 4sz', $response->getPostcode()); + $this->assertEquals('Franklins Row', $response->getStreet()); + $this->assertEquals('Greater London', $response->getCounty()); + $this->assertEquals('United Kingdom', $response->getCountry()); + $this->assertEquals(50, $response->getCoordinates()->getLatitude()); + $this->assertEquals(-1, $response->getCoordinates()->getLongitude()); + } + + private function getGateway() + { + return $this->getMockBuilder(GoogleApi::class)->setMethods(['fetch'])->getMock(); + } +} diff --git a/tests/PostcodeLookupTest.php b/tests/PostcodeLookupTest.php index f28f265..36f9c84 100644 --- a/tests/PostcodeLookupTest.php +++ b/tests/PostcodeLookupTest.php @@ -2,6 +2,7 @@ namespace Lodge\Postcode\Tests; +use Lodge\Postcode\Coordinates; use Lodge\Postcode\Gateways\GoogleApi; use Lodge\Postcode\Postcode; use PHPUnit\Framework\TestCase; @@ -20,20 +21,9 @@ public function it_returns_an_array_with_the_address_coordinates() $this->googleApiWillReturn(__DIR__.'/stubs/coordinates.json'); $response = $this->postcode->getCoordinates('SW3 4SZ'); - $this->assertTrue(is_array($response)); - $this->assertArrayHasKey('latitude', $response); - $this->assertArrayHasKey('longitude', $response); - } - - /** @test */ - public function it_mutates_the_postcode_so_that_it_doesnt_contain_spaces() - { - $this->postcode = new Postcode($this->createMock(GoogleApi::class)); - $postcode = $this->postcode->mutatePostcode('sw3 4sz'); - - // It contains uppercase letters and no spaces - $this->assertFalse(strpos(' ', $postcode)); - $this->assertEquals('SW34SZ', $postcode); + $this->assertInstanceOf(Coordinates::class, $response); + $this->assertEquals(51.4891175, $response->getLatitude()); + $this->assertEquals(-0.1579016, $response->getLongitude()); } /** @test */ @@ -42,27 +32,17 @@ public function it_returns_the_full_location_for_an_address() $this->googleApiWillReturn(__DIR__.'/stubs/lookup.json'); $response = $this->postcode->lookup('sw3 4sz'); - $this->assertEquals('SW34SZ', $response['postcode']); - $this->assertEquals('Franklins Row', $response['street']); - $this->assertEquals('Greater London', $response['county']); - $this->assertEquals('United Kingdom', $response['country']); - $this->assertEquals(51.4890557, $response['latitude']); - $this->assertEquals(-0.1579412, $response['longitude']); - - $this->assertArrayHasKey('postcode', $response); - $this->assertArrayHasKey('street_number', $response); - $this->assertArrayHasKey('street', $response); - $this->assertArrayHasKey('sublocality', $response); - $this->assertArrayHasKey('town', $response); - $this->assertArrayHasKey('county', $response); - $this->assertArrayHasKey('country', $response); - $this->assertArrayHasKey('latitude', $response); - $this->assertArrayHasKey('longitude', $response); + $this->assertEquals('SW34SZ', $response->getPostcode()); + $this->assertEquals('Franklins Row', $response->getStreet()); + $this->assertEquals('Greater London', $response->getCounty()); + $this->assertEquals('United Kingdom', $response->getCountry()); + $this->assertEquals(51.4890557, $response->getCoordinates()->getLatitude()); + $this->assertEquals(-0.1579412, $response->getCoordinates()->getLongitude()); } private function googleApiWillReturn($json) { - $googleMock = $this->createMock(GoogleApi::class); + $googleMock = $this->getMockBuilder(GoogleApi::class)->setMethods(['fetch'])->getMock(); $googleMock->method('fetch')->willReturn(json_decode(file_get_contents($json))); $this->postcode = new Postcode($googleMock); } diff --git a/tests/PostcodeUtilsTest.php b/tests/PostcodeUtilsTest.php new file mode 100644 index 0000000..6fde55c --- /dev/null +++ b/tests/PostcodeUtilsTest.php @@ -0,0 +1,21 @@ +mutatePostcode('sw3 4sz'); + + // It contains uppercase letters and no spaces + $this->assertFalse(strpos(' ', $postcode)); + $this->assertEquals('SW34SZ', $postcode); + } +} From d056db6605a00484e357bc7b99492f3546fe0e2c Mon Sep 17 00:00:00 2001 From: Dan Ursu <10077734@brookes.ac.uk> Date: Tue, 26 Feb 2019 23:45:40 +0000 Subject: [PATCH 3/4] Update readme --- README.md | 171 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 105 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index ee044da..2bd562a 100644 --- a/README.md +++ b/README.md @@ -24,20 +24,20 @@ Note: for Laravel 4 use version `0.3.0` Register the service provider. Inside your `app.php` config file add: -``` -'providers' => array( +```php +'providers' => [ ... 'Lodge\Postcode\PostcodeServiceProvider', -) +] ``` A facade is also provided, so in order to register it add the following to your `app.php` config file: -``` -'aliases' => array( +```php +'aliases' => [ ... 'Postcode' => 'Lodge\Postcode\Facades\Postcode', -); +]; ``` Publish the configuration file. @@ -51,85 +51,124 @@ Set your Google API key inside `config/postcode.php` file. From within your controller you can call: -``` - $postcode = Postcode::lookup('SW3 4SZ'); - - print_r($postcode); - - // Outputs - array( - 'postcode' => 'SW34SZ', - 'street_number' => '', - 'street' => '', - 'sublocality' => '', - 'town' => 'London', - 'county' => 'Greater London', - 'country' => 'United Kingdom', - 'latitude' => 51.489117499999999, - 'longitude' => -0.1579016 - ); +```php +$address = Postcode::lookup('SW3 4SZ'); + +// Usage +$address->getPostcode(); +$address->getStreetNumber(); +$address->getStreet(); +$address->getTown(); // -> London +$address->getCounty(); // -> Greater London +$address->getCountry(); // -> United Kingdom +$address->getCoordinates()->getLatitude(); // -> 51.489117499999999 +$address->getCoordinates()->getLongitude(); // -> -0.1579016 + +// $address->toArray(); +// Outputs +[ + 'postcode' => 'SW34SZ', + 'street_number' => '', + 'street' => '', + 'sublocality' => '', + 'town' => 'London', + 'county' => 'Greater London', + 'country' => 'United Kingdom', + 'latitude' => 51.489117499999999, + 'longitude' => -0.1579016 +] ``` #### Get the Latitude and Longitude of an address -``` - $coordinates = Postcode::getCoordinates($address); - - print_r($coordinates); +```php +$coordinates = Postcode::getCoordinates($address); - // Outputs - array( - 'latitude' => 1.521231 - 'longitude' => -23.012123 - ) +// Usage +$coordinates->getLatitude(); +$coordinates->getLongitude(); +// Output +// 51.489117499999999 +// -0.1579016 ``` ## Usage outside of Laravel -``` - // First of all you need to instantiate the class - // And assuming that you have required the composer - // autoload.php file - require 'vendor/autoload.php'; - - $googleApiKey = 'your-google-api-key'; - $postcode = new Lodge\Postcode\Postcode($googleApiKey); - $results = $postcode->lookup('SW3 4SZ'); - - print_r($results); - - // Outputs - array( - 'postcode' => 'SW34SZ', - 'street_number' => '', - 'street' => '', - 'sublocality' => '', - 'town' => 'London', - 'county' => 'Greater London', - 'country' => 'United Kingdom', - 'latitude' => 51.489117499999999, - 'longitude' => -0.1579016 - ) +```php +// First of all you need to instantiate the class +// And assuming that you have required the composer +// autoload.php file +require 'vendor/autoload.php'; + +$googleApiKey = 'your-google-api-key'; +$postcode = new Lodge\Postcode\Postcode($googleApiKey); +$address = $postcode->lookup('SW3 4SZ'); + +// Usage +$address->getPostcode(); +$address->getStreetNumber(); +$address->getStreet(); +$address->getTown(); // -> London +$address->getCounty(); // -> Greater London +$address->getCountry(); // -> United Kingdom +$address->getCoordinates()->getLatitude(); // -> 51.489117499999999 +$address->getCoordinates()->getLongitude(); // -> -0.1579016 + +// $address->toArray(); +// Outputs +[ + 'postcode' => 'SW34SZ', + 'street_number' => '', + 'street' => '', + 'sublocality' => '', + 'town' => 'London', + 'county' => 'Greater London', + 'country' => 'United Kingdom', + 'latitude' => 51.489117499999999, + 'longitude' => -0.1579016 +] ``` If you need to get just the latitude and longitude for an address you can use: -``` - $googleApiKey = 'your-google-api-key'; - $postcode = new Lodge\Postcode\Postcode($googleApiKey); - $results = $postcode->getCoordinates('SW3 4SZ'); +```php +$googleApiKey = 'your-google-api-key'; +$postcode = new Lodge\Postcode\Postcode(new Lodge\Postocde\Gateways\GoogleApi($googleApiKey)); +$coordinates = $postcode->getCoordinates('SW3 4SZ'); + +// Usage +$coordinates->getLatitude(); +$coordinates->getLongitude(); - print_r($results); +// Output +// 51.489117499999999 +// -0.1579016 +``` - // Outputs - array( - 'latitude' => 51.489117499999999 - 'longitude' => -0.1579016 - ) +## Upgrade from 0.4 to 0.5 +* Wrap your calls to `->getCoordinates()` and `->lookup()` in a try catch block +```php +try { + $address = Postcode::getCoordinates($address) +} catch (AddressNotFoundException $e) { + // do something +} +``` +* The return type for `->getCoordinates()` is now an instance of `Lodge\Postcode\Coordinates` instead of an `array` +* The return type for `->lookup()` is now an instance of `Lodge\Postcode\Address` instead of an `array` +* If you are manually creating a new instance of `Lodge\Postcode\Postcode` then you will need to inject an instance of `GoogleApi` +```php +$postcode = new Lodge\Postcode\Postcode(new Lodge\Postocde\Gateways\GoogleApi($googleApiKey)); ``` ## Changelog +* **Version 0.5** + * This version introduces breaking changes + * Minimum supported PHP version is now 7.1 + * Use an object instead of returning an array + * Add a gateway interface, so that we can connect to multiple geocode backends + * Throw exceptions when an address is not found * **Version 0.4** * Added configuration file and the ability to set the Google API key. * Updated namespaces to PSR-4 From 8560b9b8985721dec9adeedc6647c91976fd0726 Mon Sep 17 00:00:00 2001 From: Dan Ursu <10077734@brookes.ac.uk> Date: Tue, 26 Feb 2019 23:54:13 +0000 Subject: [PATCH 4/4] Add travis --- .travis.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c43e68f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: xenial +language: php + +matrix: + fast_finish: true + include: + - php: 7.1 + - php: 7.2 + - php: 7.3 + +cache: + directories: + - $HOME/.composer/cache + +before_install: + - travis_retry composer self-update + +install: + - travis_retry composer update --prefer-dist --no-interaction --prefer-stable --no-suggest + +script: vendor/bin/phpunit