【问题标题】:Magento add another new field in bundle itemMagento 在捆绑项目中添加另一个新字段
【发布时间】:2014-06-07 13:24:29
【问题描述】:

我想在捆绑项目的默认标题下方添加新的文本列。 当我创建一个新的捆绑产品时,我需要添加一个额外的字段 我希望在默认标题下方的新文本字段中添加描述。 请帮助。任何帮助将不胜感激。

【问题讨论】:

  • 请不要重复同样的问题,您可以随时编辑您的原始问题(这必须是您的原始问题stackoverflow.com/questions/24087599/…)。致社区:我无法使用手机上的标志选项
  • @KrishnaSunuwar 请帮我解决这个问题

标签: magento magento-1.7 magento-1.4


【解决方案1】:

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

  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 的详细信息。它还定义了一个观察者,它在触发时会将更改保存到我们的自定义表中。

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

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

现在我们需要在管理端显示我们的描述字段。为此,我们需要编辑一个块,以呈现捆绑选项。该块是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()

此方法用于定义用于选项内容呈现的自定义模板。使用它我们可以避免核心模板编辑。

  1. getOption()

此方法用于将我们模块的数据包含到现有选项中。通过这种方法,magento 将显示已经创建的选项的集合描述。

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

位置:app/design/adminhtml/&lt;your_package/&lt;your_theme&gt;/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 中设置一个基本模块。

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

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

【讨论】:

  • 我设置了你所说的所有内容,但我得到了:Fatal error: Class 'Programmerrkt_Customfieldinbundle_Model_Resource_Mysql4_Setup' not found in C:\wamp2.5\www\app\code\core\Mage\Core\Model\Resource\Setup.php on line 234 请指教。
  • @Rajeev K Tomy 你能给我完整的代码示例吗,因为缺少一些文件,比如 db 文件等谢谢。
  • @Rajeev 为什么要为此添加新表?为什么不向catalog_product_bundle_option_value 添加一个新列并重用现有的模型三元组?
猜你喜欢
  • 2014-07-28
  • 1970-01-01
  • 2012-02-21
  • 2013-11-02
  • 1970-01-01
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
  • 2013-04-10
相关资源
最近更新 更多