magento模块开发手册(一)Magento入门

来源:互联网 发布:人工智能在线播放 编辑:程序博客网 时间:2024/05/17 22:52


什么是Magento的?这是最强大的在线电子商务平台,正在改变电子商务的面貌. grin

不过,你可能还不知道,Magento同样是一个面向对象的PHP框架。你可以配合Magento购物车程序强大的功能,开发动态WEB应用程序。

这是Magento中文开发手册的开篇,我们会在整个手册中介绍绝大部分Magento的开发框架特性。不要想在这片文章中立刻掌握所有的特性。这仅仅是个开始,但是足够让你在同行中鹤立鸡群了。

在这篇文章中,你将了解到:

  • Magento模块(Magento Modules)代码组织形式
  • 配置型MVC架构
  • Magento控制器(Magento Controllers)
  • 基于URI的模型实例化(Context-based URI Model Loading)
  • Magento模型(Magento Models)
  • Magento助手(Magento Helpers)
  • Magento布局(Magento Layouts)
  • 事件监听(Observers)
  • Magento类重写(Class Overrides)

 

你也可以图形来了解MVC架构  Magento_MVC.pdf.

在讲解之前,我们先来认识下名词:

  • Magento模块(Magento Modules)
  • Magento控制器(Magento Controllers)
  • Magento模型(Magento Models)
  • Magento助手(Magento Helpers)
  • Magento布局(Magento Layouts)
  • 事件监听(Observers)

Magento模块中的代码组织

Magento通过将代码放入独立的模块进行组织。在一个典型的PHP MVC应用中 Model-View-Controller (MVC) , 所有的控制器会被放在一个文件夹中,所有的模型会被放在另外一个文件夹里,等等。而在Magento中,文件是基于功能进行分组的,这种分组后的组合在一起的代码组织叫做模块

magento的代码

举例来说,如果你想寻找Magento中关于付款的功能,你仅仅需要找到下面代码中的文件夹,就能获取所有的控制器,模型,助手,Blocks等。

在Magento的谷歌结帐功能中,你会发现控制器,模型,助手,块( Controllers, Models, Helpers, Blocks,)等文件夹

你的代码

如果你想自定义或扩展Magento,不要直接编辑的核心文件(core文件),你要把你自己的控制器,模型,助手,块等Magento的代码放到local文件夹,创建自己的模块

Package(通常也被称为命名空间)是用于识别您的公司或组织的唯一名称。这样做的目的是为了避免与其他用户的代码碰撞创建模块时,在全球范围内的Magento社区的每个成员会用自己的包名。

当你创建一个新的模块,你需要告诉Magento的吧。这是通过添加一个XML文件到文件夹:

此文件夹中有两种类型的文件,第一个启用单个模块,并命名为形式:Packagename_Modulename.xml

第二个是启用多个模块从包/命名空间的文件,并命名为形式:Packagename_All.xml。值得注意的是仅被core team用这个文件Mage_All.xml。我们不建议激活几个模块在一个文件中,因为这打破了你的模块的模块化。

 

基于配置的MVC

Magento是一个配置型(基于配置的)MVC(Configuration-based MVC)系统。另外一种MVC系统则是大部分PHP框架使用的,约定性(基于公约的)MVC(convertion-based MVC)。

在约定性MVC系统里,如果你想添加,比如说,一个新的控制器或者一个新的模型,你只需要创建file/class,系统会自动识别。

在配置型的系统,如Magento的,除了加入新的文件/类的代码库,你经常需要明确地告诉系统这个新类或类新组。在Magento的,每个模块都有一个名为config.xml文件。该文件包含了Magento的所有模块的相关配置。在运行时,所有这些文件都装入一个大的配置树。

例如,要使用模型中的自定义模块?您需要添加一些代码config.xml中告诉Magento的要使用模型,以及什么对你所有的型号的基类名应该是。

例如,要使用模型中的自定义模块?您需要添加一些代码到config.xml中告诉Magento要使用的模型,以及所有的型号的基类名应该是什么。

这同样适用于Helpers, Blocks, Routes for your Controllers, Event Handlers等等,几乎任何时候你想要扩展magento,你需要做出一些改变或添加到您的配置文件。

 

Magento控制器(Magento Controllers)

在任何PHP系统,主要的PHP切入点仍然是一个PHP文件。 Magento的没有什么不同,而该文件是index.php文件。

但是,你永远不要编辑index.php。在MVC体系,index.php文件将包含代码/调用,可以做以下行为动作:

1.检查URL网址

2.根据一些规则集,将这个URL分发到控制器类和动作方法(称为路由)

3.实例化控制器类并调用Action方法(称为调度)

这意味着在Magento的实际入口点(或任何基于MVC的系统)是一个控制器文件里面的方法。看下面的网址:

服务器名称(域名)后的路径的各部分被分析如下。

 

Front Name – catalog

该URL的第一部分被称为Front Name。它用来指示Magento应该在哪个模块中寻找URL中的控制器。在这个例子中,catalog就是Front Name,对应于catalog模块。

 

