看了Maple-x的这篇贴子,深受启发,以前都是编写那种功能增强型的插件,将插件作为独立的文件存放。这几天,慢慢地按照贴子的步骤熟悉了一下开发的流程,发现不算难,但也碰到了一些问题,下面详细地说一下。
看到前面一些朋友对代码的质疑,我在编写的时候,综合了一下意见,进行了改进。
下面是apply.inc.php的代码:
- <?php
- if(!defined('IN_DISCUZ'))
- {
- exit('Access Deined');
- }
- //建议:在每个插件程序的开头加上上面的代码.这是为了防止禁止直接外部访问文件
- @include_once DISCUZ_ROOT.'./forumdata/cache/plugin_apply.php';
- /*
- 调用DISCUZ生成的插件参数的缓存文件.调用缓存文件以后,就可以调用里面的变量了.
- Discuz生成的插件参数的配置文件是保存在一个二维的数组里的。$_DPLUGIN[‘apply’][‘vars’];
- 这里我们为了美观,对这个二维数组进行一下简化
- */
- $applycount = $_DPLUGIN['apply']['vars']['applycount'];
- $lowestregdates = $_DPLUGIN['apply']['vars']['lowestregdates'];
- $integral = $_DPLUGIN['apply']['vars']['integral'];
- $extcredit = $_DPLUGIN['apply']['vars']['extcredit'];
- $lowestposts = $_DPLUGIN['apply']['vars']['lowestposts'];
- /*
- 这里需要强调的一点:
- Discuz是对提交过来的变量的值进行了转义,我们可以认为他过来的值就是一个字符串,那么在使用他的时候,要尽量放在一个不会解析变量的单引号内.这样无论是安全还是效率都会有所提高.尤其是在SQL语句中.一定要把变量放在单引号呢。例如
- $db->query("SELECT * FROM {$tablepre}members WHERE uid='$discuz_uid'");
- */
- @include_once DISCUZ_ROOT.'./forumdata/cache/plugin_apply.php';
- @include language('apply');
- if(!$discuz_uid) {
- showmessage('not_loggedin','logging.php?action=login');
- }
- $applys = $apply = '';
- $applylist = array();
- //注意:记得对变量初始化,这是一个好的习惯,也可以避免安全问题。
- $page = !ispage($page) ? 1 : $page;
- $start_limit = ($page - 1) * 10;
- if($action == 'apply') { //申请斑竹
- $query = $db->query("SELECT COUNT(appid) FROM {$tablepre}plugin_apply WHERE uid='$discuz_uid'"); //查看申请用户的申请次数
- $applys = $db->result($query,0); //$db->result($query,0)可以用来取得一个记录值
- if($applys >= $applycount) { //判断是否申请次数
- showmessage($language['applys_max'], 'plugin.php?identifier=apply&module=apply');
- } else {
- require_once DISCUZ_ROOT.'./include/forum.func.php'; //包含相关与论坛帖子相关的文件。这里因为下面的forumselect()函数需要用到
- require_once DISCUZ_ROOT.'./forumdata/cache/cache_forums.php';
- $forumselect = "<select name="fid">\n<option value=""> >请选择版块</option><option value=""> </option>".str_replace('%', '%%', forumselect()).'</select>'; //这里是生成下拉采单式的版块选择,你可以看看DZ的操作方式
- include_once DISCUZ_ROOT . './plugins/apply/apply/apply.php'; //到apply目录下用对应的程序来处理申请的过程
- }
- } elseif ($action == 'del') { //这里是删除用户申请的过程
- if(($discuz_uid == $uid || $adminid == 1) && $formhash == FORMHASH) { //只有用户和管理员才有权限删除
- $db->query("DELETE FROM {$tablepre}plugin_apply WHERE uid='$discuz_uid' AND fid='$fid'");
- showmessage($language['operate_success'], 'plugin.php?identifier=apply&module=apply');
- } else {
- showmessage($language['operate_invalid']);
- }
- } else {
- $action = "view";
- $query = $db->query("SELECT * FROM {$tablepre}plugin_apply LIMIT $start_limit,10"); //取得记录,并格式化时间
- while($apply = $db->fetch_array($query)) {
- $apply['dateline'] = gmdate("$dateformat $timeformat", $apply['dateline'] + $timeoffset * 3600);
- $applylist[] = $apply;
- }
- $query = $db->query("SELECT COUNT(*) FROM {$tablepre}plugin_apply"); //分页显示
- $applynum = $db->result($query,0);
- $multipage = multi($applynum, 10, $page, "plugin.php?identifier=apply&module=apply");
- include template('apply');
- }
- ?>
复制代码
代码改进的说明:(按照代码出现的顺序)
1.将cdb_用{$tablepre}来代替——这样具有更好的通用性,如果表前缀不一样,只要在建表的sql语句修改一下即可。(在apply.php的改进中也是如此)
2.增加了@include language('apply');语句——使用语言包来规定提示信息
3.将$applylist = '';改为$applylist = array();——虽然效果一样,但意义比较明了
4.在showmessage函数中,使用$language['applys_max']这样的语句来从语言包中导入提示信息,并且将原来语句中javascript:history.go(-1)实现返回上级的方式,改成直接在提示信息中包含“返回”字样,从而实现显示回到上一级的方式。(在apply.php的改进中也是如此)
5.对$action == 'del'这段处理代码,有比较多的疑惑:
$discuz_uid == $uid || $admin == 1 && $formhash == FORMHASH
说实话,这里$discuz_uid == $uid有点怪,没有体现它的用处,不过,到后面可以跟模板网页中的传值结合起来用,可以说这是一个加强保险的语句。
这个语句有问题,因为按照运算符的俦顺序它相当于:$discuz_uid == $uid || ($admin == 1 && $formhash == FORMHASH)应改为:($discuz_uid == $uid || $admin == 1) && $formhash == FORMHASH 比较符合逻辑。这个语句中$admin有问题,实际上应该是$adminid,$adminid为1时,该用户就是管理员,所以这里正确应该是:($discuz_uid == $uid || $adminid == 1) && $formhash == FORMHASH
另外,这里应该改进一下,因为从道理上来说管理员应该能删除其他人发的申请,但作为一个范例,为免过于复杂,还是保留原样。
6.$action = "view";——新增这个语句,是与模板结合使用的,意思是如果没有明确的$action动作,那么就将用户带到查看申请的页面。
接下来是apply.php的代码:
- <?php
- if(!defined('IN_DISCUZ')) {
- exit('ACCESS Diened');
- }
- $userinfo = '';
- $query = $db->query("SELECT posts,$extcredit,regdate FROM {$tablepre}members WHERE uid='$discuz_uid'");
- $userinfo = $db->fetch_array($query);
- $userinfo['regdate'] = $timestamp - $userinfo['regdate'];
- $userinfo['regdate'] = ceil($userinfo['regdate'] / (3600*24));
- if(submitcheck('forumsubmit')) {
- if($userinfo['regdate'] < $lowestregdates || $userinfo[$extcredit] < $integral || $userinfo['posts'] < $lowestposts) {
- showmessage($language['condition_invalid'],'plugin.php?identifier=apply&module=apply&action=apply');
- }
-
- $query = $db->query("SELECT name FROM {$tablepre}forums WHERE fid='$fid'");
- $fname = $db->result($query,0);
- if(empty($fname)){
- showmessage($language['forum_invalid']);
- } else {
- $query = $db->query("SELECT COUNT(*) FROM {$tablepre}plugin_apply WHERE uid='$discuz_uid' AND fid='$fid'");
- if($db->result($query,0)) {
- showmessage($language['forum_repeat']);
- }
- }
-
- if(empty($nettime)) {
- showmessage($language['nettime_invalid']);
- } else {
- $nettime = intval($nettime);
- }
-
- if(!empty($description) && strlen($description) >= 16) {
- $description = nl2br(dhtmlspecialchars($description));
- } else {
- showmessage($language['description_invalid']);
- }
-
- if(!(empty($suggest) && strlen($suggest) >= 16)) {
- $suggest = nl2br(dhtmlspecialchars($suggest));
- } else {
- showmessage($language['suggest_invalid']);
- }
- if (!isset($agreeapply)) {
- showmessage($language['$agreeapply_invalid']);
- }
- $db->query("INSERT INTO {$tablepre}plugin_apply (`uid`,`username`,`fid`,`fname`,`suggest`,`description`,`nettime`,`dateline`,`agreeapply`)
- VALUES ('$discuz_uid','$discuz_user','$fid','$fname','$suggest','$description','$nettime','$timestamp','$agreeapply')");
- showmessage($language['apply_success'],'plugin.php?identifier=apply&module=apply');
- }
- include template('apply');
- ?>
复制代码
代码改进的说明:(按照代码出现的顺序)
1.去掉$total的定义和如下两句代码:
$query = $db->query("SELECT count(uid) FROM cdb_plugin_apply WHERE uid='$discuz_uid'");
$total = $db->result($query,0);
从整个代码来看,这两句代码没什么用处,申请最大次数已经在apply.inc.php中处理了。
2.增加是否同意版主章程的判断($agreeapply)
从整个代码流程来看,觉得有些地方需要改进,列举如下:
1.判断该用户是否已经是所申请的版块的版主了
2.每页显示数目,版主章程(这个是我自己加的^-^)等都可以放到后台插件设置里
3.投票功能——对参加申请的会员进行投票选举。
4.一次同时申请多个版块
这个教程看起来还没有写完(没有看到adminapply这个模块的编写),看到前面有人要源码和相关文件,我就把我自己做出来(有相关的模板,建表的SQL语句和导出的discuz_plugin_apply.txt插件信息文件)的贡献给大家。这个做的还是比较一般,有不少需要改进的地方,望大家多多指教。
压缩包使用说明:
1.将整个apply文件夹拷贝到bbs目录下的plugins
2.apply\images目录下的图片拷贝到bbs目录下的images\common
3.apply\templates目录下的所有文件拷贝到bbs目录下的templates\default
4.在后台导入apply目录下的discuz_plugin_apply.txt文件,并更新缓存即可使用(如果要直接使用此插件就进行这个步骤)
插件下载及界面截图: |