custom/plugins/EnderecoShopware6ClientStore/src/Service/EnderecoService.php line 72

Open in your IDE?
  1. <?php
  2. namespace Endereco\Shopware6ClientStore\Service;
  3. use GuzzleHttp\Client;
  4. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  5. use Shopware\Storefront\Page\GenericPageLoadedEvent;
  6. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  7. use Shopware\Core\System\SystemConfig\SystemConfigService;
  8. use Shopware\Core\Checkout\Customer\CustomerEvents;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  10. use GuzzleHttp\Exception\RequestException;
  11. use Shopware\Core\Framework\Context;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  14. use Psr\Log\LoggerInterface;
  15. class EnderecoService implements EventSubscriberInterface
  16. {
  17.     /**
  18.      * @var SystemConfigService
  19.      */
  20.     private $systemConfigService;
  21.     /**
  22.      * @var Client
  23.      */
  24.     private $httpClient;
  25.     /**
  26.      * @var string
  27.      */
  28.     private $apiKey;
  29.     /**
  30.      * @var string
  31.      */
  32.     private $serviceUrl;
  33.     /**
  34.      * @var EntityRepository
  35.      */
  36.     private $pluginRepository;
  37.     /** @var LoggerInterface */
  38.     private $logger;
  39.     public function __construct(
  40.         SystemConfigService $systemConfigService,
  41.         EntityRepository $pluginRepository,
  42.         LoggerInterface $logger)
  43.     {
  44.         $this->systemConfigService $systemConfigService;
  45.         $this->httpClient = new Client(['timeout' => 3.0'connection_timeout' => 2.0]);
  46.         $this->apiKey $systemConfigService->getString('EnderecoShopware6ClientStore.config.enderecoApiKey') ?? '';
  47.         $this->serviceUrl $systemConfigService->getString('EnderecoShopware6ClientStore.config.enderecoRemoteUrl') ?? '';
  48.         $this->pluginRepository $pluginRepository;
  49.         $this->logger $logger;
  50.     }
  51.     /** @return array<string, string> */
  52.     public static function getSubscribedEvents(): array
  53.     {
  54.         return [
  55.             CustomerEvents::CUSTOMER_ADDRESS_WRITTEN_EVENT => 'extractAndAccountSessions',
  56.         ];
  57.     }
  58.     public function extractAndAccountSessions(EntityWrittenEvent $event): void
  59.     {
  60.         /**
  61.          * @var array<string, boolean>
  62.          */
  63.         $accountableSessionIds = array();
  64.         if ('POST' === $_SERVER['REQUEST_METHOD']) {
  65.             foreach ($_POST as $sVarName => $sVarValue) {
  66.                 if ((strpos($sVarName'_session_counter') !== false) && intval($sVarValue)) {
  67.                     $sSessionIdName str_replace('_session_counter'''$sVarName) . '_session_id';
  68.                     $accountableSessionIds[$_POST[$sSessionIdName]] = true;
  69.                 }
  70.             }
  71.             $accountableSessionIds array_map('strval'array_keys($accountableSessionIds));
  72.             if (!empty($accountableSessionIds)) {
  73.                 $this->closeSessions($accountableSessionIds$event);
  74.             }
  75.         }
  76.     }
  77.     /** @return string */
  78.     public function generateTid(): string
  79.     {
  80.         $data random_bytes(16);
  81.         $data[6] = chr(ord($data[6]) & 0x0f 0x40);
  82.         $data[8] = chr(ord($data[8]) & 0x3f 0x80);
  83.         return vsprintf('%s%s-%s-%s-%s-%s%s%s'str_split(bin2hex($data), 4));
  84.     }
  85.     /**
  86.      * @param array<int, string> $sessionIds
  87.      * @param EntityWrittenEvent $event
  88.      */
  89.     public function closeSessions(array $sessionIdsEntityWrittenEvent $event): void
  90.     {
  91.         $anyDoAccounting false;
  92.         $context $event->getContext();
  93.         $criteria = new Criteria();
  94.         $criteria->addFilter(new EqualsFilter('name''EnderecoShopware6ClientStore'));
  95.         $enderecoAgentInfo 'Endereco Shopware6 Client v' $this->pluginRepository->search($criteria$context)->first()->getVersion();
  96.         foreach ($sessionIds as $sessionId) {
  97.             try {
  98.                 $message = array(
  99.                     'jsonrpc' => '2.0',
  100.                     'id' => 1,
  101.                     'method' => 'doAccounting',
  102.                     'params' => array(
  103.                         'sessionId' => $sessionId
  104.                     )
  105.                 );
  106.                 $newHeaders = array(
  107.                     'Content-Type' => 'application/json',
  108.                     'X-Auth-Key' => $this->apiKey,
  109.                     'X-Transaction-Id' => $sessionId,
  110.                     'X-Transaction-Referer' => $_SERVER['HTTP_REFERER']?$_SERVER['HTTP_REFERER']:__FILE__,
  111.                     'X-Agent' => $enderecoAgentInfo,
  112.                 );
  113.                 $this->httpClient->post(
  114.                     $this->serviceUrl,
  115.                     array(
  116.                         'headers' => $newHeaders,
  117.                         'body' => json_encode($message)
  118.                     )
  119.                 );
  120.                 $anyDoAccounting true;
  121.             } catch (RequestException $e) {
  122.                 if ($e->hasResponse()) {
  123.                     $response $e->getResponse();
  124.                     if ($response && 500 <= $response->getStatusCode()) {
  125.                         $this->logger->error('Serverside doAccounting failed', ['error' => $e->getMessage()]);
  126.                     }
  127.                 }
  128.             } catch(\Exception $e) {
  129.                 $this->logger->error('Serverside doAccounting failed', ['error' => $e->getMessage()]);
  130.             }
  131.         }
  132.         if ($anyDoAccounting) {
  133.             try {
  134.                 $message = array(
  135.                     'jsonrpc' => '2.0',
  136.                     'id' => 1,
  137.                     'method' => 'doConversion',
  138.                     'params' => array()
  139.                 );
  140.                 $newHeaders = array(
  141.                     'Content-Type' => 'application/json',
  142.                     'X-Auth-Key' => $this->apiKey,
  143.                     'X-Transaction-Id' => 'not_required',
  144.                     'X-Transaction-Referer' => $_SERVER['HTTP_REFERER']?$_SERVER['HTTP_REFERER']:__FILE__,
  145.                     'X-Agent' => $enderecoAgentInfo,
  146.                 );
  147.                 $this->httpClient->post(
  148.                     $this->serviceUrl,
  149.                     array(
  150.                         'headers' => $newHeaders,
  151.                         'body' => json_encode($message)
  152.                     )
  153.                 );
  154.             } catch (RequestException $e) {
  155.                 if ($e->hasResponse()) {
  156.                     $response $e->getResponse();
  157.                     if ($response && 500 <= $response->getStatusCode()) {
  158.                         $this->logger->warning('Serverside doConversion failed', ['error' => $e->getMessage()]);
  159.                     }
  160.                 }
  161.             } catch(\Exception $e) {
  162.                 $this->logger->warning('Serverside doConversion failed', ['error' => $e->getMessage()]);
  163.             }
  164.         }
  165.     }
  166. }