- 好友
- 分享
- 精华
- 阅读权限
- 255
- 注册时间
- 2017-8-17
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
验证插件二次开发 | 本功能由PHP+MYSQL语言开发,无缝对接新秀网络验证系统,采用独立入口文件、类文件、第三方类文件库进行调用开发。所有功能实现及控制均采用api接口操作,数据输出形式为JSON、XML两种常见形式,达到毫秒级数据快速交换功能。 1、插件开发是结合新秀网络验证系统进行的二次开发,不能独立使用; 2、插件开发遵循Discuz、新秀网络验证、PHP语言规范开发; 3、插件开发适用于新秀网络验证系统旗舰版ver1.0版本以后; 4、本功能与新秀网络验证系统、扩展框架系统,代码相互独立,但功能同时执行; 5、插件开发可使用Discuz内置函数、新秀网络验证内置函数、PHP函数。 | 适用环境:php版本>7.1、Mysql版本>5.7以上、Discuz版本>3.5。 | = Discuz资料库 = Discuz插件开发文档 = 开发交流 = BUG反馈 = QQ客服:3188639 QQ交流群:281079920 |
( S5 a3 X! J: ?$ X% j! R4 p3 O2 v" v! |! x* \
使 用 简 介 | 1、插件开发演示文件下载(IP地址查询) | | 2、插件开发演示文件目录说明 | xinxiuvip_network_plugin \\新秀网络验证应用中心插件主目录 —lib \\自定义类存放目录 (用于开发者存放第三方类、自定义类) ——lib_ip.php \\自定义方法库开发文件 (自定义开发接口方法库) —function \\自定义方法存放目录 (用于开发者存放自定义开发接口类和方法) ——function_ip.php \\自定义方法类开发文件 (自定义开发接口方法类) —plugins \\插件数据库代码存放目录 (用于开发者存放插件数据库执行代码) ——ip\\插件名目录 ———extend_network.php \\设置插件数据库执行代码文件(数据新增、更新、删除,接口增加、删除功能,插件安装和卸载代码) —template/plugin/admin \\插件前端htm开发存放目录(根据discuz官方插件前台开发代码进行开发) ——ip\\插件名目录 ———ip.htm \\插件后台设置文件(根据discuz官方插件后台开发代码进行开发,并在插件设计页面自行增加插件设置文件入口) —ip.inc.php \\自定义接口入口开发文件 | 3、如何安装、开发、调试? | #1、下载演示文件后,上传至新秀网络验证应用中心插件根目录。discuz论坛插件根目录 \source\plugin\xinxiuvip_network_plugin\ #2、使用PHP代码编辑软件,对入口文件 ip.inc.php 和 自定义方法类文件 function_ip.php 等进行开发。 #3、如需新增接口文件,请根据演示文件,修改 “ip” 为您想要的文件名,但不能与新秀框架插件内文件名冲突,且开发的接口方法,不能与新秀框架冲突。 #4、如何发布自己开发的插件并获取一定收益,请联系客服QQ: #5、功能代码开发完成,组装调试接口:
//根据演示文件中组装url接口地址 http://demo35.xinxiuvip.com/plugin.php?id=xinxiuvip_network_plugin:ip&action=ip_cha&key=123456&ip=14.21.97.153
[PHP] 纯文本查看 复制代码 {
"code": 200,
"result": "OK",
"count": 2,
"data": {
"ip": "14.21.97.153",
"dizhi": "- 广东"
},
"sqltime": "0.027s",
} |
ip.inc.php入口文件代码实例 | [PHP] 纯文本查看 复制代码 <?php
#========================================
#以下两行代码,用于开发环境下代码错误提示,可根据提示信息进行代码检查,无误后即可注释掉!
//ini_set("display_errors", "on");
//error_reporting(E_ALL);
#========================================
#========================================
#防止游客直接输入网址进行访问,权限检测,勿动!!!
if (!defined('IN_DISCUZ')) {
exit('Access Denied');
}
#========================================
#========================================
#引入自定义开发类文件,此文件保存位置 'function/ip' 代表 function/function_ip.php 如需修改请按格式进行!
C::import('function/ip', 'plugin/xinxiuvip_network_plugin', false);//注意这里插件开发和接口二次开发不同!
$api = new function_ip();//实例化function_ip.php类操作,实例化后可用$api->调用function_ip.php中的类方法!
#========================================
#此处为入口文件,根据接口方法,调用对应类方法。
switch ($api->action) { //$api->action 获取入口方法,勿动!!!
#========================================
case 'ip_cha': // 判断是否是此方法,如果是则进入下一步!
$ip = web_client::safe_check('ip', true); //判断参数传输,params为参数名称,iscore为是否是必填项(true为必填,false为可空)
$api->ip_cha($ip);//调用function_ip.php实例化后类方法,根据类方法设置传入参数。
break;
#此处代码根据接口开发需求,可以无限添加循环。
#========================================
#========================================
#此处代码是判断接口输入是否正确。勿删!!!
default:
web_output::json_output(400,'error010');
break;
#========================================
}
| : I& h Z% \2 f9 z# l# m
function_ip.php自定义方法类代码实例 | [PHP] 纯文本查看 复制代码 <?php
#========================================
#以下两行代码,用于开发环境下代码错误提示,可根据提示信息进行代码检查,无误后即可注释掉!
//ini_set("display_errors", "on");
//error_reporting(E_ALL);
#========================================
#========================================
#防止游客直接输入网址进行访问,权限检测,勿动!!!
if (!defined('IN_DISCUZ')) {
exit('Access Denied');
}
#========================================
#========================================
#引入核心系统类,勿删!!!
C::import('class/plugin','plugin/xinxiuvip_network_plugin',false);
#========================================
#如何引入自定义系统类?
#1、将自定义核心类、第三方核心类上传至extend文件夹下;
#2、通过 C::import 、 require_once 两种引入形式引入第三方核心类;
#3、在下方方法中使用 lib_ip::convertip_tiny($ip, $ipdatafile); 进行调用,具体功能看lib_ip封装代码;
C::import('lib/ip', 'plugin/xinxiuvip_network_plugin', false);//如果没有自定义类库,请将此处注释掉!
#注释结束
class function_ip extends class_plugin
{
public $action_all = array('ip_cha');//所有接口必填,用逗号隔开!!!除以下key、adminkey所包含以外,未包含的接口都是通过token令牌进行访问。
public $function_action_key = array('ip_cha');//使用key密钥访问的接口
public $function_action_adminkey = array();//使用管理密钥adminkey访问的接口
/**
* 构造方法 __construct() 是在实例化对象时被自动调用
* 用途:可以用于初始化程序(可以给成员属性赋值,也可以调用成员方法)
*/
public function __construct(){
$this->plugin_config;//是后台插件设置的数据,可在本页面进行调用。
parent::__construct();//注意这里和接口二次开发不同
}
#========================================
#此处为标准类方法,可根据DISCUZ、新秀网络验证内置函数进行调用,也可使用PHP官方函数进行操作。
public function ip_cha($ip){
#-具体DISCUZ内置函数、新秀网络验证内置函数、PHP函数,论坛相应帖子有专门介绍。
$tinyipfile = DISCUZ_ROOT.'./data/ipdata/tinyipdata.dat';
$data = lib_ip::convertip_tiny($ip,$tinyipfile);//调用lib自定义封装类库示例;
$data_array = array(
'ip'=>$ip,
'dizhi'=>$data,
);
#========================================
#嵌入插件开发钩子,注意:此扩展方法在应用中心扩展文件中使用‘extend_plugin.php’;
web_client::class_hook('hook_ip_cha',array('ip'=>$ip));
/*
* 下面是插件拓展对应的方法
* 注意class_hook中的'hook_ip_cha' 就是扩展文件中的方法名!
*
public function hook_ip_cha($ip){
var_dump($ip);
}
*/
#========================================
$data ? web_output::json_output(200,'OK',$data_array): web_output::json_output(400,'请检查IP地址是否正确!');
#-具体DISCUZ内置函数、新秀网络验证内置函数、PHP函数,论坛相应帖子有专门介绍。
}
#========================================
/**
* 析构方法 __destruct() 是在对象被销毁时自动调用
* 用途:可以进行资源的释放操作或文件的关闭操作或信息保存操作
*/
public function __destruct()
{
return parent::__destruct(); // TODO: 析构方法
}
} |
: ]" P, r% h0 |; ^( B! vlib_ip.php自定义方法类库代码实例 | [PHP] 纯文本查看 复制代码 <?php
#以下两行代码,用于开发环境下代码错误提示,可根据提示信息进行代码检查,无误后即可注释掉!
//ini_set("display_errors", "on");
//error_reporting(E_ALL);
#注释结束
#引入验证自带核心系统类,勿删!!!
C::import('class/xinxiu', 'plugin/xinxiuvip_network', false);
#注释结束
class lib_ip
{
/**
* 自定义方法类库,用于扩展系统功能!
* 1、在function_ip.php中引用此类库,直接调用方法即可!
* 2、引用代码:C::import('lib/ip', 'plugin/xinxiuvip_network_plugin', false);//引用自定义类库!
* 3、此方法为纯静态方法,无需实例化,可直接调用!
* 4、调用代码:lib_ip::convertip_tiny($ip,$tinyipfile);//调用lib自定义封装类库示例!
*/
public static function convertip_tiny($ip, $ipdatafile) {
static $fp = NULL, $offset = array(), $index = NULL;
$ipdot = explode('.', $ip);
$ip = pack('N', ip2long($ip));
$ipdot[0] = (int)$ipdot[0];
$ipdot[1] = (int)$ipdot[1];
if($fp === NULL && $fp = @fopen($ipdatafile, 'rb')) {
$offset = @unpack('Nlen', @fread($fp, 4));
$index = @fread($fp, $offset['len'] - 4);
} elseif($fp == FALSE) {
return '- Invalid IP data file';
}
$length = $offset['len'] - 1028;
$start = @unpack('Vlen', $index[$ipdot[0] * 4] . $index[$ipdot[0] * 4 + 1] . $index[$ipdot[0] * 4 + 2] . $index[$ipdot[0] * 4 + 3]);
for ($start = $start['len'] * 8 + 1024; $start < $length; $start += 8) {
if ($index[$start] . $index[$start + 1] . $index[$start + 2] . $index[$start + 3] >= $ip) {
$index_offset = @unpack('Vlen', $index[$start + 4] . $index[$start + 5] . $index[$start + 6] . "\x0");
$index_length = @unpack('Clen', $index[$start + 7]);
break;
}
}
@fseek($fp, $offset['len'] + $index_offset['len'] - 1024);
if($index_length['len']) {
return '- '.@fread($fp, $index_length['len']);
} else {
return '- Unknown';
}
}
}
|
+ j/ D1 K* M2 K, d6 I7 r+ mip.htm插件后台设置文件 | [HTML] 纯文本查看 复制代码 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>插件设置页面</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/source/plugin/xinxiuvip_network/template/res/layui/css/layui.css" rel="stylesheet">
<link href="/source/plugin/xinxiuvip_network/template/res/adminui/dist/css/admin.css" rel="stylesheet">
</head>
<style>
body {
background-color: #ffffff;
}
</style>
<body>
<div class="layui-fluid">
<div class="layui-main">
<blockquote class="layui-elem-quote">
此页面为插件后台设置页面,请根据具体文档进行设置。
<a href="http://www.xinxiuvip.com/forum.php?mod=viewthread&tid=649" target="_blank">【插件开发文档】</a>
</blockquote>
<div class="layui-form" id="form" lay-filter="form" action="">
<div class="layui-form-item adminj-sort-item" style="width: 100%;">
<label class="layui-form-label">radio开关类</label>
<div class="layui-input-inline" style="width: 30%;">
<!--{if $plugin_config['status'] == 0}-->
<input name="status" type="radio" value="0" checked="" title="正常" lay-skin="primary">
<input name="status" type="radio" value="1" title="禁止" lay-skin="primary">
<input name="status" type="radio" value="2" title="其他" lay-skin="primary">
<!--{elseif $plugin_config['status'] == 1}-->
<input name="status" type="radio" value="0" title="正常" lay-skin="primary">
<input name="status" type="radio" value="1" checked="" title="禁止" lay-skin="primary">
<input name="status" type="radio" value="2" title="其他" lay-skin="primary">
<!--{elseif $plugin_config['status'] == 2}-->
<input name="status" type="radio" value="0" title="正常" lay-skin="primary">
<input name="status" type="radio" value="1" title="禁止" lay-skin="primary">
<input name="status" type="radio" value="2" checked="" title="其他" lay-skin="primary">
<!--{/if}-->
</div>
<div class="layui-form-mid layui-word-aux">radio开关类注释</div>
</div>
<div class="layui-form-item adminj-sort-item" style="width: 100%;">
<label class="layui-form-label">text文本</label>
<div class="layui-input-inline" style="width: 30%;">
<input type="text" name="text" value="{$plugin_config['text']}" autocomplete="off"
class="layui-input" style="width: 99%;">
</div>
<div class="layui-form-mid layui-word-aux">text文本注释</div>
</div>
<div class="layui-form-item adminj-sort-item" style="width: 100%;">
<label class="layui-form-label">text文本验证</label>
<div class="layui-input-inline" style="width: 30%;">
<input type="password" name="password" value="{$plugin_config['password']}" autocomplete="off"
class="layui-input" style="width: 99%;">
</div>
<div class="layui-form-mid layui-word-aux">text文本验证注释</div>
</div>
<div class="layui-form-item adminj-sort-item" style="width: 100%;">
<label class="layui-form-label">
textarea文本
</label>
<div class="layui-input-inline" style="width: 30%;">
<textarea class="layui-textarea" name="textarea" style="width: 99%;">{$plugin_config['textarea']}
</textarea>
</div>
<div class="layui-form-mid layui-word-aux">
textarea文本域注释
</div>
</div>
<div class="layui-form-item adminj-sort-item" style="width: 100%;">
<label class="layui-form-label">select下拉框</label>
<div class="layui-input-inline" style="width: 30%;">
<select name="select">
<option value="">请选择</option>
<!--{if $plugin_config['select'] == 1}-->
<option value="1" selected>value为1</option>
<!--{else}-->
<option value="1">value为1</option>
<!--{/if}-->
<!--{if $plugin_config['select'] == 2}-->
<option value="2" selected>value为2</option>
<!--{else}-->
<option value="2">value为2</option>
<!--{/if}-->
<!--{if $plugin_config['select'] == 3}-->
<option value="3" selected>value为3</option>
<!--{else}-->
<option value="3">value为3</option>
<!--{/if}-->
</select>
</div>
<div class="layui-form-mid layui-word-aux">select下拉框注释</div>
</div>
<div class="layui-form-item adminj-sort-item" style="width: 100%;">
<label class="layui-form-label">时间选择</label>
<div class="layui-input-inline" style="width: 30%;">
<input type="text" name="groupline" value="{$plugin_config['groupline']}"
id="form-date" placeholder="yyyy-MM-dd HH:mm:ss" autocomplete="off"
class="layui-input" style="width: 99%;">
</div>
<div class="layui-form-mid layui-word-aux">时间选择注释</div>
</div>
<div class="layui-form-item adminj-sort-item" style="width: 100%;">
<label class="layui-form-label">
选择积分
</label>
<div class="layui-input-inline" style="width: 30%;">
<select name="credits">
{$plugin_config['credits']}
</select>
</div>
<div class="layui-form-mid layui-word-aux">
内置选择积分类型。
</div>
</div>
<div class="layui-form-item adminj-sort-item" style="width: 100%;">
<label class="layui-form-label" style="margin-top: -3px;">
选择会员组
</label>
<div class="layui-input-inline" style="width: 30%;">
<select name="groupids" lay-ignore="" class="layui-select-group layui-select-tips"
multiple="multiple" data-placeholder="" data-dropdown-css-class="select2-purple"
style="width: 99%;height: 200px;">
{$plugin_config['groupids']}
</select>
</div>
<div class="layui-form-mid layui-word-aux">
内置选择会员组。
</div>
</div>
<div class="layui-form-item adminj-sort-item">
<div class="layui-input-block">
<button type="submit" class="layui-btn" lay-submit="" lay-filter="postButton" id="postButton">
立即修改
</button>
</div>
</div>
</div>
</div>
</div>
<script src="/source/plugin/xinxiuvip_network/template/res/layui/layui.js?t=1"></script>
<script>
layui.use(['form', 'layer', 'jquery'], function () {
var form = layui.form;
var layer = layui.layer;
var $ = layui.jquery;
var laydate = layui.laydate;
laydate.render({
elem: '#form-date',
type: 'datetime',
fullPanel: true // 2.8+
});
form.on('submit(postButton)', function (data) {
function getQueryParam(param) {
const search = window.location.search || window.location.hash.split('?')[1] || '';
const params = new URLSearchParams(search);
return params.get(param);
}
const dir = getQueryParam('dir');
$.post('plugin.php?id=xinxiuvip_network_plugin:web_admin&action=api&dir=' + dir, {
data: data.field,
}, function (jsondata, textStatus, jqXHR) {
if (jsondata.code === 200) {
layer.msg('[ ' + dir + ' ] 插件设置成功!', {
icon: 1
});
} else {
layer.msg('[ ' + dir + ' ] 插件设置失败!', {
icon: 2
});
}
return false;
});
});
});
</script>
</body>
</html>
|
3 e) G3 u% r) l2 ?0 c4 c5 zextend_network.php插件安装卸载配置实例 | [PHP] 纯文本查看 复制代码 <?php
if (!defined('IN_DISCUZ')) {
exit('Access Denied');
}
C::import('class/plugin', 'plugin/xinxiuvip_network_plugin', false); //引入系统核心类
class extend_network extends class_plugin
{
public function __construct() //构造方法
{
parent::__construct(false);
}
/**
* ##创建插件的安装代码
* 1、此处代码以创建数据库表为主,提前创建插件需要的数据库表及字段!
* 2、在这里也可以添加一些插件自定义php代码,系统自动执行!
* 3、如果不需要执行代码,直接返回true即可,实例:return true;
*/
public function hook_plugin_install() //插件安装代码
{
$sql = <<<EOF
CREATE TABLE IF NOT EXISTS `pre_xinxiuvip_plugin_ip` (
`id` BIGINT(16) unsigned NOT NULL AUTO_INCREMENT,
`text1` longtext NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
EOF;
$sql ? web_mysql::xinxiuvip_plugin_run_sql($sql) : ''; //执行上面的多行SQL代码;
return true; //创建结束
}
/**
* ##更新插件的更新代码
* 1、此处代码以更新数据库表为主,对安装的数据库表和字段进行更新!
* 2、在这里也可以添加一些插件自定义php代码,系统自动执行!
* 3、如果不需要执行代码,直接返回true即可,实例:return true;
*/
public function hook_plugin_upgrade() //插件更新代码
{
$sql = <<<EOF
CREATE TABLE IF NOT EXISTS `pre_xinxiuvip_plugin_ip` (
`id` BIGINT(16) unsigned NOT NULL AUTO_INCREMENT,
`text1` longtext NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
EOF;
$sql ? web_mysql::xinxiuvip_plugin_run_sql($sql) : ''; //执行上面的多行SQL代码;
return true; //更新结束
}
/**
* ##卸载插件的卸载代码
* 1、此处代码以卸载数据库表为主,对安装的数据库表和字段进行卸载!
* 2、在这里也可以添加一些插件自定义php代码,系统自动执行!
* 3、如果不需要执行代码,直接返回true即可,实例:return true;
*/
public function hook_plugin_uninstall() //插件卸载代码
{
$sql = <<<EOF
DROP TABLE IF EXISTS `pre_xinxiuvip_plugin_ip`;
EOF;
$sql ? web_mysql::xinxiuvip_plugin_run_sql($sql) : ''; //执行上面的多行SQL代码;
return true; //更新结束
}
/**
* ##安装插件的接口代码
* 1、此处代码以添加插件接口为主,对插件封装的接口,添加到数据库!
* 2、如果不需要添加任何接口信息,直接返回false即可,实例:return false;
*/
public function hook_plugin_actions_install() //插件安装接口代码
{
$actions_array = array(
array(
'type' => 'ip模块',//插件模块
'name' => '查询ip地址',//接口名称
'actions' => 'ip_cha',//接口方法
'url' => 'http://www.xinxiuvip.com/thread-556-1-1.html',//接口文档
),
array(
'type' => 'ip模块1',//插件模块
'name' => '查询ip地址1',//接口名称
'actions' => 'ip_cha1',//接口方法
'url' => 'http://www.xinxiuvip.com/thread-556-1-1.html',//接口文档
),
);
return $actions_array;
}
/**
* ##更新插件的接口代码
* 1、此处代码以更新插件接口为主,对插件封装的接口,更新到数据库!
* 2、如果不需要更新任何接口信息,直接返回false即可,实例:return false;
*/
public function hook_plugin_actions_upgrade() //插件接口更新代码
{
$actions_array = array(
array(
'type' => 'ip模块2',//插件模块
'name' => '查询ip地址2',//接口名称
'actions' => 'ip_cha2',//接口方法
'url' => 'http://www.xinxiuvip.com/thread-556-1-1.html',//接口文档
),
);
return $actions_array;
}
}
|
6 K# r c3 J. X4 g, S3 O/ M) `3 z |
|