Discuz!官方免费开源建站系统

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

我很想做插件,可是Discuz的插件开发规则在哪?

[复制链接]
y98 发表于 2005-7-10 18:48:41 | 显示全部楼层 |阅读模式
我找了几天了,在Discuz的管方网站的相关论坛上,都找不到有关插件开发的说明,难道非得开发都化大量精力去分析原码后才能开工吗?Discuz的这种做法是在鼓励大家开发插件吗?
hehechuan 发表于 2005-7-13 09:52:35 | 显示全部楼层
这个是D4的插件文档,应该对2.5部分适用 :)


Discuz! 采用标准的开发方式,为外挂插件提供了一系列完善的支持,无论插件如何设计,数据结构如何,都不会影响到 Discuz! 自身的使用。自 3.1.2 版本起,我们开始采用了开放的插件接口,4.0.0 以后根据以往版本的经验及程序员和普通用户的反馈,对开放插件接口进行了一次全面升级,使得结构功能更加标准规范,同时可扩展性也得到了显著提高。

本文档主要对功能相对独立,使用单独程序方式的插件(即外挂型插件)的编写及接口设计作以说明,对于完全在 Discuz! 标准版本程序基础上修改的程序 Hack 不在此说明范围之列。

文件命名规范

Discuz! 按照如下的规范对程序进行命名:


可以直接通过浏览器访问的普通程序文件,以 .php 后缀命名。
被普通程序文件引用的程序文件,以 .inc.php 后缀命名。
被普通程序文件,或引用程序文件引用的函数库或类库,以 .func.php(函数库) 或 .class.php(类库) 后缀命名。
模板文件,以 .htm 后缀命名,模板文件只存在于 ./templates 目录中。
模板语言包文件,以 .lang.php 后缀命名,语言包文件只存放于 ./templates 目录中,与模板文件同级目录。
被编译后的模板文件,以 .tpl.php 后缀命名,前面的数字是模板套系的 ID,下划线后面的是模板原名,编译模板文件只存在于 ./forumdata/templates 目录中。
动态缓存文件,存放于 ./forumdata/cache 目录中,依据不同的功用进行独立的命名。
使用后台数据备份功能生成的备份文件,通常以 .sql 为后缀,存放于 ./forumdata/ 目录中。
有些目录中存在字节为 0 的 index.htm 文件,此类文件是为了避免 Web 服务器打开 Directory Index 时可能产生的安全问题。
common.inc.php 模块功能白皮书

include/common.inc.php 是 Discuz! 的通用初始化模块程序,其几乎被所有的外部代码所引用,在您开始对 Discuz! 进行二次开发之前,可以先对改模块的大致功能做一定的了解。common.inc.php 主要了以下任务:


对不同 PHP 及操作系统环境做了判断和兼容性处理,使得 Discuz! 可以运行于各种不同配置的服务器环境下。
初始化常量 IN_DISCUZ 为 TRUE,用于 include 或 require 后续程序的判断,避免其被非法引用。
读取论坛所在绝对路径,存放于常量 DISCUZ_ROOT 中。
加载所需的基本函数库 include/global.func.php。
通过 config.php 中提供的数据库账号信息,建立数据库连接。Discuz!支持数据表的前缀,如需获得表的全名,可使用”{$tablepre}tablename” 或 $tablepre.’tablename’的方式。
判断用户是否登录,如登录标记 $discuz_uid 为非 0,同时将 $discuz_user(加了 slash 的用户名,可用于不加修改的插入数据库)、 $discuz_userss(原始的用户名,可用于页面显示)、$discuz_pw(用户密码的MD5串)、$discuz_secques(登录提示问题的加密串)。
读入系统设置中的各种变量,并根据 Cache 模块的设定,根据当前被调用的程序文件名(如 index.php,forumdisplay.php 等等)读入相应的缓存代码。缓存代码被存放于 ./forumdata/cache/ 中。除了对应当前程序的缓存,可能还会加载一些通用的缓存数据,例如整个论坛的设置(./forumdata/cache/cache_settings.php)、界面风格(./forumdata/cache/style_x.php)、当前用户的用户组(./forumdata/cache/usergroup_x.php)、管理组权限(./forumdata/cache/adminusergroup_x.php)等。
缓存数据的格式,大多是存放在 $_DCACHE['cachename'] 数组中,有些常用的参数,如系统设置中的参数、风格界面等,通常还被进行了展开操作(extract)或使用常量进行赋值。
用户如果处在登录状态,会自动读出 members 表相关用户的参数值,用户的个性设置参数:如时差、时间格式、界面风格等等,会根据实际情况覆盖系统默认值,因此在后续程序通常不用再做判断。
如果程序提交的 URL 中包含 tid=x 或 fid=x,common.inc.php 模块会自动读出其所对应的论坛记录及包括 access masks、版主设定等相应权限,记录在 $forum 变量中。后续程序只要通过URL将tid或fid传递过来,便可通过 $forum 数组的存在性或相关参数来对论坛权限进行判断,不需要再读 forums 表的资料。
编写插件的原则与注意事项

在您动手编写插件之前,请仔细的阅读以下原则:


所有与插件的程序,包括其全部的前后台程序,请全部放入 ./plugins 目录中,同时在插件的安装说明中指出,插件的程序文件需要复制到 ./plugins 目录。
插件前台统一由 plugin.php?mod=xxx 的方式调用,xxx 为插件的前台名称。一个插件只可对应一个前台名称。其中调用外壳 plugin.php 功用是保证插件程序的基本工作位置在论坛目录下,避免兼容性和文件读写的权限问题。前台插件外壳程序 plugin.php 已经加载了通用初始化模块(./include/common.inc.php),不需再次引用。
插件后台统一由 admincp.php?mod=yyy 的方式调用,yyy 为插件的后台名称。一个插件可对应多个后台名称。其中调用外壳 admincp.php 功用如同前台插件调用外壳 plugin.php 一样,且同时具备了后台对管理人员的验证功能。插件中可直接写功能代码,不需再写验证程序。
一般情况下,插件需要在 config.inc.php 中加以设置,因此请插件作者在说明文档中,根据插件本身功能和设计,对如何修改 config.inc.php 及增加什么内容作以说明。
如果功能独立,请尽量使用单独程序的方式编写插件(即外挂型插件),这将给今后升级带来很大的方便。
您可以修改 Discuz! 本身的数据结构,但更推荐在不很影响效率的前提下将数据用另外的表存储,因为不能排除您增加的字段或索引和今后版本 Discuz! 冲突的可能(如重名)。
同时请请务必仔细阅读以下的注意事项:

请勿将插件程序放置在 ./plugins 以外的目录中。
请勿绕过插件的前后台外壳(plugin.php 和 admincp.php)而以直接调用某程序的方式编写插件,因为这样既造成了代码重复和插件的不规范,同时又产生了因验证程序考虑不周到带来的安全隐患。您可以在任何地方,包括表单、链接等处方便的使用 plugin.php?mod=xxx 的方式对插件程序进行调用。
所有与插件有关的程序,包括全部的前后台程序,因全部使用外壳调用,请务必在第一行加入
        if(!defined('IN_DISCUZ')) {
                exit('Access Denied');
        }


以免其被 URL 直接请求调用,产生安全问题。
在任何情况下,请不要删除 Discuz! 标准版本数据结构中已有的字段或索引。
插件接口参数与范例

在配置文件 config.inc.php 中包含了以下的内容,旨在用户通过替换该处的内容,实现对插件的配置:


        // [EN] Discuz! plugins configuration, User's Guide for further information
        // [CH] Discuz! 插件,配置和使用方法详情请参考使用说明书

                // Reserved position for plugins
                // 插件配置请在这里添加





以下是几个插件配置的例子,供参考:


        // [EN] Discuz! plugins configuration, User's Guide for further information
        // [CH] Discuz! 插件,配置和使用方法详情请参考使用说明书

        $plugins[] = array
        (
                'invisible'        => 0,
                'name'                => '插件A的名称',
                'dir'                => 'Dir_A/',
                'mod'                => 'Plugin_A_Module',
                'cpmods'                => array
                        (
                                array('name' => '插件A后台管理1', 'mod' => 'Plugin_A_Admin_Module_1'),
                                array('name' => '插件A后台管理2', 'mod' => 'Plugin_A_Admin_Module_2')
                        ),
                'include'        => 0,
                'adminid'        => 2,
                'tables'                => array('plugin_table_1', 'plugin_table_2'),
        );

        $plugins[] = array
        (
                'name'                => '插件B的名称',
                'mod'                => 'Plugin_B_Module',
                'cpmods'                => array
                        (
                                array('name' => '插件B后台管理', 'mod' => 'Plugin_B_Admin_Module')
                        )
        );

        $plugins[] = array
        (
                'name'        => '插件C的名称',
                'mod'         => 'Plugin_C_Module'
        );

        $plugins[] = array
        (
                'invisible'        => 1,
                'dir'                => 'Dir_D/',
                'mod'                 => 'Plugin_D_Module',
                'include'        => 1
        );




其中 $plugins 是个数组,其元素参数定义如下:


invisible:插件是否在前台不可见,1 为不可见,0 为可见。如果不设置此参数则默认为可见。
name:插件的名称,可以包含任意字符,如名称中有单引号出现,则将其变为 \'。
dir:插件程序(包括前台和后台)的路径,本设置为 ./plugins/ 下的相对路径,尾部必须以 "/" 结束,否则会产生错误。本参数可指定也可不指定,如果不指定,则默认插件的前后台程序均放置于 ./plugins/ 里。
mod:前台模块程序名,一个插件只能有一个前台模块程序名。可使用字母、数字、下划线、减号命名,不能包含其他符号或特殊字符。假设 mod为“abc”的插件,前台调用时的形式为 plugin.php?mod=abc。
cpmods:后台模块数组,一个插件可有 0 个或多个插件后台管理模块。该数组中,下标为 name 的为某管理模块的名字,mod 为该模块的程序名,命名规则和限制和“前台模块程序名”一样。假设后台 mod 为 abc_admin,后台调用时的形式为 admincp.php?action=plugin&pluginid=x&cpmodid=y。
include:引用开关,1 为是,0 为否。如果设置为 1,假设 mod(前台模块程序名)为“abc”,则在初始模块 ./include/common.inc.php 每次运行时,会自动包含并运行 ./plugins/abc.inc.php 这个程序(即名为 abc 扩展名为 .inc.php 的程序)。
adminid:后台模块权限限制,1 为只允许管理员管理,2 为允许管理员和超级版主管理,3 为允许管理员和所有版主管理。本限制仅在设置了 cpmods 时有效。如果不设置 adminid,默认为只允许管理员管理。
tables:插件涉及到的数据表,用于在备份功能中将插件的数据表一同备份。
在插件配置中,注意需要设置为数组的两个元素 cpmods 和 tables,要么留空,要么使用正确的数组来表示,不要赋以普通变量,以免出现问题。tables 参数的表名中切勿包含表名前缀,假设包含前缀的表名为 cdb_plugins(前缀 cdb_),插件配置中需使用 'plugins' 作表名。

