天天看點

magento 開發 -- 深入了解Magento第七章 – 自定義Magento系統配置

magento擁有十分強大的背景管理系統。作為一名開發人員,這套背景管理系統可以讓你的使用者簡單直接的配置magento系統或者你建立的子產品。和magento的其他功能一樣,你第一次使用這套管理系統的時候可能覺得很麻煩,但是一旦你上手了,你會發現它強大的功能是那麼吸引人。那麼讓我們開始吧。我們這一章的例子依然是基于helloworld子產品。

首先我們要為子產品添加一個系統配置檔案。這個檔案和“config.xml”是不搭界的

app/code/local/zhlmmc/helloworld/etc/system.xml

和全局配置(global config)相似,系統配置也是單獨存儲的。我們可以通過下面這段代碼來擷取系統配置檔案

//header('content-type: text/xml');         

header('content-type: text/plain');         

echo $config = mage::getconfig()

->loadmodulesconfiguration('system.xml')        

->getnode()

->asxml();          

exit;

你可以把這段代碼放到任何執行函數(action method)中。“loadmodulesconfiguration”方法會搜尋所有配置好的子產品的“etc”檔案夾,尋找以傳入的參數為名字的檔案,在這個例子中是“system.xml”。magento有很多不同的配置檔案,比如api.xml, wsdl.xml, wsdl2.xml, convert.xml, compilation.xml, install.xml。你可以為你建立的子產品建立這些配置檔案。

我們首先在背景系統管理頁面添加一個标簽頁(tab)。标簽頁就是背景“system->configuration”頁面左側的導航欄。預設的标簽頁有general,catalog,customers,sales,services等等。我們來建立一個新的标簽頁叫做“hello config”。建立如下檔案

location: app/code/local/zhlmmc/helloworld/etc/system.xml

<config>

    <tabs>

        <helloconfig translate="label" module="helloworld">

            <label>hello config</label>

            <sort_order>99999</sort_order>

        </helloconfig>

    </tabs> 

</config>

我們來解釋一下各個節點(tag)的意思。【譯者注:由于tab和tag中文翻譯都是标簽,是以這裡我把tag翻譯成節點,以免混淆】“<helloconfig>”就是我們要添加的标簽頁的定義節點,“helloconfig”是節點的id。你可以任意命名這個id,但是必須全局唯一,也就是不能和别人用同樣的id。這個id是用來唯一标示你的标簽頁的。“module=helloworld”,意思是這個标簽頁屬于哪個子產品。“<label>”節點的内容是标簽的名字,也就是要顯示在界面上的名字。“<sort_order>”指明了這個标簽頁顯示的位置。

打開背景“system->configuration”,你會看到如下錯誤

fatal error: class 'mage_helloworld_helper_data' not found in….

正如許多其他的php mvc系統一樣,magento也有幫助類(helper classes)。這些類用來提供一些不适合放在模型,視圖或者控制器中的功能。magento的幫助類也是采用分組類名的機制。也就是說我們可以覆寫預設的幫助類,同時我們需要在config.xml中指定幫助類的基類名。

magento系統預設子產品有一個預設的幫助類。正如我們上面的異常顯示,我們的helloworld子產品并沒有指定一個預設的幫助類。下面讓我們來添加一個。修改config.xml

file: app/code/local/zhlmmc/helloworld/etc/config.xml

<!– … –>

<global>

    <!– … –>

    <helpers>

        <helloworld>

            <class>zhlmmc_helloworld_helper</class>

        </helloworld>

    </helpers>

</global>

你現在應該對這類配置相當熟悉了。“<helloworld>”節點就是子產品的名字,“<class>”就是幫助類的基類名,命名方式如下

packagename_modulename_helper

幫助類是通過全局對象mage的靜态方法“helper”來裝載的。

mage::helper('helloworld/foo')

根據我們的配置,上面這行代碼将會裝載以下類

app/code/local/zhlmmc/helper/foo.php

class zhlmmc_helloworld_helper_foo

我們上面說過magento預設每個子產品有一個幫助類“data”

mage::helper('helloworld');

mage::helper('helloworld/data');

上面這兩行代碼是等價的,都會裝載以下類

app/code/local/zhlmmc/helper/data.php

class zhlmmc_helloworld_helper_data

下面我們來建立我們的幫助類

file: app/code/local/zhlmmc/helper/data.php

class zhlmmc_helloworld_helper_data extends mage_core_helper_abstract

{

清空magento緩存,重新裝載頁面,你會發現錯誤不見了,但是我們的标簽頁還是沒有出來。如果你好奇幫助類究竟能幹什麼,建議你去看看“mage_core_helper_abstract”類。

好了,幫助類的介紹到此結束。下面我們來看看為什麼我們的标簽頁不顯示出來。在magento中,每一個标簽頁都包含很多段(section)。舉個例子,“advanced”标簽頁預設包含“admin, system, advanced, developer”四個段。如果一個标簽頁不包含任何段,那麼這個标簽頁不會被顯示出來。下面我們在system.xml中添加“<section>”節點

