LinkedIn Twitter RSS Reset

Creating Custom Sourced Multiselect Product Attribute

Creating Multiselect type of product attribute whose source will be the Magento’s core tables is pretty simple. Just go to Manage Attributes and create a new one. But if you want the attribute’s source table be a custom table, then you need to think. Some times a case pops up that the store admin wants to save custom type of data for attribute’s option and you need to manage an image according to the attribute’s option. So for each option of the multiselect attribute option there is an image associated with it. In this case one of the method to sort out the things is to create a module that gives you an GUI to save option’s data in custom table and give option to upload the image along with it. Later, use this tables data as source of the attribute for product. The first part, saving the data in custom option is not our concern. You can go through this for doing those. But the main point of this article is to use the custom source as source of the muliselect attributes.

Assumming that first part, i.e. the saving of options are already done, you will now need to create a product attributes through SQL Setup

<?php
$installer = $this;
$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$installer->startSetup();
$setup->addAttribute('catalog_product', 'my_attribute', array(
    'input'         => 'multiselect',
	'required'		=> false,
    'type'          => 'text',
    'label'         => 'My Attribute Label',
    'source'        => 'mymodule/source_option',
    'backend'       => 'mymodule/backend_option',
    'global'        => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
    'visible'       => 1,
));
$installer->startSetup();
$installer->endSetup();

The source of the attribute is set to some Model, Ynamespace_Mymodule_Model_Source_Option. This file should look like this.

<?php
class Ynamespace_Module_Model_Source_Option
extends Mage_Eav_Model_Entity_Attribute_Source_Table
{
	public function getAllOptions()
	{
		return $this->getOptionFromTable();
	}

	private function getOptionFromTable(){
		$return=array();
		$col=Mage::getModel("modules/model")->getCollection();
		/**
		* Given that table has column as id,title,image_name
		*
		*/
		foreach($col as $row){
			array_push($return,array('label'=>$row->getTitle(),'value'=>$row->getId()));
		}
		return $return;

	}

	public function getOptionText($value)
	{
		$options = $this->getAllOptions();
		foreach ($options as $option) {
			if(is_array($value)){
				if (in_array($option['value'],$value)) {
					return $option['label'];
				}
			}
			else{
				if ($option['value']==$value) {
					return $option['label'];
				}
			}

		}
		return false;
	}
}

As you can see that the option are retrieved from the custom table in label and value pair. Remember that getAllOptions is called during product export/import as well.

Next important thing you must know is the backend model. Backend model comes into play when you save and load the product. Let me explain. Let us consider a case when you are saving product. The option of this multiselect attribute is sent in post variables as array, but the values cannot be saved as array, either you have to serialize it or implode it into string to save. So to do this change, backend model is there. Similarly, on load you need to explode or unserialize the data from the database to array. So the major functions of backend model are beforeSave() and afterLoad(), which are triggerd as product is saved or loaded. The backend model should look like this:

