创建 EAV 模型: based model(s) in Magento

http://inchoo.net/magento/creating-an-eav-based-models-in-magento/

Imagine your module is called Phonebook and put into the /Inchoo namespace under the local code pool. Logically you would need a model class like User which represents single entry into the phonebook. With this in mind you already need a structure like:

  • app/etc/modules/Inchoo_Phonebook.xml
  • app/code/local/Inchoo/Phonebook/etc/config.xml
  • app/code/local/Inchoo/Phonebook/Model/User.php
  • app/code/local/Inchoo/Phonebook/Model/Resource/User.php
  • app/code/local/Inchoo/Phonebook/Model/Resource/User/Collection.php
  • app/code/local/Inchoo/Phonebook/Model/Resource/Setup.php
  • app/code/local/Inchoo/Phonebook/sql/inchoo_phonebook_setup/install-1.0.0.0.php

Now that we outlined the file structure, let’s get down to it and see what the content of files should look like in order for it to work.


app/etc/modules/Inchoo_Phonebook.xml


<?xml version="1.0"?>
 
<config>
<modules>
<Inchoo_Phonebook>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Core />
<Mage_Eav />
</depends>
</Inchoo_Phonebook>
</modules>
</config>

app/code/local/Inchoo/Phonebook/etc/config.xml

<?xml version="1.0" encoding="UTF-8"?>
 
<config>
<modules>
<Inchoo_Phonebook>
<version>1.0.0.0</version>
</Inchoo_Phonebook>
</modules>
<global>
<models>
<inchoo_phonebook>
<class>Inchoo_Phonebook_Model</class>
<resourceModel>inchoo_phonebook_resource</resourceModel>
</inchoo_phonebook>
<inchoo_phonebook_resource>
<class>Inchoo_Phonebook_Model_Resource</class>
<entities>
<user>
<table>inchoo_phonebook_user_entity</table>
</user>
<user_entity_varchar>
<table>inchoo_phonebook_user_entity_varchar</table>
</user_entity_varchar>
<user_entity_text>
<table>inchoo_phonebook_user_entity_text</table>
</user_entity_text>
<user_entity_int>
<table>inchoo_phonebook_user_entity_int</table>
</user_entity_int>
</entities>
</inchoo_phonebook_resource>
</models>
<resources>
<inchoo_phonebook_setup>
<setup>
<module>Inchoo_Phonebook</module>
<class>Inchoo_Phonebook_Model_Resource_Setup</class>
</setup>
</inchoo_phonebook_setup>
<inchoo_phonebook_write>
<connection>
<use>default_write</use>
</connection>
</inchoo_phonebook_write>
<inchoo_phonebook_read>
<connection>
<use>default_read</use>
</connection>
</inchoo_phonebook_read>
</resources>
</global>
</config>

app/code/local/Inchoo/Phonebook/Model/User.php

<?php
 
class Inchoo_Phonebook_Model_User extends Mage_Core_Model_Abstract
{
/**
* Maps to the array key from Setup.php::getDefaultEntities()
*/
const ENTITY = 'inchoo_phonebook_user';
protected $_eventPrefix = 'inchoo_phonebook';
protected $_eventObject = 'user';
function _construct()
{
$this->_init('inchoo_phonebook/user');
}
}

app/code/local/Inchoo/Phonebook/Model/Resource/User.php

 
 
<?php
 
class Inchoo_Phonebook_Model_Resource_User extends Mage_Eav_Model_Entity_Abstract
{
public function __construct ()
{
$resource = Mage :: getSingleton ( 'core/resource' );
$this -> setType ( Inchoo_Phonebook_Model_User :: ENTITY );
 
$this -> setConnection (
$resource -> getConnection ( 'inchoo_phonebook_read' ),
$resource -> getConnection ( 'inchoo_phonebook_write' )
);
}
}


app/code/local/Inchoo/Phonebook/Model/Resource/User/Collection.php

 
 
<?php
 
