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()方法中看到页面加载的具体控件及数据,这时我们已经定位到我们做需要的位置,现在可以增加我们自己的内容;

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的语法规则。

时间: 2024-12-25 22:53:00

Magento开发经验总结(一、 初初见你——产品属性集搜索模块)的相关文章

Magento 2开发教程 - 如何添加新产品属性

添加产品属性是一种在Magento 1 和 Magento 2最受欢迎的业务. 属性是解决许多与产品相关的实际任务的有力方法. 这是一个相当广泛的话题,但在这个视频中,我们将讨论添加一个下拉类型属性到产品的简单过程. 对于这个练习,假定安装了示例数据集. 我们将添加一个属性叫做clothing_material与可能的值:Cotton, Leather, Silk, Denim, Fur, 和 Wool. 我们将在"产品视图"页面上以粗体文本显示此属性. 我们将它分配给默认属性集,并添

js算法初窥03(简单搜索及去重算法)

前面我们了解了一些常用的排序算法,那么这篇文章我们来看看搜索算法的一些简单实现,我们先来介绍一个我们在实际工作中一定用到过的搜索算法--顺序搜索. 1.顺序搜索 其实顺序搜索十分简单,我们还是以第一篇文章写好的架子作为基础,在其中加入顺序搜索的方法: //顺序搜索 this.sequentialSearch = function(item) { for(var i = 0; i < array.length; i++) { if(item === array[i]) { return i; };

Magento入门开发教程

Modules->模块 Controller->控制器 Model->模型 Magento是这个星球上最强大的购物车网店平台.当然,你应该已经对此毫无疑问了.不过,你可能还不知道,Magento同样是一个面向对象的PHP框架.你可以配合Magento购物车程序强大的功能,开发动态WEB应用程序. 这是Magento中文开发手册的开篇,我们会在整个手册中介绍绝大部分Magento的开发框架特性.不要想在这片文章中立刻掌握所有的特性.这仅仅是个开始,但是足够让你在同行中鹤立鸡群了. 在这片文

Magento开发文档(一):Magento入门

开始之前,首先声明下,Magento开发者手册由Alan Storm发表在Magento官方网站上.总共分八个部分,由浅入深的介绍了Magento的MVC架构及Magento中使用的比较特殊的EAV模型. 虽然英文文档读起来没有问题,但是真想看一遍能有一定深入的了解,还是中文看着比较舒服.并且在网上搜索了下,大部分都是Magento的模板开发手册以及没有纠错的原文翻译(因为版本问题,Magento官方网站上的一些例子已经无法正常运行),所以决定把这写文章翻译成中文,一来对于自己更深入的把握程序有

Magento控制器

提到模型-视图-控制器这种MVC架构,要追溯到Smalltalk编程语言和Xerox Parc.从那个时候开始,就有许多系统将自己描述为MVC架构.这些系统虽然在某些地方有细微差别,但都实现了数据层,逻辑层和前段表现代码的分离. 大部分的PHP MVC框架都拥有以下基本特征, 所有的URL请求会被前端控制器解析 前端控制器会检查请求的URL路径,并从中获取一个控制器和动作名(这个过程叫做路由) 实例化从URL中获取的控制器 该控制器中,与从URL里获取的动作名一致的方法会被调用 根据请求的变量,

Magento(社区版)自带模块解析以及在国内的使用建议二

11.CatalogIndex 跟商品相关的几种索引(价格.属性等等)的处理模块,商品是系统的核心组件,处理商品索引相关的模块自然也是核心模块,必须是开启状态. 12.CatalogInventory 核心模块之一的"库存"模块,管理者Magento的商品库存相关的功能. Magento的库存逻辑,主要通过两个字段来控制:库存数量(Qty)和库存状态(Stock Availability),理论上只有该商品库存数量大于0并且库存状态是In Stock时,这个商品才是前台真正可以售卖的.

Magento 模块开发之DispatchEvent

在这一章节中,我们来了解 Magento 中的事件分发机制 Mage::dispatchEvent() 在创建自己的模块时, Event 事件的分发将会变成十分有用且有效 以个人的经验, 事件的分发使用频率应该高于对类的重写(overriding), 为什么这么说呢, 当有多个模块的时候, 重写同一个类(class)时,那它们互相将会有冲突, 只有一个模块将会正常工作, 但是如果你使用事件的话, 那么多个模块都可以很轻松的去调用它 Magento 中的事件也是根据观察者(Observer)设计模

magento目录结构精编版

1 /app – 程序根目录 2 3 /app/etc – 全局配置文件目录 4 5 /app/code – 所有模块安装其模型和控制器的目录 6 7 /app/code/core – 核心代码或经过认证得模块,如果要升级不要这里的代码 8 9 /app/code/community – 社区版的模块目录10 11 /app/code/local – 定制代码目录12 13 /app/code/core/Mage? – magento默认命名空间14 15 /app/code/core/Mage

Magento 模块开发之DispatchEvent(转)

在这一章节中,我们来了解 Magento 中的事件分发机制 Mage::dispatchEvent()在创建自己的模块时, Event 事件的分发将会变成十分有用且有效 以个人的经验, 事件的分发使用频率应该高于对类的重写(overriding), 为什么这么说呢, 当有多个模块的时候, 重写同一个类(class)时,那它们互相将会有冲突, 只有一个模块将会正常工作, 但是如果你使用事件的话, 那么多个模块都可以很轻松的去调用它 Magento 中的事件也是根据观察者(Observer)设计模式