From fa89f75a729943c6265bdf760f95d306d2876277 Mon Sep 17 00:00:00 2001 From: Grzegorz Rola <grola@seostudio.pl> Date: Thu, 31 Jan 2019 15:49:21 +0100 Subject: [PATCH] Init --- .gitattributes | 15 ++ .gitignore | 5 + .gitlab-ci.yml | 6 + README.md | 6 +- changelog.txt | 2 + composer.json | 35 +++ phpunit-integration.xml | 28 +++ phpunit-unit.xml | 21 ++ src/ApiClient/CachedClient.php | 111 +++++++++ src/ApiClient/Client.php | 41 ++++ src/ApiClient/ClientFactory.php | 35 +++ src/ApiClient/ClientImplementation.php | 215 ++++++++++++++++++ src/ApiClient/RequestCacheInfoResolver.php | 139 +++++++++++ src/Request/AuthRequest.php | 53 +++++ .../Authentication/ConnectKeyInfoRequest.php | 28 +++ .../Authentication/ConnectKeyResetRequest.php | 23 ++ .../Authentication/RegisterRequest.php | 29 +++ src/Request/Authentication/TokenRequest.php | 26 +++ src/Request/BasicRequest.php | 54 +++++ src/Request/Cancel/PostCancelRequest.php | 39 ++++ src/Request/Fields/GetFieldsRequest.php | 45 ++++ src/Request/Label/PostLabelRequest.php | 36 +++ src/Request/Rate/PostRateRequest.php | 36 +++ src/Request/Request.php | 27 +++ .../Shipment/GetUserListShipmentRequest.php | 27 +++ src/Request/Shipment/PostShipmentRequest.php | 36 +++ .../ShippingPlan/PutShippingPlanRequest.php | 30 +++ .../ShippingServices/GetListRequest.php | 14 ++ .../ShippingServices/GetServiceRequest.php | 29 +++ .../GetSettingsRequest.php | 38 ++++ .../PostSettingsRequest.php | 30 +++ .../PutSettingsRequest.php | 36 +++ .../Test/GetSettingsTestRequest.php | 37 +++ src/Request/Status/GetStatusRequest.php | 49 ++++ .../Traits/SettingsItemRequestHelper.php | 28 +++ src/Request/Users/GetUserRequest.php | 28 +++ src/Response/ApiResponse.php | 35 +++ src/Response/AuthApiResponse.php | 14 ++ .../Authentication/ConnectKeyInfoResponse.php | 37 +++ .../ConnectKeyResetResponse.php | 22 ++ .../Authentication/RegisterResponse.php | 59 +++++ src/Response/Authentication/TokenResponse.php | 56 +++++ src/Response/Cancel/PostCancelResponse.php | 11 + .../Exception/EmptyMessageFromResponse.php | 19 ++ .../Exception/EmptyStatusFromResponse.php | 19 ++ .../TriedExtractDataFromErrorResponse.php | 19 ++ src/Response/Fields/GetFieldsResponse.php | 19 ++ src/Response/Label/PostLabelResponse.php | 20 ++ .../MaintenanceResponseContext.php | 50 ++++ src/Response/ProtectedResponse.php | 27 +++ src/Response/Rate/PostRateResponse.php | 31 +++ src/Response/RawResponse.php | 113 +++++++++ src/Response/Response.php | 43 ++++ .../GetListShipmentAdminContextResponse.php | 29 +++ .../Shipment/PostShipmentResponse.php | 30 +++ .../GetShippingServiceResponse.php | 20 ++ .../GetShippingServicesListResponse.php | 30 +++ .../GetSettingsResponse.php | 32 +++ .../Test/GetSettingsTestResponse.php | 36 +++ src/Response/Status/GetStatusResponse.php | 20 ++ src/Response/Traits/ApiResponseDecorator.php | 145 ++++++++++++ .../Traits/AuthApiResponseDecorator.php | 38 ++++ .../Traits/PagedListImplementation.php | 44 ++++ src/Response/Users/GetUserResponse.php | 20 ++ tests/docker-compose.yaml | 172 ++++++++++++++ tests/integration/bootstrap.php | 28 +++ tests/unit/bootstrap.php | 9 + 67 files changed, 2683 insertions(+), 1 deletion(-) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 changelog.txt create mode 100644 composer.json create mode 100644 phpunit-integration.xml create mode 100644 phpunit-unit.xml create mode 100644 src/ApiClient/CachedClient.php create mode 100644 src/ApiClient/Client.php create mode 100644 src/ApiClient/ClientFactory.php create mode 100644 src/ApiClient/ClientImplementation.php create mode 100644 src/ApiClient/RequestCacheInfoResolver.php create mode 100644 src/Request/AuthRequest.php create mode 100644 src/Request/Authentication/ConnectKeyInfoRequest.php create mode 100644 src/Request/Authentication/ConnectKeyResetRequest.php create mode 100644 src/Request/Authentication/RegisterRequest.php create mode 100644 src/Request/Authentication/TokenRequest.php create mode 100644 src/Request/BasicRequest.php create mode 100644 src/Request/Cancel/PostCancelRequest.php create mode 100644 src/Request/Fields/GetFieldsRequest.php create mode 100644 src/Request/Label/PostLabelRequest.php create mode 100644 src/Request/Rate/PostRateRequest.php create mode 100644 src/Request/Request.php create mode 100644 src/Request/Shipment/GetUserListShipmentRequest.php create mode 100644 src/Request/Shipment/PostShipmentRequest.php create mode 100644 src/Request/ShippingPlan/PutShippingPlanRequest.php create mode 100644 src/Request/ShippingServices/GetListRequest.php create mode 100644 src/Request/ShippingServices/GetServiceRequest.php create mode 100644 src/Request/ShippingServicesSettings/GetSettingsRequest.php create mode 100644 src/Request/ShippingServicesSettings/PostSettingsRequest.php create mode 100644 src/Request/ShippingServicesSettings/PutSettingsRequest.php create mode 100644 src/Request/ShippingServicesSettings/Test/GetSettingsTestRequest.php create mode 100644 src/Request/Status/GetStatusRequest.php create mode 100644 src/Request/Traits/SettingsItemRequestHelper.php create mode 100644 src/Request/Users/GetUserRequest.php create mode 100644 src/Response/ApiResponse.php create mode 100644 src/Response/AuthApiResponse.php create mode 100644 src/Response/Authentication/ConnectKeyInfoResponse.php create mode 100644 src/Response/Authentication/ConnectKeyResetResponse.php create mode 100644 src/Response/Authentication/RegisterResponse.php create mode 100644 src/Response/Authentication/TokenResponse.php create mode 100644 src/Response/Cancel/PostCancelResponse.php create mode 100644 src/Response/Exception/EmptyMessageFromResponse.php create mode 100644 src/Response/Exception/EmptyStatusFromResponse.php create mode 100644 src/Response/Exception/TriedExtractDataFromErrorResponse.php create mode 100644 src/Response/Fields/GetFieldsResponse.php create mode 100644 src/Response/Label/PostLabelResponse.php create mode 100644 src/Response/Maintenance/MaintenanceResponseContext.php create mode 100644 src/Response/ProtectedResponse.php create mode 100644 src/Response/Rate/PostRateResponse.php create mode 100644 src/Response/RawResponse.php create mode 100644 src/Response/Response.php create mode 100644 src/Response/Shipment/GetListShipmentAdminContextResponse.php create mode 100644 src/Response/Shipment/PostShipmentResponse.php create mode 100644 src/Response/ShippingServices/GetShippingServiceResponse.php create mode 100644 src/Response/ShippingServices/GetShippingServicesListResponse.php create mode 100644 src/Response/ShippingServicesSettings/GetSettingsResponse.php create mode 100644 src/Response/ShippingServicesSettings/Test/GetSettingsTestResponse.php create mode 100644 src/Response/Status/GetStatusResponse.php create mode 100644 src/Response/Traits/ApiResponseDecorator.php create mode 100644 src/Response/Traits/AuthApiResponseDecorator.php create mode 100644 src/Response/Traits/PagedListImplementation.php create mode 100644 src/Response/Users/GetUserResponse.php create mode 100644 tests/docker-compose.yaml create mode 100644 tests/integration/bootstrap.php create mode 100644 tests/unit/bootstrap.php diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a612c0c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,15 @@ +tests/ export-ignore +vendor/ export-ignore +.editorconfig export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.git/ export-ignore +.gitlab-ci.yml export-ignore +.idea export-ignore +apigen.neon export-ignore +build-coverage/ export-ignore +docs/ export-ignore +LICENSE.md export-ignore +phpcs.xml.dist export-ignore +phpunit-integration.xml export-ignore +phpunit-unit.xml export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4b86223 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/vendor/ +.idea +composer.lock +build-coverage +swagger \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..db521c1 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,6 @@ +variables: + DISABLE_ACCEPTANCE: "1" + DISABLE_FUNCTIONAL: "1" + +include: 'https://gitlab.com/wpdesk/gitlab-ci/raw/master/gitlab-ci-1.2.yml' + diff --git a/README.md b/README.md index b6395ce..a8ccb86 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ -# wp-api-client +[](https://gitlab.com/wpdesk/wp-api-client/commits/master) +Integration: [](https://gitlab.com/wpdesk/wp-api-client/commits/master) +Unit: [](https://gitlab.com/wpdesk/wp-api-client/commits/master) +API Client +========== diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..03dc550 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,2 @@ += 1.0 - 2019-01-31 = +* First release diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..6980cec --- /dev/null +++ b/composer.json @@ -0,0 +1,35 @@ +{ + "name": "wpdesk/wp-api-client", + "authors": [ + { + "name": "Krzysiek", + "email": "krzysiek@wpdesk.pl" + } + ], + "require": { + "php": ">=5.5", + "psr/log": "^1.0.1", + "wpdesk/wp-http-client": "dev-master", + "psr/simple-cache": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "<7", + "wp-coding-standards/wpcs": "^0.14.1", + "squizlabs/php_codesniffer": "^3.0.2", + "mockery/mockery": "*", + "10up/wp_mock": "*" + }, + "autoload": { + "psr-4": { + "WPDesk\\ApiClient\\": "src/" + } + }, + "autoload-dev": { + }, + "scripts": { + "phpunit-unit": "phpunit --configuration phpunit-unit.xml --coverage-text --colors=never", + "phpunit-unit-fast": "phpunit --configuration phpunit-unit.xml --no-coverage", + "phpunit-integration": "phpunit --configuration phpunit-integration.xml --coverage-text --colors=never", + "phpunit-integration-fast": "phpunit --configuration phpunit-integration.xml --no-coverage" + } +} diff --git a/phpunit-integration.xml b/phpunit-integration.xml new file mode 100644 index 0000000..4a342ab --- /dev/null +++ b/phpunit-integration.xml @@ -0,0 +1,28 @@ +<phpunit bootstrap="tests/integration/bootstrap.php" + backupGlobals="false" + > + <testsuites> + <testsuite> + <directory prefix="Test" suffix=".php">./tests/integration</directory> + </testsuite> + </testsuites> + + <filter> + <whitelist> + <directory suffix=".php">src</directory> + </whitelist> + </filter> + + <logging> + <log type="junit" target="build-coverage/report.junit.xml"/> + <log type="coverage-html" target="build-coverage/coverage" charset="UTF-8" yui="true" highlight="true"/> + <log type="coverage-text" target="build-coverage/coverage.txt"/> + <log type="coverage-clover" target="build-coverage/clover.xml"/> + </logging> + + <php> + <env name="WP_DEVELOP_DIR" value="/tmp/wordpress-develop"/> + <env name="WC_DEVELOP_DIR" value="/tmp/woocommerce"/> + </php> + +</phpunit> \ No newline at end of file diff --git a/phpunit-unit.xml b/phpunit-unit.xml new file mode 100644 index 0000000..31e5c9f --- /dev/null +++ b/phpunit-unit.xml @@ -0,0 +1,21 @@ +<phpunit bootstrap="tests/unit/bootstrap.php"> + <testsuites> + <testsuite> + <directory prefix="Test" suffix=".php">./tests/unit/</directory> + </testsuite> + </testsuites> + + <filter> + <whitelist> + <directory suffix=".php">src</directory> + </whitelist> + </filter> + + <logging> + <log type="junit" target="build-coverage/report.junit.xml"/> + <log type="coverage-html" target="build-coverage/coverage" charset="UTF-8" yui="true" highlight="true"/> + <log type="coverage-text" target="build-coverage/coverage.txt"/> + <log type="coverage-clover" target="build-coverage/clover.xml"/> + </logging> + +</phpunit> diff --git a/src/ApiClient/CachedClient.php b/src/ApiClient/CachedClient.php new file mode 100644 index 0000000..a7f512c --- /dev/null +++ b/src/ApiClient/CachedClient.php @@ -0,0 +1,111 @@ +<?php + +namespace WPDesk\SaasPlatformClient\ApiClient; + +use Psr\SimpleCache\CacheInterface; +use WPDesk\SaasPlatformClient\Cache\CacheDispatcher; +use WPDesk\SaasPlatformClient\Cache\CacheItemCreator; +use WPDesk\SaasPlatformClient\Cache\CacheItemVerifier; +use WPDesk\SaasPlatformClient\HttpClient\HttpClient; +use WPDesk\SaasPlatformClient\Request\Request; +use WPDesk\SaasPlatformClient\Response\Response; +use WPDesk\SaasPlatformClient\Serializer\Serializer; + +class CachedClient implements Client, CacheItemCreator, CacheItemVerifier +{ + + /** @var Client */ + private $client; + + /** @var CacheInterface */ + private $cache; + + /** + * @var CacheDispatcher + */ + private $cacheDispatcher; + + /** + * CachedClient constructor. + * @param Client $decorated Decorated client + * @param CacheInterface $cache + */ + public function __construct(Client $decorated, CacheInterface $cache) + { + $this->client = $decorated; + $this->cache = $cache; + $this->cacheDispatcher = new CacheDispatcher($cache, [new RequestCacheInfoResolver()]); + } + + /** + * Create item to cache. + * + * @param Request $request + * @return Response + */ + public function createCacheItem($request) + { + return $this->client->sendRequest($request); + } + + /** + * Verify cache item. + * + * @param $object + * @return Response; + */ + public function getVerifiedItemOrNull($object) + { + if ($object instanceof Response) { + return $object; + } + return null; + } + + /** + * Send request. + * + * @param Request $request + * @return mixed|Response + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function sendRequest(Request $request) + { + $response = $this->cacheDispatcher->dispatch($request, $this, $this); + return $response; + } + + /** + * @return HttpClient + */ + public function getHttpClient() + { + return $this->client->getHttpClient(); + } + + /** + * @param HttpClient $client + * @return mixed + */ + public function setHttpClient(HttpClient $client) + { + return $this->client->setHttpClient($client); + } + + /** + * @return Serializer + */ + public function getSerializer() + { + return $this->client->getSerializer(); + } + + /** + * @return string + */ + public function getApiUrl() + { + return $this->client->getApiUrl(); + } + +} \ No newline at end of file diff --git a/src/ApiClient/Client.php b/src/ApiClient/Client.php new file mode 100644 index 0000000..993f5ca --- /dev/null +++ b/src/ApiClient/Client.php @@ -0,0 +1,41 @@ +<?php + +namespace WPDesk\SaasPlatformClient\ApiClient; + +use WPDesk\SaasPlatformClient\HttpClient\HttpClient; +use WPDesk\SaasPlatformClient\Request\Request; +use WPDesk\SaasPlatformClient\Response\Response; +use WPDesk\SaasPlatformClient\Serializer\Serializer; + +interface Client +{ + /** + * Send given request trough HttpClient + * + * @param Request $request + * @return Response + */ + public function sendRequest(Request $request); + + /** + * @return HttpClient + */ + public function getHttpClient(); + + /** + * @param HttpClient $client + */ + public function setHttpClient(HttpClient $client); + + /** + * @return Serializer + */ + public function getSerializer(); + + /** + * Returns api url. Always without ending / + * + * @return string + */ + public function getApiUrl(); +} \ No newline at end of file diff --git a/src/ApiClient/ClientFactory.php b/src/ApiClient/ClientFactory.php new file mode 100644 index 0000000..a5b45e6 --- /dev/null +++ b/src/ApiClient/ClientFactory.php @@ -0,0 +1,35 @@ +<?php + +namespace WPDesk\SaasPlatformClient\ApiClient; + +use WPDesk\SaasPlatformClient\Cache\WordpressCache; +use WPDesk\SaasPlatformClient\HttpClient\HttpClientFactory; +use WPDesk\SaasPlatformClient\PlatformFactoryOptions; +use WPDesk\SaasPlatformClient\Serializer\SerializerFactory; + +class ClientFactory +{ + /** + * @param PlatformFactoryOptions $options + * @return Client + */ + public function createClient(PlatformFactoryOptions $options) + { + $httpClientFactory = new HttpClientFactory(); + $serializerFactory = new SerializerFactory(); + + $client = new ClientImplementation( + $httpClientFactory->createClient($options), + $serializerFactory->createSerializer($options), + $options->getLogger(), + $options->getApiUrl(), + $options->getDefaultRequestHeaders() + ); + + if ($options->isCachedClient()) { + $client = new CachedClient($client, new WordpressCache()); + } + + return $client; + } +} \ No newline at end of file diff --git a/src/ApiClient/ClientImplementation.php b/src/ApiClient/ClientImplementation.php new file mode 100644 index 0000000..6153d4c --- /dev/null +++ b/src/ApiClient/ClientImplementation.php @@ -0,0 +1,215 @@ +<?php + +namespace WPDesk\SaasPlatformClient\ApiClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use WPDesk\SaasPlatformClient\HttpClient\HttpClient; +use WPDesk\SaasPlatformClient\HttpClient\HttpClientResponse; +use WPDesk\SaasPlatformClient\Platform; +use WPDesk\SaasPlatformClient\Request\Request; +use WPDesk\SaasPlatformClient\Response\RawResponse; +use WPDesk\SaasPlatformClient\Response\Response; +use WPDesk\SaasPlatformClient\Serializer\Serializer; +use WPDesk\SaasPlatformClient\HttpClient\HttpClientRequestException; + +class ClientImplementation implements Client, LoggerAwareInterface +{ + const CLIENT_VERSION = '1.6.5'; + + const DEFAULT_TIMEOUT = 10; + + /** @var HttpClient */ + private $client; + + /** @var Serializer */ + private $serializer; + + /** @var LoggerInterface */ + private $logger; + + /** @var string */ + private $apiUrl; + + /** @var array */ + private $defaultRequestHeaders; + + /** + * Client constructor. + * @param HttpClient $client + * @param Serializer $serializer + * @param LoggerInterface $logger + * @param string $apiUri + * @param array $defaultRequestHeaders + */ + public function __construct( + HttpClient $client, + Serializer $serializer, + LoggerInterface $logger, + $apiUri, + array $defaultRequestHeaders + ) { + $this->client = $client; + $this->serializer = $serializer; + $this->logger = $logger; + $this->apiUrl = $apiUri; + $this->defaultRequestHeaders = $defaultRequestHeaders; + } + + /** + * Send given request trough HttpClient + * + * @param Request $request + * @throws HttpClientRequestException + * @return Response + */ + public function sendRequest(Request $request) + { + $this->logger->debug("Sends request with METHOD: {$request->getMethod()}; to ENDPOINT {$request->getEndpoint()}", + $this->getLoggerContext()); + try { + $httpResponse = $this->client->send( + $fullUrl = $this->prepareFullUrl($request), + $method = $request->getMethod(), + $body = $this->prepareRequestBody($request), + $headers = $this->prepareRequestHeaders($request), self::DEFAULT_TIMEOUT + ); + + $this->logger->debug( + "Sent request with: URL: {$fullUrl};\n METHOD: {$method};\n BODY: {$body};\n" + . "HEADERS: " . json_encode($headers) . "\n\n and got response as CODE: {$httpResponse->getResponseCode()};\n" + . "with RESPONSE BODY {$httpResponse->getBody()}", + $this->getLoggerContext()); + + + return $this->mapHttpResponseToApiResponse($httpResponse); + } catch (HttpClientRequestException $e) { + $this->logger->error("Exception {$e->getMessage()}; {$e->getCode()} occurred while sending request"); + throw $e; + } + } + + /** + * Returns full request url with endpoint + * + * @param Request $request + * @return string + */ + private function prepareFullUrl(Request $request) + { + $endpoint = $request->getEndpoint(); + if (strpos('http', $endpoint) === 0) { + return $endpoint; + } + return $this->getApiUrl() . $endpoint; + } + + /** + * Map response from http client to api response using serializer + * + * @param HttpClientResponse $response + * @return RawResponse + */ + private function mapHttpResponseToApiResponse(HttpClientResponse $response) + { + $apiResponse = new RawResponse( + $this->serializer->unserialize($response->getBody()), + $response->getResponseCode(), + $response->getHeaders() + ); + + return $apiResponse; + } + + /** + * Prepare serialized request body + * + * @param Request $request + * @return string + */ + private function prepareRequestBody(Request $request) + { + return $this->serializer->serialize($request->getBody()); + } + + /** + * Prepares array of http headers + * + * @param Request $request + * @return array + */ + private function prepareRequestHeaders(Request $request) + { + $headers = array( + 'User-Agent' => 'saas-client-' . self::CLIENT_VERSION, + 'Accept-Encoding' => '*', + 'Content-Type' => $this->serializer->getMime() + ); + $headers = array_merge($this->defaultRequestHeaders, $headers); + return array_merge($headers, $request->getHeaders()); + } + + /** + * @return HttpClient + */ + public function getHttpClient() + { + return $this->client; + } + + /** + * @param HttpClient $client + */ + public function setHttpClient(HttpClient $client) + { + $this->client = $client; + } + + /** + * @return Serializer + */ + public function getSerializer() + { + return $this->serializer; + } + + /** + * Returns api url. Always without ending / + * + * @return string + */ + public function getApiUrl() + { + return trim($this->apiUrl, '/'); + } + + /** + * Sets logger + * + * @param LoggerInterface $logger + */ + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } + + /** + * Returns logger context for + * + * @param string $additional_context Optional additional context + * @return array + */ + protected function getLoggerContext($additional_context = '') + { + $context = [ + Platform::LIBARY_LOGIN_CONTEXT, + self::class + ]; + if ($additional_context !== '') { + $context[] = $additional_context; + } + return $context; + } + + +} \ No newline at end of file diff --git a/src/ApiClient/RequestCacheInfoResolver.php b/src/ApiClient/RequestCacheInfoResolver.php new file mode 100644 index 0000000..65e2014 --- /dev/null +++ b/src/ApiClient/RequestCacheInfoResolver.php @@ -0,0 +1,139 @@ +<?php + +namespace WPDesk\SaasPlatformClient\ApiClient; + +use WPDesk\SaasPlatformClient\Cache\CacheInfoResolver; +use WPDesk\SaasPlatformClient\Cache\HowToCache; +use WPDesk\SaasPlatformClient\Request\AuthRequest; +use WPDesk\SaasPlatformClient\Request\BasicRequest; +use WPDesk\SaasPlatformClient\Request\Request; +use WPDesk\SaasPlatformClient\Request\ShippingServicesSettings\PutSettingsRequest; +use WPDesk\SaasPlatformClient\Request\Status\GetStatusRequest; +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\RawResponse; + +class RequestCacheInfoResolver implements CacheInfoResolver +{ + + const DEFAULT_CACHE_TTL = 86400; //24 hours + const CACHE_TTL_ONE_MINUTE = 60; + + const OPTION_FS_SAAS_PLATFORM_VERSION_HASH = 'fs-saas-platform-version-hash'; + + /** + * + * @param Request $request + * + * @return bool + */ + private function prepareCacheKey($request) + { + return md5($request->getEndpoint()); + } + + /** + * + * @param Request $request + * + * @return bool + */ + public function isSupported($request) + { + if ($request instanceof BasicRequest) { + return true; + } + return false; + } + + /** + * + * @param Request $request + * + * @return bool + */ + public function shouldCache($request) + { + if ($request instanceof ConnectKeyInfoRequest) { + return false; + } + if ($request instanceof GetStatusRequest) { + return false; + } + if ($request instanceof BasicRequest) { + if ('GET' === $request->getMethod()) { + return true; + } + } + return false; + } + + /** + * + * @param Request $request + * + * @return HowToCache + */ + public function prepareHowToCache($request) + { + $howToCache = new HowToCache($this->prepareCacheKey($request), self::DEFAULT_CACHE_TTL); + return $howToCache; + } + + /** + * @param ApiResponse $response + * + * @return bool + */ + private function isPlatformVersionFromResponseChanged(ApiResponse $response) + { + $stored_hash = get_option(self::OPTION_FS_SAAS_PLATFORM_VERSION_HASH, ''); + if ($stored_hash !== $response->getPlatformVersionHash()) { + return true; + } + return false; + } + + /** + * @param ApiResponse $response + */ + private function storePlatformVersionHashFromResponse(ApiResponse $response) + { + update_option(self::OPTION_FS_SAAS_PLATFORM_VERSION_HASH, $response->getPlatformVersionHash()); + } + + /** + * + * @param Request $request + * @param mixed $item + * + * @return bool + */ + public function shouldClearCache($request, $item) + { + if ($request instanceof PutSettingsRequest) { + return true; + } + if ($item instanceof ApiResponse && $this->isPlatformVersionFromResponseChanged($item)) { + $this->storePlatformVersionHashFromResponse($item); + return true; + } + return false; + } + + /** + * + * @param Request $request + * @param mixed $item + * + * @return string[] + */ + public function shouldClearKeys($request, $item) + { + if ('GET' !== $request->getMethod()) { + return [$this->prepareCacheKey($request)]; + } + return []; + } + + +} \ No newline at end of file diff --git a/src/Request/AuthRequest.php b/src/Request/AuthRequest.php new file mode 100644 index 0000000..3415812 --- /dev/null +++ b/src/Request/AuthRequest.php @@ -0,0 +1,53 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request; + +use WPDesk\SaasPlatformClient\Authentication\Token; + +class AuthRequest extends BasicRequest +{ + /** @var Token */ + private $token; + + public function __construct(Token $token) + { + $this->setToken($token); + } + + /** + * @param Token $token + */ + public function setToken(Token $token) + { + $this->token = $token; + } + + /** + * @return bool + */ + public function isTokenExpired() + { + return $this->token->isExpired(); + } + + /** + * @return bool + */ + public function isTokenInvalid() + { + return !$this->token->isSignatureValid(); + } + + /** + * Returns array of http headers + * + * @return array + */ + public function getHeaders() + { + $headers = array( + 'Authorization' => $this->token->getAuthString() + ); + return array_merge($headers, parent::getHeaders()); + } +} \ No newline at end of file diff --git a/src/Request/Authentication/ConnectKeyInfoRequest.php b/src/Request/Authentication/ConnectKeyInfoRequest.php new file mode 100644 index 0000000..fe611c6 --- /dev/null +++ b/src/Request/Authentication/ConnectKeyInfoRequest.php @@ -0,0 +1,28 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Authentication; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class ConnectKeyInfoRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'GET'; + + /** @var string */ + protected $endPoint = '/connectkeyinfo/{connectKey}'; + + + /** + * ConnectKeyInfoRequest constructor. + * @param $connectKey + * @param Token $token + */ + public function __construct($connectKey, Token $token) + { + parent::__construct($token); + + $this->endPoint = str_replace('{connectKey}', $connectKey, $this->endPoint); + } +} \ No newline at end of file diff --git a/src/Request/Authentication/ConnectKeyResetRequest.php b/src/Request/Authentication/ConnectKeyResetRequest.php new file mode 100644 index 0000000..0c2cd8c --- /dev/null +++ b/src/Request/Authentication/ConnectKeyResetRequest.php @@ -0,0 +1,23 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Authentication; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class ConnectKeyResetRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'POST'; + + /** @var string */ + protected $endPoint = '/users/{id}/connectKeyReset'; + + + public function __construct($user_id, Token $token) + { + parent::__construct($token); + + $this->endPoint = str_replace('{id}', $user_id, $this->endPoint); + } +} \ No newline at end of file diff --git a/src/Request/Authentication/RegisterRequest.php b/src/Request/Authentication/RegisterRequest.php new file mode 100644 index 0000000..3a231d6 --- /dev/null +++ b/src/Request/Authentication/RegisterRequest.php @@ -0,0 +1,29 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Authentication; + +use WPDesk\SaasPlatformClient\Request\BasicRequest; + +final class RegisterRequest extends BasicRequest +{ + /** @var string */ + protected $method = 'POST'; + + /** @var string */ + protected $endPoint = '/register'; + + /** + * RegisterRequest constructor. + * @param string $email + * @param string $domain + * @param string $locale + * @param ?string $admin_url + */ + public function __construct($email, $domain, $locale, $admin_url = null) + { + $this->data = compact('email', 'domain', 'locale'); + if ($admin_url !== null) { + $this->data['adminUrl'] = $admin_url; + } + } +} \ No newline at end of file diff --git a/src/Request/Authentication/TokenRequest.php b/src/Request/Authentication/TokenRequest.php new file mode 100644 index 0000000..289011b --- /dev/null +++ b/src/Request/Authentication/TokenRequest.php @@ -0,0 +1,26 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Authentication; + + +use WPDesk\SaasPlatformClient\Request\BasicRequest; + +final class TokenRequest extends BasicRequest +{ + /** @var string */ + protected $method = 'POST'; + + /** @var string */ + protected $endPoint = '/token'; + + /** + * TokenRequest constructor. + * @param string $connectKey + * @param string $domain + * @param string $locale + */ + public function __construct($connectKey, $domain, $locale) + { + $this->data = compact(['connectKey', 'domain', 'locale']); + } +} \ No newline at end of file diff --git a/src/Request/BasicRequest.php b/src/Request/BasicRequest.php new file mode 100644 index 0000000..c185d1e --- /dev/null +++ b/src/Request/BasicRequest.php @@ -0,0 +1,54 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request; + + +class BasicRequest implements Request +{ + /** @var string */ + protected $method; + + /** @var array */ + protected $data; + + /** @var string */ + protected $endPoint; + + /** + * @return string + */ + public function getMethod() + { + return $this->method; + } + + /** + * Return endpoint in format /[^/]+/ + * + * @return string + */ + public function getEndpoint() + { + return '/' . trim($this->endPoint, '/'); + } + + /** + * Returns array of http headers + * + * @return array + */ + public function getHeaders() + { + return array(); + } + + /** + * Return unserialized request body as array + * + * @return array + */ + public function getBody() + { + return $this->data; + } +} \ No newline at end of file diff --git a/src/Request/Cancel/PostCancelRequest.php b/src/Request/Cancel/PostCancelRequest.php new file mode 100644 index 0000000..a780ee2 --- /dev/null +++ b/src/Request/Cancel/PostCancelRequest.php @@ -0,0 +1,39 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Cancel; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class PostCancelRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'POST'; + + /** @var string */ + protected $endPoint = '/shops/{shop}/shipping_services/{service}/shipments/{shipment}/cancel'; + + /** + * PostShipmentRequest constructor. + * @param Token $token + * @param int $shippingServiceId + * @param int $shopId + * @param int $shipmentId + */ + public function __construct( + Token $token, + $shippingServiceId, + $shopId, + $shipmentId + ) { + parent::__construct($token); + + $this->endPoint = str_replace( + ['{shop}', '{service}', '{shipment}'], + [$shopId, $shippingServiceId, $shipmentId], + $this->endPoint + ); + + $this->data = []; + } +} \ No newline at end of file diff --git a/src/Request/Fields/GetFieldsRequest.php b/src/Request/Fields/GetFieldsRequest.php new file mode 100644 index 0000000..2e5b881 --- /dev/null +++ b/src/Request/Fields/GetFieldsRequest.php @@ -0,0 +1,45 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Fields; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class GetFieldsRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'GET'; + + /** @var string */ + protected $endPoint = '/shops/{shop}/shipping_services/{service}/dynamic_fields/{zone_targets}'; + + const ZONE_TARGETS_DELIMITER = ','; + + /** + * @param array $zoneTargets + * @return string + */ + private function serializeZoneTargets(array $zoneTargets) + { + return implode(self::ZONE_TARGETS_DELIMITER, $zoneTargets); + } + + /** + * PostShipmentRequest constructor. + * @param Token $token + * @param int $shippingServiceId + * @param int $shopId + * @param string[] $zoneTargets + */ + public function __construct( + Token $token, + $shippingServiceId, + $shopId, + array $zoneTargets + ) { + parent::__construct($token); + + $this->endPoint = str_replace(['{shop}', '{service}', '{zone_targets}'], + [$shopId, $shippingServiceId, $this->serializeZoneTargets($zoneTargets)], $this->endPoint); + } +} \ No newline at end of file diff --git a/src/Request/Label/PostLabelRequest.php b/src/Request/Label/PostLabelRequest.php new file mode 100644 index 0000000..e34dcd7 --- /dev/null +++ b/src/Request/Label/PostLabelRequest.php @@ -0,0 +1,36 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Label; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class PostLabelRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'POST'; + + /** @var string */ + protected $endPoint = '/shops/{shop}/shipping_services/{service}/shipments/{shipment}/labels'; + + /** + * PostShipmentRequest constructor. + * @param Token $token + * @param int $shippingServiceId + * @param int $shopId + * @param int $shipmentId + */ + public function __construct( + Token $token, + $shippingServiceId, + $shopId, + $shipmentId + ) { + parent::__construct($token); + + $this->endPoint = str_replace(['{shop}', '{service}', '{shipment}'], [$shopId, $shippingServiceId, $shipmentId], + $this->endPoint); + + $this->data = []; + } +} \ No newline at end of file diff --git a/src/Request/Rate/PostRateRequest.php b/src/Request/Rate/PostRateRequest.php new file mode 100644 index 0000000..5352104 --- /dev/null +++ b/src/Request/Rate/PostRateRequest.php @@ -0,0 +1,36 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Rate; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Model\Rate\RateRequest; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class PostRateRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'POST'; + + /** @var string */ + protected $endPoint = '/shops/{shop}/shipping_services/{service}/rates'; + + /** + * PostRateRequest constructor. + * @param Token $token + * @param int $shippingServiceId + * @param int $shopId + * @param RateRequest $request + */ + public function __construct( + Token $token, + $shippingServiceId, + $shopId, + RateRequest $request + ) { + parent::__construct($token); + + $this->endPoint = str_replace(['{shop}', '{service}'], [$shopId, $shippingServiceId], $this->endPoint); + + $this->data = $request->toArray(); + } +} \ No newline at end of file diff --git a/src/Request/Request.php b/src/Request/Request.php new file mode 100644 index 0000000..2810176 --- /dev/null +++ b/src/Request/Request.php @@ -0,0 +1,27 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request; + + +interface Request +{ + /** + * @return string + */ + public function getMethod(); + + /** + * @return array + */ + public function getHeaders(); + + /** + * @return array + */ + public function getBody(); + + /** + * @return string + */ + public function getEndpoint(); +} \ No newline at end of file diff --git a/src/Request/Shipment/GetUserListShipmentRequest.php b/src/Request/Shipment/GetUserListShipmentRequest.php new file mode 100644 index 0000000..176c4ba --- /dev/null +++ b/src/Request/Shipment/GetUserListShipmentRequest.php @@ -0,0 +1,27 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Shipment; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Model\Shipment\ShipmentRequest; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class GetUserListShipmentRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'GET'; + + /** @var string */ + protected $endPoint = '/users/{id}/shipments'; + + /** + * GetListShipmentRequest constructor. + * @param Token $token + */ + public function __construct($user_id, Token $token) +{ + parent::__construct($token); + + $this->endPoint = str_replace('{id}', $user_id, $this->endPoint); + } +} \ No newline at end of file diff --git a/src/Request/Shipment/PostShipmentRequest.php b/src/Request/Shipment/PostShipmentRequest.php new file mode 100644 index 0000000..0913827 --- /dev/null +++ b/src/Request/Shipment/PostShipmentRequest.php @@ -0,0 +1,36 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Shipment; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Model\Shipment\ShipmentRequest; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class PostShipmentRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'POST'; + + /** @var string */ + protected $endPoint = '/shops/{shop}/shipping_services/{service}/shipments'; + + /** + * PostShipmentRequest constructor. + * @param Token $token + * @param int $shippingServiceId + * @param int $shopId + * @param ShipmentRequest $request + */ + public function __construct( + Token $token, + $shippingServiceId, + $shopId, + ShipmentRequest $request + ) { + parent::__construct($token); + + $this->endPoint = str_replace(['{shop}', '{service}'], [$shopId, $shippingServiceId], $this->endPoint); + + $this->data = $request->toArray(); + } +} \ No newline at end of file diff --git a/src/Request/ShippingPlan/PutShippingPlanRequest.php b/src/Request/ShippingPlan/PutShippingPlanRequest.php new file mode 100644 index 0000000..010e09d --- /dev/null +++ b/src/Request/ShippingPlan/PutShippingPlanRequest.php @@ -0,0 +1,30 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\ShippingPlan; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Model\ShippingPlan; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + + +final class PutShippingPlanRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'PUT'; + + /** @var ShippingPlan */ + private $plan; + + /** @var string */ + protected $endPoint = '/shipping_plans/{id}'; + + public function __construct(Token $token, ShippingPlan $plan) + { + parent::__construct($token); + $this->plan = $plan; + + $this->data = $plan->toArray(); + + $this->endPoint = str_replace('{id}', $plan->getId(), $this->endPoint); + } +} \ No newline at end of file diff --git a/src/Request/ShippingServices/GetListRequest.php b/src/Request/ShippingServices/GetListRequest.php new file mode 100644 index 0000000..e23bba6 --- /dev/null +++ b/src/Request/ShippingServices/GetListRequest.php @@ -0,0 +1,14 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\ShippingServices; + +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class GetListRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'GET'; + + /** @var string */ + protected $endPoint = '/shipping_services'; +} \ No newline at end of file diff --git a/src/Request/ShippingServices/GetServiceRequest.php b/src/Request/ShippingServices/GetServiceRequest.php new file mode 100644 index 0000000..91785ab --- /dev/null +++ b/src/Request/ShippingServices/GetServiceRequest.php @@ -0,0 +1,29 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\ShippingServices; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class GetServiceRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'GET'; + + /** @var string */ + protected $endPoint = '/shipping_services/{id}'; + + /** + * PutSettingsRequest constructor. + * @param Token $token + * @param int $shippingServiceId + */ + public function __construct( + Token $token, + $shippingServiceId + ) { + parent::__construct($token); + + $this->endPoint = str_replace('{id}', $shippingServiceId, $this->endPoint); + } +} \ No newline at end of file diff --git a/src/Request/ShippingServicesSettings/GetSettingsRequest.php b/src/Request/ShippingServicesSettings/GetSettingsRequest.php new file mode 100644 index 0000000..9040b31 --- /dev/null +++ b/src/Request/ShippingServicesSettings/GetSettingsRequest.php @@ -0,0 +1,38 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\ShippingServicesSettings; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Model\ShippingServiceSetting; +use WPDesk\SaasPlatformClient\Request\AuthRequest; +use WPDesk\SaasPlatformClient\Request\Traits\SettingsItemRequestHelper; + +final class GetSettingsRequest extends AuthRequest +{ + use SettingsItemRequestHelper; + + /** @var string */ + protected $method = 'GET'; + + /** @var string */ + protected $endPoint = '/shipping_services/settings/{id}'; + + /** + * PutSettingsRequest constructor. + * @param Token $token + * @param int $shippingServiceId + * @param int $shopId + * @param string $settingType + */ + public function __construct( + Token $token, + $shippingServiceId, + $shopId, + $settingType = ShippingServiceSetting::TYPE_CONNECTION_SETTINGS + ) { + parent::__construct($token); + + $params = $this->buildSettingsId($shippingServiceId, $shopId, $settingType); + $this->endPoint = str_replace('{id}', $params, $this->endPoint); + } +} \ No newline at end of file diff --git a/src/Request/ShippingServicesSettings/PostSettingsRequest.php b/src/Request/ShippingServicesSettings/PostSettingsRequest.php new file mode 100644 index 0000000..20e9af3 --- /dev/null +++ b/src/Request/ShippingServicesSettings/PostSettingsRequest.php @@ -0,0 +1,30 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\ShippingServicesSettings; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Model\ShippingServiceSetting; +use WPDesk\SaasPlatformClient\Request\AuthRequest; +use WPDesk\SaasPlatformClient\Request\Traits\SettingsItemRequestHelper; + +final class PostSettingsRequest extends AuthRequest +{ + use SettingsItemRequestHelper; + + /** @var string */ + protected $method = 'POST'; + + /** @var ShippingServiceSetting */ + private $setting; + + /** @var string */ + protected $endPoint = '/shipping_services/settings'; + + public function __construct(Token $token, ShippingServiceSetting $setting) + { + parent::__construct($token); + $this->setting = $setting; + + $this->data = $setting->toArray(); + } +} \ No newline at end of file diff --git a/src/Request/ShippingServicesSettings/PutSettingsRequest.php b/src/Request/ShippingServicesSettings/PutSettingsRequest.php new file mode 100644 index 0000000..ea60793 --- /dev/null +++ b/src/Request/ShippingServicesSettings/PutSettingsRequest.php @@ -0,0 +1,36 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\ShippingServicesSettings; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Model\ShippingServiceSetting; +use WPDesk\SaasPlatformClient\Request\AuthRequest; +use WPDesk\SaasPlatformClient\Request\Traits\SettingsItemRequestHelper; + +final class PutSettingsRequest extends AuthRequest +{ + use SettingsItemRequestHelper; + + /** @var string */ + protected $method = 'PUT'; + + /** @var string */ + protected $endPoint = '/shipping_services/settings/{id}'; + + /** + * PutSettingsRequest constructor. + * @param Token $token + * @param int $shippingServiceId + * @param int $shopId + * @param string $settingType + */ + public function __construct(Token $token, ShippingServiceSetting $setting) + { + parent::__construct($token); + + $params = $this->buildSettingsId($setting->getShippingService(), $setting->getShop(), $setting->getType()); + $this->endPoint = str_replace('{id}', $params, $this->endPoint); + + $this->data = $setting->toArray(); + } +} \ No newline at end of file diff --git a/src/Request/ShippingServicesSettings/Test/GetSettingsTestRequest.php b/src/Request/ShippingServicesSettings/Test/GetSettingsTestRequest.php new file mode 100644 index 0000000..45009ad --- /dev/null +++ b/src/Request/ShippingServicesSettings/Test/GetSettingsTestRequest.php @@ -0,0 +1,37 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\ShippingServicesSettings\Test; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Model\ShippingServiceSetting; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class GetSettingsTestRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'GET'; + + /** @var string */ + protected $endPoint = '/shops/{shop}/shipping_services/{service}/settings/{type}/test'; + + /** + * PutSettingsRequest constructor. + * @param Token $token + * @param int $shippingServiceId + * @param int $shopId + */ + public function __construct( + Token $token, + $shippingServiceId, + $shopId + ) { + parent::__construct($token); + + $this->endPoint = str_replace( + ['{shop}', '{service}', '{type}'], + [$shopId, $shippingServiceId, ShippingServiceSetting::TYPE_CONNECTION_SETTINGS], + $this->endPoint + ); + } + +} \ No newline at end of file diff --git a/src/Request/Status/GetStatusRequest.php b/src/Request/Status/GetStatusRequest.php new file mode 100644 index 0000000..59b9a17 --- /dev/null +++ b/src/Request/Status/GetStatusRequest.php @@ -0,0 +1,49 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Status; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Request\AuthRequest; +use WPDesk\SaasPlatformClient\Request\BasicRequest; + +final class GetStatusRequest extends BasicRequest +{ + + /** @var string */ + protected $method = 'GET'; + + /** @var string */ + protected $endPoint = '/status'; + + /** @var Token */ + private $token; + + /** + * GetStatusRequest constructor. + * + * @param null|Token $token + */ + public function __construct( + Token $token = null + ) { + $this->token = $token; + } + + /** + * Returns array of http headers + * + * @return array + */ + public function getHeaders() + { + if (null !== $this->token) { + $headers = array( + 'Authorization' => $this->token->getAuthString() + ); + return array_merge($headers, parent::getHeaders()); + } else { + return parent::getHeaders(); + } + } + +} \ No newline at end of file diff --git a/src/Request/Traits/SettingsItemRequestHelper.php b/src/Request/Traits/SettingsItemRequestHelper.php new file mode 100644 index 0000000..9b97fad --- /dev/null +++ b/src/Request/Traits/SettingsItemRequestHelper.php @@ -0,0 +1,28 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Traits; + +trait SettingsItemRequestHelper +{ + + /** + * Build multiple compound key id in api-platform + * + * @param int $shippingServiceId + * @param int $shopId + * @param string|null $settingType + * @return string + */ + private function buildSettingsId($shippingServiceId, $shopId, $settingType = null) + { + $query_data = [ + 'shippingService' => $shippingServiceId, + 'shop' => $shopId, + 'type' => $settingType + ]; + if (null !== $settingType) { + $query_data['type'] = $settingType; + } + return http_build_query($query_data, null, ';'); + } +} \ No newline at end of file diff --git a/src/Request/Users/GetUserRequest.php b/src/Request/Users/GetUserRequest.php new file mode 100644 index 0000000..62b0c7a --- /dev/null +++ b/src/Request/Users/GetUserRequest.php @@ -0,0 +1,28 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Request\Users; + +use WPDesk\SaasPlatformClient\Authentication\Token; +use WPDesk\SaasPlatformClient\Request\AuthRequest; + +final class GetUserRequest extends AuthRequest +{ + /** @var string */ + protected $method = 'GET'; + + /** @var string */ + protected $endPoint = '/users/{id}'; + + /** + * getUserRequest constructor. + * + * @param $user_id + * @param Token $token + */ + public function __construct($user_id, Token $token) + { + parent::__construct($token); + + $this->endPoint = str_replace('{id}', $user_id, $this->endPoint); + } +} \ No newline at end of file diff --git a/src/Response/ApiResponse.php b/src/Response/ApiResponse.php new file mode 100644 index 0000000..486e321 --- /dev/null +++ b/src/Response/ApiResponse.php @@ -0,0 +1,35 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response; + + +interface ApiResponse extends Response +{ + /** + * Get links structure to the other request + * + * @return array + */ + public function getLinks(); + + /** + * Is it a BAD REQUEST response + * + * @return bool + */ + public function isBadRequest(); + + /** + * Is it a FATAL ERROR response + * + * @return bool + */ + public function isServerFatalError(); + + /** + * Is requested resource exists + * + * @return bool + */ + public function isNotExists(); +} \ No newline at end of file diff --git a/src/Response/AuthApiResponse.php b/src/Response/AuthApiResponse.php new file mode 100644 index 0000000..05fee14 --- /dev/null +++ b/src/Response/AuthApiResponse.php @@ -0,0 +1,14 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response; + +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +class AuthApiResponse implements ApiResponse +{ + const RESPONSE_CODE_BAD_CREDENTIALS = 401; + + const RESPONSE_CODE_NOT_EXISTS = 404; + + use AuthApiResponseDecorator; +} \ No newline at end of file diff --git a/src/Response/Authentication/ConnectKeyInfoResponse.php b/src/Response/Authentication/ConnectKeyInfoResponse.php new file mode 100644 index 0000000..d89aba8 --- /dev/null +++ b/src/Response/Authentication/ConnectKeyInfoResponse.php @@ -0,0 +1,37 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Authentication; + +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\ApiResponseDecorator; + +final class ConnectKeyInfoResponse implements ApiResponse +{ + use ApiResponseDecorator; + + /** + * @return int + */ + public function getUserId() + { + return (int)$this->getResponseBody()['owner_id']; + } + + /** + * @return \DateTimeImmutable + * @throws \Exception + */ + public function getLastUsed() + { + $lastUsed = $this->getResponseBody()['lastUsed']; + return new \DateTimeImmutable($lastUsed['date']); + } + + /** + * @return array[string] + */ + public function getDomains() + { + return $this->getResponseBody()['domains']; + } +} \ No newline at end of file diff --git a/src/Response/Authentication/ConnectKeyResetResponse.php b/src/Response/Authentication/ConnectKeyResetResponse.php new file mode 100644 index 0000000..4f78a30 --- /dev/null +++ b/src/Response/Authentication/ConnectKeyResetResponse.php @@ -0,0 +1,22 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Authentication; + +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +final class ConnectKeyResetResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + + /** + * Returns newly generated connect key + * + * @return string + */ + public function getNewConnectKey() + { + $body = $this->getResponseBody(); + return (string)$body['connectKey']; + } +} \ No newline at end of file diff --git a/src/Response/Authentication/RegisterResponse.php b/src/Response/Authentication/RegisterResponse.php new file mode 100644 index 0000000..046a70f --- /dev/null +++ b/src/Response/Authentication/RegisterResponse.php @@ -0,0 +1,59 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Authentication; + +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\RawResponse; +use WPDesk\SaasPlatformClient\Response\Traits\ApiResponseDecorator; + +final class RegisterResponse implements ApiResponse +{ + const API_KEY_FIELD = 'password'; + + const RESPONSE_CODE_USER_ALREADY_EXISTS = 460; + + const RESPONSE_CODE_DOMAIN_ALREADY_EXISTS = 461; + + use ApiResponseDecorator; + + /** + * Returns true if user is registered + * + * @return bool + */ + public function isUserRegistered() + { + return in_array($this->getResponseCode(), + [RawResponse::RESPONSE_CODE_CREATED, RawResponse::RESPONSE_CODE_SUCCESS]); + } + + /** + * Returns true if user is was already registered + * + * @return bool + */ + public function isUserAlreadyExists() + { + return $this->getResponseCode() === self::RESPONSE_CODE_USER_ALREADY_EXISTS; + } + + /** + * Returns true if user cannot be registered because domain is occupied + * + * @return bool + */ + public function isDomainOccupied() + { + return $this->getResponseCode() === self::RESPONSE_CODE_DOMAIN_ALREADY_EXISTS; + } + + /** + * Returns apiKey from register response + * + * @return string + */ + public function getApiKey() + { + return $this->getResponseBody()[self::API_KEY_FIELD]; + } +} \ No newline at end of file diff --git a/src/Response/Authentication/TokenResponse.php b/src/Response/Authentication/TokenResponse.php new file mode 100644 index 0000000..e7a7247 --- /dev/null +++ b/src/Response/Authentication/TokenResponse.php @@ -0,0 +1,56 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Authentication; + +use WPDesk\SaasPlatformClient\Authentication\JWTToken; +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\AuthApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\ApiResponseDecorator; + +final class TokenResponse implements ApiResponse +{ + use ApiResponseDecorator; + + const RESPONSE_CODE_LOGIN_SUCCESS = 200; + + /** + * Returns token if exists + * + * @return JWTToken + */ + public function getToken() + { + $body = $this->getResponseBody(); + return new JWTToken($body['token']); + } + + /** + * @return bool + */ + public function isBadCredentials() + { + return $this->getResponseCode() === AuthApiResponse::RESPONSE_CODE_BAD_CREDENTIALS; + } + + /** + * Returns true if login is a success and token is available + * + * @return bool + */ + public function isLoginSuccess() + { + return $this->getResponseCode() === self::RESPONSE_CODE_LOGIN_SUCCESS; + } + + /** + * Returns true if user cannot be registered because domain is occupied + * + * @return bool + */ + public function isDomainOccupied() + { + return $this->getResponseCode() === RegisterResponse::RESPONSE_CODE_DOMAIN_ALREADY_EXISTS; + } + + +} \ No newline at end of file diff --git a/src/Response/Cancel/PostCancelResponse.php b/src/Response/Cancel/PostCancelResponse.php new file mode 100644 index 0000000..091c610 --- /dev/null +++ b/src/Response/Cancel/PostCancelResponse.php @@ -0,0 +1,11 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Cancel; + +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +class PostCancelResponse implements ApiResponse +{ + use AuthApiResponseDecorator; +} diff --git a/src/Response/Exception/EmptyMessageFromResponse.php b/src/Response/Exception/EmptyMessageFromResponse.php new file mode 100644 index 0000000..870a00c --- /dev/null +++ b/src/Response/Exception/EmptyMessageFromResponse.php @@ -0,0 +1,19 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Exception; + +class EmptyMessageFromResponse extends \RuntimeException +{ + /** + * Exception factory + * + * @param string $request + * @param int $errorCode + * @return TriedExtractDataFromErrorResponse + */ + public static function createWithClassInfo($request, $errorCode) + { + return new EmptyStatusFromResponse("Tried to extract message from {$request} when an error occured. Response code: {$errorCode}", + $errorCode); + } +} \ No newline at end of file diff --git a/src/Response/Exception/EmptyStatusFromResponse.php b/src/Response/Exception/EmptyStatusFromResponse.php new file mode 100644 index 0000000..a077eca --- /dev/null +++ b/src/Response/Exception/EmptyStatusFromResponse.php @@ -0,0 +1,19 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Exception; + +class EmptyStatusFromResponse extends \RuntimeException +{ + /** + * Exception factory + * + * @param string $request + * @param int $errorCode + * @return TriedExtractDataFromErrorResponse + */ + public static function createWithClassInfo($request, $errorCode) + { + return new EmptyStatusFromResponse("Tried to extract status from {$request} when an error occured. Response code: {$errorCode}", + $errorCode); + } +} \ No newline at end of file diff --git a/src/Response/Exception/TriedExtractDataFromErrorResponse.php b/src/Response/Exception/TriedExtractDataFromErrorResponse.php new file mode 100644 index 0000000..38d21ff --- /dev/null +++ b/src/Response/Exception/TriedExtractDataFromErrorResponse.php @@ -0,0 +1,19 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Exception; + +class TriedExtractDataFromErrorResponse extends \RuntimeException +{ + /** + * Exception factory + * + * @param string $request + * @param int $errorCode + * @return TriedExtractDataFromErrorResponse + */ + public static function createWithClassInfo($request, $errorCode) + { + return new TriedExtractDataFromErrorResponse("Tried to extract data from {$request} when an error occured. Response code: {$errorCode}", + $errorCode); + } +} \ No newline at end of file diff --git a/src/Response/Fields/GetFieldsResponse.php b/src/Response/Fields/GetFieldsResponse.php new file mode 100644 index 0000000..710e5e6 --- /dev/null +++ b/src/Response/Fields/GetFieldsResponse.php @@ -0,0 +1,19 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Fields; + +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +class GetFieldsResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + + /** + * @return array + */ + public function getFields() + { + return $this->getResponseBody()['fieldsJson']; + } +} diff --git a/src/Response/Label/PostLabelResponse.php b/src/Response/Label/PostLabelResponse.php new file mode 100644 index 0000000..83f5985 --- /dev/null +++ b/src/Response/Label/PostLabelResponse.php @@ -0,0 +1,20 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Label; + +use WPDesk\SaasPlatformClient\Model\Label\Label; +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +class PostLabelResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + + /** + * @return Label + */ + public function getLabel() + { + return new Label($this->getResponseBody()); + } +} diff --git a/src/Response/Maintenance/MaintenanceResponseContext.php b/src/Response/Maintenance/MaintenanceResponseContext.php new file mode 100644 index 0000000..fa0a066 --- /dev/null +++ b/src/Response/Maintenance/MaintenanceResponseContext.php @@ -0,0 +1,50 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Maintenance; + +use WPDesk\SaasPlatformClient\Response\Response; + +class MaintenanceResponseContext +{ + + /** + * Response. + * + * @var Response + */ + private $response; + + public function __construct(Response $response) + { + $this->response = $response; + } + + /** + * Get maintenance message. + * + * @return string|null + */ + public function getMaintenanceMessage() + { + $responseBody = $this->response->getResponseBody(); + if (isset($responseBody['message'])) { + return $responseBody['message']; + } + return null; + } + + /** + * Get maintenance till. + * + * @return int|null + */ + public function getMaintenanceTill() + { + $responseBody = $this->response->getResponseBody(); + if (isset($responseBody['maintenance_till'])) { + return intval($responseBody['maintenance_till']); + } + return null; + } + +} \ No newline at end of file diff --git a/src/Response/ProtectedResponse.php b/src/Response/ProtectedResponse.php new file mode 100644 index 0000000..363fde0 --- /dev/null +++ b/src/Response/ProtectedResponse.php @@ -0,0 +1,27 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response; + +use WPDesk\SaasPlatformClient\Response\Exception\TriedExtractDataFromErrorResponse; +use WPDesk\SaasPlatformClient\Response\Traits\ApiResponseDecorator; + +/** + * Response is protected in a way so when you try to get body of the response when an error occured you will get an exception + * + * Class ProtectedResponse + * @package WPDesk\SaasPlatformClient\Response + */ +class ProtectedResponse implements Response +{ + use ApiResponseDecorator; + + public function getResponseBody() + { + if ($this->isError()) { + throw TriedExtractDataFromErrorResponse::createWithClassInfo(get_class($this->rawResponse), $this->getResponseCode()); + } + return $this->rawResponse->getResponseBody(); + } + + +} \ No newline at end of file diff --git a/src/Response/Rate/PostRateResponse.php b/src/Response/Rate/PostRateResponse.php new file mode 100644 index 0000000..8f53e7e --- /dev/null +++ b/src/Response/Rate/PostRateResponse.php @@ -0,0 +1,31 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Rate; + +use WPDesk\SaasPlatformClient\Model\Rate\RateResponse; +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +class PostRateResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + + const RESPONSE_CODE_RATE_FAILED = 274; + + /** + * @return RateResponse + */ + public function getRate() + { + return new RateResponse($this->getResponseBody()); + } + + /** + * Platform can't respond in meaningful way about rates + * + * @return bool + */ + public function isRateFailedError() { + return $this->rawResponse->getResponseCode() === self::RESPONSE_CODE_RATE_FAILED; + } +} diff --git a/src/Response/RawResponse.php b/src/Response/RawResponse.php new file mode 100644 index 0000000..6360d2e --- /dev/null +++ b/src/Response/RawResponse.php @@ -0,0 +1,113 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response; + +class RawResponse implements Response +{ + const RESPONSE_CODE_SUCCESS = 200; + const RESPONSE_CODE_CREATED = 201; + const RESPONSE_CODE_ERROR_BAD_REQUEST = 400; + const RESPONSE_CODE_DOMAIN_NOT_ALLOWED = 462; + const RESPONSE_CODE_ERROR_FATAL = 500; + const RESPONSE_CODE_MAINTENANCE = 503; + const HEADER_X_PLATFORM_VERSION_HASH = 'X-Platform-Version-Hash'; + + /** @var array */ + private $data; + + /** @var int */ + private $code; + + /** @var array */ + private $headers; + + /** + * RawResponse constructor. + * @param array $body + * @param int $code + * @param array $headers + */ + public function __construct(array $body, $code, array $headers) + { + $this->data = $body; + $this->code = (int)$code; + $this->headers = $headers; + } + + /** + * Returns response http code + * + * @return int + */ + public function getResponseCode() + { + return $this->code; + } + + /** + * Returns response body as array + * + * @return array + */ + public function getResponseBody() + { + return $this->data; + } + + /** + * Returns response body as array + * + * @return array + */ + public function getResponseErrorBody() + { + return $this->data; + } + + /** + * Returns response body as array + * + * @return array + */ + public function getResponseHeaders() + { + return $this->headers; + } + + /** + * Is any error occured + * + * @return bool + */ + public function isError() + { + $code = $this->getResponseCode(); + return ( $code < 200 || $code >= 300 ) && !$this->isMaintenance(); + } + + /** + * Is maintenance. + * + * @return bool + */ + public function isMaintenance() + { + $code = $this->getResponseCode(); + return self::RESPONSE_CODE_MAINTENANCE === $code; + } + + /** + * Get platform version hash string. + * + * @return bool|string + */ + public function getPlatformVersionHash() + { + if (isset($this->headers[self::HEADER_X_PLATFORM_VERSION_HASH])) { + return $this->headers[self::HEADER_X_PLATFORM_VERSION_HASH]; + } + return false; + } + + +} \ No newline at end of file diff --git a/src/Response/Response.php b/src/Response/Response.php new file mode 100644 index 0000000..245bfc4 --- /dev/null +++ b/src/Response/Response.php @@ -0,0 +1,43 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response; + + +interface Response +{ + /** + * @return int + */ + public function getResponseCode(); + + /** @return array */ + public function getResponseBody(); + + /** @return array */ + public function getResponseHeaders(); + + /** @return array */ + public function getResponseErrorBody(); + + /** + * Is any error occured + * + * @return bool + */ + public function isError(); + + /** + * Is maintenance + * + * @return bool + */ + public function isMaintenance(); + + /** + * Get platform version hash string. + * + * @return bool|string + */ + public function getPlatformVersionHash(); + +} \ No newline at end of file diff --git a/src/Response/Shipment/GetListShipmentAdminContextResponse.php b/src/Response/Shipment/GetListShipmentAdminContextResponse.php new file mode 100644 index 0000000..3aa1bd0 --- /dev/null +++ b/src/Response/Shipment/GetListShipmentAdminContextResponse.php @@ -0,0 +1,29 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Shipment; + +use WPDesk\SaasPlatformClient\Model\Shipment\ShipmentAdminContext; +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; +use WPDesk\SaasPlatformClient\Response\Traits\PagedListImplementation; + +class GetListShipmentAdminContextResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + use PagedListImplementation; + + /* + * @return ShippingService[] + */ + public function getPage() + { + $page = $this->getRawPage(); + $itemList = []; + if (count($page) > 0) { + foreach ($page as $item) { + $itemList[] = new ShipmentAdminContext($item); + } + } + return $itemList; + } +} \ No newline at end of file diff --git a/src/Response/Shipment/PostShipmentResponse.php b/src/Response/Shipment/PostShipmentResponse.php new file mode 100644 index 0000000..1153fff --- /dev/null +++ b/src/Response/Shipment/PostShipmentResponse.php @@ -0,0 +1,30 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Shipment; + +use WPDesk\SaasPlatformClient\Model\Shipment\ShipmentResponse; +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +class PostShipmentResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + + const RESPONSE_CODE_SHIPMENT_PLAN_EXCEEDED = 472; + + /** + * @return bool + */ + public function isShipmentPlanExceeded() + { + return $this->getResponseCode() === self::RESPONSE_CODE_SHIPMENT_PLAN_EXCEEDED; + } + + /** + * @return ShipmentResponse + */ + public function getShipment() + { + return new ShipmentResponse($this->getResponseBody()); + } +} diff --git a/src/Response/ShippingServices/GetShippingServiceResponse.php b/src/Response/ShippingServices/GetShippingServiceResponse.php new file mode 100644 index 0000000..3ea05c4 --- /dev/null +++ b/src/Response/ShippingServices/GetShippingServiceResponse.php @@ -0,0 +1,20 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\ShippingServices; + +use WPDesk\SaasPlatformClient\Model\ShippingService; +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +final class GetShippingServiceResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + + /** + * @return ShippingService + */ + public function getShippingService() + { + return new ShippingService($this->getResponseBody()); + } +} \ No newline at end of file diff --git a/src/Response/ShippingServices/GetShippingServicesListResponse.php b/src/Response/ShippingServices/GetShippingServicesListResponse.php new file mode 100644 index 0000000..fc89bbf --- /dev/null +++ b/src/Response/ShippingServices/GetShippingServicesListResponse.php @@ -0,0 +1,30 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\ShippingServices; + +use WPDesk\SaasPlatformClient\Model\ShippingService; +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; +use WPDesk\SaasPlatformClient\Response\Traits\PagedListImplementation; + +final class GetShippingServicesListResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + use PagedListImplementation; + + /* + * @return ShippingService[] + */ + public function getPage() + { + $page = $this->getRawPage(); + $itemList = []; + if (count($page) > 0) { + foreach ($page as $item) { + $itemList[] = new ShippingService($item); + } + } + return $itemList; + } + +} \ No newline at end of file diff --git a/src/Response/ShippingServicesSettings/GetSettingsResponse.php b/src/Response/ShippingServicesSettings/GetSettingsResponse.php new file mode 100644 index 0000000..1ab9835 --- /dev/null +++ b/src/Response/ShippingServicesSettings/GetSettingsResponse.php @@ -0,0 +1,32 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\ShippingServicesSettings; + +use WPDesk\SaasPlatformClient\Model\ShippingServiceSetting; +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +class GetSettingsResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + + /** + * @param array $data + * @return array + */ + private function convertHalReferencesToJson(array $data) + { + foreach ($data['_links'] as $key => $item) { + $data[$key] = $item['href']; + } + return $data; + } + + /** + * @return ShippingServiceSetting + */ + public function getSetting() + { + return new ShippingServiceSetting($this->convertHalReferencesToJson($this->getResponseBody())); + } +} diff --git a/src/Response/ShippingServicesSettings/Test/GetSettingsTestResponse.php b/src/Response/ShippingServicesSettings/Test/GetSettingsTestResponse.php new file mode 100644 index 0000000..ec791b2 --- /dev/null +++ b/src/Response/ShippingServicesSettings/Test/GetSettingsTestResponse.php @@ -0,0 +1,36 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\ShippingServicesSettings\Test; + +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Exception\EmptyStatusFromResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +class GetSettingsTestResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + + const MESSAGE = 'message'; + const STATUS = 'status'; + + public function getMessage() + { + $responseBody = $this->getResponseBody(); + if (isset($responseBody[self::MESSAGE])) { + return $responseBody[self::MESSAGE]; + } else { + throw EmptyMessageFromResponse::createWithClassInfo(get_class($this->rawResponse), $this->getResponseCode()); + } + } + + public function getStatus() + { + $responseBody = $this->getResponseBody(); + if (isset($responseBody[self::STATUS])) { + return $responseBody[self::STATUS]; + } else { + throw EmptyStatusFromResponse::createWithClassInfo(get_class($this->rawResponse), $this->getResponseCode()); + } + } + +} diff --git a/src/Response/Status/GetStatusResponse.php b/src/Response/Status/GetStatusResponse.php new file mode 100644 index 0000000..222902c --- /dev/null +++ b/src/Response/Status/GetStatusResponse.php @@ -0,0 +1,20 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Status; + +use WPDesk\SaasPlatformClient\Model\Status; +use WPDesk\SaasPlatformClient\Response\ApiResponse; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +class GetStatusResponse implements ApiResponse +{ + use AuthApiResponseDecorator; + + /** + * @return Status + */ + public function getStatus() + { + return new Status($this->getResponseBody()); + } +} diff --git a/src/Response/Traits/ApiResponseDecorator.php b/src/Response/Traits/ApiResponseDecorator.php new file mode 100644 index 0000000..e02c35f --- /dev/null +++ b/src/Response/Traits/ApiResponseDecorator.php @@ -0,0 +1,145 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Traits; + +use WPDesk\SaasPlatformClient\Response\AuthApiResponse; +use WPDesk\SaasPlatformClient\Response\RawResponse; +use WPDesk\SaasPlatformClient\Response\Response; + +trait ApiResponseDecorator +{ + + /** @var RawResponse */ + private $rawResponse; + + /** + * RawResponseDecorator constructor. + * @param Response $rawResponse + */ + public function __construct(Response $rawResponse) + { + $this->rawResponse = $rawResponse; + } + + /** + * Returns response http code + * + * @return int + */ + public function getResponseCode() + { + return $this->rawResponse->getResponseCode(); + } + + /** + * Returns response body as array + * + * @return array + */ + public function getResponseBody() + { + return $this->rawResponse->getResponseBody(); + } + + /** + * Returns response body as array + * + * @return array + */ + public function getResponseErrorBody() + { + return $this->rawResponse->getResponseErrorBody(); + } + + /** + * Returns response body as array + * + * @return array + */ + public function getResponseHeaders() + { + return $this->rawResponse->getResponseHeaders(); + } + + /** + * Get links structure to the other request + * + * @return array + */ + public function getLinks() + { + $body = $this->getResponseBody(); + return $body['_links']; + } + + /** + * Is it a BAD REQUEST response + * + * @return bool + */ + public function isBadRequest() + { + return $this->getResponseCode() === RawResponse::RESPONSE_CODE_ERROR_BAD_REQUEST; + } + + /** + * Is it a DOMAIN NOT ALLOWED response + * + * @return bool + */ + public function isDomainNotAllowed() + { + return $this->getResponseCode() === RawResponse::RESPONSE_CODE_DOMAIN_NOT_ALLOWED; + } + + /** + * Is it a FATAL ERROR response + * + * @return bool + */ + public function isServerFatalError() + { + return $this->getResponseCode() === RawResponse::RESPONSE_CODE_ERROR_FATAL; + } + + /** + * Is any error occured + * + * @return bool + */ + public function isError() + { + return $this->rawResponse->isError(); + } + + /** + * Is requested resource exists + * + * @return bool + */ + public function isNotExists() + { + return $this->getResponseCode() === AuthApiResponse::RESPONSE_CODE_NOT_EXISTS; + } + + /** + * Is maintenance. + * + * @return bool + */ + public function isMaintenance() + { + return $this->rawResponse->isMaintenance(); + } + + /** + * Get platform version hash string. + * + * @return bool|string + */ + public function getPlatformVersionHash() + { + return $this->rawResponse->getPlatformVersionHash(); + } + + } \ No newline at end of file diff --git a/src/Response/Traits/AuthApiResponseDecorator.php b/src/Response/Traits/AuthApiResponseDecorator.php new file mode 100644 index 0000000..5e45ff8 --- /dev/null +++ b/src/Response/Traits/AuthApiResponseDecorator.php @@ -0,0 +1,38 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Traits; + +use WPDesk\SaasPlatformClient\Response\AuthApiResponse; + +trait AuthApiResponseDecorator +{ + use ApiResponseDecorator; + + /** + * @return bool + */ + public function isBadCredentials() + { + return $this->getResponseCode() === AuthApiResponse::RESPONSE_CODE_BAD_CREDENTIALS; + } + + /** + * Is bad credential because token expires + * + * @return bool + */ + public function isTokenExpired() + { + return $this->isBadCredentials(); + } + + /** + * Is bad credential because token is invalid + * + * @return bool + */ + public function isTokenInvalid() + { + return $this->isBadCredentials(); + } +} \ No newline at end of file diff --git a/src/Response/Traits/PagedListImplementation.php b/src/Response/Traits/PagedListImplementation.php new file mode 100644 index 0000000..f364978 --- /dev/null +++ b/src/Response/Traits/PagedListImplementation.php @@ -0,0 +1,44 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Traits; + +trait PagedListImplementation +{ + /* + * @return array + */ + public function getRawPage() + { + $body = $this->getResponseBody(); + if ($body['_embedded'] !== null && $body['_embedded']['item'] !== null) { + return $body['_embedded']['item']; + } + return []; + } + + /** + * @return int + */ + public function getPageCount() + { + return (int)floor($this->getItemCount() / $this->getItemsPerPage()); + } + + /** + * @return int + */ + public function getItemsPerPage() + { + $body = $this->getResponseBody(); + return (int)$body['itemsPerPage']; + } + + /** + * @return int + */ + public function getItemCount() + { + $body = $this->getResponseBody(); + return (int)$body['totalItems']; + } +} \ No newline at end of file diff --git a/src/Response/Users/GetUserResponse.php b/src/Response/Users/GetUserResponse.php new file mode 100644 index 0000000..199a517 --- /dev/null +++ b/src/Response/Users/GetUserResponse.php @@ -0,0 +1,20 @@ +<?php + +namespace WPDesk\SaasPlatformClient\Response\Users; + +use WPDesk\SaasPlatformClient\Model\User; +use WPDesk\SaasPlatformClient\Response\Response; +use WPDesk\SaasPlatformClient\Response\Traits\AuthApiResponseDecorator; + +final class GetUserResponse implements Response +{ + use AuthApiResponseDecorator; + + /** + * @return User + */ + public function getUser() + { + return new User($this->getResponseBody()); + } +} \ No newline at end of file diff --git a/tests/docker-compose.yaml b/tests/docker-compose.yaml new file mode 100644 index 0000000..2a86b03 --- /dev/null +++ b/tests/docker-compose.yaml @@ -0,0 +1,172 @@ +version: '2.0' + +services: + + wordpress: + image: wpdesknet/phpunit-woocommerce:0-0 + volumes: + - .././:/opt/project + depends_on: + - mysql0 + environment: + WORDPRESS_DB_NAME: wptest + WORDPRESS_DB_USER: mysql + WORDPRESS_DB_PASSWORD: mysql + WORDPRESS_DB_HOST: mysql0 + + wordpress-0-1: + image: wpdesknet/phpunit-woocommerce:0-1 + volumes: + - .././:/opt/project + depends_on: + - mysql1 + environment: + WORDPRESS_DB_NAME: wptest + WORDPRESS_DB_USER: mysql + WORDPRESS_DB_PASSWORD: mysql + WORDPRESS_DB_HOST: mysql1 + + wordpress-0-2: + image: wpdesknet/phpunit-woocommerce:0-2 + volumes: + - .././:/opt/project + depends_on: + - mysql2 + environment: + WORDPRESS_DB_NAME: wptest + WORDPRESS_DB_USER: mysql + WORDPRESS_DB_PASSWORD: mysql + WORDPRESS_DB_HOST: mysql2 + + wordpress-0-3: + image: wpdesknet/phpunit-woocommerce:0-3 + volumes: + - .././:/opt/project + depends_on: + - mysql3 + environment: + WORDPRESS_DB_NAME: wptest + WORDPRESS_DB_USER: mysql + WORDPRESS_DB_PASSWORD: mysql + WORDPRESS_DB_HOST: mysql3 + + wordpress-0-4: + image: wpdesknet/phpunit-woocommerce:0-4 + volumes: + - .././:/opt/project + depends_on: + - mysql4 + environment: + WORDPRESS_DB_NAME: wptest + WORDPRESS_DB_USER: mysql + WORDPRESS_DB_PASSWORD: mysql + WORDPRESS_DB_HOST: mysql4 + + wordpress-0-5: + image: wpdesknet/phpunit-woocommerce:0-5 + volumes: + - .././:/opt/project + depends_on: + - mysql5 + environment: + WORDPRESS_DB_NAME: wptest + WORDPRESS_DB_USER: mysql + WORDPRESS_DB_PASSWORD: mysql + WORDPRESS_DB_HOST: mysql5 + + wordpress-1-0: + image: wpdesknet/phpunit-woocommerce:1-0 + volumes: + - .././:/opt/project + depends_on: + - mysql0 + environment: + WORDPRESS_DB_NAME: wptest + WORDPRESS_DB_USER: mysql + WORDPRESS_DB_PASSWORD: mysql + WORDPRESS_DB_HOST: mysql0 + + wordpress-2-0: + image: wpdesknet/phpunit-woocommerce:2-0 + volumes: + - .././:/opt/project + depends_on: + - mysql0 + environment: + WORDPRESS_DB_NAME: wptest + WORDPRESS_DB_USER: mysql + WORDPRESS_DB_PASSWORD: mysql + WORDPRESS_DB_HOST: mysql0 + + wordpress-3-0: + image: wpdesknet/phpunit-woocommerce:3-0 + volumes: + - .././:/opt/project + depends_on: + - mysql0 + environment: + WORDPRESS_DB_NAME: wptest + WORDPRESS_DB_USER: mysql + WORDPRESS_DB_PASSWORD: mysql + WORDPRESS_DB_HOST: mysql0 + + wordpress-4-0: + image: wpdesknet/phpunit-woocommerce:4-0 + volumes: + - .././:/opt/project + depends_on: + - mysql0 + environment: + WORDPRESS_DB_NAME: wptest + WORDPRESS_DB_USER: mysql + WORDPRESS_DB_PASSWORD: mysql + WORDPRESS_DB_HOST: mysql0 + + mysql0: + image: mysql:5.7 + environment: + MYSQL_ROOT_PASSWORD: mysql + MYSQL_DATABASE: wptest + MYSQL_USER: mysql + MYSQL_PASSWORD: mysql + + mysql1: + image: mysql:5.7 + environment: + MYSQL_ROOT_PASSWORD: mysql + MYSQL_DATABASE: wptest + MYSQL_USER: mysql + MYSQL_PASSWORD: mysql + + mysql2: + image: mysql:5.7 + environment: + MYSQL_ROOT_PASSWORD: mysql + MYSQL_DATABASE: wptest + MYSQL_USER: mysql + MYSQL_PASSWORD: mysql + + mysql3: + image: mysql:5.7 + environment: + MYSQL_ROOT_PASSWORD: mysql + MYSQL_DATABASE: wptest + MYSQL_USER: mysql + MYSQL_PASSWORD: mysql + + mysql4: + image: mysql:5.7 + environment: + MYSQL_ROOT_PASSWORD: mysql + MYSQL_DATABASE: wptest + MYSQL_USER: mysql + MYSQL_PASSWORD: mysql + + mysql5: + image: mysql:5.7 + environment: + MYSQL_ROOT_PASSWORD: mysql + MYSQL_DATABASE: wptest + MYSQL_USER: mysql + MYSQL_PASSWORD: mysql + diff --git a/tests/integration/bootstrap.php b/tests/integration/bootstrap.php new file mode 100644 index 0000000..a422fd9 --- /dev/null +++ b/tests/integration/bootstrap.php @@ -0,0 +1,28 @@ +<?php + +ini_set('error_reporting', E_ALL); // or error_reporting(E_ALL); +ini_set('display_errors', '1'); +ini_set('display_startup_errors', '1'); + +require_once __DIR__ . '/../../vendor/autoload.php'; + +// disable xdebug backtrace +if ( function_exists( 'xdebug_disable' ) ) { + xdebug_disable(); +} + +if ( getenv( 'PLUGIN_PATH' ) !== false ) { + define( 'PLUGIN_PATH', getenv( 'PLUGIN_PATH' ) ); +} else { + define( 'PLUGIN_PATH', __DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR ); +} + +require_once( getenv( 'WP_DEVELOP_DIR' ) . '/tests/phpunit/includes/functions.php' ); + +tests_add_filter( 'muplugins_loaded', function () { +}, 100 ); + +putenv('WP_TESTS_DIR=' . getenv( 'WP_DEVELOP_DIR' ) . '/tests/phpunit'); +require_once( getenv( 'WC_DEVELOP_DIR' ) . '/tests/bootstrap.php' ); + +do_action('plugins_loaded'); \ No newline at end of file diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php new file mode 100644 index 0000000..76b8109 --- /dev/null +++ b/tests/unit/bootstrap.php @@ -0,0 +1,9 @@ +<?php +/** + * PHPUnit bootstrap file + */ + +require_once __DIR__ . '/../../vendor/autoload.php'; + +WP_Mock::setUsePatchwork( true ); +WP_Mock::bootstrap(); -- GitLab