custom/plugins/TrustedShops/src/Subscriber/FrontendSubscriber.php line 80

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace TrustedShops\Subscriber;
  3. use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
  4. use Shopware\Core\Checkout\Order\OrderEntity;
  5. use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
  6. use Shopware\Core\Content\Product\ProductEntity;
  7. use Shopware\Core\Framework\Context;
  8. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  10. use Shopware\Core\Framework\Struct\ArrayEntity;
  11. use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
  12. use Shopware\Storefront\Page\Product\QuickView\MinimalQuickViewPageCriteriaEvent;
  13. use Shopware\Core\System\SystemConfig\SystemConfigService;
  14. use Shopware\Storefront\Event\StorefrontRenderEvent;
  15. use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
  16. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  17. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18. class FrontendSubscriber implements EventSubscriberInterface
  19. {
  20.     /**
  21.      * @var SystemConfigService
  22.      */
  23.     private $systemConfigService;
  24.     private $productRepository;
  25.     private $trustedshopProductRatingRepository;
  26.     /**
  27.      * @var string
  28.      */
  29.     private $shopReviewsApiUrl 'https://api.trustedshops.com/rest/public/v2/shops/{{tsId}}/reviews';
  30.     /**
  31.      * @var int
  32.      */
  33.     private $shopReviewsCheckInterval 3600;
  34.     public function __construct(SystemConfigService $systemConfigServiceEntityRepositoryInterface $productRepositoryEntityRepositoryInterface $trustedshopProductRatingRepository)
  35.     {
  36.         $this->systemConfigService $systemConfigService;
  37.         $this->productRepository $productRepository;
  38.         $this->trustedshopProductRatingRepository $trustedshopProductRatingRepository;
  39.     }
  40.     public static function getSubscribedEvents(): array
  41.     {
  42.         $listeners = [
  43.             StorefrontRenderEvent::class => 'onStoreFrontRender',
  44.             MinimalQuickViewPageCriteriaEvent::class => 'onMinimalQuickViewPageCriteria',
  45.             ProductPageCriteriaEvent::class => 'onProductPageCriteria',
  46.             ProductPageLoadedEvent::class=>'onProductPageLoaded',
  47.             ProductListingCriteriaEvent::class => 'onProductListingCriteria',
  48.             CheckoutFinishPageLoadedEvent::class => 'onCheckoutFinishPageLoaded',
  49.         ];
  50.         if( class_exists'Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent' ) ) {
  51.             $listenersShopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent::class ] = 'onLineItemAdded';
  52.         } else {
  53.             $listenersShopware\Core\Checkout\Cart\Event\LineItemAddedEvent::class ] = 'onLineItemAdded';
  54.         }
  55.         return $listeners;
  56.     }
  57.     public function onStoreFrontRender(StorefrontRenderEvent $event): void
  58.     {
  59.         $isAjax $event->getRequest()->isXmlHttpRequest();
  60.         if (!$isAjax) {
  61.             $this->initTrustedShopsShopReviews();
  62.         }
  63.         $config $this->systemConfigService->get'TrustedShops.config'$event->getSalesChannelContext()->getSalesChannel()->getId() );
  64.         $event->setParameter'trustedshops'$config );
  65.     }
  66.     public function onMinimalQuickViewPageCriteria(MinimalQuickViewPageCriteriaEvent $event): void
  67.     {
  68.         $event->getCriteria()->addAssociation('extensions.trustedshopsRatings');
  69.     }
  70.     public function onProductPageCriteria(ProductPageCriteriaEvent $event): void
  71.     {
  72.         $event->getCriteria()->addAssociation('extensions.trustedshopsRatings');
  73.     }
  74.     public function onProductPageLoaded(ProductPageLoadedEvent $event){
  75.         $product $event->getPage()->getProduct();
  76.         if( ( $parentId $product->getParentId()) ) {
  77.             $parent $this->productRepository->search(new Criteria([$parentId]), $event->getContext())->first();
  78.             $sku = new ArrayEntity();
  79.             $sku->set('sku'$parent->getProductNumber());
  80.             $product->addExtension("parentProduct"$sku);
  81.         }
  82.     }
  83.     public function onProductListingCriteria(ProductListingCriteriaEvent $event): void
  84.     {
  85.         $event->getCriteria()->addAssociation('extensions.trustedshopsRatings');
  86.     }
  87.     public function onLineItemAdded(BeforeLineItemAddedEvent $event): void
  88.     {
  89.         $lineItem $event->getLineItem();
  90.         if( $lineItem->getType() === 'product' ) {
  91.             $context Context::createDefaultContext();
  92.             /** @var ProductEntity $product */
  93.             $product $this->productRepository->search((new Criteria([$lineItem->getReferencedId()])),$context)->first();
  94.             if( ( $parentId $product->getParentId()) ) {
  95.                 /** @var ProductEntity $parent */
  96.                 $parent $this->productRepository->search((new Criteria([$parentId]))->addAssociation('cover'),$context)->first();
  97.                 $lineItem->setPayloadValue('parent',[
  98.                     'productId' => $parent->getId(),
  99.                     'productNumber' => $parent->getProductNumber(),
  100.                     'label' => $parent->getTranslation('name'),
  101.                     'cover' => ( $parent->getCover() ? $parent->getCover()->getMedia() : null )
  102.                 ]);
  103.             }
  104.         }
  105.     }
  106.     public function onCheckoutFinishPageLoaded(CheckoutFinishPageLoadedEvent $event): void {
  107.         $page $event->getPage();
  108.         $page->assign(['tsDeliveryTime' => $this->getTrustedShopsDeliveryTime$page->getOrder() ) ] );
  109.     }
  110.     protected function getTrustedShopsDeliveryTimeOrderEntity $order )
  111.     {
  112.         $customAvailableDeliverTime = ( $this->systemConfigService->get'TrustedShops.config.tsAvailableProductDeliveryTime' ) === 'custom' );
  113.         $customUnavailableDeliverTime = ( $this->systemConfigService->get'TrustedShops.config.tsNotAvailableProductDeliveryTime' ) === 'custom' );
  114.         $availableDeliveryTimeDays $this->systemConfigService->get'TrustedShops.config.tsAvailableProductDeliveryTimeDays' );
  115.         $unavailableDeliveryTimeDays $this->systemConfigService->get'TrustedShops.config.tsNotAvailableProductDeliveryTimeDays' );
  116.         if( $this->orderContainsUnavailableProducts$order ) ) {
  117.             if( $customUnavailableDeliverTime && $unavailableDeliveryTimeDays ) {
  118.                 $deliveryTimeDays $unavailableDeliveryTimeDays;
  119.             } else {
  120.                 return $order->getDeliveries()->first()->getShippingDateLatest();
  121.             }
  122.         } else {
  123.             if( $customAvailableDeliverTime && $availableDeliveryTimeDays ) {
  124.                 $deliveryTimeDays $availableDeliveryTimeDays;
  125.             } else {
  126.                 return $order->getDeliveries()->first()->getShippingDateLatest();
  127.             }
  128.         }
  129.         switch (date('N')) {
  130.             case 5//freitag
  131.                 $deliveryTimeDays += 2;
  132.                 break;
  133.             case 6//samstag
  134.                 $deliveryTimeDays += 1;
  135.                 break;
  136.         }
  137.         if( date'N'strtotime'+' $deliveryTimeDays 'days' ) ) === ) {
  138.             $deliveryTimeDays++;
  139.         }
  140.         return (new \DateTime())->add(new \DateInterval('P' $deliveryTimeDays 'D'));
  141.     }
  142.     protected function orderContainsUnavailableProductsOrderEntity $order ): bool
  143.     {
  144.         $context Context::createDefaultContext();
  145.         /** @var OrderLineItemEntity $lineItem */
  146.         foreach( $order->getLineItems() as $lineItem ) {
  147.             if( $lineItem->getType() === 'product' ) {
  148.                 /** @var ProductEntity $product */
  149.                 $product $this->productRepository->search((new Criteria([$lineItem->getProductId()])),$context)->first();
  150.                 if( !$product->getAvailable() ) {
  151.                     return true;
  152.                 }
  153.             }
  154.         }
  155.         return false;
  156.     }
  157.     protected function initTrustedShopsShopReviews(): void
  158.     {
  159.         $domain 'TrustedShops.config.';
  160.         $tsId $this->systemConfigService->get$domain 'tsId' );
  161.         if( $tsId ) {
  162.             $lastCheck $this->systemConfigService->get$domain 'tsShopRatingLastCheck' );
  163.             if( empty( $lastCheck ) || ( $lastCheck+$this->shopReviewsCheckInterval ) < time() ) {
  164.                 $apiUrl str_replace'{{tsId}}'$tsId$this->shopReviewsApiUrl );
  165.                 $ch curl_init();
  166.                 curl_setopt($chCURLOPT_HTTPHEADER, [ 'Accept: application/json' ] );
  167.                 curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  168.                 curl_setopt($chCURLOPT_URL$apiUrl);
  169.                 $result curl_exec($ch);
  170.                 curl_close($ch);
  171.                 if( $result ) {
  172.                     $shopReviews json_decode($result);
  173.                     if ($shopReviews && $shopReviews->response && $shopReviews->response->data && $shopReviews->response->data->shop->reviews) {
  174.                         $bestRating 0;
  175.                         $_ratings = [];
  176.                         foreach ($shopReviews->response->data->shop->reviews as $review) {
  177.                             $_rating = (float)$review->mark;
  178.                             $_ratings[] = $_rating;
  179.                             if ($_rating $bestRating) {
  180.                                 $bestRating $_rating;
  181.                             }
  182.                         }
  183.                         $ratingCount count($shopReviews->response->data->shop->reviews);
  184.                         $avgRating array_sum($_ratings) / $ratingCount;
  185.                         $this->systemConfigService->set($domain 'tsShopAvgRating'$avgRating);
  186.                         $this->systemConfigService->set($domain 'tsShopBestRating'$bestRating);
  187.                         $this->systemConfigService->set($domain 'tsShopRatingCount'$ratingCount);
  188.                         $this->systemConfigService->set($domain 'tsShopRatingLastCheck'time());
  189.                     }
  190.                 }
  191.             }
  192.         }
  193.     }
  194. }