来自产品属性的系统值不会被过滤器恢复

System values from Product attributes are not recovered by filter

我有一个自定义产品属性。在backoffice中,value恢复的很好,但是在layer navigation中,filter找不到values

有什么想法吗?

这是属性创建:

$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);  

$eavSetup->addAttribute(
    \Magento\Catalog\Model\Product::ENTITY, 'longueur_tasse_vertuo', [
        'type'  => 'text',
        'backend' => 'Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend',
        'frontend' => '',
        'label' => 'Longueur de tasse Vertuo',
        'input' => 'multiselect',
        'class' => '',
        'source' => 'Cpy\Catalog\Model\Config\Product\CupSizeVertuooption',
        'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
        'visible' => true,
        'required' => false,
        'group' => '',
        'sort_order' => 203,
        'searchable' => false,
        'filterable' => true,
        'comparable' => false,
        'used_in_product_listing' => true,
        'visible_on_front' => true
    ]
);

这是源模型

class CupSizeVertuooption extends AbstractSource
{
    /**
     * @var \Magento\Eav\Model\ResourceModel\Entity\AttributeFactory
     */
    protected $_eavAttrEntity;

    /**
     * @param \Magento\Eav\Model\ResourceModel\Entity\AttributeFactory $eavAttrEntity
     * @codeCoverageIgnore
     */
    public function __construct(
        \Magento\Eav\Model\ResourceModel\Entity\AttributeFactory $eavAttrEntity
    ) {
        $this->_eavAttrEntity = $eavAttrEntity;
    }

    public function getAllOptions()
    {
        $this->_options = [];
        $this->_options[] = ['label' => 'Espresso', 'value' => '1'];
        $this->_options[] = ['label' => 'Double Espresso', 'value' => '2'];
        $this->_options[] = ['label' => 'Gran Lungo', 'value' => '3'];
        $this->_options[] = ['label' => 'Mug', 'value' => '4'];
        $this->_options[] = ['label' => 'Alto', 'value' => '5'];

        return $this->_options;
    }

    /**
     * Retrieve option array
     *
     * @return array
     */
    public function getOptionArray()
    {
        $_options = array();
        foreach ($this->getAllOptions() as $option) {
            $_options[$option['value']] = $option['label'];
        }
        return $_options;
    }

    /**
     * Get a text for option value
     *
     * @param string|integer $value
     * @return string|bool
     */
    public function getOptionText($value)
    {
        foreach ($this->getAllOptions() as $option) {
            if ($option['value'] == $value) {
                return $option['label'];
            }
        }
        return false;
    }

    /**
     * Retrieve flat column definition
     *
     * @return array
     */
    public function getFlatColumns()
    {
        $attributeCode = $this->getAttribute()->getAttributeCode();

        return [
            $attributeCode => [
                'unsigned' => false,
                'default' => null,
                'extra' => null,
                'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                'length' => 255,
                'nullable' => true,
                'comment' => $attributeCode . ' column',
            ],
        ];
    }

    /**
     * Retrieve Indexes(s) for Flat
     *
     * @return array
     */
    public function getFlatIndexes()
    {
        $indexes = [];

        $index = 'IDX_' . strtoupper($this->getAttribute()->getAttributeCode());
        $indexes[$index] = ['type' => 'index', 'fields' => [$this->getAttribute()->getAttributeCode()]];

        return $indexes;
    }

    /**
     * Retrieve Select For Flat Attribute update
     *
     * @param int $store
     * @return \Magento\Framework\DB\Select|null
     */
    public function getFlatUpdateSelect($store)
    {
        return $this->_eavAttrEntity->create()->getFlatUpdateSelect($this->getAttribute(), $store);
    }
}

如您所见,他能够恢复属性...但不能恢复他的内容。

不过,如果我去检查我的后端属性,值就在那里;

此外,这是块定义:

<block class="Magento\Catalog\Block\Product\View\Description" name="product.info.cafe.cupsize" template="Magento_Catalog::product/view/cafe/cup-size.phtml" before="product.info.price" >
    <arguments>
        <argument name="at_call" xsi:type="string">getLongueurTasse</argument>
        <argument name="at_code" xsi:type="string">longueur_tasse</argument>
        <argument name="at_type" xsi:type="string">text</argument>
        <argument name="css_class" xsi:type="string">product-nespresso-cupsize</argument>
        <argument name="at_label" xsi:type="string">Taille des tasses :</argument>
        <argument name="add_attribute" xsi:type="string">itemprop="nespresso-cupsize"</argument>
    </arguments>
</block>

<block class="Magento\Catalog\Block\Product\View\Description" name="product.info.cafe.cupsize.vertuo" template="Magento_Catalog::product/view/cafe/vertuo/cup-size.phtml" before="product.info.price" >
    <arguments>
        <argument name="at_call" xsi:type="string">getLongueurTasseVertuo</argument>
        <argument name="at_code" xsi:type="string">longueur_tasse_vertuo</argument>
        <argument name="css_class" xsi:type="string">product-nespresso-cupsize-vertuo</argument>
        <argument name="at_label" xsi:type="string">Taille des tasses :</argument>
        <argument name="add_attribute" xsi:type="string">itemprop="nespresso-cupsize"</argument>
    </arguments>
</block>

主要问题属于 class vendor/magento/module-catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php

方法

protected function _getIndexableAttributes($multiSelect)
{
    $select = $this->getConnection()->select()->from(
        ['ca' => $this->getTable('catalog_eav_attribute')],
        'attribute_id'
    )->join(
        ['ea' => $this->getTable('eav_attribute')],
        'ca.attribute_id = ea.attribute_id',
        []
    )->where(
        $this->_getIndexableAttributesCondition()
    );

    if ($multiSelect == true) {
        $select->where('ea.backend_type = ?', 'varchar')->where('ea.frontend_input = ?', 'multiselect');
    } else {
        $select->where('ea.backend_type = ?', 'int')->where('ea.frontend_input IN( ? )', ['select', 'boolean']);
    }
    return $this->getConnection()->fetchCol($select);
}

对于多选,所需的类型是 varchar,而我的属性的类型是文本。

所以我们要做的就是把属性类型改成varchar,然后再打一次索引器,得到tablecatalog_product_index_eav里面写的关联geing,就可以出现了在过滤器中。

这是为了快速和立即修复。同时,我将问题发送给 magento,使这个 multiselect where 条件能够读取文本和 varchar 类型,请随时检查它:https://github.com/magento/magento2/issues/29676