Magento 在捆绑项目中添加另一个新字段

标签 magento magento-1.7 magento-1.4

我想在 bundle 项目的默认标题下方添加新文本列。 创建新的捆绑产品时,我需要添加额外的字段 我想要在默认标题下方添加新文本字段以添加说明。 请帮忙。任何帮助将不胜感激。 enter image description here

最佳答案

为了添加新的description field在每个 bundle option ,您需要创建一个模块。简而言之,您的模块将执行以下功能。

  1. 创建一个新表来保存我们的description field用于捆绑选项。

  2. 当产品保存时,它将更新我们的表格并进行必要的更改。

考虑到这一点,让我们创建我们的模块。让我们的模块为Programmerrkt_Customfieldinbundle

位置:app/code/local/Programmerrkt/Customfieldinbundle/etc/config.xml

<config>
<modules>
    <Programmerrkt_Customfieldinbundle>
        <version>0.1.1</version>
    </Programmerrkt_Customfieldinbundle>
</modules>
<admin>
    <routers>
        <programmerrkt_customfieldinbundle>
            <use>admin</use>
            <args>
                <module>Programmerrkt_Customfieldinbundle</module>
                <frontName>customfieldinbundle</frontName>
            </args>
        </programmerrkt_customfieldinbundle>
    </routers>
</admin>
<adminhtml>
    <layout>
        <updates>
            <programmerrkt_customfieldinbundle>
                <file>programmerrkt_customfieldinbundle.xml</file>
            </programmerrkt_customfieldinbundle>
        </updates>
    </layout>
    <events>
        <catalog_product_save_commit_after>
            <observers>
                <programmerrkt_customfieldinbundle>
                    <class>customfieldinbundle/observer</class>
                    <method>SaveDescriptionAfterProductSave</method>
                </programmerrkt_customfieldinbundle>
            </observers>
        </catalog_product_save_commit_after>
    </events>
</adminhtml>
<global>
    <models>
        <customfieldinbundle>
            <class>Programmerrkt_Customfieldinbundle_Model</class>
            <resourceModel>customfieldinbundle_mysql4</resourceModel>
        </customfieldinbundle>
        <customfieldinbundle_mysql4>
            <class>Programmerrkt_Customfieldinbundle_Model_Resource</class>
            <entities>
                <optiondescription>
                    <table>catalog_product_bundle_option_description</table>
                </optiondescription>
            </entities>
        </customfieldinbundle_mysql4>
    </models>
    <resources>
        <customfieldinbundle_setup>
            <setup>
                <module>Programmerrkt_Customfieldinbundle</module>
                <class>Programmerrkt_Customfieldinbundle_Model_Resource_Mysql4_Setup</class>
            </setup>
            <connection>
                <use>core_setup</use>
            </connection>
        </customfieldinbundle_setup>
        <customfieldinbundle_write>
            <connection>
                <use>core_write</use>
            </connection>
        </customfieldinbundle_write>
        <customfieldinbundle_read>
            <connection>
                <use>core_read</use>
            </connection>
        </customfieldinbundle_read>
    </resources>    
    <blocks>
       <!--  need to overwrite a bundle block in order to add additional field -->
        <!-- <bundle>
            <rewrite>
                <adminhtml_catalog_product_edit_tab_bundle_option>Programmerrkt_Customfieldinbundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option
                </adminhtml_catalog_product_edit_tab_bundle_option>
            </rewrite>
        </bundle>  -->
        <programmerrkt_customfieldinbundle>
            <class>Programmerrkt_Customfieldinbundle_Block</class>
        </programmerrkt_customfieldinbundle>
    </blocks>
</global>
</config>

我们的配置文件包含有关自定义表的详细信息 catalog_product_bundle_option_description我们将在其中存储 bundle 描述。它还定义了一个观察者,当触发时,会将更改保存到我们的自定义表中。

位置:app/etc/modules/Programmerrkt_Customfieldinbundle.xml

<config>
<modules>
    <Programmerrkt_Customfieldinbundle>
        <active>true</active>
        <codePool>local</codePool>
    </Programmerrkt_Customfieldinbundle>
</modules>
</config>

现在我们需要在管理端显示我们的描述字段。为此,我们需要编辑一个 block 来呈现 bundle 选项。该 block 是 app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php 。我们需要更改此文件中的两个方法。 **仅显示主要部分

<?php
  ----------

/**
* Bundle option renderer class constructor
*
* Sets block template and necessary data
*/
public function __construct()
{
    $this->setTemplate('programmerrkt/customfieldinbundle/bundle/product/edit/bundle/option.phtml');
    //$this->setTemplate('bundle/product/edit/bundle/option.phtml');
    $this->setCanReadPrice(true);
    $this->setCanEditPrice(true);
}

------

