Magento Asked on December 14, 2021
My issue is quite simple to resume :
I have 2 products attribute. One of them is already appearing in my filter front panel. The other is not.
I have almost the same configuration for both of them.
What’s tilting me is that I think the configuration is kind of ignored (indeed with that configuration I don’t think neither of these attributes should be added to the filter panel) but one is.
As you can see here is what I have under Product Attributes
The first one is already appearing in filter, but not the second one.
Inside their configuration everything is the same
So my issue is : Why the second one isn’t appearing (I have enought data to make it appear, so it’s not because I don’t have any products with that attributes).
Is there some place in the code where I can check what is going on ?
First attributes properties (the second one is the exact same except he has system values).
Attributes creation :
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
$eavSetup->addAttribute(
MagentoCatalogModelProduct::ENTITY, 'longueur_tasse_vertuo', [
'type' => 'text',
'backend' => 'MagentoEavModelEntityAttributeBackendArrayBackend',
'frontend' => '',
'label' => 'Longueur de tasse Vertuo',
'input' => 'multiselect',
'class' => '',
'source' => 'CpyCatalogModelConfigProductCupSizeVertuooption',
'global' => MagentoEavModelEntityAttributeScopedAttributeInterface::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
]
);
The sources file defines (which are the default system values.
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;
}
I can’t find any setup for the first one that is already appearing.
Also if It can help I have this in a ‘product_cofee.xml’ layout
<block class="MagentoCatalogBlockProductViewDescription" 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="MagentoCatalogBlockProductViewDescription" 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>
#EDIT
My query
2020-07-24T08:37:17+00:00 INFO (6): SELECT `main_table`.`entity_type_id`, `main_table`.`attribute_code`, `main_table`.`attribute_model`, `main_table`.`backend_model`, `main_table`.`backend_type`, `main_table`.`backend_table`, `main_table`.`frontend_model`, `main_table`.`frontend_input`, `main_table`.`frontend_label`, `main_table`.`frontend_class`, `main_table`.`source_model`, `main_table`.`is_required`, `main_table`.`is_user_defined`, `main_table`.`default_value`, `main_table`.`is_unique`, `main_table`.`note`, `additional_table`.*, IFNULL(al.value, main_table.frontend_label) AS `store_label` FROM `eav_attribute` AS `main_table`
INNER JOIN `catalog_eav_attribute` AS `additional_table` ON additional_table.attribute_id = main_table.attribute_id
LEFT JOIN `eav_attribute_label` AS `al` ON al.attribute_id = main_table.attribute_id AND al.store_id = 7 WHERE (main_table.entity_type_id = 4) AND (`additional_table`.`is_filterable` > 0) ORDER BY position ASC
#EDIT Add second request
2020-07-24T13:19:40+00:00 INFO (6): longueur_tasse
2020-07-24T13:19:40+00:00 INFO (6): SELECT `e`.*, `cat_index`.`position` AS `cat_index_position`, `price_index`.`price`, `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price`, `stock_status_index`.`is_salable` FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_category_product_index_store7` AS `cat_index` ON cat_index.product_id=e.entity_id AND cat_index.store_id=7 AND cat_index.visibility IN(2, 4) AND cat_index.category_id=43
INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = '8' AND price_index.customer_group_id = 0
INNER JOIN `catalog_product_entity` AS `product` ON product.entity_id = e.entity_id
INNER JOIN `inventory_stock_8` AS `stock_status_index` ON product.sku = stock_status_index.sku
INNER JOIN `search_tmp_5f1adfebb39791_19171320` AS `search_result` ON e.entity_id = search_result.entity_id ORDER BY `cat_index`.`position` asc, `e`.`entity_id` DESC, `cat_index`.`position` asc
LIMIT 10
2020-07-24T13:19:40+00:00 INFO (6): longueur_tasse_vertuo
2020-07-24T13:19:40+00:00 INFO (6): SELECT `e`.*, `cat_index`.`position` AS `cat_index_position`, `price_index`.`price`, `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price`, `stock_status_index`.`is_salable` FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_category_product_index_store7` AS `cat_index` ON cat_index.product_id=e.entity_id AND cat_index.store_id=7 AND cat_index.visibility IN(2, 4) AND cat_index.category_id=43
INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = '8' AND price_index.customer_group_id = 0
INNER JOIN `catalog_product_entity` AS `product` ON product.entity_id = e.entity_id
INNER JOIN `inventory_stock_8` AS `stock_status_index` ON product.sku = stock_status_index.sku
INNER JOIN `search_tmp_5f1adfebb39791_19171320` AS `search_result` ON e.entity_id = search_result.entity_id ORDER BY `cat_index`.`position` asc, `e`.`entity_id` DESC, `cat_index`.`position` asc
LIMIT 10
EDIT 18/08 :
I’ve been finding the class responsible for the missing data
It’s MagentoFrameworkSearchAdapterMysqlAggregationBuilder
And here is the method
public function build(
DataProviderInterface $dataProvider,
array $dimensions,
RequestBucketInterface $bucket,
Table $entityIdsTable
) {
$metrics = $this->metricsBuilder->build($bucket);
$select = $dataProvider->getDataSet($bucket, $dimensions, $entityIdsTable);
$select->columns($metrics);
$select->group(RequestBucketInterface::FIELD_VALUE);
if($bucket->getName() === 'longueur_tasse_vertuo_bucket' || $bucket->getName() === 'longueur_tasse_bucket'){
var_dump($bucket->getName());
var_dump($dataProvider->execute($select));
}
return $dataProvider->execute($select);
}
With longueur_tasse_bucket
I’ll have the result while with longueur_tasse_vertuo_bucket
I won’t have anything
The main issue belongs to the class vendor/magento/module-catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php
The method
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);
}
For multiselect, the required type was varchar while my attribute had a type text.
So all we have to do is to change the attribute type to varchar and then play the indexer once again to get the association geing written in the table catalog_product_index_eav
making it possible to be appearing in the filter.
This is for the quick and immediate fix. In the same time, I send the issue to magento to make this multiselect where condition be able to read both text and varchar type, feel free to check it : https://github.com/magento/magento2/issues/29676
Answered by Claims on December 14, 2021
You need to put some log at the function MagentoCatalogModelLayerCategoryFilterableAttributeList::getList
this is temporary and therefore can be in the vendor folder directly.
The log we want to use is to know what query runs when the layer filters are pulled in the block MagentoLayeredNavigationBlockNavigation
put the lines below just above the line $collection->load();
$writer = new ZendLogWriterStream(BP . '/var/log/layerdebug.log');
$logger = new ZendLogLogger();
$logger->addWriter($writer);
$logger->info($collection->getSelect()->__toString());
My query on my system is:
SELECT `main_table`.`entity_type_id`, `main_table`.`attribute_code`, `main_table`.`attribute_model`, `main_table`.`backend_model`, `main_table`.`backend_type`, `main_table`.`backend_table`, `main_table`.`frontend_model`, `main_table`.`frontend_input`, `main_table`.`frontend_label`, `main_table`.`frontend_class`, `main_table`.`source_model`, `main_table`.`is_required`, `main_table`.`is_user_defined`, `main_table`.`default_value`, `main_table`.`is_unique`, `main_table`.`note`, `additional_table`.*, IFNULL(al.value, main_table.frontend_label) AS `store_label` FROM `eav_attribute` AS `main_table`
INNER JOIN `catalog_eav_attribute` AS `additional_table` ON additional_table.attribute_id = main_table.attribute_id
LEFT JOIN `eav_attribute_label` AS `al` ON al.attribute_id = main_table.attribute_id AND al.store_id = 1 WHERE (main_table.entity_type_id = 4) AND (`additional_table`.`is_filterable` > 0)
Once we will know your query, it is likely we will understand why your first system product attribute is not with us.
Step 2: if the above returns the attribute, at this point we want to check if the attributes has some options to render:
same process as above can apply to troubleshoot, you may go to the function MagentoCatalogSearchModelLayerFilterAttribute::_getItemsData
and put the log just above this line
$isAttributeFilterable =
$this->getAttributeIsFilterable($attribute) === static::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS;
$writer = new ZendLogWriterStream(BP . '/var/log/layerdebug.log');
$logger = new ZendLogLogger();
$logger->addWriter($writer);
$logger->info($productCollection->getSelect()->__toString());
then at this point, everything should come together. Of course, the query may be big but essentially, you are within the bone of the feature.. and then there is nothing deeper.. so we better have to find from here
Answered by Herve Tribouilloy on December 14, 2021
It does seem the one that is product attribute that is system does not want to be in the layer.
I will look into it now. Having said that, one would think it might be worth creating a new product attribute identical to the no system one and then 'do assign your data to the new attribute and refresh index..'
that should be a quick win, if you want to do this and you miss a script to update the attribute, I surely can provide you with this script
Answered by Herve Tribouilloy on December 14, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP