分享一个插件机制

jerry thinkphp 2015年11月18日 收藏
代替widget
代码比较乱没有打包,需要修改框架。
我们知道官网的widget是继承的widget基础类,总感觉不够爽。
这里使用的插件的思想就是为系统添加一个CX标签,让插件继承的是action类。。。
首先修改框架
/lib/Driver/TagLib/Taglibx.class.php
标签定义处 Mod标签:
  1. 'mod'       =>  array('attr'=>'name','close'=>0,level=>'1'),  //插件
下面是标签代码
  1. //插件
  2.     public function _mod($attr,$content)
  3.     {     
  4.         $tag      = $this->parseXmlAttr($attr,'mod');
  5.         $name     =!empty($tag['name'])?$tag['name']:''; 
  6.                //在此呢mod只有一个必须的tag,那就是name:调用插件的名称 
  7.         $name     =strtolower($name);
  8.         $path='./Mod/'.$name.'/default.php'; //载入每个插件的文件
  9.         if(!file_exists($path))
  10.         {            
  11.             return '<b style=color:red >Mod:'.$name.',not found!</b>';;    
  12.         }     
  13.         include_once $path;
  14.         //new 构造函数
  15.         $mod=new $name($tag);
  16.                //这个status是保存在数据中的,决定是否被启用
  17.         if($mod->param['status']==0)  return '<font color=red >Mod:'.$name.',is unavailable</font>';
  18.         return $mod->run();
  19.         //载入插件
  20.     }
根据$path,他会自动加载./Mod/插件名称/default.php的内容,并执行run()方法。目录结构:
在此,default.php会继承ModAction,代码:
  1. <?php
  2. class kindeditor extends ModAction
  3. {    
  4.     //参数
  5.     public $param=array(
  6.            'mod_name'=>'html在线编辑器',
  7.            'mod_description'=>'KindEditor 是一套开源的在线HTML编辑器',
  8.            'mod_author'=>'无语西风', 
  9.            'id'=>'editor_id',
  10.            'width'=>'99%',
  11.            'height'=>'300px',
  12.            'class'=>'',
  13.            'items'=>'',
  14.            'mode'=>1,  //模式1 全部模式,2精简模式
  15.     );
  16.    //这里写入你插件的具体代码
  17.     public function run()
  18.     {          
  19.         //设置默认的
  20.         $this->param=array_merge($this->default,$this->param);
  21.         //默认
  22.         if($this->param['mode']==1) $this->param['items']='';
  23.         //精简模式
  24.         if($this->param['mode']==2) $this->param['items']=<<<EOT
  25.         items:[
  26.                 'source','|','code','fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline',
  27.                 'removeformat', '|', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist',
  28.                 'insertunorderedlist', '|', 'emoticons','link'
  29.             ],
  30. EOT;
  31.                 
  32.         $this->p=$this->param;      
  33.         return $this->getHtml();  //run方法只要返回被渲染过的模板内容就行
  34.     }
  35.     

  36.  
  37. }
在模板中调用,
<Mod name='kindeditor' mode='1' width='99%' height='50px' ...任何你想加入的参数也就是标签的tag.... />
总结下:也就是mod会根据name找到./Mod/kindeditor/default.php 中的kindeditor类。
下面就是ModAction类了,你可以把它放到公用的类中.
  1. <?php 
  2. class ModAction extends BaseAction
  3. { 
  4.     /*
  5.      * 外部直接条用方式为
  6.      * ?s=mod-name
  7.      * */ 
  8.     public $default=array(
  9.           'mod_name'=>'',
  10.           'mod_author' =>'',
  11.           'mod_email'  =>'',
  12.           'mod_site'   =>'',
  13.           'mod_description'=>'',
  14.     );
  15.     public $param=array();    
  16.     function __construct($tags=null){
  17.        $this->default['mod_alias']=get_class($this);        
  18.        //参数优先顺序     调用(tags)  = >  数据库配置=> 插件文件配置 => 默认配置
  19.        if($this->param)
  20.           $this->param=array_merge($this->default,$this->param);
  21.        else 
  22.           $this->param=$this->default;    
  23.        //下面是数据配置,方便在后台启用或禁用,读取数据配置,缓存插件
  24.        if(!$plus_arr=S('plus_arr')){
  25.            $plus_arr=M('plus')->select();
  26.            S('plus_arr',$plus_arr);           
  27.        }
  28.        $ret=list_search($plus_arr, array('mod_alias'=>$this->default['mod_alias']));  
  29.        if($ret[0]){    
  30.                $this->param['status']=$ret[0]['status'];
  31.                $this->param=array_merge($this->param,json_decode( $ret[0]['param'],true));    
  32.        }  
  33.        //tags
  34.        if($tags)  $this->param=array_merge($this->param,$tags);
  35.        //调用初始化
  36.        BaseAction::_initialize();       
  37.       
  38.     }
  39.     //插件渲染模板用,默认路径就是插件的路径
  40.     function getHtml($tpl='index.html')
  41.     {
  42.         //mod 的名称
  43.         $name=get_class($this);
  44.         //C('MOD_DIR') 就是  /Mod
  45.         return $this->fetch('.'.C('MOD_DIR').$name.'/'.$tpl);        
  46.     }    
  47.    //默认run()
  48.     public function run()
  49.     {
  50.         return $this->getHtml();
  51.     }    
  52.      
  53. }
ModAction呢只有两个方法,
getHtml(),用于渲染模板,
run(),
构造函数的功能就是配置参数了,
参数优先顺序 调用(tags) = > 数据库配置=> 插件文件配置 => 默认配置
数据库配置呢就是就建立个插件表,用于在后台管理的,其中有个字段param是吧参数序列化保存的(我这里是json格式)。我的表:,后台配置自己写个:

BaseAction是我的所有action的基类,如果没有直接继承Action就行。
要实现单独调用mod呢,还需要在你的Action中或BaseAction中添加
  1. //mod 单独调用
  2.     function mod()
  3.     {          
  4.         $mod=_get('name');  
  5.         $fun=_get('fun');
  6.         $path='.'.C('MOD_DIR').$mod.'/default.php' ;
  7.         include_once $path; 
  8.         $myMod=new $mod;
  9.         if(empty($fun)) $fun='run';
  10.         $ret=$myMod->$fun();
  11.         if(!empty($ret))
  12.             echo $ret;        
  13.     }
所以单独调用这个mod为 ?s=mod-kindeditor
这个插件呢其实呢是继承了action,可以像所有action使用,又可以放到任何模板中任意位置。随心所欲了。
===================
发个实例吧,实例使用tp版本3.13,和上面的代码有点区别,上面的代码是在3.12中使用的,代码以例子为准。

附件mod_plus.rar ( 8.91 KB 下载:36 次 )