class Inchoo_Phonebook_Model_Resource_User_Collection extends Mage_Eav_Model_Entity_Collection_Abstract
{
protected function _construct ()
{
$this -> _init ( 'inchoo_phonebook/user' );
}
protected function _initSelect ()
{
$this -> getSelect () -> from ( array ( 'e' => $this -> getEntity () -> getEntityTable ()));
 
if ( $this -> getEntity () -> getTypeId ()) {
/**
* We override the Mage_Eav_Model_Entity_Collection_Abstract->_initSelect()
* because we want to remove the call to addAttributeToFilter for 'entity_type_id'
* as it is causing invalid SQL select, thus making the User model load failing.
*/
//$this->addAttributeToFilter('entity_type_id', $this->getEntity()->getTypeId());
}
return $this ;
}
}

app/code/local/Inchoo/Phonebook/Model/Resource/Setup.php

 
 
<?php
 
class Inchoo_Phonebook_Model_Resource_Setup extends Mage_Eav_Model_Entity_Setup {
 
public function getDefaultEntities () {
return array (
Inchoo_Phonebook_Model_User :: ENTITY => array (
'entity_model' => 'inchoo_phonebook/user' ,
'table' => 'inchoo_phonebook/user' , /* Maps to the config.xml > global > models > inchoo_phonebook_resource > entities > user */
'attributes' => array (
'first_name' => array (
'type' => 'varchar' ,
'label' => 'First name' ,
'input' => 'text' ,
'required' => true ,
'sort_order' => 10 ,
'position' => 10 ,
'global' => Mage_Catalog_Model_Resource_Eav_Attribute :: SCOPE_GLOBAL ,
),
'last_name' => array (
'type' => 'varchar' ,
'label' => 'Last name' ,
'input' => 'text' ,
'required' => true ,
'sort_order' => 20 ,
'position' => 20 ,
'global' => Mage_Catalog_Model_Resource_Eav_Attribute :: SCOPE_GLOBAL ,
),
'email' => array (
'type' => 'varchar' ,
'label' => 'Email' ,
'input' => 'text' ,
'required' => true ,
'sort_order' => 30 ,
'position' => 30 ,
'global' => Mage_Catalog_Model_Resource_Eav_Attribute :: SCOPE_GLOBAL ,
),
'address' => array (
'type' => 'text' ,
'label' => 'Address' ,
'input' => 'multiline' ,
'sort_order' => 40 ,
'multiline_count' => 2 ,
'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}' ,
'position' => 40 ,
'required' => false ,
'global' => Mage_Catalog_Model_Resource_Eav_Attribute :: SCOPE_GLOBAL ,
),
'is_active' => array (
'type' => 'int' ,
'label' => 'Is Active' ,
'input' => 'text' ,
'required' => false ,
'sort_order' => 50 ,
'position' => 50 ,
'required' => false ,
'global' => Mage_Catalog_Model_Resource_Eav_Attribute :: SCOPE_GLOBAL ,
),
)
)
);
}
}

app/code/local/Inchoo/Phonebook/sql/inchoo_phonebook_setup/install-1.0.0.0.php


 
 
<?php
 
/* @var $installer Inchoo_Phonebook_Model_Resource_Setup */
$installer = $this ;
 
$installer -> startSetup ();
 
