Shopware(PHP)商品所有变体加载代码返回空列表的修复方案
代码问题原因及修复方案
问题定位
你的代码出现空返回主要有3个核心错误:
- 过滤字段多加了不必要的
product.前缀,导致字段匹配失败 - 依赖未预加载的
getParent()关联获取父产品,大概率返回null,过滤条件失效 - 普通产品仓储传入销售渠道上下文查询时,默认会应用额外的可见性过滤,容易漏数据
修复后的完整代码
use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult; use Shopware\Storefront\Page\Product\ProductPageLoadedEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ProductViewSubscriber implements EventSubscriberInterface { // 如果你需要查询当前销售渠道可见的变体,注入sales_channel.product.repository即可 private EntityRepositoryInterface $productRepository; public function __construct(EntityRepositoryInterface $productRepository) { $this->productRepository = $productRepository; } public function getVariantsOfProduct(SalesChannelProductEntity $product, Context $context): EntitySearchResult { // 优先用parentId判断,不依赖未预加载的parent关联 $parentId = $product->getParentId() ?? $product->getUniqueIdentifier(); $criteria = new Criteria(); // 去掉不必要的product.前缀 $criteria->addFilter(new EqualsFilter('parentId', $parentId)); // 如果需要查所有变体(包括不活跃、不在当前销售渠道的),就用默认上下文,替换下面的$context为Context::createDefaultContext() return $this->productRepository->search($criteria, $context); } public static function getSubscribedEvents(): array { return [ ProductPageLoadedEvent::class => ['addVariants'], ]; } public function addVariants(ProductPageLoadedEvent $pEvent) { $products = $this->getVariantsOfProduct($pEvent->getPage()->getProduct(), $pEvent->getContext()); $matchingVariants = $products->getElements(); // 后续可以把$matchingVariants赋值到页面对象上使用 } }
额外注意事项
- 如果你在services.yaml中注入的是默认的
product.repository,查询时如果用销售渠道上下文,会自动过滤掉未上架、不在当前销售渠道分配、无库存的变体,符合前端展示的需求 - 如果你需要查询所有变体不管状态,就把search方法的第二个参数换成
Context::createDefaultContext()即可
内容的提问来源于stack exchange,提问作者simon_kohl
相关产品推荐
相关产品推荐

