custom/plugins/BelcoShopware/src/Storefront/Subscriber/BelcoSubscriber.php line 232

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace BelcoShopware\Storefront\Subscriber;
  3. use JetBrains\PhpStorm\ArrayShape;
  4. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  5. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  6. use Shopware\Core\Content\Seo\SeoUrlPlaceholderHandlerInterface;
  7. use Shopware\Core\Framework\Context;
  8. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\CountAggregation;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\MaxAggregation;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\SumAggregation;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  14. use Shopware\Core\Framework\Plugin\Context\ActivateContext;
  15. use Shopware\Core\Framework\Plugin\Context\UninstallContext;
  16. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  17. use Shopware\Storefront\Pagelet\Footer\FooterPageletLoadedEvent;
  18. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  19. use Shopware\Core\System\SystemConfig\SystemConfigService;
  20. /**
  21.  * Class BelcoSubscriber
  22.  * @package BelcoShopware\Storefront\Subscriber
  23.  */
  24. class BelcoSubscriber implements EventSubscriberInterface
  25. {
  26.     /**
  27.      * @var SeoUrlPlaceholderHandlerInterface
  28.      */
  29.     private $seoUrl;
  30.     /**
  31.      * @var CartService
  32.      */
  33.     private $cartService;
  34.     /**
  35.      * @var EntityRepositoryInterface
  36.      */
  37.     private $repository;
  38.     /**
  39.      * @var SystemConfigService
  40.      */
  41.     private $systemConfigService;
  42.     /**
  43.      * @param ActivateContext $context
  44.      */
  45.     public function activate(ActivateContext $context)
  46.     {
  47.     }
  48.     /**
  49.      * @param UninstallContext $context
  50.      */
  51.     public function uninstall(UninstallContext $context)
  52.     {
  53.         if ($context->keepUserData()) {
  54.             return; //NOSONAR
  55.         }
  56.     }
  57.     /**
  58.      * @return string[]
  59.      */
  60.     #[ArrayShape([FooterPageletLoadedEvent::class => "string"])]
  61.     public static function getSubscribedEvents(): array
  62.     {
  63.         return [
  64.             FooterPageletLoadedEvent::class => 'onPostDispatch'
  65.         ];
  66.     }
  67.     /**
  68.      * BelcoSubscriber constructor.
  69.      * @param SystemConfigService $systemConfigService
  70.      * @param CartService $cartService
  71.      * @param SeoUrlPlaceholderHandlerInterface $ceoUrl
  72.      * @param EntityRepositoryInterface $entityRepository
  73.      */
  74.     public function __construct(SystemConfigService $systemConfigService,
  75.                                 CartService $cartService,
  76.                                 SeoUrlPlaceholderHandlerInterface $ceoUrl,
  77.                                 EntityRepositoryInterface $entityRepository
  78.     )
  79.     {
  80.         $this->systemConfigService $systemConfigService;
  81.         $this->cartService $cartService;
  82.         $this->seoUrl $ceoUrl;
  83.         $this->repository $entityRepository;
  84.     }
  85.     /**
  86.      * @param SalesChannelContext $context
  87.      * @return array|null
  88.      */
  89.     public function getCart(SalesChannelContext $context): ?array
  90.     {
  91.         $cart $this->cartService->getCart($context->getToken(), $context);
  92.         if ($cart->getLineItems()->count() == 0) {
  93.             return null;
  94.         }
  95.         $items = [];
  96.         foreach ($cart->getLineItems()->getElements() as $item) {
  97.             //ID is a Hexadecimal value, but needs to be a long. Since this ID isn't used (until now) it is changed to 0
  98.             $items[] = array(
  99.                 'id'=>0,
  100.                 'name' => $item->getLabel(),
  101.                 'price' => (float)$item->getPrice()->getUnitPrice(),
  102.                 'url' => $this->getProductUrl($context$item),
  103.                 'quantity' => (int)$item->getQuantity());
  104.         }
  105.         return array(
  106.             'total' => (float)$cart->getPrice()->getTotalPrice(),
  107.             'subtotal' => (float)$cart->getPrice()->getNetPrice(),
  108.             'currency' => $context->getCurrency()->getIsoCode(),
  109.             'items' => $items,
  110.         );
  111.     }
  112.     /**
  113.      * @param SalesChannelContext $context
  114.      * @return array Returns a Array with the User information
  115.      */
  116.     public function getCustomer(SalesChannelContext $context): array
  117.     {
  118.         $customer = array();
  119.         if ($context->getCustomer() != null) {
  120.             $user $context->getCustomer();
  121.             $customer = array(
  122.                 'id' => $user->getId(),
  123.                 'firstName' => $user->getFirstName(),
  124.                 'lastName' => $user->getLastName(),
  125.                 'email' => $user->getEmail(),
  126.                 'country' => $context->getCurrency()->getIsoCode(),
  127.                 'signedUp' => ($user->getFirstLogin())
  128.             );
  129.             if ($context->getCustomer()->getDefaultBillingAddress()->getPhoneNumber() != null) {
  130.                 $customer['phoneNumber'] = $context->getCustomer()->getDefaultBillingAddress()->getPhoneNumber();
  131.             }
  132.         }
  133.         return $customer;
  134.     }
  135.     /**
  136.      * @param $context
  137.      * @param $customerId
  138.      * @return array|null
  139.      */
  140.     private function getOrderData($context$customerId): ?array
  141.     {
  142.         $criteria = new Criteria();
  143.         $criteria->addAggregation(
  144.             new SumAggregation('totalSpent''amountTotal')
  145.         );
  146.         $criteria->addAggregation(
  147.             new MaxAggregation('lastOrder''orderDateTime')
  148.         );
  149.         $criteria->addAggregation(
  150.             new CountAggregation('orderCount''id')
  151.         );
  152.         $criteria->addAssociation('OrderCustomer');
  153.         $criteria->addFilter(
  154.             new EqualsFilter('orderCustomer.customerId'$customerId)
  155.         );
  156.         $result $this->repository->search($criteria$context);
  157.         if ($result != null && $result->getAggregations() != null) {
  158.             $aggregations $result->getAggregations();
  159.             $lastOrder null;
  160.             if ($aggregations->get('lastOrder')->getVars()['max'] != null) {
  161.                 $lastOrder strtotime($aggregations->get('lastOrder')->getVars()['max']);
  162.             }
  163.             return array(
  164.                 'totalSpent' => (float)$aggregations->get('totalSpent')->getVars()['sum'],
  165.                 'lastOrder' => $lastOrder,
  166.                 'orderCount' => (int)$aggregations->get('orderCount')->getVars()['count']
  167.             );
  168.         }
  169.         return null;
  170.     }
  171.     /**
  172.      * @param SalesChannelContext $salesContext
  173.      * @param Context $context
  174.      * @return string
  175.      */
  176.     public function getWidgetConfig(SalesChannelContext $salesContextContext $context): string
  177.     {
  178.         $customer $this->getCustomer($salesContext);
  179.         $belcoConfig = array(
  180.             'shopId' => $this->getConfig()['shopId'],
  181.             'cart' => $this->getCart($salesContext)
  182.         );
  183. //        dd($belcoConfig);
  184.         if ($customer) {
  185.             $belcoConfig array_merge($belcoConfig$customer);
  186.             $order $this->getOrderData($context$customer['id']);
  187.             if ($order != null) {
  188.                 $belcoConfig array_merge($belcoConfig$order);
  189.             }
  190.             if ($this->getConfig()['apiSecret']) {
  191.                 $belcoConfig['hash'] = hash_hmac('sha256'$customer['id'], $this->getConfig()['apiSecret']);
  192.             }
  193.         }
  194.         return json_encode($belcoConfig);
  195.     }
  196.     private function getConfig(): array
  197.     {
  198.         return $this->systemConfigService->get('BelcoShopware.config');
  199.     }
  200.     /**
  201.      * @param FooterPageletLoadedEvent $event
  202.      */
  203.     public function onPostDispatch(FooterPageletLoadedEvent $event): void
  204.     {
  205.         if (!$this->getConfig()['shopId']) {
  206.             return;
  207.         }
  208.         $salesContext $event->getSalesChannelContext();
  209.         $context $event->getContext();
  210.         $pagelet $event->getPagelet();
  211.         $shopId $this->getConfig()['shopId'];
  212.         if (!$this->getConfig()['shopId']||!$this->getConfig()['apiSecret']||!$this->getConfig()['domainName']) {
  213.             return;
  214.         }
  215.         $belcoConfig $this->getWidgetConfig($salesContext$context);
  216.         $optionsConfig = array(
  217.             'belcoConfig' => $belcoConfig,
  218.             'shopId' => $shopId
  219.         );
  220.         $pagelet->assign($optionsConfig);
  221.     }
  222.     /**
  223.      * @param SalesChannelContext $context
  224.      * @param LineItem $item
  225.      * @return string
  226.      */
  227.     private function getProductUrl(SalesChannelContext $contextLineItem $item): string
  228.     {
  229.         return $this->seoUrl->replace(
  230.             $this->seoUrl->generate('frontend.detail.page', ['productId' => $item->getId()]),
  231.             $this->getConfig()['domainName'],
  232.             $context);
  233.     }
  234. }