/* Create table 'inchoo_phonebook/user' */
$table = $installer -> getConnection ()
-> newTable ( $installer -> getTable ( 'inchoo_phonebook/user' ))
-> addColumn ( 'entity_id' , Varien_Db_Ddl_Table :: TYPE_INTEGER , null , array (
'identity' => true ,
'unsigned' => true ,
'nullable' => false ,
'primary' => true ,
), 'Entity 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' )
-> setComment ( 'Inchoo Phonebook User Table' );
$installer -> getConnection () -> createTable ( $table );
 
 
/* Create table 'inchoo_phonebook/user_entity_varchar' */
$table = $installer -> getConnection ()
-> newTable ( $installer -> getTable ( 'inchoo_phonebook/user_entity_varchar' ))
-> 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' , Varien_Db_Ddl_Table :: TYPE_TEXT , 255 , array (
), 'Value' )
-> addIndex (
$installer -> getIdxName (
'inchoo_phonebook_user_entity_varchar' ,
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 ( $installer -> getIdxName ( 'inchoo_phonebook_user_entity_varchar' , array ( 'attribute_id' )),
array ( 'attribute_id' ))
-> addIndex ( $installer -> getIdxName ( 'inchoo_phonebook_user_entity_varchar' , array ( 'store_id' )),
array ( 'store_id' ))
-> addIndex ( $installer -> getIdxName ( 'inchoo_phonebook_user_entity_varchar' , array ( 'entity_id' )),
array ( 'entity_id' ))
-> addForeignKey (
$installer -> getFkName ( 'inchoo_phonebook_user_entity_varchar' , 'attribute_id' , 'eav/attribute' , 'attribute_id' ),
'attribute_id' , $installer -> getTable ( 'eav/attribute' ), 'attribute_id' ,
Varien_Db_Ddl_Table :: ACTION_CASCADE , Varien_Db_Ddl_Table :: ACTION_CASCADE )
-> addForeignKey (
$installer -> getFkName ( 'inchoo_phonebook_user_entity_varchar' , 'entity_id' , 'inchoo_phonebook/user' , 'entity_id' ),
'entity_id' , $installer -> getTable ( 'inchoo_phonebook/user' ), 'entity_id' ,
Varien_Db_Ddl_Table :: ACTION_CASCADE , Varien_Db_Ddl_Table :: ACTION_CASCADE )
-> addForeignKey (
$installer -> getFkName ( 'inchoo_phonebook_user_entity_varchar' , 'store_id' , 'core/store' , 'store_id' ),
'store_id' , $installer -> getTable ( 'core/store' ), 'store_id' ,
Varien_Db_Ddl_Table :: ACTION_CASCADE , Varien_Db_Ddl_Table :: ACTION_CASCADE )
-> setComment ( 'Inchoo Phonebook User Entity Varchar' );
$installer -> getConnection () -> createTable ( $table );
 
 
/* Create table 'inchoo_phonebook/user_entity_int' */
$table = $installer -> getConnection ()
-> newTable ( $installer -> getTable ( 'inchoo_phonebook/user_entity_int' ))
-> 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' , Varien_Db_Ddl_Table :: TYPE_TEXT , 255 , array (
), 'Value' )
-> addIndex (
$installer -> getIdxName (
'inchoo_phonebook_user_entity_int' ,
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 ( $installer -> getIdxName ( 'inchoo_phonebook_user_entity_int' , array ( 'attribute_id' )),
array ( 'attribute_id' ))
-> addIndex ( $installer -> getIdxName ( 'inchoo_phonebook_user_entity_int' , array ( 'store_id' )),
array ( 'store_id' ))
-> addIndex ( $installer -> getIdxName ( 'inchoo_phonebook_user_entity_int' , array ( 'entity_id' )),
array ( 'entity_id' ))
-> addForeignKey (
$installer -> getFkName ( 'inchoo_phonebook_user_entity_int' , 'attribute_id' , 'eav/attribute' , 'attribute_id' ),
'attribute_id' , $installer -> getTable ( 'eav/attribute' ), 'attribute_id' ,
Varien_Db_Ddl_Table :: ACTION_CASCADE , Varien_Db_Ddl_Table :: ACTION_CASCADE )
-> addForeignKey (
$installer -> getFkName ( 'inchoo_phonebook_user_entity_int' , 'entity_id' , 'inchoo_phonebook/user' , 'entity_id' ),
'entity_id' , $installer -> getTable ( 'inchoo_phonebook/user' ), 'entity_id' ,
Varien_Db_Ddl_Table :: ACTION_CASCADE , Varien_Db_Ddl_Table :: ACTION_CASCADE )
-> addForeignKey (
$installer -> getFkName ( 'inchoo_phonebook_user_entity_int' , 'store_id' , 'core/store' , 'store_id' ),
'store_id' , $installer -> getTable ( 'core/store' ), 'store_id' ,
Varien_Db_Ddl_Table :: ACTION_CASCADE , Varien_Db_Ddl_Table :: ACTION_CASCADE )
-> setComment ( 'Inchoo Phonebook User Entity Int' );
$installer -> getConnection () -> createTable ( $table );
 
 
/* Create table 'inchoo_phonebook/user_entity_text' */
$table = $installer -> getConnection ()
-> newTable ( $installer -> getTable ( 'inchoo_phonebook/user_entity_text' ))
-> 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' , Varien_Db_Ddl_Table :: TYPE_TEXT , 255 , array (
), 'Value' )
-> addIndex (
$installer -> getIdxName (
'inchoo_phonebook_user_entity_text' ,
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 ( $installer -> getIdxName ( 'inchoo_phonebook_user_entity_text' , array ( 'attribute_id' )),
array ( 'attribute_id' ))
-> addIndex ( $installer -> getIdxName ( 'inchoo_phonebook_user_entity_text' , array ( 'store_id' )),
array ( 'store_id' ))
-> addIndex ( $installer -> getIdxName ( 'inchoo_phonebook_user_entity_text' , array ( 'entity_id' )),
array ( 'entity_id' ))
-> addForeignKey (
$installer -> getFkName ( 'inchoo_phonebook_user_entity_text' , 'attribute_id' , 'eav/attribute' , 'attribute_id' ),
'attribute_id' , $installer -> getTable ( 'eav/attribute' ), 'attribute_id' ,
Varien_Db_Ddl_Table :: ACTION_CASCADE , Varien_Db_Ddl_Table :: ACTION_CASCADE )
-> addForeignKey (
$installer -> getFkName ( 'inchoo_phonebook_user_entity_text' , 'entity_id' , 'inchoo_phonebook/user' , 'entity_id' ),
'entity_id' , $installer -> getTable ( 'inchoo_phonebook/user' ), 'entity_id' ,
Varien_Db_Ddl_Table :: ACTION_CASCADE , Varien_Db_Ddl_Table :: ACTION_CASCADE )
-> addForeignKey (
$installer -> getFkName ( 'inchoo_phonebook_user_entity_text' , 'store_id' , 'core/store' , 'store_id' ),
'store_id' , $installer -> getTable ( 'core/store' ), 'store_id' ,
Varien_Db_Ddl_Table :: ACTION_CASCADE , Varien_Db_Ddl_Table :: ACTION_CASCADE )
-> setComment ( 'Inchoo Phonebook User Entity Text' );
$installer -> getConnection () -> createTable ( $table );
 
 
$installer -> endSetup ();
 
 
$installer -> installEntities ();


For each attribute type like “varchar”, “text”, “int”… you need to create a corresponding table like inchoo_phonebook_user_entity_varchar, inchoo_phonebook_user_entity_text, inchoo_phonebook_user_entity_int. Study the install-1.0.0.0.php and the config.xml file to see how to get that one done.


 
 
<?php
 
$phonebookUser = Mage :: getModel ( 'inchoo_phonebook/user' );
 
$phonebookUser -> setFristname ( 'John' );
$phonebookUser -> setLastname ( 'Doe' );
$phonebookUser -> setEmail ( 'john.doe@magento.com' );
$phonebookUser -> setAddress ( 'Sample address line here' );
$phonebookUser -> setIsActive ( true );
 
$phonebookUser -> save ();
 
Zend_Debug :: dump ( $phonebookUser -> debug (), '$phonebookUser' );
 
$users = Mage :: getModel ( 'inchoo_phonebook/user' ) -> getCollection ();
 
foreach ( $users as $user ) {
Zend_Debug :: dump ( $user -> debug (), '$user' );
}

就是这样。虽然简单,有一些打字工作要做为基础的模型得到的EAV功能。希望它可以帮助别人。



Finally, you can test your model and it’s collection by running the following somewhere in your code:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值