【问题标题】:magento multiselect insert databasemagento 多选插入数据库
【发布时间】:2011-10-04 12:32:04
【问题描述】:

我想在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),
        ));
   }

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

【问题讨论】:

    标签: magento


    【解决方案1】:

    由于 Magento 有自己的方式在数据库中存储 Store 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/Block/Adminhtml/YM/Edit/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)

    让我们也将 Store 添加到 Grid 中。 在 _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 复制的。

    保存前:

    /**
     *
     *
     * @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;
    }
    

    保存后

    /**
     *
     * @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)
        );
    }
    

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

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

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

    祝你好运,格格利

    【讨论】:

      【解决方案2】:

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

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

      谢谢, 斯里德维

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-04
          • 2023-02-03
          • 2019-07-31
          • 1970-01-01
          • 2017-01-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多