magento multiselect插入数据库

时间:2011-10-04 12:32:05

标签: magento

我想在magento的管理员部分创建一个多选属性下拉列表,以便我可以将序列化方式的属性值插入到数据库中。

请注意,我要插入值的表是自定义的,即我在数据库中由自己的表创建。 我看过多店的代码如下:

      if (!Mage::app()->isSingleStoreMode()) {
        $fieldset->addField('store_id', 'multiselect', array(
            'name'      => 'stores[]',
            'label'     => Mage::helper('cms')->__('Store View'),
            'title'     => Mage::helper('cms')->__('Store View'),
            'required'  => true,
            'values'    => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(false, true),
        ));
   }

但我无法使用这种格式,因为我的数据库表是自定义的。 请让我知道替代代码,通过该代码我可以将多选属性的值插入数据库。 感谢

3 个答案:

答案 0 :(得分:6)

由于Magento有自己的方式将商店ID存储在数据库中,我建议遵循这些标准。使用序列化值不是一个好主意......

YM =您的模块 YM_store是我们稍后将创建的新表。 YM_entity_id是您要在此处使用的任何实体的ID。 (例如,在Core / cms / block中,“YM_entity_id”是“block_id”。)

请确保在任何地方使用相同的大写字母。

1)

您需要创建一个新表来存储entity_id<> store_id地图。

在mysql4-upgrade-x.x.x-n.n.n.php文件(YM / sql / YM_setup /)中添加以下代码以创建新表:

<?php

$installer = $this;

$installer->startSetup();

