SNS进阶

插件开发

插件开发

关键词:插件开发,二次开发
<?php
  
namespace  Addons\CheckIn;
  
use  Common\Controller\Addon;
  
/**
  * 签到插件
  * @author 嘉兴想天信息科技有限公司
  */
class  CheckInAddon  extends  Addon
{
      /** 
      *  插件的信息,必须。
      */
     public  $info  array (
         'name'  =>  'CheckIn' ,     //插件的英文名
         'title'  =>  '签到' ,        //插件的中文名
         'description'  =>  '签到插件' ,    //插件的描述
         'status'  => 1,                 //插件的状态
         'author'  =>  'xjw129xjt(肖骏涛)' ,    //插件的作者
         'version'  =>  '0.1'                //插件的版本号
     );
  
      /**
      * 插件的安装方法。不需要创建任何表则直接return true;
      */ 
     public  function  install()
     {
         $prefix  = C( "DB_PREFIX" );
         D()->execute( "DROP TABLE IF EXISTS `{$prefix}checkin`" );
         D()->execute(<<<SQL
          CREATE TABLE IF NOT EXISTS `{ $prefix }checkin` (
               `id` int(11) NOT NULL AUTO_INCREMENT,
               `uid` int(11) NOT NULL,
               `create_time` int(11) NOT NULL,
                PRIMARY KEY (`id`)
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
               SQL
         );
  
         D()->execute(<<<SQL
         ALTER TABLE  `{ $prefix }member` ADD  `con_check` INT NOT NULL DEFAULT   '0' ,
         ADD  `total_check` INT NOT NULL DEFAULT   '0' ;
          SQL
         );
  
  
         return  true;
     }
      /**
      * 插件的卸载方法。不需删除任何表则直接返回 true。
      */
     public  function  uninstall()  
     {
  
         $prefix  = C( "DB_PREFIX" );
         D()->execute( "DROP TABLE IF EXISTS `{$prefix}checkin`" );
  
         D()->execute(<<<SQL
           ALTER TABLE `{ $prefix }member`
             DROP `con_check`,
               DROP `total_check`;
           SQL
         );
         return  true;
     }
      // 接下去编写钩子的实现方法。
  
}


    5、继续编写钩子对应的实现方法。在CheckInAddon.class.php文件中。如下

 

  public  function  checkIn( $param )
     {
         $model  $this ->checkInModel();
         $uid  = is_login();
         $check  $model ->getCheck( $uid );
         $this ->assign( 'check' $check );
         $this ->assignDate();
         $html  $this ->rank( 'today' );
         $this ->assign( 'html' $html );
         $this ->display( 'View/checkin' );
  
     }
  
     private  function  checkInModel()
     {
         return  D( 'Addons://CheckIn/CheckIn' );
     }
  
     public  function  rank( $type )
     {
         $time  = get_some_day(0);
         $rank  = S( 'check_rank_'  $type  '_'  $time );
         if  ( empty ( $rank )) {
             $model  $this ->checkInModel();
             $rank  $model ->getRank( $type );
             S( 'check_rank_'  $type  '_'  $time $rank , 300);
         }
         $this ->assign( 'rank' $rank );
         $this ->assign( 'type' $type );
         $this ->assign( 'type_ch' $type  ==  'con'  '连签'  '累签' );
         $html  $this ->fetch( 'View/rank' );
         return  $html ;
     }
  
