10

I have a custom multi select attribute which I'd like to take part in filtering of products. The attribute is set as used in Layered Navigation however doesn't appear in the list of available filters. Could be due to custom model implementation? Anyone have some tips where to check why it doesn't appear? Attribute is set for several products Magento version used is EE 1.11

Thanks

Zifius
  • 1,650
  • 1
  • 16
  • 27
  • Figured it out to the point `Mage_Catalog_Model_Layer_Filter_Attribute` method `getCount` doesn't return products beloning to the multi select attribute – Zifius Sep 30 '11 at 14:17
  • More details, the method doesn't return optionId => productCount pairs for multiselect attribute. Here is the relevant SQL generated: http://pastebin.com/JJnnXHKG – Zifius Oct 03 '11 at 08:20
  • My custom attribute is probably not saving data properly to `catalog_product_index_eav` table as there are no entries associated with attribute's id – Zifius Oct 03 '11 at 08:30
  • Probably caused by the fact that I use flat collection for the attribute – Zifius Oct 03 '11 at 08:58
  • did you ever get your custom source model to be indexed properly for the layered navigation? I checked your GH, but I don't think I see the module. – laketuna Jan 19 '15 at 23:07

3 Answers3

14

For those who will struggle with this in the future: the problem is in Mage_Catalog_Model_Resource_Product_Indexer_Eav_Source file on line 191. By default multi select attribute values are being pulled from eav_attribute_option and if your custom attribute uses custom source model the attribute will not be indexed.

I don't know as of yet if it's intended but I couldn't find a better solution than overriding that model in local pull and adding required values in $options array.

Hope this helps someone, someday

Zifius
  • 1,650
  • 1
  • 16
  • 27
  • Wow. It took me forever to find this post, and now I'm feeling slightly redeemed that it wasn't necessarily a problem with my module, but is instead effectively a Magento bug. – pspahn Jan 29 '13 at 00:32
  • Do you have a sample of what you added to the core file to make this work? – pspahn Jan 29 '13 at 00:39
  • 2
    @pspahn yes, see this gist: https://gist.github.com/52856ac5ebe016a9caa9 I'm yet unsure if it's my lack of indexers knowledge or a bug. You can also find the rest of the module at my GH. Use with care! – Zifius Jan 29 '13 at 14:00
13

What is the backend_type. i.e. are the values stored in the catalog_product_entity_varchar or catalog_product_entity_text table?
The backend_type has to match the checks in Mage_Catalog_Model_Resource_Eav_Attribute::isIndexable(), so text wouldn't work without rewriting the attribute model.

Is the is_filterable and/or is_filterable_in_search attribute property set?
The Mage_Catalog_Model_Product_Indexer_Eav::_registerCatalogAttributeSaveEvent() checks for those when updating the index for the layered navigation.

Are the methods getFlatColums(), getFlatIndexes() and getFlatUpdateSelect() implemented in the custom source model?
This actually is only required for building and updating the flat catalog product tables (so the used_in_product_listing or is_filterable property needs to be set in order for Magento to pick up the attribute).
Check the class Mage_Eav_Model_Entity_Attribute_Source_Table as a reference on what these there methods are supposed to return.