$installer->run("

CREATE TABLE {$this->getTable('YM_store')} (
  `YM_entity_id` smallint(6) NOT NULL default '0',
  `store_id` smallint(5) NOT NULL default '0',
  PRIMARY KEY (`YM_entity_id`,`store_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

");

$installer->endSetup(); 

2)

下一步是将此表添加到模块配置中: 将以下行添加到config.xml(YM / etc / config.xml)

在最后一个表实体之后查找并添加它:

<YM_store>
 <table>YM_store</table>
</YM_store>

确保将config.xml中的版本号更改为与mysql升级文件相同。

3)

下一步是将下拉表单元素添加到Form.php中 (YM /砌块/ Adminhtml / YM /编辑/ form.php的)

     /**
     * Check is single store mode
     */
    if (!Mage::app()->isSingleStoreMode()) {
        $fieldset->addField('store_id', 'multiselect', array(
            'name'      => 'stores[]',
            'label'     => Mage::helper('cms')->__('Store View'),
            'title'     => Mage::helper('cms')->__('Store View'),
            'required'  => true,
            'values'    => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(false, true),
        ));
    }
    else {
        $fieldset->addField('store_id', 'hidden', array(
            'name'      => 'stores[]',
            'value'     => Mage::app()->getStore(true)->getId()
        ));
        $model->setStoreId(Mage::app()->getStore(true)->getId());
    }

4)

下一步是让控制器知道新表: 在您的YMController.php文件(YM / controllers / Adminhtml /)中,您应该有一个saveAction函数,其中包含以下行:

$model->setData($data);

这是一个通用的保存功能,它将确保将表单中的所有数据发送到保存功能。 (包括新创建的下拉列表的值)

5)

下一步是将addStoreFilter函数添加到Collection.php(YM / Model / Mysql4 / YM) 这段代码是从cms / block Collection.php复制的。您需要更改表字段名称。 (YM_entity_id)

/**
 * Add Filter by store
 *
 * @param int|Mage_Core_Model_Store $store
 * @return Mage_Cms_Model_Mysql4_Page_Collection
 */
public function addStoreFilter($store, $withAdmin = true)
{
    if ($store instanceof Mage_Core_Model_Store) {
        $store = array($store->getId());
    }

    $this->getSelect()->join(
        array('store_table' => $this->getTable('YM/YM_store')),
        'main_table.YM_entity_id = store_table.YM_entity_id',
        array()
    )
    ->where('store_table.store_id in (?)', ($withAdmin ? array(0, $store) : $store))
    ->group('main_table.YM_entity_id');

    return $this;
} 

6)

我们也将商店添加到网格中。 在_prepareColumns()函数(YM / Block / Adminhtml / YM / Grid.php)中,在要显示商店的列之后添加以下行:

if (!Mage::app()->isSingleStoreMode()) {
    $this->addColumn('store_id', array(
        'header'        => Mage::helper('cms')->__('Store View'),
        'index'         => 'store_id',
        'type'          => 'store',
        'store_all'     => true,
        'store_view'    => true,
        'sortable'      => false,
        'filter_condition_callback'
                        => array($this, '_filterStoreCondition'),
    ));
}

并在结束“}”之前将此函数添加到文件末尾。

  protected function _filterStoreCondition($collection, $column)
  {
    if (!$value = $column->getFilter()->getValue()) {
      return;
    }

    $this->getCollection()->addStoreFilter($value);
  } 

请注意,此代码只会将网格中的“所有商店视图”列为缺少的内容,而我无法弄清楚是什么。也许别人会给我们答案......:)

7)

最后一步是向YM.php添加一些函数,以便它能够保存并加载store_ids(YM / Model / Mysql4 / YM.php)以下函数是从cms / blocks复制的。

BeforeSave:

/**
 *
 *
 * @param Mage_Core_Model_Abstract $object
 */
protected function _beforeSave(Mage_Core_Model_Abstract $object)
{
    if (! $object->getId()) {
        $object->setCreationTime(Mage::getSingleton('core/date')->gmtDate());
    }
    $object->setUpdateTime(Mage::getSingleton('core/date')->gmtDate());
    return $this;
}

AfterSave

/**
 *
 * @param Mage_Core_Model_Abstract $object
 */
protected function _afterSave(Mage_Core_Model_Abstract $object)
{
    $condition = $this->_getWriteAdapter()->quoteInto('YM_entity_id = ?', $object->getId());
    $this->_getWriteAdapter()->delete($this->getTable('YM/YM_store'), $condition);

    foreach ((array)$object->getData('stores') as $store) {
        $storeArray = array();
        $storeArray['YM_entity_id'] = $object->getId();
        $storeArray['store_id'] = $store;
        $this->_getWriteAdapter()->insert($this->getTable('YM/YM_store'), $storeArray);
    }

    return parent::_afterSave($object);
}

负载。您可能没有标识符,因此我认为您不需要if语句。

public function load(Mage_Core_Model_Abstract $object, $value, $field=null)
{

    if (!intval($value) && is_string($value)) {
        $field = 'identifier'; // You probably don't have an identifier...
    }
    return parent::load($object, $value, $field);
}

后负荷

/**
 *
 * @param Mage_Core_Model_Abstract $object
 */
protected function _afterLoad(Mage_Core_Model_Abstract $object)
{
    $select = $this->_getReadAdapter()->select()
        ->from($this->getTable('YM/YM_store'))
        ->where('YM_entity_id = ?', $object->getId());

    if ($data = $this->_getReadAdapter()->fetchAll($select)) {
        $storesArray = array();
        foreach ($data as $row) {
            $storesArray[] = $row['store_id'];
        }
        $object->setData('store_id', $storesArray);
    }

    return parent::_afterLoad($object);
}

getLoadSelect

/**
 * Retrieve select object for load object data
 *
 * @param string $field
 * @param mixed $value
 * @return Zend_Db_Select
 */
protected function _getLoadSelect($field, $value, $object)
{

    $select = parent::_getLoadSelect($field, $value, $object);

    if ($object->getStoreId()) {
        $select->join(array('cbs' => $this->getTable('YM/YM_store')), $this->getMainTable().'.YM_entity_id = cbs.YM_entity_id')
                ->where('is_active=1 AND cbs.store_id in (0, ?) ', $object->getStoreId())
                ->order('store_id DESC')
                ->limit(1);
    }
    return $select;
}

lookupStoreIds

/**
 * Get store ids to which specified item is assigned
 *
 * @param int $id
 * @return array
 */
public function lookupStoreIds($id)
{
    return $this->_getReadAdapter()->fetchCol($this->_getReadAdapter()->select()
        ->from($this->getTable('YM/YM_store'), 'store_id')
        ->where("{$this->getIdFieldName()} = ?", $id)
    );
}

好的,如果我没有遗漏任何东西,这应该有效。 :) 登录管理区域,进入系统&gt;高级。如果您设置版本正确,这应该运行mysql升级。您可以检查数据库是否有新表。

转到您的实体,检查您是否有新的商店选择下拉列表。 尝试保存新值...:)

如果不起作用,请告诉我。我可能在代码中犯了一些错误。如前所述,我从cms / blocks中复制了大部分内容。同样如上所述,网格没有加载正确的值,但我不知道为什么。谁能告诉我们? :)

祝你好运,Gergely

答案 1 :(得分:2)

要在网格列中列出选定的商店视图,请在自定义模块中的grid.php中添加以下代码,靠近_filterStoreCondition()函数

protected function _afterLoadCollection() { $this->getCollection()->walk('afterLoad'); parent::_afterLoadCollection(); }

谢谢, Sreedevi

答案 2 :(得分:0)

最好的例子 - 是CMS模块。例如,您可以调查保存CMS页面。 主表为cms_page,其他表为cms_page_store。 您需要修改实体的集合。 请查看Mage_Cms_Model_Mysql4_Page课程,尤其是_afterSave_afterLoad方法。