<?php
class Ynamespace_Modules_Model_Backend_Option
    extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract
{
    /**
     * Before Attribute Save Process
     *
     * @param Varien_Object $object
     * @return Mage_Catalog_Model_Category_Attribute_Backend_Sortby
     */
    public function beforeSave($object) {
        $attributeCode = $this->getAttribute()->getName();
        if ($attributeCode == 'my_attribute') {
            $data = $object->getData($attributeCode);
            if (!is_array($data)) {
                $data = array();
            }
            $object->setData($attributeCode, join(',', $data));
        }
        return $this;
    }

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

Now you are all set, you should have the values of the multiselect attribute saved in database joined by comma seperated values and while on load those values will be exploded as array. Last thing you can do is export the product data using default profile and check if the error shows up or not regarding this attributes. Must not! I think I’ve checked its integrity with import and export as well. If it shows any, feel free to contact me.

16 Responses to “Creating Custom Sourced Multiselect Product Attribute”

  1. Julio
    March 8, 2010 at 3:09 pm #

    I did everything but i getting SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘e.myAttr’ in fieldlist

    • Subesh Pokhrel
      March 8, 2010 at 3:32 pm #

      Do you have myAttr attribute already added in the attribute list? Please check.

      After that please change myAttr to my_attr and its dependent code. This might just help you.

  2. June 13, 2010 at 10:38 am #

    The source is really great.

  3. Boris
    July 8, 2010 at 9:13 am #

    Hi,
    Thanks voor this snippet..
    There’s only one problem for me..
    When I’m trying to edit a product with the new attribute I get an error from magento which says ‘Warning: include(Mage\Attributes\Model\Backend\Option.php) [function.include]: failed to open stream: No such file or directory’
    So it’s trying to open from the folder Mage\..
    And not from the folder where I put the source in.
    That folders is called Bestsellers\..

    I hope you can help me with this..
    Thanks in advance

  4. pablo
    July 10, 2010 at 7:58 pm #

    If I understand correctly you are creating a new db table (model) with custom columns. Then you are using the rows as options for a multiselect attribute?

    Will this work with the Flat Product table? Does Magento knows how to use my custom table to cache the options?
    When editing the custom table, will it reflect in the flat table?

    Thanks

  5. Chris
    October 28, 2010 at 11:47 pm #

    Hi,
    I like your tutorials very much, however I wonder how is it possible to add a new product option type in Magento? In my case, I need a file attachment of ANY type; I know there is the option “File”, but it seems to be tied to pictures only (it checks width and height in the validation, etc). Any hints how to do this in my own custom module? Is it possible to rewrite a part of Mage/Catalog/Model/Product with such a new option? Greetings from Poland and thanks for your help in advance :)
    Krzysztof (Chris)

    • admin
      October 29, 2010 at 4:33 am #

      Hi Chris, I’ve done those type of work.. but can’t write a blog or help you because there is a lot going for that… can’t be helped from distance..I can only help you if you try and get stuck somewhere in the process. Thanks

  6. Łukasz Zaremba
    June 28, 2011 at 4:34 pm #

    Great post! I have been looking something like this for hours. Thank you! Keep up the good work!

  7. sunil
    July 18, 2011 at 12:11 pm #

    HI,
    Thanks ,
    If i select more than one option value ,when i get option value on frontend side get only one value :::
    following code use get value :-
    –>$product->getResource()->getAttribute(‘redemption_code’)->getFrontend()->getValue($product)

  8. amadex
    August 18, 2011 at 5:17 pm #

    Hi! This post is very helpful but I’m really lost. There’s no new attribute…

    I’ve created the following files:
    app/etc/modules/BW_Storeloc.xml
    app/code/local/BW/Storeloc/etc/config.xml
    app/code/local/BW/Storeloc/Model/Backend/Option.php
    app/code/local/BW/Storeloc/Model/Source/Option.php
    app/code/local/BW/Storeloc/sql/storeloc_setup/mysql4-install-0.1.0.php

    The config.xml is like this:

    0.1.0

    BW_Storeloc_Model

    BW_Storeloc

    core_setup

    core_write

    core_read

    The other files are mainly like you explain.

    Can anybody help on this?!….

    Tkx!

    • August 18, 2011 at 11:15 pm #

      Hi! I’ve found the problem. Now I have another one… :) It seems the beforeSave() isn’t being correctly activated. The product doesn’t get updated with the chosen attribute. How can I better find what’s happening? Tkx!

      • admin
        August 19, 2011 at 4:35 am #

        Do you use Eclipse PDT + Xdebug to debug your code?

  9. vipin
    October 11, 2011 at 9:06 am #

    really awesome.. thnx a lot,

  10. October 19, 2011 at 5:08 pm #

    Hi! I’ve put this to work. The only thing that doesn’t work is the loading of options/labels at the attribute backend. I’m on Magento 1.6. What can I do?… tkx

Trackbacks/Pingbacks

  1. Adding new attributes | Magento Media - January 26, 2012

    [...] http://subesh.com.np/2010/01/creating-custom-sourced-multiselect-product-attribute/ [...]

  2. Adding new attributes | Magento Media - January 26, 2012

    [...] http://subesh.com.np/2010/01/creating-custom-sourced-multiselect-product-attribute/ [...]

Leave a Comment