Magento Forum

   
Filterable attributes not showing up on frontend
 
RuneRifle
Jr. Member
 
Total Posts:  3
Joined:  2013-05-06
 

I have made a script that creates attributes in bulk for me. This script makes use of Mage_Eav_Model_Entity_Setup. It creates attributes and sets and then adds the attributes to the needed sets. That part of the script works. As the title of this topic states, the attributes that should be filterable, are not showing up on the front-end.

This is basically the core code of what I’m doing:

$attributeValues = array(
    
'is_global'                     => '1',
    
'frontend_input'                => 'select',
    
'default_value_text'            => '',
    
'default_value_yesno'           => '0',
    
'default_value_date'            => '',
    
'default_value_textarea'        => '',
    
'is_unique'                     => '0',
    
'is_required'                   => '0',
    
'frontend_class'                => '',
    
'is_searchable'                 => '1',
    
'is_visible_in_advanced_search' => '1',
    
'is_comparable'                 => '0',
    
'is_used_for_promo_rules'       => '0',
    
'is_html_allowed_on_front'      => '1',
    
'is_visible_on_front'           => '1',
    
'used_in_product_listing'       => '1',
    
'used_for_sort_by'              => '0',
    
'is_configurable'               => '0',
    
'is_filterable'                 => '1',
    
'is_filterable_in_search'       => '1',
    
'backend_type'                  => 'varchar',
    
'default_value'                 => '',
    
'apply_to'                      => array(),
    
'attribute_code'                => 'attr_code',
    
'frontend_label'                => array(
        
=> 'Attr Label'
    
)
);

$this->createAttribute($attributeValues);

Where the createAttribute function is:

public function createAttribute($attrData)
{
    $entityTypeID 
Mage::getModel('eav/entity')->setType('catalog_product')->getEntityType()->getId();
    
    
$attribute Mage::getModel('catalog/resource_eav_attribute')->setEntityTypeId($entityTypeID);
    
    
$attribute->addData($attrData);
    
$attribute->setIsUserDefined(1);
    
    
$attribute->save();
    
    
$attributeId $attribute->getId();
}

As you can see, nothing special. On the backend, everything looks perfectly fine, but they are not showing up as filter on the frontend.

I have reindexed (a lot).
I have compared them with attributed that do work, no difference.
There are attributes showing up that were created without this script (brand and price).
Any type of caching is put off.

I am totally clueless on what causes this. It would help me a lot of anyone knew what can cause this..

 
Magento Community Magento Community
Magento Community
Magento Community
 
serpyre
Guru
 
Avatar
Total Posts:  737
Joined:  2013-05-20
 

If you go in and save the attribute manually and then reindex does it work, if so you are missing something in your creation script, no time to look in detail we’re afraid but should point you in the right direction.

 
Magento Community Magento Community
Magento Community
Magento Community
 
RuneRifle
Jr. Member
 
Total Posts:  3
Joined:  2013-05-06
 
serpyre - 28 October 2013 07:02 AM

If you go in and save the attribute manually and then reindex does it work, if so you are missing something in your creation script, no time to look in detail we’re afraid but should point you in the right direction.

Saving manually and then reindexing does nothing. Neither does selecting a different value for a product.

 
Magento Community Magento Community
Magento Community
Magento Community
 
serpyre
Guru
 
Avatar
Total Posts:  737
Joined:  2013-05-20
 

Try creating an attribute by hand, adding a value, assign it in a product and trying reindxing and clear your cache, if that works your create code is wrong. If not, then it is something in your setup, when reindexing reindex all even if it says it is up to date, often is is not.

 
Magento Community Magento Community
Magento Community
Magento Community
 
RuneRifle
Jr. Member
 
Total Posts:  3
Joined:  2013-05-06
 
serpyre - 28 October 2013 07:57 AM

Try creating an attribute by hand, adding a value, assign it in a product and trying reindxing and clear your cache, if that works your create code is wrong. If not, then it is something in your setup, when reindexing reindex all even if it says it is up to date, often is is not.

Alright, I have done that, and it is actually showing up. That means there’s an error in the code. Unfortunately, I don’t see the problem, since the values at the back-end are all correct. What am I missing here?

 
Magento Community Magento Community
Magento Community
Magento Community
 
z3ppelin
Jr. Member
 
Total Posts:  2
Joined:  2012-10-03
Bucharest
 

The problem is because the frontend_input is select and the backend_type is varchar.
When getting filters on frontent, digging in the code I reached this method Mage_Catalog_Model_Layer_Filter_Attribute::_getItemsData() where $optionsCount = $this->_getResource()->getCount($this); returnes nothing because that method makes a query joining the catalog_product_index_eav table looking for the values of your attribute. But your values will never get there. Why? When reindexing in Mage_Catalog_Model_Resource_Product_Indexer_Eav_Source::_getIndexableAttributes() for I don’t know what reason magento only looks for attributes like select-int and multiselect-varchar

/**
     * Retrieve indexable eav attribute ids
     *
     * @param bool $multiSelect
     * @return array
     */
    protected function _getIndexableAttributes($multiSelect)
    
{
        $select 
$this->_getReadAdapter()->select()
            ->
from(array('ca' => $this->getTable('catalog/eav_attribute')), 'attribute_id')
            ->
join(
                array(
'ea' => $this->getTable('eav/attribute')),
                
'ca.attribute_id = ea.attribute_id',
                array())
            ->
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 = ?''select');
        
}
        
        
return $this->_getReadAdapter()->fetchCol($select);
    
}

And if you make your select a multiselect it still wouldn’t work because you have a source model for your options and in Mage_Catalog_Model_Resource_Product_Indexer_Eav_Source::_prepareMultiselectIndex() options are only taken from eav/attribute_option table, magento does not look if the attribute has a source model :(

So solutions are:
1. you override a lot of magento code, although it is not recommended, as I said I don’t know what was the logic when magento implemented this that way
2. more feasable: you make your select to have an int backend_type and you make a mapping between your old string keys to new one int keys and every time you work with that attribute you get your string key by the int key (make a method smth like getRealValue(int value))

PS: I looked into a Magento CE 1.7

 
Magento Community Magento Community
Magento Community
Magento Community
Magento Community
Magento Community
    Back to top