1
0
mirror of synced 2024-11-25 14:26:05 +03:00

WIP: Hacks for inline JSON string inside another JSON or inside XML (some responses actually look like that)

This commit is contained in:
Pavel 2020-09-30 17:50:44 +03:00
parent efd71698ca
commit 9b081e2e7f
26 changed files with 407 additions and 206 deletions

View File

@ -18,14 +18,11 @@ Details about those third-party libraries and why you need to install them can b
use RetailCrm\Component\AppData;
use RetailCrm\Builder\ClientBuilder;
use RetailCrm\Builder\ContainerBuilder;
use RetailCrm\Component\Authenticator\TokenAuthenticator;
$authenticator = new TokenAuthenticator('appKey', 'token');
$appData = new AppData(AppData::OVERSEAS_ENDPOINT, 'appKey', 'appSecret');
$client = ClientBuilder::create()
->setContainer(ContainerBuilder::create()->build())
->setAppData($appData)
->setAuthenticator($authenticator)
->build();
```
@ -39,7 +36,6 @@ use RetailCrm\Component\Environment;
use RetailCrm\Component\Logger\StdoutLogger;
use RetailCrm\Builder\ClientBuilder;
use RetailCrm\Builder\ContainerBuilder;
use RetailCrm\Component\Authenticator\TokenAuthenticator;
$client = new Client();
$logger = new StdoutLogger();
@ -57,7 +53,8 @@ $container = ContainerBuilder::create()
$client = ClientBuilder::create()
->setContainer($container)
->setAppData($appData)
->setAuthenticator($authenticator)
->build();
```
Logger should implement `Psr\Log\LoggerInterface` (PSR-3), HTTP client should implement `Psr\Http\Client\ClientInterface` (PSR-18), HTTP objects must be compliant to PSR-7.
You can use your own container - it must be compliant to PSR-11. But this is strongly discouraged because it'll be much easier to just integrate library with your own application, and your own DI system.

View File

