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

Shopware 6中基于实体和值的条件循环实现问题求助

问题分析与修复方案

你的代码存在3个核心问题,直接导致TagCollection为空:

1. 属性选项查询未过滤,循环判断逻辑完全错误

你当前查询了所有属性选项,后续循环里用in_array($options, $currentPropertyOptions)——这里$options是整个选项集合,不是单个选项的标识,根本无法匹配选中的选项ID数组。

修复:
直接在查询属性选项时就通过currentPropertyOptions过滤,只获取选中的选项,避免无效循环:

// 替换原有的criteria1和options查询代码
$criteria1 = new Criteria($currentPropertyOptions); // 直接传入选中的选项ID数组作为筛选条件
$criteria1->addAssociation('myTags');

$tags = new TagCollection();
$options = $this->optionRepository->search($criteria1, $event->getContext())->getEntities();
/** @var PropertyGroupOptionEntity $option */
foreach ($options as $option) {
    $extension = $option->getExtension('myTags');
    
    if (!$extension instanceof TagCollection) {
        continue;
    }
    
    // 无需再判断选项是否在选中列表里,因为查询已经过滤过了
    $tags->merge($extension);
}

2. 标签值提取逻辑缺失

你需要将TagCollection转换为标签值数组,后续才能用于筛选:

// 在获取tags集合后,提取值到数组
$tagValues = [];
foreach ($tags as $tag) {
    $tagValues[] = $tag->getName(); // 或者$tag->getValue(),根据你的标签存储字段调整
}

3. Filter字段路径错误

原代码中的PrefixFilter('product.properties.name', $tag)字段路径有误,Shopware的Criteria关联字段不需要加product.前缀,直接用关联名称即可:

// 替换原有的multiFilter循环代码
foreach ($tagValues as $tagValue) {
    $multiFilter->addQuery(new PrefixFilter('properties.group.name', $tagValue)); 
    // 若要筛选属性选项名称则用'properties.name',根据你的需求调整
}

完整修正后的核心代码片段

public function onListingCriteria(ProductListingCriteriaEvent $event): void
{
    $event->getCriteria()->addAssociation('properties');
    $event->getCriteria()->addAssociation('properties.group');

    $criteria = $event->getCriteria();
    $filters = $criteria->getExtension('filters');

    if (!$filters instanceof FilterCollection) {
        return;
    }

    $propertyFilter = $filters->get('properties');

    if (!$propertyFilter instanceof Filter || !\is_array($propertyFilter->getValues())) {
        return;
    }

    $currentPropertyOptions = $propertyFilter->getValues();

    $event->getContext()->addExtension('currentPropertyOptionsCriteria', new ArrayEntity($currentPropertyOptions));

    // 仅查询选中的属性选项
    $criteria1 = new Criteria($currentPropertyOptions);
    $criteria1->addAssociation('myTags');

    $tags = new TagCollection();
    $options = $this->optionRepository->search($criteria1, $event->getContext())->getEntities();
    /** @var PropertyGroupOptionEntity $option */
    foreach ($options as $option) {
        $extension = $option->getExtension('myTags');
        
        if (!$extension instanceof TagCollection) {
            continue;
        }
        
        $tags->merge($extension);
    }

    // 提取标签值到数组
    $tagValues = [];
    foreach ($tags as $tag) {
        $tagValues[] = $tag->getName(); // 按实际字段调整,比如getValue()
    }

    $event->getContext()->addExtension('myTags1', new ArrayEntity($tagValues)); // 用ArrayEntity包装数组存入上下文

    if (in_array('3f777000a2734deead391133cee3a6a9', $currentPropertyOptions)) {
        $multiFilter = new MultiFilter(MultiFilter::CONNECTION_OR);

        foreach ($tagValues as $tagValue) {
            // 字段路径根据需求调整:properties.name(选项名)或properties.group.name(属性组名)
            $multiFilter->addQuery(new PrefixFilter('properties.group.name', $tagValue));
        }

        $criteria->addFilter($multiFilter);
    }
    // ... 后续代码
}

额外注意事项

  • 确认myTags是PropertyGroupOptionEntity的正确关联名称,若关联定义的是tags则需改为$option->getExtension('tags')
  • 检查标签实体的字段,确保getName()或getValue()能正确获取到你需要的筛选值
  • 若currentPropertyOptions存储的是选项的value而非id,则查询时需要用EqualsAnyFilter代替直接传入ID数组:
    $criteria1 = new Criteria();
    $criteria1->addFilter(new EqualsAnyFilter('value', $currentPropertyOptions));
    $criteria1->addAssociation('myTags');
    

内容的提问来源于stack exchange,提问作者Stacker1427

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:15:34