Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ phpunit.xml
.phpunit.result.cache
.php-cs-fixer.cache
.puli/
.idea
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<server name="BINGMAPS_API_KEY" value="YOUR_API_KEY"/>
<server name="GEOIPS_API_KEY" value="YOUR_API_KEY"/>
<server name="GEONAMES_USERNAME" value="YOUR_USERNAME"/>
<server name="GEONAMES_TOKEN" value="YOUR_TOKEN"/>
<server name="GOOGLE_GEOCODING_KEY" value="YOUR_GEOCODING_KEY"/>
<server name="GRAPHHOPPER_API_KEY" value="YOUR_API_KEY"/>
<server name="HERE_APP_CODE" value="YOUR_APP_CODE"/>
Expand Down
72 changes: 65 additions & 7 deletions src/Provider/Geonames/Geonames.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,37 +32,64 @@
*/
final class Geonames extends AbstractHttpProvider implements Provider
{

/**
* @var string
*/
public const GEOCODE_ENDPOINT_URL = 'http://api.geonames.org/searchJSON?q=%s&maxRows=%d&style=full&username=%s';
public const PREMIUM_WEBSERVICE_BASE_URL = 'https://secure.geonames.net';

/**
* @var string
*/
public const REVERSE_ENDPOINT_URL = 'http://api.geonames.org/findNearbyPlaceNameJSON?lat=%F&lng=%F&style=full&maxRows=%d&username=%s';
public const FREE_WEBSERVICE_BASE_URL = 'http://api.geonames.org';

/**
* @var string
*/
public const BASE_ENDPOINT_URL = 'http://api.geonames.org/%s?username=%s';
public const GEOCODE_ENDPOINT_PATH = '%s/searchJSON?q=%s&maxRows=%d&style=full&username=%s';

/**
* @var string
*/
public const REVERSE_ENDPOINT_PATH = '%s/findNearbyPlaceNameJSON?lat=%F&lng=%F&style=full&maxRows=%d&username=%s';

/**
* @var string
*/
private $username;

/**
* @var string|null
*/
private $token;

/**
* @var string
*/
private $baseUrl;

/**
* @param ClientInterface $client An HTTP adapter
* @param string $username Username login (Free registration at http://www.geonames.org/login)
* @param string|null $token Optional token for premium accounts
* @param bool $secure Use secure endpoint (https://secure.geonames.net) for premium accounts
*/
public function __construct(ClientInterface $client, string $username)
public function __construct(ClientInterface $client, string $username, ?string $token = null, bool $secure = false)
{
if (empty($username)) {
throw new InvalidCredentials('No username provided.');
}

$this->username = $username;
$this->token = $token;

// Determine base URL based on secure flag.
if ($secure === true) {
$this->baseUrl = self::PREMIUM_WEBSERVICE_BASE_URL;
} else {
$this->baseUrl = self::FREE_WEBSERVICE_BASE_URL;
}

parent::__construct($client);
}

Expand All @@ -75,7 +102,15 @@ public function geocodeQuery(GeocodeQuery $query): Collection
throw new UnsupportedOperation('The Geonames provider does not support IP addresses.');
}

$url = sprintf(self::GEOCODE_ENDPOINT_URL, urlencode($address), $query->getLimit(), $this->username);
$url = sprintf(
self::GEOCODE_ENDPOINT_PATH,
$this->baseUrl,
urlencode($address),
$query->getLimit(),
$this->username
);

$url = $this->appendToken($url);

return $this->executeQuery($url, $query->getLocale());
}
Expand All @@ -86,7 +121,16 @@ public function reverseQuery(ReverseQuery $query): Collection
$longitude = $coordinates->getLongitude();
$latitude = $coordinates->getLatitude();

$url = sprintf(self::REVERSE_ENDPOINT_URL, $latitude, $longitude, $query->getLimit(), $this->username);
$url = sprintf(
self::REVERSE_ENDPOINT_PATH,
$this->baseUrl,
$latitude,
$longitude,
$query->getLimit(),
$this->username
);

$url = $this->appendToken($url);

return $this->executeQuery($url, $query->getLocale());
}
Expand All @@ -96,7 +140,7 @@ public function reverseQuery(ReverseQuery $query): Collection
*/
public function getCountryInfo(?string $country = null, ?string $locale = null): array
{
$url = sprintf(self::BASE_ENDPOINT_URL, 'countryInfoJSON', $this->username);
$url = sprintf('%s/countryInfoJSON?username=%s', $this->baseUrl, $this->username);

if (isset($country)) {
$url = sprintf('%s&country=%s', $url, $country);
Expand All @@ -109,6 +153,8 @@ public function getCountryInfo(?string $country = null, ?string $locale = null):
$url = sprintf('%s&lang=%s', $url, substr($locale, 0, 2));
}

$url = $this->appendToken($url);

$content = $this->getUrlContents($url);
if (null === $json = json_decode($content)) {
throw InvalidServerResponse::create($url);
Expand Down Expand Up @@ -217,4 +263,16 @@ private function executeQuery(string $url, ?string $locale = null): AddressColle

return new AddressCollection($results);
}

/**
* Append token parameter to URL if token is provided.
*/
private function appendToken(string $url): string
{
if (null !== $this->token && '' !== $this->token) {
$url = sprintf('%s&token=%s', $url, $this->token);
}

return $url;
}
}
Loading