mirror of
https://github.com/retailcrm/prestashop-module.git
synced 2025-03-01 19:03:14 +03:00
Refactor RetailcrmProxy
This commit is contained in:
parent
35bccc98b4
commit
5bbddab7ee
11
doc/2. Workflow/Pipeline/Middlewares.md
Normal file
11
doc/2. Workflow/Pipeline/Middlewares.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Middlewares
|
||||
|
||||
Pipeline содержит стек middleware. В глубине стека выполняется callback-функция, переданная в метод setAction класса *RetailcrmPipeline*.
|
||||
|
||||
Для добавления дополнительной логики при обработке запроса вы можете добавить новую middleware в pipeline.
|
||||
Для этого требуется создать класс, реализующий интерфейс *RetailcrmMiddlewareInterface* и добавить имя класса в массив, который передаётся в метод setMiddlewares класса RetailcrmPipeline.
|
||||
|
||||
Порядок в массиве, передаваемом в *setMiddlewares()* определяет позицию middleware в стеке. Напрмер, массив `[MW1, MW2, MW3]` приведет к вызову `MW1 -> MW2 -> MW3 -> ACTION -> MW3 -> MW2 -> MW1`.
|
||||
К middleware применяются фильтры из папки `custom/hooks`
|
||||
|
||||
В методе *__invoke()* middleware-класса должна быть описана логика, которую вы хотите выполнить при обработке запроса, а так же вызов следующей middleware в стеке.
|
20
retailcrm/lib/RetailcrmLogger.php
Normal file → Executable file
20
retailcrm/lib/RetailcrmLogger.php
Normal file → Executable file
@ -302,4 +302,24 @@ class RetailcrmLogger
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces error array into string
|
||||
*
|
||||
* @param $errors
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function reduceErrors($errors)
|
||||
{
|
||||
$reduced = '';
|
||||
|
||||
if (is_array($errors)) {
|
||||
foreach ($errors as $key => $error) {
|
||||
$reduced .= sprintf('%s => %s\n', $key, $error);
|
||||
}
|
||||
}
|
||||
|
||||
return $reduced;
|
||||
}
|
||||
}
|
64
retailcrm/lib/api/RetailcrmApiRequest.php
Normal file
64
retailcrm/lib/api/RetailcrmApiRequest.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
class RetailcrmApiRequest
|
||||
{
|
||||
private $api;
|
||||
|
||||
private $data;
|
||||
|
||||
private $method;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getApi()
|
||||
{
|
||||
return $this->api;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $api
|
||||
* @return RetailcrmApiRequest
|
||||
*/
|
||||
public function setApi($api)
|
||||
{
|
||||
$this->api = $api;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $method
|
||||
*/
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->method = $method;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -38,13 +38,11 @@
|
||||
class RetailcrmApiResponse implements \ArrayAccess
|
||||
{
|
||||
// HTTP response status code
|
||||
protected $statusCode;
|
||||
private $statusCode;
|
||||
|
||||
// response assoc array
|
||||
protected $response;
|
||||
private $response;
|
||||
|
||||
// raw response
|
||||
protected $rawResponse;
|
||||
private $rawResponse;
|
||||
|
||||
/**
|
||||
* ApiResponse constructor.
|
||||
|
90
retailcrm/lib/api/RetailcrmProxy.php
Normal file → Executable file
90
retailcrm/lib/api/RetailcrmProxy.php
Normal file → Executable file
@ -37,75 +37,45 @@
|
||||
*/
|
||||
class RetailcrmProxy
|
||||
{
|
||||
private $api;
|
||||
private $log;
|
||||
|
||||
public function __construct($url, $key, $log)
|
||||
{
|
||||
$this->api = new RetailcrmApiClientV5($url, $key);
|
||||
$this->log = $log;
|
||||
}
|
||||
/**
|
||||
* @var RetailcrmApiClientV5
|
||||
*/
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* Reduces error array into string
|
||||
*
|
||||
* @param $errors
|
||||
*
|
||||
* @return false|string
|
||||
* @var RetailcrmPipeline
|
||||
*/
|
||||
private static function reduceErrors($errors)
|
||||
private $pipeline;
|
||||
|
||||
public function __construct($url, $key)
|
||||
{
|
||||
$reduced = '';
|
||||
$this->client = new RetailcrmApiClientV5($url, $key);
|
||||
|
||||
if (is_array($errors)) {
|
||||
foreach ($errors as $key => $error) {
|
||||
$reduced .= sprintf('%s => %s\n', $key, $error);
|
||||
}
|
||||
}
|
||||
|
||||
return $reduced;
|
||||
$this->pipeline = new RetailcrmPipeline();
|
||||
$this->pipeline
|
||||
->setMiddlewares(
|
||||
RetailcrmTools::filter(
|
||||
'RetailcrmFilterMiddlewares',
|
||||
[
|
||||
RetailcrmLoggerMiddleware::class,
|
||||
])
|
||||
)
|
||||
->setAction(function ($request) {
|
||||
return call_user_func_array([$this->client, $request->getMethod()], $request->getData());
|
||||
})
|
||||
->build()
|
||||
;
|
||||
}
|
||||
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
$date = date('Y-m-d H:i:s');
|
||||
try {
|
||||
RetailcrmLogger::writeDebug($method, print_r($arguments, true));
|
||||
$response = call_user_func_array(array($this->api, $method), $arguments);
|
||||
{
|
||||
$request = new RetailcrmApiRequest();
|
||||
$request->setApi($this->client);
|
||||
$request->setMethod($method);
|
||||
$request->setData($arguments);
|
||||
|
||||
if (!($response instanceof RetailcrmApiResponse)) {
|
||||
RetailcrmLogger::writeDebug($method, $response);
|
||||
return $response;
|
||||
}
|
||||
$response = $this->pipeline->run($request);
|
||||
|
||||
if (!$response->isSuccessful()) {
|
||||
RetailcrmLogger::writeCaller($method, $response->getErrorMsg());
|
||||
|
||||
if (isset($response['errors'])) {
|
||||
RetailcrmApiErrors::set($response['errors'], $response->getStatusCode());
|
||||
$error = static::reduceErrors($response['errors']);
|
||||
RetailcrmLogger::writeNoCaller($error);
|
||||
}
|
||||
|
||||
$response = false;
|
||||
} else {
|
||||
// Don't print long lists in debug logs (errors while calling this will be easy to detect anyway)
|
||||
if (in_array($method, array('statusesList', 'paymentTypesList', 'deliveryTypesList'))) {
|
||||
RetailcrmLogger::writeDebug($method, '[request was successful, but response is omitted]');
|
||||
} else {
|
||||
RetailcrmLogger::writeDebug($method, $response->getRawResponse());
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
} catch (CurlException $e) {
|
||||
RetailcrmLogger::writeCaller(get_class($this->api).'::'.$method, $e->getMessage());
|
||||
RetailcrmLogger::writeNoCaller($e->getTraceAsString());
|
||||
return false;
|
||||
} catch (InvalidJsonException $e) {
|
||||
RetailcrmLogger::writeCaller(get_class($this->api).'::'.$method, $e->getMessage());
|
||||
RetailcrmLogger::writeNoCaller($e->getTraceAsString());
|
||||
return false;
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
38
retailcrm/lib/api/middleware/RetailcrmLoggerMiddleware.php
Normal file
38
retailcrm/lib/api/middleware/RetailcrmLoggerMiddleware.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
class RetailcrmLoggerMiddleware implements RetailcrmMiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* @param RetailcrmApiRequest $request
|
||||
* @param callable|null $next
|
||||
* @return RetailcrmApiResponse
|
||||
*/
|
||||
public function __invoke(RetailcrmApiRequest $request, callable $next = null)
|
||||
{
|
||||
$method = $request->getMethod();
|
||||
|
||||
if (!is_null($request->getMethod())) {
|
||||
RetailcrmLogger::writeDebug($method, print_r($request->getData(), true));
|
||||
}
|
||||
$response = $next($request);
|
||||
|
||||
if ($response->isSuccessful()) {
|
||||
// Don't print long lists in debug logs (errors while calling this will be easy to detect anyway)
|
||||
if (in_array($method, ['statusesList', 'paymentTypesList', 'deliveryTypesList'])) {
|
||||
RetailcrmLogger::writeDebug($method, '[request was successful, but response is omitted]');
|
||||
} else {
|
||||
RetailcrmLogger::writeDebug($method, $response->getRawResponse());
|
||||
}
|
||||
} else {
|
||||
RetailcrmLogger::writeCaller($method, $response->getErrorMsg());
|
||||
|
||||
if (isset($response['errors'])) {
|
||||
RetailcrmApiErrors::set($response['errors'], $response->getStatusCode());
|
||||
$error = RetailcrmLogger::reduceErrors($response['errors']);
|
||||
RetailcrmLogger::writeNoCaller($error);
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
8
retailcrm/lib/api/middleware/index.php
Normal file
8
retailcrm/lib/api/middleware/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
11
retailcrm/lib/api/pipeline/RetailcrmMiddlewareInterface.php
Normal file
11
retailcrm/lib/api/pipeline/RetailcrmMiddlewareInterface.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
interface RetailcrmMiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* @param RetailcrmApiRequest $request
|
||||
* @param callable|null $next
|
||||
* @return RetailcrmApiResponse
|
||||
*/
|
||||
public function __invoke(RetailcrmApiRequest $request, callable $next = null);
|
||||
}
|
72
retailcrm/lib/api/pipeline/RetailcrmPipeline.php
Normal file
72
retailcrm/lib/api/pipeline/RetailcrmPipeline.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
class RetailcrmPipeline
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $middlewares;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $action;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $pipeline;
|
||||
|
||||
/**
|
||||
* @param RetailcrmApiRequest $request
|
||||
* @return callable
|
||||
*/
|
||||
public function run(RetailcrmApiRequest $request)
|
||||
{
|
||||
$pipeline = $this->pipeline;
|
||||
return $pipeline($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $action
|
||||
* @return $this
|
||||
*/
|
||||
public function setAction(callable $action)
|
||||
{
|
||||
$this->action = $action;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $middlewares
|
||||
* @return $this
|
||||
*/
|
||||
public function setMiddlewares(array $middlewares)
|
||||
{
|
||||
$this->middlewares = $middlewares;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
$this->pipeline =
|
||||
array_reduce(
|
||||
array_reverse($this->middlewares),
|
||||
$this->buildStack(),
|
||||
$this->action
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return callable
|
||||
*/
|
||||
private function buildStack()
|
||||
{
|
||||
return function ($stack, $middlewareClass) {
|
||||
return function ($request) use ($stack, $middlewareClass) {
|
||||
$middleware = new $middlewareClass;
|
||||
return $middleware($request, $stack);
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
8
retailcrm/lib/api/pipeline/index.php
Normal file
8
retailcrm/lib/api/pipeline/index.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
header("Location: ../");
|
||||
exit;
|
Loading…
x
Reference in New Issue
Block a user