Skip to content

Commit

Permalink
Add Find Place support (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
PabloKowalczyk authored Oct 21, 2018
1 parent 6f4202e commit 85ec223
Show file tree
Hide file tree
Showing 25 changed files with 877 additions and 43 deletions.
43 changes: 34 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,29 @@ composer require gplacesphp/api-client

## Usage

More usage examples are in `examples` directory.

### Place details

#### Basic example

This example uses `php-http/curl-client` as a http-client
This examples uses `php-http/curl-client` as a http-client
and `zendframework/zend-diactoros` as a PSR-7/PSR-17 implementation.
Any other PSR-7/PSR-17 implementations are supported.
If you don't have them installed you will need to run:

If you don't have them install you will ned to run:
```bash
composer require php-http/curl-client zendframework/zend-diactoros
```

Remember to replace `<YOUR_API_KEY>` with you key.

More usage examples are in `examples` directory.

### Place details

#### Basic example

```php
<?php

require_once __DIR__ . '/vendor/autoload.php';

$apiKey = ''<YOUR_API_KEY>'';
$apiKey = '<YOUR_API_KEY>';
$httpClient = new \Http\Client\Curl\Client();
$requestFactory = new \Zend\Diactoros\RequestFactory();

Expand All @@ -63,6 +63,31 @@ var_dump($placeDetails);

```

### Find place

#### Basic example

```php
<?php

require_once __DIR__ . '/vendor/autoload.php';

$apiKey = '<YOUR_API_KEY>';
$httpClient = new \Http\Client\Curl\Client();
$requestFactory = new \Zend\Diactoros\RequestFactory();

$client = \GPlacesPhp\ApiClient\Client::create(
$apiKey,
$httpClient,
$requestFactory
);

$findPlace = $client->findPlace('Warszawa, Polska'); // Warsaw

var_dump($findPlace);

```

## TODOs

Things to do before stable `v1` release:
Expand Down
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ parameters:
excludes_analyse:
- src/Cache/NullCache.php
- tests/TestCase/Cache/CacheSpy.php

includes:
- vendor-bin/dev/vendor/phpstan/phpstan-phpunit/extension.neon
- vendor-bin/dev/vendor/phpstan/phpstan-phpunit/rules.neon
27 changes: 27 additions & 0 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace GPlacesPhp\ApiClient;

use GPlacesPhp\ApiClient\Cache\NullCache;
use GPlacesPhp\ApiClient\Client\FindPlace;
use GPlacesPhp\ApiClient\Client\FindPlace\OptionalParameters;
use GPlacesPhp\ApiClient\Client\PlaceDetails;
use GPlacesPhp\ApiClient\Client\Url;
use GPlacesPhp\ApiClient\Exception\ApiException;
Expand Down Expand Up @@ -91,6 +93,31 @@ public function placeDetails(string $placeId, PlaceDetails\OptionalParameters $p
return PlaceDetails::fromArray($placeDetailsData);
}

public function findPlace(
string $input,
string $inputType = self::INPUT_TYPE_TEXT,
OptionalParameters $optionalParameters = null
): FindPlace {
$url = Url::findPlace(
$this->key,
$input,
$inputType,
$optionalParameters ?? OptionalParameters::fromArray([])
);
$request = $this->requestFactory
->createRequest('GET', $url->toString());
$response = $this->httpClient
->sendRequest($request);
$responseData = $this->parseJsonResponse($response->getBody());
$responseStatus = $responseData['status'] ?? '';

if ('OK' !== $responseStatus) {
throw ApiException::create($responseStatus, $responseData['error_message'] ?? '');
}

return FindPlace::fromArray($responseData['candidates'] ?? []);
}

private function parseJsonResponse(StreamInterface $stream): array
{
$data = \json_decode((string) $stream, true);
Expand Down
36 changes: 36 additions & 0 deletions src/Client/FindPlace.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace GPlacesPhp\ApiClient\Client;

use GPlacesPhp\ApiClient\Client\FindPlace\Candidate;

final class FindPlace
{
/** @var Candidate[] */
private $candidates;

private function __construct(Candidate ...$candidates)
{
$this->candidates = $candidates;
}

/** @return Candidate[] */
public function candidates(): array
{
return $this->candidates;
}

public static function fromArray(array $data): self
{
return new self(
...\array_map(
function (array $candidateData): Candidate {
return Candidate::fromArray($candidateData);
},
$data ?? []
)
);
}
}
71 changes: 71 additions & 0 deletions src/Client/FindPlace/Candidate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace GPlacesPhp\ApiClient\Client\FindPlace;

use GPlacesPhp\ApiClient\Client\Geometry;

final class Candidate
{
/** @var string */
private $formattedAddress;
/** @var Geometry */
private $geometry;
/** @var string */
private $name;
/** @var string */
private $placeId;
/** @var string */
private $id;

private function __construct(
string $formattedAddress,
Geometry $geometry,
string $name,
string $placeId,
string $id
) {
$this->formattedAddress = $formattedAddress;
$this->geometry = $geometry;
$this->name = $name;
$this->placeId = $placeId;
$this->id = $id;
}

public function placeId(): string
{
return $this->placeId;
}

public function id(): string
{
return $this->id;
}

public function geometry(): Geometry
{
return $this->geometry;
}

public function name(): string
{
return $this->name;
}

public static function fromArray(array $data): self
{
return new self(
$data['formatted_address'] ?? '',
Geometry::fromArray($data['geometry'] ?? []),
$data['name'] ?? '',
$data['place_id'] ?? '',
$data['id'] ?? ''
);
}

public function formattedAddress(): string
{
return $this->formattedAddress;
}
}
59 changes: 59 additions & 0 deletions src/Client/FindPlace/OptionalParameters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace GPlacesPhp\ApiClient\Client\FindPlace;

final class OptionalParameters
{
/** @var null|string */
private $language;
/** @var array */
private $fields;

private function __construct(?string $language = null, array $fields = [])
{
$this->language = $language;
$this->fields = $fields;
}

public static function fromArray(array $data): self
{
return new self(
$data['language'] ?? null,
\array_map(
function (string $field): string {
return $field;
},
$data['fields'] ?? []
)
);
}

/** @param string[] $fields */
public static function fromArguments(?string $language = null, array $fields = []): self
{
return new self(
$language,
\array_map(
function (string $field): string {
return $field;
},
$fields
)
);
}

public function toArray(): array
{
return \array_filter(
[
'language' => $this->language,
'fields' => \implode(',', $this->fields),
],
function ($value): bool {
return !empty($value);
}
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

declare(strict_types=1);

namespace GPlacesPhp\ApiClient\Client\PlaceDetails;
namespace GPlacesPhp\ApiClient\Client;

use GPlacesPhp\ApiClient\Client\PlaceDetails\Geometry\Location;
use GPlacesPhp\ApiClient\Client\PlaceDetails\Geometry\Viewport;
use GPlacesPhp\ApiClient\Client\Geometry\Location;
use GPlacesPhp\ApiClient\Client\Geometry\Viewport;

final class Geometry
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace GPlacesPhp\ApiClient\Client\PlaceDetails\Geometry;
namespace GPlacesPhp\ApiClient\Client\Geometry;

final class Location
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace GPlacesPhp\ApiClient\Client\PlaceDetails\Geometry;
namespace GPlacesPhp\ApiClient\Client\Geometry;

final class Viewport
{
Expand Down
1 change: 0 additions & 1 deletion src/Client/PlaceDetails.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace GPlacesPhp\ApiClient\Client;

use GPlacesPhp\ApiClient\Client\PlaceDetails\AddressComponents;
use GPlacesPhp\ApiClient\Client\PlaceDetails\Geometry;
use GPlacesPhp\ApiClient\Client\PlaceDetails\Reviews;

final class PlaceDetails
Expand Down
51 changes: 51 additions & 0 deletions src/Client/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace GPlacesPhp\ApiClient\Client;

use GPlacesPhp\ApiClient\Client\FindPlace\OptionalParameters as FindPlaceOptionalParameters;
use GPlacesPhp\ApiClient\Client\PlaceDetails\OptionalParameters;
use GPlacesPhp\ApiClient\ClientInterface;
use GPlacesPhp\ApiClient\Exception\UrlException;

final class Url
Expand Down Expand Up @@ -49,4 +51,53 @@ public static function details(

return new self(self::BASE_URL . "details/json?{$paramsString}");
}

public static function findPlace(
string $apiKey,
string $input,
string $inputType,
FindPlaceOptionalParameters $optionalParams
): self {
self::checkFindPlaceArguments(
$apiKey,
$input,
$inputType
);

$params = $optionalParams->toArray();
$params['key'] = $apiKey;
$params['input'] = $input;
$params['inputtype'] = $inputType;
$paramsString = \http_build_query($params);

return new self(self::BASE_URL . "findplacefromtext/json?{$paramsString}");
}

private static function checkFindPlaceArguments(
string $apiKey,
string $input,
string $inputType
): void {
if ('' === $apiKey) {
throw UrlException::emptyApiKey();
}

if ('' === $input) {
throw UrlException::emptyInput();
}

if ('' === $inputType) {
throw UrlException::emptyInputType();
}

$supportedInputType = \in_array(
$inputType,
ClientInterface::INPUT_TYPES,
true
);

if (!$supportedInputType) {
throw UrlException::unsupportedInputType($inputType, ClientInterface::INPUT_TYPES);
}
}
}
Loading

0 comments on commit 85ec223

Please sign in to comment.