Magento开发经验总结(一 初初见你——产品属性集搜索模块)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Magento开发经验总结(一 初初见你——产品属性集搜索模块)相关的知识,希望对你有一定的参考价值。
一、 初初见你——产品属性集搜索模块
产品属性搜索模块作为我第一个开发的定制功能模块,对于我个人理解magento系统内部规则与机制、二次开发规则等具有极其重要的意义。可以这么说,通过此模块的开发,我轻轻叩开了magento系统开发的大门,第一次看到了门内复杂、深邃、丰富及灵活的运行机制。
在门外徘徊的我感触良多,magento上手难这件事情我真真切切得感受到了,但是一旦入了门,我们可以从过程中学到非常多的东西,如深入理解设计模式、构建软件理论、模式设计、领域驱动设计等等。
1. 功能需求:新创建商品时,由于产品属性集数量过多,选择相应的产品属性集造成了很大困难,所以需要增加一个产品属性集搜索功能;
2. 功能设计:
方案一:修改属性集选择方式,从select下拉框变为radio单选按钮,将所有数据平铺在页面上,通过浏览器搜索页面内容来定位所要选择的属性集;
方案二:增加一个input输入框,通过搜索关键字进行属性集选择;
3. 方案分析:首先,方案一虽然可以完成我们想要完成的功能,但是将所有属性集平铺在页面上,使得页面内容过多、杂乱,显得有些蠢,用户界面不友好,所以我们选择方案二;其次,方案二可以通过Ajax方式搜索,也可以通过js代码搜索静态内容,在我们这种情况下,产品属性集数据已经被一次性取出,如果再使用Ajax方式搜索数据会增加系统不必要的开销,所以pass;最后,我们得出结论,使用输入框对静态数据进行搜索;
4. 接下来我们需要分析所修改模块的运行机制,然后找到具体从何处入手,添加我们所需的功能;
-
- 该页面地址为:example.com/index.php/admin/catalog_product/index/key /f69e5bd9dc6e01ad2ed4becc85a5f31ebda96f26429055d7e80b8333ccde0572/,其中 index/后的key字符串是系统的secret key,用来保障系统后台访问安全用的,在测试环境下可以将其关闭,路径为System|Configuration|Admin|Security;
- 我们获得有效信息路径为/admin/catalog_product/index/,根据magento规则(其中magento具体规则请参看《magento学习手记》),我们可以得出,该路径的控制器为/code/core/Mage/Adminhtml/controllers/Catelog/ProductControllers.php中的newAction()方法,在该方法中我们可以看到正常的取数据、赋值、加载布局和渲染布局。
- 根据magento的系统规则我们这时去Adminhtml模块中的config.xml去寻找对应的布局文件;
1 <layout> 2 <updates> 3 <adminhtml> 4 <file>main.xml</file> 5 </adminhtml> 6 <report> 7 <file>report.xml</file> 8 </report> 9 <catalog> 10 <file>catalog.xml</file> 11 </catalog> 12 <customer> 13 <file>customer.xml</file> 14 </customer> 15 <promo> 16 <file>promo.xml</file> 17 </promo> 18 </updates> 19 </layout> 20
-
- 与访问控制器比对Adminhtml/controllers/Catelog/ProductControllers.php,我们可以看到Adminhtml模块中的catalog部分的布局文件为catalog.xml;
- catalog.xml文件路径为/app/design/adminhtml/default/default/layout/catalog.xml(根据magento前端布局规则),找到<adminhtml_catalog_product_new>标签,刚好对应相应控制器,代码如下:
1 <adminhtml_catalog_product_new> 2 <update handle="editor"/> 3 <reference name="content"> 4 <block type="adminhtml/catalog_product_edit" name="product_edit"></block> 5 </reference> 6 <reference name="left"> 7 <block type="adminhtml/catalog_product_edit_tabs" name="product_tabs"></block> 8 </reference> 9 <reference name="js"> 10 <block type="adminhtml/catalog_product_edit_js" template="catalog/product/js.phtml" name="catalog_product_js"></block> 11 <block type="core/template" template="catalog/wysiwyg/js.phtml"/> 12 </reference> 13 </adminhtml_catalog_product_new>
-
- 从上面代码中我们可以看出,其中引入了四个block;第一个catalog_product_edit是我们页面中最外层大的block,上面有Back、Reset等按钮及页面显示内容框架;第二个catalog_product_edit_tabs是左侧标签显示及其相关右侧内容块;第三和第四个都是引入js代码的块;
- block标签中的type对应的是其引用的类,根据规则可以知道该路径为/Mage/Adminhtml/Block/Catalog/Product/Edit/Tabs.php,我们来看一下Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs类中的代码,我们定位到_prepareLayout()方法,该方法为此block类渲染页面准备必要的配置和数据。在该方法的第187行,我们可以清楚的看到,当 setId为空时(即为创建新商品),setting tabs的内容页引用的类为adminhtml/catalog_product_edit_tab_settings;
-
- 这时我们找到adminhtml/catalog_product_edit_tab_settings类的位置为/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Settings.php,打开该文件,我们在_prepareForm()方法中看到页面加载的具体控件及数据,这时我们已经定位到我们做需要的位置,现在可以增加我们自己的内容;
- 这时我们找到adminhtml/catalog_product_edit_tab_settings类的位置为/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Settings.php,打开该文件,我们在_prepareForm()方法中看到页面加载的具体控件及数据,这时我们已经定位到我们做需要的位置,现在可以增加我们自己的内容;
5. 接下来我们将用到Magento后台的通用组件Form,相关Form的widget请查阅《Magento学习手记》,其中有所有widget的详细用法。我们先分析一下_perpareForm()方法中的代码:
1 protected function _prepareForm() 2 { 3 $form = new Varien_Data_Form();//创建Form对象 4 $fieldset = $form->addFieldset(‘settings‘, array(‘legend‘=>Mage::helper(‘catalog‘)->__(‘Create Product Settings‘)));//设置Tab页标题 5 6 $entityType = Mage::registry(‘product‘)->getResource()->getEntityType();//获取实例类型 7 8 $fieldset->addField(‘attribute_set_id‘, ‘select‘, array( 9 ‘label‘ => Mage::helper(‘catalog‘)->__(‘Attribute Set‘), 10 ‘title‘ => Mage::helper(‘catalog‘)->__(‘Attribute Set‘), 11 ‘name‘ => ‘set‘, 12 ‘value‘ => $entityType->getDefaultAttributeSetId(), 13 ‘values‘=> Mage::getResourceModel(‘eav/entity_attribute_set_collection‘) 14 ->setEntityTypeFilter($entityType->getId()) 15 ->load() 16 ->toOptionArray() 17 ));//设置Attributes set下拉框及相关内容 18 19 $fieldset->addField(‘product_type‘, ‘select‘, array( 20 ‘label‘ => Mage::helper(‘catalog‘)->__(‘Product Type‘), 21 ‘title‘ => Mage::helper(‘catalog‘)->__(‘Product Type‘), 22 ‘name‘ => ‘type‘, 23 ‘value‘ => ‘‘, 24 ‘values‘=> Mage::getModel(‘catalog/product_type‘)->getOptionArray() 25 ));//设置Product Type下拉框及相关内容 26 27 $fieldset->addField(‘continue_button‘, ‘note‘, array( 28 ‘text‘ => $this->getChildHtml(‘continue_button‘), 29 ));//设置按钮 30 31 $this->setForm($form);//加载form 32 }
6. 现在我们知道了要在在Attributes Set下拉框前增加一个input内容,这时我们考虑如何完成该事情。首先,肯定不能直接添加代码,原因有两条:第一、当magento系统升级时可能会覆盖我们所增加的功能代码;第二、除非是bug我们需要修改代码,如果是正常模块代码,直接修改将违背开放封闭原则,不利于代码维护及团队开发;所以,我们应该选择系统增加新模块扩展原更能模块,这样新模块可以基于被扩展模块增加新的功能,又不影响旧有模块的使用。
7. 接下来我们在/code/local下新建YM命名空间,在新建一个Attributesetsearch模块(具体模块新建过程请查看《Magento学习手记》);
8. 接下来我们考虑通过何种方式扩展原模块功能,magento系统提供类重写和事件监听机制进行功能扩展,其中具体差别和优缺点也可以查看《Magento学习手记》,此处,我们两种方式都可用,因为我们所需要重写的类Mage_Adminhtml_Block_Catalog_Product_Edit
_Tab_Settings没有子孙类,所以重写该类中的某个方法并不会影响到其他类的正常使用,另外,该类仅在Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs类中被使用了一次,而这正是我们要改动扩展的地方,所以使用类重写的方式并不会影响系统中其他功能代码;
9. 类的重写需要先配置我们新建模块的config.xml文件,配置类重写(配置类的重写规则请参考《Magento学习手记》中重写核心类实例),具体代码如下:
1 <global> 2 <blocks> 3 <attributesetsearch> 4 <class>YEMA_Attributesetsearch_Block</class> 5 </attributesetsearch> 6 <adminhtml> 7 <rewrite> 8 <catalog_product_edit_tab_settings>YEMA_Attributesetsearch_Block_Catalog_Product_Edit_Tab_Settings</catalog_product_edit_tab_settings> 9 </rewrite> 10 </adminhtml> 11 </blocks> 12 </global>
10. 此时我们根据规则创建/Attributesetsearch/Block/Catalog/Product/Edit/Tab/Setting.php文件,申明YM_Attributesetsearch_Block_Catalog_Product_Edit_Tab_Settings类,该类继承类Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Settings,将需要重写的方法拷贝复制到类主体中,具体代码如下:
1 <?php 2 class YEMA_Attributesetsearch_Block_Catalog_Product_Edit_Tab_Settings extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Settings{ 3 protected function _prepareForm() 4 { 5 $form = new Varien_Data_Form(); 6 $fieldset = $form->addFieldset(‘settings‘, array(‘legend‘=>Mage::helper(‘catalog‘)->__(‘Create Product Settings‘))); 7 8 $entityType = Mage::registry(‘product‘)->getResource()->getEntityType(); 9 10 $_jscode = " 11 function search(val){ 12 if(val == ‘‘){ 13 resetAction(); 14 }else{ 15 resetAction(); 16 searchAction(val); 17 } 18 } 19 function resetAction(){ 20 var options =\$A($(‘attribute_set_id‘).options).each(function(option){ 21 option.show(); 22 }); 23 } 24 function searchAction(val){ 25 var options =\$A($(‘attribute_set_id‘).options).each(function(option){ 26 var keyword = new RegExp(val); 27 var content = option.innerHTML; 28 if(!keyword.test(content)){ 29 option.hide(); 30 } 31 }); 32 } 33 search($(this).value); 34 "; 35 $fieldset->addField(‘attribute_set_search‘, ‘text‘, array( 36 ‘label‘ => Mage::helper(‘catalog‘)->__(‘Attribute Set Search‘), 37 ‘title‘ => Mage::helper(‘catalog‘)->__(‘Attribute Set Search‘), 38 ‘name‘ => ‘search‘, 39 ‘onchange‘=> $_jscode, 40 )); 41 42 $fieldset->addField(‘attribute_set_id‘, ‘select‘, array( 43 ‘label‘ => Mage::helper(‘catalog‘)->__(‘Attribute Set‘), 44 ‘title‘ => Mage::helper(‘catalog‘)->__(‘Attribute Set‘), 45 ‘name‘ => ‘set‘, 46 ‘value‘ => $entityType->getDefaultAttributeSetId(), 47 ‘values‘=> Mage::getResourceModel(‘eav/entity_attribute_set_collection‘) 48 ->setEntityTypeFilter($entityType->getId()) 49 ->load() 50 ->toOptionArray() 51 )); 52 53 $fieldset->addField(‘product_type‘, ‘select‘, array( 54 ‘label‘ => Mage::helper(‘catalog‘)->__(‘Product Type‘), 55 ‘title‘ => Mage::helper(‘catalog‘)->__(‘Product Type‘), 56 ‘name‘ => ‘type‘, 57 ‘value‘ => ‘‘, 58 ‘values‘=> Mage::getModel(‘catalog/product_type‘)->getOptionArray() 59 )); 60 61 $fieldset->addField(‘continue_button‘, ‘note‘, array( 62 ‘text‘ => $this->getChildHtml(‘continue_button‘), 63 )); 64 65 $this->setForm($form); 66 } 67 }
11. 这里我们在Attribute Set下拉框选项前,增加了一个Attribute Set Search输入框,通过该输入框可以控制Attribute Set下拉框显示内容,从而完成属性集搜索功能,我们使用了input中的onchange方法来触发我们搜索的js代码;这里需要注意的是,magento的后台没有引入jquery,虽然看起来有点儿像,其实我们这里使用的是prototype.js的语法规则。
以上是关于Magento开发经验总结(一 初初见你——产品属性集搜索模块)的主要内容,如果未能解决你的问题,请参考以下文章