@ -15,7 +15,6 @@ namespace RetailCrm\Builder;
use RetailCrm\Component\Constants;
use RetailCrm\Component\ServiceLocator;
use RetailCrm\Interfaces\AppDataInterface;
use RetailCrm\Interfaces\AuthenticatorInterface;
use RetailCrm\Interfaces\BuilderInterface;
use RetailCrm\Interfaces\ContainerAwareInterface;
use RetailCrm\Interfaces\TopRequestFactoryInterface;
@ -40,9 +39,6 @@ class ClientBuilder implements ContainerAwareInterface, BuilderInterface
/** @var \RetailCrm\Interfaces\AppDataInterface $appData */
private $appData;
/*** @var AuthenticatorInterface $authenticator */
protected $authenticator;
/**
* @return static
*/
@ -62,24 +58,13 @@ class ClientBuilder implements ContainerAwareInterface, BuilderInterface
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 build(): Client
{
$client = new Client($this->appData, $this->authenticator);
$client = new Client($this->appData);
$client->setHttpClient($this->container->get(Constants::HTTP_CLIENT));
$client->setSerializer($this->container->get(Constants::SERIALIZER));
$client->setValidator($this->container->get(Constants::VALIDATOR));

View File

@ -1,60 +0,0 @@
<?php
/**
* PHP version 7.3
*
* @category TokenAuthenticator
* @package RetailCrm\Component\Authenticator
* @author RetailCRM <integration@retailcrm.ru>
* @license MIT https://mit-license.org
* @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 <integration@retailcrm.ru>
* @license MIT https://mit-license.org
* @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;
}
}

View File

@ -42,20 +42,21 @@ class TopApiException extends Exception
* TopApiException constructor.
*
* @param \RetailCrm\Model\Response\Body\ErrorResponseBody $responseBody
* @param string|null $requestId
* @param \Throwable|null $previous
*/
public function __construct(ErrorResponseBody $responseBody, Throwable $previous = null)
public function __construct(ErrorResponseBody $responseBody, ?string $requestId, Throwable $previous = null)
{
parent::__construct($responseBody->msg, $responseBody->code, $previous);
$this->subCode = $responseBody->subCode;
$this->requestId = $responseBody->requestId;
$this->requestId = $requestId;
}
/**
* @return string
*/
public function getSubCode(): string
public function getSubCode(): ?string
{
return $this->subCode;
}
@ -63,7 +64,7 @@ class TopApiException extends Exception
/**
* @return string
*/
public function getRequestId(): string
public function getRequestId(): ?string
{
return $this->requestId;
}

View File

@ -0,0 +1,201 @@
<?php
/**
* PHP version 7.3
*
* @category InlineJsonBodyHandler
* @package RetailCrm\Component\Serializer
* @author RetailCRM <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see http://help.retailcrm.ru
*/
namespace RetailCrm\Component\Serializer;
use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\GraphNavigatorInterface;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonSerializationVisitor;
use JMS\Serializer\Metadata\PropertyMetadata;
use JMS\Serializer\Metadata\StaticPropertyMetadata;
use JMS\Serializer\Visitor\DeserializationVisitorInterface;
use JMS\Serializer\Visitor\SerializationVisitorInterface;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use ReflectionClass;
/**
* Class InlineJsonBodyHandler
*
* @category InlineJsonBodyHandler
* @package RetailCrm\Component\Serializer
* @author RetailDriver LLC <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see https://help.retailcrm.ru
* @todo Doesn't work as expected.
*/
class InlineJsonBodyHandler implements SubscribingHandlerInterface
{
/**
* @param \JMS\Serializer\Visitor\SerializationVisitorInterface $visitor
* @param mixed $item
* @param array $type
* @param \JMS\Serializer\Context $context
*
* @return false|string
* @throws \JsonException
* @throws \ReflectionException
*/
public function serialize(SerializationVisitorInterface $visitor, $item, array $type, Context $context)
{
$typeName = $type['name'];
$classMetadata = $context->getMetadataFactory()->getMetadataForClass($typeName);
$reflection = new ReflectionClass($type['name']);
$visitor->startVisitingObject($classMetadata, $item, ['name' => $typeName]);
foreach ($reflection->getProperties() as $property) {
if ($property->isStatic()) {
continue;
}
if (!$property->isPublic()) {
$property->setAccessible(true);
}
$value = $property->getValue($item);
$metadata = new StaticPropertyMetadata($type['name'], $property->getName(), $value);
$visitor->visitProperty($metadata, $value);
}
return json_encode(
$visitor->endVisitingObject($classMetadata, $item, ['name' => $typeName]),
JSON_THROW_ON_ERROR
);
}
/**
* @param \JMS\Serializer\Visitor\DeserializationVisitorInterface $visitor
* @param string $json
* @param array $type
* @param \JMS\Serializer\Context $context
*
* @return object
* @throws \JsonException
* @throws \ReflectionException
*/
public function deserialize(DeserializationVisitorInterface $visitor, $json, array $type, Context $context)
{
$typeName = $type['name'];
$instance = new $type['name'];
$classMetadata = $context->getMetadataFactory()->getMetadataForClass($typeName);
$reflection = new ReflectionClass($type['name']);
$jsonData = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
$visitor->startVisitingObject($classMetadata, $instance, ['name' => $typeName]);
foreach ($reflection->getProperties() as $property) {
if ($property->isStatic()) {
continue;
}
if (!$property->isPublic()) {
$property->setAccessible(true);
}
$metadata = new PropertyMetadata($type['name'], $property->getName());
$property->setValue($instance, $visitor->visitProperty($metadata, $jsonData));
}
$result = $visitor->endVisitingObject($classMetadata, $instance, ['name' => $typeName]);
return $visitor->getResult($result);
}
/**
* @return array
*/
public static function getSubscribingMethods()
{
$methods = [];
foreach (self::getInlineJsonBodyModels() as $type) {
$methods[] = [
'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => $type,
'method' => 'serialize',
];
$methods[] = [
'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION,
'format' => 'json',
'type' => $type,
'method' => 'deserialize',
];
$methods[] = [
'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION,
'format' => 'xml',
'type' => $type,
'method' => 'serialize',
];
$methods[] = [
'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION,
'format' => 'xml',
'type' => $type,
'method' => 'deserialize',
];
}
return $methods;
}
/**
* @return array
* @todo That's horrifying. Maybe find better solution?
*/
private static function getInlineJsonBodyModels(): array
{
$items = [];
$rootDir = realpath(dirname(__DIR__) . '/..');
$directory = new RecursiveDirectoryIterator(
__DIR__ . '/../../Model/Response/Body/InlineJsonBody',
RecursiveDirectoryIterator::SKIP_DOTS
);
$fileIterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::LEAVES_ONLY);
/** @var \SplFileObject $file */
foreach ($fileIterator as $file) {
if ('php' !== $file->getExtension()) {
continue;
}
$items[] = self::pathToClasspath($rootDir, $file->getPath(), $file->getFilename());
}
return $items;
}
/**
* @param string $root
* @param string $path
* @param string $fileName
*
* @return string
*/
private static function pathToClasspath(string $root, string $path, string $fileName): string
{
return 'RetailCrm\\' .
str_replace(
DIRECTORY_SEPARATOR,
'\\',
str_replace(
$root . DIRECTORY_SEPARATOR,
'',
realpath($path)
)
) . '\\' . trim(substr($fileName, 0, -4));
}
}

