PMS : Pixmicat! Module System
有關舊有的擴充套件的介紹請看這裡

本條目記錄 Pixmicat! Module System 的設計框架及說明。

系統結構

lib/pms.php (Pixmicat! Module System 主函式庫)
lib/lib_pms.php (PMS Dispatcher)
module/ (各類模組放置區)
└ mod_rss.php (模組檔案)

示意圖

pmc_structure

架構

類似 PIO, FileIO,會有一個物件 PMS 會被定義出來,這個物件主要存放各模組物件及相關控制方法。再者模組採事前載入方式,也就是 PMS 產生實體後,隨即依照模組載入設定列表載入必要的 PHP 程式並生成物件。此模組系統採巨核模式,也就是已經有一個巨大的核心在負責運作,其他模組僅利用模組系統提供的資源來做一些些事情。

模組系統需要引入掛載點 (或稱接口) 的概念,模組需要利用模組系統事先定義好的幾個方法來寫,而主系統要如何叫這些模組工作呢?當然就是增設幾個掛載點,讓模組掛於其上。一旦主程式需要使用時,先查看掛載點有無掛在其上的模組方法,如果有則將控制權給這些模組,讓這些模組工作 (改數值、印資料、遠端要求, etc),完成後再將控制權回歸主程式,達成目標。

而各個模組也許需要一個頁面來印出一些資料或運行若干程式碼,這時候也利用掛載點的概念,告知程式我這個模組需要一個獨立頁面。這時候主程式便可以以 ?mode=module&load=mod_XXX 來啟動模組的獨立頁面。

各模組的設定檔自行存放於 mod_xxx.php 內,不再另外統一成設定檔。而模組的載入列表存放在主程式 config 內,以陣列方式儲存。

// 模組載入
$ModuleList = array();
$ModuleList[] = 'mod_threadlist';
$ModuleList[] = 'mod_archiver';
$ModuleList[] = 'mod_rss';
$ModuleList[] = 'mod_captcha';

掛載點

掛載點就類似設計網頁使用 Script 的 onload, onclick, onmouseover 等事件機制一樣,設計師將自訂的函式掛在這些點上面,而當事件發生時系統會自動執行這些在掛載點上的函式。

為了讓模組系統能夠較為靈活而達成特定目標,需要大量的掛載點,讓模組可以自由撰寫特定的處理方法。

例如說有個掛載點叫做 Head,他可能是管理輸出頁面前的檔頭。處理好預設的檔頭後,模組系統開始查看掛載點,是否有其他模組方法要繼續實行?如果有,就把這個預設檔頭傳給模組方法,讓其自由修改。改完後再傳回來,最後印出。

目前 PMS 定義了若干掛載點,請參閱 PMS API 條目之 模組檔案 API -> 掛載點一覽 (非方法) 部分。

自動掛載機能

即模組方法名為 autoHook + 掛載點名稱,例如 autoHookHead() 這個方法在模組載入後即會自動掛載於 Head 掛載點。自動掛載在特定掛載點的方法只能有一個 (也就是 autoHook + 掛載點 這個限制),但是模組可以自己撰寫多個方法,而由自動掛載的方法來呼叫使用其他方法。

手動掛載

有自動當然也有手動,模組獨立頁面就沒有自動掛載機能,而只有手動掛載方法。方法是呼叫 $PMS->hookModuleMethod() 方法即可。詳細的使用方式請參見 PMS API 條目。底下的模組結構範例也展示了如何在建構元手動掛載獨立頁面。

在掛載點呼叫模組方法

到了適當的掛載點,主程式會呼叫模組出來工作。使用 $PMS->useModuleMethods() 方法來呼叫所有掛載於其上的模組方法,並將執行可能需要用到的資料傳給它們處理。

自訂掛載點

自訂掛載點 (Custom Hook Point, CHP) 為掛載點概念的延伸,能讓任何模組自行定義自己的掛載點。而其他模組就能透過將方法掛載此自訂掛載點上來強化此模組的功能,同時也達成了模組協同工作。

自訂掛載點依呼叫的方式不同可以分為兩種機制,一種是藉由自訂掛載點讓其他模組來強化,使自身模組更強,另一種則是藉由自訂掛載點分享自己模組的功能給其他模組使用,讓其他模組更強。

  • 藉由自訂掛載點讓其他模組來強化,使自身模組更強

