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

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