天天看點

第一章 - Magento強大的配置系統

深入了解Magento

作者:​​Alan Storm​​​翻譯:​​zhlmmc​​

前言

我從2007年開始使用Magento,應該算是國内第一批使用Magento的使用者。但是我卻從來沒有認真研究過Magento,更多的停留在應用層面。雖然也做過一些插件,但也就是依葫蘆畫瓢而已。偶然間看到

​​Alan Storm​​

的一系列關于

​​Magento的文章​​

,我忍不住的心潮澎湃,相見恨晚。Alan的文章循序漸進,深入淺出地講述了Magento的架構和工作方式,把一個複雜系統的内部結構淋漓盡緻的展現在我們面前。讀完以後,我茅塞頓開,感歎Magento的強大,架構之美。于是我決定翻譯Alan的文章,希望對更多的Magento開發者有所幫助。

Alan的文章不是Magento入門教程,并不是教你如何安裝,使用Magento。借用 Alan的原話“Magento Articles for Professional Developers”,我認為這裡的“Professional”包含以下幾點:

  1. 懂得PHP的運作方式
  2. 良好的程式設計基礎 (寫過5w行代碼以上)
  3. 了解基本設計模式
  4. 安裝并使用過Magento
  5. 閱讀并修改過Magento代碼

我的翻譯加入了我自己的了解,對原文有所修改和調整。還有,Alan的文章寫的比較早,現在Magento出新版了,是以我對文中的代碼進行了修改,我翻譯以後的文章是基于Magento 1.4.0.1版本的。是以如果你發現我的翻譯和原文有不符的地方,請不要見怪。下面讓我們開始奇妙的Magento之旅!

第一章 - Magento強大的配置系統

Magento的配置系統就像是Magento的心髒,支撐着Magento的運作。這套配置系統掌管着幾乎所有“module/model/class/template/etc”。它把整個Magento系統抽象出來,用一個配置檔案來描述。這裡的“配置檔案”并不是一個實體上存在的檔案,而是Magento根據目前的系統狀态動态生成的一段XML。大多數的PHP開發者并不習慣于這樣抽象層,因為它增加的程式設計的複雜性。但是這樣的抽象提供了無與倫比的靈活性,允許你覆寫幾乎任何系統的預設行為。

首先,讓我們寫一個簡單的插件來看看這個所謂的“配置檔案”長什麼樣。雖然我已經提供的現成的

​​代碼​​

,但是還是建議你自己建立這個插件,把整個流程走一遍有助于你的了解。

設定插件的目錄結構

我們将要建立一個Magento的子產品【譯者注: Magento的插件不叫plug-in,叫module,翻譯成子產品】。Magento的子產品由php和xml檔案組成,目的是擴充或者覆寫系統的行為,比如為訂單增加資料模型,更改一個類的方法,或者增加一個全新的功能。【譯者注:Magento自帶的那些功能也都是基于子產品的,比如使用者注冊,商品展示,結賬流程等等。Magento給我的感覺就是一切皆子產品,和Eclipse的插件體系結構有點像】

大多數Magento的系統子產品的結構和我們将要建構的插件的結構是一樣的。Magento的系統子產品在以下目錄

app/code/core/Mage

每一個子目錄都是一個單獨的子產品。這些子產品是由Magento官方開發的。我們安裝完Magento以後,所使用的功能就是來自這些子產品。我們自己建立的子產品應該放在如下目錄

app/code/local/Packagename

“Packagename”應該是一個唯一的字元串,用來辨別你的代碼。通常人們使用公司名字作為Packagename,比如

app/code/local/Microsoft

由于我在做我自己的Magento項目,我将使用我自己的域名“Alanstormdotcom”。然後,我們要建立以下目錄結構

app/code/local/Alanstormdotcom/Configviewer/Block

app/code/local/Alanstormdotcom/Configviewer/controllers

app/code/local/Alanstormdotcom/Configviewer/etc

app/code/local/Alanstormdotcom/Configviewer/Helper

app/code/local/Alanstormdotcom/Configviewer/Model

app/code/local/Alanstormdotcom/Configviewer/sql

你的插件并不一定需要包含以上所有的目錄,但是為了以後開發友善,我們還是在一開始就把目錄建立好。接下來我們要建立兩個檔案,一個是config.xml,放在etc目錄下面

app/code/local/Alanstormdotcom/Configviewer/etc/config.xml

