# 三、插件开发
一、插件的安装卸载机制介绍
OpenSNS的插件支持云市场在线安装和本地安装。
如果要能够被OpenSNS识别并允许安装卸载。开发人员需要遵守以下约定。
目录结构约定:
插件文件放置在
/Addons 下
每一个插件的目录结构如下
以CheckIn(签到)插件为例
CheckIn
Controller //控制器目录,有URL访问的时候才需要,可选
CheckInController.class.php //插件控制器,名字可以不和插件名一样
Model //插件的Model
CheckInModel.class.php
Static
images //放置插件所需用到的图片
js // 插件js文件放置的文件夹
css //插件的css文件放置的文件夹
View //插件的模版文件
default
CheckIn
ranking.html
checkin.html //插件模板页面,一般直接放在插件的目录下。这里放在了View文件夹下。
rank.html
CheckInAddon.class.php //插件定义和实现的文件,必须有!!
config.php // 插件的配置文件
插件的生命周期:
1.安装插件
2.使用插件
3.卸载插件
安装插件
用管理员帐号打开网站后台->云市场->插件管理->未安装;从中找到《签到》插件。
点击安装按钮进行安装。提示安装成功则表示插件已经安装成功,此时可以在已安装的选项卡中找到《签到》插件
安装成功后,钩子摆放的位子将会出现签到的组件。如下:
卸载插件
用管理员帐号打开网站后台->云市场->插件管理->已安装;从中找到《签到》插件。
点击卸载按钮提示“卸载成功”则表示插件已经成功卸载。如之后不再使用该插件可以删除插件目录下相关文件。
二、插件的开发----以签到插件为例
1、设计插件,并创建钩子。如“签到”插件所需用到的钩子有 checkIn、rank、handleAction
2、 在Addons下创建插件文件夹并命名插件名字为 CheckIn
3、创建插件的定义和实现文件,与插件名字同名,即CheckInAddon.class.php
4、编写插件信息,以及安装和卸载的方法。如下
<?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、编写对应Controller、Model、和模版。与模块相似。
与模块不同的地方有:
(1)调用Controller:模块中调用Controller用U()函数,在插件中用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/',
)
),
)
)
)
);
8、插件到这里基本就算开发完成了。