Showing posts with label attribute. Show all posts
Showing posts with label attribute. Show all posts

Friday, November 2, 2012

Product attribute with custom options

Magento gives you the possibility to create dropdown product attributes. The problem I have sometimes is that the options for all the dropdown attributes are all in one single table. So for each option I get a (somehow) random ID. There are cases that I really need to know the id of one specific option and I don't want to hard code it. The solution for this is to have a custom source model for your dropdown attributes. The following example creates an attribute called 'Provider' with custom options. For the purpose of the example I'm going to use the namespace 'Easylife' and my extension is going to be names 'Provider'.
Here are the files you need to create:
app/code/local/Easylife/Provider/etc/config.xml - the extension config file
<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Provider>
            <version>0.0.1</version>
        </Easylife_Provider>
    </modules>
    <global>
        <models>
            <provider>
                <class>Easylife_Provider_Model</class>
            </provider>
        </models>
        <resources>
            <easylife_provider_setup>
                <setup>
                    <module>Easylife_Provider</module>
                    <class>Mage_Catalog_Model_Resource_Eav_Mysql4_Setup</class>
                </setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </easylife_provider_setup>
        </resources>
    </global>
</config>
app/code/local/Easylife/Provider/sql/easylife_provider_setup/mysql4-install-0.0.1.php - this will add an attribute named 'Provider' to your product
<?php
$this->startSetup();
//if you want to add the attribute to the category instead of the product change on the line below 'catalog_product' to 'catalog_category'
$this->addAttribute('catalog_product', 'provider', array(
        'group'                => 'General',
        'type'              => 'int',
        'backend'           => '',
        'frontend_input'    => '',
        'frontend'          => '',
        'label'             => 'Provider',
        'input'             => 'select',
        'class'             => '',
        'source'            => 'provider/attribute_source_provider',
        'global'             => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,//can be SCOPE_WEBSITE or SCOPE_STORE
        'visible'           => true,
        'used_in_product_listing' =>true,//can also be false
        'frontend_class'     => '',
        'required'          => false,//can be true
        'user_defined'      => true,
        'default'           => '',
        'searchable'        => false,//can be true
        'filterable'        => false,//can be true
        'comparable'        => false,//can be true
        'visible_on_front'  => false,//can be true
        'unique'            => false,
        'position'            => 60,//put any number here
    ));
$this->endSetup();
app/code/local/Easylife/Provider/Model/Attribute/Source/Provider.php - this is the source of you attribute
<?php
class Easylife_Provider_Model_Attribute_Source_Provider extends Mage_Eav_Model_Entity_Attribute_Source_Abstract{
    protected $_options = null;
    public function getAllOptions($withEmpty = false){
        if (is_null($this->_options)){
            $this->_options = array();
                       //$this->_options[] = array('label'=>'HERE GOES THE LABEL', 'value'=>'HERE GOES THE VALUE');
            //as example
            $this->_options[] = array('label'=> $this->__('Provider 1'), value=>1);
            $this->_options[] = array('label'=> $this->__('Provider 2'), value=>2);
            $this->_options[] = array('label'=> $this->__('Provider 3'), value=>3);
        }
        $options = $this->_options;
        if ($withEmpty) {
            array_unshift($options, array('value'=>'', 'label'=>''));
        }
        return $options;
    }
    public function getOptionText($value)
    {
        $options = $this->getAllOptions(false);

        foreach ($options as $item) {
            if ($item['value'] == $value) {
                return $item['label'];
            }
        }
        return false;
    }
    public function getFlatColums()
    {
        $attributeCode = $this->getAttribute()->getAttributeCode();
        $column = array(
            'unsigned'  => false,
            'default'   => null,
            'extra'     => null
        );

        if (Mage::helper('core')->useDbCompatibleMode()) {
            $column['type']     = 'int(10)';
            $column['is_null']  = true;
        } else {
            $column['type']     = Varien_Db_Ddl_Table::TYPE_SMALLINT;
            $column['length']   = 10;
            $column['nullable'] = true;
            $column['comment']  = $attributeCode . ' column';
        }

        return array($attributeCode => $column);
    }
    public function getFlatUpdateSelect($store)
    {
        return Mage::getResourceModel('eav/entity_attribute')
            ->getFlatUpdateSelect($this->getAttribute(), $store);
    }
}
app/etc/modules/Easylife_Provider.xml - the module declaration
<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Provider>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Catalog />
            </depends>
        </Easylife_Provider>
    </modules>