Controller Name – category

URL的第二部分告诉Magento它应该使用哪个控制器文件。每个有控制器的模块都包含有一个名为“控制器”的特殊文件夹,这个文件包含了这个模块的所有控制器文件。在上面的例子中,URL部分类别被转换成控制器文件

其中控制器文件的定义格式为

在Magento的购物车应用程序中,所有控制器都是Mage_Core_Controller_Front_Action的延伸(继承与该类)。

 

Action Name – view

URL的第三部分就是 action name. 在我们的例子中,它是 “view”. “view” 就是创建的Action的名字. 所以,在我们的例子中, “view” 就是 “viewAction”

 

人们熟悉的Zend框架将在这里认识这种命名约定。

 

Paramater/Value – id/25

任何位于action方法名之后的路径,都会被认为是key/value形式传递的GET变量。那么在我们的例子当中,’id/25′表示有一个值为25的$_GET[‘id’]变量。

正如前面提到的,如果你希望你的模块使用控制器,你需要配置它们。下面是在配置块中使用控制器的目录模块配置代码

不要太担心了具体的权利,但注意到<frontName>catalog</frontName>, 这是用来关联模块与URL地址中frontname的。Magento核心代码选择将一个模块的名字与frontname一致,但这不是强制规定的。

 

Multiple Routers

上述的路由是Magento的购物应用程序(通常称为前端)。如果Magento的没有找到一个有效的控制器/动作的URL,它再次尝试,为管理应用程序使用的是第二组路由这段时间的规则。如果Magento的没有找到一个有效的管理控制器/动作,它使用一个名为Mage_Cms_IndexController一种特殊的控制器。

CMS的控制器检查Magento的内容管理系统,看看是否有应加载任何内容。如果找到了一些,它加载它,否则用户将看到一个404页面。

例如,Magento的“index”页(首页)是一个使用CMS的控制,而这往往把新引入到一个死循环里。

Context-Based URI 模型加载

现在,我们将Action方作为切入点,我们将要开始实例化的类做点事情。Magento的提供了一种特殊的方式来实例化模型,利用Models, Helpers and Blocks,即使用Mage全局类提供的静态工厂方法. 例如

‘catalog/product’字符串被称为Grouped Class Name。通常叫做URI。Grouped Class Name的第一部分用来指示该类存在于哪个模块当中。第二部分用来决定哪个类将被调用。

所以,在这两个以上的实施例中,“catalog”解析为模块的app/code/core/Mage/Catalog。
这意味着我们的 class name将开始于Mage_Catalog。
然后根据调用的类型,将product类名加入到最后一部分。即

这些规则是由每个模块的配置文件所约束的,当你在建立一个自定义的模块时,你将定义你自己的group class name,例如:

Mage::getModel('myspecialprefix/modelname');.

不是一定要用Groupd Class Name来实例化你的类名,但是,为了以后的学习,这样做有一定的优势

 

Magento模型(Magento Models)

像大多是框架一样,magento也提供了对应关系映射(ORM)系统,ORMs 让你之关注SQL的业务,并允许您通过PHP代码完全操纵的数据存储,而不是无尽的SQL语句。例如:

 

在上面这个例子中,我们调用了“getPrice”和“setPrice”方法。然而,在Mage_Catalog_Model_Product类 中并没有此方法。那为什么上面这个例子能够使用这些方法呢?因为Magento的ORM系统中使用了PHP的_get和_set魔术方法。

调用$product->getPrice()会获取模型属性price,而调用$product->setPrice()会设置 price属性。当然,所有的这些都假设模型类没有getPrice和setPrice方法。如果它们存在于模型类中,PHP魔术方法会被忽略。如果你有 兴趣知道这是如何实现的,可以参考Varien_Object类,所有的模型类都继承自该类。

如果你想获取模型当中所有的数据,可以直接调用$product->getData()方法,它会返回包含所有字段的一个数组。

你可能已经注意到上例中的方法存在使用->符号链接的形式:

$model->setPrice($price)->setSku('SK83293432');

这是由于每个set方法都会返回一个模型的实例,你会在代码中看到很多都用这种模式

Magento的ORM还包含一种方法通过Collections接口查找多个对象,下面我们将获得所有费用5.00美元产品的集合

同样地,你会发现Magento实现了一个链接接口。集合使用PHP的标准库实现有阵类似属性的对象。集合(Collections)使用PHP的标准库来实现属性组的对象

你可能想知道的“addAttributeToSelect”的方法是什么。 Magento的有两大类型的模型对象。一种是传统的“一个对象,一张表”的Active Record风格模型。当你实例化这些模型的时候,所有的属性将被自动选中。

第二类模型是一个实体属性值(EAV)模型。 EAV模型会按照一定的规律将数据分散存储在数据库不同的表中。这使Magento的系统的灵活性,提供了灵活的产品属性的系统,而无需每次添加一个属性时做架构更改。当创建EAV对象的集合,Magento查询列的次数是保守的,因此您可以使用addAttributeToSelect得到你想要的列,或addAttributeToSelect(“*”)来获取所有的列。

 