在前面的例子中,共有四个插件设置,分别为:


第一个例子是较复杂的插件,全部文件放置于 ./plugins/Dir_A/ 中。包含前台(./plugins/Dir_A/Plugin_A_Module.php)、两个后台程序(./plugins/Plugin_A_Admin_Module_1.php 和 ./plugins/Plugin_Admin_Module_2.php)和一个通用模块(./plugins/Plugin_A_Module.inc.php)。同时后台需要制程序需要超级版主及以上的管理人员才能进入,插件使用了两个数据表 cdb_plugin_table_1 和 cdb_plugin_table_2(如果表名前缀是默认的“cdb_”的话);
第二个例子是规模比较常见的一种插件,其中包含前台(./plugins/Plugin_B_Module.php)和一个后台管理(./plugins/Plugin_B_Admin_Module)。
第三个例子则较为简单,只是包含一个前台的程序(./plugins/Plugin_C_Module.php),用户可以通过链接访问到它;
第四个例子仅是在所有论坛程序中包含了一个内嵌程序(./plugins/Plugin_D_Module.inc.php),没有前后台,也不可见。
调用插件的方式:


前台调用插件的方式比较简单,使用 plugin.php?mod=abc 的形式即可;
后台我们提供了两种方式,其一是如前所述的 admincp.php?action=plugin&pluginid=x&cpmodid=y 的形式,x 和 y 分别是 pluginid 和 cpmodid 的值,这两个值可通过 $pluginid 和 $cpmodid 直接取到,无需另行计算。我们同时提供了一个内置的变量 $purl,用于存放上述 URL。依据以上原则,您在表单中,可以这样写(链接同样道理):

        echo "<form method=\"post\" action=\"admincp.php?action=plugin&pluginid=$pluginid&cpmodid=$cpmodid\">;




也可以简便的写为如下的方式,作用是一样的:


        echo "<form method=\"post\" action=\"$purl\">;




我们为插件程序预留了一个扩展积分字段,即 members 表中的 extracredit,为整型有符号数。您可以使用该字段用于插件程序的写作,如扩展为金钱,威望等。

Discuz! 代码中对插件的处理

除了上面的说明,您还可以通过以下 Discuz! 中对插件数据进行处理的代码,更深入的了解插件的具体工作方式和过程。

./include/common.inc.php 中对插件数据的处理:


        echo "<form method=\"post\" action=\"$purl\">;




欢迎各位插件程序员继续为我们提出意见和建议,感谢您的支持。
回复

使用道具 举报

泡哥 发表于 2005-7-17 18:41:49 | 显示全部楼层
欣赏 学习!
回复

使用道具 举报

smallwl 发表于 2005-7-17 23:56:25 | 显示全部楼层
太多字,看着看着自己就晕了。
回复

使用道具 举报

PerfectWorks 发表于 2005-7-18 09:00:09 | 显示全部楼层
D4的啊,D25也差不多吗?
回复

使用道具 举报

ninelife 发表于 2005-7-18 23:21:57 | 显示全部楼层
看着就晕了^_^估计没人会打算详细看吧
回复

使用道具 举报

六仔 发表于 2005-7-20 17:53:21 | 显示全部楼层
各人有各人的规则,所以这里的插件乱得很。

你爱怎么写就怎么写。
回复

使用道具 举报

PerfectWorks 发表于 2005-7-26 12:16:46 | 显示全部楼层
我是看完啦~应该弄个discuz的全局变量表出来
回复

使用道具 举报

纳米 发表于 2005-7-30 21:37:52 | 显示全部楼层
Discuz!的插件接口不同Discuz!4的
回复

使用道具 举报

泡哥 发表于 2005-8-2 19:50:23 | 显示全部楼层
原帖由 文文の封印 于 2005-7-26 12:16 发表
我是看完啦~应该弄个discuz的全局变量表出来


呵呵 第一个要看懂的就是DZ怎么连接数据库的设置!!这就是开始、这个就是速度!全局变量不太重哟了!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Discuz! 官方站 ( 皖ICP备16010102号 )star

GMT+8, 2024-4-23 15:07 , Processed in 0.165559 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表