深入理解Magento
作者:Alan Storm
翻譯:Hailong Zhang
第一章 – 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
文件內容如下
- <config>
- <modules>
- <Alanstormdotcom_Configviewer>
- <version>0.1.0</version>
- </Alanstormdotcom_Configviewer>
- </modules>
- </config>
第二個文件需要在如下位置創建 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確實裝載了你的模塊
- 清空Magento緩存
- 在後臺管理界面,進入 System->Configuration->Advanced
- 展開“Disable Modules Output”
- 確認“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緩存,輸入如下URLhttp://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');
Magento將通過以下邏輯來處理這行代碼
- 在配置文件中查找<helpers />標籤
- 在<helpers />裏面查找 <salesrule />標籤
- 在<sales />裏面查找 <class />標籤
- 實例化從#3找到的類(Mage_SalesRule_Helper)
Magento總是通過配置文件來獲得類名,這個邏輯看起來有些複雜,但這樣做的優點也很明顯,我們可以不需要更改Magento的代碼就能更改 Magento的核心功能。【譯者注: 在這個例子中,我們可以通過修改配置文件用我們自己的SalesRule_Helper類來替換原來那個】這種高度抽象的編程方式在php中並不常見,但 是它可以讓你清晰的擴展或者替換系統的某一部分。