ZBlog外掛開發檔案結構(外掛)

黄文Rex發表於2024-08-25

以下基於透過「建立應用」生成的初始檔案:

/path/zb_users/plugin/demoPlugin
│  logo.png       [必需]圖示,128x128;
│  plugin.xml     [必需]自述檔案;
│  main.php       [可選]應用內建管理頁,在建立外掛時填寫才會生成;
│  include.php    [可選]應用嵌入頁,在建立外掛時填寫才會生成;

自動建立的檔案最多隻有上邊四個,可依據需要自行建立需要的資料夾及檔案:

│  function.php   [可選]根目錄下除了這個外不建議放置額外的「*.PHP」檔案;
│                      「function.php」放不下的,可以拆分後放置到「function」資料夾;
├─class           [可選]放置 class 定義檔案,;
├─css             [可選]CSS 樣式檔案,前後臺儘量分開;
├─script          [可選]JS 指令碼目錄,前後臺儘量分開;
└─other           [可選]其他任意自定義資料夾及內容

Hello Z-Blog

  1. 使用demoPlugin為「應用 ID」建立一個應用,
    • 「應用名稱」填寫「第一個外掛」;
    • 其他資訊保持預設;
  2. 不需要額外建立檔案
  3. 使用下邊程式碼「覆蓋」「include.php」的內容;
    • 可直接點選「Copy to clipboard」按鈕複製;
  4. 「啟用外掛」後瀏覽任意「前臺頁面」即可檢視效果;
<?php
// 如果有其他 PHP 檔案可以在這裡引入,或者在需要的地方「按需要引入」
// require __DIR__ . "function.php";
// require __DIR__ . "class/db.php";
# 註冊外掛
RegisterPlugin("demoPlugin", "ActivePlugin_demoPlugin");
// 註冊介面函式
function ActivePlugin_demoPlugin()
{
  // 向名為'Filter_Plugin_Index_Begin'的介面註冊函式
  Add_Filter_Plugin('Filter_Plugin_Index_Begin', 'demoPlugin_HelloZBlog');
}
// 介面函式定義
function demoPlugin_HelloZBlog()
{
  // 注意,在函式中使用變數 $zbp 前應進行全域性宣告
  global $zbp;
  // 向前臺頁面的 <head></head> 內部插入內容
  $zbp->header .= "<script>alert(\"hello {$zbp->user->Name}\")</script>";
  // 讀取外掛配置項
  $InstallTime = $zbp->Config('demoPlugin')->InstallTime;
  $zbp->header .= "<script>alert(\"「demoPlugin」外掛首次啟用時間為 {$InstallTime}\")</script>";
}
// 外掛啟用時呼叫
function InstallPlugin_demoPlugin()
{
  global $zbp;
  $InstallTime = date('Y-m-d H:i:s');
  // 判斷配置項是否存在
  // $zbp->HasConfig('外掛ID'); //return bool
  if (!$zbp->HasConfig('demoPlugin')) {
    $zbp->Config('demoPlugin')->version = 1;
    $zbp->Config('demoPlugin')->InstallTime = $InstallTime;
    $zbp->SaveConfig('demoPlugin');
  }
}
// 外掛關閉時呼叫
function UninstallPlugin_demoPlugin()
{
  global $zbp;
  // 存在相應開關選項並且狀態為開啟時,刪除當前外掛配置
  // $zbp->Config('外掛ID')->HasKey('配置名'); //return bool
  if ($zbp->Config('demoPlugin')->HasKey('DelConfig') && 
       $zbp->Config('demoPlugin')->DelConfig == 1) {
    $zbp->DelConfig('demoPlugin');
  }
}

註冊及介面掛載

Z-BlogPHP 系統的外掛是採用主動插入方式來通知系統。所以必須在「include.php」檔案中呼叫RegisterPlugin函式才能讓外掛進入系統的外掛體系。

// 註冊外掛
RegisterPlugin("外掛ID","ActivePlugin_外掛ID");