View File

@ -19,6 +19,7 @@ use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\SerializerInterface;
use Psr\Container\ContainerInterface;
use RetailCrm\Component\Constants;
use RetailCrm\Component\Serializer\InlineJsonBodyHandler;
use RetailCrm\Interfaces\FactoryInterface;
/**
@ -73,17 +74,17 @@ class SerializerFactory implements FactoryInterface
$returnSame = function ($visitor, $obj, array $type) {
return $obj;
};
$serializeJson = function ($visitor, $obj, array $type) use ($container) {
/** @var SerializerInterface $serializer */
$serializer = $container->get(Constants::SERIALIZER);
return $serializer->serialize($obj, 'json');
};
$registry->registerHandler(
GraphNavigatorInterface::DIRECTION_SERIALIZATION,
'RequestDtoInterface',
'json',
function ($visitor, $obj, array $type) use ($container) {
/** @var SerializerInterface $serializer */
$serializer = $container->get(Constants::SERIALIZER);
return $serializer->serialize($obj, 'json');
}
$serializeJson
);
$registry->registerHandler(
GraphNavigatorInterface::DIRECTION_DESERIALIZATION,
@ -132,6 +133,7 @@ class SerializerFactory implements FactoryInterface
'xml',
$returnNull
);
$registry->registerSubscribingHandler(new InlineJsonBodyHandler());
})->addDefaultHandlers()
->setSerializationContextFactory(new SerializationContextFactory())
->build();

View File

@ -20,7 +20,6 @@ use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UriFactoryInterface;
use RetailCrm\Component\Exception\FactoryException;
use RetailCrm\Interfaces\AppDataInterface;
use RetailCrm\Interfaces\AuthenticatorInterface;
use RetailCrm\Interfaces\FileItemInterface;
use RetailCrm\Interfaces\TopRequestFactoryInterface;
use RetailCrm\Model\Request\BaseRequest;
@ -123,19 +122,19 @@ class TopRequestFactory implements TopRequestFactoryInterface
/**
* @param \RetailCrm\Model\Request\BaseRequest $request
* @param \RetailCrm\Interfaces\AppDataInterface $appData
* @param \RetailCrm\Interfaces\AuthenticatorInterface $authenticator
*
* @return \Psr\Http\Message\RequestInterface
* @throws \RetailCrm\Component\Exception\FactoryException
*/
public function fromModel(
BaseRequest $request,
AppDataInterface $appData,
AuthenticatorInterface $authenticator
AppDataInterface $appData
): RequestInterface {
$requestData = $this->serializer->toArray($request);
$requestHasBinaryData = $this->filter->hasBinaryFromRequestData($requestData);
ksort($requestData);
if (empty($requestData)) {
throw new FactoryException('Empty request data');
}

View File

@ -1,34 +0,0 @@
<?php
/**
* PHP version 7.3
*
* @category AuthenticatorInterface
* @package RetailCrm\Interfaces
* @author RetailCRM <integration@retailcrm.ru>
* @license MIT https://mit-license.org
* @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 <integration@retailcrm.ru>
* @license MIT https://mit-license.org
* @link http://retailcrm.ru
* @see https://help.retailcrm.ru
*/
interface AuthenticatorInterface
{
/**
* @param \RetailCrm\Model\Request\BaseRequest $request
*/
public function authenticate(BaseRequest $request): void;
}

View File

@ -31,7 +31,6 @@ interface TopRequestFactoryInterface
/**
* @param \RetailCrm\Model\Request\BaseRequest $request
* @param \RetailCrm\Interfaces\AppDataInterface $appData
* @param \RetailCrm\Interfaces\AuthenticatorInterface $authenticator
*
* @return RequestInterface
* @throws \RetailCrm\Component\Exception\FactoryException
@ -39,7 +38,6 @@ interface TopRequestFactoryInterface
*/
public function fromModel(
BaseRequest $request,
AppDataInterface $appData,
AuthenticatorInterface $authenticator
AppDataInterface $appData
): RequestInterface;
}

