From 535368ec6eab22bb8db81f62e18673bb30352f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B0=D0=B2=D0=B5=D0=BB?= Date: Mon, 28 Sep 2020 16:08:55 +0300 Subject: [PATCH] refactor, authenticator, signer --- composer.json | 6 +- .../Authenticator/TokenAuthenticator.php | 76 +++++++++++ src/Component/Constants.php | 32 +++++ .../DependencyInjection/Container.php | 6 +- src/Factory/ClientFactory.php | 26 +++- src/Factory/ContainerFactory.php | 61 +++++++-- src/Factory/UploadedFileFactory.php | 59 +++++++++ src/Interfaces/AuthenticatorInterface.php | 44 +++++++ ...terface.php => RequestSignerInterface.php} | 17 ++- ...e.php => UploadedFileFactoryInterface.php} | 16 +-- src/Model/Request/BaseRequest.php | 124 ++++++++++++++++++ src/Service/RequestBuilder.php | 28 ++++ src/Service/RequestSigner.php | 76 +++++++++++ src/TopClient/Client.php | 59 ++++++--- src/Traits/HttpClientAwareTrait.php | 44 ------- src/Traits/SerializerAwareTrait.php | 45 ------- src/Traits/ValidatorAwareTrait.php | 15 +++ ...ironmentTest.php => ClientFactoryTest.php} | 19 +-- 18 files changed, 599 insertions(+), 154 deletions(-) create mode 100644 src/Component/Authenticator/TokenAuthenticator.php create mode 100644 src/Component/Constants.php create mode 100644 src/Factory/UploadedFileFactory.php create mode 100644 src/Interfaces/AuthenticatorInterface.php rename src/Interfaces/{ValidatorAwareInterface.php => RequestSignerInterface.php} (50%) rename src/Interfaces/{HttpClientAwareInterface.php => UploadedFileFactoryInterface.php} (55%) create mode 100644 src/Model/Request/BaseRequest.php create mode 100644 src/Service/RequestBuilder.php create mode 100644 src/Service/RequestSigner.php delete mode 100644 src/Traits/HttpClientAwareTrait.php delete mode 100644 src/Traits/SerializerAwareTrait.php rename tests/Component/{EnvironmentTest.php => ClientFactoryTest.php} (60%) diff --git a/composer.json b/composer.json index 1a05623..6448dc2 100644 --- a/composer.json +++ b/composer.json @@ -21,11 +21,11 @@ "ext-curl": "*", "ext-json": "*", "psr/http-client": "^1.0", - "symfony/serializer": "^5.1", "symfony/validator": "^5.1", + "jms/serializer": "^3.9", + "shieldon/psr-http": "^1.2", "doctrine/annotations": "^1.10", - "doctrine/cache": "^1.10", - "symfony/property-access": "^5.1" + "doctrine/cache": "^1.10" }, "require-dev": { "phpunit/phpunit": "^9.3", diff --git a/src/Component/Authenticator/TokenAuthenticator.php b/src/Component/Authenticator/TokenAuthenticator.php new file mode 100644 index 0000000..c205a3e --- /dev/null +++ b/src/Component/Authenticator/TokenAuthenticator.php @@ -0,0 +1,76 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ +namespace RetailCrm\Component\Authenticator; + +use RetailCrm\Interfaces\AuthenticatorInterface; +use RetailCrm\Model\Request\BaseRequest; + +/** + * Class TokenAuthenticator + * + * @category TokenAuthenticator + * @package RetailCrm\Component\Authenticator + * @author RetailDriver LLC + * @license MIT + * @link http://retailcrm.ru + * @see https://help.retailcrm.ru + */ +class TokenAuthenticator implements AuthenticatorInterface +{ + /** + * @var string $appKey + */ + private $appKey; + + /** + * @var string $token + */ + private $token; + + /** + * TokenAuthenticator constructor. + * + * @param string $appKey + * @param string $token + */ + public function __construct(string $appKey, string $token) + { + $this->appKey = $appKey; + $this->token = $token; + } + + /** + * @param \RetailCrm\Model\Request\BaseRequest $request + */ + public function authenticate(BaseRequest $request): void + { + $request->appKey = $this->appKey; + $request->session = $this->token; + } + + /** + * @return string + */ + public function getAppKey(): string + { + return $this->appKey; + } + + /** + * @return string + */ + public function getAppSecret(): string + { + return $this->token; + } +} diff --git a/src/Component/Constants.php b/src/Component/Constants.php new file mode 100644 index 0000000..65ebfc9 --- /dev/null +++ b/src/Component/Constants.php @@ -0,0 +1,32 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ +namespace RetailCrm\Component; + +/** + * Class Constants + * + * @category Constants + * @package RetailCrm\Component + * @author RetailDriver LLC + * @license MIT + * @link http://retailcrm.ru + * @see https://help.retailcrm.ru + */ +class Constants +{ + public const HTTP_CLIENT = 'httpClient'; + public const SERIALIZER = 'serializer'; + public const VALIDATOR = 'validator'; + public const TOP_VERSION = 'top-sdk-php-20180326'; + public const UNSIGNED_MARK = '00000000000000000000000000000000'; +} diff --git a/src/Component/DependencyInjection/Container.php b/src/Component/DependencyInjection/Container.php index b791be5..0713692 100644 --- a/src/Component/DependencyInjection/Container.php +++ b/src/Component/DependencyInjection/Container.php @@ -34,17 +34,17 @@ use Throwable; * @link http://retailcrm.ru * @see https://help.retailcrm.ru */ -class Container implements ContainerInterface +final class Container implements ContainerInterface { /** * @var array $instances */ - public $instances = []; + private $instances = []; /** * @var array $definitions */ - public $definitions = []; + private $definitions = []; /** * Container constructor. diff --git a/src/Factory/ClientFactory.php b/src/Factory/ClientFactory.php index 271e192..f3dd765 100644 --- a/src/Factory/ClientFactory.php +++ b/src/Factory/ClientFactory.php @@ -13,6 +13,8 @@ namespace RetailCrm\Factory; use Psr\Container\ContainerInterface; +use RetailCrm\Component\Constants; +use RetailCrm\Interfaces\AuthenticatorInterface; use RetailCrm\Interfaces\ContainerAwareInterface; use RetailCrm\Interfaces\FactoryInterface; use RetailCrm\TopClient\Client; @@ -35,6 +37,9 @@ class ClientFactory implements ContainerAwareInterface, FactoryInterface /** @var string $serviceUrl */ private $serviceUrl; + /*** @var AuthenticatorInterface $authenticator */ + protected $authenticator; + /** * @param \Psr\Container\ContainerInterface $container * @@ -53,22 +58,33 @@ class ClientFactory implements ContainerAwareInterface, FactoryInterface * * @return $this */ - public function setServiceUrl(string $serviceUrl): ClientFactory + public function setServiceUrl(string $serviceUrl): self { $this->serviceUrl = $serviceUrl; return $this; } + /** + * @param \RetailCrm\Interfaces\AuthenticatorInterface $authenticator + * + * @return $this + */ + public function setAuthenticator(AuthenticatorInterface $authenticator): self + { + $this->authenticator = $authenticator; + return $this; + } + /** * @return \RetailCrm\TopClient\Client * @throws \RetailCrm\Component\Exception\ValidationException */ public function create(): Client { - $client = new Client($this->serviceUrl); - $client->setHttpClient($this->container->get('httpClient')); - $client->setSerializer($this->container->get('serializer')); - $client->setValidator($this->container->get('validator')); + $client = new Client($this->serviceUrl, $this->authenticator); + $client->setHttpClient($this->container->get(Constants::HTTP_CLIENT)); + $client->setSerializer($this->container->get(Constants::SERIALIZER)); + $client->setValidator($this->container->get(Constants::VALIDATOR)); $client->validateSelf(); return $client; diff --git a/src/Factory/ContainerFactory.php b/src/Factory/ContainerFactory.php index 121d419..e8772e1 100644 --- a/src/Factory/ContainerFactory.php +++ b/src/Factory/ContainerFactory.php @@ -12,18 +12,21 @@ */ namespace RetailCrm\Factory; +use JMS\Serializer\GraphNavigatorInterface; +use JMS\Serializer\Serializer; +use RetailCrm\Component\Constants; +use Shieldon\Psr17\StreamFactory; +use Shieldon\Psr17\UploadedFileFactory as BaseFactory; +use JMS\Serializer\SerializerBuilder; use Psr\Container\ContainerInterface; use Psr\Http\Client\ClientInterface; use RetailCrm\Component\DependencyInjection\Container; use RetailCrm\Component\Environment; use RetailCrm\Interfaces\FactoryInterface; -use Symfony\Component\Serializer\Encoder\JsonEncoder; -use Symfony\Component\Serializer\Encoder\XmlEncoder; -use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; -use Symfony\Component\Serializer\Serializer; use Symfony\Component\Validator\Validation; use Symfony\Component\Validator\Validator\TraceableValidator; use Symfony\Component\Validator\Validator\ValidatorInterface; +use JMS\Serializer\Handler\HandlerRegistry; /** * Class EnvironmentFactory @@ -99,14 +102,13 @@ class ContainerFactory implements FactoryInterface */ protected function setProdServices(Container $container): void { - $container->set('httpClient', $this->httpClient); - $container->set('validator', Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator()); + $container->set(Constants::HTTP_CLIENT, $this->httpClient); $container->set( - 'serializer', new Serializer( - [new ObjectNormalizer()], - [new XmlEncoder(), new JsonEncoder()] - ) + Constants::VALIDATOR, + Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator() ); + $container->set(Constants::SERIALIZER, $this->getSerializer()); + $container->set(UploadedFileFactory::class, new UploadedFileFactory(new BaseFactory(), new StreamFactory())); } /** @@ -120,4 +122,43 @@ class ContainerFactory implements FactoryInterface $container->set('validator', new TraceableValidator($validator)); } } + + /** + * @return \JMS\Serializer\Serializer + */ + protected function getSerializer(): Serializer + { + return SerializerBuilder::create() + ->configureHandlers(function(HandlerRegistry $registry) { + $returnNull = function($visitor, $obj, array $type) { + return null; + }; + + $registry->registerHandler( + GraphNavigatorInterface::DIRECTION_SERIALIZATION, + 'UploadedFileInterface', + 'json', + $returnNull + ); + $registry->registerHandler( + GraphNavigatorInterface::DIRECTION_DESERIALIZATION, + 'UploadedFileInterface', + 'json', + $returnNull + ); + $registry->registerHandler( + GraphNavigatorInterface::DIRECTION_SERIALIZATION, + 'UploadedFileInterface', + 'xml', + $returnNull + ); + $registry->registerHandler( + GraphNavigatorInterface::DIRECTION_DESERIALIZATION, + 'UploadedFileInterface', + 'xml', + $returnNull + ); + })->addDefaultHandlers() + ->build(); + } } diff --git a/src/Factory/UploadedFileFactory.php b/src/Factory/UploadedFileFactory.php new file mode 100644 index 0000000..0892295 --- /dev/null +++ b/src/Factory/UploadedFileFactory.php @@ -0,0 +1,59 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ +namespace RetailCrm\Factory; + +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\UploadedFileFactoryInterface as BaseUploadedFileFactoryInterface; +use Psr\Http\Message\UploadedFileInterface; +use RetailCrm\Interfaces\UploadedFileFactoryInterface; + +/** + * Class UploadedFileFactory + * + * @category UploadedFileFactory + * @package RetailCrm\Factory + * @author RetailDriver LLC + * @license MIT + * @link http://retailcrm.ru + * @see https://help.retailcrm.ru + */ +class UploadedFileFactory implements UploadedFileFactoryInterface +{ + /** @var BaseUploadedFileFactoryInterface $baseFactory */ + private $baseFactory; + + /** @var StreamFactoryInterface $streamFactory */ + private $streamFactory; + + /** + * UploadedFileFactory constructor. + * + * @param \Psr\Http\Message\UploadedFileFactoryInterface $baseFactory + * @param \Psr\Http\Message\StreamFactoryInterface $streamFactory + */ + public function __construct(BaseUploadedFileFactoryInterface $baseFactory, StreamFactoryInterface $streamFactory) + { + $this->baseFactory = $baseFactory; + $this->streamFactory = $streamFactory; + } + + /** + * @param string $fileName + * + * @return \Psr\Http\Message\UploadedFileInterface + */ + public function create(string $fileName): UploadedFileInterface + { + return $this->baseFactory->createUploadedFile($this->streamFactory->createStreamFromFile($fileName)); + } +} diff --git a/src/Interfaces/AuthenticatorInterface.php b/src/Interfaces/AuthenticatorInterface.php new file mode 100644 index 0000000..81dff47 --- /dev/null +++ b/src/Interfaces/AuthenticatorInterface.php @@ -0,0 +1,44 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ + +namespace RetailCrm\Interfaces; + +use RetailCrm\Model\Request\BaseRequest; + +/** + * Interface AuthenticatorInterface + * + * @category AuthenticatorInterface + * @package RetailCrm\Interfaces + * @author RetailDriver LLC + * @license MIT + * @link http://retailcrm.ru + * @see https://help.retailcrm.ru + */ +interface AuthenticatorInterface +{ + /** + * @param \RetailCrm\Model\Request\BaseRequest $request + */ + public function authenticate(BaseRequest $request): void; + + /** + * @return string + */ + public function getAppKey(): string; + + /** + * @return string + */ + public function getAppSecret(): string; +} diff --git a/src/Interfaces/ValidatorAwareInterface.php b/src/Interfaces/RequestSignerInterface.php similarity index 50% rename from src/Interfaces/ValidatorAwareInterface.php rename to src/Interfaces/RequestSignerInterface.php index 7c75c47..a4c4306 100644 --- a/src/Interfaces/ValidatorAwareInterface.php +++ b/src/Interfaces/RequestSignerInterface.php @@ -3,7 +3,7 @@ /** * PHP version 7.3 * - * @category ValidatorAwareInterface + * @category RequestSignerInterface * @package RetailCrm\Interfaces * @author RetailCRM * @license MIT @@ -13,22 +13,25 @@ namespace RetailCrm\Interfaces; -use Symfony\Component\Validator\Validator\ValidatorInterface; +use RetailCrm\Model\Request\BaseRequest; /** - * Interface ValidatorAwareInterface + * Interface RequestSignerInterface * - * @category ValidatorAwareInterface + * @category RequestSignerInterface * @package RetailCrm\Interfaces * @author RetailDriver LLC * @license MIT * @link http://retailcrm.ru * @see https://help.retailcrm.ru */ -interface ValidatorAwareInterface +interface RequestSignerInterface { /** - * @param \Symfony\Component\Validator\Validator\ValidatorInterface $validator + * Signs provided request. + * + * @param \RetailCrm\Model\Request\BaseRequest $request + * @param \RetailCrm\Interfaces\AuthenticatorInterface $authenticator */ - public function setValidator(ValidatorInterface $validator): void; + public function sign(BaseRequest $request, AuthenticatorInterface $authenticator): void; } diff --git a/src/Interfaces/HttpClientAwareInterface.php b/src/Interfaces/UploadedFileFactoryInterface.php similarity index 55% rename from src/Interfaces/HttpClientAwareInterface.php rename to src/Interfaces/UploadedFileFactoryInterface.php index c39dd59..ff77cca 100644 --- a/src/Interfaces/HttpClientAwareInterface.php +++ b/src/Interfaces/UploadedFileFactoryInterface.php @@ -3,7 +3,7 @@ /** * PHP version 7.3 * - * @category ClientAwareInterface + * @category UploadedFileFactoryInterface * @package RetailCrm\Interfaces * @author RetailCRM * @license MIT @@ -13,24 +13,24 @@ namespace RetailCrm\Interfaces; -use Psr\Http\Client\ClientInterface; +use Psr\Http\Message\UploadedFileInterface; /** - * Interface HttpClientAwareInterface + * Interface UploadedFileFactoryInterface * - * @category HttpClientAwareInterface + * @category UploadedFileFactoryInterface * @package RetailCrm\Interfaces * @author RetailDriver LLC * @license MIT * @link http://retailcrm.ru * @see https://help.retailcrm.ru */ -interface HttpClientAwareInterface +interface UploadedFileFactoryInterface { /** - * @param \Psr\Http\Client\ClientInterface $httpClient + * @param string $fileName * - * @return mixed + * @return \Psr\Http\Message\UploadedFileInterface */ - public function setHttpClient(ClientInterface $httpClient): void; + public function create(string $fileName): UploadedFileInterface; } diff --git a/src/Model/Request/BaseRequest.php b/src/Model/Request/BaseRequest.php new file mode 100644 index 0000000..4a60805 --- /dev/null +++ b/src/Model/Request/BaseRequest.php @@ -0,0 +1,124 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ +namespace RetailCrm\Model\Request; + +use JMS\Serializer\Annotation as JMS; +use RetailCrm\Component\Constants; +use Symfony\Component\Validator\Constraints as Assert; + +/** + * Class BaseRequest + * + * @category BaseRequest + * @package RetailCrm\Model\Request + * @author RetailDriver LLC + * @license MIT + * @link http://retailcrm.ru + * @see https://help.retailcrm.ru + */ +abstract class BaseRequest +{ + /** + * @var string $method + * + * @JMS\Type("string") + * @JMS\SerializedName("method") + * @Assert\NotBlank() + */ + public $method; + + /** + * @var string $appKey + * + * @JMS\Type("string") + * @JMS\SerializedName("app_key") + * @Assert\NotBlank() + */ + public $appKey; + + /** + * @var string $appKey + * + * @JMS\Type("string") + * @JMS\SerializedName("session") + * @Assert\NotBlank() + */ + public $session; + + /** + * @var \DateTime $timestamp + * + * @JMS\Type("DateTime<'yyyy-MM-dd H:i:s'>") + * @JMS\SerializedName("timestamp") + * @Assert\NotBlank() + */ + public $timestamp; + + /** + * @var string $format + * + * @JMS\Type("string") + * @JMS\SerializedName("format") + * @Assert\NotBlank() + * @Assert\Choice({"xml", "json"}) + */ + public $format = 'json'; + + /** + * @var string $version + * + * @JMS\Type("string") + * @JMS\SerializedName("v") + * @Assert\NotBlank() + * @Assert\Choice({"2.0"}) + */ + public $version = '2.0'; + + /** + * @var bool $simplify + * + * @JMS\Type("bool") + * @JMS\SerializedName("simplify") + * @Assert\NotBlank() + */ + public $simplify = false; + + /** + * @var string $signMethod + * + * @JMS\Type("string") + * @JMS\SerializedName("sign_method") + * @Assert\NotBlank() + * @Assert\Choice({"hmac", "md5"}) + */ + public $signMethod = 'hmac'; + + /** + * @var string $sign + * + * @JMS\Type("string") + * @JMS\SerializedName("sign") + * @Assert\NotBlank() + * @Assert\Length(min="32", max="32") + */ + public $sign = Constants::UNSIGNED_MARK; + + /** + * @var string $partnerId + * + * @JMS\Type("string") + * @JMS\SerializedName("partner_id") + * @Assert\NotBlank() + */ + public $partnerId = Constants::TOP_VERSION; +} diff --git a/src/Service/RequestBuilder.php b/src/Service/RequestBuilder.php new file mode 100644 index 0000000..8365fd4 --- /dev/null +++ b/src/Service/RequestBuilder.php @@ -0,0 +1,28 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ +namespace RetailCrm\Service; + +/** + * Class RequestBuilder + * + * @category RequestBuilder + * @package RetailCrm\Service + * @author RetailDriver LLC + * @license MIT + * @link http://retailcrm.ru + * @see https://help.retailcrm.ru + */ +class RequestBuilder +{ + +} diff --git a/src/Service/RequestSigner.php b/src/Service/RequestSigner.php new file mode 100644 index 0000000..0d1a8c3 --- /dev/null +++ b/src/Service/RequestSigner.php @@ -0,0 +1,76 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ +namespace RetailCrm\Service; + +use JMS\Serializer\SerializerInterface; +use RetailCrm\Interfaces\AuthenticatorInterface; +use RetailCrm\Interfaces\RequestSignerInterface; +use RetailCrm\Model\Request\BaseRequest; + +/** + * Class RequestSigner + * + * @category RequestSigner + * @package RetailCrm\Service + * @author RetailDriver LLC + * @license MIT + * @link http://retailcrm.ru + * @see https://help.retailcrm.ru + */ +class RequestSigner implements RequestSignerInterface +{ + /** + * @var SerializerInterface|\JMS\Serializer\Serializer $serializer + */ + public $serializer; + + /** + * RequestSigner constructor. + * + * @param \JMS\Serializer\SerializerInterface $serializer + */ + public function __construct(SerializerInterface $serializer) + { + $this->serializer = $serializer; + } + + /** + * @param BaseRequest $request + * @param \RetailCrm\Interfaces\AuthenticatorInterface $authenticator + */ + public function sign(BaseRequest $request, AuthenticatorInterface $authenticator): void + { + $stringToBeSigned = ''; + $params = $this->getRequestData($request); + + foreach ($params as $param => $value) { + $stringToBeSigned .= $param . $value; + } + + $request->sign = hash_hmac('md5', $stringToBeSigned, $authenticator->getAppSecret()); + } + + /** + * @param \RetailCrm\Model\Request\BaseRequest $request + * + * @return array + */ + private function getRequestData(BaseRequest $request): array + { + $params = array_filter($this->serializer->toArray($request)); + unset($params['sign']); + ksort($params); + + return $params; + } +} diff --git a/src/TopClient/Client.php b/src/TopClient/Client.php index ba0c4a1..767dd3b 100644 --- a/src/TopClient/Client.php +++ b/src/TopClient/Client.php @@ -12,13 +12,10 @@ */ namespace RetailCrm\TopClient; -use RetailCrm\Component\Exception\ValidationException; -use RetailCrm\Interfaces\HttpClientAwareInterface; -use RetailCrm\Interfaces\ValidatorAwareInterface; -use RetailCrm\Traits\HttpClientAwareTrait; -use RetailCrm\Traits\SerializerAwareTrait; +use JMS\Serializer\SerializerInterface; +use Psr\Http\Client\ClientInterface; +use RetailCrm\Interfaces\AuthenticatorInterface; use RetailCrm\Traits\ValidatorAwareTrait; -use Symfony\Component\Serializer\SerializerAwareInterface; use Symfony\Component\Validator\Constraints as Assert; /** @@ -31,31 +28,49 @@ use Symfony\Component\Validator\Constraints as Assert; * @link http://retailcrm.ru * @see https://help.retailcrm.ru */ -class Client implements SerializerAwareInterface, HttpClientAwareInterface, ValidatorAwareInterface +class Client { use ValidatorAwareTrait; - use HttpClientAwareTrait; - use SerializerAwareTrait; public const OVERSEAS_ENDPOINT = 'https://api.taobao.com/router/rest'; public const CHINESE_ENDPOINT = 'https://eco.taobao.com/router/rest'; public const AVAILABLE_ENDPOINTS = [self::OVERSEAS_ENDPOINT, self::CHINESE_ENDPOINT]; /** - * @var string $serviceUrl + * @var string $serviceUrl * @Assert\Url() - * @Assert\Choice(choices=Client::AVAILABLE_ENDPOINTS, message="Choose a valid endpoint.") + * @Assert\Choice(choices=Client::AVAILABLE_ENDPOINTS, message="Invalid endpoint provided.") */ protected $serviceUrl; + /** + * @var AuthenticatorInterface $authenticator + * @Assert\NotNull(message="Authenticator should be provided") + */ + protected $authenticator; + + /** + * @var ClientInterface $httpClient + * @Assert\NotNull(message="HTTP client should be provided") + */ + protected $httpClient; + + /** + * @var SerializerInterface $serializer + * @Assert\NotNull(message="Serializer should be provided") + */ + protected $serializer; + /** * Client constructor. * - * @param string serviceUrl + * @param string $serviceUrl + * @param \RetailCrm\Interfaces\AuthenticatorInterface $authenticator */ - public function __construct(string $serviceUrl) + public function __construct(string $serviceUrl, AuthenticatorInterface $authenticator) { $this->serviceUrl = $serviceUrl; + $this->authenticator = $authenticator; } /** @@ -67,16 +82,18 @@ class Client implements SerializerAwareInterface, HttpClientAwareInterface, Vali } /** - * @param mixed $item - * - * @throws \RetailCrm\Component\Exception\ValidationException + * @param \Psr\Http\Client\ClientInterface $httpClient */ - private function validate($item): void + public function setHttpClient(ClientInterface $httpClient): void { - $violations = $this->validator->validate($item); + $this->httpClient = $httpClient; + } - if ($violations->count()) { - throw new ValidationException("Invalid data", $violations); - } + /** + * @param \JMS\Serializer\SerializerInterface $serializer + */ + public function setSerializer(SerializerInterface $serializer): void + { + $this->serializer = $serializer; } } diff --git a/src/Traits/HttpClientAwareTrait.php b/src/Traits/HttpClientAwareTrait.php deleted file mode 100644 index db9fbe6..0000000 --- a/src/Traits/HttpClientAwareTrait.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @license MIT - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ - -namespace RetailCrm\Traits; - -use Psr\Http\Client\ClientInterface; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * Trait HttpClientAwareTrait - * - * @category HttpClientAwareTrait - * @package RetailCrm\Traits - * @author RetailDriver LLC - * @license MIT - * @link http://retailcrm.ru - * @see https://help.retailcrm.ru - */ -trait HttpClientAwareTrait -{ - /** - * @var ClientInterface $httpClient - * @Assert\NotNull(message="HTTP client should be provided") - */ - protected $httpClient; - - /** - * @param \Psr\Http\Client\ClientInterface $httpClient - */ - public function setHttpClient(ClientInterface $httpClient): void - { - $this->httpClient = $httpClient; - } -} diff --git a/src/Traits/SerializerAwareTrait.php b/src/Traits/SerializerAwareTrait.php deleted file mode 100644 index 96b992b..0000000 --- a/src/Traits/SerializerAwareTrait.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @license MIT - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ - -namespace RetailCrm\Traits; - -use Symfony\Component\Validator\Constraints as Assert; -use Symfony\Component\Serializer\SerializerInterface; - -/** - * Trait SerializerAwareTrait - * - * @category SerializerAwareTrait - * @package RetailCrm\Traits - * @author Joel Wurtz - * @author RetailDriver LLC - * @license MIT - * @link http://retailcrm.ru - * @see https://help.retailcrm.ru - */ -trait SerializerAwareTrait -{ - /** - * @var SerializerInterface $serializer - * @Assert\NotNull(message="Serializer should be provided") - */ - protected $serializer; - - /** - * @param \Symfony\Component\Serializer\SerializerInterface $serializer - */ - public function setSerializer(SerializerInterface $serializer): void - { - $this->serializer = $serializer; - } -} diff --git a/src/Traits/ValidatorAwareTrait.php b/src/Traits/ValidatorAwareTrait.php index 8902972..cb3e114 100644 --- a/src/Traits/ValidatorAwareTrait.php +++ b/src/Traits/ValidatorAwareTrait.php @@ -14,6 +14,7 @@ namespace RetailCrm\Traits; use Symfony\Component\Validator\Constraints as Assert; +use RetailCrm\Component\Exception\ValidationException; use Symfony\Component\Validator\Validator\ValidatorInterface; /** @@ -41,4 +42,18 @@ trait ValidatorAwareTrait { $this->validator = $validator; } + + /** + * @param mixed $item + * + * @throws \RetailCrm\Component\Exception\ValidationException + */ + protected function validate($item): void + { + $violations = $this->validator->validate($item); + + if ($violations->count()) { + throw new ValidationException("Invalid data", $violations); + } + } } diff --git a/tests/Component/EnvironmentTest.php b/tests/Component/ClientFactoryTest.php similarity index 60% rename from tests/Component/EnvironmentTest.php rename to tests/Component/ClientFactoryTest.php index fac65f3..8e8eb4e 100644 --- a/tests/Component/EnvironmentTest.php +++ b/tests/Component/ClientFactoryTest.php @@ -3,7 +3,7 @@ /** * PHP version 7.4 * - * @category EnvironmentTest + * @category ClientFactoryTest * @package Component * @author RetailCRM * @license MIT @@ -13,30 +13,33 @@ namespace Component; use PHPUnit\Framework\TestCase; +use RetailCrm\Component\Authenticator\TokenAuthenticator; use RetailCrm\Component\Environment; use RetailCrm\Factory\ClientFactory; use RetailCrm\Factory\ContainerFactory; use RetailCrm\TopClient\Client; /** - * Class EnvironmentTest + * Class ClientFactoryTest * - * @category EnvironmentTest + * @category ClientFactoryTest * @package Component * @author RetailDriver LLC * @license MIT * @link http://retailcrm.ru * @see https://help.retailcrm.ru */ -class EnvironmentTest extends TestCase +class ClientFactoryTest extends TestCase { public function testCreateClient() { $client = ClientFactory::withContainer( - ContainerFactory::withEnv(Environment::DEV) - ->withClient(new \GuzzleHttp\Client()) - ->create() - )->setServiceUrl(Client::OVERSEAS_ENDPOINT)->create(); + ContainerFactory::withEnv(Environment::DEV) + ->withClient(new \GuzzleHttp\Client()) + ->create() + )->setServiceUrl(Client::OVERSEAS_ENDPOINT) + ->setAuthenticator(new TokenAuthenticator('appKey', 'token')) + ->create(); self::assertInstanceOf(Client::class, $client); }