How to create an EAV entity?
Part 1
For the purpose of this demo I'm going to create a module, let's name it Easylife_News
that contains an entity named Article
.
The module comes with complete CRUD code for backend, including the section for managing attributes, and some simple frontend listing and view page for each article. It also ads a menu item in the top menu to the listing of articles.
It also contains URL rewrites, RSS feed and breadcrumbs for frontend.
This entity will have 4 attributes: Title, Short Description, Description, Publish Date
in addition to the system ones (created_at
, updated_at
, status
, in_rss
, url_key
).
The module should contain the following files.
app/etc/module/Easylife_News.xml
- the declaration module:
<?xml version="1.0"?>
<config>
<modules>
<Easylife_News>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Catalog /><!-- some classes extend one class from the catalog module to avoid duplicating it -->
</depends>
</Easylife_News>
</modules>
</config>
app/code/local/Easylife/News/etc/config.xml
- the configuration file
<?xml version="1.0"?>
<config>
<modules>
<Easylife_News>
<version>1.0.0</version>
</Easylife_News>
</modules>
<global>
<resources>
<easylife_news_setup>
<setup>
<module>Easylife_News</module>
<class>Easylife_News_Model_Resource_Setup</class>
</setup>
</easylife_news_setup>
</resources>
<blocks>
<easylife_news>
<class>Easylife_News_Block</class>
</easylife_news>
</blocks>
<helpers>
<easylife_news>
<class>Easylife_News_Helper</class>
</easylife_news>
</helpers>
<models>
<easylife_news>
<class>Easylife_News_Model</class>
<resourceModel>easylife_news_resource</resourceModel>
</easylife_news>
<easylife_news_resource>
<class>Easylife_News_Model_Resource</class>
<entities>
<article>
<table>easylife_news_article</table>
</article>
<eav_attribute>
<table>easylife_news_eav_attribute</table>
</eav_attribute>
</entities>
</easylife_news_resource>
</models>
<events>
<controller_front_init_routers><!-- event for custom router - url rewrites -->
<observers>
<easylife_news>
<class>Easylife_News_Controller_Router</class>
<method>initControllerRouters</method>
</easylife_news>
</observers>
</controller_front_init_routers>
</events>
</global>
<adminhtml>
<layout>
<updates>
<easylife_news>
<file>easylife_news.xml</file>
</easylife_news>
</updates>
</layout>
<translate>
<modules>
<Easylife_News>
<files>
<default>Easylife_News.csv</default>
</files>
</Easylife_News>
</modules>
</translate>
<global_search>
<article>
<class>easylife_news/adminhtml_search_article</class>
<acl>easylife_news</acl>
</article>
</global_search>
</adminhtml>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<Easylife_News before="Mage_Adminhtml">Easylife_News_Adminhtml</Easylife_News>
</modules>
</args>
</adminhtml>
</routers>
</admin>
<frontend>
<events>
<page_block_html_topmenu_gethtml_before><!-- add link to top menu -->
<observers>
<easylife_news>
<class>easylife_news/observer</class>
<method>addItemsToTopmenuItems</method>
</easylife_news>
</observers>
</page_block_html_topmenu_gethtml_before>
</events>
<routers>
<easylife_news>
<use>standard</use>
<args>
<module>Easylife_News</module>
<frontName>news</frontName>
</args>
</easylife_news>
</routers>
<layout>
<updates>
<easylife_news>
<file>easylife_news.xml</file>
</easylife_news>
</updates>
</layout>
<translate>
<modules>
<Easylife_News>
<files>
<default>Easylife_News.csv</default>
</files>
</Easylife_News>
</modules>
</translate>
</frontend>
<default>
<easylife_news>
<article>
<breadcrumbs>1</breadcrumbs>
<url_prefix>article</url_prefix>
<url_suffix>html</url_suffix>
<rss>1</rss>
<meta_title>Articles</meta_title>
</article>
</easylife_news>
</default>
</config>
app/code/local/Easylife/News/etc/adminhtml.xml
- the admin acl and menu file.
<?xml version="1.0"?>
<config>
<acl>
<resources>
<admin>
<children>
<system>
<children>
<config>
<children>
<easylife_news translate="title" module="easylife_news">
<title>News</title>
</easylife_news>
</children>
</config>
</children>
</system>
<cms>
<children>
<easylife_news translate="title" module="easylife_news">
<title>News</title>
<children>
<article translate="title" module="easylife_news">
<title>Article</title>
<sort_order>0</sort_order>
</article>
<article_attributes translate="title" module="easylife_news">
<title>Manage Article attributes</title>
<sort_order>7</sort_order>
</article_attributes>
</children>
</easylife_news>
</children>
</cms>
</children>
</admin>
</resources>
</acl>
<menu>
<cms><!-- I added the admin menu under CMS. Feel free to move it. -->
<children>
<easylife_news translate="title" module="easylife_news">
<title>News</title>
<sort_order>17</sort_order>
<children>
<article translate="title" module="easylife_news">
<title>Article</title>
<action>adminhtml/news_article</action>
<sort_order>0</sort_order>
</article>
<article_attributes translate="title" module="easylife_news">
<title>Manage Article Attributes</title>
<action>adminhtml/news_article_attribute</action>
<sort_order>7</sort_order>
</article_attributes>
</children>
</easylife_news>
</children>
</cms>
</menu>
</config>
app/code/local/Easylife/News/etc/system.xml
- the system configuration file. It allows you to manage a few settings like SEO for the articles list, breadcrumbs, RSS enable/disable, url prefix and suffix
<?xml version="1.0"?>
<config>
<tabs>
<easylife translate="label" module="easylife_news">
<label>News</label>
<sort_order>2000</sort_order>
</easylife>
</tabs>
<sections>
<easylife_news translate="label" module="easylife_news">
<class>separator-top</class>
<label>News</label>
<tab>easylife</tab>
<frontend_type>text</frontend_type>
<sort_order>100</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<groups>
<article translate="label" module="easylife_news">
<label>Article</label>
<frontend_type>text</frontend_type>
<sort_order>0</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<fields>
<breadcrumbs translate="label">
<label>Use Breadcrumbs</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_yesno</source_model>
<sort_order>10</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</breadcrumbs>
<url_prefix translate="label comment">
<label>URL prefix</label>
<frontend_type>text</frontend_type>
<sort_order>20</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<comment>Leave empty for no prefix</comment>
</url_prefix>
<url_suffix translate="label comment">
<label>Url suffix</label>
<frontend_type>text</frontend_type>
<sort_order>30</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<comment>What goes after the dot. Leave empty for no suffix.</comment>
</url_suffix>
<rss translate="label">
<label>Enable rss</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_yesno</source_model>
<sort_order>40</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</rss>
<meta_title translate="label">
<label>Meta title for articles list page</label>
<frontend_type>text</frontend_type>
<sort_order>50</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</meta_title>
<meta_description translate="label">
<label>Meta description for articles list page</label>
<frontend_type>textarea</frontend_type>
<sort_order>60</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</meta_description>
<meta_keywords translate="label">
<label>Meta keywords for articles list page</label>
<frontend_type>textarea</frontend_type>
<sort_order>70</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</meta_keywords>
</fields>
</article>
</groups>
</easylife_news>
</sections>
</config>
app/code/local/Easylife/News/sql/easylife_news_setup/install-1.0.0.php
- the install script
<?php
$this->startSetup();
//create the entity table
$table = $this->getConnection()
->newTable($this->getTable('easylife_news/article'))
->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
'identity' => true,
'unsigned' => true,
'nullable' => false,
'primary' => true,
), 'Entity ID')
->addColumn('entity_type_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
'unsigned' => true,
'nullable' => false,
'default' => '0',
), 'Entity Type ID')
->addColumn('attribute_set_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
'unsigned' => true,
'nullable' => false,
'default' => '0',
), 'Attribute Set ID')
->addColumn('created_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array(
), 'Creation Time')
->addColumn('updated_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array(
), 'Update Time')
->addIndex($this->getIdxName('easylife_news/article', array('entity_type_id')),
array('entity_type_id'))
->addIndex($this->getIdxName('easylife_news/article', array('attribute_set_id')),
array('attribute_set_id'))
->addForeignKey(
$this->getFkName(
'easylife_news/article',
'attribute_set_id',
'eav/attribute_set',
'attribute_set_id'
),
'attribute_set_id', $this->getTable('eav/attribute_set'), 'attribute_set_id',
Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
->addForeignKey($this->getFkName('easylife_news/article', 'entity_type_id', 'eav/entity_type', 'entity_type_id'),
'entity_type_id', $this->getTable('eav/entity_type'), 'entity_type_id',
Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
->setComment('Article Table');
$this->getConnection()->createTable($table);
//create the attribute values tables (int, decimal, varchar, text, datetime)
$articleEav = array();
$articleEav['int'] = array(
'type' => Varien_Db_Ddl_Table::TYPE_INTEGER,
'length' => null,
'comment' => 'Article Datetime Attribute Backend Table'
);
$articleEav['varchar'] = array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
'length' => 255,
'comment' => 'Article Varchar Attribute Backend Table'
);
$articleEav['text'] = array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
'length' => '64k',
'comment' => 'Article Text Attribute Backend Table'
);
$articleEav['datetime'] = array(
'type' => Varien_Db_Ddl_Table::TYPE_DATETIME,
'length' => null,
'comment' => 'Article Datetime Attribute Backend Table'
);
$articleEav['decimal'] = array(
'type' => Varien_Db_Ddl_Table::TYPE_DECIMAL,
'length' => '12,4',
'comment' => 'Article Datetime Attribute Backend Table'
);
foreach ($articleEav as $type => $options) {
$table = $this->getConnection()
->newTable($this->getTable(array('easylife_news/article', $type)))
->addColumn('value_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
'identity' => true,
'nullable' => false,
'primary' => true,
), 'Value ID')
->addColumn('entity_type_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
'unsigned' => true,
'nullable' => false,
'default' => '0',
), 'Entity Type ID')
->addColumn('attribute_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
'unsigned' => true,
'nullable' => false,
'default' => '0',
), 'Attribute ID')
->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
'unsigned' => true,
'nullable' => false,
'default' => '0',
), 'Store ID')
->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
'unsigned' => true,
'nullable' => false,
'default' => '0',
), 'Entity ID')
->addColumn('value', $options['type'], $options['length'], array(
), 'Value')
->addIndex(
$this->getIdxName(
array('easylife_news/article', $type),
array('entity_id', 'attribute_id', 'store_id'),
Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE
),
array('entity_id', 'attribute_id', 'store_id'),
array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE))
->addIndex($this->getIdxName(array('easylife_news/article', $type), array('store_id')),
array('store_id'))
->addIndex($this->getIdxName(array('easylife_news/article', $type), array('entity_id')),
array('entity_id'))
->addIndex($this->getIdxName(array('easylife_news/article', $type), array('attribute_id')),
array('attribute_id'))
->addForeignKey(
$this->getFkName(
array('easylife_news/article', $type),
'attribute_id',
'eav/attribute',
'attribute_id'
),
'attribute_id', $this->getTable('eav/attribute'), 'attribute_id',
Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
->addForeignKey(
$this->getFkName(
array('easylife_news/article', $type),
'entity_id',
'easylife_news/article',
'entity_id'
),
'entity_id', $this->getTable('easylife_news/article'), 'entity_id',
Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
->addForeignKey($this->getFkName(array('easylife_news/article', $type), 'store_id', 'core/store', 'store_id'),
'store_id', $this->getTable('core/store'), 'store_id',
Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
->setComment($options['comment']);
$this->getConnection()->createTable($table);
}
//crete the news_eav_attribute (for additional attribute settings)
$table = $this->getConnection()
->newTable($this->getTable('easylife_news/eav_attribute'))
->addColumn('attribute_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
'identity' => true,
'nullable' => false,
'primary' => true,
), 'Attribute ID')
->addColumn('is_global', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'Attribute scope')
->addColumn('position', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'Attribute position')
->addColumn('is_wysiwyg_enabled', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'Attribute uses WYSIWYG')
->addColumn('is_visible', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'Attribute is visible')
->setComment('News attribute table');
$this->getConnection()->createTable($table);
$this->installEntities();
$this->endSetup();
Models
app/code/local/Easylife/News/Model/Observer.php
- add the new menu item on the top menu:
<?php
class Easylife_News_Model_Observer {
public function addItemsToTopmenuItems($observer) {
$menu = $observer->getMenu();
$tree = $menu->getTree();
$action = Mage::app()->getFrontController()->getAction()->getFullActionName();
$articleNodeId = 'article';
$data = array(
'name' => Mage::helper('easylife_news')->__('Articles'),
'id' => $articleNodeId,
'url' => Mage::helper('easylife_news/article')->getArticlesUrl(),
'is_active' => ($action == 'easylife_news_article_index' || $action == 'easylife_news_article_view')
);
$articleNode = new Varien_Data_Tree_Node($data, 'id', $tree, $menu);
$menu->addChild($articleNode);
return $this;
}
}
app/code/local/Easylife/News/Model/Article.php
- the article main model
<?php
class Easylife_News_Model_Article
extends Mage_Catalog_Model_Abstract {
const ENTITY = 'easylife_news_article';
const CACHE_TAG = 'easylife_news_article';
protected $_eventPrefix = 'easylife_news_article';
protected $_eventObject = 'article';
public function _construct(){
parent::_construct();
$this->_init('easylife_news/article');
}
protected function _beforeSave(){
parent::_beforeSave();
$now = Mage::getSingleton('core/date')->gmtDate();
if ($this->isObjectNew()){
$this->setCreatedAt($now);
}
$this->setUpdatedAt($now);
return $this;
}
public function getArticleUrl(){
if ($this->getUrlKey()){
$urlKey = '';
if ($prefix = Mage::getStoreConfig('easylife_news/article/url_prefix')){
$urlKey .= $prefix.'/';
}
$urlKey .= $this->getUrlKey();
if ($suffix = Mage::getStoreConfig('easylife_news/article/url_suffix')){
$urlKey .= '.'.$suffix;
}
return Mage::getUrl('', array('_direct'=>$urlKey));
}
return Mage::getUrl('easylife_news/article/view', array('id'=>$this->getId()));
}
public function checkUrlKey($urlKey, $active = true){
return $this->_getResource()->checkUrlKey($urlKey, $active);
}
public function getDescription(){ //this needs to be implemented for all WYSIWYG attributes
$description = $this->getData('description');
$helper = Mage::helper('cms');
$processor = $helper->getBlockTemplateProcessor();
$html = $processor->filter($description);
return $html;
}
public function getDefaultAttributeSetId() {
return $this->getResource()->getEntityType()->getDefaultAttributeSetId();
}
public function getAttributeText($attributeCode) {
$text = $this->getResource()
->getAttribute($attributeCode)
->getSource()
->getOptionText($this->getData($attributeCode));
if (is_array($text)){
return implode(', ',$text);
}
return $text;
}
public function getDefaultValues() {
$values = array();
$values['status'] = 1;
$values['in_rss'] = 1;
return $values;
}
}
app/code/local/Easylife/News/Model/Resource/Article.php
- the resource model for the article
<?php
class Easylife_News_Model_Resource_Article
extends Mage_Catalog_Model_Resource_Abstract {
public function __construct() {
$resource = Mage::getSingleton('core/resource');
$this->setType('easylife_news_article')
->setConnection(
$resource->getConnection('article_read'),
$resource->getConnection('article_write')
);
}
public function getMainTable() {
return $this->getEntityTable();
}
public function checkUrlKey($urlKey, $storeId, $active = true){
$stores = array(Mage_Core_Model_App::ADMIN_STORE_ID, $storeId);
$select = $this->_initCheckUrlKeySelect($urlKey, $stores);
if (!$select){
return false;
}
$select->reset(Zend_Db_Select::COLUMNS)
->columns('e.entity_id')
->limit(1);
return $this->_getReadAdapter()->fetchOne($select);
}
protected function _initCheckUrlKeySelect($urlKey, $store){
$urlRewrite = Mage::getModel('eav/config')->getAttribute('easylife_news_article', 'url_key');
if (!$urlRewrite || !$urlRewrite->getId()){
return false;
}
$table = $urlRewrite->getBackend()->getTable();
$select = $this->_getReadAdapter()->select()
->from(array('e' => $table))
->where('e.attribute_id = ?', $urlRewrite->getId())
->where('e.value = ?', $urlKey)
->where('e.store_id IN (?)', $store)
->order('e.store_id DESC');
return $select;
}
}
app/code/local/Easylife/News/Model/Resource/Article/Collection.php
- the collection model
<?php
class Easylife_News_Model_Resource_Article_Collection
extends Mage_Catalog_Model_Resource_Collection_Abstract {
protected function _construct(){
parent::_construct();
$this->_init('easylife_news/article');
}
protected function _toOptionArray($valueField='entity_id', $labelField='title', $additional=array()){
$this->addAttributeToSelect('title');
return parent::_toOptionArray($valueField, $labelField, $additional);
}
protected function _toOptionHash($valueField='entity_id', $labelField='title'){
$this->addAttributeToSelect('title');
return parent::_toOptionHash($valueField, $labelField);
}
public function getSelectCountSql(){
$countSelect = parent::getSelectCountSql();
$countSelect->reset(Zend_Db_Select::GROUP);
return $countSelect;
}
}
The code is too long to fit in one answer. The rest will follow....wait for it.
Part 2.
app/code/local/Easylife/News/Model/Attribute.php
- the model for the article attributes
<?php
class Easylife_News_Model_Attribute
extends Mage_Eav_Model_Entity_Attribute {
const SCOPE_STORE = 0;
const SCOPE_GLOBAL = 1;
const SCOPE_WEBSITE = 2;
const MODULE_NAME = 'Easylife_News';
const ENTITY = 'easylife_news_eav_attribute';
protected $_eventPrefix = 'easylife_news_entity_attribute';
protected $_eventObject = 'attribute';
static protected $_labels = null;
protected function _construct(){
$this->_init('easylife_news/attribute');
}
protected function _beforeSave(){
$this->setData('modulePrefix', self::MODULE_NAME);
if (isset($this->_origData['is_global'])) {
if (!isset($this->_data['is_global'])) {
$this->_data['is_global'] = self::SCOPE_GLOBAL;
}
}
if ($this->getFrontendInput() == 'textarea') {
if ($this->getIsWysiwygEnabled()) {
$this->setIsHtmlAllowedOnFront(1);
}
}
return parent::_beforeSave();
}
protected function _afterSave(){
Mage::getSingleton('eav/config')->clear();
return parent::_afterSave();
}
public function getIsGlobal(){
return $this->_getData('is_global');
}
public function isScopeGlobal(){
return $this->getIsGlobal() == self::SCOPE_GLOBAL;
}
public function isScopeWebsite(){
return $this->getIsGlobal() == self::SCOPE_WEBSITE;
}
public function isScopeStore(){
return !$this->isScopeGlobal() && !$this->isScopeWebsite();
}
public function getStoreId(){
$dataObject = $this->getDataObject();
if ($dataObject) {
return $dataObject->getStoreId();
}
return $this->getData('store_id');
}
public function getSourceModel(){
$model = $this->getData('source_model');
if (empty($model)) {
if ($this->getBackendType() == 'int' && $this->getFrontendInput() == 'select') {
return $this->_getDefaultSourceModel();
}
}
return $model;
}
public function getFrontendLabel(){
return $this->_getData('frontend_label');
}
protected function _getLabelForStore(){
return $this->getFrontendLabel();
}
public static function initLabels($storeId = null){
if (is_null(self::$_labels)) {
if (is_null($storeId)) {
$storeId = Mage::app()->getStore()->getId();
}
$attributeLabels = array();
$attributes = Mage::getResourceSingleton('catalog/product')->getAttributesByCode();
foreach ($attributes as $attribute) {
if (strlen($attribute->getData('frontend_label')) > 0) {
$attributeLabels[] = $attribute->getData('frontend_label');
}
}
self::$_labels = Mage::app()->getTranslator()->getResource()->getTranslationArrayByStrings($attributeLabels, $storeId);
}
}
public function _getDefaultSourceModel(){
return 'eav/entity_attribute_source_table';
}
}
app/code/local/Easylife/News/Model/Resource/Attribute.php
- the attribute resource model
<?php
class Easylife_News_Model_Resource_Attribute
extends Mage_Eav_Model_Resource_Entity_Attribute {
protected function _afterSave(Mage_Core_Model_Abstract $object){
$setup = Mage::getModel('eav/entity_setup', 'core_write');
$entityType = $object->getEntityTypeId();
$setId = $setup->getDefaultAttributeSetId($entityType);
$groupId = $setup->getDefaultAttributeGroupId($entityType);
$attributeId = $object->getId();
$sortOrder = $object->getPosition();
$setup->addAttributeToGroup($entityType, $setId, $groupId, $attributeId, $sortOrder);
return parent::_afterSave($object);
}
}
app/code/local/Easylife/News/Model/Resource/Eav/Attribute.php
- the attribute EAV resource model
<?php
class Easylife_News_Model_Resource_Eav_Attribute
extends Mage_Eav_Model_Entity_Attribute {
const MODULE_NAME = 'Easylife_News';
const ENTITY = 'easylife_news_eav_attribute';
protected $_eventPrefix = 'easylife_news_entity_attribute';
protected $_eventObject = 'attribute';
static protected $_labels = null;
protected function _construct() {
$this->_init('easylife_news/attribute');
}
public function isScopeStore() {
return $this->getIsGlobal() == Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE;
}
public function isScopeWebsite() {
return $this->getIsGlobal() == Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE;
}
public function isScopeGlobal() {
return (!$this->isScopeStore() && !$this->isScopeWebsite());
}
public function getBackendTypeByInput($type) {
switch ($type){
case 'file':
//intentional fallthrough
case 'image':
return 'varchar';
break;
default:
return parent::getBackendTypeByInput($type);
break;
}
}
protected function _beforeDelete(){
if (!$this->getIsUserDefined()){
throw new Mage_Core_Exception(Mage::helper('easylife_news')->__('This attribute is not deletable'));
}
return parent::_beforeDelete();
}
}
app/code/local/Easylife/News/Model/Resource/Article/Collection.php
- attribute collection model
<?php
class Easylife_News_Model_Resource_Article_Attribute_Collection
extends Mage_Eav_Model_Resource_Entity_Attribute_Collection {
protected function _initSelect() {
$this->getSelect()->from(array('main_table' => $this->getResource()->getMainTable()))
->where('main_table.entity_type_id=?', Mage::getModel('eav/entity')->setType('easylife_news_article')->getTypeId())
->join(
array('additional_table' => $this->getTable('easylife_news/eav_attribute')),
'additional_table.attribute_id=main_table.attribute_id'
);
return $this;
}
public function setEntityTypeFilter($typeId) {
return $this;
}
public function addVisibleFilter() {
return $this->addFieldToFilter('additional_table.is_visible', 1);
}
public function addEditableFilter() {
return $this->addFieldToFilter('additional_table.is_editable', 1);
}
}
app/code/local/Easylife/News/Model/Resource/Setup.php
- the setup resource model - used for adding the entities and attribtues:
<?php
class Easylife_News_Model_Resource_Setup
extends Mage_Catalog_Model_Resource_Setup {
public function getDefaultEntities(){
$entities = array();
$entities['easylife_news_article'] = array(
'entity_model' => 'easylife_news/article',
'attribute_model' => 'easylife_news/resource_eav_attribute',
'table' => 'easylife_news/article',
'additional_attribute_table' => 'easylife_news/eav_attribute',
'entity_attribute_collection' => 'easylife_news/article_attribute_collection',
'attributes' => array(
'title' => array(
'group' => 'General',
'type' => 'varchar',
'backend' => '',
'frontend' => '',
'label' => 'Title',
'input' => 'text',
'source' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'required' => '1',
'user_defined' => false,
'default' => '',
'unique' => false,
'position' => '10',
'note' => '',
'visible' => '1',
'wysiwyg_enabled'=> '0',
),
'short_description' => array(
'group' => 'General',
'type' => 'text',
'backend' => '',
'frontend' => '',
'label' => 'Short description',
'input' => 'textarea',
'source' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'required' => '1',
'user_defined' => true,
'default' => '',
'unique' => false,
'position' => '20',
'note' => '',
'visible' => '1',
'wysiwyg_enabled'=> '0',
),
'description' => array(
'group' => 'General',
'type' => 'text',
'backend' => '',
'frontend' => '',
'label' => 'Description',
'input' => 'textarea',
'source' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'required' => '1',
'user_defined' => true,
'default' => '',
'unique' => false,
'position' => '30',
'note' => '',
'visible' => '1',
'wysiwyg_enabled'=> '1',
),
'publish_date' => array(
'group' => 'General',
'type' => 'datetime',
'backend' => 'eav/entity_attribute_backend_datetime',
'frontend' => '',
'label' => 'Publish Date',
'input' => 'date',
'source' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
'required' => '1',
'user_defined' => true,
'default' => '',
'unique' => false,
'position' => '40',
'note' => '',
'visible' => '1',
'wysiwyg_enabled'=> '0',
),
'status' => array(
'group' => 'General',
'type' => 'int',
'backend' => '',
'frontend' => '',
'label' => 'Enabled',
'input' => 'select',
'source' => 'eav/entity_attribute_source_boolean',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'required' => '',
'user_defined' => false,
'default' => '',
'unique' => false,
'position' => '50',
'note' => '',
'visible' => '1',
'wysiwyg_enabled'=> '0',
),
'url_key' => array(
'group' => 'General',
'type' => 'varchar',
'backend' => 'easylife_news/article_attribute_backend_urlkey',
'frontend' => '',
'label' => 'URL key',
'input' => 'text',
'source' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'required' => '',
'user_defined' => false,
'default' => '',
'unique' => false,
'position' => '60',
'note' => '',
'visible' => '1',
'wysiwyg_enabled'=> '0',
),
'in_rss' => array(
'group' => 'General',
'type' => 'int',
'backend' => '',
'frontend' => '',
'label' => 'In RSS',
'input' => 'select',
'source' => 'eav/entity_attribute_source_boolean',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'required' => '',
'user_defined' => false,
'default' => '',
'unique' => false,
'position' => '70',
'note' => '',
'visible' => '1',
'wysiwyg_enabled'=> '0',
),
'meta_title' => array(
'group' => 'General',
'type' => 'varchar',
'backend' => '',
'frontend' => '',
'label' => 'Meta title',
'input' => 'text',
'source' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'required' => '',
'user_defined' => false,
'default' => '',
'unique' => false,
'position' => '80',
'note' => '',
'visible' => '1',
'wysiwyg_enabled'=> '0',
),
'meta_keywords' => array(
'group' => 'General',
'type' => 'text',
'backend' => '',
'frontend' => '',
'label' => 'Meta keywords',
'input' => 'textarea',
'source' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'required' => '',
'user_defined' => false,
'default' => '',
'unique' => false,
'position' => '90',
'note' => '',
'visible' => '1',
'wysiwyg_enabled'=> '0',
),
'meta_description' => array(
'group' => 'General',
'type' => 'text',
'backend' => '',
'frontend' => '',
'label' => 'Meta description',
'input' => 'textarea',
'source' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'required' => '',
'user_defined' => false,
'default' => '',
'unique' => false,
'position' => '100',
'note' => '',
'visible' => '1',
'wysiwyg_enabled'=> '0',
),
)
);
return $entities;
}
}
app/code/local/Easylife/News/Model/Article/Attribute/Backend/File.php
- backend for file attributes if you decide to add one
<?php
class Easylife_News_Model_Article_Attribute_Backend_File
extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract {
public function afterSave($object){
$value = $object->getData($this->getAttribute()->getName());
if (is_array($value) && !empty($value['delete'])) {
$object->setData($this->getAttribute()->getName(), '');
$this->getAttribute()->getEntity()
->saveAttribute($object, $this->getAttribute()->getName());
return;
}
$path = Mage::helper('easylife_news/article')->getFileBaseDir();
try {
$uploader = new Varien_File_Uploader($this->getAttribute()->getName());
//set allowed file extensions if you need
//$uploader->setAllowedExtensions(array('mp4', 'mov', 'f4v', 'flv', '3gp', '3g2', 'mp3', 'aac', 'm4a', 'swf'));
$uploader->setAllowRenameFiles(true);
$uploader->setFilesDispersion(true);
$result = $uploader->save($path);
$object->setData($this->getAttribute()->getName(), $result['file']);
$this->getAttribute()->getEntity()->saveAttribute($object, $this->getAttribute()->getName());
} catch (Exception $e) {
if ($e->getCode() != 666){
//throw $e;
}
return;
}
}
}
app/code/local/Easylife/News/Model/Article/Attribute/Backend/Image.php
- backend for image attributes if you decide to add one
<?php
class Easylife_News_Model_Article_Attribute_Backend_Image
extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract {
public function afterSave($object){
$value = $object->getData($this->getAttribute()->getName());
if (is_array($value) && !empty($value['delete'])) {
$object->setData($this->getAttribute()->getName(), '');
$this->getAttribute()->getEntity()
->saveAttribute($object, $this->getAttribute()->getName());
return;
}
$path = Mage::helper('easylife_news/article_image')->getImageBaseDir();
try {
$uploader = new Varien_File_Uploader($this->getAttribute()->getName());
$uploader->setAllowRenameFiles(true);
$uploader->setFilesDispersion(true);
$result = $uploader->save($path);
$object->setData($this->getAttribute()->getName(), $result['file']);
$this->getAttribute()->getEntity()->saveAttribute($object, $this->getAttribute()->getName());
} catch (Exception $e) {
if ($e->getCode() != 666){
//throw $e;
}
return;
}
}
}
app/code/local/Easylife/News/Model/Article/Attribute/Backend/Urlkey.php
- backend for url key attribute
<?php
class Easylife_News_Model_Article_Attribute_Backend_Urlkey
extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract {
public function beforeSave($object) {
$attributeName = $this->getAttribute()->getName();
$urlKey = $object->getData($attributeName);
if ($urlKey == '') {
$urlKey = $object->getTitle();
}
$urlKey = $this->formatUrlKey($urlKey);
$validKey = false;
while (!$validKey) {
$entityId = Mage::getResourceModel('easylife_news/article')->checkUrlKey($urlKey, $object->getStoreId(), false);
if ($entityId == $object->getId() || empty($entityId)) {
$validKey = true;
}
else {
$parts = explode('-', $urlKey);
$last = $parts[count($parts) - 1];
if (!is_numeric($last)){
$urlKey = $urlKey.'-1';
}
else {
$suffix = '-'.($last + 1);
unset($parts[count($parts) - 1]);
$urlKey = implode('-', $parts).$suffix;
}
}
}
$object->setData($attributeName, $urlKey);
return $this;
}
public function formatUrlKey($str) {
$urlKey = preg_replace('#[^0-9a-z]+#i', '-', Mage::helper('catalog/product_url')->format($str));
$urlKey = strtolower($urlKey);
$urlKey = trim($urlKey, '-');
return $urlKey;
}
}
app/code/local/Easylife/News/Model/Adminhtml/Search/Article.php
- model that handles the admin global search
<?php
class Easylife_News_Model_Adminhtml_Search_Article
extends Varien_Object {
public function load(){
$arr = array();
if (!$this->hasStart() || !$this->hasLimit() || !$this->hasQuery()) {
$this->setResults($arr);
return $this;
}
$collection = Mage::getResourceModel('easylife_news/article_collection')
->addAttributeToFilter('title', array('like' => $this->getQuery().'%'))
->setCurPage($this->getStart())
->setPageSize($this->getLimit())
->load();
foreach ($collection->getItems() as $article) {
$arr[] = array(
'id'=> 'article/1/'.$article->getId(),
'type' => Mage::helper('easylife_news')->__('Article'),
'name' => $article->getTitle(),
'description' => $article->getTitle(),
'url' => Mage::helper('adminhtml')->getUrl('*/news_article/edit', array('id'=>$article->getId())),
);
}
$this->setResults($arr);
return $this;
}
}
We're done with the models. Let's go on to blocks.
app/code/local/Easylife/News/Block/Rss.php
- the general rss block
<?php
class Easylife_News_Block_Rss
extends Mage_Core_Block_Template {
protected $_feeds = array();
public function addFeed($label, $url, $prepare = false) {
$link = ($prepare ? $this->getUrl($url) : $url);
$feed = new Varien_Object();
$feed->setLabel($label);
$feed->setUrl($link);
$this->_feeds[$link] = $feed;
return $this;
}
public function getFeeds() {
return $this->_feeds;
}
}
app/code/local/Easylife/News/Block/Adminhtml/Article.php
- the main article block
<?php
class Easylife_News_Block_Adminhtml_Article
extends Mage_Adminhtml_Block_Widget_Grid_Container {
public function __construct(){
$this->_controller = 'adminhtml_article';
$this->_blockGroup = 'easylife_news';
parent::__construct();
$this->_headerText = Mage::helper('easylife_news')->__('Article');
$this->_updateButton('add', 'label', Mage::helper('easylife_news')->__('Add Article'));
$this->setTemplate('easylife_news/grid.phtml');
}
}
app/code/local/Easylife/News/Block/Adminhtml/Article/Edit.php
- the admin edit form
<?php
class Easylife_News_Block_Adminhtml_Article_Edit
extends Mage_Adminhtml_Block_Widget_Form_Container {
public function __construct(){
parent::__construct();
$this->_blockGroup = 'easylife_news';
$this->_controller = 'adminhtml_article';
$this->_updateButton('save', 'label', Mage::helper('easylife_news')->__('Save Article'));
$this->_updateButton('delete', 'label', Mage::helper('easylife_news')->__('Delete Article'));
$this->_addButton('saveandcontinue', array(
'label' => Mage::helper('easylife_news')->__('Save And Continue Edit'),
'onclick' => 'saveAndContinueEdit()',
'class' => 'save',
), -100);
$this->_formScripts[] = "
function saveAndContinueEdit(){
editForm.submit($('edit_form').action+'back/edit/');
}
";
}
public function getHeaderText(){
if( Mage::registry('current_article') && Mage::registry('current_article')->getId() ) {
return Mage::helper('easylife_news')->__("Edit Article '%s'", $this->escapeHtml(Mage::registry('current_article')->getTitle()));
}
else {
return Mage::helper('easylife_news')->__('Add Article');
}
}
}
Looks like there will be a part 3.....
Part 3.
app/code/local/Easylife/News/Block/Adminhtml/Article/Grid.php
- the admin grid
<?php
class Easylife_News_Block_Adminhtml_Article_Grid
extends Mage_Adminhtml_Block_Widget_Grid {
public function __construct(){
parent::__construct();
$this->setId('articleGrid');
$this->setDefaultSort('entity_id');
$this->setDefaultDir('ASC');
$this->setSaveParametersInSession(true);
$this->setUseAjax(true);
}
protected function _prepareCollection(){
$collection = Mage::getModel('easylife_news/article')->getCollection()
->addAttributeToSelect('publish_date')
->addAttributeToSelect('status')
->addAttributeToSelect('url_key');
$adminStore = Mage_Core_Model_App::ADMIN_STORE_ID;
$store = $this->_getStore();
$collection->joinAttribute('title', 'easylife_news_article/title', 'entity_id', null, 'inner', $adminStore);
if ($store->getId()) {
$collection->joinAttribute('easylife_news_article_title', 'easylife_news_article/title', 'entity_id', null, 'inner', $store->getId());
}
$this->setCollection($collection);
return parent::_prepareCollection();
}
protected function _prepareColumns(){
$this->addColumn('entity_id', array(
'header' => Mage::helper('easylife_news')->__('Id'),
'index' => 'entity_id',
'type' => 'number'
));
$this->addColumn('title', array(
'header' => Mage::helper('easylife_news')->__('Title'),
'align' => 'left',
'index' => 'title',
));
if ($this->_getStore()->getId()){
$this->addColumn('easylife_news_article_title', array(
'header' => Mage::helper('easylife_news')->__('Title in %s', $this->_getStore()->getName()),
'align' => 'left',
'index' => 'easylife_news_article_title',
));
}
$this->addColumn('status', array(
'header' => Mage::helper('easylife_news')->__('Status'),
'index' => 'status',
'type' => 'options',
'options' => array(
'1' => Mage::helper('easylife_news')->__('Enabled'),
'0' => Mage::helper('easylife_news')->__('Disabled'),
)
));
$this->addColumn('publish_date', array(
'header'=> Mage::helper('easylife_news')->__('Publish Date'),
'index' => 'publish_date',
'type'=> 'date',
));
$this->addColumn('url_key', array(
'header' => Mage::helper('easylife_news')->__('URL key'),
'index' => 'url_key',
));
$this->addColumn('created_at', array(
'header' => Mage::helper('easylife_news')->__('Created at'),
'index' => 'created_at',
'width' => '120px',
'type' => 'datetime',
));
$this->addColumn('updated_at', array(
'header' => Mage::helper('easylife_news')->__('Updated at'),
'index' => 'updated_at',
'width' => '120px',
'type' => 'datetime',
));
$this->addColumn('action',
array(
'header'=> Mage::helper('easylife_news')->__('Action'),
'width' => '100',
'type' => 'action',
'getter'=> 'getId',
'actions' => array(
array(
'caption' => Mage::helper('easylife_news')->__('Edit'),
'url' => array('base'=> '*/*/edit'),
'field' => 'id'
)
),
'filter'=> false,
'is_system' => true,
'sortable' => false,
));
$this->addExportType('*/*/exportCsv', Mage::helper('easylife_news')->__('CSV'));
$this->addExportType('*/*/exportExcel', Mage::helper('easylife_news')->__('Excel'));
$this->addExportType('*/*/exportXml', Mage::helper('easylife_news')->__('XML'));
return parent::_prepareColumns();
}
protected function _getStore(){
$storeId = (int) $this->getRequest()->getParam('store', 0);
return Mage::app()->getStore($storeId);
}
protected function _prepareMassaction(){
$this->setMassactionIdField('entity_id');
$this->getMassactionBlock()->setFormFieldName('article');
$this->getMassactionBlock()->addItem('delete', array(
'label'=> Mage::helper('easylife_news')->__('Delete'),
'url' => $this->getUrl('*/*/massDelete'),
'confirm' => Mage::helper('easylife_news')->__('Are you sure?')
));
$this->getMassactionBlock()->addItem('status', array(
'label'=> Mage::helper('easylife_news')->__('Change status'),
'url' => $this->getUrl('*/*/massStatus', array('_current'=>true)),
'additional' => array(
'status' => array(
'name' => 'status',
'type' => 'select',
'class' => 'required-entry',
'label' => Mage::helper('easylife_news')->__('Status'),
'values' => array(
'1' => Mage::helper('easylife_news')->__('Enabled'),
'0' => Mage::helper('easylife_news')->__('Disabled'),
)
)
)
));
return $this;
}
public function getRowUrl($row){
return $this->getUrl('*/*/edit', array('id' => $row->getId()));
}
public function getGridUrl(){
return $this->getUrl('*/*/grid', array('_current'=>true));
}
}
app/code/local/Easylife/News/Block/Adminhtml/Article/Edit/Tabs.php
- the tabs in the add/edit form
<?php
class Easylife_News_Block_Adminhtml_Article_Edit_Tabs
extends Mage_Adminhtml_Block_Widget_Tabs {
public function __construct() {
parent::__construct();
$this->setId('article_info_tabs');
$this->setDestElementId('edit_form');
$this->setTitle(Mage::helper('easylife_news')->__('Article Information'));
}
protected function _prepareLayout(){
$article = $this->getArticle();
$entity = Mage::getModel('eav/entity_type')->load('easylife_news_article', 'entity_type_code');
$attributes = Mage::getResourceModel('eav/entity_attribute_collection')
->setEntityTypeFilter($entity->getEntityTypeId());
$attributes->addFieldToFilter('attribute_code', array('nin'=>array('meta_title', 'meta_description', 'meta_keywords')));
$attributes->getSelect()->order('additional_table.position', 'ASC');
$this->addTab('info', array(
'label' => Mage::helper('easylife_news')->__('Article Information'),
'content' => $this->getLayout()->createBlock('easylife_news/adminhtml_article_edit_tab_attributes')
->setAttributes($attributes)
->toHtml(),
));
$seoAttributes = Mage::getResourceModel('eav/entity_attribute_collection')
->setEntityTypeFilter($entity->getEntityTypeId())
->addFieldToFilter('attribute_code', array('in'=>array('meta_title', 'meta_description', 'meta_keywords')));
$seoAttributes->getSelect()->order('additional_table.position', 'ASC');
$this->addTab('meta', array(
'label' => Mage::helper('easylife_news')->__('Meta'),
'title' => Mage::helper('easylife_news')->__('Meta'),
'content' => $this->getLayout()->createBlock('easylife_news/adminhtml_article_edit_tab_attributes')
->setAttributes($seoAttributes)
->toHtml(),
));
return parent::_beforeToHtml();
}
public function getArticle(){
return Mage::registry('current_article');
}
}
app/code/local/Easylife/News/Block/Adminhtml/Article/Edit/Form.php
- the form container
<?php
class Easylife_News_Block_Adminhtml_Article_Edit_Form
extends Mage_Adminhtml_Block_Widget_Form {
protected function _prepareForm() {
$form = new Varien_Data_Form(array(
'id' => 'edit_form',
'action' => $this->getUrl('*/*/save', array('id' => $this->getRequest()->getParam('id'), 'store' => $this->getRequest()->getParam('store'))),
'method' => 'post',
'enctype' => 'multipart/form-data'
)
);
$form->setUseContainer(true);
$this->setForm($form);
return parent::_prepareForm();
}
}
app/code/local/Easylife/News/Block/Adminhtml/Article/Edit/Tab/Attribtues.php
- the attributes contained in a tab.
<?php
class Easylife_News_Block_Adminhtml_Article_Edit_Tab_Attributes
extends Mage_Adminhtml_Block_Widget_Form {
protected function _prepareForm() {
$form = new Varien_Data_Form();
$form->setDataObject(Mage::registry('current_article'));
$fieldset = $form->addFieldset('info',
array(
'legend'=>Mage::helper('easylife_news')->__('Article Information'),
'class'=>'fieldset-wide',
)
);
$attributes = $this->getAttributes();
foreach ($attributes as $attribute){
$attribute->setEntity(Mage::getResourceModel('easylife_news/article'));
}
$this->_setFieldset($attributes, $fieldset, array());
$formValues = Mage::registry('current_article')->getData();
$form->addValues($formValues);
$form->setFieldNameSuffix('article');
$this->setForm($form);
}
protected function _prepareLayout() {
Varien_Data_Form::setElementRenderer(
$this->getLayout()->createBlock('adminhtml/widget_form_renderer_element')
);
Varien_Data_Form::setFieldsetRenderer(
$this->getLayout()->createBlock('adminhtml/widget_form_renderer_fieldset')
);
Varien_Data_Form::setFieldsetElementRenderer(
$this->getLayout()->createBlock('easylife_news/adminhtml_news_renderer_fieldset_element')
);
}
protected function _getAdditionalElementTypes(){
return array(
'file' => Mage::getConfig()->getBlockClassName('easylife_news/adminhtml_article_helper_file'),
'image' => Mage::getConfig()->getBlockClassName('easylife_news/adminhtml_article_helper_image'),
'textarea' => Mage::getConfig()->getBlockClassName('adminhtml/catalog_helper_form_wysiwyg')
);
}
public function getArticle() {
return Mage::registry('current_article');
}
}
app/code/local/Easylfe/News/Block/Adminhtml/Article/Helper/File.php
- block helper for rendering file elements.
<?php
class Easylife_News_Block_Adminhtml_Article_Helper_File
extends Varien_Data_Form_Element_Abstract {
public function __construct($data){
parent::__construct($data);
$this->setType('file');
}
public function getElementHtml(){
$html = '';
$this->addClass('input-file');
$html.= parent::getElementHtml();
if ($this->getValue()) {
$url = $this->_getUrl();
if( !preg_match("/^http\:\/\/|https\:\/\//", $url) ) {
$url = Mage::helper('easylife_news/article')->getFileBaseUrl() . $url;
}
$html .= '<br /><a href="'.$url.'">'.$this->_getUrl().'</a> ';
}
$html.= $this->_getDeleteCheckbox();
return $html;
}
protected function _getDeleteCheckbox(){
$html = '';
if ($this->getValue()) {
$label = Mage::helper('easylife_news')->__('Delete File');
$html .= '<span class="delete-image">';
$html .= '<input type="checkbox" name="'.parent::getName().'[delete]" value="1" class="checkbox" id="'.$this->getHtmlId().'_delete"'.($this->getDisabled() ? ' disabled="disabled"': '').'/>';
$html .= '<label for="'.$this->getHtmlId().'_delete"'.($this->getDisabled() ? ' class="disabled"' : '').'> '.$label.'</label>';
$html .= $this->_getHiddenInput();
$html .= '</span>';
}
return $html;
}
protected function _getHiddenInput(){
return '<input type="hidden" name="'.parent::getName().'[value]" value="'.$this->getValue().'" />';
}
protected function _getUrl(){
return $this->getValue();
}
public function getName(){
return $this->getData('name');
}
}
app/code/local/Easylfe/News/Block/Adminhtml/Article/Helper/Image.php
- block helper for rendering image elements.
<?php
class Easylife_News_Block_Adminhtml_Article_Helper_Image
extends Varien_Data_Form_Element_Image {
protected function _getUrl(){
$url = false;
if ($this->getValue()) {
$url = Mage::helper('easylife_news/article_image')->getImageBaseUrl().$this->getValue();
}
return $url;
}
}
app/code/local/Easylife/News/Block/Adminhtml/Attribute.php
- main block for managing attributes
<?php
class Easylife_News_Block_Adminhtml_Article_Attribute
extends Mage_Adminhtml_Block_Widget_Grid_Container {
public function __construct(){
$this->_controller = 'adminhtml_article_attribute';
$this->_blockGroup = 'easylife_news';
$this->_headerText = Mage::helper('easylife_news')->__('Manage Article Attributes');
parent::__construct();
$this->_updateButton('add', 'label', Mage::helper('easylife_news')->__('Add New Article Attribute'));
}
}
app/code/local/Easylife/News/Block/Adminhtml/Attribute/Grid.php
- the attribute grid block
<?php
class Easylife_News_Block_Adminhtml_Article_Attribute_Grid
extends Mage_Eav_Block_Adminhtml_Attribute_Grid_Abstract {
protected function _prepareCollection(){
$collection = Mage::getResourceModel('easylife_news/article_attribute_collection')
->addVisibleFilter();
$this->setCollection($collection);
return parent::_prepareCollection();
}
protected function _prepareColumns() {
parent::_prepareColumns();
$this->addColumnAfter('is_global', array(
'header'=>Mage::helper('easylife_news')->__('Scope'),
'sortable'=>true,
'index'=>'is_global',
'type' => 'options',
'options' => array(
Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE =>Mage::helper('easylife_news')->__('Store View'),
Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE =>Mage::helper('easylife_news')->__('Website'),
Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL =>Mage::helper('easylife_news')->__('Global'),
),
'align' => 'center',
), 'is_user_defined');
return $this;
}
}
app/code/local/Easylife/News/Block/Adminhtml/Attribute/Edit.php
- the attribute edit form.
<?php
class Easylife_News_Block_Adminhtml_Article_Attribute_Edit
extends Mage_Adminhtml_Block_Widget_Form_Container {
public function __construct() {
$this->_objectId = 'attribute_id';
$this->_controller = 'adminhtml_article_attribute';
$this->_blockGroup = 'easylife_news';
parent::__construct();
$this->_addButton(
'save_and_edit_button',
array(
'label' => Mage::helper('easylife_news')->__('Save and Continue Edit'),
'onclick' => 'saveAndContinueEdit()',
'class' => 'save'
),
100
);
$this->_updateButton('save', 'label', Mage::helper('easylife_news')->__('Save Article Attribute'));
$this->_updateButton('save', 'onclick', 'saveAttribute()');
if (!Mage::registry('entity_attribute')->getIsUserDefined()) {
$this->_removeButton('delete');
} else {
$this->_updateButton('delete', 'label', Mage::helper('easylife_news')->__('Delete Article Attribute'));
}
}
public function getHeaderText(){
if (Mage::registry('entity_attribute')->getId()) {
$frontendLabel = Mage::registry('entity_attribute')->getFrontendLabel();
if (is_array($frontendLabel)) {
$frontendLabel = $frontendLabel[0];
}
return Mage::helper('easylife_news')->__('Edit Article Attribute "%s"', $this->htmlEscape($frontendLabel));
}
else {
return Mage::helper('easylife_news')->__('New Article Attribute');
}
}
public function getValidationUrl(){
return $this->getUrl('*/*/validate', array('_current'=>true));
}
public function getSaveUrl(){
return $this->getUrl('*/'.$this->_controller.'/save', array('_current'=>true, 'back'=>null));
}
}
app/code/local/Easylife/News/Block/Adminhtml/Attribute/Edit/Tabs.php
- the attribute edit tabs
<?php
class Easylife_News_Block_Adminhtml_Article_Attribute_Edit_Tabs
extends Mage_Adminhtml_Block_Widget_Tabs {
public function __construct() {
parent::__construct();
$this->setId('article_attribute_tabs');
$this->setDestElementId('edit_form');
$this->setTitle(Mage::helper('easylife_news')->__('Attribute Information'));
}
protected function _beforeToHtml() {
$this->addTab('main', array(
'label' => Mage::helper('easylife_news')->__('Properties'),
'title' => Mage::helper('easylife_news')->__('Properties'),
'content' => $this->getLayout()->createBlock('easylife_news/adminhtml_article_attribute_edit_tab_main')->toHtml(),
'active' => true
));
$this->addTab('labels', array(
'label' => Mage::helper('easylife_news')->__('Manage Label / Options'),
'title' => Mage::helper('easylife_news')->__('Manage Label / Options'),
'content' => $this->getLayout()->createBlock('easylife_news/adminhtml_article_attribute_edit_tab_options')->toHtml(),
));
return parent::_beforeToHtml();
}
}
app/code/local/Easylife/News/Block/Adminhtml/Attribute/Edit/Form.php
- the attribute edit form container
<?php
class Easylife_News_Block_Adminhtml_Article_Attribute_Edit_Form
extends Mage_Adminhtml_Block_Widget_Form {
protected function _prepareForm() {
$form = new Varien_Data_Form(array('id' => 'edit_form', 'action' => $this->getUrl('adminhtml/news_article_attribute/save'), 'method' => 'post'));
$form->setUseContainer(true);
$this->setForm($form);
return parent::_prepareForm();
}
}
app/code/local/Easylife/News/Block/Adminhtml/Attribute/Edit/Tab/Main.php
- the attribute edit main tab:
<?php
class Easylife_News_Block_Adminhtml_Article_Attribute_Edit_Tab_Main
extends Mage_Eav_Block_Adminhtml_Attribute_Edit_Main_Abstract {
protected function _prepareForm(){
parent::_prepareForm();
$attributeObject = $this->getAttributeObject();
$form = $this->getForm();
$fieldset = $form->getElement('base_fieldset');
$frontendInputElm = $form->getElement('frontend_input');
$additionalTypes = array(
array(
'value' => 'image',
'label' => Mage::helper('easylife_news')->__('Image')
),
array(
'value' => 'file',
'label' => Mage::helper('easylife_news')->__('File')
)
);
$response = new Varien_Object();
$response->setTypes(array());
Mage::dispatchEvent('adminhtml_article_attribute_types', array('response'=>$response));
$_disabledTypes = array();
$_hiddenFields = array();
foreach ($response->getTypes() as $type) {
$additionalTypes[] = $type;
if (isset($type['hide_fields'])) {
$_hiddenFields[$type['value']] = $type['hide_fields'];
}
if (isset($type['disabled_types'])) {
$_disabledTypes[$type['value']] = $type['disabled_types'];
}
}
Mage::register('attribute_type_hidden_fields', $_hiddenFields);
Mage::register('attribute_type_disabled_types', $_disabledTypes);
$frontendInputValues = array_merge($frontendInputElm->getValues(), $additionalTypes);
$frontendInputElm->setValues($frontendInputValues);
$yesnoSource = Mage::getModel('adminhtml/system_config_source_yesno')->toOptionArray();
$scopes = array(
Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE =>Mage::helper('easylife_news')->__('Store View'),
Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE =>Mage::helper('easylife_news')->__('Website'),
Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL =>Mage::helper('easylife_news')->__('Global'),
);
$fieldset->addField('is_global', 'select', array(
'name' => 'is_global',
'label' => Mage::helper('easylife_news')->__('Scope'),
'title' => Mage::helper('easylife_news')->__('Scope'),
'note' => Mage::helper('easylife_news')->__('Declare attribute value saving scope'),
'values'=> $scopes
), 'attribute_code');
$fieldset->addField('position', 'text', array(
'name' => 'position',
'label' => Mage::helper('easylife_news')->__('Position'),
'title' => Mage::helper('easylife_news')->__('Position'),
'note' => Mage::helper('easylife_news')->__('Position in the admin form'),
), 'is_global');
$fieldset->addField('note', 'textarea', array(
'name' => 'note',
'label' => Mage::helper('easylife_news')->__('Note'),
'title' => Mage::helper('easylife_news')->__('Note'),
'note' => Mage::helper('easylife_news')->__('Text to appear below the input.'),
), 'position');
$fieldset->removeField('default_value_text');
$fieldset->removeField('default_value_yesno');
$fieldset->removeField('default_value_date');
$fieldset->removeField('default_value_textarea');
$fieldset->removeField('is_unique');
// frontend properties fieldset
$fieldset = $form->addFieldset('front_fieldset', array('legend'=>Mage::helper('easylife_news')->__('Frontend Properties')));
$fieldset->addField('is_wysiwyg_enabled', 'select', array(
'name' => 'is_wysiwyg_enabled',
'label' => Mage::helper('easylife_news')->__('Enable WYSIWYG'),
'title' => Mage::helper('easylife_news')->__('Enable WYSIWYG'),
'values' => $yesnoSource,
));
Mage::dispatchEvent('easylife_news_adminhtml_article_attribute_edit_prepare_form', array(
'form' => $form,
'attribute' => $attributeObject
));
return $this;
}
}
app/code/local/Easylife/News/Block/Adminhtml/Attribute/Edit/Tab/Options.php
- tab for rendering attribute options
<?php
class Easylife_News_Block_Adminhtml_Article_Attribute_Edit_Tab_Options
extends Mage_Eav_Block_Adminhtml_Attribute_Edit_Options_Abstract {
}
app/code/local/Easylife/News/Block/Adminhtml/News/Helper/Form/Wysiwyg/Content.php
- helper block for WYSIWYG elements
<?php
class Easylife_News_Block_Adminhtml_News_Helper_Form_Wysiwyg_Content
extends Mage_Adminhtml_Block_Widget_Form {
protected function _prepareForm(){
$form = new Varien_Data_Form(array('id' => 'wysiwyg_edit_form', 'action' => $this->getData('action'), 'method' => 'post'));
$config['document_base_url'] = $this->getData('store_media_url');
$config['store_id'] = $this->getData('store_id');
$config['add_variables'] = false;
$config['add_widgets'] = false;
$config['add_directives'] = true;
$config['use_container'] = true;
$config['container_class'] = 'hor-scroll';
$editorConfig = Mage::getSingleton('cms/wysiwyg_config')->getConfig($config);
$editorConfig->setData('files_browser_window_url', Mage::getSingleton('adminhtml/url')->getUrl('adminhtml/cms_wysiwyg_images/index'));
$form->addField($this->getData('editor_element_id'), 'editor', array(
'name' => 'content',
'style' => 'width:725px;height:460px',
'required' => true,
'force_load' => true,
'config' => $editorConfig
));
$this->setForm($form);
return parent::_prepareForm();
}
}
now look for part 4.