     private  function  assignDate()
     {
         $week  date ( 'w' );
         switch  ( $week ) {
             case  '0' :
                 $week  '周日' ;
                 break ;
             case  '1' :
                 $week  '周一' ;
                 break ;
             case  '2' :
                 $week  '周二' ;
                 break ;
             case  '3' :
                 $week  '周三' ;
                 break ;
             case  '4' :
                 $week  '周四' ;
                 break ;
             case  '5' :
                 $week  '周五' ;
                 break ;
             case  '6' :
                 $week  '周六' ;
                 break ;
         }
         $this ->assign( 'day' date ( 'Y.m.d' ));
         $this ->assign( 'week' $week );
  
     }
  
  
     public  function  doCheckIn()
     {
         $time  = get_some_day(0);
         $uid  = is_login();
         $model  $this ->checkInModel();
         $memberModel  = D( 'Member' );
         $check  $model ->getCheck( $uid );
         if  (! $check ) {
             $model ->addCheck( $uid );
             $memberModel ->where( array ( 'uid'  =>  $uid ))->setInc( 'total_check' );
             $model ->checkYesterday( $uid );
             clean_query_user_cache( $uid array ( 'con_check' 'total_check' ));
             S( 'check_rank_today_'  $time , null);
             S( 'check_rank_con_'  $time , null);
             S( 'check_rank_total_'  $time , null);
             return  true;
         else  {
             return  false;
         }
     }
  
  
     public  function  handleAction( $param )
     {
         $config  $this ->getConfig();
         if  (! empty ( $config [ 'action' ])) {
             $action_info  = M( 'Action' )->getByName( $config [ 'action' ]);
             if  ( $action_info [ 'id' ] ==  $param [ 'action_id' ]) {
                 $res  $this ->doCheckIn();
                 if  ( $res ) {
                     $param [ 'log_score' ] .=  '签到成功!' ;
                     return  $res ;
                 }
             }
         }
         return  false;
  
     }


 

    6、编写对应ControllerModel、和模版。与模块相似。

    与模块不同的地方有:

        1)调用Controller:模块中调用ControllerU()函数,在插件中用addons_url()

        2)调用Model:在插件中调用Model 需要在D()函数中写明资源等信息,如: D('Addons://CheckIn/CheckIn');即为实例化Addons下的CheckIn插件中的CheckInModel

        3)模版的渲染与模块相同。

 

 

    7、插件的配置文件的编写

                         

<?php
  
return  array (
     'action' => array (
         'title' => '签到绑定行为:' ,
         'type' => 'select' ,
         'options' =>get_option(),
     )
  
);
  
  
/**
* 以下为调用函数。配置文件的主体为以上的数组
*/ 
function  get_option(){
     $opt  = D( 'Action' )->getActionOpt();
     $return  array (0=> '不绑定' );
     foreach ( $opt  as  $v ){
         $return [ $v [ 'name' ]] =  $v [ 'title' ];
     }
     return  $return ;
}


 

数组的每个键都对应一个form表单。键名就是配置里会显示的表单名。title是字段前面的标识字。type是form标准的type。然后有多个选项的会有options键和值是相应选项的数组。值里每个键是选项的value后面的值是显示的label文字。value字段是该表单项的默认值。 tip是表单项后面的提示文字。

支持Group分组 : 每个group里值options就是多个配置分组tab。然后分组显示名是其title。然后options里是每个配置的复合数组。那个写法和之前单独的配置一样。 

用 同步登录插件的配置文件做展示,如下:

 

<?php
  