然後在ActivePlugin_外掛ID中完成「大部分」介面的掛載;

// 具體的介面掛接
function ActivePlugin_外掛ID() {
  Add_Filter_Plugin('API名稱','執行程式碼(函式)');
}

注:可按需在掛載介面前進行判斷;也可在介面 A 內部掛載介面 B。

「啟用 / 停止 / 更新」外掛時執行

可按如下示例定義函式,將在外掛執行對應操作時自動呼叫;

function InstallPlugin_外掛ID(){}
function UninstallPlugin_外掛ID(){}
function UpdatePlugin_外掛ID(){}
// 舊版相容
function 外掛ID_Updated(){UpdatePlugin_外掛ID();}

外掛狀態判斷

// 外掛未啟用直接退出本頁面(一般用於配置頁面)
if (!$zbp->CheckPlugin('外掛ID')) {$zbp->ShowError(48);die();}

使用者許可權判斷

在預設生成的main.php中,除了上邊的$zbp->CheckPlugin()呼叫外,還有如下判斷使用者許可權的指令:

// `root` 既管理員許可權
$action='root';
if (!$zbp->CheckRights($action)) {$zbp->ShowError(6);die();}

$zbp->CheckRights()用於判斷「當前使用者」(包括遊客)是否有權執行傳入引數代表的某項操作,可配合「使用者等級」對許可權進行細化管理;

可以透過 -host-/zb_system/cmd.php?act=misc&type=vrs檢視當前使用者擁有的許可權;

可針對使用者等級靈活制定其許可權;「Z-Blog 角色分配器 - Z-Blog 應用中心」

參考「使用者等級劃定」;

外掛配置資料存取

「Hello Z-Blog」中已有相應用例,以下為逐條講解;

「配置項」的「值」可以是數字字串陣列;對於PHP 物件,理論上需要能夠被序列化,實際使用中建議轉為JSON儲存;

1、設定並儲存配置選項

$zbp->Config('外掛ID')->配置名 = 值;
$zbp->SaveConfig('外掛ID');

2、讀取配置選項

$s = $zbp->Config('外掛ID')->配置名;
echo $s;

3、判斷配置選項是否已建立

$zbp->HasConfig('外掛ID'); //return bool

4、判斷配置選項某一鍵值是否存在

$zbp->Config('外掛ID')->HasKey('配置名'); //return bool

5、刪除某一配置

$zbp->Config('外掛ID')->DelKey('配置名');
$zbp->SaveConfig('外掛ID');

6、刪除配置

停用外掛時可以選擇刪除配置項,通常我們建議保留配置以備下次重新啟用,或者提供專門的開關選項由使用者確認刪除;

$zbp->DelConfig('外掛ID');

CSRF 相關 「重要

對於需要使用者點連結或提交表單觸發,進而對資料或檔案產生影響的,除必要的使用者許可權驗證外,應另外加入 CSRF Token 驗證;

透過 GET 方法提交,如果您的目標地址是 cmd.php,那麼您可以使用以下函式:

<?php echo BuildSafeCmdURL('act=TagPst'); ?>

如果不是,那麼您也可以直接:

<?php echo BuildSafeURL('main.php'); ?>

透過 POST 方法提交,您可以在 form 表單內加入

<input type="hidden" name="csrfToken" value="<?php echo $zbp->GetCSRFToken();?>">

對於應用內的,比如儲存配置項,上傳檔案等操作中,可使用CheckIsRefererValid();進行驗證;

if (count($_POST) > 0) {
  CheckIsRefererValid();
  // 你的程式碼,以下為示例
  // 配置項儲存 ↓
  foreach ($_POST as $key => $value) {
    $zbp->Config("demoPlugin")->$key = $value;
  }
  $zbp->SaveConfig("demoPlugin");
  // 結束
  $zbp->SetHint('good');
  Redirect('./main.php');
}

注:對於舊版本 Z-Blog PHP,可能需要先判斷:if (function_exists('CheckIsRefererValid')) {CheckIsRefererValid();}

相關文章