假設有兩個模組 A, B,自訂掛載點 mod_A_hook1。模組 B 掛載於此自訂掛載點的作用是為了能夠強化模組 A。
模組 A 則呼叫自訂掛載點上的方法來得到強化。

範例: mod_bbbutton 提供 mod_bbbutton_addButtons 讓其他模組動態新增按鈕,使 mod_bbbutton 更強。

  • 藉由自訂掛載點分享自己模組的功能給其他模組使用,讓其他模組更強

剛好反過來。假設有兩個模組 A, B,自訂掛載點 mod_A_hook1。模組 A 利用此自訂掛載點分享方法給其他模組。
模組 B 則呼叫自訂掛載點上的方法來得到強化。

範例: mod_audit 提供 mod_audit_logcat 讓其他模組能夠利用它得以記錄稽核記錄,使其他模組更強。

目前自訂掛載點的名稱由各模組自行定義,但建議格式為 模組名稱 + 自訂名稱,例如 mod_test_hook1。

自訂掛載點的掛載和呼叫使用 $PMS->addCHP() 和 $PMS->callCHP() 兩個方法。

<?php
// 掛載 mod_b_hook1 的模組 a
class mod_a{
    function mod_a($PMS){
        if(method_exists($PMS,'addCHP')) {
            $PMS->addCHP('mod_b_hook1', array($this, 'add'));
        }
    }
    function getModuleName(){ return 'mod_a'; }
    function getModuleVersion(){ return '0.1'; }
 
    function add($txt){
        $txt .= 'Hello world';
    }
}
?>
 
<?php
// 建立 mod_b_hook1 的模組 b
class mod_b{
    private $PMS;
    function mod_b($PMS){
        $this->PMS = $PMS;
        $PMS->hookModuleMethod('ModulePage', __CLASS__);
    }
    function getModuleName(){ return 'mod_b'; }
    function getModuleVersion(){ return '0.1'; }
 
    function ModulePage(){
        $txt = '';
        $this->PMS->callCHP('mod_b_hook1', array(&$txt));
        // Now $txt will be append "Hello world"
    }
}
?>

系統提供方法

系統提供 getModulePageURL() 和 hookModuleMethod() 方法供使用,請參閱 PMS API 條目之 PMS API 模組設計者面部分。

模組結構

每個模組都是一個物件,以 class 定義,以下是範例:

<?php
class mod_dummy{
    private $PMS;
    function mod_dummy($PMS){
        $this->PMS = $PMS;
        $PMS->hookModuleMethod('ModulePage', __CLASS__); // 手動掛載 ModulePage
    }
 
    function getModuleName(){
        return 'mod_dummy : 展示掛載點功能模組';
    }
 
    function getModuleVersionInfo(){
        return '1.00';
    }
 
    function ModulePage(){
        echo "Welcome to my world.";
    }
 
    function autoHookToplink(&$link){
        $link .= '[<a href="'.$this->PMS->getModulePageURL(__CLASS__).'">統計</a>]'."\n";
    }
 
    function autoHookPostInfo(&$txt){
        $txt .= '<li>目前線上人數:102</li>'."\n";
    }
 
    function autoHookThreadFront(&$txt){
        $txt .= '<div style="text-align: center;"><a href="#">[AD] 這是廣告#01!</a></div>'."\n";
    }
 
    function autoHookThreadRear(&$txt){
        $txt .= '<div style="text-align: center;"><a href="#">[AD] 這是廣告#02!</a></div>'."\n";
    }
 
    function autoHookFoot(&$foot){
        $foot .= '<span class="warn_txt2">本網站由 雙貓聯合站 提供資源,謹此致謝</span>'."\n";
    }
}
?>

此範例大量運用自動掛載,於各式各樣的掛載點作了不同的工作。其中 getModuleName() 和 getModuleVersionInfo() 是模組內一定要有的方法

方法一覽

請參閱 PMS API 條目之模組檔案 API 部分。

討論

新增一則回應
登入為 Wikidot 使用者
(將不會發佈)
- +
除非特別註明,本頁內容採用以下授權方式: Creative Commons Attribution-Noncommercial-Share Alike 2.5 License.