/**
* Retrieve list of bundle product options
*
* @return array
*/
public function getOptions()
{
    if (!$this->_options) {

        $customCollection = Mage::getModel('customfieldinbundle/optiondescription')->getCollection();
        $store_id = $this->getProduct()->getData('store_id');

        //sets default values of description module
        $empty = FALSE;
        if(count($customCollection)){
            $description_id = (int)(count($customCollection)+1);
        }
        else{
            $empty = TRUE;
            $description_id = 1;
        }
        $description_content = "";

        $this->getProduct()->getTypeInstance(true)->setStoreFilter($this->getProduct()->getStoreId(),
            $this->getProduct());

        $optionCollection = $this->getProduct()->getTypeInstance(true)->getOptionsCollection($this->getProduct());

        $selectionCollection = $this->getProduct()->getTypeInstance(true)->getSelectionsCollection(
            $this->getProduct()->getTypeInstance(true)->getOptionsIds($this->getProduct()),
            $this->getProduct()
        );

        $this->_options = $optionCollection->appendSelections($selectionCollection);


        foreach ($this->_options as $option) {
                    //gets each option's id
                   $option_id = $option->getData('option_id');
                   //loop through module collection
            if($empty === FALSE){
                   foreach($customCollection as $description){
                        //finds the entry corresponds to option id, if exist
                        if($description['option_id']==$option_id && $description['store_id']==$store_id){
                            $description_id = (int)$description['description_id'];
                            $description_content = $description['description'];
                            break;  
                        }    

                   }
                   //adds our new datas to option
                   $option->addData(array('desc_id'=> $description_id, 'description' => $description_content, 'desc_new'=> 'no'));
            }
            else {              
                    $description_id = (int)$description['description_id'];
                    $description_content = $description['description'];
                    //adds our new datas to option
                   $option->addData(array('desc_id'=> $description_id, 'description' => $description_content,'desc_new'=> 'yes'));
                   $description_id++;

            }
        }


        if ($this->getCanReadPrice() === false) {
            foreach ($this->_options as $option) {
                if ($option->getSelections()) {
                    foreach ($option->getSelections() as $selection) {
                        $selection->setCanReadPrice($this->getCanReadPrice());
                        $selection->setCanEditPrice($this->getCanEditPrice());
                    }
                }
            }
        }    
    }
    return $this->_options;
}

------

这些方法是

  1. __construct()

