Shopware 6中Product Repository调用商品在Product Block无法正常显示
解决Shopware 6 Storefront商品组件缺失数据问题
问题场景
在Shopware 6 Storefront中尝试引入商品卡片组件(box.html.twig),使用如下Twig代码:
{% include '@Storefront/storefront/component/product/card/box.html.twig' with {'product': product} %}
但组件无法正常显示商品图片、价格等信息,导致渲染异常。获取商品数据的代码通过product.repository服务实现,具体逻辑见下方代码:
namespace RcCarPartScout\Service; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; use Shopware\Core\System\SystemConfig\SystemConfigService; use Shopware\Storefront\Event\StorefrontRenderEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Psr\Container\ContainerInterface; use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting; class AddDataToPage implements EventSubscriberInterface { private SystemConfigService $systemConfigService; private EntityRepository $productRepository; public function __construct( SystemConfigService $systemConfigService, ContainerInterface $container, EntityRepository $productRepository) { $this->systemConfigService = $systemConfigService; $this->productRepository = $productRepository; } public static function getSubscribedEvents(): array { return[ StorefrontRenderEvent::class => 'onStorefrontRender' ]; } /** * @param StorefrontRenderEvent $event */ public function onStorefrontRender(StorefrontRenderEvent $event): void { $event->setParameter('product', $this->getProduct($event->getContext(), $event->getRequest()->get('productnumber'))); } /** * @param Context $context * @param $id */ private function getProduct(Context $context, $id) { $criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('productNumber', $id)); $product = $this->productRepository->search($criteria, $context); $product = $product->first(); return $product; } }
核心原因
Shopware的数据抽象层(DAL)默认不会加载实体的关联数据(如商品媒体、价格、制造商等)。当前查询仅获取了Product实体的基础字段,而box.html.twig组件依赖这些未加载的关联数据来渲染完整的商品卡片。
解决方案
方案1:手动添加必要的关联数据
修改getProduct方法,在Criteria中显式添加组件所需的关联字段:
private function getProduct(Context $context, $id) { $criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('productNumber', $id)); // 添加商品图片关联(含媒体文件详情) $criteria->addAssociation('media'); $criteria->addAssociation('media.media'); // 添加价格关联 $criteria->addAssociation('prices'); // 添加制造商关联(若组件需要) $criteria->addAssociation('manufacturer'); // 可根据组件需求添加更多关联,如categories $product = $this->productRepository->search($criteria, $context); return $product->first(); }
方案2:使用Storefront专用的ProductLoader(推荐)
Shopware Storefront提供了ProductLoaderInterface,它会自动处理Storefront场景下所需的所有关联数据、价格计算(基于当前销售渠道、客户组)和上下文适配,比手动维护关联更可靠。
步骤1:修改类的依赖注入
// 引入ProductLoaderInterface use Shopware\Storefront\Page\Product\ProductLoaderInterface; use Shopware\Core\System\SalesChannel\SalesChannelContext; class AddDataToPage implements EventSubscriberInterface { private SystemConfigService $systemConfigService; private ProductLoaderInterface $productLoader; public function __construct( SystemConfigService $systemConfigService, ContainerInterface $container, ProductLoaderInterface $productLoader) { $this->systemConfigService = $systemConfigService; $this->productLoader = $productLoader; }
步骤2:修改获取商品的逻辑
/** * @param StorefrontRenderEvent $event */ public function onStorefrontRender(StorefrontRenderEvent $event): void { $salesChannelContext = $event->getSalesChannelContext(); $event->setParameter('product', $this->getProduct($salesChannelContext, $event->getRequest()->get('productnumber'))); } /** * @param SalesChannelContext $salesChannelContext * @param string|null $productNumber */ private function getProduct(SalesChannelContext $salesChannelContext, ?string $productNumber): ?Product { if (!$productNumber) { return null; } $criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('productNumber', $productNumber)); $result = $this->productLoader->load($criteria, $salesChannelContext); return $result->getEntities()->first(); }
验证
修改代码后,清除Shopware缓存(执行命令bin/console cache:clear),刷新页面即可看到商品组件正常显示图片、价格等信息。
内容的提问来源于stack exchange,提问作者ollo182
相关产品推荐
相关产品推荐

