src/Services/Main/ApiRequestService.php line 107

Open in your IDE?
  1. <?php
  2. namespace App\Services\Main;
  3. use App\Enum\ApiCodeEnum;
  4. use App\Object\Api\CallResponse;
  5. use App\Services\Util\ConfigService;
  6. use App\Services\Util\JsonService;
  7. use App\Services\Util\UtilService;
  8. use Psr\Log\LoggerInterface;
  9. use Symfony\Component\HttpClient\CurlHttpClient;
  10. use Symfony\Component\HttpClient\HttpClient;
  11. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  12. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  13. use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
  14. use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
  15. use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
  16. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  17. use Throwable;
  18. class ApiRequestService
  19. {
  20.     /**
  21.      * @var JsonService
  22.      */
  23.     protected JsonService $jsonService;
  24.     /**
  25.      * @var LoggerInterface
  26.      */
  27.     protected LoggerInterface $logger;
  28.     /**
  29.      * @var ConfigService
  30.      */
  31.     private ConfigService $configService;
  32.     /**
  33.      * @var UtilService
  34.      */
  35.     private UtilService $utilService;
  36.     private SessionInterface $session;
  37.     /**
  38.      * @var CurlHttpClient
  39.      */
  40.     private CurlHttpClient $client;
  41.     /**
  42.      * @var mixed
  43.      */
  44.     private $clientIdentifier;
  45.     /**
  46.      * @var mixed
  47.      */
  48.     private $apiUrl;
  49.     /**
  50.      * ApiRequestService constructor.
  51.      *
  52.      * @param ConfigService $configService
  53.      * @param JsonService $jsonService
  54.      * @param UtilService $utilService
  55.      * @param LoggerInterface $logger
  56.      */
  57.     public function __construct(
  58.         ConfigService $configService,
  59.         JsonService $jsonService,
  60.         UtilService $utilService,
  61.         SessionInterface $session,
  62.         LoggerInterface $logger
  63.     ) {
  64.         $this->configService $configService;
  65.         $this->jsonService $jsonService;
  66.         $this->utilService $utilService;
  67.         $this->session $session;
  68.         $this->logger $logger;
  69.         $this->client HttpClient::create();
  70.         $this->apiUrl $this->configService->getApiUrl();
  71.         $this->clientIdentifier $this->configService->getParameter('api_client_id');
  72.     }
  73.     /**
  74.      * @param string $method
  75.      * @param string $endpoint
  76.      * @param array $options
  77.      * @param null $defaultResult
  78.      * @param bool $debug
  79.      *
  80.      * @return CallResponse
  81.      */
  82.     public function request(
  83.         string $method,
  84.         string $endpoint,
  85.         array $options = [],
  86.         $defaultResult null,
  87.         bool $debug false
  88.     ): CallResponse {
  89.         // Populate ClientIdentifier in either json or body param
  90.         $bodyKey = isset($options['json']) ? 'json' 'body';
  91.         $options[$bodyKey] ??= [];
  92.         $options[$bodyKey]['clientId'] = $this->clientIdentifier;
  93.         $options['timeout'] = 3600;
  94.         $impersonating $this->session->get('impersonating');
  95.         if (!empty($impersonating)) {
  96.             $options[$bodyKey]['previousUserId'] = $impersonating['previousUser']->getId();
  97.         }
  98.         $requestResponse = new CallResponse();
  99.         try {
  100.             $url $this->apiUrl $endpoint;
  101.             $response $this->client->request($method$url$options);
  102.             $requestResponse->setUrl($url);
  103.             $requestResponse->setStatusCode($response->getStatusCode());
  104.             $requestResponse->setContent(
  105.                 $this->formatResponseContent($url$response->toArray(), $defaultResult$debug)
  106.             );
  107.             if ($debug) {
  108.                 $requestResponse->debug();
  109.             } else {
  110.                 $responseError json_decode($response->getContent(false), true);
  111.                 if (isset($responseError['error']) && $responseError['error']) {
  112.                     if (is_array($responseError['message'])) {
  113.                         $requestResponse->setErrorKey($responseError['message']);
  114.                     } else {
  115.                         $requestResponse->setErrorKey('api.error.' $responseError['message']);
  116.                     }
  117.                 }
  118.             }
  119.         } catch (ClientExceptionInterface $e) {
  120.             $requestResponse->setErrorKey('api.error.client');
  121.         } catch (ServerExceptionInterface $e) {
  122.             $requestResponse->setErrorKey('api.error.server');
  123.         } catch (RedirectionExceptionInterface $e) {
  124.             $requestResponse->setErrorKey('api.error.redirection');
  125.         } catch (TransportExceptionInterface $e) {
  126.             $requestResponse->setErrorKey('api.error.transport');
  127.         } catch (DecodingExceptionInterface $e) {
  128.             $requestResponse->setErrorKey('api.error.decoding');
  129.         } catch (Throwable $e) {
  130.             $requestResponse->setErrorKey($e->getMessage());
  131.         }
  132.         return $requestResponse;
  133.     }
  134.     /**
  135.      * @param string $message
  136.      *
  137.      * @return bool
  138.      */
  139.     public function messageIsErrorCode(string $message): bool
  140.     {
  141.         return in_array($messageApiCodeEnum::LIST_ERROR_CODES)
  142.             || in_array($messageApiCodeEnum::LIST_WARNING_CODES)
  143.             || in_array($messageApiCodeEnum::LIST_INFO_CODES);
  144.     }
  145.     /**
  146.      * @param string $url
  147.      * @param array $responseContent
  148.      * @param $defaultContent
  149.      * @param bool $debug
  150.      *
  151.      * @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
  152.      *
  153.      * @return array|object
  154.      */
  155.     public function formatResponseContent(string $url, array $responseContent$defaultContentbool $debug)
  156.     {
  157.         $formattedResponseContent = [
  158.             'error' => false,
  159.             'message' => '',
  160.             'content' => $defaultContent,
  161.         ];
  162.         if (!$debug && isset($responseContent['error']) && $responseContent['error']) {
  163.             $formattedResponseContent['error'] = true;
  164.             if ($this->isProductSaveRequest($url)) {
  165.                 if (is_array($responseContent['message']) && $this->productResultContainsErrorCode($responseContent['message'])) {
  166.                     $formattedResponseContent['message'] = $this->translateProductResultErrors($responseContent['message']);
  167.                 } else {
  168.                     $errorKey $this->messageIsErrorCode($responseContent['message'])
  169.                         ? $responseContent['message']
  170.                         : 'default';
  171.                     $formattedResponseContent['message'] = $this->utilService->translate("api.error.{$errorKey}");
  172.                 }
  173.             } else {
  174.                 $errorKey $this->messageIsErrorCode($responseContent['message'])
  175.                     ? $responseContent['message']
  176.                     : 'default';
  177.                 $formattedResponseContent['message'] = $this->utilService->translate("api.error.{$errorKey}");
  178.             }
  179.         } elseif (!array_key_exists('content'$responseContent)) {
  180.             $formattedResponseContent['content'] = $responseContent;
  181.         } else {
  182.             $formattedResponseContent $responseContent;
  183.         }
  184.         return $this->jsonService->denormalize(
  185.             $formattedResponseContent,
  186.             'App\Object\Api\Content'
  187.         );
  188.     }
  189.     /**
  190.      * @param string $url
  191.      *
  192.      * @return bool
  193.      */
  194.     public function isProductSaveRequest(string $url): bool
  195.     {
  196.         return str_contains($url'pim/product/save');
  197.     }
  198.     /**
  199.      * @param array $result
  200.      *
  201.      * @return bool
  202.      */
  203.     public function productResultContainsErrorCode(array $result): bool
  204.     {
  205.         foreach ($result as $channelCode => $listLanguages) {
  206.             foreach ($listLanguages as $languageCode => $listAttributes) {
  207.                 foreach ($listAttributes as $attributeCode => $listMessage) {
  208.                     foreach ($listMessage as $message) {
  209.                         preg_match_all('/[_[:upper:]]+/'$message$listErrorCodes);
  210.                         foreach ($listErrorCodes[0] as $errorCode) {
  211.                             return $this->messageIsErrorCode($errorCode);
  212.                         }
  213.                     }
  214.                 }
  215.             }
  216.         }
  217.         return false;
  218.     }
  219.     /**
  220.      * @param array $result
  221.      *
  222.      * @return array
  223.      */
  224.     public function translateProductResultErrors(array $result): array
  225.     {
  226.         $listMessages = [];
  227.         foreach ($result as $channelCode => $listLanguages) {
  228.             foreach ($listLanguages as $languageCode => $listAttributes) {
  229.                 foreach ($listAttributes as $attributeCode => $listMessage) {
  230.                     foreach ($listMessage as $message) {
  231.                         preg_match_all('/[_[:upper:]]+/'$message$listErrorCodes);
  232.                         foreach ($listErrorCodes[0] as $errorCode) {
  233.                             if ($this->messageIsErrorCode($errorCode)) {
  234.                                 if (!isset($listMessages[$channelCode][$languageCode][$attributeCode])) {
  235.                                     $listMessages[$channelCode][$languageCode][$attributeCode] = [];
  236.                                 }
  237.                                 $listMessages[$channelCode][$languageCode][$attributeCode][] = str_replace("{$errorCode} : "''$message);
  238.                             }
  239.                         }
  240.                     }
  241.                 }
  242.             }
  243.         }
  244.         return $listMessages;
  245.     }
  246. }