此方法用于定义选项内容渲染的自定义模板。使用这个我们可以避免核心模板编辑。

  • getOption()
  • 此方法用于将我们模块的数据包含到现有选项中。通过这种方法,magento 将显示已创建的选项的设置描述。

    现在是我们的模板文件。 **仅显示主要部分

    位置:app/design/adminhtml/<your_package/<your_theme>/programmerrkt/customfieldinbundle/bundle/product/edit/bundle/option.phtml

    <script type="text/javascript">
    optionTemplate = '<div id="<?php echo $this->getFieldId() ?>_{{index}}"  class="option-box"> ' +
    '<input id="description_id" type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][description_id]" value="{{desc_id}}" />'+
    '<input id="description_new" type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][description_new]" value="{{desc_new}}" />'+
    '<div class="option-title"> ' +
        '<label for="<?php echo $this->getFieldName() ?>[{{index}}][title]"><?php echo Mage::helper('bundle')->__('Default Title') ?> <span class="required">*</span></label>' +
        <?php if ($this->isDefaultStore()): ?>
        '<input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_title" value="{{title}}">' +
        <?php else: ?>
        '<input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][default_title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_default_title" value="{{default_title}}">' +
        <?php endif; ?>
    '<?php echo $this->jsQuoteEscape($this->getOptionDeleteButtonHtml()) ?>' +
    '</div>' +
    
    
    '<div style="margin-top: 10px;font-weight: bold;"> ' +
        '<label for="<?php echo $this->getFieldName() ?>[{{index}}][description]" style="float:left;"><?php echo Mage::helper('bundle')->__('Default Description') ?> </label>' +
        '<textarea class="input-text" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][description]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_description" style="margin-left: 10px;width: 226px;height: 100px;">{{description}}</textarea>' +
    '</div>' +
    
    
        '<table class="option-header" cellpadding="0" cellspacing="0">' +
            '<thead>' +
                '<tr>' +
                    <?php if (!$this->isDefaultStore()): ?>
                    '<th class="opt-title"><?php echo Mage::helper('bundle')->__('Store View Title') ?>  <span class="required">*</span></th>' +
                    <?php endif; ?>
                    '<th class="opt-type"><?php echo Mage::helper('bundle')->__('Input Type') ?></th>' +
                    '<th class="opt-req"><?php echo $this->jsQuoteEscape(Mage::helper('bundle')->__('Is Required')) ?></th>' +
                    '<th class="opt-order"><?php echo Mage::helper('bundle')->__('Position') ?></th>' +
                    '<th>&nbsp;</th>' +
                '</tr>' +
            '</thead>' +
            '<tbody>' +
                '<tr>' +
                    '<input type="hidden" id="<?php echo $this->getFieldId() ?>_id_{{index}}" name="<?php echo $this->getFieldName() ?>[{{index}}][option_id]" value="{{option_id}}">' +
                    '<input type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][delete]" value="" class="delete">' +
                    <?php if (!$this->isDefaultStore()): ?>
                    '<td><input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_title_store" value="{{title}}"></td>' +
                    <?php endif; ?>
                    '<td><?php echo $this->getTypeSelectHtml() ?></td>' +
                    '<td><?php echo $this->getRequireSelectHtml() ?></td>' +
                    '<td><input class="input-text validate-zero-or-greater" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][position]" value="{{position}}"></td>' +
                    '<td>&nbsp;<?php echo $this->jsQuoteEscape($this->getAddSelectionButtonHtml()) ?></td>' +
                '</tr>' +
            '</tbody>' +
        '</table>' +
        '<div id="<?php echo $this->getFieldId() ?>_search_{{index}}">' +
        '</div>' +
    '</div>';
    </script>
    

    我们所做的是,我们在标题字段下方添加了一个文本区域。

    现在是最重要的文件。我们的观察者。这对我们的模块起到了作用。它用于通过检查不同的标准来保存我们的数据。

    <?php
    /**
     * Bundle Products Observer
     *
     * @category    Mage
     * @package     Programmerrkt_Customfieldinbundle
     * @author      Programmer_RKT
     */
    class Programmerrkt_Customfieldinbundle_Model_Observer
    {
        /**
         * Setting Bundle Items Data to product for father processing
         *
         * @param Varien_Object $observer
         * @return Programmerrkt_Customfieldbundle_Model_Observer
         */
        public function SaveDescriptionAfterProductSave($observer)
        {
    
            $model = Mage::getModel('customfieldinbundle/optiondescription'); // loads module's model
            $collection =  $model->getCollection();
    
            $product = $observer->getEvent()->getProduct(); //get current product
    
            //$optionCollection use to get ids of new options. 
            //$bundleOption does not contain option_id of new option
            //$optionCollection does not contain module's field values. This we can obtain from $bundleOptions
            $optionCollection =  $product->getTypeInstance(TRUE)->getOptionsCollection($product);
            $bundleOptions = $product->getBundleOptionsData(); //@data : array which conatains array
                                                            //get all option data such as title, description, type etc.
    
            if(!empty($bundleOptions)){
                $store_id = (int)$product->getData('store_id'); //@data : integer
    
                if($store_id !=0) {
                    //if not default store
                    foreach ($bundleOptions as $option) {
                        $option_id = (int)$option['option_id'];
                        $description_id = (int)$option['description_id'];
                        $description_new = $option['description_new'];
    
                        //use to set option_id for new options in our module
                        if($option_id <= 0 || is_null($option_id)){
                            foreach ($optionCollection as $new) {
                                if($new['type'] == $option['type'] && ( $new['title'] == $option['title'] || $new['default_title'] == $option['title'] )){
                                    $option_id = $new['option_id'];
                                }
                            }
                        }
    
                        $data = array(
                            'option_id' => $option_id,
                            'store_id' => $store_id,
                            'description' => $option['description']
                        );
    
                       //description id exist means already there is an entry
                        if($description_id >= 0 || $description_new=='no'){
                            $model->load($description_id);
                            $model->addData($data);
                            $model->save();
                        }
                        else{
    
                            $model->setData($data);
                            $model->save();
                        }
    
                    }
                }
    
                else {
                    //if default store
                    foreach ($bundleOptions as $option) {
    
                        $option_id = (int)$option['option_id'];
                        $description_id = (int)$option['description_id'];
                        $description_new = $option['description_new'];
    
                        //use to set option_id for new options in our module
                        if($option_id <= 0 || is_null($option_id)){
                            foreach ($optionCollection as $new) {
                                if($new['type'] == $option['type'] && ( $new['title'] == $option['title'] || $new['default_title'] == $option['title'] )){
                                    $option_id = $new['option_id'];
                                }
                            }
                        }
    
                        $data = array(
                            'option_id' => $option_id,
                            'store_id' => 0,
                            'description' => $option['description']
                        );
    
                        //description id exist means already there is an entry
                        if($description_id >= 0 || $description_new=='no'){
                            $model->load($description_id);
                            $model->addData($data);
                            $model->save();
                        }
                        else{
    
                            $model->setData($data);
                            $model->save();
                        }
    
                    }
    
                }
    
            }
    
             return $this;
    
        }
    }
    

    注意:我只描述了我们模块的重要文件。我想你们都知道如何在 Magento 中设置基本模块。

    就是这样。你已经准备好出发了。清除缓存并加载捆绑产品。您可以在 bundle 选项的标题字段下方看到一个文本区域。

    如有任何疑问,请随时询问。

    关于Magento 在捆绑项目中添加另一个新字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24097689/

    相关文章:

    magento - magento 中 paypal 快速结帐的 ipn url 是什么

    php - 在 Magento 中使用产品的 "getTypeInstance()"

    magento - 如何在产品列表页面上显示产品详细说明?

    magento - Opencart,从产品的规范 URL 中删除类别字符串

    css - 将站点复制到另一台服务器后,Magento CSS 未更​​新

    Magento CE 1.4 索引器 - 索引管理

    magento - Curl、Magento 和 Paypal。 (Curl 不返回任何错误)

    magento - 覆盖\app\code\core\Mage\Core\Block\Messages.php

    magento - Magento 1.4.x 中的订单状态/状态如何工作

    magento - 从管理中删除 Magento Logo 和商标是否合法