</config>
That's it. Clear the cache and try again. If you choose to include the attribute in the product listing or if you made it filtrable
'used_in_product_listing' =>true,
...
'filterable'        => false
then you need to rebuild your indexes. Now if you need to get all the products that belong to 'Provider 1' all you need to do is this:
$products = Mage::getModel('catalog/product')->getCollection()->addAttributeToFilter('provider', 1);
Enjoy, Marius.

Tuesday, October 30, 2012

Add a new field to the store view

Here is the clear way to add a new field on the store view in Magento.
In order to do this you should create a new extension.
For the purpose of this demo I will use the 'namespace' Easylife. replace it with your own namespace if you want.
The extension is named Core because I'm overriding something in the core. You can name it how ever you want. Here are the files that need to be created:

app/code/local/Easylife/Core/etc/config:
<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Core>
            <version>0.0.1</version>
        </Easylife_Core>
    </modules>
    <global>
        <resources>
            <easylife_core_setup>
                <setup>
                    <module>Easylife_Core</module>
                </setup>
            </easylife_core_setup>
        </resources>
        <blocks>
            <adminhtml>
                <rewrite>
                    <system_store_edit_form>Easylife_Core_Block_Adminhtml_System_Store_Edit_Form</system_store_edit_form>
                </rewrite>
            </adminhtml>
        </blocks>
    </global>
</config>
app/code/local/Easylife/Core/sql/easylife_core_setup/mysql4-install-0.0.1.php
<?php 
$this->startSetup();
$this->run("ALTER TABLE `{$this->getTable('core/store')}` ADD COLUMN `custom` VARCHAR(255)");//change the name and type of the column if you need.
$this->endSetup();
app/code/local/Easylife/Core/Block/Adminhtml/System/Store/Edit/Form.php - this overrides the admin block.
<?php 
class Easylife_Core_Block_Adminhtml_System_Store_Edit_Form extends Mage_Adminhtml_Block_System_Store_Edit_Form{
    protected function _prepareForm(){
        parent::_prepareForm();
        if (Mage::registry('store_type') == 'store'){
            $storeModel = Mage::registry('store_data');
            $fieldset = $this->getForm()->getElement('store_fieldset');
            $fieldset->addField('custom', 'text', array(
                    'name'      => 'store[custom]',
                    'label'     => Mage::helper('core')->__('Custom'),
                    'required'  => true,//or false
                    'value'        => $storeModel->getData('custom') 
                ));
        }
        return $this;
    }
}
In order to activate your module you need this file
app/etc/modules/Easylife_Core.xml
<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Core>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Core/>
            </depends>
        </Easylife_Core>
    </modules>
</config>
Enjoy.
Marius.

Monday, March 1, 2010

Retrieve attributes by groupId

Problem: how to retrieve product attributes by group id.
See here: http://www.magentocommerce.com/boards/viewthread/79694/

Possible solution:
<?php
require_once 'path/to/app_dir/app/Mage.php';
Mage::app('default');
$product = Mage::getModel('catalog/product');
$product->setAttributeSetId('THE ATTRIBUTE SET YOU WANT TO USE');
$groupId = 'THE ID OF THE GROUP YOU WANT TO RETRIEVE';

$collection = $product->getAttributes($groupId, false);
foreach($collection as $attribute){
//do something with the attribute
}
?>