Magento – Create a sortable and filterable custom attribute to stand-alone entity

attributescustom-optionsfilter

I would like to add a custom attribute type that allows an admin to assign a product to a custom entity by name. The end user should be able to sort and filter by the same custom entity.

For example think about a custom entity which is (for example) a region where the product is produced, this region has got many fields amongst which a name, id, and image. All products are assigned to one region. The end user could be interested in products produced only in one certain region and therefore would like to be able to filter on this custom attribute.

I have already created a custom stand-alone entity with a setup script that look like:

$installer = $this;
$installer->startSetup();

$connection = $installer->getConnection();

if($connection->isTableExists("company_custom_region")){
    $connection->dropTable("company_custom_region");
    $connection->commit();
}

$table = $connection
    ->newTable($installer->getTable('company_custom/region'))
    ->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'identity'  => true,
        'unsigned'  => true,
        'nullable'  => false,
        'primary'   => true,
    ), 'ID')
    ->addColumn('name', Varien_Db_Ddl_Table::TYPE_TEXT, 0, array(
        'nullable'  => false,
    ), 'Name')
    ->addColumn('image', Varien_Db_Ddl_Table::TYPE_CLOB, 0, array(
        'nullable'  => false,
    ), 'Image')
;

$installer->getConnection()->createTable($table);

$installer->endSetup();

The next step is to add a custom attribute source by extending the above with the following:

$installer->addAttribute('catalog_product', 'product_type', array(
        'group'             => 'Production region',
        'label'             => 'Region',
        'note'              => '',
        'type'              => 'int',
        'input'             => 'select',
        'frontend_class'    => '',
        'source'            => 'sourcetype/attribute_source_type',
        'backend'           => '',
        'frontend'          => '',
        'global'            => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE,
        'required'          => false,
        'visible_on_front'  => false,
        'apply_to'          => 'simple',
        'is_configurable'   => false,
        'used_in_product_listing'   => false,
        'sort_order'        => 5,
    ));

And then add a custom source type which returns the entity options using the getAllOptions() method:

    public function getAllOptions(){
        $collection = Mage::getModel('company_custom/region')->getCollection()->setOrder('id','asc');

        if (!$this->_options) {
            $this->_options = array();
            foreach($collection as $data){
                $this->_options[] = array(
                    'value' => $data->getData('id'),
                    'label' => $data->getData('name')
                );
            }
        }
        return $this->_options;
    }
}

So far this seems to be pretty straightforward, but the part I am missing is how to extend this custom entity (or the source type) to allow this to be used for sorting and filtering.

My best clue so far is the post by Inchoo: http://inchoo.net/ecommerce/magento/how-to-create-custom-attribute-source-type/ where the addValueSortToCollection($collection, $dir = 'asc') method is implemented.

I cannot find a great deal of information on this method and how to use it, so any hints in the right direction are very welcome!

Best Answer

When adding the product attribute, set used_in_product_listing, used_for_sort_by and filterable to true.

You can do that with the following update script:

$installer = Mage::getResourceModel('catalog/setup', 'catalog_setup');
$installer->startSetup();
$installer->updateAttribute('catalog_product', 'product_type', 'used_in_product_listing', 1);
$installer->updateAttribute('catalog_product', 'product_type', 'used_for_sort_by', 1);
$installer->updateAttribute('catalog_product', 'product_type', 'is_filterable', 1);
$installer->endSetup();

Thats all, if if you are NOT using the flat catalog.

If you enable the flat catalog product feature, then you need to ensure that your custom source model implements the methods getFlatColums(), getFlatIndexes() and getFlatUpdateSelect().
If they are missing, your attribute won't be included in the generated flat tables, even if used_in_product_listing is enabled.
Have a look at the class Mage_Eav_Model_Entity_Attribute_Source_Boolean for an example. You can probably copy over the methods with minimal adjustments into your custom source model from there. Otherwise, please ask a new question.

Related Topic