    <sections>

        <helloworld_options translate="label" module="helloworld">

            <label>hello world config options</label>

            <tab>helloconfig</tab>

            <frontend_type>text</frontend_type>

            <sort_order>1000</sort_order>

            <show_in_default>1</show_in_default>

            <show_in_website>1</show_in_website>

            <show_in_store>1</show_in_store>                    

        </helloworld_options>

    </sections>     

這裡有些節點你應該很熟悉,就不多解釋了,來講講以前沒見過的。

和前面的<hellowconfig>相似,這個節點是用來唯一标示你的段,“helloworld_options”就是段的id,可以随意取名,隻要不重複就好。

這個節點有點搞。“<frontend_type />”在配置檔案的其他部分有用(稍後會講),放在這裡其實沒什麼作用。但是核心子產品在此處的配置檔案都包含這個節點,是以我們也把它添加進去。

這些節點的值是布爾類型的,0或者1。這些标簽是用來控制在不同的環境下,目前段是否應該顯示。

好了,我們已經配置好段了,清空緩存,再一次重新整理頁面,你應該看到“hello config”标簽頁顯示出來了。

如果你剛才點了我們建立的标簽頁下面的“hello world config options”,你大概會很失望。什麼都沒有顯示出來,連左邊的導航欄都沒有了。這是因為“adminhtml”在權限控制清單(access control list, acl)中找不到我們建立的段的權限資訊。【譯者注:adminhtml就是magento的背景管理系統,屬于magento的一個核心子產品】

acl是一個很複雜的話題,但是我會介紹一些最基本的概念,以便于了解magento的權限控制。這部分内容和上下文關系不大,如果你不感興趣,可以直接跳到本節結尾,複制一段xml到你的config.xml就行了。

在magento中,對于有些資源的通路時有限制的。使用者必須先經過認證才能通路相關資源。在這裡,資源(resource)是一個廣義的概念,它可能是指一個頁面,也可能是一個功能。magento的系統配置功能(system config)就是需要認證才能通路的資源。

任何一個資源都是通過一個uri來辨別。比如說“web”配置段(屬于背景管理general标簽頁)的uri是

admin/system/config/web

我們“helloworld_options”段的uri是

admin/system/config/helloworld_options

當一個使用者通路一個受保護的資源的時候,背景管理系統(adminhtml)的執行控制器會執行以下步驟

為使用者正在通路的資源生成一個uri

根據acl系統檢查該使用者是否有權限通路指定的資源

如果使用者擁有通路權限,那麼進行使用者指定的操作。否則,跳轉到相應的錯誤頁面(也可能是停止操作或者顯示空白頁面)。

如果你去“system -> permissions -> roles”頁面,點選“add new role”按鈕,你會看到所有系統的資源都以樹形結構顯示在頁面上。

剛才說acl中沒有我們配置段的資訊,那麼我們來建立一個。請注意,如果你是建立一個新的段,那麼你需要建立一個新的權限,如果你在已有的段上添加内容,你不需要建立權限。

在config.xml中,添加以下内容

file: app/code/local/zhlmmc/helloworld/etc/config.xml  

<config>    

    <adminhtml>

        <acl>

            <resources>

                <admin>

                    <children>

                        <system>

                            <children>

                                <config>

                                    <children>

                                        <helloworld_options>

                                            <title>store hello world module section</title>

                                        </helloworld_options>

                                    </children>

                                </config>

                            </children>

                        </system>

                    </children>

                </admin>

            </resources>

        </acl>

    </adminhtml>

讓我們來分析一下這段代碼。所有的資源定義都包含在如下代碼中

<adminhtml>

    <acl>

        <resources>

        </resource>

    </acl>

</adminhtml>

在<resources>節點下面,每一個子節點都是uri的一部分,比如

<admin>

    <children>

        <system>

            <children>

代表uri

admin/system

最後一個節點

<helloworld_options>

    <title>store hello world module section</title>

</helloworld_options>

這裡<title>的内容将會在背景權限管理的時候顯示出來,也就是我們定義的權限的名字。

清空magento緩存,重新整理頁面,你應該能看到我們建立的配置段了,标準的背景管理頁面,但是主體内容是空的,隻有一個“save config”按鈕。你可能需要重新登入背景管理才能看到正确的頁面。那是因為背景管理有一些額外的緩存。【譯者注:我們添加了權限以後,管理者是預設擁有該權限的,是以我們用管理者登入背景管理系統就能通路我們建立的段】

請注意,不懂事出于什麼原因,magento把<adminhtml />部分從全局配置中删掉了。是以,我們不能用之前建立的configviewer來檢視這部分内容。我正在研究magento把<adminhtml />存在哪裡了。

【譯者注:按照邏輯,這裡應該講的内容是添加選項。mageto中,選項是按照組(group)來劃分的,是以我們在添加選項之前得先添加組。】修改system.xml