Vinai
  • 14,162
  • 2
  • 49
  • 69
  • Thanks, found a lot of mistakes. Indeed my attribute used `text` type as its backend. It should work if I change it to `varchar` directly in `eav_attribute` table, no need to recreate via a setup script, right? `is_filtrable` was set, setting now `is_filterable_in_search` as well. Main question now, do I extend `Mage_Eav_Model_Entity_Attribute_Source_Table` or `Mage_Eav_Model_Entity_Attribute_Source_Abstract`? Thank you very much for the insight – Zifius Oct 03 '11 at 11:38
  • By the way `isIndexable` method also checks for `is_visible_in_advanced_search` flag to be true – Zifius Oct 03 '11 at 11:55
  • Still can't get it working. My problems is in `Mage_Catalog_Model_Resource_Layer_Filter_Attribute` `getCount` method. It seems it doesn't work with multi select very well unless I'm missing something. Maybe I need to override it – Zifius Oct 03 '11 at 13:13
  • 1
    If you don't use the attribute option tables I suggest extending Mage_Eav_Model_Entity_Attribute_Source_Abstract. is_visible_in_advanced_search is only checked in conjuction with is_filterable and is_filterable_in_search (only setting one is enough if the others aren't needed). – Vinai Oct 03 '11 at 14:18
  • 1
    Mage_Catalog_Model_Resource_Layer_Filter_Attribute::getCount() should work if the indexer picks up the attribute correctly. You can change the backend_type in eav_attribute directly, but be sure to remove obsolete entries from catalog_product_entity_text (and fix the setup script, too). – Vinai Oct 03 '11 at 14:23
  • There seems to be indeed problem with indexer, attributes values aren't written into `catalog_product_index_eav`. While debugging I see that method of my source model `getFlatUpdateSelect` is called and right now I'm doing `return parent::getFlatUpdateSelect($store);` as I've extended `Mage_Eav_Model_Entity_Attribute_Source_Table` but perhaps I need to do something more smart there to explode comma-separated values from `catalog_product_entity_varchar` – Zifius Oct 03 '11 at 14:29
  • And you are of course right about `is_visible_in_advanced_search`. I've misread the code – Zifius Oct 03 '11 at 14:39
  • Works perfectly when I've added a test entry into `catalog_product_index_eav` table. So it must be indexer problem. Sadly I'm not experienced about indexes – Zifius Oct 03 '11 at 15:15
  • Maybe I need to set `backend_table` value? Really lost here – Zifius Oct 03 '11 at 15:34
  • Dug indexer code with xdebug. Found a place where indexing of my attribut omitted. It's happening on the line 191 of `Mage_Catalog_Model_Resource_Product_Indexer_Eav_Source` where it looks into `eav_attribute_option` table. My attribute id is not there – Zifius Oct 03 '11 at 19:32
  • Feels like I'm missing something really trivial. Here are exports of attribute's properties http://pastebin.com/JxT6cZPy – Zifius Oct 03 '11 at 19:39
  • Also, I my catalog is EAV. So I went back to `Mage_Eav_Model_Entity_Attribute_Source_Abstract` source. Currently solved by doing a dirty hack with adding attribute options to that `$options` array in `Mage_Catalog_Model_Resource_Product_Indexer_Eav_Source` class but would love to hear a proper solution or confirm it's a bug in the core. Thank you. System says can award bounty in one hour :) – Zifius Oct 04 '11 at 06:02
9

NOTE: I'm adding this in a new answer to use the code format.

How it was said, the problem is with multiselect attributes using a custom source model.

Solution: Rewrite the class

Mage_Catalog_Model_Resource_Product_Indexer_Eav_Source

Override the method:

_prepareMultiselectIndex

add this code after the $options array is filled with the default code (check line 200 in original file)

foreach($attrIds as $attId){
            if( ! isset($options[$attId])){
                $options[$attId] = $this->_getOptionsFromSourceModel($attId);
            }
        }

add this method too:

protected function _getOptionsFromSourceModel($attId)
    {
        $options = array();
        /** @var Mage_Eav_Model_Entity_Attribute_Abstract $attribute */
        $attribute = Mage::getResourceSingleton('catalog/product')->getAttribute($attId);
        /** @var Mage_Eav_Model_Entity_Attribute_Source_Abstract $source */
        $source = $attribute->getSource();
        $sourceOptions = $source->getAllOptions();
        if($sourceOptions){
            foreach($sourceOptions as $sourceOption){
                if(isset($sourceOption['value'])){
                    $options[$sourceOption['value']] = true;
                }
            }
        }
        return $options;
    }

I couldn't find a less intrusive way to fix this.

Enrique
  • 4,693
  • 5
  • 51
  • 71