View File

@ -33,7 +33,6 @@ interface TopRequestProcessorInterface
*
* @param \RetailCrm\Model\Request\BaseRequest $request
* @param \RetailCrm\Interfaces\AppDataInterface $appData
* @param \RetailCrm\Interfaces\AuthenticatorInterface $authenticator
*
* @return void
* @throws \RetailCrm\Component\Exception\FactoryException
@ -41,7 +40,6 @@ interface TopRequestProcessorInterface
*/
public function process(
BaseRequest $request,
AppDataInterface $appData,
AuthenticatorInterface $authenticator
AppDataInterface $appData
): void;
}

View File

@ -53,7 +53,7 @@ abstract class BaseRequest
*
* @JMS\Type("string")
* @JMS\SerializedName("session")
* @Assert\NotBlank()
* @JMS\SkipWhenEmpty()
*/
public $session;
@ -91,6 +91,7 @@ abstract class BaseRequest
*
* @JMS\Type("bool")
* @JMS\SerializedName("simplify")
* @JMS\Accessor(getter="isSimplify")
*/
public $simplify = false;
@ -131,6 +132,14 @@ abstract class BaseRequest
$this->method = $this->getMethod();
}
/**
* @return bool|null
*/
public function isSimplify(): ?bool
{
return $this->simplify ? true : null;
}
/**
* @param string $method
*

View File

@ -12,7 +12,7 @@
*/
namespace RetailCrm\Model\Request;
use RetailCrm\Model\Response\BaseResponse;
use RetailCrm\Model\Response\HttpDnsGetResponse;
/**
* Class HttpDnsGetRequest
@ -43,7 +43,6 @@ class HttpDnsGetRequest extends BaseRequest
*/
public function getExpectedResponse(): string
{
// TODO: Implement getExpectedResponse() method.
return BaseResponse::class;
return HttpDnsGetResponse::class;
}
}

View File

@ -24,7 +24,7 @@ use JMS\Serializer\Annotation as JMS;
* @link http://retailcrm.ru
* @see https://help.retailcrm.ru
*/
class BaseResponse
class BaseResponse implements TopResponseInterface
{
/**
* @var \RetailCrm\Model\Response\Body\ErrorResponseBody
@ -33,4 +33,12 @@ class BaseResponse
* @JMS\SerializedName("error_response")
*/
public $errorResponse;
/**
* @var string $requestId
*
* @JMS\Type("string")
* @JMS\SerializedName("request_id")
*/
public $requestId;
}

View File

@ -49,12 +49,4 @@ class ErrorResponseBody
* @JMS\SerializedName("sub_code")
*/
public $subCode;
/**
* @var string $requestId
*
* @JMS\Type("string")
* @JMS\SerializedName("request_id")
*/
public $requestId;
}

View File

