You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 09:41:02