odd_duck
odd_duck

Reputation: 4101

Magento - Multi Select Category Attribute not saving

I'm using Magento Community 1.9.0.0.

I have programmatically created a custom category attribute which is a multi select. The attribute can be seen in my admin category section. When i select any values - whether it's one or more and press save i get a successful saved message but the values never save.

I then also tried an extension which creates category attributes. This had the same issue. When i contacted support they said

Category entity does not support multi selection so this type of attribute will not work with category.

Is this true? Can multi select not work on category attributes on CE-1.9?

Here is the code i was using to create it programmatically:

require_once('app/Mage.php');
Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID));
$installer = new Mage_Sales_Model_Mysql4_Setup;
$attribute  = array(
    'type' => 'text',
    'label'=> 'Room Type',
    'input' => 'multiselect',
    'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
    'visible' => true,
    'required' => false,
    'user_defined' => true,
    'default' => "",
    'group' => "General Information",
    'option' => array ( 
        'value' => array(
            'kitchen' => array('Kitchen'), 
            'bedroom' => array('Bedroom'), 
            'bathroom' => array('Bathroom'), 
            'loft' => array('Loft'), 
            'basement' => array('Basement'), 
            'lounge' => array('Lounge')
        ) 
    )

);
$installer->addAttribute('catalog_category', 'room_type', $attribute);
$installer->endSetup();

Upvotes: 0

Views: 2510

Answers (2)

Andi Han
Andi Han

Reputation: 11

@Rian is right, multi-select values are sent as an array, which can't be processed. However, we don't have to use observer. Instead, we should add a backend model for the attribute. Add the following line to your attribute data array when creating it.

'backend' => 'your_module/category_attribute_backend_related',

In your backend model (Your_Module_Model_Category_Attribute_Backend_Related), you should have the following functions to help the selected options be saved or loaded correctly.

public function beforeSave($object) {
    $attributeCode = $this->getAttribute()->getName();
    if ($attributeCode == 'room_type') {
        $data = $object->getData($attributeCode);
        if (!is_array($data)) {
            $data = array();
        }
        $object->setData($attributeCode, join(',', $data));
    }
    if (is_null($object->getData($attributeCode))) {
        $object->setData($attributeCode, false);
    }
    return $this;
}

public function afterLoad($object) {
    $attributeCode = $this->getAttribute()->getName();
    if ($attributeCode == 'room_type') {
        $data = $object->getData($attributeCode);
        if ($data) {
            $object->setData($attributeCode, explode(',', $data));
        }
    }
    return $this;
}

Upvotes: 1

Rian
Rian

Reputation: 296

So this question is a bit old, but I figure better late than never.

Categories can work splendidly with multi selects, you just have to help them along a bit. Multiselects are sent to the category entity as an array, which it can't process, meaning you end up with an empty multiselect. What you want to do is merge the ids into a single string. Either using javascript, or as I did, using an observer.

My multiselect attribute is called category_limit.

This goes in the config.xml

<events>
    <catalog_category_prepare_save>
        <observers>
            <rianorie_categorylimit_save>
                <class>rianorie_categorylimit/observer</class>
                <method>adjustCategory</method>
            </rianorie_categorylimit_save>
        </observers>
    </catalog_category_prepare_save>
</events>

and this is the actual observer doing the work:

class RianOrie_CategoryLimit_Model_Observer
{
    public function adjustCategory(Varien_Event_Observer $observer)
    {
        $event = $observer->getEvent();
        $category = $event->getCategory();
        $category->setCategoryLimit(
              implode(',', $category->getCategoryLimit())
        );
    }
}

Upvotes: 0

Related Questions