Discuz教程网

[二次开发] DISCUZX/DISCUZ 模组挂载系统

[复制链接]
authicon dly 发表于 2012-6-23 18:31:03 | 显示全部楼层 |阅读模式
发布一个DISCUZX模组挂载系统…
通过这个挂载系统 可以让我们在外部”手术刀”得方式 以最小改动源程序进行修改功能得目的

class Module {        /* 模组挂载系统 */        public $Module = Array();        //记录实例        public $ModuleCallnum = Array();        //记录需要call次数        public $ModuleCallnumed = Array();        //记录需要已经call次数        public $ModuleMethodClist = Array();        public $ModuleReturnClist = Array();        //记录模组有return得 检查        public $ModulePointlist = Array();        //所有被CALL数组        public $Pointlist = Array();        //全局嵌入点列表        public $FuncPointlist = Array();        //函数嵌入点列表        public $ClassPointlist = Array();        //类嵌入点列表        public $Returns = Array();                public function Module(){                GLOBAL $Module;                $Module = Array();                $this->Module = & $Module;        }        public function ModuleAdd($modname_point, $function = '' ,$class = '') {                if(strpos($modname_point,'/')){                        @list($modname,$args0,$args1,$args2) = explode('/',$modname_point);                        if($args2){                                $class = $args0;                                $function=$args1;                                $point = $args2;                        }elseif($args1){                                $function=$args0;                                $point = $args1;                        }else{                                $point = $args0;                        }                }else{                        echo 'Notice: Module: '.$modname_point.'.Point Missing';                        return false;                }                if(!isset($this->Module[$modname])){                        $this->ModuleMethodClist[$modname] = $this->ModuleReturnClist[$modname] = Array();                }                //判断模组插入点是否重复插入相同得模组                if(in_array($modname_point,$this->ModulePointlist)){                        echo 'Notice: Module: '.$modname.' Been Added';                        return false;                }                if(!class_exists($modname)) {                        echo 'Notice: Module: '.$modname.' NoExists';                        return false;                }                if(!in_array($modname,$this->ModuleMethodClist[$modname])){                        $class_methods = get_class_methods($modname);                        $this->ModuleMethodClist[$modname]=in_array('action',$class_methods )&&in_array('execute',$class_methods);                        if(!$this->ModuleMethodClist[$modname]){                                echo 'Notice: Module: '.$modname.' Method Missing';                                return false;                        }                }                if(!in_array($modname,$this->ModuleReturnClist[$modname])){                        $class_vars = get_class_vars($modname);                        $this->ModuleReturnClist[$modname] = array_key_exists('returns',$class_vars);                }                if($class && $function && $point && !in_array($modname_point,$this->ModulePointlist)){                        $this->ModulePointlist[] = $modname_point;                        if(!isset($this->ModuleCallnum[$modname])){                                $this->ModuleCallnum[$modname] = 1;                        }else{                                $this->ModuleCallnum[$modname] ++;                        }                                                if(!in_array($modname,$this->ClassPointlist[$class][$function][$point])){                                $this->ClassPointlist[$class][$function][$point][] = $modname;                        }                }elseif($function && $point && !in_array($modname_point,$this->ModulePointlist)){                        $this->ModulePointlist[] = $modname_point;                                        if(!isset($this->ModuleCallnum[$modname])){                                $this->ModuleCallnum[$modname] = 1;                        }else{                                $this->ModuleCallnum[$modname] ++;                        }                        if(!in_array($modname,$this->FuncPointlist[$function][$point])){                                $this->FuncPointlist[$function][$point][] = $modname;                        }                }elseif(!in_array($modname_point,$this->ModulePointlist)){                        $this->ModulePointlist[] = $modname_point;                        if(!isset($this->ModuleCallnum[$modname])){                                $this->ModuleCallnum[$modname] = 1;                        }else{                                $this->ModuleCallnum[$modname] ++;                        }                        if(!is_array($this->Pointlist[$point])||!in_array($modname,$this->Pointlist[$point])){                                $this->Pointlist[$point][] = $modname;                        }                }        }        public function ModulePoint($point, $function = '' ,$class = '') {                if($class && $function && !empty($this->ClassPointlist[$class][$function][$point])){                        $this->Classexecute($point,$this->ClassPointlist[$class][$function][$point]);                }elseif($function && !empty($this->FuncPointlist[$function][$point])){                        $this->Functionexecute($point,$this->FuncPointlist[$function][$point]);                }elseif($point && !empty($this->Pointlist[$point])){                        $this->Pointexecute($point,$this->Pointlist[$point]);                }        }        public function Classexecute($point,& $classAry) {                foreach($classAry as $name){                        $this->execute($name,$point);                }        }        public function Functionexecute($point,& $functionAry) {                foreach($functionAry as $name){                        $this->execute($name,$point);                }        }        public function Pointexecute($point,& $pointAry) {                foreach($pointAry as $name){                        $this->execute($name,$point);                }        }        public function execute($name,$point) {                if(!isset($this->Module[$name])){                        $this->Module[$name] = new $name();                }                if($this->ModuleReturnClist[$name]){                        $this->Module[$name]->returns = & $this->Returns;                }                if($this->Module[$name]->action($point)){                        $this->Module[$name]->execute($point);                }                if(!isset($this->ModuleCallnumed[$modname])){                        $this->ModuleCallnumed[$modname] = 1;                }else{                        $this->ModuleCallnumed[$modname] ++;                }                if($this->ModuleCallnumed[$name] >= $this->ModuleCallnum[$name]){                        unset($this->Module[$name]);                }        }}function & Module() {        static $Module;        if(!isset($Module)){                $Module = New Module();        }        return $Module;}function ModuleAdd($name) {        $Module = Module();        $Module->ModuleAdd($name);}function ModulePointWhether($name,$function='',$class ='') {        $Module = Module();        if($class && $function && !empty($Module->ClassPointlist[$class][$function][$name])){                return TRUE;        }elseif($function && !empty($Module->FuncPointlist[$function][$name])){                return TRUE;        }elseif($name && !empty($Module->Pointlist[$name])){                return TRUE;        }else{                return FALSE;        }}function ModulePoint($name,$function='',$class ='', $returns = array()) {        $Module = Module();        if($returns) $Module->Returns = $returns;        $Module->ModulePoint($name,$function,$class);        if($Module->Returns) return $Module->Returns;}以上便是模组挂载系统的全部代码
其实这个挂载系统可以挂载到任意程序上..
下载我们改造下DISCUZX 让他可以挂载东西..
将以上模组系统得代码 我建议我们放置到一个单独得 程序文件下
比如 在程序主目录下新建 require.php
将模组系统的代码复制其中
将执行文件 加入到 内核执行之前 于是我们找到文件
source/class/class_core.php
在 代码
class discuz_core {之前加入
define(‘BIGQI_ROOT’, substr(dirname(__FILE__), 0, -12));
require_once BIGQI_ROOT.’./require.php’;
这样模组系统 就成功加入PHP 代码中了..
下面 我们给discuzx加入挂载点 (你可以自由定义挂载点..)
这里介绍下我自己认为需要添加得挂载点..
start 内核被执行前
core 内核执行后,功能script执行前
template 模版加载前
output 模版输出前
好了 知道这几个挂载点得 含义 我们接下来去加入这些挂载点
增加 start 挂载点:
打开文件
source/class/class_core.php

class discuz_core {得上一行加入
/* ModuleSystem Point */
if(ModulePointWhether(‘start’,__FUNCTION__,__CLASS__)){
$Modextract = ModulePoint(‘start’,__FUNCTION__,__CLASS__);
if(isset($Modextract) && is_array($Modextract)){
extract($Modextract);
unset($Modextract);
}
}
/* ModuleSystem Point */

增加 core 挂载点:
打开文件
source/class/class_core.php
找到代码
$this->_init_misc();在其下部加入
                        /* ModuleSystem Point */                        if(ModulePointWhether('core')){                                                                $Modextract = ModulePoint('core');                                if(isset($Modextract) && is_array($Modextract)){                                        extract($Modextract);                                        unset($Modextract);                                }                        }                        /* ModuleSystem Point */增加 core 挂载点:
打开文件
source\function\function_core.php
找到代码
function template($file, $templateid = 0, $tpldir = '', $gettplfile = 0, $primaltpl='') {        global $_G;在其下部加入
        /* ModuleSystem Point */        if(ModulePointWhether('template')){                $Modextract = ModulePoint('template');                if(isset($Modextract) && is_array($Modextract)){                        extract($Modextract);                        unset($Modextract);                }        }        /* ModuleSystem Point */增加 output 挂载点:
打开文件
source\function\function_core.php
找到代码
function output() {        global $_G;在其下部加入
        /* ModuleSystem Point */        if(ModulePointWhether('output')){                $Modextract = ModulePoint('output');                if(isset($Modextract) && is_array($Modextract)){                        extract($Modextract);                        unset($Modextract);                }        }        /* ModuleSystem Point */好了 现在 4个挂载点 就全部增加完毕.. 现在就该我们看看 要怎么用到这个挂载系统 挂载具体得功能
我先发一个案例(此案例是预防机器人发帖得部分代码)
类得 定义 必须有2个方法分别是 action 用来判断执行 execute具体得执行代码
class postvalidate {        public function action($point) { //                if(CURSCRIPT == 'forum' && CURMODULE == 'post' && $_POST){                        return true;                }else{                        return false;                }        }        public function execute() {                if( FORMHASH != $_G['gp_posthash']){                        showmessage('undefined_action');                }        }}ModuleAdd('postvalidate/output'); //含义:在output 上挂载postvalidate类将以上代码 复制到 require.php 文件内
看到了.. 很简单得几行代码 我们就可以对 forum动作得 POST进行截断执行postvalidate ::execute下得代码
其实 这个代码挂载系统 还远远不只这些功能…
下载我们再来更牛叉点得功能…
给一个函数内加入挂载点
首先需要修改代码
打开文件
source\function\function_core.php
找到代码
$string = str_replace(array("\r", "\n"), array('', ''), $string);在其下部加入
/* ModuleSystem Point */
if(ModulePointWhether(‘output’,__FUNCTION__,__CLASS__)){
$returns['string'] = $string;
$returns['replace'] = $replace;
$returns['http_resp**e_code'] = $http_resp**e_code;
$Modextract = ModulePoint(‘output’,__FUNCTION__,__CLASS__,$returns);
if(isset($Modextract) && is_array($Modextract)){
extract($Modextract);
unset($Modextract);
}
}
/* ModuleSystem Point */
好了 发一个案例
这个功能 就是 更改提示信息跳转得URL (wp.cc使用得URL规则)
class redirect_staticlink {        public $returns;         public function action($point) {                if(CURSCRIPT == 'forum'&& CURMODULE == 'redirect'){                        return true;                }elseif(CURSCRIPT == 'forum'&& CURMODULE == 'post'){                        return true;                }else{                        return false;                }        }        public function execute() {                global $_G;                if (preg_match ('/forum.php\?mod\=viewthread&(amp;)?tid=(\d+)/is', $this->returns['string'], $matches)) {                        $query = "SELECT fid FROM ".DB::table('forum_thread')." WHERE tid='$matches[2]'";                        $fid = DB::result_first($query);                        $this->returns['string'] = str_replace('tid='.$matches[2],'fid='.$fid.'&tid='.$matches[2],$this->returns['string']);                        $siteurl = str_replace('develop/','',$_G['siteurl']);                        $search = '/forum.php\?mod\=viewthread&(amp;)?fid\=(\d+)&(amp;)?tid=(\d+)(&(amp;)?page\=(\d+))?(&(amp;)?[^"\'# ]+)?/e';                        $replace= '$siteurl.manage_staticlink::staticrewrite(\'$0\',\'$2\',\'$4\',\'$7\',\'$8\')';                                                $this->returns['string'] = preg_replace($search,$replace,$this->returns['string']);                }        }}ModuleAdd('redirect_staticlink/dheader/output'); // 在dheader函数内得 output挂载点加入redirect_staticlink
游客,如果您要查看本帖隐藏内容请回复




上一篇:dz论坛从X2升级到X2.5升级陷入死循环的解决方法
下一篇:关于Discuz X1 嵌入点 及其插件的编写 注意说明
authicon 9523 发表于 2012-6-24 19:39:29 | 显示全部楼层
学习一下 强烈支持楼主ing……
authicon 音趣网-小卢 发表于 2012-6-27 20:07:21 | 显示全部楼层
真是难得给力的帖子啊。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-2 01:31

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

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