In two previous lessons, we had a look at EAV Model and Magento Product Types. However, these tutorials did not mention how to create an EAV attribute and where to place an EAV attribute.
In this lesson, we will learn custom attributes. It lasts for two hours and is divided into two parts. Now, we begin by describing how to add a custom attribute to a product. Keep up with our Magento Tutorials.
1. How to add a custom attribute to a product
Code example: app\code\local\Magestore\Lesson21\sql\lesson21_setup\mysql4-install-0.1.0.php
1.1. Add a custom attribute to a product
In order to add an attribute to a product, use function addAttribute() of model eav/entity_setup
$setup = new Mage_Eav_Model_Entity_Setup('catalog_setup'); $attr = array( 'group' => 'General', 'type' => 'text', 'input' => 'text', 'label' => 'Is Featured', 'backend' => '', 'frontend' => '', 'source' => 'eav/entity_attribute_source_boolean', 'visible' => 1, 'user_defined' => 1, 'used_for_price_rules' => 1, 'position' => 2, 'unique' => 0, 'default' => '', 'sort_order' => 101 ); $setup->addAttribute('catalog_product','featured',$attr);
- Group: Attribute group added
- Type: It specifies data type of the attribute. Magento has five types: static, datetime, int, text, varchar. Specially, the attributes of static type are stored in main entity table.
- Label: Label of the attribute added
- Backend: This usually has the path of a model class. These model classes are used when saving attribute value in database. For example, saving of product media images requires some operating to happen before and after saving. So those operations are defined in these classes.
Example: Backend model “Mage_Eav_Model_Entity_Attribute_Backend_Array”:
public function beforeSave($object) { $attributeCode = $this->getAttribute()->getAttributeCode(); $data = $object->getData($attributeCode); if (is_array($data)) { $data = array_filter($data); $object->setData($attributeCode, implode(',', $data)); } return parent::beforeSave($object); }
- Frontend: This class is used to change the display format of the values if required. For instance, Mage_Eav_Model_Entity_Attribute_Frontend_Datetime has a getValue() which is used to format dates.
public function getValue(Varien_Object $object) { $data = ''; $value = parent::getValue($object); $format = Mage::app()->getLocale()->getDateFormat( Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM ); if ($value) { try { $data = Mage::getSingleton('core/locale')->date($value, Zend_Date::ISO_8601, null, false)->toString($format); } catch (Exception $e) { $data = Mage::getSingleton('core/locale')->date($value, null, null, false)->toString($format); } } return $data; }
- Source: This is a path to a model, from which values are taken. If attribute type is selected, the options in the dropdown menu are shown from this class.
- Visible: This property plays several roles. The search result filter collection is restricted to the visible attributes (this restriction is absent in the layered navigation filter collection). Only visible attributes can be used by the configurable type products as configurable options. This property also restricts a user’s ability to edit “invisible” attributes in the backend product forms, since such attributes will not be shown there. Exceptions are attributes weight_type,sku_type, and price_type – these attributes are editable, but only in connection to, respectively, the attributes weight, sku, and price. Special renderer blocks are used to display their input fields.
- User defined: Weather is user-generated attribute or magento system attributes.
- User for price rules: The name of this attribute suggests that it controls the attribute ability to be used in catalog price rules. Other attribute properties determine if the attribute is displayed as a possible rule condition in backend. These are is_used_for_promo_rules, is_visible and frontend_input.
- Position: Position of attribute
- Unique: Setting this attribute will command the system to check that there are not any entities of the given type sharing the same value for this attribute. An example could be product SKUs or bar codes.
We can check the result by accessing Catalog/Manage Product and moving to a product.
1.2. Update an available attribute
Code example: app\code\local\Magestore\Lesson21\sql\lesson21_setup\mysql4-upgrade-0.1.0-0.1.1
In this section we can change attribute properties of the attribute we need to update.
$setup = new Mage_Eav_Model_Entity_Setup('catalog_setup'); //get attribute id $attributeId = $setup->getAttributeId('catalog_product', 'is_featured'); //load attribute by id $isFeatured = Mage::getModel('catalog/resource_eav_attribute')->load($attributeId); $isFeatured->addData(array( 'is_global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE, 'is_required' => 0, 'is_configurable' => 1, 'is_searchable' => 1, 'is_visible_in_advanced_search' => 1, 'is_comparable' => 0, 'is_filterable' => 0, 'is_filterable_in_search' => 1, 'is_used_for_promo_rules' => 1, 'is_html_allowed_on_front' => 0, 'is_visible_on_front' => 0, 'used_in_product_listing' => 1, 'used_for_sort_by' => 0, ))->save();
2. EAV attribute in the product collection
By default, a new attribute added to a product won’t be loaded in collection. To load it, use function addAttributeToSelect:
$collection = Mage::getModel('catalog/product')->getCollection(); $collection->addAttributeToSelect('is_featured');
Config to load EAV attribute in product collection outside frontend.
In file config.xml of Catalog module of Core Magento, add attribute code:
Code example: app\code\local\Magestore\Lesson21\etc\config.xml
<frontend> ... <product> <collection> <attributes> <gift_amount/> </attributes> </collection> </product> </frontend>
3. How to get a product attribute value
3.1. Attribute has already loaded in product collection
Use function getData:
$collection = $observer->getCollection(); foreach($collection as $product){ $isFeatured = $product->getIsFeatured(); // or $isFeatured = $product->getData('is_featured'); }
3.2. Attribute has not loaded in product collection yet
We get attribute value from EAV storage tables.
For example: In product list page, discount products whose attribute “is featured” is “yes”.
Step 1: Declare event
catalog_product_collection_load_after trong file config.xml
Code example: app\code\local\Magestore\Lesson21\etc\config.xml
<events> <catalog_product_collection_load_after> <observers> <lesson21_observers> <class>lesson21/observer</class> <method>productCollectionLoadAfter</method> </lesson21_observers> </observers> </catalog_product_collection_load_after> </events>
Step 2: Write function productCollectionLoadAfter in file model observer
Code example: app\code\local\Magestore\Lesson21\Model\Observer.php
public function productCollectionLoadAfter($observer) { $storeId = Mage::app()->getStore()->getId(); $collection = $observer->getCollection(); foreach ($collection as $product) { $isFeatured = Mage::getResourceModel('catalog/product') ->getAttributeRawValue($product->getId(), 'is_featured', $storeId); if($isFeatured) $product->setFinalPrice($product->getFinalPrice()/2); } }
getAttributeRawValue gets value of attribute is_featured without loading product.
+ $product->getId(): product id
+ is_featured: attribute code of attribute needed to get value
+ $storeId: id of store showing product
Result shown as belows:
So, we have just finished another lesson in series Magento Open Course. After learning this tutorial, you should know:
- How to add a custom attribute to a product
- EAV attribute in the product collection
- How to get a product attribute value
Let’s practice and leave us a comment if you have any difficulties. Enjoy coding and see you later. Follow us in Magento Open Course for Magento Tutorial.
1 Comment
It’s useful for me.