来自产品属性的系统值不会被过滤器恢复
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
我有一个自定义产品属性。在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