大约半年多没碰康盛的东西了,年前在DZ7.2开发了几个插件,我们这边的开发任务就停止了,现在又有项目需要做dzx2.5的开发,于是开始搞特殊主题。
尼玛我参照开发手册写的开始开发,结果就是在论坛的设置处可以看到自定义的特殊主题,发帖的时候却没有这个选项。蛋疼。断断续续折腾了两天,蛋疼,直接翻DZ相关源码,终于找到问题所在:尼玛。。。弄个特殊主题光在论坛设置里面设置还不够,还特么要在用户组给用户使用这个特殊主题的权限。。。
0×1这特么是怎么个情况?
断断续续两天时间,太纠结了。找了个不靠谱的人问了问,毛也没给解决,这些事还是得自力更生。反复测试了很久也没找到问题,索性直接翻DZ相关源码。
入口看URL:http://dzx/forum.php?mod=post&action=newthread&specialextra=dabing&fid=2&cedit=yes&extra=,这里以随便找了个安装了特殊主题的插件为例。
首先看forum.php,最后一句required了mod,如下- require DISCUZ_ROOT.'./source/module/forum/forum_'.$mod.'.php';
复制代码 mod=post,于是找source/module/forum/forum_post.php。
连个注释也没有,这特么蛋疼,在看action=newthread,直接搜newthread。
在347行找到了newthread的具体处理流程。首先加载缓存处理数据什么的,然后用了libfile函数。- /**
- *
- * @param string $libname lib的名字,依靠是否有/来判断引用路径
- * @param string $folder 指定引用的二级目录,默认没有
- * @return Ambi**s <boolean, string> 如果路径正确则返回包含文件位置,否则返回false
- */
- function libfile($libname, $folder = '') {
- $libpath = '/source/'.$folder;
- //处理引用的位置
- if(strstr($libname, '/')) {
- list($pre, $name) = explode('/', $libname);
- $path = "{$libpath}/{$pre}/{$pre}_{$name}";
- } else {
- $path = "{$libpath}/{$libname}";
- }
- //判断是否是合法引用
- return preg_match('/^[\w\d\/_]+$/i', $path) ? realpath(DISCUZ_ROOT.$path.'.php') : false;
- }
复制代码 根据提交的参数libfile(‘post/newthread’, ‘include’);,打开source/include/post/post_newthread.php。- ....
- //从第84行开始
- } elseif($specialextra) {
- //开始调用特殊主题
- $threadpluginclass = null;
- if(isset($_G['setting']['threadplugins'][$specialextra]['module'])) {
- //module是特殊主题的类名,就是在模块-特殊主题-名字的地方填写的,这里是preview
- $threadpluginfile = DISCUZ_ROOT.'./source/plugin/'.$_G['setting']['threadplugins'][$specialextra]['module'].'.class.php';
- //可以直接echo出来看看:F:\PHP_Work\DZX\./source/plugin/dabing/preview.class.php
- echo DISCUZ_ROOT.'./source/plugin/'.$_G['setting']['threadplugins'][$specialextra]['module'].'.class.php';
- //开始引用
- if(file_exists($threadpluginfile)) {
- @include_once $threadpluginfile;
- $classname = 'threadplugin_'.$specialextra;//$specialextra这个?应该返回去搜索了。这里是插件的ID
- //在文件存在,类存在,方法存在的情况下,就开始调用该类的newthread方法了。
- if(class_exists($classname) && method_exists($threadpluginclass = new $classname, 'newthread')) {
- $threadplughtml = $threadpluginclass->newthread($_G['fid']);
- $buttontext = lang('plugin/'.$specialextra, $threadpluginclass->buttontext);
- $iconfile = $threadpluginclass->iconfile;
- $ic**flip = array_flip($_G['cache']['ic**']);
- $thread['iconid'] = $ic**flip[$iconfile];
- }
- }
- }
复制代码 顿时觉得特殊主题的逻辑和实现其实超级简单,呵呵。
然后切换成我们的主题,发现就是不显示,哪怕你手动指定了specialextra也会跳转到发表普通帖子的页面。
于是回到forum_post.php,肯定对specialextra参数进行了处理。
在第236行让我吃了一惊,亲,听说过圈复杂度么。。。。莫不是发行版本是经过压缩优化过的?尼玛啊。。
- if($specialextra && $_G['group']['allowpost'] && $_G['setting']['threadplugins'] &&
- (!array_key_exists($specialextra, $_G['setting']['threadplugins']) ||
- !@in_array($specialextra, is_array($_G['forum']['threadplugin']) ? $_G['forum']['threadplugin'] : dunserialize($_G['forum']['threadplugin'])) ||
- !@in_array($specialextra, $_G['group']['allowthreadplugin']))) {
- $specialextra = '';
- }
复制代码 $specialextra:dabing,非空值,true。
$_G['group']['allowpost']:1,看名字应该是组权限允许发帖),true。
$_G['setting']['threadplugins']:Array,非空,打印出来是所有的特殊主题的数组,表明存在特殊主题,true。
!array_key_exists($specialextra, $_G['setting']['threadplugins']):判断URL输入的特殊主题ID是否真的存在,存在取反,为false。
三目运算符:is_array($_G['forum']['threadplugin']) ? $_G['forum']['threadplugin'] : dunserialize($_G['forum']['threadplugin'])) :判断该论坛的允许使用的特殊主题列表的保存形式,如果是数组则不变,如果是序列化果断反序列化之,返回数组。这里本来就是数组,无所谓。
!@in_array($specialextra, $_G['forum']['threadplugin']):这个特殊主题是否在这个论坛中允许使用,这个在论坛的帖子相关设置过,存在取反为false。
!@in_array($specialextra, $_G['group']['allowthreadplugin']):问题出现了,尼玛这个 $_G['group']['allowthreadplugin']没有刚才自己写的插件的ID,看名字应该是组允许使用的特殊主题列表,这里是false,取反为true。
则以上为- if(true && true && true && (false || false || true)) {
- $specialextra = '';
- }
复制代码 最终为true,于是$specialextra被赋空值了。
根据名字猜测是用户组/管理组权限问题,马上翻后台去看看,果然有这个选项。。。蛋疼。。。看来做DZ二次开发,要同时配备开发手册和使用手册。。。
到此为止找到原因,突然觉得特殊主题的逻辑好简单:)是否可以山寨一个呢亲?
呵呵,问题很好解决,关键是又复习了~
作者:疯狂的大饼
Discuz!X2.5特殊主题简单开发教程
|