From 3e848a3b43d7ca9e29fe78520b3f12b9d5fcd760 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Tue, 28 May 2024 11:38:10 +0530 Subject: [PATCH 01/14] added saloon --- composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5c50a76..56c1fca 100644 --- a/composer.json +++ b/composer.json @@ -44,5 +44,7 @@ "GooglePlaces": "SKAgarwal\\GoogleApi\\Facade" } } - } + }, + "minimum-stability": "dev", + "prefer-stable": false } From c24baf42a56ad955793fd8a90a1cbdbcae1d6ea9 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sun, 30 Jun 2024 17:29:22 +0530 Subject: [PATCH 02/14] feat: convert the existing API to Saloon. WIP Response errors --- composer.json | 16 +- config/google.php | 7 +- src/Facade.php | 18 - src/GoogleMaps/Endpoint.php | 26 ++ src/GoogleMaps/GoogleMaps.php | 190 ++++++++ src/GoogleMaps/Requests/FindPlace.php | 49 ++ src/GoogleMaps/Requests/NearbySearch.php | 49 ++ src/GoogleMaps/Requests/Photo.php | 35 ++ src/GoogleMaps/Requests/PlaceAutocomplete.php | 46 ++ src/GoogleMaps/Requests/PlaceDetails.php | 46 ++ src/GoogleMaps/Requests/QueryAutocomplete.php | 46 ++ src/GoogleMaps/Requests/TextSearch.php | 46 ++ src/PlacesApi.php | 437 ------------------ src/ServiceProvider.php | 16 +- src/helpers.php | 20 - 15 files changed, 550 insertions(+), 497 deletions(-) delete mode 100644 src/Facade.php create mode 100644 src/GoogleMaps/Endpoint.php create mode 100644 src/GoogleMaps/GoogleMaps.php create mode 100644 src/GoogleMaps/Requests/FindPlace.php create mode 100644 src/GoogleMaps/Requests/NearbySearch.php create mode 100644 src/GoogleMaps/Requests/Photo.php create mode 100644 src/GoogleMaps/Requests/PlaceAutocomplete.php create mode 100644 src/GoogleMaps/Requests/PlaceDetails.php create mode 100644 src/GoogleMaps/Requests/QueryAutocomplete.php create mode 100644 src/GoogleMaps/Requests/TextSearch.php delete mode 100644 src/PlacesApi.php delete mode 100644 src/helpers.php diff --git a/composer.json b/composer.json index 56c1fca..bb3fdd2 100644 --- a/composer.json +++ b/composer.json @@ -18,19 +18,17 @@ } ], "require": { - "php": "^8.0.2", - "illuminate/support": "^9.0|^10.0|^11.0", - "illuminate/container": "^9.0|^10.0|^11.0", - "guzzlehttp/guzzle": "^7.5" + "php": "^8.1", + "illuminate/support": "^10.0|^11.0", + "illuminate/container": "^10.0|^11.0", + "guzzlehttp/guzzle": "^7.5", + "saloonphp/saloon": "v3.x-dev" }, "require-dev": { "phpunit/phpunit": "^9.5.8|^10.5", "skagarwal/reflection": "~1.0" }, "autoload": { - "files": [ - "src/helpers.php" - ], "psr-4": { "SKAgarwal\\GoogleApi\\": "src/" } @@ -45,6 +43,6 @@ } } }, - "minimum-stability": "dev", - "prefer-stable": false + "minimum-stability": "stable", + "prefer-stable": true } diff --git a/config/google.php b/config/google.php index d91b313..164de66 100644 --- a/config/google.php +++ b/config/google.php @@ -2,8 +2,13 @@ return [ 'places' => [ + /** + * Google Places API Key + * @see https://developers.google.com/maps/documentation/places/web-service/get-api-key + */ 'key' => env('GOOGLE_PLACES_API_KEY', null), + + 'verify_ssl' => true, - 'headers' => [] ], ]; diff --git a/src/Facade.php b/src/Facade.php deleted file mode 100644 index 96f3f2c..0000000 --- a/src/Facade.php +++ /dev/null @@ -1,18 +0,0 @@ -key = $key; + $this->verifySSL = $verifySSL ?? true; + } + + /** + * @return string|null + */ + public function getKey(): ?string + { + return $this->key; + } + + /** + * @param string $key + * + * @return $this + */ + public function setKey(string $key): static + { + $this->key = $key; + + return $this; + } + + /** + * @param bool $verifySSL + * + * @return static + */ + public function verifySSL(bool $verifySSL = true): static + { + $this->verifySSL = $verifySSL; + + return $this; + } + + /** + * @return string + */ + public function resolveBaseUrl(): string + { + return Endpoint::BASE->value; + } + + /** + * @return bool[] + */ + protected function defaultConfig(): array + { + return [ + 'verify' => $this->verifySSL, + ]; + } + + /** + * @return \Saloon\Contracts\Authenticator|null + */ + protected function defaultAuth(): ?Authenticator + { + return new QueryAuthenticator('key', $this->key); + } + + /** + * @param string $input + * @param string $inputType + * @param array $params + * + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function findPlace(string $input, string $inputType, array $params = []): Response + { + return $this->send(new FindPlace($input, $inputType, $params)); + } + + /** + * @param string $location + * @param string|null $radius + * @param array $params + * + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function nearbySearch(string $location, ?string $radius = null, array $params = []): Response + { + return $this->send(new NearbySearch($location, $radius, $params)); + } + + /** + * @param string $input + * @param array $params + * + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function placeAutocomplete(string $input, array $params = []): Response + { + return $this->send(new PlaceAutocomplete($input, $params)); + } + + /** + * @param string $placeId + * @param array $params + * + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function placeDetails(string $placeId, array $params = []): Response + { + return $this->send(new PlaceDetails($placeId, $params)); + } + + /** + * @param string $input + * @param array $params + * + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function queryAutocomplete(string $input, array $params = []): Response + { + return $this->send(new QueryAutocomplete($input, $params)); + } + + /** + * @param string $query + * @param array $params + * + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function textSearch(string $query, array $params = []): Response + { + return $this->send(new TextSearch($query, $params)); + } +} diff --git a/src/GoogleMaps/Requests/FindPlace.php b/src/GoogleMaps/Requests/FindPlace.php new file mode 100644 index 0000000..5148e81 --- /dev/null +++ b/src/GoogleMaps/Requests/FindPlace.php @@ -0,0 +1,49 @@ +value; + } + + /** + * @return array|mixed[] + */ + protected function defaultQuery(): array + { + return [ + 'input' => $this->input, + 'inputtype' => $this->inputType, + ...$this->params, + ]; + } +} diff --git a/src/GoogleMaps/Requests/NearbySearch.php b/src/GoogleMaps/Requests/NearbySearch.php new file mode 100644 index 0000000..965f14d --- /dev/null +++ b/src/GoogleMaps/Requests/NearbySearch.php @@ -0,0 +1,49 @@ +value; + } + + /** + * @return array|mixed[] + */ + protected function defaultQuery(): array + { + return [ + 'location' => $this->location, + 'radius' => $this->radius, + ...$this->params, + ]; + } +} diff --git a/src/GoogleMaps/Requests/Photo.php b/src/GoogleMaps/Requests/Photo.php new file mode 100644 index 0000000..73c54e2 --- /dev/null +++ b/src/GoogleMaps/Requests/Photo.php @@ -0,0 +1,35 @@ +value; + } + + protected function defaultQuery(): array + { + return [ + 'photoreference' => $this->photoReference, + ...$this->params, + ]; + } +} diff --git a/src/GoogleMaps/Requests/PlaceAutocomplete.php b/src/GoogleMaps/Requests/PlaceAutocomplete.php new file mode 100644 index 0000000..c033b2b --- /dev/null +++ b/src/GoogleMaps/Requests/PlaceAutocomplete.php @@ -0,0 +1,46 @@ +value; + } + + /** + * @return string[] + */ + protected function defaultQuery(): array + { + return [ + 'input' => $this->input, + ...$this->params, + ]; + } +} diff --git a/src/GoogleMaps/Requests/PlaceDetails.php b/src/GoogleMaps/Requests/PlaceDetails.php new file mode 100644 index 0000000..3bd7d0f --- /dev/null +++ b/src/GoogleMaps/Requests/PlaceDetails.php @@ -0,0 +1,46 @@ +value; + } + + /** + * @return array|mixed[] + */ + protected function defaultQuery(): array + { + return [ + 'place_id' => $this->placeId, + ...$this->params, + ]; + } +} diff --git a/src/GoogleMaps/Requests/QueryAutocomplete.php b/src/GoogleMaps/Requests/QueryAutocomplete.php new file mode 100644 index 0000000..6e5f456 --- /dev/null +++ b/src/GoogleMaps/Requests/QueryAutocomplete.php @@ -0,0 +1,46 @@ +value; + } + + /** + * @return array|mixed[] + */ + protected function defaultQuery(): array + { + return [ + 'input' => $this->input, + ...$this->params, + ]; + } +} diff --git a/src/GoogleMaps/Requests/TextSearch.php b/src/GoogleMaps/Requests/TextSearch.php new file mode 100644 index 0000000..502c115 --- /dev/null +++ b/src/GoogleMaps/Requests/TextSearch.php @@ -0,0 +1,46 @@ +value; + } + + /** + * @return array|mixed[] + */ + protected function defaultQuery(): array + { + return [ + 'query' => $this->searchQuery, + ...$this->params, + ]; + } +} diff --git a/src/PlacesApi.php b/src/PlacesApi.php deleted file mode 100644 index 5dfee51..0000000 --- a/src/PlacesApi.php +++ /dev/null @@ -1,437 +0,0 @@ -key = $key; - - $this->verifySSL = $verifySSL; - - $this->client = new Client([ - 'base_uri' => self::BASE_URL, - 'headers' => $headers, - ]); - } - - /** - * Find Place Request to google places api. - * - * @param string $input (for example, a name, address, or phone number) - * @param string $inputType (textquery or phonenumber) - * @param array $params - * - * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException - * @return \Illuminate\Support\Collection - */ - public function findPlace(string $input, string $inputType, array $params = []): Collection - { - $this->checkKey(); - - $params['input'] = $input; - - $params['inputtype'] = $inputType; - - $response = $this->makeRequest(self::FIND_PLACE, $params); - - return $this->convertToCollection($response, 'candidates'); - } - - /** - * Place Nearby Search Request to google api. - * - * @param string $location - * @param string|null $radius - * @param array $params - * - * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException - * @return \Illuminate\Support\Collection - */ - public function nearbySearch(string $location, string $radius = null, array $params = []): Collection - { - $this->checkKey(); - - $params = $this->prepareNearbySearchParams($location, $radius, $params); - $response = $this->makeRequest(self::NEARBY_SEARCH_URL, $params); - - return $this->convertToCollection($response, 'results'); - } - - /** - * Place Text Search Request to google places api. - * - * @param string $query - * @param array $params - * - * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException - * @return \Illuminate\Support\Collection - */ - public function textSearch(string $query, array $params = []): Collection - { - $this->checkKey(); - - $params['query'] = $query; - $response = $this->makeRequest(self::TEXT_SEARCH_URL, $params); - - return $this->convertToCollection($response, 'results'); - } - - /** - * Place Details Request to google places api. - * - * @param string $placeId - * @param array $params - * - * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException - * @return \Illuminate\Support\Collection - */ - public function placeDetails(string $placeId, array $params = []): Collection - { - $this->checkKey(); - - $params['placeid'] = $placeId; - - $response = $this->makeRequest(self::DETAILS_SEARCH_URL, $params); - - return $this->convertToCollection($response); - } - - /** - * @param string $photoReference - * @param array $params - * - * @throws \GuzzleHttp\Exception\GuzzleException - * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException - * @return mixed|string - */ - public function photo(string $photoReference, array $params = []): string - { - $this->checkKey(); - - $params['photoreference'] = $photoReference; - - if (!array_any_keys_exists(['maxwidth', 'maxheight'], $params)) { - throw new GooglePlacesApiException('maxwidth or maxheight param is required'); - } - - $options = $this->getOptions($params); - - $url = ''; - - $options['on_stats'] = function (TransferStats $stats) use (&$url) { - $url = $stats->getEffectiveUri(); - }; - - $this->client->get(self::PLACE_PHOTO_URL, $options); - - return (string)$url; - } - - /** - * Place AutoComplete Request to google places api. - * - * @param string $input - * @param array $params - * - * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException - * @return \Illuminate\Support\Collection - */ - public function placeAutocomplete(string $input, array $params = []): Collection - { - $this->checkKey(); - - $params['input'] = $input; - - $response = $this->makeRequest(self::PLACE_AUTOCOMPLETE_URL, $params); - - return $this->convertToCollection($response, 'predictions'); - } - - /** - * Query AutoComplete Request to the Google api. - * - * @param string $input - * @param array $params - * - * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException - * @return \Illuminate\Support\Collection - */ - public function queryAutocomplete(string $input, array $params = []): Collection - { - $this->checkKey(); - - $params['input'] = $input; - - $response = $this->makeRequest(self::QUERY_AUTOCOMPLETE_URL, $params); - - return $this->convertToCollection($response, 'predictions'); - } - - /** - * @param string $uri - * @param array $params - * @param string $method - * - * @throws \SKAgarwal\GoogleApi\Exceptions\InvalidRequestException - * @throws \SKAgarwal\GoogleApi\Exceptions\NotImplementedException - * @throws \SKAgarwal\GoogleApi\Exceptions\OverQueryLimitException - * @throws \SKAgarwal\GoogleApi\Exceptions\RequestDeniedException - * @throws \SKAgarwal\GoogleApi\Exceptions\UnknownErrorException - * @return mixed|string - */ - private function makeRequest(string $uri, array $params, string $method = 'get') - { - $options = $this->getOptions($params, $method); - - $response = json_decode( - $this->client->$method($uri, $options)->getBody()->getContents(), - true - ); - - $this->setStatus($response['status']); - - switch ($response['status']) { - case 'OK': - case 'ZERO_RESULTS': - return $response; - case 'INVALID_REQUEST': - throw new InvalidRequestException( - "Response returned with status: " . $response['status'], - $response['error_message'] ?? null - ); - case 'OVER_QUERY_LIMIT': - throw new OverQueryLimitException( - "Response returned with status: " . $response['status'], - $response['error_message'] ?? null - ); - case 'REQUEST_DENIED': - throw new RequestDeniedException( - "Response returned with status: " . $response['status'], - $response['error_message'] ?? null - ); - case 'UNKNOWN_ERROR': - throw new UnknownErrorException( - "Response returned with status: " . $response['status'], - $response['error_message'] ?? null - ); - default: - throw new NotImplementedException( - "Response returned with status: " . $response['status'], - $response['error_message'] ?? null - ); - } - } - - /** - * @param array $data - * @param null $index - * - * @return \Illuminate\Support\Collection - */ - private function convertToCollection(array $data, $index = null): Collection - { - $data = collect($data); - - if ($index) { - $data[$index] = collect($data[$index]); - } - - return $data; - } - - /** - * @param mixed $status - */ - private function setStatus($status) - { - $this->status = $status; - } - - /** - * @return mixed - */ - public function getStatus() - { - return $this->status; - } - - /** - * @return string|null - */ - public function getKey(): string - { - return $this->key; - } - - /** - * @param string $key - * - * @return $this - */ - public function setKey(string $key): PlacesApi - { - $this->key = $key; - - return $this; - } - - /** - * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException - */ - private function checkKey() - { - if (!$this->key) { - throw new GooglePlacesApiException('API KEY is not specified.'); - } - } - - /** - * Prepare the params for the Place Search. - * - * @param string $location - * @param string $radius - * @param array $params - * - * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException - * @return mixed - */ - private function prepareNearbySearchParams(string $location, string $radius, array $params): array - { - $params['location'] = $location; - $params['radius'] = $radius; - - if (array_key_exists('rankby', $params) - and $params['rankby'] === 'distance' - ) { - unset($params['radius']); - - if (!array_any_keys_exists(['keyword', 'name', 'type'], $params)) { - throw new GooglePlacesApiException("Nearby Search require one" - . " or more of 'keyword', 'name', or 'type' params since 'rankby' = 'distance'."); - } - } elseif (!$radius) { - throw new GooglePlacesApiException("'radius' param is not defined."); - } - - return $params; - } - - /** - * @param bool $verifySSL - * - * @return PlacesApi - */ - public function verifySSL(bool $verifySSL = true): PlacesApi - { - $this->verifySSL = $verifySSL; - - return $this; - } - - /** - * @param array $params - * @param string $method - * - * @return array - */ - private function getOptions(array $params, string $method = 'get'): array - { - $options = [ - 'query' => [ - 'key' => $this->key, - ], - ]; - - if ($method == 'post') { - $options = array_merge(['body' => json_encode($params)], $options); - } else { - $options['query'] = array_merge($options['query'], $params); - } - - $options['http_errors'] = false; - - $options['verify'] = $this->verifySSL; - - if (!empty($this->headers)) { - $options['headers'] = $this->headers; - } - - return $options; - } - - /** - * @param array $headers - * - * @return PlacesApi - */ - public function withHeaders(array $headers): PlacesApi - { - $this->headers = $headers; - - return $this; - } -} diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index a0a2ee8..c3ad349 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -1,4 +1,5 @@ app->singleton('GooglePlaces', function ($app) { - $key = isset($app['config']['google.places.key']) - ? $app['config']['google.places.key'] : null; - - $verifySSL = isset($app['config']['google.places.verify_ssl']) - ? $app['config']['google.places.verify_ssl'] : true; - - $headers = isset($app['config']['google.places.headers']) - ? $app['config']['google.places.headers'] : []; - - return new PlacesApi($key, $verifySSL, $headers); - }); + // } /** * Boot + * + * @return void */ public function boot() { diff --git a/src/helpers.php b/src/helpers.php deleted file mode 100644 index ca7efc4..0000000 --- a/src/helpers.php +++ /dev/null @@ -1,20 +0,0 @@ - Date: Sat, 19 Oct 2024 18:36:22 +0530 Subject: [PATCH 03/14] feat: PlacesNew APIs --- src/Facade.php | 18 + src/PlacesApi.php | 437 ++++++++++++++++++++++++ src/PlacesNew/Endpoint.php | 40 +++ src/PlacesNew/GooglePlaces.php | 198 +++++++++++ src/PlacesNew/Requests/Autocomplete.php | 65 ++++ src/PlacesNew/Requests/NearbySearch.php | 74 ++++ src/PlacesNew/Requests/PlaceDetails.php | 48 +++ src/PlacesNew/Requests/PlacePhoto.php | 58 ++++ src/PlacesNew/Requests/TextSearch.php | 62 ++++ src/ServiceProvider.php | 13 +- src/helpers.php | 20 ++ 11 files changed, 1032 insertions(+), 1 deletion(-) create mode 100644 src/Facade.php create mode 100644 src/PlacesApi.php create mode 100644 src/PlacesNew/Endpoint.php create mode 100644 src/PlacesNew/GooglePlaces.php create mode 100644 src/PlacesNew/Requests/Autocomplete.php create mode 100644 src/PlacesNew/Requests/NearbySearch.php create mode 100644 src/PlacesNew/Requests/PlaceDetails.php create mode 100644 src/PlacesNew/Requests/PlacePhoto.php create mode 100644 src/PlacesNew/Requests/TextSearch.php create mode 100644 src/helpers.php diff --git a/src/Facade.php b/src/Facade.php new file mode 100644 index 0000000..b025c27 --- /dev/null +++ b/src/Facade.php @@ -0,0 +1,18 @@ +key = $key; + + $this->verifySSL = $verifySSL; + + $this->client = new Client([ + 'base_uri' => self::BASE_URL, + 'headers' => $headers, + ]); + } + + /** + * Find Place Request to google places api. + * + * @param string $input (for example, a name, address, or phone number) + * @param string $inputType (textquery or phonenumber) + * @param array $params + * + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + * @return \Illuminate\Support\Collection + */ + public function findPlace(string $input, string $inputType, array $params = []): Collection + { + $this->checkKey(); + + $params['input'] = $input; + + $params['inputtype'] = $inputType; + + $response = $this->makeRequest(self::FIND_PLACE, $params); + + return $this->convertToCollection($response, 'candidates'); + } + + /** + * Place Nearby Search Request to google api. + * + * @param string $location + * @param string|null $radius + * @param array $params + * + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + * @return \Illuminate\Support\Collection + */ + public function nearbySearch(string $location, string $radius = null, array $params = []): Collection + { + $this->checkKey(); + + $params = $this->prepareNearbySearchParams($location, $radius, $params); + $response = $this->makeRequest(self::NEARBY_SEARCH_URL, $params); + + return $this->convertToCollection($response, 'results'); + } + + /** + * Place Text Search Request to google places api. + * + * @param string $query + * @param array $params + * + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + * @return \Illuminate\Support\Collection + */ + public function textSearch(string $query, array $params = []): Collection + { + $this->checkKey(); + + $params['query'] = $query; + $response = $this->makeRequest(self::TEXT_SEARCH_URL, $params); + + return $this->convertToCollection($response, 'results'); + } + + /** + * Place Details Request to google places api. + * + * @param string $placeId + * @param array $params + * + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + * @return \Illuminate\Support\Collection + */ + public function placeDetails(string $placeId, array $params = []): Collection + { + $this->checkKey(); + + $params['placeid'] = $placeId; + + $response = $this->makeRequest(self::DETAILS_SEARCH_URL, $params); + + return $this->convertToCollection($response); + } + + /** + * @param string $photoReference + * @param array $params + * + * @throws \GuzzleHttp\Exception\GuzzleException + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + * @return string + */ + public function photo(string $photoReference, array $params = []): string + { + $this->checkKey(); + + $params['photoreference'] = $photoReference; + + if (!array_any_keys_exists(['maxwidth', 'maxheight'], $params)) { + throw new GooglePlacesApiException('maxwidth or maxheight param is required'); + } + + $options = $this->getOptions($params); + + $url = ''; + + $options['on_stats'] = function (TransferStats $stats) use (&$url) { + $url = $stats->getEffectiveUri(); + }; + + $this->client->get(self::PLACE_PHOTO_URL, $options); + + return (string)$url; + } + + /** + * Place AutoComplete Request to google places api. + * + * @param string $input + * @param array $params + * + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + * @return \Illuminate\Support\Collection + */ + public function placeAutocomplete(string $input, array $params = []): Collection + { + $this->checkKey(); + + $params['input'] = $input; + + $response = $this->makeRequest(self::PLACE_AUTOCOMPLETE_URL, $params); + + return $this->convertToCollection($response, 'predictions'); + } + + /** + * Query AutoComplete Request to the Google api. + * + * @param string $input + * @param array $params + * + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + * @return \Illuminate\Support\Collection + */ + public function queryAutocomplete(string $input, array $params = []): Collection + { + $this->checkKey(); + + $params['input'] = $input; + + $response = $this->makeRequest(self::QUERY_AUTOCOMPLETE_URL, $params); + + return $this->convertToCollection($response, 'predictions'); + } + + /** + * @param string $uri + * @param array $params + * @param string $method + * + * @throws \SKAgarwal\GoogleApi\Exceptions\InvalidRequestException + * @throws \SKAgarwal\GoogleApi\Exceptions\NotImplementedException + * @throws \SKAgarwal\GoogleApi\Exceptions\OverQueryLimitException + * @throws \SKAgarwal\GoogleApi\Exceptions\RequestDeniedException + * @throws \SKAgarwal\GoogleApi\Exceptions\UnknownErrorException + * @return mixed|string + */ + private function makeRequest(string $uri, array $params, string $method = 'get') + { + $options = $this->getOptions($params, $method); + + $response = json_decode( + $this->client->$method($uri, $options)->getBody()->getContents(), + true + ); + + $this->setStatus($response['status']); + + switch ($response['status']) { + case 'OK': + case 'ZERO_RESULTS': + return $response; + case 'INVALID_REQUEST': + throw new InvalidRequestException( + "Response returned with status: " . $response['status'], + $response['error_message'] ?? null + ); + case 'OVER_QUERY_LIMIT': + throw new OverQueryLimitException( + "Response returned with status: " . $response['status'], + $response['error_message'] ?? null + ); + case 'REQUEST_DENIED': + throw new RequestDeniedException( + "Response returned with status: " . $response['status'], + $response['error_message'] ?? null + ); + case 'UNKNOWN_ERROR': + throw new UnknownErrorException( + "Response returned with status: " . $response['status'], + $response['error_message'] ?? null + ); + default: + throw new NotImplementedException( + "Response returned with status: " . $response['status'], + $response['error_message'] ?? null + ); + } + } + + /** + * @param array $data + * @param null $index + * + * @return \Illuminate\Support\Collection + */ + private function convertToCollection(array $data, $index = null): Collection + { + $data = collect($data); + + if ($index) { + $data[$index] = collect($data[$index]); + } + + return $data; + } + + /** + * @param mixed $status + */ + private function setStatus($status) + { + $this->status = $status; + } + + /** + * @return mixed + */ + public function getStatus() + { + return $this->status; + } + + /** + * @return string|null + */ + public function getKey(): string + { + return $this->key; + } + + /** + * @param string $key + * + * @return $this + */ + public function setKey(string $key): PlacesApi + { + $this->key = $key; + + return $this; + } + + /** + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + */ + private function checkKey() + { + if (!$this->key) { + throw new GooglePlacesApiException('API KEY is not specified.'); + } + } + + /** + * Prepare the params for the Place Search. + * + * @param string $location + * @param string $radius + * @param array $params + * + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + * @return mixed + */ + private function prepareNearbySearchParams(string $location, string $radius, array $params): array + { + $params['location'] = $location; + $params['radius'] = $radius; + + if (array_key_exists('rankby', $params) + and $params['rankby'] === 'distance' + ) { + unset($params['radius']); + + if (!array_any_keys_exists(['keyword', 'name', 'type'], $params)) { + throw new GooglePlacesApiException("Nearby Search require one" + . " or more of 'keyword', 'name', or 'type' params since 'rankby' = 'distance'."); + } + } elseif (!$radius) { + throw new GooglePlacesApiException("'radius' param is not defined."); + } + + return $params; + } + + /** + * @param bool $verifySSL + * + * @return PlacesApi + */ + public function verifySSL(bool $verifySSL = true): PlacesApi + { + $this->verifySSL = $verifySSL; + + return $this; + } + + /** + * @param array $params + * @param string $method + * + * @return array + */ + private function getOptions(array $params, string $method = 'get'): array + { + $options = [ + 'query' => [ + 'key' => $this->key, + ], + ]; + + if ($method == 'post') { + $options = array_merge(['body' => json_encode($params)], $options); + } else { + $options['query'] = array_merge($options['query'], $params); + } + + $options['http_errors'] = false; + + $options['verify'] = $this->verifySSL; + + if (!empty($this->headers)) { + $options['headers'] = $this->headers; + } + + return $options; + } + + /** + * @param array $headers + * + * @return PlacesApi + */ + public function withHeaders(array $headers): PlacesApi + { + $this->headers = $headers; + + return $this; + } +} diff --git a/src/PlacesNew/Endpoint.php b/src/PlacesNew/Endpoint.php new file mode 100644 index 0000000..c19043c --- /dev/null +++ b/src/PlacesNew/Endpoint.php @@ -0,0 +1,40 @@ +value)->replace('{placeId}', $placeId)->toString(); + } + + /** + * @param string $name + * + * @return string + */ + public static function placePhoto(string $name): string + { + return Str::of(self::PLACE_PHOTO->value)->replace('{name}', $name)->toString(); + } +} diff --git a/src/PlacesNew/GooglePlaces.php b/src/PlacesNew/GooglePlaces.php new file mode 100644 index 0000000..adf90f9 --- /dev/null +++ b/src/PlacesNew/GooglePlaces.php @@ -0,0 +1,198 @@ +key = $key; + $this->verifySSL = $verifySSL ?? true; + } + + /** + * @return string|null + */ + public function getKey(): ?string + { + return $this->key; + } + + /** + * @param string $key + * + * @return $this + */ + public function setKey(string $key): static + { + $this->key = $key; + + return $this; + } + + /** + * @param bool $verifySSL + * + * @return static + */ + public function verifySSL(bool $verifySSL = true): static + { + $this->verifySSL = $verifySSL; + + return $this; + } + + /** + * @return string + */ + public function resolveBaseUrl(): string + { + return Endpoint::BASE_URL->value; + } + + /** + * @return bool[] + */ + protected function defaultConfig(): array + { + return [ + 'verify' => $this->verifySSL, + ]; + } + + /** + * @return \Saloon\Contracts\Authenticator|null + */ + protected function defaultAuth(): ?Authenticator + { + return new HeaderAuthenticator($this->key, 'X-Goog-Api-Key'); + } + + /** + * @param string $input + * @param array $fields + * @param bool $includeQueryPredictions + * @param array $params + * + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function autocomplete( + string $input, + array $fields = ['*'], + bool $includeQueryPredictions = false, + array $params = [], + ): Response { + return $this->send(new Autocomplete($input, $fields, $includeQueryPredictions, $params)); + } + + /** + * @param float $latitude + * @param float $longitude + * @param float $radius + * @param array $fields + * @param array $params + * + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function nearbySearch( + float $latitude, + float $longitude, + float $radius = 0.0, + array $fields = ['*'], + array $params = [], + ): Response { + return $this->send(new NearbySearch($latitude, $longitude, $radius, $fields, $params)); + } + + /** + * @param string $placeId + * @param array $fields + * @param array $params + * + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function placeDetails(string $placeId, array $fields = ['*'], array $params = []): Response + { + return $this->send(new PlaceDetails($placeId, $fields, $params)); + } + + /** + * @param string $name + * @param int|null $maxHeightPx + * @param int|null $maxWidthPx + * @param bool $skipHttpRedirect + * + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function placePhoto( + string $name, + int $maxHeightPx = null, + int $maxWidthPx = null, + bool $skipHttpRedirect = false, + ): Response { + return $this->send(new PlacePhoto($name, $maxHeightPx, $maxWidthPx, $skipHttpRedirect)); + } + + /** + * @param string $textQuery + * @param array $fields + * @param array $params + * + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return \Saloon\Http\Response + */ + public function textSearch(string $textQuery, array $fields = ['*'], array $params = []): Response + { + return $this->send(new TextSearch($textQuery, $fields, $params)); + } +} diff --git a/src/PlacesNew/Requests/Autocomplete.php b/src/PlacesNew/Requests/Autocomplete.php new file mode 100644 index 0000000..0847f54 --- /dev/null +++ b/src/PlacesNew/Requests/Autocomplete.php @@ -0,0 +1,65 @@ +value; + } + + /** + * @return array|mixed[] + */ + protected function defaultQuery(): array + { + return [ + 'fields' => implode(',', $this->fields), + ]; + } + + /** + * @return array + */ + protected function defaultBody(): array + { + return [ + 'input' => $this->input, + 'includeQueryPredictions' => $this->includeQueryPredictions, + ...$this->params, + ]; + } +} diff --git a/src/PlacesNew/Requests/NearbySearch.php b/src/PlacesNew/Requests/NearbySearch.php new file mode 100644 index 0000000..8e46ced --- /dev/null +++ b/src/PlacesNew/Requests/NearbySearch.php @@ -0,0 +1,74 @@ +value; + } + + /** + * @return array|mixed[] + */ + protected function defaultQuery(): array + { + return [ + 'fields' => implode(',', $this->fields), + ]; + } + + /** + * @return array|mixed[] + */ + protected function defaultBody(): array + { + return [ + 'locationRestriction' => [ + 'circle' => [ + 'center' => [ + 'latitude' => $this->latitude, + 'longitude' => $this->longitude, + ], + 'radius' => $this->radius, + ], + ], + ...$this->params, + ]; + } +} diff --git a/src/PlacesNew/Requests/PlaceDetails.php b/src/PlacesNew/Requests/PlaceDetails.php new file mode 100644 index 0000000..b77c5ec --- /dev/null +++ b/src/PlacesNew/Requests/PlaceDetails.php @@ -0,0 +1,48 @@ +paceId); + } + + /** + * @return array|mixed[] + */ + protected function defaultQuery(): array + { + return [ + 'fields' => implode(',', $this->fields), + ...$this->params, + ]; + } +} diff --git a/src/PlacesNew/Requests/PlacePhoto.php b/src/PlacesNew/Requests/PlacePhoto.php new file mode 100644 index 0000000..8704329 --- /dev/null +++ b/src/PlacesNew/Requests/PlacePhoto.php @@ -0,0 +1,58 @@ +maxHeightPx && !$this->maxWidthPx) { + throw new GooglePlacesApiException('$maxHeightPx or $maxWidthPx param is required'); + } + } + + /** + * @return string + */ + public function resolveEndpoint(): string + { + return Endpoint::placePhoto($this->name); + } + + /** + * @return array|mixed[] + */ + protected function defaultQuery(): array + { + return array_filter([ + 'maxHeightPx' => $this->maxHeightPx, + 'maxWidthPx' => $this->maxWidthPx, + 'skipHttpRedirect' => $this->skipHttpRedirect, + ], fn ($value) => $value !== null); + } +} diff --git a/src/PlacesNew/Requests/TextSearch.php b/src/PlacesNew/Requests/TextSearch.php new file mode 100644 index 0000000..ba73066 --- /dev/null +++ b/src/PlacesNew/Requests/TextSearch.php @@ -0,0 +1,62 @@ +value; + } + + /** + * @return array|mixed[] + */ + protected function defaultQuery(): array + { + return [ + 'fields' => implode(',', $this->fields), + ]; + } + + /** + * @return array|mixed[] + */ + protected function defaultBody(): array + { + return [ + 'textQuery' => $this->textQuery, + ...$this->params, + ]; + } +} diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index c3ad349..945323c 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -13,7 +13,18 @@ class ServiceProvider extends BaseServiceProvider */ public function register() { - // + $this->app->singleton('GooglePlaces', function ($app) { + $key = isset($app['config']['google.places.key']) + ? $app['config']['google.places.key'] : null; + + $verifySSL = isset($app['config']['google.places.verify_ssl']) + ? $app['config']['google.places.verify_ssl'] : true; + + $headers = isset($app['config']['google.places.headers']) + ? $app['config']['google.places.headers'] : []; + + return new PlacesApi($key, $verifySSL, $headers); + }); } /** diff --git a/src/helpers.php b/src/helpers.php new file mode 100644 index 0000000..837f29b --- /dev/null +++ b/src/helpers.php @@ -0,0 +1,20 @@ + Date: Sat, 19 Oct 2024 19:16:39 +0530 Subject: [PATCH 04/14] feat: Namepsace Change and Abstracted Connector --- src/Connector.php | 95 ++++++++++++++++++ src/Facade.php | 3 + src/{GoogleMaps => Places}/Endpoint.php | 4 +- .../GooglePlaces.php} | 99 +++---------------- .../Requests/FindPlace.php | 4 +- .../Requests/NearbySearch.php | 4 +- src/{GoogleMaps => Places}/Requests/Photo.php | 4 +- .../Requests/PlaceAutocomplete.php | 4 +- .../Requests/PlaceDetails.php | 4 +- .../Requests/QueryAutocomplete.php | 4 +- .../Requests/TextSearch.php | 4 +- src/PlacesApi.php | 5 +- src/PlacesNew/GooglePlaces.php | 90 +---------------- 13 files changed, 130 insertions(+), 194 deletions(-) create mode 100644 src/Connector.php rename src/{GoogleMaps => Places}/Endpoint.php (80%) rename src/{GoogleMaps/GoogleMaps.php => Places/GooglePlaces.php} (57%) rename src/{GoogleMaps => Places}/Requests/FindPlace.php (90%) rename src/{GoogleMaps => Places}/Requests/NearbySearch.php (91%) rename src/{GoogleMaps => Places}/Requests/Photo.php (87%) rename src/{GoogleMaps => Places}/Requests/PlaceAutocomplete.php (89%) rename src/{GoogleMaps => Places}/Requests/PlaceDetails.php (89%) rename src/{GoogleMaps => Places}/Requests/QueryAutocomplete.php (89%) rename src/{GoogleMaps => Places}/Requests/TextSearch.php (89%) diff --git a/src/Connector.php b/src/Connector.php new file mode 100644 index 0000000..784f404 --- /dev/null +++ b/src/Connector.php @@ -0,0 +1,95 @@ +key = $key; + $this->verifySSL = $verifySSL ?? true; + } + + /** + * @return string|null + */ + public function getKey(): ?string + { + return $this->key; + } + + /** + * @param string $key + * + * @return $this + */ + public function setKey(string $key): static + { + $this->key = $key; + + return $this; + } + + /** + * @param bool $verifySSL + * + * @return static + */ + public function verifySSL(bool $verifySSL = true): static + { + $this->verifySSL = $verifySSL; + + return $this; + } + + /** + * @return bool[] + */ + protected function defaultConfig(): array + { + return [ + 'verify' => $this->verifySSL, + ]; + } + + /** + * @return \Saloon\Contracts\Authenticator|null + */ + protected function defaultAuth(): ?Authenticator + { + return new HeaderAuthenticator($this->key, 'X-Goog-Api-Key'); + } +} diff --git a/src/Facade.php b/src/Facade.php index b025c27..f8898b6 100644 --- a/src/Facade.php +++ b/src/Facade.php @@ -3,6 +3,9 @@ use Illuminate\Support\Facades\Facade as BaseFacade; +/** + * @deprecated + */ class Facade extends BaseFacade { /** diff --git a/src/GoogleMaps/Endpoint.php b/src/Places/Endpoint.php similarity index 80% rename from src/GoogleMaps/Endpoint.php rename to src/Places/Endpoint.php index b8f2d5a..365fc02 100644 --- a/src/GoogleMaps/Endpoint.php +++ b/src/Places/Endpoint.php @@ -1,10 +1,10 @@ key = $key; - $this->verifySSL = $verifySSL ?? true; - } - - /** - * @return string|null - */ - public function getKey(): ?string - { - return $this->key; - } - - /** - * @param string $key - * - * @return $this - */ - public function setKey(string $key): static - { - $this->key = $key; - - return $this; - } - - /** - * @param bool $verifySSL - * - * @return static - */ - public function verifySSL(bool $verifySSL = true): static - { - $this->verifySSL = $verifySSL; - - return $this; - } - /** * @return string */ public function resolveBaseUrl(): string { - return Endpoint::BASE->value; - } - - /** - * @return bool[] - */ - protected function defaultConfig(): array - { - return [ - 'verify' => $this->verifySSL, - ]; + return Endpoint::BASE_URL->value; } /** diff --git a/src/GoogleMaps/Requests/FindPlace.php b/src/Places/Requests/FindPlace.php similarity index 90% rename from src/GoogleMaps/Requests/FindPlace.php rename to src/Places/Requests/FindPlace.php index 5148e81..52dde15 100644 --- a/src/GoogleMaps/Requests/FindPlace.php +++ b/src/Places/Requests/FindPlace.php @@ -1,10 +1,10 @@ key; } diff --git a/src/PlacesNew/GooglePlaces.php b/src/PlacesNew/GooglePlaces.php index adf90f9..c506d08 100644 --- a/src/PlacesNew/GooglePlaces.php +++ b/src/PlacesNew/GooglePlaces.php @@ -2,12 +2,8 @@ namespace SKAgarwal\GoogleApi\PlacesNew; -use Saloon\Contracts\Authenticator; -use Saloon\Http\Auth\HeaderAuthenticator; -use Saloon\Http\Auth\QueryAuthenticator; -use Saloon\Http\Connector; use Saloon\Http\Response; -use SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException; +use SKAgarwal\GoogleApi\Connector; use SKAgarwal\GoogleApi\PlacesNew\Requests\Autocomplete; use SKAgarwal\GoogleApi\PlacesNew\Requests\NearbySearch; use SKAgarwal\GoogleApi\PlacesNew\Requests\PlaceDetails; @@ -16,72 +12,6 @@ class GooglePlaces extends Connector { - /** - * @var string|null - */ - private ?string $key; - - /** - * @var bool - */ - private bool $verifySSL = true; - - /** - * @param string|null $key - * @param bool|null $verifySSL - * - * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException - */ - public function __construct(?string $key = null, ?bool $verifySSL = null) - { - $errorMessage = 'Google Places API KEY is missing.'; - - if (function_exists('config')) { - $key = $key ?? config('google.places.key'); - $verifySSL = $verifySSL ?? config('google.places.verify_ssl'); - $errorMessage = 'Google Places API KEY is not set in google config file.'; - } - - if (!$key) { - throw new GooglePlacesApiException($errorMessage); - } - - $this->key = $key; - $this->verifySSL = $verifySSL ?? true; - } - - /** - * @return string|null - */ - public function getKey(): ?string - { - return $this->key; - } - - /** - * @param string $key - * - * @return $this - */ - public function setKey(string $key): static - { - $this->key = $key; - - return $this; - } - - /** - * @param bool $verifySSL - * - * @return static - */ - public function verifySSL(bool $verifySSL = true): static - { - $this->verifySSL = $verifySSL; - - return $this; - } - /** * @return string */ @@ -90,24 +20,6 @@ public function resolveBaseUrl(): string return Endpoint::BASE_URL->value; } - /** - * @return bool[] - */ - protected function defaultConfig(): array - { - return [ - 'verify' => $this->verifySSL, - ]; - } - - /** - * @return \Saloon\Contracts\Authenticator|null - */ - protected function defaultAuth(): ?Authenticator - { - return new HeaderAuthenticator($this->key, 'X-Goog-Api-Key'); - } - /** * @param string $input * @param array $fields From 2cbd350ebd7b8f6c5fd78e194fd2a2fdfd74e8a3 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sat, 19 Oct 2024 19:28:41 +0530 Subject: [PATCH 05/14] feat: Option to throw exception on Errors --- config/google.php | 10 ++++++++++ src/Connector.php | 31 ++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/config/google.php b/config/google.php index 164de66..1edef15 100644 --- a/config/google.php +++ b/config/google.php @@ -11,4 +11,14 @@ 'verify_ssl' => true, ], + + /** + * Throw exceptions when Google API returns an error + * + * If set to false, Error message will be returned as response, + * and you need check if the response has failed using the failed() method + * + * You can also use throw() method to throw an exception per-request basis + */ + 'throw_on_errors' => false, ]; diff --git a/src/Connector.php b/src/Connector.php index 784f404..b137fcc 100644 --- a/src/Connector.php +++ b/src/Connector.php @@ -3,8 +3,11 @@ namespace SKAgarwal\GoogleApi; use Saloon\Contracts\Authenticator; +use Saloon\Enums\PipeOrder; use Saloon\Http\Auth\HeaderAuthenticator; use Saloon\Http\Connector as SaloonConnector; +use Saloon\Http\PendingRequest; +use Saloon\Http\Response; use SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException; abstract class Connector extends SaloonConnector @@ -19,19 +22,26 @@ abstract class Connector extends SaloonConnector */ protected bool $verifySSL = true; + /** + * @var bool + */ + protected bool $throwOnErrors = false; + /** * @param string|null $key * @param bool|null $verifySSL + * @param bool|null $throwOnErrors * * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException */ - public function __construct(?string $key = null, ?bool $verifySSL = null) + public function __construct(?string $key = null, ?bool $verifySSL = null, ?bool $throwOnErrors = null) { $errorMessage = 'Google Places API KEY is missing.'; if (function_exists('config')) { $key = $key ?? config('google.places.key'); $verifySSL = $verifySSL ?? config('google.places.verify_ssl'); + $throwOnErrors = $throwOnErrors ?? config('google.throw_on_errors', false); $errorMessage = 'Google Places API KEY is not set in google config file.'; } @@ -41,6 +51,18 @@ public function __construct(?string $key = null, ?bool $verifySSL = null) $this->key = $key; $this->verifySSL = $verifySSL ?? true; + $this->throwOnErrors = $throwOnErrors ?? false; + } + + public function boot(PendingRequest $pendingRequest): void + { + if ($this->throwOnErrors) { + $pendingRequest->middleware()->onResponse( + callable: static fn (Response $response) => $response->throw(), + name: 'alwaysThrowOnErrors', + order: PipeOrder::LAST, + ); + } } /** @@ -75,6 +97,13 @@ public function verifySSL(bool $verifySSL = true): static return $this; } + public function throwOnErrors(bool $throwOnErrors): static + { + $this->throwOnErrors = $throwOnErrors; + + return $this; + } + /** * @return bool[] */ From dc5cd709f65d5c57e655fdc6e796d0b8838ef467 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sat, 19 Oct 2024 20:09:19 +0530 Subject: [PATCH 06/14] feat: Handle Validations and Photo in Legacy API --- composer.json | 3 +++ src/Places/GooglePlaces.php | 17 ++++++++++++++++- src/Places/Requests/NearbySearch.php | 22 +++++++++++++++++++--- src/Places/Requests/Photo.php | 26 ++++++++++++++++++++++++-- src/PlacesNew/GooglePlaces.php | 11 +++-------- src/PlacesNew/Requests/PlacePhoto.php | 4 +--- 6 files changed, 66 insertions(+), 17 deletions(-) diff --git a/composer.json b/composer.json index bb3fdd2..253e5d1 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,9 @@ "skagarwal/reflection": "~1.0" }, "autoload": { + "files": [ + "src/helpers.php" + ], "psr-4": { "SKAgarwal\\GoogleApi\\": "src/" } diff --git a/src/Places/GooglePlaces.php b/src/Places/GooglePlaces.php index 0109e93..ba358b2 100644 --- a/src/Places/GooglePlaces.php +++ b/src/Places/GooglePlaces.php @@ -8,6 +8,7 @@ use SKAgarwal\GoogleApi\Connector; use SKAgarwal\GoogleApi\Places\Requests\FindPlace; use SKAgarwal\GoogleApi\Places\Requests\NearbySearch; +use SKAgarwal\GoogleApi\Places\Requests\Photo; use SKAgarwal\GoogleApi\Places\Requests\PlaceAutocomplete; use SKAgarwal\GoogleApi\Places\Requests\PlaceDetails; use SKAgarwal\GoogleApi\Places\Requests\QueryAutocomplete; @@ -51,7 +52,7 @@ public function findPlace(string $input, string $inputType, array $params = []): * @param array $params * * @throws \Saloon\Exceptions\Request\FatalRequestException - * @throws \Saloon\Exceptions\Request\RequestException + * @throws \Saloon\Exceptions\Request\RequestException|\SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException * @return \Saloon\Http\Response */ public function nearbySearch(string $location, ?string $radius = null, array $params = []): Response @@ -110,4 +111,18 @@ public function textSearch(string $query, array $params = []): Response { return $this->send(new TextSearch($query, $params)); } + + /** + * @param string $photoReference + * @param array $params + * + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException + * @throws \Saloon\Exceptions\Request\FatalRequestException + * @throws \Saloon\Exceptions\Request\RequestException + * @return string|null + */ + public function photo(string $photoReference, array $params = []): ?string + { + return $this->send(new Photo($photoReference, $params))->getRequest()->getPhotoUrl(); + } } diff --git a/src/Places/Requests/NearbySearch.php b/src/Places/Requests/NearbySearch.php index 32cae6f..5509bb0 100644 --- a/src/Places/Requests/NearbySearch.php +++ b/src/Places/Requests/NearbySearch.php @@ -4,6 +4,7 @@ use Saloon\Enums\Method; use Saloon\Http\Request; +use SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException; use SKAgarwal\GoogleApi\Places\Endpoint; /** @@ -20,12 +21,27 @@ class NearbySearch extends Request * @param string $location * @param string|null $radius * @param array $params + * + * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException */ public function __construct( private readonly string $location, - private readonly ?string $radius = null, - private readonly array $params = [], - ) {} + private ?string $radius = null, + private array $params = [], + ) { + $this->params['radius'] = $radius; + + if (array_key_exists('rankby', $this->params) and $this->params['rankby'] === 'distance') { + unset($this->params['radius']); + + if (!array_any_keys_exists(['keyword', 'name', 'type'], $this->params)) { + throw new GooglePlacesApiException("Nearby Search require one" + . " or more of 'keyword', 'name', or 'type' params since 'rankby' = 'distance'."); + } + } elseif (!$this->radius) { + throw new GooglePlacesApiException("'radius' param is not defined."); + } + } /** * @return string diff --git a/src/Places/Requests/Photo.php b/src/Places/Requests/Photo.php index 9f38909..3dde496 100644 --- a/src/Places/Requests/Photo.php +++ b/src/Places/Requests/Photo.php @@ -2,8 +2,10 @@ namespace SKAgarwal\GoogleApi\Places\Requests; +use GuzzleHttp\TransferStats; use Saloon\Enums\Method; use Saloon\Http\Request; +use SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException; use SKAgarwal\GoogleApi\Places\Endpoint; /** @@ -15,10 +17,25 @@ class Photo extends Request { protected Method $method = Method::GET; + protected ?string $photoUrl = null; + public function __construct( private readonly string $photoReference, private readonly array $params = [], - ) {} + ) { + if (!array_any_keys_exists(['maxwidth', 'maxheight'], $this->params)) { + throw new GooglePlacesApiException('maxwidth or maxheight param is required'); + } + } + + protected function defaultConfig(): array + { + return [ + 'on_stats' => function (TransferStats $stats) { + $this->photoUrl = $stats->getEffectiveUri(); + }, + ]; + } public function resolveEndpoint(): string { @@ -28,8 +45,13 @@ public function resolveEndpoint(): string protected function defaultQuery(): array { return [ - 'photoreference' => $this->photoReference, + 'photo_reference' => $this->photoReference, ...$this->params, ]; } + + public function getPhotoUrl(): ?string + { + return $this->photoUrl; + } } diff --git a/src/PlacesNew/GooglePlaces.php b/src/PlacesNew/GooglePlaces.php index c506d08..a81efe9 100644 --- a/src/PlacesNew/GooglePlaces.php +++ b/src/PlacesNew/GooglePlaces.php @@ -78,20 +78,15 @@ public function placeDetails(string $placeId, array $fields = ['*'], array $para * @param string $name * @param int|null $maxHeightPx * @param int|null $maxWidthPx - * @param bool $skipHttpRedirect * * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException * @throws \Saloon\Exceptions\Request\FatalRequestException * @throws \Saloon\Exceptions\Request\RequestException * @return \Saloon\Http\Response */ - public function placePhoto( - string $name, - int $maxHeightPx = null, - int $maxWidthPx = null, - bool $skipHttpRedirect = false, - ): Response { - return $this->send(new PlacePhoto($name, $maxHeightPx, $maxWidthPx, $skipHttpRedirect)); + public function placePhoto(string $name, int $maxHeightPx = null, int $maxWidthPx = null): Response + { + return $this->send(new PlacePhoto($name, $maxHeightPx, $maxWidthPx)); } /** diff --git a/src/PlacesNew/Requests/PlacePhoto.php b/src/PlacesNew/Requests/PlacePhoto.php index 8704329..f562c4b 100644 --- a/src/PlacesNew/Requests/PlacePhoto.php +++ b/src/PlacesNew/Requests/PlacePhoto.php @@ -21,7 +21,6 @@ class PlacePhoto extends Request * @param string $name * @param int|null $maxHeightPx * @param int|null $maxWidthPx - * @param bool $skipHttpRedirect * * @throws \SKAgarwal\GoogleApi\Exceptions\GooglePlacesApiException */ @@ -29,7 +28,6 @@ public function __construct( private readonly string $name, private readonly ?int $maxHeightPx = null, private readonly ?int $maxWidthPx = null, - private readonly bool $skipHttpRedirect = false, ) { if (!$this->maxHeightPx && !$this->maxWidthPx) { throw new GooglePlacesApiException('$maxHeightPx or $maxWidthPx param is required'); @@ -52,7 +50,7 @@ protected function defaultQuery(): array return array_filter([ 'maxHeightPx' => $this->maxHeightPx, 'maxWidthPx' => $this->maxWidthPx, - 'skipHttpRedirect' => $this->skipHttpRedirect, + 'skipHttpRedirect' => true, ], fn ($value) => $value !== null); } } From d26afa5e6101631f8fe0a56f4a392dff64840208 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sat, 19 Oct 2024 20:09:56 +0530 Subject: [PATCH 07/14] feat: removed todo --- src/Places/Requests/Photo.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Places/Requests/Photo.php b/src/Places/Requests/Photo.php index 3dde496..7d5ba69 100644 --- a/src/Places/Requests/Photo.php +++ b/src/Places/Requests/Photo.php @@ -9,8 +9,6 @@ use SKAgarwal\GoogleApi\Places\Endpoint; /** - * todo only use it in new one. - * * @see https://developers.google.com/maps/documentation/places/web-service/photos */ class Photo extends Request From b60f8bb0fb56fb2924f88d27afec6faf94184633 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sun, 17 Nov 2024 04:41:13 +0530 Subject: [PATCH 08/14] feat: WIP Documentation --- README-Legacy.md | 224 ++++++++++++++++++++++++++++++++++++++++++++++ README.md | 156 ++++++++++++-------------------- config/google.php | 5 ++ src/Connector.php | 12 +++ 4 files changed, 299 insertions(+), 98 deletions(-) create mode 100644 README-Legacy.md diff --git a/README-Legacy.md b/README-Legacy.md new file mode 100644 index 0000000..9c679df --- /dev/null +++ b/README-Legacy.md @@ -0,0 +1,224 @@ + +[![Latest Stable Version](https://poser.pugx.org/skagarwal/google-places-api/v/stable?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) +[![Latest Unstable Version](https://poser.pugx.org/skagarwal/google-places-api/v/unstable?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) +[![Total Downloads](https://poser.pugx.org/skagarwal/google-places-api/downloads?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) +[![License](https://poser.pugx.org/skagarwal/google-places-api/license?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) + + +# Google Places API. + +This is a PHP wrapper for **Google Places API Web Service**. And is [Laravel Framework](https://laravel.com/docs/5.2) friendly. + +## About Package +With just 2 lines of code you can request to any google places api feature. No need to manually perform any curl requests. + +### The following place requests are available: +* [Place Search](#place-search) This service gives a list of places based on a user's location or search string. +* [Place Details](#place-details) This service gives more detailed information about a specific Place, including user reviews. +* [Place Autocomplete](#place-autocomplete) This service is Used to automatically fill in the name and/or address of a place as you type. +* [Query Autocomplete](#query-autocomplete) This service is Used to provide a query prediction service for text-based geographic searches, by returning suggested queries as you type. +* [Place Photo](#place-photo) This gives you access to the millions of photos stored in the Google's Places database +* [Custom Headers](#custom-headers) Set Custom Headers. +* [Additional Methods](#additional-methods) Additional Methods Available. + +# Installation +Install it with composer +``` +composer require skagarwal/google-places-api +``` + + + +# Usage + +**Laravel user can see the [Laravel Usage](#laravel-usage) section** + +## Step 1 - Import the class using namespace +```php +use SKAgarwal\GoogleApi\PlacesApi; +``` + +## Step 2 - Initiate the object +```php +$googlePlaces = new PlacesApi('API KEY'); +``` + +**Note:** You can also set the **API KEY** after initiating the class using `setKey('KEY')` method. You can chain this with method with any other methods. + +## Step 3 - Start Using the Api. +Example: +```php +$response = $googlePlaces->placeAutocomplete('some Place'); +``` + +As mentioned earlier just 2 lines of code to make any request. + +**Full example:** +```php +use SKAgarwal\GoogleApi\PlacesApi; + + +function () { + $googlePlaces = new PlacesApi('API_KEY') # line 1 + $response = $googlePlaces->placeAutocomplete('some input'); # line 2 +} + +``` + +--- + + +# Use with Laravel +## For Laravel 5.5 +Auto Discovery added. + +## For Laravel 5.4 and below +## Step 1 +Set up the service provider and facade in the **config\app.php** +```php + +'providers' => [ +.... +.... +SKAgarwal\GoogleApi\ServiceProvider::class, +]; + +'aliases' => [ +.... +.... +'GooglePlaces' => SKAgarwal\GoogleApi\Facade::class, +]; + +``` + +## Step 2 +publish the config file with following artisan command +``` +php artisan vendor:publish --provider="SKAgarwal\GoogleApi\ServiceProvider" +``` + +This will create **google.php** file in the config directory. + +Set the *API KEY* in this config file. + +## Set 3 +Start using the package using Facade. + +``` +$response = GooglePlaces::placeAutocomplete('some city'); +``` + +--- +# Response +The response returned is a [Laravel's Collection](https://laravel.com/docs/5.2/collections) so that you can perform any of the available collection methods on it. + +
+If you are not familiar with Laravel's Collection you can either reference the docs here or you can use response as simple array. +
+ +--- + +# Available Methods + + +## Place Search +### nearbySearch($location, $radius = null, $params = []) +* `location` — The latitude/longitude around which to retrieve place information. This must be specified as latitude, longitude. +* 'radius' — Defines the distance (in meters) within which to return place results. The maximum allowed radius is 50 000 meters. Note that `radius` must not be included if `rankby=distance` (described under **Optional parameters** below) is specified. +* If `rankby=distance` (described under **Optional parameters** below) is specified, then one or more of `keyword`, `name`, or `types` is required. +* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/search) + +### textSearch($query, $params = []) +* `query` — The text string on which to search, for example: "restaurant". The Google Places service will return candidate matches based on this string and order the results based on their perceived relevance. +* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/search) + +### findPlace($input, $inputType, $params = []) +* `input` — The text input specifying which place to search for (for example, a name, address, or phone number). +* `inputType` — The type of input. This can be one of either textquery or phonenumber. Phone numbers must be in international format (prefixed by a plus sign ("+"), followed by the country code, then the phone number itself). +* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/search#FindPlaceRequests) + +--- + + +# Place Details +### placeDetails($placeId, $params = []) +* `placeId` — A textual identifier that uniquely identifies a place, returned from a Place Search. +* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/details) + +--- + + +# Place Autocomplete +### placeAutocomplete($input, $params = []) +* `input` — The text string on which to search. The Place Autocomplete service will return candidate matches based on this string and order results based on their perceived relevance. +* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/autocomplete) + +--- + + +# Query Autocomplete +### queryAutocomplete($input, $params = []) +* `input` — The text string on which to search. The Places service will return candidate matches based on this string and order results based on their perceived relevance. +* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/query) + +--- + + +# Place Photo +### photo($photoReference, $params = []) +* `params` - The set of key-value parameters necessary to add a place to Google. You can refer to the fields on [Google's Official Webpage regarding Place Add](https://developers.google.com/places/web-service/photos) + +--- + + +# Custom Headers +### withHeaders(array $headers) +Call This method before any other methods to set the headers. You can chain this method. + +### new PlacesApi($key = null, $verifySSL = true, array $headers = []) +To have custom headers set for every call, you can pass 3rd parameter as the headers to class constructor. + +**Note:** For Laravel Users, you can set this in config file with key `headers` + +--- + + +# Additional Methods +### getStatus() +This will return the status of the response send by google api. Use it after making any request. + +### getKey() +This will return the `API KEY` been used with the requests. + +### setKey($key) +This will set the `API KEY`. + +### verifySSL($verifySSL = true) +You can pass `false` to disable Verification of SSL Certification. + +**Note:** For Laravel Users, you can set this in config file with key `verify_ssl` + +Or You can Pass the path to the certificate. + + +# Exceptions +Google Places API may throw various exceptions based on the given `$params` or response and is located in the `SKAgarwal\GoogleApi\Exceptions` namespace. + +- A `GooglePlacesApiException` is thrown when no `API KEY` is provided or `$params` is invalid. +**Note:** This is the parent class for the preceding exceptions. +- A `InvalidRequestException` is thrown when the response `status` is `INVALID_REQUEST` +- A `OverQueryLimitException` is thrown when the response `status` is `OVER_QUERY_LIMIT` +- A `RequestDeniedException` is thrown when the response `status` is `REQUEST_DENIED` +- A `UnknownErrorException` is thrown when the response `status` is `UNKNOWN_ERROR` +- A `NotImplementedException` is thrown when the response cannot be determined. + +If any of these exception has been thrown, you can use the `getErrorMessage()` method to get the `error_message` field from the response if any is provided. +**Note:** `error_message` field is not guaranteed to be always present, and its content is subject to change. + +# Contribution +Feel free to report issues or make Pull Requests. +If you find this document can be improved in any way, please feel free to open an issue for it. + +# License + +The Google Places Api is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) diff --git a/README.md b/README.md index 9c679df..7b56c8b 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,21 @@ # Google Places API. -This is a PHP wrapper for **Google Places API Web Service**. And is [Laravel Framework](https://laravel.com/docs/5.2) friendly. +This is a PHP wrapper for **Google Places API Web Service**. And is [Laravel Framework](https://laravel.com) friendly. + +### Version Supports +| Version | PHP | Laravel | Google Places API | +|----------|--------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ^3.0 | ^8.1 | ^10\|^11 | [Place API](https://developers.google.com/places/web-service/search) \| [Place API (New)](https://developers.google.com/maps/documentation/places/web-service/op-overview) | +| [^2.2]((https://github.com/SachinAgarwal1337/google-places-api/tree/2.2.0)) | ^8.0.2 | ^9\|^10\|^11 | [Place API](https://developers.google.com/places/web-service/search) | + + +## Note + +V3 is a complete re-write from scratch using [Saloon](https://docs.saloon.dev/) and has major breaking changes. Please refer to the [Upgrade Guide]() for more information.
+But is also backward compatibility with [^2.2]((https://github.com/SachinAgarwal1337/google-places-api/tree/2.2.0))
+Backward compatibility will be removed in the next major release. -## About Package -With just 2 lines of code you can request to any google places api feature. No need to manually perform any curl requests. ### The following place requests are available: * [Place Search](#place-search) This service gives a list of places based on a user's location or search string. @@ -33,65 +44,28 @@ composer require skagarwal/google-places-api **Laravel user can see the [Laravel Usage](#laravel-usage) section** -## Step 1 - Import the class using namespace ```php -use SKAgarwal\GoogleApi\PlacesApi; -``` +use SKAgarwal\GoogleApi\PlacesNew\GooglePlaces; -## Step 2 - Initiate the object -```php -$googlePlaces = new PlacesApi('API KEY'); -``` -**Note:** You can also set the **API KEY** after initiating the class using `setKey('KEY')` method. You can chain this with method with any other methods. +public function foo() { + $response = GooglePlaces::make(key: 'API KEY', verifySSL: false, throwOnError: false)->autocomplete('some input'); + + $data = $response->array(); +} -## Step 3 - Start Using the Api. -Example: -```php -$response = $googlePlaces->placeAutocomplete('some Place'); ``` -As mentioned earlier just 2 lines of code to make any request. - -**Full example:** -```php -use SKAgarwal\GoogleApi\PlacesApi; +**Note:** You can also set the **API KEY** after initiating the class using `GooglePlaces::make()->setKey('KEY')` method. -function () { - $googlePlaces = new PlacesApi('API_KEY') # line 1 - $response = $googlePlaces->placeAutocomplete('some input'); # line 2 -} - -``` - --- # Use with Laravel -## For Laravel 5.5 -Auto Discovery added. - -## For Laravel 5.4 and below -## Step 1 -Set up the service provider and facade in the **config\app.php** -```php -'providers' => [ -.... -.... -SKAgarwal\GoogleApi\ServiceProvider::class, -]; -'aliases' => [ -.... -.... -'GooglePlaces' => SKAgarwal\GoogleApi\Facade::class, -]; - -``` - -## Step 2 +## Step 1 publish the config file with following artisan command ``` php artisan vendor:publish --provider="SKAgarwal\GoogleApi\ServiceProvider" @@ -101,38 +75,44 @@ This will create **google.php** file in the config directory. Set the *API KEY* in this config file. -## Set 3 -Start using the package using Facade. +## Set 2 +Start making requests + +```php +use SKAgarwal\GoogleApi\PlacesNew\GooglePlaces; + + +public function foo() { + $response = GooglePlaces::make()->autocomplete('some input'); + + $data = $response->collect(); +} -``` -$response = GooglePlaces::placeAutocomplete('some city'); ``` --- # Response -The response returned is a [Laravel's Collection](https://laravel.com/docs/5.2/collections) so that you can perform any of the available collection methods on it. - -
-If you are not familiar with Laravel's Collection you can either reference the docs here or you can use response as simple array. -
+The response returned is a [Saloon's Response](https://docs.saloon.dev/the-basics/responses#useful-methods). You can refer to the documentation for more information. --- -# Available Methods +# Available Requests + +## Places API ## Place Search -### nearbySearch($location, $radius = null, $params = []) +### nearbySearch(string \$location, ?string \$radius = null, array $params = []) * `location` — The latitude/longitude around which to retrieve place information. This must be specified as latitude, longitude. -* 'radius' — Defines the distance (in meters) within which to return place results. The maximum allowed radius is 50 000 meters. Note that `radius` must not be included if `rankby=distance` (described under **Optional parameters** below) is specified. +* `radius` — Defines the distance (in meters) within which to return place results. The maximum allowed radius is 50 000 meters. Note that `radius` must not be included if `rankby=distance` (described under **Optional parameters** below) is specified. * If `rankby=distance` (described under **Optional parameters** below) is specified, then one or more of `keyword`, `name`, or `types` is required. * `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/search) -### textSearch($query, $params = []) +### textSearch(string \$query, array \$params = []) * `query` — The text string on which to search, for example: "restaurant". The Google Places service will return candidate matches based on this string and order the results based on their perceived relevance. * `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/search) -### findPlace($input, $inputType, $params = []) +### findPlace(string \$input, string \$inputType, array \$params = []) * `input` — The text input specifying which place to search for (for example, a name, address, or phone number). * `inputType` — The type of input. This can be one of either textquery or phonenumber. Phone numbers must be in international format (prefixed by a plus sign ("+"), followed by the country code, then the phone number itself). * `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/search#FindPlaceRequests) @@ -141,7 +121,7 @@ If you are not familiar with Laravel's Collection you can either refere # Place Details -### placeDetails($placeId, $params = []) +### placeDetails(string \$placeId, array \$params = []) * `placeId` — A textual identifier that uniquely identifies a place, returned from a Place Search. * `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/details) @@ -149,7 +129,7 @@ If you are not familiar with Laravel's Collection you can either refere # Place Autocomplete -### placeAutocomplete($input, $params = []) +### placeAutocomplete(string \$input, array \$params = []) * `input` — The text string on which to search. The Place Autocomplete service will return candidate matches based on this string and order results based on their perceived relevance. * `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/autocomplete) @@ -157,7 +137,7 @@ If you are not familiar with Laravel's Collection you can either refere # Query Autocomplete -### queryAutocomplete($input, $params = []) +### queryAutocomplete(string \$input, array \$params = []) * `input` — The text string on which to search. The Places service will return candidate matches based on this string and order results based on their perceived relevance. * `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/query) @@ -165,59 +145,39 @@ If you are not familiar with Laravel's Collection you can either refere # Place Photo -### photo($photoReference, $params = []) +### photo(string $photoReference, array $params = []): ?string * `params` - The set of key-value parameters necessary to add a place to Google. You can refer to the fields on [Google's Official Webpage regarding Place Add](https://developers.google.com/places/web-service/photos) +* Returns the URL of the photo. --- # Custom Headers -### withHeaders(array $headers) -Call This method before any other methods to set the headers. You can chain this method. +### GooglePlaces::make()->headers()->add(string \$key, mixed \$value) +Call This method before making any request to set custom headers. -### new PlacesApi($key = null, $verifySSL = true, array $headers = []) -To have custom headers set for every call, you can pass 3rd parameter as the headers to class constructor. - -**Note:** For Laravel Users, you can set this in config file with key `headers` +### Default Headers (Laravel only) +To have custom headers set for every call, you can set `headers` in the config file --- # Additional Methods -### getStatus() -This will return the status of the response send by google api. Use it after making any request. - -### getKey() -This will return the `API KEY` been used with the requests. - -### setKey($key) +### setKey(string \$key) This will set the `API KEY`. -### verifySSL($verifySSL = true) +### verifySSL(bool \$verifySSL = true) You can pass `false` to disable Verification of SSL Certification. **Note:** For Laravel Users, you can set this in config file with key `verify_ssl` -Or You can Pass the path to the certificate. - - -# Exceptions -Google Places API may throw various exceptions based on the given `$params` or response and is located in the `SKAgarwal\GoogleApi\Exceptions` namespace. - -- A `GooglePlacesApiException` is thrown when no `API KEY` is provided or `$params` is invalid. -**Note:** This is the parent class for the preceding exceptions. -- A `InvalidRequestException` is thrown when the response `status` is `INVALID_REQUEST` -- A `OverQueryLimitException` is thrown when the response `status` is `OVER_QUERY_LIMIT` -- A `RequestDeniedException` is thrown when the response `status` is `REQUEST_DENIED` -- A `UnknownErrorException` is thrown when the response `status` is `UNKNOWN_ERROR` -- A `NotImplementedException` is thrown when the response cannot be determined. - -If any of these exception has been thrown, you can use the `getErrorMessage()` method to get the `error_message` field from the response if any is provided. -**Note:** `error_message` field is not guaranteed to be always present, and its content is subject to change. +### throwOnErrors(bool \$throwOnError) +By default, when request to Google places API fails, no exception is thrown. You can check the request status by calling `$response->status()` +You can change this behaviour by setting `throwOnError` to `true`. This will throw an exception if the request fails. # Contribution -Feel free to report issues or make Pull Requests. -If you find this document can be improved in any way, please feel free to open an issue for it. +Feel free to report issues or make Pull Requests to develop branch. +If you find this document can be improved in any way, please feel free to open an issue/PR for it. # License diff --git a/config/google.php b/config/google.php index 1edef15..c1ab1ad 100644 --- a/config/google.php +++ b/config/google.php @@ -12,6 +12,11 @@ 'verify_ssl' => true, ], + /** + * Default headers to be sent with each request + */ + 'headers' => [], + /** * Throw exceptions when Google API returns an error * diff --git a/src/Connector.php b/src/Connector.php index b137fcc..7f6c366 100644 --- a/src/Connector.php +++ b/src/Connector.php @@ -121,4 +121,16 @@ protected function defaultAuth(): ?Authenticator { return new HeaderAuthenticator($this->key, 'X-Goog-Api-Key'); } + + /** + * @return array|mixed[] + */ + protected function defaultHeaders(): array + { + if (function_exists('config')) { + return config('google.headers', []); + } + + return []; + } } From c07c2d5156c1a0f3754fcf26adb580809dac8af4 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sat, 30 Nov 2024 11:01:26 +0530 Subject: [PATCH 09/14] feat: Documentation --- README.md | 211 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 125 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index 7b56c8b..5f7febf 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,30 @@ - -[![Latest Stable Version](https://poser.pugx.org/skagarwal/google-places-api/v/stable?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) -[![Latest Unstable Version](https://poser.pugx.org/skagarwal/google-places-api/v/unstable?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) -[![Total Downloads](https://poser.pugx.org/skagarwal/google-places-api/downloads?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) +[![Latest Stable Version](https://poser.pugx.org/skagarwal/google-places-api/v/stable?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) +[![Total Downloads](https://poser.pugx.org/skagarwal/google-places-api/downloads?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) [![License](https://poser.pugx.org/skagarwal/google-places-api/license?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) +# Google Places API for PHP -# Google Places API. - -This is a PHP wrapper for **Google Places API Web Service**. And is [Laravel Framework](https://laravel.com) friendly. - -### Version Supports -| Version | PHP | Laravel | Google Places API | -|----------|--------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| ^3.0 | ^8.1 | ^10\|^11 | [Place API](https://developers.google.com/places/web-service/search) \| [Place API (New)](https://developers.google.com/maps/documentation/places/web-service/op-overview) | -| [^2.2]((https://github.com/SachinAgarwal1337/google-places-api/tree/2.2.0)) | ^8.0.2 | ^9\|^10\|^11 | [Place API](https://developers.google.com/places/web-service/search) | +A PHP wrapper for **Google Places API Web Service**, compatible with [Laravel](https://laravel.com). +## Version Compatibility -## Note +| Package Version | PHP | Laravel | Google Places API | +|:---------------:|:------:|:----------------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ^3.0 | ^8.1 | ^10 \| ^11 | [Places API](https://developers.google.com/places/web-service/search) and [Places API (New)](https://developers.google.com/maps/documentation/places/web-service/op-overview) | +| ^2.2 | ^8.0.2 | ^9 \| ^10 \| ^11 | [Places API](https://developers.google.com/places/web-service/search) | -V3 is a complete re-write from scratch using [Saloon](https://docs.saloon.dev/) and has major breaking changes. Please refer to the [Upgrade Guide]() for more information.
-But is also backward compatibility with [^2.2]((https://github.com/SachinAgarwal1337/google-places-api/tree/2.2.0))
-Backward compatibility will be removed in the next major release. +> **Note**: +> Version 3 is a complete rewrite using [Saloon](https://docs.saloon.dev/) with breaking changes. v2.2 API is deprecated and will be removed in next major version. Which means it is backward compatible. But it is recommended to shift to v3 API before next major release. -### The following place requests are available: -* [Place Search](#place-search) This service gives a list of places based on a user's location or search string. -* [Place Details](#place-details) This service gives more detailed information about a specific Place, including user reviews. -* [Place Autocomplete](#place-autocomplete) This service is Used to automatically fill in the name and/or address of a place as you type. -* [Query Autocomplete](#query-autocomplete) This service is Used to provide a query prediction service for text-based geographic searches, by returning suggested queries as you type. -* [Place Photo](#place-photo) This gives you access to the millions of photos stored in the Google's Places database -* [Custom Headers](#custom-headers) Set Custom Headers. -* [Additional Methods](#additional-methods) Additional Methods Available. - -# Installation +## Installation Install it with composer ``` composer require skagarwal/google-places-api ``` - -# Usage +## General Usage **Laravel user can see the [Laravel Usage](#laravel-usage) section** @@ -56,16 +40,16 @@ public function foo() { ``` -**Note:** You can also set the **API KEY** after initiating the class using `GooglePlaces::make()->setKey('KEY')` method. +>You can also set the **API KEY** after initiating the class using `GooglePlaces::make()->setKey('KEY')` method. --- - -# Use with Laravel + +## Laravel -## Step 1 +### Step 1 publish the config file with following artisan command ``` php artisan vendor:publish --provider="SKAgarwal\GoogleApi\ServiceProvider" @@ -75,7 +59,7 @@ This will create **google.php** file in the config directory. Set the *API KEY* in this config file. -## Set 2 +### Step 2 Start making requests ```php @@ -92,93 +76,148 @@ public function foo() { --- # Response -The response returned is a [Saloon's Response](https://docs.saloon.dev/the-basics/responses#useful-methods). You can refer to the documentation for more information. + +The response returned is a [Saloon's Response](https://docs.saloon.dev/the-basics/responses#useful-methods) thus you can use all the methods provided by Saloon. + +```php +$response->array(); // returns the response as array +$response->collect(); // returns the response as collection +$response->json(); // returns the response as json +$response->status(); // returns the status of the response +$response->headers(); // returns the headers of the response +$response->body(); // returns the body of the response +$response->throw(); // throws an exception if the response is not successful +``` + +You can refer to Saloon's documentation for more methods. + +> **Note**: +> By default, no exception is thrown for API errors. You can check the request status with `$response->status()`. +> You can also use `GooglePlaces::make()->findPlace()->throw()` to throw an exception if the request fails. --- -# Available Requests +# API Reference + +This library supports both the **[Places API (original)](#places-original)** and the **[Places API (New)](#places-new)**. + ## Places API +This section covers methods available for original Places API. +Use `SKAgarwal\GoogleApi\Places\GooglePlaces::make()` to create an instance of the Places API. +Eg: `GooglePlaces::make()->nearbySearch('40.748817,-73.985428');` - -## Place Search -### nearbySearch(string \$location, ?string \$radius = null, array $params = []) -* `location` — The latitude/longitude around which to retrieve place information. This must be specified as latitude, longitude. -* `radius` — Defines the distance (in meters) within which to return place results. The maximum allowed radius is 50 000 meters. Note that `radius` must not be included if `rankby=distance` (described under **Optional parameters** below) is specified. -* If `rankby=distance` (described under **Optional parameters** below) is specified, then one or more of `keyword`, `name`, or `types` is required. -* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/search) +### Place Search -### textSearch(string \$query, array \$params = []) -* `query` — The text string on which to search, for example: "restaurant". The Google Places service will return candidate matches based on this string and order the results based on their perceived relevance. -* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/search) +#### `findPlace(string $input, string $inputType, array $params = [])` +- **$input**: Text to search (e.g., name, address). +- **$inputType**: `textquery` or `phonenumber`. +- **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/search-find-place). -### findPlace(string \$input, string \$inputType, array \$params = []) -* `input` — The text input specifying which place to search for (for example, a name, address, or phone number). -* `inputType` — The type of input. This can be one of either textquery or phonenumber. Phone numbers must be in international format (prefixed by a plus sign ("+"), followed by the country code, then the phone number itself). -* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/search#FindPlaceRequests) +#### `nearbySearch(string $location, ?string $radius = null, array $params = [])` +- **$location**: Latitude,Longitude coordinates. Order - (lat,lng) (e.g., `40.748817,-73.985428`). +- **$radius**: Distance in meters (max 50,000). Required unless using `rankby=distance`. +- **$params**: Optional parameters (e.g., `keyword`, `type`). [More info](https://developers.google.com/maps/documentation/places/web-service/search-nearby). + +#### `textSearch(string $query, array $params = [])` +- **$query**: Search string (e.g., `"restaurant"`). +- **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/search-text). + +--- + +### Place Details + +#### `placeDetails(string $placeId, array $params = [])` +- **$placeId**: Unique identifier for a place. +- **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/details). --- - -# Place Details -### placeDetails(string \$placeId, array \$params = []) -* `placeId` — A textual identifier that uniquely identifies a place, returned from a Place Search. -* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/details) +### Place Autocomplete +#### `placeAutocomplete(string $input, array $params = [])` +- **$input**: Text to search (e.g., name, address). +- **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/autocomplete). --- - -# Place Autocomplete -### placeAutocomplete(string \$input, array \$params = []) -* `input` — The text string on which to search. The Place Autocomplete service will return candidate matches based on this string and order results based on their perceived relevance. -* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/autocomplete) +### Query Autocomplete +#### `queryAutocomplete(string $input, array $params = [])` +- **$input**: Text to search (e.g., name, address). +- **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/query). --- - -# Query Autocomplete -### queryAutocomplete(string \$input, array \$params = []) -* `input` — The text string on which to search. The Places service will return candidate matches based on this string and order results based on their perceived relevance. -* `params` - **Optional Parameters** You can refer all the available optional parameters on the [Google's Official Webpage](https://developers.google.com/places/web-service/query) +### Place Photo +#### `photo(string $photoReference, array $params = [])` +- **$photoReference**: Reference to a photo. [More info](https://developers.google.com/maps/documentation/places/web-service/photos#photo_references) +- **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/photos). --- + +## Places API (New) - -# Place Photo -### photo(string $photoReference, array $params = []): ?string -* `params` - The set of key-value parameters necessary to add a place to Google. You can refer to the fields on [Google's Official Webpage regarding Place Add](https://developers.google.com/places/web-service/photos) -* Returns the URL of the photo. +This section covers methods available for Places API (New). +Use `SKAgarwal\GoogleApi\PlacesNew\GooglePlaces::make()` to create an instance of the Places API. +Eg: `GooglePlaces::make()->nearbySearch(40.748817, -73.985428, 500.0);` --- # Custom Headers -### GooglePlaces::make()->headers()->add(string \$key, mixed \$value) -Call This method before making any request to set custom headers. +#### Set Custom Headers +```php +GooglePlaces::make()->headers()->add('Header-Key', 'Header-Value'); +``` -### Default Headers (Laravel only) -To have custom headers set for every call, you can set `headers` in the config file +#### `autocomplete(string $input, array $fields = ['*'], bool $includeQueryPredictions = false, array $params = [])` +- **$input**: Text to search (e.g., name, address). +- **$fields**: Fields to return. Default is all fields. [More info](https://developers.google.com/maps/documentation/places/web-service/choose-fields). +- **$includeQueryPredictions**: If `true`, the response includes both place and query predictions. The default value is **false**, meaning the response only includes place predictions. +- **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/place-autocomplete). + +#### `nearbySearch(float $latitude, float $longitude, float $radius = 0.0, array $fields = ['*'], array $params = [])` +- **$latitude**: Latitude of the location. +- **$longitude**: Longitude of the location. +- **$radius**: The radius must be between **0.0** and **50000.0**, inclusive. The default radius is 0.0. You must set it in your request to a value greater than 0.0. +- **$fields**: Fields to return. Default is all fields. [More info](https://developers.google.com/maps/documentation/places/web-service/choose-fields). +- **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/nearby-search). + +#### `placeDetails(string $placeId, array $fields = ['*'], array $params = [])` +- **$placeId**: Unique identifier for a place. +- **$fields**: Fields to return. Default is all fields. [More info](https://developers.google.com/maps/documentation/places/web-service/choose-fields). +- **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/place-details). + +#### `textSearch(string $textQuery, array $fields = ['*'], array $params = [])` +- **$textQuery**: Search string (e.g., `"restaurant"`). +- **$fields**: Fields to return. Default is all fields. [More info](https://developers.google.com/maps/documentation/places/web-service/choose-fields). +- **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/text-search). + +#### `placePhoto(string $name, int $maxHeightPx = null, int $maxWidthPx = null)` +- **$name**: A string identifier that uniquely identifies a photo. [More Info](https://developers.google.com/maps/documentation/places/web-service/place-photos#photo-name) +- **$maxHeightPx**: The maximum desired height of the image in pixels. (Should be between 1 and 4800) +- **$maxWidthPx**: The maximum desired width of the image in pixels. (Should be between 1 and 4800) +> [skipHttpRedirect](https://developers.google.com/maps/documentation/places/web-service/place-photos#skiphttpredirect) is set to false internally to get JSON response. This cannot be changed --- # Additional Methods -### setKey(string \$key) -This will set the `API KEY`. - -### verifySSL(bool \$verifySSL = true) -You can pass `false` to disable Verification of SSL Certification. -**Note:** For Laravel Users, you can set this in config file with key `verify_ssl` +- **`setKey(string $key)`**: Set the API key. +- **`getKey(string $key)`**: Get the API key being used. +- **`verifySSL(bool $verifySSL = true)`**: Enable/disable SSL verification. +- **`throwOnErrors(bool $throwOnError)`**: + - By default, no exception is thrown for API errors. You can check the request status with `$response->status()`. + - When `throwOnError` is set to `true`, the library will throw exceptions on API failures. -### throwOnErrors(bool \$throwOnError) -By default, when request to Google places API fails, no exception is thrown. You can check the request status by calling `$response->status()` -You can change this behaviour by setting `throwOnError` to `true`. This will throw an exception if the request fails. +--- # Contribution -Feel free to report issues or make Pull Requests to develop branch. -If you find this document can be improved in any way, please feel free to open an issue/PR for it. +- Report issues or contribute to the `develop` branch. +- Open issues/PRs to improve this documentation. + +--- # License +This package is licensed under the [MIT License](http://opensource.org/licenses/MIT). -The Google Places Api is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) From 5e8e22393c363f5926154fe79f0c85c5f20ac475 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sat, 30 Nov 2024 11:05:02 +0530 Subject: [PATCH 10/14] feat: Documentation badges in same line --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5f7febf..fc5bca7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![Latest Stable Version](https://poser.pugx.org/skagarwal/google-places-api/v/stable?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) -[![Total Downloads](https://poser.pugx.org/skagarwal/google-places-api/downloads?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) +[![Latest Stable Version](https://poser.pugx.org/skagarwal/google-places-api/v/stable?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) +[![Total Downloads](https://poser.pugx.org/skagarwal/google-places-api/downloads?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) [![License](https://poser.pugx.org/skagarwal/google-places-api/license?format=flat-square)](https://packagist.org/packages/skagarwal/google-places-api) # Google Places API for PHP From f9aa4d0234be86a5b0d6133251819e627b7e7e6d Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sat, 30 Nov 2024 11:16:39 +0530 Subject: [PATCH 11/14] feat: Documentation changes --- README.md | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index fc5bca7..9cc5258 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,9 @@ A PHP wrapper for **Google Places API Web Service**, compatible with [Laravel](h | ^3.0 | ^8.1 | ^10 \| ^11 | [Places API](https://developers.google.com/places/web-service/search) and [Places API (New)](https://developers.google.com/maps/documentation/places/web-service/op-overview) | | ^2.2 | ^8.0.2 | ^9 \| ^10 \| ^11 | [Places API](https://developers.google.com/places/web-service/search) | -> **Note**: +> [!CAUTION] > Version 3 is a complete rewrite using [Saloon](https://docs.saloon.dev/) with breaking changes. v2.2 API is deprecated and will be removed in next major version. Which means it is backward compatible. But it is recommended to shift to v3 API before next major release. +> You can refer to v2.2 documentation [here](README-Legacy.md). ## Installation @@ -55,9 +56,9 @@ publish the config file with following artisan command php artisan vendor:publish --provider="SKAgarwal\GoogleApi\ServiceProvider" ``` -This will create **google.php** file in the config directory. +This will create **[google.php](config/google.php)** file in the config directory. -Set the *API KEY* in this config file. +Set the **_API_ KEY** in this config file. ### Step 2 Start making requests @@ -91,7 +92,7 @@ $response->throw(); // throws an exception if the response is not successful You can refer to Saloon's documentation for more methods. -> **Note**: +> [!IMPORTANT] > By default, no exception is thrown for API errors. You can check the request status with `$response->status()`. > You can also use `GooglePlaces::make()->findPlace()->throw()` to throw an exception if the request fails. @@ -103,7 +104,18 @@ This library supports both the **[Places API (original)](#places-original)** and ## Places API -This section covers methods available for original Places API. +This section covers methods available for original Places API. +```php +use SKAgarwal\GoogleApi\Places\GooglePlaces; // Original Places API class + +public function foo() { + $response = GooglePlaces::make()->nearbySearch('40.748817,-73.985428'); + + $data = $response->array(); +} + +``` + Use `SKAgarwal\GoogleApi\Places\GooglePlaces::make()` to create an instance of the Places API. Eg: `GooglePlaces::make()->nearbySearch('40.748817,-73.985428');` @@ -157,17 +169,18 @@ Eg: `GooglePlaces::make()->nearbySearch('40.748817,-73.985428');` ## Places API (New) This section covers methods available for Places API (New). -Use `SKAgarwal\GoogleApi\PlacesNew\GooglePlaces::make()` to create an instance of the Places API. -Eg: `GooglePlaces::make()->nearbySearch(40.748817, -73.985428, 500.0);` - ---- - -# Custom Headers -#### Set Custom Headers ```php -GooglePlaces::make()->headers()->add('Header-Key', 'Header-Value'); +use SKAgarwal\GoogleApi\PlacesNew\GooglePlaces; // New Places API class + +public function foo() { + $response = GooglePlaces::make()->nearbySearch(40.748817, -73.985428, 500.0); + + $data = $response->array(); +} + ``` +--- #### `autocomplete(string $input, array $fields = ['*'], bool $includeQueryPredictions = false, array $params = [])` - **$input**: Text to search (e.g., name, address). @@ -200,6 +213,15 @@ GooglePlaces::make()->headers()->add('Header-Key', 'Header-Value'); --- + +# Custom Headers +#### Set Custom Headers +```php +GooglePlaces::make()->headers()->add('Header-Key', 'Header-Value'); +``` + +--- + # Additional Methods From 77ea6bad7725831dae95ecf96d60bf2a41e93df2 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sat, 30 Nov 2024 11:19:58 +0530 Subject: [PATCH 12/14] feat: Documentation changes --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9cc5258..5a7297c 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,9 @@ A PHP wrapper for **Google Places API Web Service**, compatible with [Laravel](h | ^2.2 | ^8.0.2 | ^9 \| ^10 \| ^11 | [Places API](https://developers.google.com/places/web-service/search) | > [!CAUTION] -> Version 3 is a complete rewrite using [Saloon](https://docs.saloon.dev/) with breaking changes. v2.2 API is deprecated and will be removed in next major version. Which means it is backward compatible. But it is recommended to shift to v3 API before next major release. +> Version 3 is a complete rewrite using [Saloon](https://docs.saloon.dev/) with breaking changes. +> v2.2 API is deprecated and will be removed in next major version. Which means it is backward compatible. +> And it is recommended to shift to v3 API before next major release. > You can refer to v2.2 documentation [here](README-Legacy.md). @@ -113,12 +115,8 @@ public function foo() { $data = $response->array(); } - ``` -Use `SKAgarwal\GoogleApi\Places\GooglePlaces::make()` to create an instance of the Places API. -Eg: `GooglePlaces::make()->nearbySearch('40.748817,-73.985428');` - ### Place Search #### `findPlace(string $input, string $inputType, array $params = [])` @@ -178,7 +176,6 @@ public function foo() { $data = $response->array(); } - ``` --- From b6d9570117e7719677faf4e35867bcee02e85ab1 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sat, 30 Nov 2024 11:27:19 +0530 Subject: [PATCH 13/14] feat: Make $fields optional in new Autocomplete.php API --- README.md | 4 ++-- src/PlacesNew/GooglePlaces.php | 6 +++--- src/PlacesNew/Requests/Autocomplete.php | 8 ++++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 5a7297c..d6639d1 100644 --- a/README.md +++ b/README.md @@ -179,9 +179,9 @@ public function foo() { ``` --- -#### `autocomplete(string $input, array $fields = ['*'], bool $includeQueryPredictions = false, array $params = [])` +#### `autocomplete(string $input, bool $includeQueryPredictions = false, ?array $fields = null, array $params = [])` - **$input**: Text to search (e.g., name, address). -- **$fields**: Fields to return. Default is all fields. [More info](https://developers.google.com/maps/documentation/places/web-service/choose-fields). +- **$fields**: Fields to return. [More info](https://developers.google.com/maps/documentation/places/web-service/choose-fields). - **$includeQueryPredictions**: If `true`, the response includes both place and query predictions. The default value is **false**, meaning the response only includes place predictions. - **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/place-autocomplete). diff --git a/src/PlacesNew/GooglePlaces.php b/src/PlacesNew/GooglePlaces.php index a81efe9..868b5a3 100644 --- a/src/PlacesNew/GooglePlaces.php +++ b/src/PlacesNew/GooglePlaces.php @@ -22,8 +22,8 @@ public function resolveBaseUrl(): string /** * @param string $input - * @param array $fields * @param bool $includeQueryPredictions + * @param array|null $fields * @param array $params * * @throws \Saloon\Exceptions\Request\FatalRequestException @@ -32,11 +32,11 @@ public function resolveBaseUrl(): string */ public function autocomplete( string $input, - array $fields = ['*'], bool $includeQueryPredictions = false, + ?array $fields = null, array $params = [], ): Response { - return $this->send(new Autocomplete($input, $fields, $includeQueryPredictions, $params)); + return $this->send(new Autocomplete($input, $includeQueryPredictions, $fields, $params)); } /** diff --git a/src/PlacesNew/Requests/Autocomplete.php b/src/PlacesNew/Requests/Autocomplete.php index 0847f54..b256cfe 100644 --- a/src/PlacesNew/Requests/Autocomplete.php +++ b/src/PlacesNew/Requests/Autocomplete.php @@ -22,14 +22,14 @@ class Autocomplete extends Request implements HasBody /** * @param string $input - * @param array $fields + * @param array|null $fields * @param bool $includeQueryPredictions * @param array $params */ public function __construct( private readonly string $input, - private readonly array $fields = ['*'], private readonly bool $includeQueryPredictions = false, + private readonly ?array $fields = null, private readonly array $params = [], ) {} @@ -46,6 +46,10 @@ public function resolveEndpoint(): string */ protected function defaultQuery(): array { + if (is_null($this->fields)) { + return []; + } + return [ 'fields' => implode(',', $this->fields), ]; From 26d3d050c2c33945a9f7aed836eadd2cb82b0b19 Mon Sep 17 00:00:00 2001 From: Sachin Agarwal Date: Sat, 30 Nov 2024 11:29:31 +0530 Subject: [PATCH 14/14] feat: Documentation Changes --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index d6639d1..aa3141d 100644 --- a/README.md +++ b/README.md @@ -179,12 +179,14 @@ public function foo() { ``` --- +### Autocomplete #### `autocomplete(string $input, bool $includeQueryPredictions = false, ?array $fields = null, array $params = [])` - **$input**: Text to search (e.g., name, address). - **$fields**: Fields to return. [More info](https://developers.google.com/maps/documentation/places/web-service/choose-fields). - **$includeQueryPredictions**: If `true`, the response includes both place and query predictions. The default value is **false**, meaning the response only includes place predictions. - **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/place-autocomplete). +### Nearby Search #### `nearbySearch(float $latitude, float $longitude, float $radius = 0.0, array $fields = ['*'], array $params = [])` - **$latitude**: Latitude of the location. - **$longitude**: Longitude of the location. @@ -192,16 +194,19 @@ public function foo() { - **$fields**: Fields to return. Default is all fields. [More info](https://developers.google.com/maps/documentation/places/web-service/choose-fields). - **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/nearby-search). +### Place Details #### `placeDetails(string $placeId, array $fields = ['*'], array $params = [])` - **$placeId**: Unique identifier for a place. - **$fields**: Fields to return. Default is all fields. [More info](https://developers.google.com/maps/documentation/places/web-service/choose-fields). - **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/place-details). +### Text Search #### `textSearch(string $textQuery, array $fields = ['*'], array $params = [])` - **$textQuery**: Search string (e.g., `"restaurant"`). - **$fields**: Fields to return. Default is all fields. [More info](https://developers.google.com/maps/documentation/places/web-service/choose-fields). - **$params**: Optional parameters. [More info](https://developers.google.com/maps/documentation/places/web-service/text-search). +### Place Photo #### `placePhoto(string $name, int $maxHeightPx = null, int $maxWidthPx = null)` - **$name**: A string identifier that uniquely identifies a photo. [More Info](https://developers.google.com/maps/documentation/places/web-service/place-photos#photo-name) - **$maxHeightPx**: The maximum desired height of the image in pixels. (Should be between 1 and 4800)