@ -0,0 +1,36 @@
<?php
/**
* PHP version 7.3
*
* @category HttpDnsGetResponseResult
* @package RetailCrm\Model\Response\Body\InlineJsonBody
* @author RetailCRM <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see http://help.retailcrm.ru
*/
namespace RetailCrm\Model\Response\Body\InlineJsonBody;
use JMS\Serializer\Annotation as JMS;
/**
* Class HttpDnsGetResponseResult
*
* @category HttpDnsGetResponseResult
* @package RetailCrm\Model\Response\Body\InlineJsonBody
* @author RetailDriver LLC <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see https://help.retailcrm.ru
*/
class HttpDnsGetResponseResult
{
/**
* @var array $env
*
* @JMS\Type("int")
* @JMS\SerializedName("env")
*/
public $env;
}

View File

@ -0,0 +1,37 @@
<?php
/**
* PHP version 7.3
*
* @category HttpDnsGetResponseData
* @package RetailCrm\Model\Response\Data
* @author RetailCRM <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see http://help.retailcrm.ru
*/
namespace RetailCrm\Model\Response\Data;
use JMS\Serializer\Annotation as JMS;
use RetailCrm\Model\Response\Body\InlineJsonBody\HttpDnsGetResponseResult;
/**
* Class HttpDnsGetResponseData
*
* @category HttpDnsGetResponseData
* @package RetailCrm\Model\Response\Data
* @author RetailDriver LLC <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see https://help.retailcrm.ru
*/
class HttpDnsGetResponseData
{
/**
* @var HttpDnsGetResponseResult $result
*
* @JMS\Type("RetailCrm\Model\Response\Body\InlineJsonBody\HttpDnsGetResponseResult")
* @JMS\SerializedName("result")
*/
public $result;
}

View File

@ -0,0 +1,36 @@
<?php
/**
* PHP version 7.3
*
* @category HttpDnsGetResponse
* @package RetailCrm\Model\Response
* @author RetailCRM <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see http://help.retailcrm.ru
*/
namespace RetailCrm\Model\Response;
use JMS\Serializer\Annotation as JMS;
/**
* Class HttpDnsGetResponse
*
* @category HttpDnsGetResponse
* @package RetailCrm\Model\Response
* @author RetailDriver LLC <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see https://help.retailcrm.ru
*/
class HttpDnsGetResponse extends BaseResponse
{
/**
* @var \RetailCrm\Model\Response\Data\HttpDnsGetResponseData $responseData
*
* @JMS\Type("RetailCrm\Model\Response\Data\HttpDnsGetResponseData")
* @JMS\SerializedName("httpdns_get_response")
*/
public $responseData;
}

View File

@ -0,0 +1,28 @@
<?php
/**
* PHP version 7.3
*
* @category TopResponseInterface
* @package RetailCrm\Model\Response
* @author RetailCRM <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see http://help.retailcrm.ru
*/
namespace RetailCrm\Model\Response;
/**
* Interface TopResponseInterface
*
* @category TopResponseInterface
* @package RetailCrm\Model\Response
* @author RetailDriver LLC <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see https://help.retailcrm.ru
*/
interface TopResponseInterface
{
}

View File

