symfony Shopware 6插件-无法检索产品详细信息页面上的运费(不添加产品到购物车)

pgccezyw  于 12个月前  发布在  PWA
关注(0)|答案(1)|浏览(137)

我目前正在开发一个Shopware 6插件,旨在根据商店的默认国家/地区动态确定单个产品的运费。我想在不将产品添加到购物车的情况下获得产品的运费。我的插件目录中的自定义文件MyCustomShippingMethodRoute.php如下所示:

<?php

use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Routing\Annotation\Entity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Shopware\Core\Checkout\Shipping\SalesChannel\AbstractShippingMethodRoute;
use Shopware\Core\Checkout\Shipping\SalesChannel\ShippingMethodRouteResponse;
use SwagProductReview\Service\ShippingPriceService;

/**
 * @Route(defaults={"_routeScope"={"store-api"}})
 */
class MyCustomShippingMethodRoute extends AbstractShippingMethodRoute
{
    private AbstractShippingMethodRoute $decorated;
    private ShippingPriceService $shippingPriceService;

    public function __construct(AbstractShippingMethodRoute $decorated, ShippingPriceService $shippingPriceService) 
    {
        $this->decorated = $decorated;
        $this->shippingPriceService = $shippingPriceService;
    }

    public function getDecorated(): AbstractShippingMethodRoute
    {
        return $this->decorated;
    }

    /**
     * @Entity("shipping_method")
     * @Route("/store-api/shipping-method", name="store-api.shipping.method", methods={"GET", "POST"})
     */
  public function load(Request $request, SalesChannelContext $context, Criteria $criteria): ShippingMethodRouteResponse { $criteria->addAssociation('prices');
      $result = $this->decorated->load($request, $context, $criteria);
      $originalResult = clone $result;
//      $cart = $this->cartService->getCart($context->getToken(), $context);
      $shippingMethods = $result->getShippingMethods()->filterByActiveRules($context);
      /** @var ShippingMethodEntity $shippingMethod */
      try {
          foreach ($shippingMethods as $shippingMethod) {
              $shippingPrices= $shippingMethod->getPrices();
//            dd($shippingMethod->getPrices());
          }
      } catch (\Error $exception) {
          return $originalResult;
      }
      return $result;
  }
}

但是,我遇到了一个问题,我不知道如何在产品详细信息页面上显示$shippingPrices的值。
1.它甚至可以显示运费的详细信息页面,而不添加到购物车?
1.如果是的话,请指导我该怎么做?
此致,

9avjhtql

9avjhtql1#

当你装饰产品详细路线时,你可以注入CartService,以获取当前购物车并将产品作为新的行项目添加到购物车。此外,你可以注入CartRuleLoader并使用它来计算产品添加到购物车的运费。为了避免计算后购物车被持久化,你可以设置一个虚拟值作为购物车的标记,并订阅CartVerifyPersistEvent。在监听器中,你检查该虚拟值的标记,并设置一个标志,使购物车在以后不会被持久化。设置CartBehavior标志还应该防止在较新的版本,但无论哪种方式都可以进行回退检查。

<service id="SwagBasicExample\Route\MyCustomProductDetailRoute" 
         decorates="Shopware\Core\Content\Product\SalesChannel\Detail\ProductDetailRoute" 
         public="true">
    <argument type="service" id="SwagBasicExample\Route\MyCustomProductDetailRoute.inner"/>
    <argument type="service" id="Shopware\Core\Checkout\Cart\SalesChannel\CartService"/>
    <argument type="service" id="Shopware\Core\Checkout\Cart\CartRuleLoader"/>
</service>

<service id="SwagBasicExample\Subscriber\MySubscriber">
    <tag name="kernel.event_subscriber"/>
</service>
use Shopware\Core\Checkout\Cart\CartBehavior;
use Shopware\Core\Checkout\Cart\CartRuleLoader;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Content\Product\SalesChannel\Detail\AbstractProductDetailRoute;
use Shopware\Core\Content\Product\SalesChannel\Detail\ProductDetailRouteResponse;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\Request;

class MyCustomProductDetailRoute extends AbstractProductDetailRoute
{
    public const DUMMY_TOKEN = 'dummy-token';

    public function __construct(
        private readonly AbstractProductDetailRoute $decorated,
        private readonly CartService $cartService,
        private readonly CartRuleLoader $cartRuleLoader
    ) {
    }

    public function getDecorated(): AbstractProductDetailRoute
    {
        return $this->decorated;
    }

    /*
     * @Entity("product")
     * @Route("/store-api/product/{productId}", name="store-api.product.detail", methods={"POST"})
     */
    public function load(string $productId, Request $request, SalesChannelContext $context, Criteria $criteria): ProductDetailRouteResponse
    {
        $result = $this->decorated->load($productId, $request, $context, $criteria);

        $cart = $this->cartService->getCart($context->getToken(), $context);
        $cart->setToken(self::DUMMY_TOKEN);

        $productLineItem = new LineItem($productId, LineItem::PRODUCT_LINE_ITEM_TYPE, $productId);
        $productLineItem->setGood(true);
        $productLineItem->setStackable(true);
        $productLineItem->setRemovable(true);
        
        $cart->add($productLineItem);

        $behavior = new CartBehavior([], true, true);
        $cart = $this->cartRuleLoader->loadByCart($context, $cart, $behavior)->getCart();

        $result->getResult()->addExtension('expectedShippingCosts', $cart->getShippingCosts());

        return $result;
    }
}
use Shopware\Core\Checkout\Cart\Event\CartVerifyPersistEvent;
use SwagBasicExample\Route\MyCustomProductDetailRoute;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class MySubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [CartVerifyPersistEvent::class => 'onCartPersistVerify'];
    }

    public function onCartPersistVerify(CartVerifyPersistEvent $event): void
    {
        if ($event->getCart()->getToken() !== MyCustomProductDetailRoute::DUMMY_TOKEN) {
            return;
        }

        $event->setShouldPersist(false);
    }
}

相关问题