            <show_in_store>1</show_in_store>

            <groups>

                <messages translate="label">

                    <label>demo of config fields</label>

                    <frontend_type>text</frontend_type>

                    <sort_order>1</sort_order>

                    <show_in_default>1</show_in_default>

                    <show_in_website>1</show_in_website>

                    <show_in_store>1</show_in_store>

                </messages>

            </groups>

這裡也沒什麼好解釋的。重新整理一下頁面看看你就什麼都明白了。

最後,我們要添加每一個單獨的配置選項。配置選項是以<fields />節點的形式添加到<messages />節點下面的。

<messages translate="label">

    <label>demo of config fields</label>

    <frontend_type>text</frontend_type>

    <sort_order>1</sort_order>

    <show_in_default>1</show_in_default>

    <show_in_website>1</show_in_website>

    <show_in_store>1</show_in_store>

    <fields>

        <hello_message>

            <label>message</label>

            <sort_order>1</sort_order>

        </hello_message>

    </fields>

</messages>

這裡有一個節點需要說明,“<frontend_type>”,剛才說這個節點沒什麼用。但是這裡有用了,這個節點說明了這個選項的資料類型。你可以把它換成别的類型,比如“time”。這裡支援大部分預設的varien定義的資料類型(lib/varien/data/form/element)。這個有點像是工廠(factory)設計模式。讓我們把類型改成“select”。你會看到一個下拉框,但是沒有選項。我們來添加選項。首先我們要添加一個源模型(source model)

<hello_message>

    <label>message</label>

    <frontend_type>select</frontend_type>

    <!– adding a source model –>

    <source_model>helloworld/words</source_model>                           

    <show_in_store>1</show_in_store>                    

</hello_message>

“<source_model>”定義了源模型的uri。和我們以前建立的模型一樣,源模型也是一個模型,為“select”提供了預設的資料。我想我不說你也明白,根據這裡的uri定義,我們要建立以下檔案

file: app/code/local/zhlmmc/helloworld/model/words.php

class zhlmmc_helloworld_model_words

    public function tooptionarray()

    {

        return array(

            array('value'=>1, 'label'=>mage::helper('helloworld')->__('hello')),

            array('value'=>2, 'label'=>mage::helper('helloworld')->__('goodbye')),

            array('value'=>3, 'label'=>mage::helper('helloworld')->__('yes')),

            array('value'=>4, 'label'=>mage::helper('helloworld')->__('no')),

        );

    }

}

源模型提供了一個方法“tooptionsarray”,傳回的資料時用來填充我們之前定義的配置選項的。這個方法在運作時會被“initfields”調用。“initfields”在以下類中定義

app/code/core/mage/adminhtml/block/system/config/form.php

我們這裡調用了幫助類的翻譯函數(__)來擷取資料。雖然不是很必要,但調用翻譯函數總是一個好習慣。說不定哪天你要将子產品翻譯成日文呢。【譯者注:值得注意的是我們這裡建立的模型不需要繼承任何父類,隻需要擁有“tooptionarray”方法就可以了。我覺得這個很不科學,起碼要繼承一個接口吧】

除了建立一個标簽頁,或者配置段,你也可以利用已有的标簽頁和配置段,向裡面添加内容。比如我們添加以下代碼到system.xml

file: app/code/local/zhlmmc/helloworld/etc/system.xml

        <!– … –>

        <general>

                <example>

                    <label>example of adding a group</label>

                    <show_in_store>1</show_in_store>                    

                </example>

        </general>

    </section>

重新整理頁面,你會在“general”标簽頁下面看到一個新的組,叫做“example of adding a group”。

到目前為止,我們隻是講了如何設定magento,可以讓使用者可以配置我們的子產品。現在讓我們來看看如何擷取使用者的配置資料。

mage::getstoreconfig('helloworld_options/messages/hello_message');

上面這行代碼就可以擷取我們上面配置的那個“select”選項的資料。這個函數的參數是我們要擷取的資料的uri,格式如下

section_name/group_name/field_name

你也可以通過以下代碼來擷取一個組或者段的所有值

mage::getstoreconfig('helloworld_options/messages');

mage::getstoreconfig('helloworld_options');

最後,如果你想擷取針對某個特定店面(store)的資料,你可以傳入store id

mage::getstoreconfig('helloworld_options',1);

這一章我們講了如何在magento的背景管理中添加個性化的配置。我們也順便介紹了幫助類的使用和acl基礎。這裡最重要的内容是背景配置的層級結構,标簽頁包含了配置段,配置段包含了組,組包含了配置選項。我們将在以後的章節中介紹系統配置的進階内容,包括自定義格式,資料驗證等等。

源文:http://www.zhlmmc.com/?p=674