@ -70,9 +70,8 @@ class RequestSigner implements RequestSignerInterface
switch ($request->signMethod) {
case Constants::SIGN_TYPE_MD5:
$request->sign = strtoupper(md5(
$appData->getAppSecret() . $stringToBeSigned . $appData->getAppSecret()
));
$stringToBeSigned = $appData->getAppSecret() . $stringToBeSigned . $appData->getAppSecret();
$request->sign = strtoupper(md5($stringToBeSigned));
break;
case Constants::SIGN_TYPE_HMAC:
$request->sign = strtoupper(hash_hmac('md5', $stringToBeSigned, $appData->getAppSecret()));
@ -91,7 +90,11 @@ class RequestSigner implements RequestSignerInterface
private function getDataForSigning(BaseRequest $request): array
{
$params = $this->filter->filterBinaryFromRequestData($this->serializer->toArray($request));
unset($params['sign']);
$params = array_filter(array_filter($params, static function ($val) {
return !is_array($val);
}));
unset($params['sign'], $params['session']);
ksort($params);
return $params;

View File

@ -13,7 +13,6 @@
namespace RetailCrm\Service;
use RetailCrm\Interfaces\AppDataInterface;
use RetailCrm\Interfaces\AuthenticatorInterface;
use RetailCrm\Interfaces\RequestSignerInterface;
use RetailCrm\Interfaces\RequestTimestampProviderInterface;
use RetailCrm\Interfaces\TopRequestProcessorInterface;
@ -71,12 +70,12 @@ class TopRequestProcessor implements TopRequestProcessorInterface
*/
public function process(
BaseRequest $request,
AppDataInterface $appData,
AuthenticatorInterface $authenticator
AppDataInterface $appData
): void {
$authenticator->authenticate($request);
$this->signer->sign($request, $appData);
$request->appKey = $appData->getAppKey();
$this->timestampProvider->provide($request);
$this->signer->sign($request, $appData);
$this->validate($request);
}
}

View File

@ -12,6 +12,7 @@
*/
namespace RetailCrm\TopClient;
use DateTime;
use JMS\Serializer\SerializerInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\StreamInterface;
@ -19,11 +20,11 @@ use RetailCrm\Component\Exception\TopApiException;
use RetailCrm\Component\Exception\TopClientException;
use RetailCrm\Component\ServiceLocator;
use RetailCrm\Interfaces\AppDataInterface;
use RetailCrm\Interfaces\AuthenticatorInterface;
use RetailCrm\Interfaces\TopRequestFactoryInterface;
use RetailCrm\Interfaces\TopRequestProcessorInterface;
use RetailCrm\Model\Request\BaseRequest;
use RetailCrm\Model\Response\BaseResponse;
use RetailCrm\Model\Response\TopResponseInterface;
use RetailCrm\Traits\ValidatorAwareTrait;
use Symfony\Component\Validator\Constraints as Assert;
@ -46,12 +47,6 @@ class Client
*/
protected $appData;
/**
* @var AuthenticatorInterface $authenticator
* @Assert\NotNull(message="Authenticator should be provided")
*/
protected $authenticator;
/**
* @var ClientInterface $httpClient
* @Assert\NotNull(message="HTTP client should be provided")
@ -89,12 +84,10 @@ class Client
* Client constructor.
*
* @param \RetailCrm\Interfaces\AppDataInterface $appData
* @param \RetailCrm\Interfaces\AuthenticatorInterface $authenticator
*/
public function __construct(AppDataInterface $appData, AuthenticatorInterface $authenticator)
public function __construct(AppDataInterface $appData)
{
$this->appData = $appData;
$this->authenticator = $authenticator;
}
/**
@ -159,18 +152,18 @@ class Client
/**
* @param \RetailCrm\Model\Request\BaseRequest $request
*
* @return \RetailCrm\Model\Response\BaseResponse
* @return TopResponseInterface
* @throws \Psr\Http\Client\ClientExceptionInterface
* @throws \RetailCrm\Component\Exception\ValidationException
* @throws \RetailCrm\Component\Exception\FactoryException
* @throws \RetailCrm\Component\Exception\TopClientException
* @throws \RetailCrm\Component\Exception\TopApiException
*/
public function sendRequest(BaseRequest $request)
public function sendRequest(BaseRequest $request): TopResponseInterface
{
$this->processor->process($request, $this->appData, $this->authenticator);
$this->processor->process($request, $this->appData);
$httpRequest = $this->requestFactory->fromModel($request, $this->appData, $this->authenticator);
$httpRequest = $this->requestFactory->fromModel($request, $this->appData);
$httpResponse = $this->httpClient->sendRequest($httpRequest);
/** @var BaseResponse $response */
@ -185,7 +178,7 @@ class Client
}
if (null !== $response->errorResponse) {
throw new TopApiException($response->errorResponse);
throw new TopApiException($response->errorResponse, $response->requestId);
}
return $response;

View File

@ -86,28 +86,6 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase
return new AppData($endpoint, $appKey, $appSecret);
}
/**
* @return \RetailCrm\Interfaces\AuthenticatorInterface
*/
protected function getEnvAuthenticator(): AuthenticatorInterface
{
return $this->getAuthenticator(
self::getenv('APP_KEY', 'appKey'),
self::getenv('SESSION', 'helloworld')
);
}
/**
* @param string $appKey
* @param string $token
*
* @return \RetailCrm\Interfaces\AuthenticatorInterface
*/
protected function getAuthenticator(string $appKey = 'appKey', string $token = 'token'): AuthenticatorInterface
{
return new TokenAuthenticator($appKey, $token);
}
/**
* @param string $signMethod
*

View File

@ -13,7 +13,6 @@
namespace RetailCrm\Tests\Builder;
use RetailCrm\Component\AppData;
use RetailCrm\Component\Authenticator\TokenAuthenticator;
use RetailCrm\Component\ServiceLocator;
use RetailCrm\Builder\ClientBuilder;
use RetailCrm\Test\TestCase;
@ -36,7 +35,6 @@ class ClientBuilderTest extends TestCase
$client = ClientBuilder::create()
->setContainer($this->getContainer())
->setAppData(new AppData(AppData::OVERSEAS_ENDPOINT, 'appKey', 'helloworld'))
->setAuthenticator(new TokenAuthenticator('appKey', 'token'))
->build();
self::assertInstanceOf(Client::class, $client);

View File

@ -35,8 +35,7 @@ class TopRequestFactoryTest extends TestCase
$factory = $this->getContainer()->get(TopRequestFactoryInterface::class);
$request = $factory->fromModel(
$this->getTestRequest(Constants::SIGN_TYPE_HMAC),
$this->getAppData(),
$this->getAuthenticator()
$this->getAppData()
);
$uri = $request->getUri();
$contents = self::getStreamData($request->getBody());
@ -52,8 +51,7 @@ class TopRequestFactoryTest extends TestCase
$factory = $this->getContainer()->get(TopRequestFactoryInterface::class);
$request = $factory->fromModel(
$this->getTestRequest(Constants::SIGN_TYPE_HMAC, true, true),
$this->getAppData(),
$this->getAuthenticator()
$this->getAppData()
);
$uri = $request->getUri();
$contents = self::getStreamData($request->getBody());

View File

@ -16,7 +16,6 @@ use RetailCrm\Component\AppData;
use RetailCrm\Component\Constants;
use RetailCrm\Interfaces\AppDataInterface;
use RetailCrm\Interfaces\RequestSignerInterface;
use RetailCrm\Service\RequestSigner;
use RetailCrm\Test\TestCase;
use RetailCrm\Test\TestSignerRequest;
@ -56,22 +55,22 @@ class RequestSignerTest extends TestCase
[
$this->getTestRequest(Constants::SIGN_TYPE_MD5),
$appData,
'4BC79C5FAA1B5E254E95A97E65BACEAB'
'468BF7C95925C187D0DFD7D042072EB4'
],
[
$this->getTestRequest(Constants::SIGN_TYPE_HMAC),
$appData,
'497FA7FCAD98F4F335EFAE2451F8291D'
'5EF5C76D5C158BFFA9F35BAAA712A879'
],
[
$this->getTestRequest(Constants::SIGN_TYPE_MD5, true),
$appData,
'4BC79C5FAA1B5E254E95A97E65BACEAB'
'468BF7C95925C187D0DFD7D042072EB4'
],
[
$this->getTestRequest(Constants::SIGN_TYPE_HMAC, true),
$appData,
'497FA7FCAD98F4F335EFAE2451F8291D'
'5EF5C76D5C158BFFA9F35BAAA712A879'
]
];
}

View File

@ -16,6 +16,8 @@ use Psr\Http\Message\RequestInterface;
use RetailCrm\Builder\ClientBuilder;
use RetailCrm\Component\AppData;
use RetailCrm\Component\Authenticator\TokenAuthenticator;
use RetailCrm\Component\Constants;
use RetailCrm\Component\Exception\TopApiException;
use RetailCrm\Model\Request\HttpDnsGetRequest;
use RetailCrm\Model\Response\BaseResponse;
use RetailCrm\Model\Response\Body\ErrorResponseBody;
@ -52,7 +54,6 @@ class ClientTest extends TestCase
$client = ClientBuilder::create()
->setContainer($this->getContainer($mockClient))
->setAppData(new AppData(AppData::OVERSEAS_ENDPOINT, 'appKey', 'appSecret'))
->setAuthenticator(new TokenAuthenticator('appKey', 'token'))
->build();
$this->expectExceptionMessage($errorBody->msg);