return  array (
     'type' => array (
         'title' => '开启同步登陆:' ,
         'type' => 'checkbox' ,
         'options' => array (
             'Qq' => 'Qq' ,
             'Sina' => 'Sina' ,
             'Weixin' => 'Weixin' ,
         ),
     ),
     'meta' => array ( //配置在表单中的键名 ,这个会是config[title]
         'title' => '接口验证代码:' , //表单的文字
         'type' => 'textarea' ,          //表单的类型:text、textarea、checkbox、radio、select等
         'value' => '' ,                 //表单的默认值
         'tip' => '需要在Meta标签中写入验证信息时,拷贝代码到这里。'
     ),
     'bind' => array ( //配置在表单中的键名 ,这个会是config[title]
         'title' => '是否开启帐号绑定:' , //表单的文字
         'type' => 'radio' ,             //表单的类型:text、textarea、checkbox、radio、select等
         'options' => array (
             '1' => '是' ,
             '0' => '否' ,
         ),
         'value' => '0' ,
         'tip' => '不开启则跳过与本地帐号绑定过程,建议审核时关闭绑定。'
     ),
  
     'group' => array (
         'type' => 'group' ,
         'options' => array (
             'Qq' => array (
                 'title' => 'QQ配置' ,
                 'options' => array (
                     'QqKEY' => array (
                         'title' => 'QQ互联APP ID:' ,
                         'type' => 'text' ,
                         'value' => '' ,
                         'tip' => '申请地址:http://connect.qq.com' ,
                     ),
                     'QqSecret' => array (
                         'title' => 'QQ互联APP KEY:' ,
                         'type' => 'text' ,
                         'value' => '' ,
                         'tip' => '申请地址:http://connect.qq.com' ,
                     )
                 ),
              ),
             'Sina' => array (
                 'title' => '新浪配置' ,
                 'options' => array (
  
                     'SinaKEY' => array (
                         'title' => '新浪App Key:' ,
                         'type' => 'text' ,
                         'value' => '' ,
                         'tip' => '申请地址:http://open.weibo.com/' ,
                     ),
                     'SinaSecret' => array (
                         'title' => '新浪App Sercet:' ,
                         'type' => 'text' ,
                         'value' => '' ,
                         'tip' => '申请地址:http://open.weibo.com/' ,
                     )
  
                 ),
  
             ),
             'Weixin' => array (
                 'title' => '微信配置' ,
                 'options' => array (
  
                     'WeixinKEY' => array (
                         'title' => '微信App Key:' ,
                         'type' => 'text' ,
                         'value' => '' ,
                         'tip' => '申请地址:https://open.weixin.qq.com/' ,
                     ),
                     'WeixinSecret' => array (
                         'title' => '微信App Sercet:' ,
                         'type' => 'text' ,
                         'value' => '' ,
                         'tip' => '申请地址:https://open.weixin.qq.com/' ,
                     )
  
                 ),
  
             )
         )
     )
);


 

blob.png

 

 

    8、插件到这里基本就算开发完成了。去后台安装一下吧。

 

 eg:部分内容摘自onethink 插件开发指南  http://document.onethink.cn/manual_1_0.html#onethink_3_5

插件和钩子介绍

关键词:插件,钩子

一、什么是插件

插件是用于扩展系统的功能的一些独立“组件”。


插件的定位是用于实现某些简单的显示及数据处理的功能扩展。



二、什么是钩子

讲到插件,不得不讲钩子。首先,我们之前说明了插件是一个扩展的功能实现。

既然是扩展的,那么就要很灵活、可复用,并不是像我们之前开发项目,一个功能实现了,就写死在代码里了。

项目其他地方要用了,怎么办,复制一份改个名,改的那个地方能调用实现。这样一次两次可以,次数多了就不行了。

因为后面每次开发的底层架构在不断变化。不断重复的功能版本造成人力的浪费。我们做成插件的目的就是为了方便大家扩展我们这个产品的功能。到时候形成规模,大家自由的搭建自己的站点就方便了。

那么如何让一个扩展的功能在多个地方可随意的使用呢。那就用到了我们的钩子。

为什么叫它钩子呢?因为它的作用就是如此和生活中的钩子类似。

打个比方,我们做的网站比作一个有多个功能的立式衣架。

这个衣架给什么人用就有不同的用途。

假如你专门用来挂大衣的,那就是大衣衣架。如果你专门挂袋子,那就是一个储物衣架。

当你不想要某个挂件、衣服时,取下来即可。并不会破坏原有的袋子或者衣服的功能。

你挂与不挂,钩子就在那里。

为什么能挂那么多东西呢?说明被挂的东西都符合一个标准:能挂的住。

换作你挂一个橡皮泥、或者棉花之类的。挂不了多久就会掉了。因为他们不符合要有部分封闭的可固定的这一个部分的标准。

还有挂一个太重的比如10个背包挂一个钩子上。要么架子毁了,要么钩子断了。总之就是挂不住。

因为任何一个钩子都有其承重上限。你加起来的超过了,肯定不行。

所以我们不能把插件当成万能的使,什么东西都整成插件,不管功能的大小。

任何系统都有瓶颈,你不能把个重量级的东西做成插件后挂上,说不定以后就会影响整个站点。就违背了插件的独立性原则。那些就不应该做成插件而是做成模型扩展或者应用扩展。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值