Magento辅助类(Helpers)

Magento的辅助类包含一些实用的方法,可以让你对对象和变量执行日常性的操作。例如:

$helper = Mage::helper('catalog');

你会发现这里舍弃了Grouped Class Name的第二部分?每个模块都有一个默认的data辅助类。下面的语句与上面的作用是相同的,即默认使用模块下的data辅助类。

$helper = Mage::helper('catalog/data');

大部分辅助类继承自Mage_Core_Helper_Abstract,它给你默认了一些有用的方法。

 

Magento布局(Layouts)

到这儿,我们已经了解了Controllers, Models, and Helpers,在典型的PHP MVC系统当中,在操作模型之后,一般会

  • 传递变量到视图中。
  • 系统会自动读取默认的外层布局
  • 接着将视图加载到外层布局中

但是,如果你只看一个典型的Magento控制器的动作,你看不到任何东西

相反,这个控制器由两个会话结束

所以,在Magento的MVC中的“V”型已经不同于可能已经与你习惯的V不一样了,在你需要明确地分发到布局。

Magento的布局本身也区别与你经常使用的MVC系统。Magento布局是一个包含嵌套或者树状的Block对象的对象。每一个Block对象输出一部分HTML,输出HTML的环节包含两个部分,PHP代码组成的Block以及.phtml模板文件。

Block对象是为了与Magento的系统来检索模型数据进行交互,而PHTML模板文件会产生所需的页面的HTML。

例如,页面头部Block文件app/code/core/Mage/Page/Block/Html/Head.php使用与其对应的page/html/head.phtml模板文件。

换种方式说的话,Blocks类就像迷你控制器,而.phtml文件就是视图文件。

默认情况下,当你调用

Magento将加载网站骨架结构布局。这些结构Blocks用来输出head,body以及设定单栏或多栏的布局。此外,还会有一些内容块的导航,默认的欢迎信息等。

“结构”和“内容”Blocks在布局系统中是随意设置的。一般不会在代码中刻意添加代码,从而区分一个Block是结构还是内容,但是Blocks要么属于“结构”,要么属于“内容”。

添加内容到这个布局,你需要告诉Magento系统如

或者

这可以通过编程的控制器操作来完成

但更常见的(至少在购物车前端应用程序),是使用XML布局体系。

在主题布局的XML文件里允许你在每个控制器的基础上,消除通常被控制器分发的块,或添加块到默认骨架的区域。例如,考虑这种布局的XML文件:

上面代买是说,在catalog模块的控制器category和方法default中,插入catalog/navigation模块到“left”的结构模块,使用catalog/navigation/ left.phtml模板。

关于块的最后一个重要的事情。你会经常看到的代码模板,如下所示:

$this->getChildHtml('order_items')

这是Block输出套嵌Block的方式。但是,只有在XML布局文件中明确声明一个Block包含另一个子Block时,才能在模板文件中通过getChildHtml()方法调用子Block的模板文件。

例如,我们有像这样的

从catalog/navigation Block中我们才能调用

$this->getChildHtml('foobar');

 

Magento观察员(Observers)

像任何优秀的面向对象的系统,Magento通过实现观察者模式给用户作为钩子,作为一个页面请求(模型被保存,用户登录等)在某些动作发生,Magento的会发出一个事件信号。

在创建自己的模块的时候,可以“监听”这些事件。比如说,你想在特定用户登录商店的时候发一封邮件到管理员信箱里,可以通过“监听”customer_login事件(设置在config.xml中)。

接着写一些代码当用户登录时运行

 

类重写(Class Overrides)

最后,Magento系统还提供了类的复写功能,你可以通过自己的代码覆盖核心代码里的Model, Helper 和 Block 类。类似Ruby或Python语言中的”Duck Typing” 和”Monkey Patching”。

下面是一个例子来帮助大家理解。一个产品的模型类是Mage_Catalog_Model_Product。

只要下面的代码被调用时,将创建一个Mage_Catalog_Model_Product对象

他是一个工厂模式。

Magento的类重写系统的作用是让你告诉系统

然后,如果你愿意,你的Packagename_Modulename_Model_Foobazproduct类可以扩展原有产品类别

这将允许您更改类的任何方法的行为,但保持现有方法的功能。

 

正如你所料,这最主要的(或重写)在config.xml文件中完成。

有一件事,重要的是要注意这里。在你的模块里的类都覆盖各个类中的其他模块。 ,但是覆盖整个模块,你都没有。这使您可以更改特定的行为方式,而不必担心什么模块的其余部分在做什么。

我们希望您喜欢的一些Magento的电子商务系统提供给开发商的这一特点旋风之旅。它可以是一个有点势不可挡,第一,特别是如果这是你与一个现代化的,面向对象的PHP系统初体验。如果你开始感到沮丧,深呼吸,提醒自己,这是新的,新的东西很难,但在一天结束的时候它的编码只是一种不同的方式。一旦你得到了学习曲线,你会发现自己不愿意回到其他不那么强大的系统。

0 0
原创粉丝点击