檔案内容如下

第二個檔案需要在如下位置建立

app/etc/modules/Alanstormdotcom_Configviewer.xml

第二個檔案應該遵循如下命名規則“Packagename_Modulename.xml”,檔案内容如下

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

我們先不管這些檔案是幹什麼的,以後會解釋。建立好這兩個檔案以後,你的子產品的骨架就已經完成了。Magento已經知道你的子產品存在,但是現在你的子產品不會做任何事情。我們來确認一下Magento确實裝載了你的子產品

  1. 清空Magento緩存
  2. 在背景管理界面,進入 System->Configuration->Advanced
  3. 展開“Disable Modules Output”
  4. 确認“Alanstormdotcom_Configviewer”顯示出來了

如果你看到“Alanstormdotcom_Configviewer”,那麼恭喜你,你已經成功建立了你第一個Magento子產品!

建立子產品邏輯

我們之前建立的子產品不會做任何事情,下面我們來為這個子產品加入邏輯

1. 檢查“showConfig”查詢字元串是否存在

2. 如果“showConfig”存在,那麼檢查“showConfigFormat”查詢字元串是否存在

3. 如果“showConfigFormat”存在,那麼輸出指定格式的配置資訊,否則輸出預設格式的配置資訊

4. 終止執行流程

首先更改我們的config.xml檔案

<config> <modules>...</modules> <global> <events> <controller_front_init_routers> <observers> <alanstormdotcom_configviewer_model_observer> <type>singleton</type> <class>Alanstormdotcom_Configviewer_Model_Observer</class> <method>checkForConfigRequest</method> </alanstormdotcom_configviewer_model_observer> </observers> </controller_front_init_routers> </events> </global> </config>      

然後建立如下檔案

Alanstormdotcom/Configviewer/Model/Observer.php

輸入以下内容

<?php class Alanstormdotcom_Configviewer_Model_Observer { const FLAG_SHOW_CONFIG = 'showConfig'; const FLAG_SHOW_CONFIG_FORMAT = 'showConfigFormat'; private $request; public function checkForConfigRequest($observer) { $this->request = $observer->getEvent()->getData('front')->getRequest(); if($this->request->{self::FLAG_SHOW_CONFIG} === 'true'){ $this->setHeader(); $this->outputConfig(); } } private function setHeader() { $format = isset($this->request->{self::FLAG_SHOW_CONFIG_FORMAT}) ? $this->request->{self::FLAG_SHOW_CONFIG_FORMAT} : 'xml'; switch($format){ case 'text': header("Content-Type: text/plain"); break; default: header("Content-Type: text/xml"); } } private function outputConfig() { die(Mage::app()->getConfig()->getNode()->asXML()); } } ?>      

好了,代碼編輯結束。清空你的Magento緩存,輸入如下URL

​​http://magento.example.com/?showConfig=true​​ 【譯者注:根據文中的配置,不難看出任何指向Magento的URL加了“?showConfig=true”以後,都會輸出同樣的内容,正常的執行流程會被終止。】

配置檔案分析

打開上述URL,你應該看到一個巨大的XML檔案。這個檔案描述了目前Magento系統的狀态。它列出了所有的子產品,資料模型,類,事件,監聽器等等。舉個例子,如果你搜尋如下字元串

Configviewer_Model_Observer

你會發現剛剛你建立的那個類被列出來了。Magento會解析每個子產品的config.xml,并把它們包含在這個全局配置中。

這個配置檔案有啥用?

到目前為止,我們所作的事情似乎沒什麼意義,但是這個配置檔案卻是了解Magento的關鍵因素。你建立的每一個子產品都會被加到這個配置檔案中,任何時候,你需要調用一個系統功能的時候,Magento都會通過這個配置檔案來查詢相應的子產品和功能。舉個簡單的例子,如果你懂MVC的話,你應該和“helper class”之類概念的打過交道

$helper_salesrule = new Mage_SalesRule_Helper();

Magento抽象了PHP的類聲明方式。在Magento系統中,上面的代碼等同于

$helper_salesrule = Mage::helper('salesrule');

  1. 在配置檔案中查找<helpers />标簽
  2. 在<helpers />裡面查找 <salesrule />标簽
  3. 在<sales />裡面查找 <class />标簽
  4. 執行個體化從#3找到的類(Mage_SalesRule_Helper)