From a61e15e2b6d8b994f498eafe942e447e0b061d2c Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 11:54:29 +0200 Subject: [PATCH 01/29] Removed deprecated builder methods --- src/ClientBase.php | 74 +++++++---------------------- src/Extras/GuzzleRequestFactory.php | 29 ----------- 2 files changed, 18 insertions(+), 85 deletions(-) delete mode 100644 src/Extras/GuzzleRequestFactory.php diff --git a/src/ClientBase.php b/src/ClientBase.php index a4ebecc..d9a1ede 100644 --- a/src/ClientBase.php +++ b/src/ClientBase.php @@ -16,15 +16,14 @@ use OlzaLogistic\PpApi\Client\Exception\AccessDeniedException; use OlzaLogistic\PpApi\Client\Exception\MethodFailedException; use OlzaLogistic\PpApi\Client\Exception\ObjectNotFoundException; -use OlzaLogistic\PpApi\Client\Extras\GuzzleRequestFactory; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\RequestInterface; -abstract class ClientBase implements ClientContract +abstract class ClientBase implements ClientContract { /** - * Configures client to use specific API URL + * Configures the client to engage with a Pickup Point API at the provided URL. * * @param string $apiUrl Valid API URL, i.e. 'https://api.olzalogistic.com/v1' */ @@ -34,7 +33,8 @@ public static function useApi(string $apiUrl): self } /** - * Configures client to use specific access token while talking to Pickup Points API. + * Configures the client to utilize a specific access token when interacting with the Pickup + * Points API. * * @param string $accessToken Your private access token. */ @@ -49,7 +49,7 @@ public function withAccessToken(string $accessToken): self } /** - * Sets User Agent string to be used with all the API requests. + * Specifies the User-Agent string for all HTTP API requests. * * @param string $userAgent User agent string. */ @@ -60,75 +60,36 @@ public function withUserAgent(string $userAgent): self } /** - * Configures Client instance to use Guzzle HTTP client. + * Configures a PSR-18 compatible instance of an HTTP client implementation. * - * NOTE: Requires Guzzle package to be installed. + * @param ClientInterface $httpClient Instance of PSR-18 compatible HTTP client. */ - public function withGuzzleHttpClient(): self + public function withHttpClient(ClientInterface $httpClient): self { $this->assertClientNotConfigured(); - // NOTE: do NOT move Guzzle reference out of this method! This code is OPTIONAL and - // if you "optimize" by i.e. adding "use" instead, then instantiation of this - // class will be Guzzle dependent and will simply fail if there's no Guzzle dependency. - /** @noinspection ClassConstantCanBeUsedInspection */ - $httpClientClass = '\GuzzleHttp\Client'; - - if (!\class_exists($httpClientClass)) { - throw new \RuntimeException('Guzzle HTTP client not found. See library docs for assistance.'); - } - - $this->setHttpClient(new $httpClientClass()); - $this->setRequestFactory(new GuzzleRequestFactory()); + $this->setHttpClient($httpClient); return $this; } - /** - * Configures Client instance to use Symfony's PSR18 HTTP client. - * - * NOTE: Requires Symfony HTTP client and support packages to be installed. - */ - public function withSymfonyHttpClient(): self - { - $this->assertClientNotConfigured(); - - // NOTE: do NOT move Symfony reference out of this method! This code is OPTIONAL and - // if you "optimize" by i.e. adding "use" instead, then instantiation of this - // class will be Symfony client dependent and will simply fail if there's no Symfony - // HTTP client dependency. - /** @noinspection ClassConstantCanBeUsedInspection */ - $httpClientClass = '\Symfony\Component\HttpClient\Psr18Client'; - - if (!\class_exists($httpClientClass)) { - throw new \RuntimeException('Symfony HTTP client not found. See library docs for assistance.'); - } - - $client = new $httpClientClass(); - $this->setHttpClient($client); - $this->setRequestFactory($client); - return $this; - } /** - * Configures Client instance to use generic PSR-17 compatible HTTP client. + * Configures a PSR-17 compatible request factory instance to work with the HTTP client. * - * @param ClientInterface $httpClient Instance of PSR-17 compatible HTTP client. * @param RequestFactoryInterface $requestFactory Instance of PSR-17 compatible request factory. */ - public function withPsrClient(ClientInterface $httpClient, - RequestFactoryInterface $requestFactory): self + public function withRequestFactory(requestFactoryInterface $requestFactory): self { $this->assertClientNotConfigured(); - $this->setHttpClient($httpClient); $this->setRequestFactory($requestFactory); return $this; } /** - * Configures client to throw exception when any API connection failure happened. - * Useful for "exception driven" code approach. + * Configures the client to throw an exception in case of any API connection failure. + * Beneficial for an "exception-driven" coding approach. */ public function throwOnError(): self { @@ -153,8 +114,8 @@ public function build(): self protected bool $isClientInitialized = false; /** - * Closes ability to further configure the client. Once seal() is called no further - * changes to the client are allowed. + * Disallows further configuration of the client. Once seal() is invoked, no subsequent changes + * to the client are permitted. */ protected function seal(): void { @@ -162,7 +123,7 @@ protected function seal(): void } /** - * Ensures Client is correctly configured. Will throw exception if not. + * Verifies the client's configuration is correct. An exception will be thrown if it's not. */ protected function assertConfigurationSealed(): void { @@ -172,7 +133,8 @@ protected function assertConfigurationSealed(): void } /** - * Ensures client is not yet configured and all configuration methods can safely be executed. + * Ensures the client has not been configured yet, allowing all configuration methods to be + * executed safely. */ protected function assertClientNotConfigured(): void { diff --git a/src/Extras/GuzzleRequestFactory.php b/src/Extras/GuzzleRequestFactory.php deleted file mode 100644 index 0f00130..0000000 --- a/src/Extras/GuzzleRequestFactory.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @copyright 2021-2023 DevelArt - * @license http://www.opensource.org/licenses/mit-license.php MIT - * @link https://github.com/develart-projects/pickup-points-api-client/ - */ - -namespace OlzaLogistic\PpApi\Client\Extras; - -use Psr\Http\Message\RequestFactoryInterface; -use Psr\Http\Message\RequestInterface; - -/** - * PSR-17 compatible request factory for Guzzle HTTP client. - * - * NOTE: requires Guzzle to be installed as project dependency - */ -class GuzzleRequestFactory implements RequestFactoryInterface -{ - public function createRequest(string $method, $uri): RequestInterface - { - return new \GuzzleHttp\Psr7\Request($method, $uri); - } -} From bba6d0bf6ec27fbfab60e082ed6d8ae050152242 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 12:26:17 +0200 Subject: [PATCH 02/29] Updated documentation and usage examples --- CHANGES.md | 8 ++ README.md | 35 ++++---- docs/README.md | 18 ++-- docs/api.md | 145 ++++++++++++++++++++++++++++++++ docs/classes.md | 40 +++++++++ docs/client.md | 177 +++++++++------------------------------ docs/examples/README.md | 17 ++++ docs/examples/config.md | 48 +++++++++++ docs/examples/details.md | 51 +++++++++++ docs/examples/find.md | 53 ++++++++++++ docs/examples/nearby.md | 53 ++++++++++++ docs/exceptions.md | 16 +--- docs/installation.md | 23 ++--- docs/params.md | 17 ++-- docs/requirements.md | 45 ++++------ docs/response.md | 20 ++--- examples/config.php | 33 -------- examples/details.php | 36 -------- examples/find.php | 35 -------- examples/nearby.php | 38 --------- 20 files changed, 511 insertions(+), 397 deletions(-) create mode 100644 docs/api.md create mode 100644 docs/classes.md create mode 100644 docs/examples/README.md create mode 100644 docs/examples/config.md create mode 100644 docs/examples/details.md create mode 100644 docs/examples/find.md create mode 100644 docs/examples/nearby.md delete mode 100644 examples/config.php delete mode 100644 examples/details.php delete mode 100644 examples/find.php delete mode 100644 examples/nearby.php diff --git a/CHANGES.md b/CHANGES.md index ebc5157..553c17d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,14 @@ Olza Logistic's Pickup Point API Client PHP library. # Changelog +* v2.0.0-dev (YYYY-MM-DD) + * Added `withHttpClient()` and `withRequestFactory()` methods to `Client` builder. + * Removed `withGuzzleHttpClient()` as Guzzle no longer needs special treatment. + * Removed `withSymfonyHttpClient()`. See docs on how to use Symfony HTTP client. + * Removed `withPsrClient()`. Use `withHttpClient()` and `withRequestClient()` instead. + * Updated library documentation. + + * v1.2.2 (2023-10-06) * Fixed API response code not being included in the thrown exception. * Added dedicated exceptions to reflect API error codes (when `throwOnError` is enabled). diff --git a/README.md b/README.md index 7cbf56a..ac420ea 100644 --- a/README.md +++ b/README.md @@ -2,29 +2,28 @@ # PP API Client for PHP -The PP API Client is a robust library for PHP 7.4 or newer, designed to interact with the Pickup -Points (PP) API service offered by Olza Logistic, facilitating seamless access to a comprehensive -database of parcel delivery pickup points. This library empowers developers to execute precise -queries to fetch information about pickup points across various parameters. With the PP API Client, -one can effortlessly: - -* search for pickup points in a specified country, -* filter pickup points based on the courier service, -* distinguish between different types of pickup points such as lockers or offices, -* locate pickup points in proximity to a defined location, -* retrieve detailed information about individual pickup points. - -Whether integrating a parcel delivery system or enhancing the user experience by providing -convenient pickup options, the PP API Client library is an indispensable tool that offers a -streamlined interface to the PP API service, thereby simplifying the development process and -augmenting the functionality of parcel delivery-related applications. - +The PP API Client is a robust library tailored for PHP 7.4 or newer, designed to interact with the +Pickup Points (PP) API service offered by Olza Logistic. This library facilitates seamless access to +a comprehensive database of parcel delivery pickup points, empowering developers to execute precise +queries to retrieve information about pickup points based on various parameters. With the PP API +Client, one can effortlessly: + +* Search for pickup points in a specified country, +* Filter pickup points based on the courier service, +* Distinguish between different types of pickup points, such as lockers or offices, +* Locate pickup points in proximity to a defined location, +* Retrieve detailed information about individual pickup points. + +Whether you're integrating a parcel delivery system or enhancing the user experience by providing +convenient pickup options, the PP API Client library is an indispensable tool. It offers +a streamlined interface to the PP API service, simplifying the development process and augmenting +the functionality of parcel delivery-related applications. --- ## Documentation * [Requirements](docs/installation.md) -* [Usage examples](examples.md) +* [Usage examples](examples/) * [Library API reference](docs/README.md) --- diff --git a/docs/README.md b/docs/README.md index e0ccab7..4dfd507 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,18 +4,10 @@ # PP API Client for PHP -* **[« Go back](README.md)** +**[« Go back to main README](../README.md)** + * [Library requirements](requirements.md) * [Installation](installation.md) -* Library API reference - * [`Client` class - gateway to the PP API](client.md#gateway-to-the-api) - * [Creating client instance](client.md#instantiation) - * Public API methods - * [`config(Params $params): Result;`](client.md#configparams-params-result) - * [`details(Params $params): Result;`](client.md#detailsparams-params-result) - * [`find(Params $params): Result;`](client.md#findparams-params-result) - * [`search(Params $params): Result;`](client.md#searchparams-params-result) - * [`Params` class - passing method arguments](params.md#passing-method-arguments) - * [`Result` class - accessing response data](response.md#accessing-response-data) - * [`Data` class - accessing response payload](response.md#accessing-response-payload) - * [Exceptions](exceptions.md) +* [Public API methods](api.md) +* [Library classes reference](classes.md) +* [Usage examples](examples/README.md) diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..f1a9cd6 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,145 @@ +![Olza Logistic Logo](olza-logo-small.png) + +--- + +# PP API Client for PHP + +* [Library requirements](requirements.md) +* [Installation](installation.md) +* Public API methods + * [`config(Params $params): Result;`](#configparams-params-result) + * [`details(Params $params): Result;`](#detailsparams-params-result) + * [`find(Params $params): Result;`](#findparams-params-result) + * [`search(Params $params): Result;`](#searchparams-params-result) +* [Library classes reference](classes.md) + +--- + +## Usage + +To simplify the usage of the library, all public methods provided by the library expect arguments to +be passed using the [Params](params.md) class. All response data is also returned, encapsulated +within a unified [Result](response.md) class object. For those who prefer handling exceptions rather +than checking the result, there's a mode that transforms each unsuccessful API response into a +corresponding exception (for more information, see the details +on [Client class instantiation](client.md)). + +--- + +## Public API methods + +The following public methods serve as you gateway to PP API: + +#### `config(Params $params): Result;` + +Returns current vital information about PP API environment. + +![Note](note.png) It's highly recommended to invoke the `config/` method as the very first method +during your PP API communication session. This method is expected to return vital runtime parameters +back to the client, allowing you to act accordingly. For instance, `config/` will return a list of +all currently available carriers (and their IDs), providing foresight on what to expect from other +carrier-dependent methods. + +Required arguments: + +* `country` - **(required)** country code (use Country::xxx consts) + +```php +$params = Params::create() + ->withCountry(Country::CZECH_REPUBLIC); +$result = $client->config($params); +$configItems = $result->getData(); +... +... +``` + +#### `details(Params $params): Result;` + +Return details about specific Pickup Point. + +Required arguments: + +* `country` - **(required)** country code (use `Country::xxx` consts) +* `spedition` - **(required)** one (string) or more (array of strings) +* `id` - **(required)** Pickup point identifier + +```php +$params = Params::create() + ->withCountry(Country::CZECH_REPUBLIC) + ->withSpedition(Spedition::PACKETA_IPP) + ->withSpeditionId('12345'); +$result = $client->details($params); +$items = $result->getData(); +foreach($items as $pp) { + echo $pp->getSpeditionId() . PHP_EOL; +} +... + +... +``` + +#### `find(Params $params): Result;` + +Searches for available pickup points that match the provided parameters. + +Required arguments: + +* `country` - **[required]** country code (use `Country::xxx` consts). +* `spedition` - **[required]** either a single spedition (string) or multiple speditions (array of + strings). + +Optional arguments: + +* `search` - A search string that will be additionally matched against pickup point names, + identifiers, addresses, etc. +* `services` - A list of services (see `ServiceType::*`) that a pickup point must support to be + included in the returned dataset. **NOTE: services are `OR`ed, so supporting just one suffices.** +* `payments` - A list of payment types (see `PaymentType::*`) that a pickup point must support to be + included in the returned dataset. **NOTE: payment types are `OR`ed, so supporting just one + suffices.** +* `limit` - The maximum number of items to be returned. The default is to return all matching items. + +```php +$params = Params::create() + ->withCountry(Country::CZECH_REPUBLIC) + ->withSpedition(Spedition::PACKETA_IPP); +$result = $client->find($params); +$items = $result->getData() ?? []; +foreach($items as $pp) { + echo $pp->getSpeditionId() . PHP_EOL; +} +... +``` + +#### `nearby(Params $params): Result;` + +Searches for pickup points located near a specified geographic location. + +Required arguments: + +* `country` - **[required]** country code (use `Country::xxx` consts). +* `spedition` - **[required]** either a single spedition (string) or multiple speditions (array of + strings). +* `coords` - **[required]** geographic coordinates to search near. The value should be a string in + the format `latitude,longitude`. + +![Note](note.png) The `coords` argument description seems to have been copied erroneously from +the `search` +argument in the previous method. It should specify the format for providing geographic coordinates +rather than matching against pickup point attributes. + +```php +$lat = 50.087; +$long = 14.421; +$params = Params::create() + ->withCountry(Country::CZECH_REPUBLIC) + ->withSpedition(Spedition::PACKETA_IPP) + ->withLocation($lat, $long); +$result = $client->nearby($params); +/** @var ?Data $data */ +$items = $result->getData() ?? []; +foreach($items as $pp) { + echo $pp->getSpeditionId() . PHP_EOL; +} +... +``` diff --git a/docs/classes.md b/docs/classes.md new file mode 100644 index 0000000..21b6710 --- /dev/null +++ b/docs/classes.md @@ -0,0 +1,40 @@ +![Olza Logistic Logo](olza-logo-small.png) + +--- + +# PP API Client for PHP + +* [Library requirements](requirements.md) +* [Installation](installation.md) +* [Public API methods](api.md) +* Library classes reference +* [Exceptions](exceptions.md) + +--- + +## `Client` - gateway to PP API + +The `Client` class serves as your gateway to the PP API. It acts as a wrapper around the HTTP client +library, handling the intricacies of communicating with the API and processing responses. + +[`Client` class API documentation](client.md) + +--- + +## `Params` - method arguments vessel + +All public client methods requiring arguments expect instance of `Params` class as argument, with +all the method required arguments set using all exposed `withXXX()` helper methods. + +[`Params` class API documentation](params.md) + +--- + +## `Result` - response data container + +Client responses are always provided as instances of the `Result` class. The object is immutable, +and for ease of use, `Result` is a subclass +of [ArrayObject](https://www.php.net/manual/en/class.arrayobject.php) and aside from exposing useful +methods, it also acts as a regular array. + +[`Result` class API documentation](response.md) diff --git a/docs/client.md b/docs/client.md index 8670e76..6ee2e19 100644 --- a/docs/client.md +++ b/docs/client.md @@ -4,52 +4,53 @@ # PP API Client for PHP -* **[« Go back](README.md)** * [Library requirements](requirements.md) * [Installation](installation.md) -* Library API reference - * [`Client` class - gateway to the PP API](client.md#gateway-to-the-api) - * [Creating client instance](client.md#instantiation) - * Public API methods - * [`config(Params $params): Result;`](client.md#configparams-params-result) - * [`details(Params $params): Result;`](client.md#detailsparams-params-result) - * [`find(Params $params): Result;`](client.md#findparams-params-result) - * [`search(Params $params): Result;`](client.md#searchparams-params-result) - * [`Params` class - passing method arguments](params.md#passing-method-arguments) - * [`Result` class - accessing response data](response.md#accessing-response-data) - * [`Data` class - accessing response payload](response.md#accessing-response-payload) +* [Public API methods](api.md) +* [Library classes reference](classes.md) + * `Client` - gateway to the PP API + * [Usage](#usage) + * [Creating client instance](#creating-client-instance) + * [Using Client with Guzzle library](#using-client-with-guzzle-library) + * [`Params` - passing method arguments](params.md) + * [`Result` - accessing response data](response.md) * [Exceptions](exceptions.md) --- ## Usage +The `Client` class serves as your gateway to the PP API. It acts as a wrapper around the HTTP client +library, handling the intricacies of communicating with the API and processing responses. + To simplify the usage of the library, all public methods provided by the library expect arguments to be passed using the `Params` class. All response data is also returned, encapsulated within a unified `Result` class object. For those who prefer handling exceptions rather than checking the result, there's a mode that transforms each unsuccessful API response into a corresponding exception (for more information, see the details on `Client` class instantiation). ---- - -## Client class +### Creating client instance -The `Client` class serves as your gateway to the PP API. It acts as a wrapper around the HTTP client -library, handling the intricacies of communicating with the API and processing responses. +To begin using the library, you need to first create an instance of the `Client` class, using +static `public static function useApi(string $apiUrl)` method and several builder methods: -### Instantiation +| Method signature | Description | +|---------------------------------------------------------------|-------------------------------------------------------------------------------------------------------| +| `withAccessToken(string $accessToken)` | Configures the client to utilize a specific access token when interacting with the Pickup Points API. | +| `withUserAgent(string $userAgent)` | Specifies the User-Agent string for all HTTP API requests. | +| `withHttpClient(ClientInterface $httpClient)` | Configures a PSR-18 compatible instance of an HTTP client implementation. | +| `withRequestFactory(requestFactoryInterface $requestFactory)` | Configures a PSR-17 compatible request factory instance to work with the HTTP client. | +| `throwOnError()` | Configures the client to throw an exception in case of any API connection failure. | -To begin using the library, you need to first create an instance of the `Client` class: +Then calling `build()` to obrain the `Client` instance: ```php use OlzaLogistic\PpApi\Client\Client as PpApiClient; -$url = ... -$accessToken = ... - $client = PpApiClient::useApi($url) ->withAccessToken($token) - ->withGuzzleHttpClient() + ->withHttpClient($client) + ->withRequestFactory($requestFactory) ->throwOnError() ->build(); ``` @@ -61,7 +62,8 @@ need an instance of the `Params` class to pass all the required information to t ```php $client = PpApiClient::useApi($url) ->withAccessToken($token) - ->withGuzzleHttpClient() + ->withHttpClient($client) + ->withRequestFactory($requestFactory) ->build(); $params = Params::create() @@ -88,7 +90,8 @@ be thrown): ```php $client = PpApiClient::useApi($url) ->withAccessToken($token) - ->withGuzzleHttpClient() + ->withHttpClient($client) + ->withRequestFactory($requestFactory) ->throwOnError() // <-- any error will end up as an exception ->build(); @@ -106,122 +109,24 @@ try { therefore you will not see the code checking the `success()` method on the `Result` object, however you are free to use either approach as you see fit. ---- - -### Public API methods - -The following public methods serve as you gateway to PP API: - -#### `config(Params $params): Result;` - -Returns current vital information about PP API environment. - -![Note](note.png) It's highly recommended to invoke the `config/` method as the very first method -during your PP API communication session. This method is expected to return vital runtime parameters -back to the client, allowing you to act accordingly. For instance, `config/` will return a list of -all currently available carriers (and their IDs), providing foresight on what to expect from other -carrier-dependent methods. - -Required arguments: - -* `country` - **(required)** country code (use Country::xxx consts) - -```php -$params = Params::create() - ->withCountry(Country::CZECH_REPUBLIC); -$result = $client->config($params); -$configItems = $result->getData(); -... -... -``` - -#### `details(Params $params): Result;` +#### Using Client with Guzzle library -Return details about specific Pickup Point. +To use the Client with Guzzle library, ensure you install both the HTTP client and PSR-7 compatible +request library: -Required arguments: - -* `country` - **(required)** country code (use `Country::xxx` consts) -* `spedition` - **(required)** one (string) or more (array of strings) -* `id` - **(required)** Pickup point identifier - -```php -$params = Params::create() - ->withCountry(Country::CZECH_REPUBLIC) - ->withSpedition(Spedition::PACKETA_IPP) - ->withSpeditionId('12345'); -$result = $client->details($params); -$items = $result->getData(); -foreach($items as $pp) { - echo $pp->getSpeditionId() . PHP_EOL; -} -... - -... +```bash +composer require guzzlehttp/guzzle guzzlehttp/psr7 ``` -#### `find(Params $params): Result;` - -Searches for available pickup points that match the provided parameters. - -Required arguments: - -* `country` - **[required]** country code (use `Country::xxx` consts). -* `spedition` - **[required]** either a single spedition (string) or multiple speditions (array of - strings). - -Optional arguments: - -* `search` - A search string that will be additionally matched against pickup point names, - identifiers, addresses, etc. -* `services` - A list of services (see `ServiceType::*`) that a pickup point must support to be - included in the returned dataset. **NOTE: services are `OR`ed, so supporting just one suffices.** -* `payments` - A list of payment types (see `PaymentType::*`) that a pickup point must support to be - included in the returned dataset. **NOTE: payment types are `OR`ed, so supporting just one - suffices.** -* `limit` - The maximum number of items to be returned. The default is to return all matching items. +Then, create an instance of the `Client` class: ```php -$params = Params::create() - ->withCountry(Country::CZECH_REPUBLIC) - ->withSpedition(Spedition::PACKETA_IPP); -$result = $client->find($params); -$items = $result->getData() ?? []; -foreach($items as $pp) { - echo $pp->getSpeditionId() . PHP_EOL; -} -... -``` - -#### `nearby(Params $params): Result;` - -Searches for pickup points located near a specified geographic location. - -Required arguments: - -* `country` - **[required]** country code (use `Country::xxx` consts). -* `spedition` - **[required]** either a single spedition (string) or multiple speditions (array of - strings). -* `coords` - **[required]** geographic coordinates to search near. The value should be a string in - the format `latitude,longitude`. +$httpClient = new \GuzzleHttp\Client(); +$requestFactory = new \GuzzleHttp\Psr7\HttpFactory(); -![Note](note.png) The `coords` argument description seems to have been copied erroneously from -the `search` -argument in the previous method. It should specify the format for providing geographic coordinates -rather than matching against pickup point attributes. - -```php -$lat = 50.087; -$long = 14.421; -$params = Params::create() - ->withCountry(Country::CZECH_REPUBLIC) - ->withSpedition(Spedition::PACKETA_IPP) - ->withLocation($lat, $long); -$result = $client->nearby($params); -/** @var ?Data $data */ -$items = $result->getData() ?? []; -foreach($items as $pp) { - echo $pp->getSpeditionId() . PHP_EOL; -} -... +$client = PpApiClient::useApi($url) + ->withAccessToken($token) + ->withHttpClient($client) + ->withRequestFactory($requestFactory) + ->build(); ``` diff --git a/docs/examples/README.md b/docs/examples/README.md new file mode 100644 index 0000000..0452ba1 --- /dev/null +++ b/docs/examples/README.md @@ -0,0 +1,17 @@ +![Olza Logistic Logo](../olza-logo-small.png) + +--- + +# PP API Client for PHP + +**[« Go back to main ToC](../README.md)** + +* [Library requirements](../requirements.md) +* [Installation](../installation.md) +* [Public API methods](../api.md) +* [Library classes reference](../classes.md) +* Usage examples + * [Obtaing API configuration](config.md) + * [Searching for pickup points](find.md) + * [Retrieving pickup point details](detail.md) + * [Finding nearby pickup points](nearby.md) diff --git a/docs/examples/config.md b/docs/examples/config.md new file mode 100644 index 0000000..cfea58b --- /dev/null +++ b/docs/examples/config.md @@ -0,0 +1,48 @@ +![Olza Logistic Logo](../olza-logo-small.png) + +--- + +# PP API Client for PHP + +**[« Go back to main ToC](../README.md)** + +* [Library requirements](../requirements.md) +* [Installation](../installation.md) +* [Public API methods](../api.md) +* [Library classes reference](../classes.md) +* Usage examples + * [Obtaing API configuration](config.md) + * [Searching for pickup points](find.md) + * Retrieving pickup point details + * [Finding nearby pickup points](nearby.md) + +--- + +## Getting API runtime details for given country + +```php +use OlzaLogistic\PpApi\Client\Client as PpApiClient; +use OlzaLogistic\PpApi\Client\Params; +use OlzaLogistic\PpApi\Client\Model\Country; + +$apiToken = ''; +$apiUrl = 'https://...'; + +// Using Guzzle HTTP client +$httpClient = \GuzzleHttp\Client(); +$requestFactory = \GuzzleHttp\Psr7\RequestFactory(); + +$client = PpApiClient::useApi($apiUrl) + ->withAccessToken($apiToken) + ->withHttpClient($httpClient) + ->withRequestFactory($requestFactory) + ->throwOnError() + ->build(); + +$params = Params::create() + ->withCountry(Country::CZECHIA); + +$apiResponse = $client->config($params); + +print_r($apiResponse); +``` diff --git a/docs/examples/details.md b/docs/examples/details.md new file mode 100644 index 0000000..da66a62 --- /dev/null +++ b/docs/examples/details.md @@ -0,0 +1,51 @@ +![Olza Logistic Logo](../olza-logo-small.png) + +--- + +# PP API Client for PHP + +**[« Go back to main ToC](../README.md)** + +* [Library requirements](../requirements.md) +* [Installation](../installation.md) +* [Public API methods](../api.md) +* [Library classes reference](../classes.md) +* Usage examples + * [Obtaing API configuration](config.md) + * [Searching for pickup points](find.md) + * Retrieving pickup point details + * [Finding nearby pickup points](nearby.md) + +--- + +## Retrieving pickup point details + +```php +use OlzaLogistic\PpApi\Client\Client as PpApiClient; +use OlzaLogistic\PpApi\Client\Params; +use OlzaLogistic\PpApi\Client\Model\Country; +use OlzaLogistic\PpApi\Client\Model\Spedition; + +$apiToken = ''; +$apiUrl = 'https://...'; + +// Using Guzzle HTTP client +$httpClient = \GuzzleHttp\Client(); +$requestFactory = \GuzzleHttp\Psr7\RequestFactory(); + +$client = PpApiClient::useApi($apiUrl) + ->withAccessToken($apiToken) + ->withHttpClient($httpClient) + ->withRequestFactory($requestFactory) + ->throwOnError() + ->build(); + +$params = Params::create() + ->withCountry(Country::CZECHIA) + ->withSpedition(Spedition::PACKETA_IPP) + ->withSpeditionId('135'); + +$apiResponse = $client->details($params); + +print_r($apiResponse); +``` diff --git a/docs/examples/find.md b/docs/examples/find.md new file mode 100644 index 0000000..65939d0 --- /dev/null +++ b/docs/examples/find.md @@ -0,0 +1,53 @@ +![Olza Logistic Logo](../olza-logo-small.png) + +--- + +# PP API Client for PHP + +**[« Go back to main ToC](../README.md)** + +* [Library requirements](../requirements.md) +* [Installation](../installation.md) +* [Public API methods](../api.md) +* [Library classes reference](../classes.md) +* Usage examples + * [Obtaing API configuration](config.md) + * Searching for pickup points + * [Retrieving pickup point details](detail.md) + * [Finding nearby pickup points](nearby.md) + +--- + +## Finds Pickup Points in given country + +```php +use OlzaLogistic\PpApi\Client\Client as PpApiClient; +use OlzaLogistic\PpApi\Client\Params; +use OlzaLogistic\PpApi\Client\Model\Country; +use OlzaLogistic\PpApi\Client\Model\Spedition; + +$apiToken = ''; +$apiUrl = 'https://...'; + +// Using Guzzle HTTP client +$httpClient = \GuzzleHttp\Client(); +$requestFactory = \GuzzleHttp\Psr7\RequestFactory(); + +$client = PpApiClient::useApi($apiUrl) + ->withAccessToken($apiToken) + ->withHttpClient($httpClient) + ->withRequestFactory($requestFactory) + ->throwOnError() + ->build(); + +$params = Params::create() + ->withCountry(Country::CZECHIA) + ->withSpeditions([ + Spedition::PACKETA_IPP, + Spedition::PACKETA_EPP_SPEEDY_PP, + ]); + +$apiResponse = $client->find($params); + +print_r($apiResponse); +``` diff --git a/docs/examples/nearby.md b/docs/examples/nearby.md new file mode 100644 index 0000000..3479ad9 --- /dev/null +++ b/docs/examples/nearby.md @@ -0,0 +1,53 @@ +![Olza Logistic Logo](../olza-logo-small.png) + +--- + +# PP API Client for PHP + +**[« Go back to main ToC](../README.md)** + +* [Library requirements](../requirements.md) +* [Installation](../installation.md) +* [Public API methods](../api.md) +* [Library classes reference](../classes.md) +* Usage examples + * [Obtaing API configuration](config.md) + * [Searching for pickup points](find.md) + * Retrieving pickup point details + * [Finding nearby pickup points](nearby.md) + +--- + +## Finding pickup points around given location + +```php +use OlzaLogistic\PpApi\Client\Client as PpApiClient; +use OlzaLogistic\PpApi\Client\Params; +use OlzaLogistic\PpApi\Client\Model\Country; +use OlzaLogistic\PpApi\Client\Model\Spedition; + +$apiToken = ''; +$apiUrl = 'https://...'; + +// Using Guzzle HTTP client +$httpClient = \GuzzleHttp\Client(); +$requestFactory = \GuzzleHttp\Psr7\RequestFactory(); + +$client = PpApiClient::useApi($apiUrl) + ->withAccessToken($apiToken) + ->withHttpClient($httpClient) + ->withRequestFactory($requestFactory) + ->throwOnError() + ->build(); + +$lat = 50.087; +$long = 14.421; +$params = Params::create() + ->withCountry(Country::CZECHIA) + ->withSpedition(Spedition::PACKETA_IPP) + ->withLocation($lat, $long); + +$apiResponse = $client->nearby($params); + +print_r($apiResponse); +``` diff --git a/docs/exceptions.md b/docs/exceptions.md index 7fd23af..f352f50 100644 --- a/docs/exceptions.md +++ b/docs/exceptions.md @@ -4,21 +4,11 @@ # PP API Client for PHP -* **[« Go back](README.md)** * [Library requirements](requirements.md) * [Installation](installation.md) -* Library API reference - * [`Client` class - gateway to the PP API](client.md#gateway-to-the-api) - * [Creating client instance](client.md#instantiation) - * Public API methods - * [`config(Params $params): Result;`](client.md#configparams-params-result) - * [`details(Params $params): Result;`](client.md#detailsparams-params-result) - * [`find(Params $params): Result;`](client.md#findparams-params-result) - * [`search(Params $params): Result;`](client.md#searchparams-params-result) - * [`Params` class - passing method arguments](params.md#passing-method-arguments) - * [`Result` class - accessing response data](response.md#accessing-response-data) - * [`Data` class - accessing response payload](response.md#accessing-response-payload) - * [Exceptions](exceptions.md) +* [Public API methods](api.md) +* [Library classes reference](classes.md) +* **Exceptions** --- diff --git a/docs/installation.md b/docs/installation.md index bb16c44..26033fd 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -4,21 +4,10 @@ # PP API Client for PHP -* **[« Go back](README.md)** * [Library requirements](requirements.md) * [Installation](installation.md) -* Library API reference - * [`Client` class - gateway to the PP API](client.md#gateway-to-the-api) - * [Creating client instance](client.md#instantiation) - * Public API methods - * [`config(Params $params): Result;`](client.md#configparams-params-result) - * [`details(Params $params): Result;`](client.md#detailsparams-params-result) - * [`find(Params $params): Result;`](client.md#findparams-params-result) - * [`search(Params $params): Result;`](client.md#searchparams-params-result) - * [`Params` class - passing method arguments](params.md#passing-method-arguments) - * [`Result` class - accessing response data](response.md#accessing-response-data) - * [`Data` class - accessing response payload](response.md#accessing-response-payload) - * [Exceptions](exceptions.md) +* [Public API methods](api.md) +* [Library classes reference](classes.md) --- @@ -37,10 +26,8 @@ composer require develart-projects/pickup-points-api-client ### HTTP Clients The library supports the following HTTP clients: - -* Guzzle (version 7.4 or newer) - *Symfony HttpClient (version 5.4 or newer) - *Any PSR-18 compatible HTTP client + * Any `PSR-18` compatible HTTP client and `PSR-17` compatible request factory. + * Symfony HttpClient (version 5.4 or newer) This command will download the PP API Client library and its core dependencies. Next, you need to @@ -48,7 +35,7 @@ install one of the supported HTTP clients (unless you have it installed already) For example, to install Guzzle, run the following command: ```bash -composer require guzzlehttp/guzzle +composer require guzzlehttp/guzzle guzzlehttp/psr7 ``` To install Symfony HTTP client, run the following command: diff --git a/docs/params.md b/docs/params.md index 8c21602..9375d2e 100644 --- a/docs/params.md +++ b/docs/params.md @@ -4,20 +4,13 @@ # PP API Client for PHP -* **[« Go back](README.md)** * [Library requirements](requirements.md) * [Installation](installation.md) -* Library API reference - * [`Client` class - gateway to the PP API](client.md#gateway-to-the-api) - * [Creating client instance](client.md#instantiation) - * Public API methods - * [`config(Params $params): Result;`](client.md#configparams-params-result) - * [`details(Params $params): Result;`](client.md#detailsparams-params-result) - * [`find(Params $params): Result;`](client.md#findparams-params-result) - * [`search(Params $params): Result;`](client.md#searchparams-params-result) - * [`Params` class - passing method arguments](params.md#passing-method-arguments) - * [`Result` class - accessing response data](response.md#accessing-response-data) - * [`Data` class - accessing response payload](response.md#accessing-response-payload) +* [Public API methods](api.md) +* [Library classes reference](classes.md) + * [`Client` - gateway to the PP API](client.md) + * `Params` - passing method arguments + * [`Result` - accessing response data](response.md) * [Exceptions](exceptions.md) --- diff --git a/docs/requirements.md b/docs/requirements.md index 26c3c7a..7fcbc28 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -4,21 +4,10 @@ # PP API Client for PHP -* **[« Go back](README.md)** -* [Library requirements](requirements.md) +* Library requirements] * [Installation](installation.md) -* Library API reference - * [`Client` class - gateway to the PP API](client.md#gateway-to-the-api) - * [Creating client instance](client.md#instantiation) - * Public API methods - * [`config(Params $params): Result;`](client.md#configparams-params-result) - * [`details(Params $params): Result;`](client.md#detailsparams-params-result) - * [`find(Params $params): Result;`](client.md#findparams-params-result) - * [`search(Params $params): Result;`](client.md#searchparams-params-result) - * [`Params` class - passing method arguments](params.md#passing-method-arguments) - * [`Result` class - accessing response data](response.md#accessing-response-data) - * [`Data` class - accessing response payload](response.md#accessing-response-payload) - * [Exceptions](exceptions.md) +* [Public API methods](api.md) +* [Library classes reference](classes.md) --- @@ -27,20 +16,14 @@ The PP API Client library has the following requirements: * PHP 7.4 or newer. -* One HTTP client library to handle HTTP requests and responses. -* PSR-17 HTTP Factory library to create request/response objects, stream objects, and URI objects. - -![Note](note.png) Though various HTTP clients are supported, only one is required to make the library functional. The -choice of HTTP client can be based on the specific needs of your project. Aside from the solid -implementations provided, any future HTTP client adhering to the PSR standards will also be -supported out of the box. - -### HTTP Clients - -The library directly supports and was tested with the following HTTP clients: - -* Guzzle (version 7.4 or newer) -*Symfony HttpClient (version 5.4 or newer) - -It also supports -[PSR compatible HTTP clients](https://packagist.org/providers/psr/http-client-implementation) +* [PSR-18](https://www.php-fig.org/psr/psr-18/) compatible HTTP client library to handle HTTP + requests and responses. +* [PSR-17](https://www.php-fig.org/psr/psr-17/) compatible HTTP Factory library to create + request/response objects, stream objects, and URI objects + +![Note](note.png) Though various HTTP clients are supported, only one is required to make the +library functional. The choice of HTTP client can be based on the specific needs of your project. +Aside from the solid implementations provided, any future HTTP client adhering to the PSR standards +will also be supported out of the box. Most of the most popular libraries (like i.e. Guzzle or +Symfony client already support PSR-18 and PSR-17 and can be used with the library. See the +documentation for usage examples). diff --git a/docs/response.md b/docs/response.md index 9e7f04d..da652ce 100644 --- a/docs/response.md +++ b/docs/response.md @@ -4,21 +4,15 @@ # PP API Client for PHP -* **[« Go back](README.md)** * [Library requirements](requirements.md) * [Installation](installation.md) +* [Public API methods](api.md) * Library API reference - * [`Client` class - gateway to the PP API](client.md#gateway-to-the-api) - * [Creating client instance](client.md#instantiation) - * Public API methods - * [`config(Params $params): Result;`](client.md#configparams-params-result) - * [`details(Params $params): Result;`](client.md#detailsparams-params-result) - * [`find(Params $params): Result;`](client.md#findparams-params-result) - * [`search(Params $params): Result;`](client.md#searchparams-params-result) - * [`Params` class - passing method arguments](params.md#passing-method-arguments) - * [`Result` class - accessing response data](response.md#accessing-response-data) - * [`Data` class - accessing response payload](response.md#accessing-response-payload) - * [Exceptions](exceptions.md) + +* [Library classes reference](classes.md) + * [`Client` class - gateway to the PP API](client.md) + * [`Params` - passing method arguments](params.md) + * `Result` - accessing response data --- @@ -30,13 +24,11 @@ of [ArrayObject](https://www.php.net/manual/en/class.arrayobject.php). Aside fro methods, it also acts as a regular array: ```php -... $result = $client->find('cz'); $items = $result->getData(); foreach($items as $item) { echo $item->getSpeditionId() . PHP_EOL; } -... ``` `Result` class exposes the following public methods: diff --git a/examples/config.php b/examples/config.php deleted file mode 100644 index 1e6e812..0000000 --- a/examples/config.php +++ /dev/null @@ -1,33 +0,0 @@ -withAccessToken($apiToken) - ->withGuzzleHttpClient() - ->build(); - -$params = Params::create() - ->withCountry(Country::CZECHIA); - -$apiResponse = $client->config($params); - -echo '
';
-print_r($apiResponse);
-echo '
'; diff --git a/examples/details.php b/examples/details.php deleted file mode 100644 index b75ff00..0000000 --- a/examples/details.php +++ /dev/null @@ -1,36 +0,0 @@ -withAccessToken($apiToken) - ->withGuzzleHttpClient() - ->build(); - -$params = Params::create() - ->withCountry(Country::CZECHIA) - ->withSpedition(Spedition::PACKETA_IPP) - ->withSpeditionId('135'); - -$apiResponse = $client->details($params); - -echo '
';
-print_r($apiResponse);
-echo '
'; diff --git a/examples/find.php b/examples/find.php deleted file mode 100644 index a52d550..0000000 --- a/examples/find.php +++ /dev/null @@ -1,35 +0,0 @@ -withAccessToken($apiToken) - ->withGuzzleHttpClient() - ->build(); - -$params = Params::create() - ->withCountry(Country::CZECHIA) - ->withSpeditions([Spedition::PACKETA_IPP, Spedition::PACKETA_EPP_SPEEDY_PP]); - -$apiResponse = $client->find($params); - -echo '
';
-print_r($apiResponse);
-echo '
'; diff --git a/examples/nearby.php b/examples/nearby.php deleted file mode 100644 index 826616b..0000000 --- a/examples/nearby.php +++ /dev/null @@ -1,38 +0,0 @@ -withAccessToken($apiToken) - ->withGuzzleHttpClient() - ->build(); - -$lat = 50.087; -$long = 14.421; -$params = Params::create() - ->withCountry(Country::CZECHIA) - ->withSpedition(Spedition::PACKETA_IPP) - ->withLocation($lat, $long); - -$apiResponse = $client->nearby($params); - -echo '
';
-print_r($apiResponse);
-echo '
'; From 50006fc6aa50ac8dda211ef73f4edca4af012870 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 12:52:47 +0200 Subject: [PATCH 03/29] Added documentation for use of Symfony HTTP Client --- docs/client.md | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/docs/client.md b/docs/client.md index 6ee2e19..cb11265 100644 --- a/docs/client.md +++ b/docs/client.md @@ -11,7 +11,8 @@ * `Client` - gateway to the PP API * [Usage](#usage) * [Creating client instance](#creating-client-instance) - * [Using Client with Guzzle library](#using-client-with-guzzle-library) + * [Using with Guzzle library](#using-with-guzzle-library) + * [Using with Symfony HTTP Client)](#using-client-with-symfony-http-client) * [`Params` - passing method arguments](params.md) * [`Result` - accessing response data](response.md) * [Exceptions](exceptions.md) @@ -29,7 +30,7 @@ unified `Result` class object. For those who prefer handling exceptions rather t result, there's a mode that transforms each unsuccessful API response into a corresponding exception (for more information, see the details on `Client` class instantiation). -### Creating client instance +## Creating client instance To begin using the library, you need to first create an instance of the `Client` class, using static `public static function useApi(string $apiUrl)` method and several builder methods: @@ -109,9 +110,9 @@ try { therefore you will not see the code checking the `success()` method on the `Result` object, however you are free to use either approach as you see fit. -#### Using Client with Guzzle library +### Using with Guzzle library -To use the Client with Guzzle library, ensure you install both the HTTP client and PSR-7 compatible +To use the this library with Guzzle, ensure you install both the HTTP client and PSR-7 compatible request library: ```bash @@ -130,3 +131,26 @@ $client = PpApiClient::useApi($url) ->withRequestFactory($requestFactory) ->build(); ``` + +### Using with Symfony HTTP Client + +Unless you are trying to use this library from i.e. existing Symfony framework based project, you +need to install the Symfony HTTP client package and any package implementing PSR-17 request factory, +l.e. [nyholm/psr7](https://packagist.org/packages/nyholm/psr7): + +```bash +composer require symfony/http-client nyholm/psr7 +``` + +Then, create an instance of the `Client` class: + +```php +$httpClient = new \GuzzleHttp\Client(); +$requestFactory = new \Nyholm\Psr7\Factory\Psr17Factory(); + +$client = PpApiClient::useApi($url) + ->withAccessToken($token) + ->withHttpClient($client) + ->withRequestFactory($requestFactory) + ->build(); +``` From a6b9baa68b9bc2d546a6c4e934a1f534a55414f8 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 12:59:21 +0200 Subject: [PATCH 04/29] Corrected documentation markdown --- .markdownlint.yaml.dist | 3 ++- README.md | 3 ++- docs/api.md | 8 ++++---- docs/installation.md | 23 +++-------------------- 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/.markdownlint.yaml.dist b/.markdownlint.yaml.dist index 20a969b..7f21841 100644 --- a/.markdownlint.yaml.dist +++ b/.markdownlint.yaml.dist @@ -78,7 +78,8 @@ MD013: # Include code blocks code_blocks: true # Include tables - tables: true + # tables: true + tables: false # MOR # Include headings headings: true # Include headings diff --git a/README.md b/README.md index ac420ea..891978f 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,13 @@ Whether you're integrating a parcel delivery system or enhancing the user experi convenient pickup options, the PP API Client library is an indispensable tool. It offers a streamlined interface to the PP API service, simplifying the development process and augmenting the functionality of parcel delivery-related applications. + --- ## Documentation * [Requirements](docs/installation.md) -* [Usage examples](examples/) +* [Usage examples](docs/examples/README.md) * [Library API reference](docs/README.md) --- diff --git a/docs/api.md b/docs/api.md index f1a9cd6..d634626 100644 --- a/docs/api.md +++ b/docs/api.md @@ -30,7 +30,7 @@ on [Client class instantiation](client.md)). The following public methods serve as you gateway to PP API: -#### `config(Params $params): Result;` +### `config(Params $params): Result;` Returns current vital information about PP API environment. @@ -53,7 +53,7 @@ $configItems = $result->getData(); ... ``` -#### `details(Params $params): Result;` +### `details(Params $params): Result;` Return details about specific Pickup Point. @@ -78,7 +78,7 @@ foreach($items as $pp) { ... ``` -#### `find(Params $params): Result;` +### `find(Params $params): Result;` Searches for available pickup points that match the provided parameters. @@ -111,7 +111,7 @@ foreach($items as $pp) { ... ``` -#### `nearby(Params $params): Result;` +### `nearby(Params $params): Result;` Searches for pickup points located near a specified geographic location. diff --git a/docs/installation.md b/docs/installation.md index 26033fd..3861241 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -25,24 +25,7 @@ composer require develart-projects/pickup-points-api-client ### HTTP Clients -The library supports the following HTTP clients: - * Any `PSR-18` compatible HTTP client and `PSR-17` compatible request factory. - * Symfony HttpClient (version 5.4 or newer) +The library supports any `PSR-18` compatible HTTP client and `PSR-17` compatible request factory, - -This command will download the PP API Client library and its core dependencies. Next, you need to -install one of the supported HTTP clients (unless you have it installed already). -For example, to install Guzzle, run the following command: - -```bash -composer require guzzlehttp/guzzle guzzlehttp/psr7 -``` - -To install Symfony HTTP client, run the following command: - -```bash -composer require symfony/http-client -``` - -With these steps, you are now ready to use the PP API Client library in your project. Remember, you -only need to install one HTTP client. Choose the one that best fits your project's needs. +See [Client class documentation](client.md) or [usage examples](examples/) now how to use library +with various HTTP clients. From 63f64272baab4df80a14597519ec6f67c364a47f Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 13:07:45 +0200 Subject: [PATCH 05/29] Added dedicated exceptions to be thrown when accesing saeled/non-sealed client --- CHANGES.md | 2 ++ docs/exceptions.md | 4 +++ src/ClientBase.php | 25 ++++++++----------- .../ClientAlreadyInitializedException.php | 24 ++++++++++++++++++ src/Exception/ClientNotSealedException.php | 24 ++++++++++++++++++ 5 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 src/Exception/ClientAlreadyInitializedException.php create mode 100644 src/Exception/ClientNotSealedException.php diff --git a/CHANGES.md b/CHANGES.md index 553c17d..fcc5c26 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,8 @@ Olza Logistic's Pickup Point API Client PHP library. * Removed `withGuzzleHttpClient()` as Guzzle no longer needs special treatment. * Removed `withSymfonyHttpClient()`. See docs on how to use Symfony HTTP client. * Removed `withPsrClient()`. Use `withHttpClient()` and `withRequestClient()` instead. + * Attempt to modify sealed client now throws `ClientAlreadyInitializedException`. + * Attempt to access not sealed client now throws `ClientNotSealedException`. * Updated library documentation. diff --git a/docs/exceptions.md b/docs/exceptions.md index f352f50..a4d8440 100644 --- a/docs/exceptions.md +++ b/docs/exceptions.md @@ -27,3 +27,7 @@ exceptions will be thrown on API errors: invalid or outdated access token). * `ObjectNotFoundException` - thrown when requested data was not found (i.e. invalid PP reference ID, or invalid carrier ID etc.). + +The client can also throw `ClientNotSealedException` on attempts to use the client before it +configuration was concluded with `build()`, and `ClientAlreadyInitializedException` on attempts to +modify configuration of already initialized client. diff --git a/src/ClientBase.php b/src/ClientBase.php index d9a1ede..74fe058 100644 --- a/src/ClientBase.php +++ b/src/ClientBase.php @@ -14,6 +14,8 @@ use OlzaLogistic\PpApi\Client\Contracts\ClientContract; use OlzaLogistic\PpApi\Client\Exception\AccessDeniedException; +use OlzaLogistic\PpApi\Client\Exception\ClientAlreadyInitializedException; +use OlzaLogistic\PpApi\Client\Exception\ClientNotSealedException; use OlzaLogistic\PpApi\Client\Exception\MethodFailedException; use OlzaLogistic\PpApi\Client\Exception\ObjectNotFoundException; use Psr\Http\Client\ClientInterface; @@ -44,8 +46,7 @@ public function withAccessToken(string $accessToken): self throw new \InvalidArgumentException('Invalid API access token.'); } - $this->setAccessToken($accessToken); - return $this; + return $this->setAccessToken($accessToken); } /** @@ -55,8 +56,7 @@ public function withAccessToken(string $accessToken): self */ public function withUserAgent(string $userAgent): self { - $this->setUserAgent($userAgent); - return $this; + return $this->setUserAgent($userAgent); } /** @@ -68,12 +68,10 @@ public function withHttpClient(ClientInterface $httpClient): self { $this->assertClientNotConfigured(); - $this->setHttpClient($httpClient); - return $this; + return $this->setHttpClient($httpClient); } - /** * Configures a PSR-17 compatible request factory instance to work with the HTTP client. * @@ -83,8 +81,7 @@ public function withRequestFactory(requestFactoryInterface $requestFactory): sel { $this->assertClientNotConfigured(); - $this->setRequestFactory($requestFactory); - return $this; + return $this->setRequestFactory($requestFactory); } /** @@ -93,8 +90,7 @@ public function withRequestFactory(requestFactoryInterface $requestFactory): sel */ public function throwOnError(): self { - $this->setThrowOnError(true); - return $this; + return $this->setThrowOnError(true); } /** @@ -128,7 +124,7 @@ protected function seal(): void protected function assertConfigurationSealed(): void { if (!$this->isClientInitialized) { - throw new \RuntimeException('Client not initialized.'); + throw new ClientNotSealedException(); } } @@ -139,7 +135,7 @@ protected function assertConfigurationSealed(): void protected function assertClientNotConfigured(): void { if ($this->isClientInitialized) { - throw new \RuntimeException('Client already initialized.'); + throw new ClientAlreadyInitializedException(); } } @@ -179,7 +175,7 @@ protected function setAccessToken(string $accessToken): self /** * Network client for API communication. * - * @var \Psr\Http\Client\ClientInterface + * @var ClientInterface */ protected ClientInterface $httpClient; @@ -325,7 +321,6 @@ protected function handleHttpRequest(string $endPoint, ?Params $apiParams, */ $result = $processResponseCallback($apiResponse); } catch (\Throwable $ex) { - // FIXME: log the exception $result = Result::fromThrowable($ex); } diff --git a/src/Exception/ClientAlreadyInitializedException.php b/src/Exception/ClientAlreadyInitializedException.php new file mode 100644 index 0000000..84e7881 --- /dev/null +++ b/src/Exception/ClientAlreadyInitializedException.php @@ -0,0 +1,24 @@ + + * @copyright 2023 DevelArt + * @license Proprietary + */ + +namespace OlzaLogistic\PpApi\Client\Exception; + +/** + * Thrown on attempt to modify sealed client instance. + */ +class ClientAlreadyInitializedException extends \LogicException +{ + public function __construct() + { + parent::__construct('Client already initialized'); + } + +} // end of class diff --git a/src/Exception/ClientNotSealedException.php b/src/Exception/ClientNotSealedException.php new file mode 100644 index 0000000..b95cc39 --- /dev/null +++ b/src/Exception/ClientNotSealedException.php @@ -0,0 +1,24 @@ + + * @copyright 2023 DevelArt + * @license Proprietary + */ + +namespace OlzaLogistic\PpApi\Client\Exception; + +/** + * Thrown on attempt to use not sealed client instance. + */ +class ClientNotSealedException extends \LogicException +{ + public function __construct() + { + parent::__construct('Client configuration not sealed'); + } + +} // end of class From ed69d281cd6dbd92c024bab3ca19260038854b0f Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 13:09:48 +0200 Subject: [PATCH 06/29] Removed dead tests --- .../tests/HttpClient/GuzzleHttpClientTest.php | 48 ----------------- .../HttpClient/SymfonyHttpClientTest.php | 51 ------------------- 2 files changed, 99 deletions(-) delete mode 100644 tests/tests/HttpClient/GuzzleHttpClientTest.php delete mode 100644 tests/tests/HttpClient/SymfonyHttpClientTest.php diff --git a/tests/tests/HttpClient/GuzzleHttpClientTest.php b/tests/tests/HttpClient/GuzzleHttpClientTest.php deleted file mode 100644 index aaac4ad..0000000 --- a/tests/tests/HttpClient/GuzzleHttpClientTest.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2021-2023 DevelArt - * @license http://www.opensource.org/licenses/mit-license.php MIT - * @link https://github.com/develart-projects/pickup-points-api-client/ - */ - -namespace OlzaLogistic\PpApi\Client\Tests\HttpClient; - -use OlzaLogistic\PpApi\Client\Params; -use OlzaLogistic\PpApi\Client\Client; -use OlzaLogistic\PpApi\Client\Model\Country; -use OlzaLogistic\PpApi\Client\Data; -use OlzaLogistic\PpApi\Client\FieldType; -use OlzaLogistic\PpApi\Client\Tests\BaseTestCase; - -class GuzzleHttpClientTest extends BaseTestCase -{ - /** - * Tests integration with Guzzle HTTP client - */ - public function testGuzzle(): void - { - $this->markTestSkipped('Not isolated.'); - -// $url = 'http://127.0.0.1:8000'; -// $accessToken = 'pass'; -// -// $apiClient = Client::useApi($url) -// ->withAccessToken($accessToken) -// ->withGuzzleHttpClient() -// ->build(); -// -// $sped = $this->getRandomString('sped'); -// $filter = Params::create() -// ->withCountry(Country::CZECH) -// ->withSpedition($sped); -// $response = $apiClient->find($filter); -// -// $this->assertTrue($response->success(), $response->getMessage()); -// $this->assertInstanceOf(Data::class, $response->getData(), $response->getMessage()); - } - -} // end of class diff --git a/tests/tests/HttpClient/SymfonyHttpClientTest.php b/tests/tests/HttpClient/SymfonyHttpClientTest.php deleted file mode 100644 index 9ca3431..0000000 --- a/tests/tests/HttpClient/SymfonyHttpClientTest.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright 2021-2023 DevelArt - * @license http://www.opensource.org/licenses/mit-license.php MIT - * @link https://github.com/develart-projects/pickup-points-api-client/ - */ - -namespace OlzaLogistic\PpApi\Client\Tests\HttpClient; - -use OlzaLogistic\PpApi\Client\Params; -use OlzaLogistic\PpApi\Client\Client; -use OlzaLogistic\PpApi\Client\Model\Country; -use OlzaLogistic\PpApi\Client\Data; -use OlzaLogistic\PpApi\Client\FieldType; -use OlzaLogistic\PpApi\Client\Tests\BaseTestCase; - -class SymfonyHttpClientTest extends BaseTestCase -{ - /** - * Tests integration with Symfony HTTP client - */ - public function testSymfonyHttpClient(): void - { - $this->markTestSkipped('Not isolated.'); - -// $url = 'http://127.0.0.1:8000'; -// $accessToken = 'pass'; -// -// $apiClient = Client::useApi($url) -// ->withAccessToken($accessToken) -// ->withSymfonyHttpClient() -// ->build(); -// -// $sped = $this->getRandomString('sped'); -// $filter = Params::create() -// ->withCountry(Country::CZECH) -// ->withSpedition($sped) -// ->addField(FieldType::NAME) -// ->addField(FieldType::LOCATION); -// -// $response = $apiClient->find($filter); -// $apiMsg = $response->getMessage(); -// $this->assertTrue($response->success(), $apiMsg); -// $this->assertInstanceOf(Data::class, $response->getData(), $apiMsg); - } - -} // end of class From 730bfe0805478f0b07412b37b62831a56c8028bf Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 13:12:52 +0200 Subject: [PATCH 07/29] Updated tests --- tests/tests/Endpoint/ConfigTest.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/tests/Endpoint/ConfigTest.php b/tests/tests/Endpoint/ConfigTest.php index 3f95f54..833af90 100644 --- a/tests/tests/Endpoint/ConfigTest.php +++ b/tests/tests/Endpoint/ConfigTest.php @@ -57,7 +57,7 @@ public function testConfig(): void /** @var array $json */ $json = \json_decode(static::apiJsonConfigResponse, true, 32, JSON_THROW_ON_ERROR); $this->assertSuccessResponse($json); - $jsonData = $json[ ApiResponse::KEY_DATA ]; + $jsonData = $json[ApiResponse::KEY_DATA]; $this->assertNotNull($jsonData); $streamIfaceStub = $this->createStub(DummyStreamInterface::class); @@ -79,9 +79,10 @@ public function testConfig(): void $httpClientStub->method('sendRequest')->willReturn($responseStub); $apiClient = Client::useApi($url) - ->withAccessToken($accessToken) - ->withPsrClient($httpClientStub, $requestFactoryStub) - ->build(); + ->withAccessToken($accessToken) + ->withHttpClient($httpClientStub) + ->withRequestFactory($requestFactoryStub) + ->build(); $apiParams = Params::create()->withCountry(Country::CZECHIA); @@ -99,13 +100,13 @@ public function testConfig(): void $this->assertNotEmpty($speditions); $returnedSpeditionCodes = \array_keys($speditions); - $this->assertArrayEquals(\array_keys($jsonData[ ApiResponse::KEY_SPEDITIONS ]), $returnedSpeditionCodes); + $this->assertArrayEquals(\array_keys($jsonData[ApiResponse::KEY_SPEDITIONS]), $returnedSpeditionCodes); foreach ($speditions as $spedCode => $spedition) { /** @var \OlzaLogistic\PpApi\Client\Model\Spedition $spedition */ - $i = $jsonData[ ApiResponse::KEY_SPEDITIONS ][ $spedCode ]; - $this->assertEquals($i[ ApiResponse::KEY_CODE ], $spedition->getCode()); + $i = $jsonData[ApiResponse::KEY_SPEDITIONS][$spedCode]; + $this->assertEquals($i[ApiResponse::KEY_CODE], $spedition->getCode()); // $this->assertEquals($i[ ApiResponse::KEY_LABEL ], $spedition->getLabel()); // TODO: check translations From a1a86910ec68cfd175cf68a8dd46a7dbd6d0ee5c Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 13:17:15 +0200 Subject: [PATCH 08/29] Corrected markdown reference --- docs/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.md b/docs/api.md index d634626..d05fedb 100644 --- a/docs/api.md +++ b/docs/api.md @@ -10,7 +10,7 @@ * [`config(Params $params): Result;`](#configparams-params-result) * [`details(Params $params): Result;`](#detailsparams-params-result) * [`find(Params $params): Result;`](#findparams-params-result) - * [`search(Params $params): Result;`](#searchparams-params-result) + * [`nearby(Params $params): Result;`](#nearbyparams-params-result) * [Library classes reference](classes.md) --- From 8648ea2825de1eeaa3a920f3c4c57119c80d9c8c Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 13:18:45 +0200 Subject: [PATCH 09/29] Corrected Symfony docs link --- docs/client.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/client.md b/docs/client.md index cb11265..d6a07dc 100644 --- a/docs/client.md +++ b/docs/client.md @@ -12,7 +12,7 @@ * [Usage](#usage) * [Creating client instance](#creating-client-instance) * [Using with Guzzle library](#using-with-guzzle-library) - * [Using with Symfony HTTP Client)](#using-client-with-symfony-http-client) + * [Using with Symfony HTTP Client)](#using-with-symfony-http-client) * [`Params` - passing method arguments](params.md) * [`Result` - accessing response data](response.md) * [Exceptions](exceptions.md) From 7811856c263d8b45cd5caa0d684772b7fe7c5311 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 13:38:54 +0200 Subject: [PATCH 10/29] Updated usage examples --- docs/examples/config.md | 9 +++++---- docs/examples/details.md | 9 +++++---- docs/examples/find.md | 9 +++++---- docs/examples/nearby.md | 9 +++++---- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/docs/examples/config.md b/docs/examples/config.md index cfea58b..ff9d9e0 100644 --- a/docs/examples/config.md +++ b/docs/examples/config.md @@ -25,13 +25,12 @@ use OlzaLogistic\PpApi\Client\Client as PpApiClient; use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; +// Configure with real URL and token $apiToken = ''; $apiUrl = 'https://...'; -// Using Guzzle HTTP client -$httpClient = \GuzzleHttp\Client(); -$requestFactory = \GuzzleHttp\Psr7\RequestFactory(); - +// Construct instance of API Client +// See docs for details about HTTP client and request factory $client = PpApiClient::useApi($apiUrl) ->withAccessToken($apiToken) ->withHttpClient($httpClient) @@ -39,9 +38,11 @@ $client = PpApiClient::useApi($apiUrl) ->throwOnError() ->build(); +// Prepare request params $params = Params::create() ->withCountry(Country::CZECHIA); +// Call API method $apiResponse = $client->config($params); print_r($apiResponse); diff --git a/docs/examples/details.md b/docs/examples/details.md index da66a62..acadb21 100644 --- a/docs/examples/details.md +++ b/docs/examples/details.md @@ -26,13 +26,12 @@ use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; use OlzaLogistic\PpApi\Client\Model\Spedition; +// Configure with real URL and token $apiToken = ''; $apiUrl = 'https://...'; -// Using Guzzle HTTP client -$httpClient = \GuzzleHttp\Client(); -$requestFactory = \GuzzleHttp\Psr7\RequestFactory(); - +// Construct instance of API Client +// See docs for details about HTTP client and request factory $client = PpApiClient::useApi($apiUrl) ->withAccessToken($apiToken) ->withHttpClient($httpClient) @@ -40,11 +39,13 @@ $client = PpApiClient::useApi($apiUrl) ->throwOnError() ->build(); +// Prepare request params $params = Params::create() ->withCountry(Country::CZECHIA) ->withSpedition(Spedition::PACKETA_IPP) ->withSpeditionId('135'); +// Call API method $apiResponse = $client->details($params); print_r($apiResponse); diff --git a/docs/examples/find.md b/docs/examples/find.md index 65939d0..b2b8907 100644 --- a/docs/examples/find.md +++ b/docs/examples/find.md @@ -26,13 +26,12 @@ use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; use OlzaLogistic\PpApi\Client\Model\Spedition; +// Configure with real URL and token $apiToken = ''; $apiUrl = 'https://...'; -// Using Guzzle HTTP client -$httpClient = \GuzzleHttp\Client(); -$requestFactory = \GuzzleHttp\Psr7\RequestFactory(); - +// Construct instance of API Client +// See docs for details about HTTP client and request factory $client = PpApiClient::useApi($apiUrl) ->withAccessToken($apiToken) ->withHttpClient($httpClient) @@ -40,6 +39,7 @@ $client = PpApiClient::useApi($apiUrl) ->throwOnError() ->build(); +// Prepare request params $params = Params::create() ->withCountry(Country::CZECHIA) ->withSpeditions([ @@ -47,6 +47,7 @@ $params = Params::create() Spedition::PACKETA_EPP_SPEEDY_PP, ]); +// Call API method $apiResponse = $client->find($params); print_r($apiResponse); diff --git a/docs/examples/nearby.md b/docs/examples/nearby.md index 3479ad9..6178055 100644 --- a/docs/examples/nearby.md +++ b/docs/examples/nearby.md @@ -26,13 +26,12 @@ use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; use OlzaLogistic\PpApi\Client\Model\Spedition; +// Configure with real URL and token $apiToken = ''; $apiUrl = 'https://...'; -// Using Guzzle HTTP client -$httpClient = \GuzzleHttp\Client(); -$requestFactory = \GuzzleHttp\Psr7\RequestFactory(); - +// Construct instance of API Client +// See docs for details about HTTP client and request factory $client = PpApiClient::useApi($apiUrl) ->withAccessToken($apiToken) ->withHttpClient($httpClient) @@ -40,6 +39,7 @@ $client = PpApiClient::useApi($apiUrl) ->throwOnError() ->build(); +// Prepare request params $lat = 50.087; $long = 14.421; $params = Params::create() @@ -47,6 +47,7 @@ $params = Params::create() ->withSpedition(Spedition::PACKETA_IPP) ->withLocation($lat, $long); +// Call API method $apiResponse = $client->nearby($params); print_r($apiResponse); From 1855ac9928279ce9e4d53190332aed9c400a9c1c Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 13:39:45 +0200 Subject: [PATCH 11/29] Updated usage examples --- docs/examples/config.md | 4 ++-- docs/examples/details.md | 4 ++-- docs/examples/find.md | 4 ++-- docs/examples/nearby.md | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/examples/config.md b/docs/examples/config.md index ff9d9e0..7eb992d 100644 --- a/docs/examples/config.md +++ b/docs/examples/config.md @@ -33,8 +33,8 @@ $apiUrl = 'https://...'; // See docs for details about HTTP client and request factory $client = PpApiClient::useApi($apiUrl) ->withAccessToken($apiToken) - ->withHttpClient($httpClient) - ->withRequestFactory($requestFactory) + ->withHttpClient(...) + ->withRequestFactory(...) ->throwOnError() ->build(); diff --git a/docs/examples/details.md b/docs/examples/details.md index acadb21..4a455b1 100644 --- a/docs/examples/details.md +++ b/docs/examples/details.md @@ -34,8 +34,8 @@ $apiUrl = 'https://...'; // See docs for details about HTTP client and request factory $client = PpApiClient::useApi($apiUrl) ->withAccessToken($apiToken) - ->withHttpClient($httpClient) - ->withRequestFactory($requestFactory) + ->withHttpClient(...) + ->withRequestFactory(...) ->throwOnError() ->build(); diff --git a/docs/examples/find.md b/docs/examples/find.md index b2b8907..426f137 100644 --- a/docs/examples/find.md +++ b/docs/examples/find.md @@ -34,8 +34,8 @@ $apiUrl = 'https://...'; // See docs for details about HTTP client and request factory $client = PpApiClient::useApi($apiUrl) ->withAccessToken($apiToken) - ->withHttpClient($httpClient) - ->withRequestFactory($requestFactory) + ->withHttpClient(...) + ->withRequestFactory(...) ->throwOnError() ->build(); diff --git a/docs/examples/nearby.md b/docs/examples/nearby.md index 6178055..1bb4360 100644 --- a/docs/examples/nearby.md +++ b/docs/examples/nearby.md @@ -34,8 +34,8 @@ $apiUrl = 'https://...'; // See docs for details about HTTP client and request factory $client = PpApiClient::useApi($apiUrl) ->withAccessToken($apiToken) - ->withHttpClient($httpClient) - ->withRequestFactory($requestFactory) + ->withHttpClient(...) + ->withRequestFactory(...) ->throwOnError() ->build(); From c68cfa8b2cabd80679b4e1953e8a7d58df3317f1 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 13:41:23 +0200 Subject: [PATCH 12/29] Updated usage examples --- docs/examples/config.md | 8 ++------ docs/examples/details.md | 8 ++------ docs/examples/find.md | 8 ++------ docs/examples/nearby.md | 8 ++------ 4 files changed, 8 insertions(+), 24 deletions(-) diff --git a/docs/examples/config.md b/docs/examples/config.md index 7eb992d..f8b4e81 100644 --- a/docs/examples/config.md +++ b/docs/examples/config.md @@ -25,14 +25,10 @@ use OlzaLogistic\PpApi\Client\Client as PpApiClient; use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; -// Configure with real URL and token -$apiToken = ''; -$apiUrl = 'https://...'; - // Construct instance of API Client // See docs for details about HTTP client and request factory -$client = PpApiClient::useApi($apiUrl) - ->withAccessToken($apiToken) +$client = PpApiClient::useApi('') + ->withAccessToken('') ->withHttpClient(...) ->withRequestFactory(...) ->throwOnError() diff --git a/docs/examples/details.md b/docs/examples/details.md index 4a455b1..959cabd 100644 --- a/docs/examples/details.md +++ b/docs/examples/details.md @@ -26,14 +26,10 @@ use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; use OlzaLogistic\PpApi\Client\Model\Spedition; -// Configure with real URL and token -$apiToken = ''; -$apiUrl = 'https://...'; - // Construct instance of API Client // See docs for details about HTTP client and request factory -$client = PpApiClient::useApi($apiUrl) - ->withAccessToken($apiToken) +$client = PpApiClient::useApi('') + ->withAccessToken('') ->withHttpClient(...) ->withRequestFactory(...) ->throwOnError() diff --git a/docs/examples/find.md b/docs/examples/find.md index 426f137..e5ad633 100644 --- a/docs/examples/find.md +++ b/docs/examples/find.md @@ -26,14 +26,10 @@ use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; use OlzaLogistic\PpApi\Client\Model\Spedition; -// Configure with real URL and token -$apiToken = ''; -$apiUrl = 'https://...'; - // Construct instance of API Client // See docs for details about HTTP client and request factory -$client = PpApiClient::useApi($apiUrl) - ->withAccessToken($apiToken) +$client = PpApiClient::useApi('') + ->withAccessToken('') ->withHttpClient(...) ->withRequestFactory(...) ->throwOnError() diff --git a/docs/examples/nearby.md b/docs/examples/nearby.md index 1bb4360..9bbbd45 100644 --- a/docs/examples/nearby.md +++ b/docs/examples/nearby.md @@ -26,14 +26,10 @@ use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; use OlzaLogistic\PpApi\Client\Model\Spedition; -// Configure with real URL and token -$apiToken = ''; -$apiUrl = 'https://...'; - // Construct instance of API Client // See docs for details about HTTP client and request factory -$client = PpApiClient::useApi($apiUrl) - ->withAccessToken($apiToken) +$client = PpApiClient::useApi('') + ->withAccessToken('') ->withHttpClient(...) ->withRequestFactory(...) ->throwOnError() From 69d0b84e34f77f04adbbafa7082a61f056e2ecb3 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 14:11:02 +0200 Subject: [PATCH 13/29] Updated usage examples --- docs/examples/config.md | 14 +++++++------- docs/examples/details.md | 14 +++++++------- docs/examples/find.md | 15 ++++++++------- docs/examples/nearby.md | 14 +++++++------- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/docs/examples/config.md b/docs/examples/config.md index f8b4e81..f333146 100644 --- a/docs/examples/config.md +++ b/docs/examples/config.md @@ -21,18 +21,18 @@ ## Getting API runtime details for given country ```php -use OlzaLogistic\PpApi\Client\Client as PpApiClient; +use OlzaLogistic\PpApi\Client\Client; use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; // Construct instance of API Client // See docs for details about HTTP client and request factory -$client = PpApiClient::useApi('') - ->withAccessToken('') - ->withHttpClient(...) - ->withRequestFactory(...) - ->throwOnError() - ->build(); +$client = Client::useApi('') + ->withAccessToken('') + ->withHttpClient(...) + ->withRequestFactory(...) + ->throwOnError() + ->build(); // Prepare request params $params = Params::create() diff --git a/docs/examples/details.md b/docs/examples/details.md index 959cabd..dc807d5 100644 --- a/docs/examples/details.md +++ b/docs/examples/details.md @@ -21,19 +21,19 @@ ## Retrieving pickup point details ```php -use OlzaLogistic\PpApi\Client\Client as PpApiClient; +use OlzaLogistic\PpApi\Client\Client; use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; use OlzaLogistic\PpApi\Client\Model\Spedition; // Construct instance of API Client // See docs for details about HTTP client and request factory -$client = PpApiClient::useApi('') - ->withAccessToken('') - ->withHttpClient(...) - ->withRequestFactory(...) - ->throwOnError() - ->build(); +$client = Client::useApi('') + ->withAccessToken('') + ->withHttpClient(...) + ->withRequestFactory(...) + ->throwOnError() + ->build(); // Prepare request params $params = Params::create() diff --git a/docs/examples/find.md b/docs/examples/find.md index e5ad633..586674f 100644 --- a/docs/examples/find.md +++ b/docs/examples/find.md @@ -21,19 +21,20 @@ ## Finds Pickup Points in given country ```php -use OlzaLogistic\PpApi\Client\Client as PpApiClient; +use OlzaLogistic\PpApi\Client\Client; use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; use OlzaLogistic\PpApi\Client\Model\Spedition; // Construct instance of API Client // See docs for details about HTTP client and request factory -$client = PpApiClient::useApi('') - ->withAccessToken('') - ->withHttpClient(...) - ->withRequestFactory(...) - ->throwOnError() - ->build(); +$client = Client::useApi('') + ->withAccessToken('') + ->withHttpClient(...) + ->withRequestFactory(...) + ->throwOnError() + ->build(); + // Prepare request params $params = Params::create() diff --git a/docs/examples/nearby.md b/docs/examples/nearby.md index 9bbbd45..da9be3a 100644 --- a/docs/examples/nearby.md +++ b/docs/examples/nearby.md @@ -21,19 +21,19 @@ ## Finding pickup points around given location ```php -use OlzaLogistic\PpApi\Client\Client as PpApiClient; +use OlzaLogistic\PpApi\Client\Client; use OlzaLogistic\PpApi\Client\Params; use OlzaLogistic\PpApi\Client\Model\Country; use OlzaLogistic\PpApi\Client\Model\Spedition; // Construct instance of API Client // See docs for details about HTTP client and request factory -$client = PpApiClient::useApi('') - ->withAccessToken('') - ->withHttpClient(...) - ->withRequestFactory(...) - ->throwOnError() - ->build(); +$client = Client::useApi('') + ->withAccessToken('') + ->withHttpClient(...) + ->withRequestFactory(...) + ->throwOnError() + ->build(); // Prepare request params $lat = 50.087; From 8c49cde3f563c889513abc00978c649de960a7a1 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 18:25:24 +0200 Subject: [PATCH 14/29] Corrected example in Symfony related chapter --- docs/client.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/client.md b/docs/client.md index d6a07dc..4d866d2 100644 --- a/docs/client.md +++ b/docs/client.md @@ -145,7 +145,7 @@ composer require symfony/http-client nyholm/psr7 Then, create an instance of the `Client` class: ```php -$httpClient = new \GuzzleHttp\Client(); +$httpClient = new \Symfony\Component\HttpClient\Psr18Client(); $requestFactory = new \Nyholm\Psr7\Factory\Psr17Factory(); $client = PpApiClient::useApi($url) From 411d17bd58ba9818cb2b3ed5c22a07131373708b Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Thu, 19 Oct 2023 18:25:32 +0200 Subject: [PATCH 15/29] Corrected version in CHANGELOG --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index fcc5c26..8b08734 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ Olza Logistic's Pickup Point API Client PHP library. # Changelog -* v2.0.0-dev (YYYY-MM-DD) +* v1.3.0-dev (YYYY-MM-DD) * Added `withHttpClient()` and `withRequestFactory()` methods to `Client` builder. * Removed `withGuzzleHttpClient()` as Guzzle no longer needs special treatment. * Removed `withSymfonyHttpClient()`. See docs on how to use Symfony HTTP client. From a859a66dd52436798d2185b015a01819c5d23dda Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 08:42:56 +0200 Subject: [PATCH 16/29] Added Arrayable contract --- src/Contracts/ArrayableContract.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/Contracts/ArrayableContract.php diff --git a/src/Contracts/ArrayableContract.php b/src/Contracts/ArrayableContract.php new file mode 100644 index 0000000..089d115 --- /dev/null +++ b/src/Contracts/ArrayableContract.php @@ -0,0 +1,22 @@ + + * @copyright 2021-2023 DevelArt + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link https://github.com/develart-projects/pickup-points-api-client/ + */ + +namespace OlzaLogistic\PpApi\Client\Contracts; + +interface ArrayableContract +{ + /** + * Returns array representation of the object. + */ + public function toArray(): array; + +} // end of class From 3134a880f2b3de0e2a23036bc593d0b62e941e93 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 08:43:14 +0200 Subject: [PATCH 17/29] Data object now implements Arrayable --- src/Data.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Data.php b/src/Data.php index 64e3d34..4a4740a 100644 --- a/src/Data.php +++ b/src/Data.php @@ -12,11 +12,15 @@ namespace OlzaLogistic\PpApi\Client; +use OlzaLogistic\PpApi\Client\Contracts\ArrayableContract; + /** * Immutable object representing elements of "data" node of the API response. */ -class Data extends \ArrayObject +class Data extends \ArrayObject implements ArrayableContract { - // empty - -} // end of class + public function toArray(): array + { + return $this->getArrayCopy(); + } +} From 2cc120f7b6e78c36754065ad7c497eed648a022b Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 08:43:29 +0200 Subject: [PATCH 18/29] ConfigData object now implements Arrayable --- src/ConfigData.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/ConfigData.php b/src/ConfigData.php index 4d97868..3f71531 100644 --- a/src/ConfigData.php +++ b/src/ConfigData.php @@ -78,4 +78,17 @@ public function addSpedition(Spedition $spedition): self /* ****************************************************************************************** */ + public function toArray(): array + { + $result = []; + foreach ($this->config as $key => $value) { + $result['config'][$key] = $value; + } + foreach ($this->speditions as $key => $value) { + $result['speditions'][$key] = $value->toArray(); + } + + return $result; + } + } // end of class From eb2f07433b479a331cd8a46833f60d0ae15d4228 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 08:46:36 +0200 Subject: [PATCH 19/29] The `Spedition::getLabel()` now returns spedition code if no label was retuned by API. --- src/Model/Spedition.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Model/Spedition.php b/src/Model/Spedition.php index 877bde9..37c31fd 100644 --- a/src/Model/Spedition.php +++ b/src/Model/Spedition.php @@ -101,7 +101,7 @@ public function setCode(string $code): self /* ****************************************************************************************** */ - protected string $label; + protected ?string $label = null; /** * Returns spedition's label (name). @@ -110,7 +110,9 @@ public function setCode(string $code): self */ public function getLabel(): string { - return $this->label; + return $this->label !== null + ? $this->label + : $this->getCode(); } /** From 933ecd9e5fc3c220e96f219a0272f3b7cf269886 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 08:46:52 +0200 Subject: [PATCH 20/29] Spedition object implements Arrayable now --- src/Model/Spedition.php | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Model/Spedition.php b/src/Model/Spedition.php index 37c31fd..cb807e4 100644 --- a/src/Model/Spedition.php +++ b/src/Model/Spedition.php @@ -9,9 +9,12 @@ * @license http://www.opensource.org/licenses/mit-license.php MIT * @link https://github.com/develart-projects/pickup-points-api-client/ */ + namespace OlzaLogistic\PpApi\Client\Model; -class Spedition +use OlzaLogistic\PpApi\Client\Contracts\ArrayableContract; + +class Spedition implements ArrayableContract { public const COLETARIA = 'zas-col'; public const CZECH_POST = 'cp-bal'; @@ -178,11 +181,10 @@ final protected function __construct() {} /* ****************************************************************************************** */ - public const KEY_COUNTRY = 'country'; - public const KEY_SPEDITION = 'spedition'; - public const KEY_CODE = 'code'; - public const KEY_LABEL = 'label'; - public const KEY_NAMES = 'names'; + public const KEY_CODE = 'code'; + public const KEY_ENABLED = 'enabled'; + public const KEY_LABEL = 'label'; + public const KEY_NAMES = 'names'; /** * Returns instance of Spedition, instantiated using data from provided source array. @@ -206,4 +208,16 @@ public static function fromApiResponse(array $spedData): self return $spedition; } + /* ****************************************************************************************** */ + + public function toArray(): array + { + return [ + static::KEY_CODE => $this->getCode(), + static::KEY_ENABLED => $this->isEnabled(), + static::KEY_LABEL => $this->getLabel(), + static::KEY_NAMES => $this->getNames(), + ]; + } + } // end of class From f3823c160d2eac82a89203b5d30d9267dc0489f1 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 08:48:07 +0200 Subject: [PATCH 21/29] Result object implements Arrayable now --- src/Result.php | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/Result.php b/src/Result.php index 368a5b2..1071d09 100644 --- a/src/Result.php +++ b/src/Result.php @@ -12,6 +12,7 @@ namespace OlzaLogistic\PpApi\Client; +use OlzaLogistic\PpApi\Client\Contracts\ArrayableContract; use OlzaLogistic\PpApi\Client\Exception\InvalidResponseStructureException; use OlzaLogistic\PpApi\Client\Model\PickupPoint; use OlzaLogistic\PpApi\Client\Model\Spedition; @@ -20,7 +21,7 @@ /** * Immutable object representing API action response. */ -class Result +class Result implements ArrayableContract { /** * Returns instance of Result preconfigured to indicate success. @@ -237,9 +238,6 @@ protected function __construct(bool $success) */ protected bool $success = false; - /** - * Returns TRUE if result relates to successful action's response, FALSE otherwise. - */ public function success(): bool { return $this->success; @@ -263,9 +261,6 @@ protected function setSuccess(bool $success): self */ protected int $code = 0; - /** - * Returns API code associated with the response. - */ public function getCode(): int { return $this->code; @@ -284,9 +279,6 @@ protected function setCode(int $apiCode): self protected string $message = ''; - /** - * Returns message associated with the response. - */ public function getMessage(): string { return $this->message; @@ -305,9 +297,6 @@ protected function setMessage(string $message): self protected ?Data $data = null; - /** - * Returns data associated with the response. - */ public function getData(): ?Data { return $this->data; @@ -324,4 +313,31 @@ protected function setData(?Data $data): self return $this; } + /* ****************************************************************************************** */ + + public function toArray(): array + { + $result = [ + 'success' => $this->success(), + 'code' => $this->getCode(), + 'message' => $this->getMessage(), + ]; + + $data = $this->getData(); + if ($data instanceof ArrayableContract) { + $data = $data->toArray(); + } else if ($data instanceof \Stringable) { + $data = $data->__toString(); + } else if ($data instanceof \ArrayObject) { + $data = $data->getArrayCopy(); + } else if (is_object($data)) { + $cls = \get_class($data); + $data = "<{$cls}>"; + } + + $result['data'] = $data; + + return $result; + } + } // end of class From 0e606f6f75ccc3f2837f61b1fd64e796382f846f Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 12:47:05 +0200 Subject: [PATCH 22/29] Data object implements Arrayable contact --- src/Data.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Data.php b/src/Data.php index 4a4740a..91e1c30 100644 --- a/src/Data.php +++ b/src/Data.php @@ -21,6 +21,21 @@ class Data extends \ArrayObject implements ArrayableContract { public function toArray(): array { - return $this->getArrayCopy(); + $result = []; + foreach($this as $key => $value) { + if ($value instanceof ArrayableContract) { + $value = $value->toArray(); + } else if ($value instanceof \Stringable) { + $value = $value->__toString(); + } else if ($value instanceof \ArrayObject) { + $value = $value->getArrayCopy(); + } else if (is_object($value)) { + $cls = \get_class($value); + $value = "<{$cls}>"; + } + $result[$key] = $value; + } + return $result; } + } From 1458ed48b8282a02530292ac3a569a8ddc67530f Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 12:47:23 +0200 Subject: [PATCH 23/29] PickupPoint class implements Arrayable contact --- src/Model/PickupPoint.php | 66 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/Model/PickupPoint.php b/src/Model/PickupPoint.php index f887e5c..068c62f 100644 --- a/src/Model/PickupPoint.php +++ b/src/Model/PickupPoint.php @@ -12,7 +12,9 @@ namespace OlzaLogistic\PpApi\Client\Model; -class PickupPoint +use OlzaLogistic\PpApi\Client\Contracts\ArrayableContract; + +class PickupPoint implements ArrayableContract { /* ****************************************************************************************** */ @@ -1007,4 +1009,66 @@ public static function fromApiResponse(array $ppData): self return $pp; } + /* ****************************************************************************************** */ + + public function toArray(): array + { + return [ + static::KEY_ID => $this->getSpeditionId(), + static::KEY_SPEDITION => $this->getSpedition(), + static::KEY_GROUP_NAME => $this->getNames(), + static::KEY_GROUP_ADDRESS => [ + static::KEY_FULL_ADDRESS => $this->getFullAddress(), + static::KEY_STREET => $this->getStreet(), + static::KEY_ZIP => $this->getZip(), + static::KEY_CITY => $this->getCity(), + static::KEY_COUNTY => $this->getCounty(), + static::KEY_COUNTRY => $this->getCountry(), + ], + + static::KEY_GROUP_CONTACTS => [ + static::KEY_PHONE => $this->getPhone(), + static::KEY_EMAIL => $this->getEmail(), + ], + + static::KEY_GROUP_HOURS => [ + static::KEY_OPEN_247 => $this->isOpen247(), + static::KEY_MONDAY => [ + static::KEY_HOURS => $this->getMondayHours(), + static::KEY_BREAK => $this->getMondayBreak(), + ], + static::KEY_TUESDAY => [ + static::KEY_HOURS => $this->getTuesdayHours(), + static::KEY_BREAK => $this->getTuesdayBreak(), + ], + static::KEY_WEDNESDAY => [ + static::KEY_HOURS => $this->getWednesdayHours(), + static::KEY_BREAK => $this->getWednesdayBreak(), + ], + static::KEY_THURSDAY => [ + static::KEY_HOURS => $this->getThursdayHours(), + static::KEY_BREAK => $this->getThursdayBreak(), + ], + static::KEY_FRIDAY => [ + static::KEY_HOURS => $this->getFridayHours(), + static::KEY_BREAK => $this->getFridayBreak(), + ], + static::KEY_SATURDAY => [ + static::KEY_HOURS => $this->getSaturdayHours(), + static::KEY_BREAK => $this->getSaturdayBreak(), + ], + static::KEY_SUNDAY => [ + static::KEY_HOURS => $this->getSundayHours(), + static::KEY_BREAK => $this->getSundayBreak(), + ], + ], + + static::KEY_GROUP_LOCATION => [ + static::KEY_LATITUDE => $this->getLatitude(), + static::KEY_LONGITUDE => $this->getLongitude(), + ], + + ]; + } + } // end of class From f0590b77f41aebfdb9bd5ca830c11b541533595b Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 13:02:35 +0200 Subject: [PATCH 24/29] Updated examples --- docs/api.md | 58 ++++++---------------------------------- docs/examples/config.md | 2 +- docs/examples/details.md | 2 +- docs/examples/find.md | 5 ++-- docs/examples/nearby.md | 5 ++-- 5 files changed, 16 insertions(+), 56 deletions(-) diff --git a/docs/api.md b/docs/api.md index d05fedb..6dcc6c5 100644 --- a/docs/api.md +++ b/docs/api.md @@ -44,14 +44,9 @@ Required arguments: * `country` - **(required)** country code (use Country::xxx consts) -```php -$params = Params::create() - ->withCountry(Country::CZECH_REPUBLIC); -$result = $client->config($params); -$configItems = $result->getData(); -... -... -``` +[See usage example](examples/config.md) + +--- ### `details(Params $params): Result;` @@ -63,17 +58,7 @@ Required arguments: * `spedition` - **(required)** one (string) or more (array of strings) * `id` - **(required)** Pickup point identifier -```php -$params = Params::create() - ->withCountry(Country::CZECH_REPUBLIC) - ->withSpedition(Spedition::PACKETA_IPP) - ->withSpeditionId('12345'); -$result = $client->details($params); -$items = $result->getData(); -foreach($items as $pp) { - echo $pp->getSpeditionId() . PHP_EOL; -} -... +[See usage example](examples/details.md) ... ``` @@ -99,17 +84,9 @@ Optional arguments: suffices.** * `limit` - The maximum number of items to be returned. The default is to return all matching items. -```php -$params = Params::create() - ->withCountry(Country::CZECH_REPUBLIC) - ->withSpedition(Spedition::PACKETA_IPP); -$result = $client->find($params); -$items = $result->getData() ?? []; -foreach($items as $pp) { - echo $pp->getSpeditionId() . PHP_EOL; -} -... -``` +[See usage example](examples/find.md) + +--- ### `nearby(Params $params): Result;` @@ -123,23 +100,4 @@ Required arguments: * `coords` - **[required]** geographic coordinates to search near. The value should be a string in the format `latitude,longitude`. -![Note](note.png) The `coords` argument description seems to have been copied erroneously from -the `search` -argument in the previous method. It should specify the format for providing geographic coordinates -rather than matching against pickup point attributes. - -```php -$lat = 50.087; -$long = 14.421; -$params = Params::create() - ->withCountry(Country::CZECH_REPUBLIC) - ->withSpedition(Spedition::PACKETA_IPP) - ->withLocation($lat, $long); -$result = $client->nearby($params); -/** @var ?Data $data */ -$items = $result->getData() ?? []; -foreach($items as $pp) { - echo $pp->getSpeditionId() . PHP_EOL; -} -... -``` +[See usage example](examples/nearby.md) diff --git a/docs/examples/config.md b/docs/examples/config.md index f333146..7c15bd1 100644 --- a/docs/examples/config.md +++ b/docs/examples/config.md @@ -41,5 +41,5 @@ $params = Params::create() // Call API method $apiResponse = $client->config($params); -print_r($apiResponse); +var_dump($apiResponse->toArray()); ``` diff --git a/docs/examples/details.md b/docs/examples/details.md index dc807d5..d05f387 100644 --- a/docs/examples/details.md +++ b/docs/examples/details.md @@ -44,5 +44,5 @@ $params = Params::create() // Call API method $apiResponse = $client->details($params); -print_r($apiResponse); +var_dump($apiResponse->toArray()); ``` diff --git a/docs/examples/find.md b/docs/examples/find.md index 586674f..4312303 100644 --- a/docs/examples/find.md +++ b/docs/examples/find.md @@ -42,10 +42,11 @@ $params = Params::create() ->withSpeditions([ Spedition::PACKETA_IPP, Spedition::PACKETA_EPP_SPEEDY_PP, - ]); + ]) + ->withLimit(3); // Call API method $apiResponse = $client->find($params); -print_r($apiResponse); +var_dump($apiResponse->toArray()); ``` diff --git a/docs/examples/nearby.md b/docs/examples/nearby.md index da9be3a..4866a7c 100644 --- a/docs/examples/nearby.md +++ b/docs/examples/nearby.md @@ -41,10 +41,11 @@ $long = 14.421; $params = Params::create() ->withCountry(Country::CZECHIA) ->withSpedition(Spedition::PACKETA_IPP) - ->withLocation($lat, $long); + ->withLocation($lat, $long) + ->withLimit(5); // Call API method $apiResponse = $client->nearby($params); -print_r($apiResponse); +var_dump($apiResponse->toArray); ``` From ba562637fe2b54cdc26f8f2a07d1b06074aa5bde Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 13:03:19 +0200 Subject: [PATCH 25/29] Updated nearby() docs to cover "limit" parameter --- docs/api.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/api.md b/docs/api.md index 6dcc6c5..e7b81fb 100644 --- a/docs/api.md +++ b/docs/api.md @@ -42,7 +42,7 @@ carrier-dependent methods. Required arguments: -* `country` - **(required)** country code (use Country::xxx consts) +* `country` - **(required)** country code (use `Country::xxx` consts) [See usage example](examples/config.md) @@ -60,8 +60,7 @@ Required arguments: [See usage example](examples/details.md) -... -``` +--- ### `find(Params $params): Result;` @@ -82,7 +81,8 @@ Optional arguments: * `payments` - A list of payment types (see `PaymentType::*`) that a pickup point must support to be included in the returned dataset. **NOTE: payment types are `OR`ed, so supporting just one suffices.** -* `limit` - The maximum number of items to be returned. The default is to return all matching items. +* `limit` - The maximum number of items to be returned. The default is to return all matching items + (API cap limit may apply). [See usage example](examples/find.md) @@ -99,5 +99,7 @@ Required arguments: strings). * `coords` - **[required]** geographic coordinates to search near. The value should be a string in the format `latitude,longitude`. +* `limit` - The maximum number of items to be returned. The default is to return all matching + items (API cap limit may apply). [See usage example](examples/nearby.md) From 2341fb6242f4830893de360814d910797483a1e5 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 13:04:17 +0200 Subject: [PATCH 26/29] Updated CHANGELOG --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 8b08734..0f2d6eb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,9 @@ Olza Logistic's Pickup Point API Client PHP library. * Removed `withPsrClient()`. Use `withHttpClient()` and `withRequestClient()` instead. * Attempt to modify sealed client now throws `ClientAlreadyInitializedException`. * Attempt to access not sealed client now throws `ClientNotSealedException`. + * Improved construction of `Config` response object. + * The `Spedition::getLabel()` now returns spedition code if no label is returned by API. + * Implemented `Arrayable` contact (`toArray()`) for response data classes. * Updated library documentation. From 7807e1ed165b775e93582ce6f7d446514515c1e7 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 13:26:41 +0200 Subject: [PATCH 27/29] Updated tests --- CHANGES.md | 1 + tests/Util/PickupPointResponseGenerator.php | 4 ++-- tests/tests/Model/PickupPointTest.php | 25 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0f2d6eb..ecbcb20 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ Olza Logistic's Pickup Point API Client PHP library. * Improved construction of `Config` response object. * The `Spedition::getLabel()` now returns spedition code if no label is returned by API. * Implemented `Arrayable` contact (`toArray()`) for response data classes. + * Updated tests. * Updated library documentation. diff --git a/tests/Util/PickupPointResponseGenerator.php b/tests/Util/PickupPointResponseGenerator.php index db33527..38aceb4 100644 --- a/tests/Util/PickupPointResponseGenerator.php +++ b/tests/Util/PickupPointResponseGenerator.php @@ -90,10 +90,10 @@ public function withContacts(?array $fields = null): self PP::KEY_EMAIL, ]; - if (\array_key_exists(PP::KEY_PHONE, $fields)) { + if (\in_array(PP::KEY_PHONE, $fields)) { $this->data[ PP::KEY_GROUP_CONTACTS ][ PP::KEY_PHONE ] = $this->getRandomString('phone'); } - if (\array_key_exists(PP::KEY_EMAIL, $fields)) { + if (\in_array(PP::KEY_EMAIL, $fields)) { $this->data[ PP::KEY_GROUP_CONTACTS ][ PP::KEY_EMAIL ] = $this->getRandomString('email'); } diff --git a/tests/tests/Model/PickupPointTest.php b/tests/tests/Model/PickupPointTest.php index eb63064..1d58609 100644 --- a/tests/tests/Model/PickupPointTest.php +++ b/tests/tests/Model/PickupPointTest.php @@ -11,9 +11,11 @@ namespace OlzaLogistic\PpApi\Client\Tests\Model; +use OlzaLogistic\PpApi\Client\Contracts\ArrayableContract; use OlzaLogistic\PpApi\Client\Model\PickupPoint as PP; use OlzaLogistic\PpApi\Client\Tests\BaseTestCase; use OlzaLogistic\PpApi\Client\Tests\Util\PickupPointResponseGenerator; +use PHPUnit\Framework\Assert; class PickupPointTest extends BaseTestCase { @@ -59,4 +61,27 @@ protected function assertModelMatchesData(array $expected, PP $pp): void } } + /* ****************************************************************************************** */ + + public function testArrayable(): void + { + $data = PickupPointResponseGenerator::data() + ->withAll() + ->get(); + $pp = PP::fromApiResponse($data); + + $expected = $data; + unset($expected[PP::KEY_GROUP_SERVICES]); + $expected[PP::KEY_GROUP_LOCATION][PP::KEY_LATITUDE] + = \strval($expected[PP::KEY_GROUP_LOCATION][PP::KEY_LATITUDE]); + $expected[PP::KEY_GROUP_LOCATION][PP::KEY_LONGITUDE] + = \strval($expected[PP::KEY_GROUP_LOCATION][PP::KEY_LONGITUDE]); + Assert::assertInstanceof(ArrayableContract::class, $pp); + + $actual = $pp->toArray(); + unset($actual[PP::KEY_GROUP_HOURS]); + $this->addWarning('Hours are not tested'); + Assert::assertEquals($expected, $actual); + } + } // end of class From 1d3d8d9ea7434994c1f6ad738850f3b46832e083 Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 13:26:41 +0200 Subject: [PATCH 28/29] Updated tests --- CHANGES.md | 1 + tests/Util/PickupPointResponseGenerator.php | 4 +- tests/tests/Client/ResultTest.php | 51 +++++++++++++++++++++ tests/tests/Model/PickupPointTest.php | 25 ++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0f2d6eb..ecbcb20 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ Olza Logistic's Pickup Point API Client PHP library. * Improved construction of `Config` response object. * The `Spedition::getLabel()` now returns spedition code if no label is returned by API. * Implemented `Arrayable` contact (`toArray()`) for response data classes. + * Updated tests. * Updated library documentation. diff --git a/tests/Util/PickupPointResponseGenerator.php b/tests/Util/PickupPointResponseGenerator.php index db33527..38aceb4 100644 --- a/tests/Util/PickupPointResponseGenerator.php +++ b/tests/Util/PickupPointResponseGenerator.php @@ -90,10 +90,10 @@ public function withContacts(?array $fields = null): self PP::KEY_EMAIL, ]; - if (\array_key_exists(PP::KEY_PHONE, $fields)) { + if (\in_array(PP::KEY_PHONE, $fields)) { $this->data[ PP::KEY_GROUP_CONTACTS ][ PP::KEY_PHONE ] = $this->getRandomString('phone'); } - if (\array_key_exists(PP::KEY_EMAIL, $fields)) { + if (\in_array(PP::KEY_EMAIL, $fields)) { $this->data[ PP::KEY_GROUP_CONTACTS ][ PP::KEY_EMAIL ] = $this->getRandomString('email'); } diff --git a/tests/tests/Client/ResultTest.php b/tests/tests/Client/ResultTest.php index 23d23a7..d2cf785 100644 --- a/tests/tests/Client/ResultTest.php +++ b/tests/tests/Client/ResultTest.php @@ -14,6 +14,7 @@ use OlzaLogistic\PpApi\Client\ApiResponse; use OlzaLogistic\PpApi\Client\Result; use OlzaLogistic\PpApi\Client\Tests\BaseTestCase; +use PHPUnit\Framework\Assert; class ResultTest extends BaseTestCase { @@ -110,5 +111,55 @@ public function isApiResponseValidDataProvider(): array /* ****************************************************************************************** */ + public function testArrayableSuccess(): void + { + $message = $this->getRandomString('msg'); + + $expected = [ + 'success' => true, + 'code' => 0, + 'message' => $message, + 'data' => null, + ]; + + $result = Result::asSuccess(); + $this->call($result, 'setMessage', [$message]); + $actual = $result->toArray(); + + Assert::assertEquals($expected, $actual); + } + + public function testArrayableError(): void + { + $message = $this->getRandomString('msg'); + $code = $this->getRandomInt(1, 255); + + $expected = [ + 'success' => false, + 'code' => $code, + 'message' => $message, + 'data' => null, + ]; + + $result = Result::asError(); + $this->call($result, 'setMessage', [$message]); + $this->call($result, 'setCode', [$code]); + $actual = $result->toArray(); + + Assert::assertEquals($expected, $actual); + } + + /** + * @return mixed + * @throws \ReflectionException + */ + public static function call(object $obj, string $methodName, array $args = []) + { + $reflection = new \ReflectionClass($obj); + $method = $reflection->getMethod($methodName); + $method->setAccessible(true); + + return $method->invokeArgs(\is_object($obj) ? $obj : null, $args); + } } // end of class diff --git a/tests/tests/Model/PickupPointTest.php b/tests/tests/Model/PickupPointTest.php index eb63064..1d58609 100644 --- a/tests/tests/Model/PickupPointTest.php +++ b/tests/tests/Model/PickupPointTest.php @@ -11,9 +11,11 @@ namespace OlzaLogistic\PpApi\Client\Tests\Model; +use OlzaLogistic\PpApi\Client\Contracts\ArrayableContract; use OlzaLogistic\PpApi\Client\Model\PickupPoint as PP; use OlzaLogistic\PpApi\Client\Tests\BaseTestCase; use OlzaLogistic\PpApi\Client\Tests\Util\PickupPointResponseGenerator; +use PHPUnit\Framework\Assert; class PickupPointTest extends BaseTestCase { @@ -59,4 +61,27 @@ protected function assertModelMatchesData(array $expected, PP $pp): void } } + /* ****************************************************************************************** */ + + public function testArrayable(): void + { + $data = PickupPointResponseGenerator::data() + ->withAll() + ->get(); + $pp = PP::fromApiResponse($data); + + $expected = $data; + unset($expected[PP::KEY_GROUP_SERVICES]); + $expected[PP::KEY_GROUP_LOCATION][PP::KEY_LATITUDE] + = \strval($expected[PP::KEY_GROUP_LOCATION][PP::KEY_LATITUDE]); + $expected[PP::KEY_GROUP_LOCATION][PP::KEY_LONGITUDE] + = \strval($expected[PP::KEY_GROUP_LOCATION][PP::KEY_LONGITUDE]); + Assert::assertInstanceof(ArrayableContract::class, $pp); + + $actual = $pp->toArray(); + unset($actual[PP::KEY_GROUP_HOURS]); + $this->addWarning('Hours are not tested'); + Assert::assertEquals($expected, $actual); + } + } // end of class From b4a25c5ee457080821b83c3ef74c9fabb901033d Mon Sep 17 00:00:00 2001 From: Marcin Orlowski Date: Fri, 20 Oct 2023 14:05:42 +0200 Subject: [PATCH 29/29] Simplified Result's toArray() --- src/Result.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Result.php b/src/Result.php index 1071d09..24dbfa9 100644 --- a/src/Result.php +++ b/src/Result.php @@ -326,13 +326,6 @@ public function toArray(): array $data = $this->getData(); if ($data instanceof ArrayableContract) { $data = $data->toArray(); - } else if ($data instanceof \Stringable) { - $data = $data->__toString(); - } else if ($data instanceof \ArrayObject) { - $data = $data->getArrayCopy(); - } else if (is_object($data)) { - $cls = \get_class($data); - $data = "<{$cls}>"; } $result['data'] = $data;