2020.02新版

This commit is contained in:
Blokura
2020-02-21 16:20:55 +08:00
parent 45e2415d71
commit a2f29a310b
755 changed files with 95144 additions and 0 deletions

45
includes/lib/Cache.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
namespace lib;
class Cache {
public function get($key) {
global $_CACHE;
return $_CACHE[$key];
}
public function read($key = 'config') {
global $DB;
$value = $DB->getColumn("SELECT v FROM pre_cache WHERE k=:key LIMIT 1", [':key'=>$key]);
return $value;
}
public function save($key ,$value, $expire=0) {
if (is_array($value)) $value = serialize($value);
global $DB;
return $DB->exec("REPLACE INTO pre_cache VALUES (:key, :value, :expire)", [':key'=>$key, ':value'=>$value, ':expire'=>$expire]);
}
public function pre_fetch(){
global $_CACHE;
$_CACHE=array();
$cache = $this->read('config');
$_CACHE = @unserialize($cache);
if(empty($_CACHE['version']))$_CACHE = $this->update();
return $_CACHE;
}
public function update() {
global $DB;
$cache = array();
$result = $DB->getAll("SELECT * FROM pre_config");
foreach($result as $row){
$cache[ $row['k'] ] = $row['v'];
}
$this->save('config', $cache);
return $cache;
}
public function clear($key = 'config') {
global $DB;
return $DB->exec("UPDATE pre_cache SET v='' WHERE k=:key", [':key'=>$key]);
}
public function clean() {
global $DB;
return $DB->exec("DELETE FROM pre_cache WHERE expire>0 AND expire<'".time()."'");
}
}

191
includes/lib/Channel.php Normal file
View File

@@ -0,0 +1,191 @@
<?php
namespace lib;
class Channel {
static public function get($id){
global $DB;
$value=$DB->getRow("SELECT * FROM pre_channel WHERE id='$id' LIMIT 1");
return $value;
}
// 支付提交处理(输入支付方式名称)
static public function submit($type, $gid=0){
global $DB;
if(checkmobile()==true){
$sqls = " AND (device=0 OR device=2)";
}else{
$sqls = " AND (device=0 OR device=1)";
}
$paytype=$DB->getRow("SELECT id,name,status FROM pre_type WHERE name='$type'{$sqls} LIMIT 1");
if(!$paytype || $paytype['status']==0)sysmsg('支付方式(type)不存在');
$typeid = $paytype['id'];
$typename = $paytype['name'];
return self::getSubmitInfo($typeid, $typename, $gid);
}
// 支付提交处理2输入支付方式ID
static public function submit2($typeid, $gid=0){
global $DB;
$paytype=$DB->getRow("SELECT id,name,status FROM pre_type WHERE id='$typeid' LIMIT 1");
if(!$paytype || $paytype['status']==0)sysmsg('支付方式(type)不存在');
$typename = $paytype['name'];
return self::getSubmitInfo($typeid, $typename, $gid);
}
//获取通道、插件、费率信息
static public function getSubmitInfo($typeid, $typename, $gid){
global $DB;
if($gid>0)$groupinfo=$DB->getColumn("SELECT info FROM pre_group WHERE gid='$gid' LIMIT 1");
if(!$groupinfo)$groupinfo=$DB->getColumn("SELECT info FROM pre_group WHERE gid=0 LIMIT 1");
if($groupinfo){
$info = json_decode($groupinfo,true);
$groupinfo = $info[$typeid];
if(is_array($groupinfo)){
$channel = $groupinfo['channel'];
$money_rate = $groupinfo['rate'];
}
else{
$channel = -1;
$money_rate = null;
}
if($channel==0){ //当前商户关闭该通道
return false;
}
elseif($channel==-1){ //随机可用通道
$row=$DB->getRow("SELECT id,plugin,status,rate,apptype FROM pre_channel WHERE type='$typeid' AND status=1 ORDER BY rand() LIMIT 1");
if($row){
$channel = $row['id'];
$plugin = $row['plugin'];
$apptype = $row['apptype'];
if(empty($money_rate))$money_rate = $row['rate'];
}
}
else{
if($groupinfo['type']=='roll'){ //解析轮询组
$channel = self::getChannelFromRoll($channel);
if($channel==0){ //当前轮询组未开启
return false;
}
}
$row=$DB->getRow("SELECT plugin,status,rate,apptype FROM pre_channel WHERE id='$channel' LIMIT 1");
if($row['status']==1){
$plugin = $row['plugin'];
$apptype = $row['apptype'];
if(empty($money_rate))$money_rate = $row['rate'];
}
}
}else{
$row=$DB->getRow("SELECT id,plugin,status,rate,apptype FROM pre_channel WHERE type='$typeid' AND status=1 ORDER BY rand() LIMIT 1");
if($row){
$channel = $row['id'];
$plugin = $row['plugin'];
$apptype = $row['apptype'];
$money_rate = $row['rate'];
}
}
if(!$plugin || !$channel){ //通道已关闭
return false;
}
return ['typeid'=>$typeid, 'typename'=>$typename, 'plugin'=>$plugin, 'channel'=>$channel, 'rate'=>$money_rate, 'apptype'=>$apptype];
}
// 获取当前商户可用支付方式
static public function getTypes($gid=0){
global $DB;
if(checkmobile()==true){
$sqls = " AND (device=0 OR device=2)";
}else{
$sqls = " AND (device=0 OR device=1)";
}
$rows = $DB->getAll("SELECT * FROM pre_type WHERE status=1{$sqls}");
$paytype = [];
foreach($rows as $row){
$paytype[$row['id']] = $row;
}
if($gid>0)$groupinfo=$DB->getColumn("SELECT info FROM pre_group WHERE gid='$gid' LIMIT 1");
if(!$groupinfo)$groupinfo=$DB->getColumn("SELECT info FROM pre_group WHERE gid=0 LIMIT 1");
if($groupinfo){
$info = json_decode($groupinfo,true);
foreach($info as $id=>$row){
if(!isset($paytype[$id]))continue;
if($row['channel']==0){
unset($paytype[$id]);
}elseif($row['channel']==-1){
$status=$DB->getColumn("SELECT status FROM pre_channel WHERE type='$id' AND status=1 LIMIT 1");
if(!$status || $status==0){
unset($paytype[$id]);
}elseif(empty($row['rate'])){
$paytype[$id]['rate']=$DB->getColumn("SELECT rate FROM pre_channel WHERE type='$id' AND status=1 LIMIT 1");
}else{
$paytype[$id]['rate']=$row['rate'];
}
}else{
if($row['type']=='roll'){
$status=$DB->getColumn("SELECT status FROM pre_roll WHERE id='{$row['channel']}' LIMIT 1");
}else{
$status=$DB->getColumn("SELECT status FROM pre_channel WHERE id='{$row['channel']}' LIMIT 1");
}
if(!$status || $status==0)unset($paytype[$id]);
else $paytype[$id]['rate']=$row['rate'];
}
}
}else{
foreach($paytype as $id=>$row){
$status=$DB->getColumn("SELECT status FROM pre_channel WHERE type='$id' AND status=1 limit 1");
if(!$status || $status==0)unset($paytype[$id]);
else{
$paytype[$id]['rate']=$DB->getColumn("SELECT rate FROM pre_channel WHERE type='$id' AND status=1 limit 1");
}
}
}
return $paytype;
}
//根据轮询组ID获取支付通道ID
static private function getChannelFromRoll($channel){
global $DB;
$row=$DB->getRow("SELECT * FROM pre_roll WHERE id='$channel' LIMIT 1");
if($row['status']==1){
$info = self::rollinfo_decode($row['info'],true);
if($row['kind']==1){
$channel = self::random_weight($info);
}else{
$channel = $info[$row['index']]['name'];
$index = ($row['index'] + 1) % count($info);
$DB->exec("UPDATE pre_roll SET `index`='$index' WHERE id='{$row['id']}'");
}
return $channel;
}
return false;
}
//解析轮询组info
static private function rollinfo_decode($content){
$result = [];
$arr = explode(',',$content);
foreach($arr as $row){
$a = explode(':',$row);
$result[] = ['name'=>$a[0], 'weight'=>$a[1]];
}
return $result;
}
//加权随机
static private function random_weight($arr){
$weightSum = 0;
foreach ($arr as $value) {
$weightSum += $value['weight'];
}
if($weightSum<=0)return false;
$randNum = rand(1, $weightSum);
foreach ($arr as $k => $v) {
if ($randNum <= $v['weight']) {
return $v['name'];
}
$randNum -=$v['weight'];
}
}
}

273
includes/lib/GeetestLib.php Normal file
View File

@@ -0,0 +1,273 @@
<?php
namespace lib;
/**
* 极验行为式验证安全平台php 网站主后台包含的库文件
*
* @author Tanxu
*/
class GeetestLib {
const GT_SDK_VERSION = 'php_3.0.0';
public static $connectTimeout = 1;
public static $socketTimeout = 1;
private $response;
private $captcha_id;
private $private_key;
public function __construct($captcha_id, $private_key) {
$this->captcha_id = $captcha_id;
$this->private_key = $private_key;
}
/**
* 判断极验服务器是否down机
*
* @param array $data
* @return int
*/
public function pre_process($param, $new_captcha=1) {
if(!empty($this->captcha_id) && !empty($this->private_key)){
$data = array('gt'=>$this->captcha_id,
'new_captcha'=>$new_captcha
);
$data = array_merge($data,$param);
$query = http_build_query($data);
$url = "http://api.geetest.com/register.php?" . $query;
$challenge = $this->send_request($url);
if (strlen($challenge) != 32) {
$this->failback_process();
return 0;
}
$this->success_process($challenge);
return 1;
}else{
$url = "https://www.geetest.com/demo/gt/register-slide?t=" . time() . "123";
$data = get_curl($url,0,'https://www.geetest.com/demo/slide-popup.html');
$this->response = json_decode($data, true);
return 1;
}
}
/**
* @param $challenge
*/
private function success_process($challenge) {
$challenge = md5($challenge . $this->private_key);
$result = array(
'success' => 1,
'gt' => $this->captcha_id,
'challenge' => $challenge,
'new_captcha'=>1
);
$this->response = $result;
}
/**
*
*/
private function failback_process() {
$rnd1 = md5(rand(0, 100));
$rnd2 = md5(rand(0, 100));
$challenge = $rnd1 . substr($rnd2, 0, 2);
$result = array(
'success' => 0,
'gt' => $this->captcha_id,
'challenge' => $challenge,
'new_captcha'=>1
);
$this->response = $result;
}
/**
* @return mixed
*/
public function get_response_str() {
return json_encode($this->response);
}
/**
* 返回数组方便扩展
*
* @return mixed
*/
public function get_response() {
return $this->response;
}
/**
* 正常模式获取验证结果
*
* @param string $challenge
* @param string $validate
* @param string $seccode
* @param array $param
* @return int
*/
public function success_validate($challenge, $validate, $seccode,$param, $json_format=1) {
if(!empty($this->captcha_id) && !empty($this->private_key)){
if (!$this->check_validate($challenge, $validate)) {
return 0;
}
$query = array(
"seccode" => $seccode,
"timestamp"=>time(),
"challenge"=>$challenge,
"captchaid"=>$this->captcha_id,
"json_format"=>$json_format,
"sdk" => self::GT_SDK_VERSION
);
$query = array_merge($query,$param);
$url = "http://api.geetest.com/validate.php";
$codevalidate = $this->post_request($url, $query);
$obj = json_decode($codevalidate,true);
if ($obj === false){
return 0;
}
if ($obj['seccode'] == md5($seccode)) {
return 1;
} else {
return 0;
}
}else{
$url = "https://www.geetest.com/demo/gt/validate-slide";
$post = "geetest_challenge=".$challenge."&geetest_validate=".$validate."&geetest_seccode=".$seccode;
$data = get_curl($url,$post,'https://www.geetest.com/demo/slide-popup.html');
$arr = json_decode($data, true);
if($arr['status'] == 'success')return 1;
else return 0;
}
}
/**
* 宕机模式获取验证结果
*
* @param $challenge
* @param $validate
* @param $seccode
* @return int
*/
public function fail_validate($challenge, $validate, $seccode) {
if(md5($challenge) == $validate){
return 1;
}else{
return 0;
}
}
/**
* @param $challenge
* @param $validate
* @return bool
*/
private function check_validate($challenge, $validate) {
if (strlen($validate) != 32) {
return false;
}
if (md5($this->private_key . 'geetest' . $challenge) != $validate) {
return false;
}
return true;
}
/**
* GET 请求
*
* @param $url
* @return mixed|string
*/
private function send_request($url) {
if (function_exists('curl_exec')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
curl_setopt($ch, CURLOPT_TIMEOUT, self::$socketTimeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$curl_errno = curl_errno($ch);
$data = curl_exec($ch);
curl_close($ch);
if ($curl_errno >0) {
return 0;
}else{
return $data;
}
} else {
$opts = array(
'http' => array(
'method' => "GET",
'timeout' => self::$connectTimeout + self::$socketTimeout,
)
);
$context = stream_context_create($opts);
$data = @file_get_contents($url, false, $context);
if($data){
return $data;
}else{
return 0;
}
}
}
/**
*
* @param $url
* @param array $postdata
* @return mixed|string
*/
private function post_request($url, $postdata = '') {
if (!$postdata) {
return false;
}
$data = http_build_query($postdata);
if (function_exists('curl_exec')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
curl_setopt($ch, CURLOPT_TIMEOUT, self::$socketTimeout);
//不可能执行到的代码
if (!$postdata) {
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
} else {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
$data = curl_exec($ch);
if (curl_errno($ch)) {
$err = sprintf("curl[%s] error[%s]", $url, curl_errno($ch) . ':' . curl_error($ch));
$this->triggerError($err);
}
curl_close($ch);
} else {
if ($postdata) {
$opts = array(
'http' => array(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($data) . "\r\n",
'content' => $data,
'timeout' => self::$connectTimeout + self::$socketTimeout
)
);
$context = stream_context_create($opts);
$data = file_get_contents($url, false, $context);
}
}
return $data;
}
/**
* @param $err
*/
private function triggerError($err) {
trigger_error($err);
}
}

88
includes/lib/PayUtils.php Normal file
View File

@@ -0,0 +1,88 @@
<?php
namespace lib;
class PayUtils {
/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
* @param $para 需要拼接的数组
* return 拼接完成以后的字符串
*/
static public function createLinkstring($para) {
$arg = "";
foreach ($para as $key=>$val) {
$arg.=$key."=".$val."&";
}
//去掉最后一个&字符
$arg = substr($arg,0,-1);
return $arg;
}
/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串并对字符串做urlencode编码
* @param $para 需要拼接的数组
* return 拼接完成以后的字符串
*/
static public function createLinkstringUrlencode($para) {
$arg = "";
foreach ($para as $key=>$val) {
$arg.=$key."=".urlencode($val)."&";
}
//去掉最后一个&字符
$arg = substr($arg,0,-1);
return $arg;
}
/**
* 除去数组中的空值和签名参数
* @param $para 签名参数组
* return 去掉空值与签名参数后的新签名参数组
*/
static public function paraFilter($para) {
$para_filter = array();
foreach ($para as $key=>$val) {
if($key == "sign" || $key == "sign_type" || $val == "")continue;
else $para_filter[$key] = $para[$key];
}
return $para_filter;
}
/**
* 对数组排序
* @param $para 排序前的数组
* return 排序后的数组
*/
static public function argSort($para) {
ksort($para);
reset($para);
return $para;
}
/**
* 签名字符串
* @param $prestr 需要签名的字符串
* @param $key 私钥
* return 签名结果
*/
static public function md5Sign($prestr, $key) {
$prestr = $prestr . $key;
return md5($prestr);
}
/**
* 验证签名
* @param $prestr 需要签名的字符串
* @param $sign 签名结果
* @param $key 私钥
* return 签名结果
*/
static public function md5Verify($prestr, $sign, $key) {
$prestr = $prestr . $key;
$mysgin = md5($prestr);
if($mysgin == $sign) {
return true;
}
else {
return false;
}
}
}

211
includes/lib/PdoHelper.php Normal file
View File

@@ -0,0 +1,211 @@
<?php
namespace lib;
class PdoHelper
{
private $sqlPrefix = "pre_";//SQL数据表前缀识别字符
private $db;
private $fetchStyle = \PDO::FETCH_ASSOC;
private $prefix;
/**
* PdoHelper constructor.
*
* @param array $dbconfig 数据库信息
*/
function __construct($dbconfig)
{
$this->prefix = $dbconfig['dbqz'].'_';
try {
$this->db = new \PDO("mysql:host={$dbconfig['host']};dbname={$dbconfig['dbname']};port={$dbconfig['port']}",$dbconfig['user'],$dbconfig['pwd']);
} catch (Exception $e) {
exit('链接数据库失败:' . $e->getMessage());
}
$this->db->exec("set sql_mode = ''");
$this->db->exec("set names utf8");
}
/**
* 设置结果集方式
*
* @param string $_style
*/
public function setFetchStyle($_style)
{
$this->fetchStyle = $_style;
}
/**
* 替换数据表前缀
* @param $_sql
*
* @return mixed
*/
private function dealPrefix($_sql){
return str_replace($this->sqlPrefix,$this->prefix,$_sql);
}
/**
* 获取PDOStatement
* @param string $_sql
* @param array $_array
*
* @return \PDOStatement
*/
public function query($_sql, $_array = null)
{
$_sql = $this->dealPrefix($_sql);
if (is_array($_array)) {
$stmt = $this->db->prepare($_sql);
if($stmt) $stmt->execute($_array);
} else {
$stmt = $this->db->query($_sql);
}
return $stmt;
}
/**
* 查询一条结果
*
* @param string $_sql string
* @param array $_array array
*
* @return mixed
*/
public function getRow($_sql, $_array = null)
{
$_sql = $this->dealPrefix($_sql);
if (is_array($_array)) {
$stmt = $this->db->prepare($_sql);
if($stmt) $stmt->execute($_array);
} else {
$stmt = $this->db->query($_sql);
}
if($stmt) {
return $stmt->fetch($this->fetchStyle);
}else{
return false;
}
}
/**
* 获取所有结果
*
* @param string $_sql
* @param array $_array
*
* @return array
*/
public function getAll($_sql, $_array = null)
{
$_sql = $this->dealPrefix($_sql);
if (is_array($_array)) {
$stmt = $this->db->prepare($_sql);
if($stmt) $stmt->execute($_array);
} else {
$stmt = $this->db->query($_sql);
}
if($stmt) {
return $stmt->fetchAll($this->fetchStyle);
}else{
return false;
}
}
/**
* 获取结果数
* @param string $_sql
* @param array $_array
*
* @return int
*/
public function getCount($_sql, $_array = null)
{
$_sql = $this->dealPrefix($_sql);
$stmt = $this->db->prepare($_sql);
if($stmt) {
$stmt->execute($_array);
return $stmt->rowCount();
}else{
return false;
}
}
/**
* 获取一个字段值
* @param string $_sql
* @param array $_array
*
* @return int
*/
public function getColumn($_sql, $_array = null)
{
$_sql = $this->dealPrefix($_sql);
if (is_array($_array)) {
$stmt = $this->db->prepare($_sql);
if($stmt) $stmt->execute($_array);
} else {
$stmt = $this->db->query($_sql);
}
if($stmt) {
return $stmt->fetchColumn();
}else{
return false;
}
}
/**
* 执行语句
* @param string $_sql
* @param array $_array
*
* @return int|\PDOStatement
*/
public function exec($_sql, $_array = null)
{
$_sql = $this->dealPrefix($_sql);
if (is_array($_array)) {
$stmt = $this->db->prepare($_sql);
if($stmt) {
return $stmt->execute($_array);
}else{
return false;
}
} else {
return $this->db->exec($_sql);
}
}
/**
* 返回最后插入行的ID
*
* @return int|\PDOStatement
*/
public function lastInsertId()
{
return $this->db->lastInsertId();
}
/**
* 返回错误信息
*
* @return string|\PDOStatement
*/
public function error()
{
$error = $this->db->errorInfo();
return '['.$error[1].']'.$error[2];
}
function __get($name)
{
return $this->$name;
}
function __destruct()
{
$this->db = null;
}
}

124
includes/lib/Plugin.php Normal file
View File

@@ -0,0 +1,124 @@
<?php
namespace lib;
class Plugin {
static public function getList(){
$dir = PLUGIN_ROOT;
$dirArray[] = NULL;
if (false != ($handle = opendir($dir))) {
$i = 0;
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && strpos($file, ".")===false) {
$dirArray[$i] = $file;
$i++;
}
}
closedir($handle);
}
return $dirArray;
}
static public function getConfig($name){
$filename = PLUGIN_ROOT.$name.'/config.ini';
if(file_exists($filename)){
return parse_ini_file($filename);
}else{
return false;
}
}
static public function load($s){
if(preg_match('/^(.[a-zA-Z0-9]+)\/(.[a-zA-Z0-9]+)\/(.[0-9]+)\/$/',$s, $matchs)){
$filename = PLUGIN_ROOT.$matchs[1].'/'.$matchs[2].'.php';
if(file_exists($filename)){
define("IN_PLUGIN", true);
define("PAY_ROOT", PLUGIN_ROOT.$matchs[1].'/');
define("TRADE_NO", $matchs[3]);
define("PAY_PLUGIN", $matchs[1]);
return $filename;
}else{
exit('Pay file not found');
}
}else{
exit('error');
}
}
static public function load2($plugin, $page, $trade_no){
if(preg_match('/^(.[a-zA-Z0-9]+)$/',$plugin) && preg_match('/^(.[a-zA-Z0-9]+)$/',$page) && preg_match('/^(.[0-9]+)$/',$trade_no)){
$filename = PLUGIN_ROOT.$plugin.'/'.$page.'.php';
if(file_exists($filename)){
define("IN_PLUGIN", true);
define("PAY_ROOT", PLUGIN_ROOT.$plugin.'/');
define("TRADE_NO", $trade_no);
define("PAY_PLUGIN", $plugin);
return $filename;
}else{
exit('Pay file not found');
}
}else{
exit('error');
}
}
static public function exists($name){
$filename = PLUGIN_ROOT.$name.'/config.ini';
if(file_exists($filename)){
return true;
}else{
return false;
}
}
static public function isrefund($name){
$filename = PLUGIN_ROOT.$name.'/refund.php';
if(file_exists($filename)){
return true;
}else{
return false;
}
}
static public function refund($plugin, $trade_no){
if(preg_match('/^(.[a-zA-Z0-9]+)$/',$plugin) && preg_match('/^(.[0-9]+)$/',$trade_no)){
$filename = PLUGIN_ROOT.$plugin.'/refund.php';
if(file_exists($filename)){
define("IN_REFUND", true);
define("PAY_ROOT", PLUGIN_ROOT.$plugin.'/');
define("TRADE_NO", $trade_no);
define("PAY_PLUGIN", $plugin);
return $filename;
}else{
return false;
}
}else{
return false;
}
}
static public function updateAll(){
global $DB;
$DB->exec("TRUNCATE TABLE pre_plugin");
$list = self::getList();
foreach($list as $name){
if($config = self::getConfig($name)){
if($config['name']!=$name)continue;
$DB->exec("INSERT INTO pre_plugin VALUES (:name, :showname, :author, :link, :types, :inputs, :select)", [':name'=>$config['name'], ':showname'=>$config['showname'], ':author'=>$config['author'], ':link'=>$config['link'], ':types'=>$config['types'], ':inputs'=>$config['inputs'], ':select'=>$config['select']]);
}
}
return true;
}
static public function get($name){
global $DB;
$result = $DB->getRow("SELECT * FROM pre_plugin WHERE name='$name'");
return $result;
}
static public function getAll(){
global $DB;
$result = $DB->getAll("SELECT * FROM pre_plugin");
return $result;
}
}

117
includes/lib/QC.php Normal file
View File

@@ -0,0 +1,117 @@
<?php
namespace lib;
/* PHP SDK
* @version 2.0.0
* @author connect@qq.com
* @copyright © 2013, Tencent Corporation. All rights reserved.
*/
/*
* @brief QC类api外部对象调用接口全部依赖于此对象
* */
class QC{
const VERSION = "2.0";
const GET_AUTH_CODE_URL = "https://graph.qq.com/oauth2.0/authorize";
const GET_ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token";
const GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me";
function __construct($QC_config){
$this->appid = $QC_config["appid"];
$this->appkey = $QC_config["appkey"];
$this->callback = $QC_config['callback'];
}
public function qq_login(){
$state = md5(uniqid(rand(), TRUE));
$_SESSION['Oauth_state'] = $state;
//-------构造请求参数列表
$keysArr = array(
"response_type" => "code",
"client_id" => $this->appid,
"redirect_uri" => $this->callback,
"state" => $state
);
$login_url = self::GET_AUTH_CODE_URL.'?'.http_build_query($keysArr);
header("Location:$login_url");
}
public function qq_callback(){
if($_GET['state'] != $_SESSION['Oauth_state']){
sysmsg("<h2>The state does not match. You may be a victim of CSRF.</h2>");
}
//-------请求参数列表
$keysArr = array(
"grant_type" => "authorization_code",
"client_id" => $this->appid,
"redirect_uri" => $this->callback,
"client_secret" => $this->appkey,
"code" => $_GET['code']
);
//------构造请求access_token的url
$token_url = self::GET_ACCESS_TOKEN_URL.'?'.http_build_query($keysArr);
$response = $this->get_curl($token_url);
if(strpos($response, "callback") !== false){
$lpos = strpos($response, "(");
$rpos = strrpos($response, ")");
$response = substr($response, $lpos + 1, $rpos - $lpos -1);
$msg = json_decode($response);
if(isset($msg->error)){
sysmsg('<h3>error:</h3>'.$msg->error.'<h3>msg :</h3>'.$msg->error_description);
}
}
$params = array();
parse_str($response, $params);
return $params["access_token"];
}
public function get_openid($access_token){
//-------请求参数列表
$keysArr = array(
"access_token" => $access_token
);
$graph_url = self::GET_OPENID_URL.'?'.http_build_query($keysArr);
$response = $this->get_curl($graph_url);
//--------检测错误是否发生
if(strpos($response, "callback") !== false){
$lpos = strpos($response, "(");
$rpos = strrpos($response, ")");
$response = substr($response, $lpos + 1, $rpos - $lpos -1);
}
$user = json_decode($response);
if(isset($user->error)){
sysmsg('<h3>error:</h3>'.$msg->error.'<h3>msg :</h3>'.$msg->error_description);
}
//------记录openid
return $user->openid;
}
public function get_curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Linux; U; Android 4.4.1; zh-cn) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.5 Mobile Safari/533.1');
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}
}

49
includes/lib/Template.php Normal file
View File

@@ -0,0 +1,49 @@
<?php
namespace lib;
class Template {
static public function getList(){
$dir = TEMPLATE_ROOT;
$dirArray[] = NULL;
if (false != ($handle = opendir($dir))) {
$i = 0;
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && strpos($file, ".")===false) {
$dirArray[$i] = $file;
$i++;
}
}
closedir($handle);
}
return $dirArray;
}
static public function load($name = 'index'){
global $conf;
$template = $conf['template']?$conf['template']:'default';
if(!preg_match('/^[a-zA-Z0-9]+$/',$name))exit('error');
$filename = TEMPLATE_ROOT.$template.'/'.$name.'.php';
$filename_default = TEMPLATE_ROOT.'default/'.$name.'.php';
if(file_exists($filename)){
define("INDEX_ROOT",TEMPLATE_ROOT.$template.'/');
define("STATIC_ROOT",'/template/'.$template.'/assets/');
return $filename;
}elseif(file_exists($filename_default)){
define("INDEX_ROOT",TEMPLATE_ROOT.'default/');
define("STATIC_ROOT",'/template/default/assets/');
return $filename_default;
}else{
exit('Template file not found');
}
}
static public function exists($template){
$filename = TEMPLATE_ROOT.$template.'/index.php';
if(file_exists($filename)){
return true;
}else{
return false;
}
}
}

View File

@@ -0,0 +1,171 @@
<?php
namespace lib;
class hieroglyphy{
private $characters;
private $numbers;
private $unescape;
private $functionConstructor;
public function __construct(){
$this->precharacters();
}
private function precharacters(){
$this->numbers = array(
"+[]",
"+!![]",
"!+[]+!![]",
"!+[]+!![]+!![]",
"!+[]+!![]+!![]+!![]",
"!+[]+!![]+!![]+!![]+!![]",
"!+[]+!![]+!![]+!![]+!![]+!![]",
"!+[]+!![]+!![]+!![]+!![]+!![]+!![]",
"!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]",
"!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]"
);
$this->characters = array(
"0" => "(" . $this->numbers[0] . "+[])",
"1" => "(" . $this->numbers[1] . "+[])",
"2" => "(" . $this->numbers[2] . "+[])",
"3" => "(" . $this->numbers[3] . "+[])",
"4" => "(" . $this->numbers[4] . "+[])",
"5" => "(" . $this->numbers[5] . "+[])",
"6" => "(" . $this->numbers[6] . "+[])",
"7" => "(" . $this->numbers[7] . "+[])",
"8" => "(" . $this->numbers[8] . "+[])",
"9" => "(" . $this->numbers[9] . "+[])"
);
$_object_Object = "[]+{}";
$_NaN = "+{}+[]";
$_true = "!![]+[]";
$_false = "![]+[]";
$_undefined = "[][[]]+[]";
$this->characters[" "] = "(" . $_object_Object . ")[" . $this->numbers[7] . "]";
$this->characters["["] = "(" . $_object_Object . ")[" . $this->numbers[0] . "]";
$this->characters["]"] = "(" . $_object_Object . ")[" . $this->characters[1] . "+" . $this->characters[4] . "]";
$this->characters["a"] = "(" . $_NaN . ")[" . $this->numbers[1] . "]";
$this->characters["b"] = "(" . $_object_Object . ")[" . $this->numbers[2] . "]";
$this->characters["c"] = "(" . $_object_Object . ")[" . $this->numbers[5] . "]";
$this->characters["d"] = "(" . $_undefined . ")[" . $this->numbers[2] . "]";
$this->characters["e"] = "(" . $_undefined . ")[" . $this->numbers[3] . "]";
$this->characters["f"] = "(" . $_false . ")[" . $this->numbers[0] . "]";
$this->characters["i"] = "(" . $_undefined . ")[" . $this->numbers[5] . "]";
$this->characters["j"] = "(" . $_object_Object . ")[" . $this->numbers[3] . "]";
$this->characters["l"] = "(" . $_false . ")[" . $this->numbers[2] . "]";
$this->characters["n"] = "(" . $_undefined . ")[" . $this->numbers[1] . "]";
$this->characters["o"] = "(" . $_object_Object . ")[" . $this->numbers[1] . "]";
$this->characters["r"] = "(" . $_true . ")[" . $this->numbers[1] . "]";
$this->characters["s"] = "(" . $_false . ")[" . $this->numbers[3] . "]";
$this->characters["t"] = "(" . $_true . ")[" . $this->numbers[0] . "]";
$this->characters["u"] = "(" . $_undefined . ")[" . $this->numbers[0] ."]";
$this->characters["N"] = "(" . $_NaN . ")[" . $this->numbers[0] . "]";
$this->characters["O"] = "(" . $_object_Object . ")[" . $this->numbers[8] . "]";
$_Infinity = "+(" . $this->numbers[1] . "+" . $this->characters["e"] . "+" . $this->characters[1] . "+" . $this->characters[0] . "+" . $this->characters[0] . "+" . $this->characters[0] . ")+[]";
$this->characters["y"] = "(" . $_Infinity . ")[" . $this->numbers[7] . "]";
$this->characters["I"] = "(" . $_Infinity . ")[" . $this->numbers[0] . "]";
$_1e100 = "+(" . $this->numbers[1] . "+" . $this->characters["e"] . "+" . $this->characters[1] . "+" . $this->characters[0] . "+" . $this->characters[0] . ")+[]";
$this->characters["+"] = "(" . $_1e100 . ")[" . $this->numbers[2] . "]";
$this->functionConstructor = "[][" . $this->hieroglyphyString("sort") . "][" . $this->hieroglyphyString("constructor") . "]";
//Below $this->characters need target http(s) pages
$locationString = "[]+" . $this->hieroglyphyScript("return location");
$this->characters["h"] = "(" . $locationString . ")" . "[" . $this->numbers[0] . "]";
$this->characters["p"] = "(" . $locationString . ")" . "[" . $this->numbers[3] . "]";
$this->characters["/"] = "(" . $locationString . ")" . "[" . $this->numbers[6] . "]";
$this->unescape = $this->hieroglyphyScript("return unescape");
$escape = $this->hieroglyphyScript("return escape");
$this->characters["%"] = $escape . "(" . $this->hieroglyphyString("[") . ")[" . $this->numbers[0] . "]";
}
private function getHexaString ($number, $digits) {
$string = bin2hex($number);
while (strlen($string) < $digits) {
$string = "0" . $string;
}
return $string;
}
private function getUnescapeSequence ($charCode) {
return $this->unescape . "(" .
$this->hieroglyphyString("%" . $this->getHexaString($charCode, 2)) . ")";
}
private function getHexaSequence ($charCode) {
return $this->hieroglyphyString("\\x" . $this->getHexaString($charCode, 2));
}
private function getUnicodeSequence ($charCode) {
return $this->hieroglyphyString("\\u" . $this->getHexaString($charCode, 4));
}
private function hieroglyphyCharacter ($char) {
$charCode = ord($char);
if (isset($this->characters[$char])) {
return $this->characters[$char];
}
if (($char == "\\") || ($char == "x")) {
//These chars must be handled appart becuase the others need them
$this->characters[$char] = $this->getUnescapeSequence($charCode);
return $this->characters[$char];
}
$shortestSequence = $this->getUnicodeSequence($charCode);
//ASCII $characters can be obtained with hexa and unscape sequences
if ($charCode < 128) {
$unescapeSequence = $this->getUnescapeSequence($charCode);
if (strlen($shortestSequence) > strlen($unescapeSequence)) {
$shortestSequence = $unescapeSequence;
}
$hexaSequence = $this->getHexaSequence($charCode);
if (strlen($shortestSequence) > strlen($hexaSequence)) {
$shortestSequence = $hexaSequence;
}
}
$this->characters[$char] = $shortestSequence;
return $shortestSequence;
}
public function hieroglyphyString ($str) {
$hieroglyphiedStr = "";
for ($i = 0; $i < strlen($str); $i++) {
$hieroglyphiedStr .= ($i > 0) ? "+" : "";
$hieroglyphiedStr .= $this->hieroglyphyCharacter($str[$i]);
}
return $hieroglyphiedStr;
}
public function hieroglyphyNumber ($n) {
$n = +$n;
if ($n <= 9) {
return $this->numbers[$n];
}
return "+(" . $this->hieroglyphyString(ord($n[10])) . ")";
}
public function hieroglyphyScript ($src) {
return $this->functionConstructor . "(" . $this->hieroglyphyString($src) . ")()";
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace lib\mail;
class Aliyun {
private $AccessKeyId;
private $AccessKeySecret;
function __construct($AccessKeyId, $AccessKeySecret){
$this->AccessKeyId = $AccessKeyId;
$this->AccessKeySecret = $AccessKeySecret;
}
private function aliyunSignature($parameters, $accessKeySecret, $method)
{
ksort($parameters);
$canonicalizedQueryString = '';
foreach ($parameters as $key => $value) {
$canonicalizedQueryString .= '&' . $this->percentEncode($key). '=' . $this->percentEncode($value);
}
$stringToSign = $method . '&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
$signature = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret."&", true));
return $signature;
}
private function percentEncode($str)
{
$res = urlencode($str);
$res = preg_replace('/\+/', '%20', $res);
$res = preg_replace('/\*/', '%2A', $res);
$res = preg_replace('/%7E/', '~', $res);
return $res;
}
public function send($to, $sub, $msg, $from, $from_name){
if(empty($this->AccessKeyId)||empty($this->AccessKeySecret))return false;
$url='https://dm.aliyuncs.com/';
$data=array(
'Action' => 'SingleSendMail',
'AccountName' => $from,
'ReplyToAddress' => 'false',
'AddressType' => 1,
'ToAddress' => $to,
'FromAlias' => $from_name,
'Subject' => $sub,
'HtmlBody' => $msg,
'Format' => 'JSON',
'Version' => '2015-11-23',
'AccessKeyId' => $this->AccessKeyId,
'SignatureMethod' => 'HMAC-SHA1',
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
'SignatureVersion' => '1.0',
'SignatureNonce' => random(8));
$data['Signature'] = $this->aliyunSignature($data, $this->AccessKeySecret, 'POST');
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$json=curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$arr=json_decode($json,true);
if($httpCode==200){
return true;
}else{
return $arr['Message'];
}
}
}

236
includes/lib/mail/SMTP.php Normal file
View File

@@ -0,0 +1,236 @@
<?php
/* SMTP Class
* Example:
* $x = new SMTP('smtp.qq.com',25,true,'kenvix@qq.com','*************');
* $x->send('God.Kenvix <kenvix@vip.qq.com>','God.Kenvix <kenvix@qq.com>','f','fff');
*/
namespace lib\mail;
class SMTP {
public $smtp_port;
public $time_out;
public $host_name;
public $log_file;
public $part_boundary = '--PART-BOUNDARY-ID-WRG11-Y4RD1-5AS1D-RE4D1-AF1EG---';
public $relay_host;
public $debug;
public $auth;
public $user;
public $pass;
public $sock;
public $log;
public $error;
public $att = array(); //附件内容
public $ssl = false;
public function __construct($relay_host = '', $smtp_port = 25, $auth = false, $user, $pass , $ssl = false) {
$this ->debug = false;
$this ->smtp_port = $smtp_port;
if ($ssl == true) {
$this->ssl = true;
$relay_host = 'ssl://' . $relay_host;
}
$this ->relay_host = $relay_host;
$this ->time_out = 30;
$this ->auth = $auth;
$this ->user = $user;
$this ->pass = $pass;
$this ->host_name = "localhost";
$this ->log_file = "";
}
/**
* 添加一个附件
* @param string $name 文件名
* @param string $value 文件内容
*/
public function addatt($name , $value = '') {
$this->att[$name] = $value;
}
public function send($to, $from, $subject = "", $body = "", $fromname = "彩虹云任务", $reply = '', $cc = "", $bcc = "", $additional_headers = "") {
if (empty($reply)) {
$reply = $from;
}
$header = "";
$mail_from = $this ->get_address($this ->strip_comment($from));
$from = "=?UTF-8?B?".base64_encode($fromname)."?= " . "<$from>";
$body = mb_ereg_replace("(^|(\r\n))(\\.)", "\\1.\\3", $body);
$header .= "MIME-Version:1.0\r\n";
$header .= 'Content-Type: multipart/mixed; boundary="'.$this->part_boundary.'"' . "\r\n";
$header .= "To: " . $to . "\r\n";
if ($cc!="") $header .= "Cc: " . $cc . "\r\n";
$header .= "From: " . $from . "\r\n";
$header .= "Subject: " . $subject . "\r\n";
$header .= $additional_headers;
$header .= "Date: " . date("r") . "\r\n";
$header .= 'Reply-To: ' . $reply . "\r\n";
$header .= "Content-Transfer-Encoding: base64\r\n";
list($msec, $sec) = explode(" ", microtime());
$header .= "Message-ID: <" . date("YmdHis", $sec) . "." . ($msec*1000000) . "." . $mail_from . ">\r\n";
$TO = explode(",", $this ->strip_comment($to));
if ($cc!="") $TO = array_merge($TO, explode(",", $this ->strip_comment($cc)));
if ($bcc!="") $TO = array_merge($TO, explode(",", $this ->strip_comment($bcc)));
$sent = true;
foreach ($TO as $rcpt_to) {
$rcpt_to = $this ->get_address($rcpt_to);
if (!$this ->smtp_sockopen($rcpt_to)) {
$this ->log_write("Error: Cannot send email to [ " . $rcpt_to . " ] (Step 1)<br/>" . $this->error);
$sent = false;
continue;
}
if ($this ->smtp_send($this ->host_name, $mail_from, $rcpt_to, $header, $body)) {
$this ->log_write("邮件已成功发送到 [" . $rcpt_to . "]\n");
} else {
$this ->log_write("Error: Cannot send email to [ " . $rcpt_to . " ] (Step 2)<br/>" . $this->error);
$sent = false;
}
fclose($this ->sock);
}
return $sent;
}
private function smtp_send($helo, $from, $to, $header, $body = "") {
if (!$this ->smtp_putcmd("HELO", $helo)) return $this ->smtp_error("sending HELO command");
if ($this ->auth) {
if (!$this ->smtp_putcmd("AUTH LOGIN", base64_encode($this ->user))) return $this ->smtp_error("sending HELO command");
if (!$this ->smtp_putcmd("", base64_encode($this ->pass))) return $this ->smtp_error("sending HELO command");
}
if (!$this ->smtp_putcmd("MAIL", "FROM:<" . $from . ">")) return $this ->smtp_error("sending MAIL FROM command");
if (!$this ->smtp_putcmd("RCPT", "TO:<" . $to . ">")) return $this ->smtp_error("sending RCPT TO command");
if (!$this ->smtp_putcmd("DATA")) return $this ->smtp_error("sending DATA command");
if (!$this ->smtp_message($header)) return $this ->smtp_error("sending head message");
if (!$this ->smtp_sendbody($body)) return $this ->smtp_error("sending body message");
if (!$this ->smtp_sendatt()) return $this ->smtp_error("sending attachments message");
if (!$this ->smtp_sendend()) return $this ->smtp_error("sending end message");
if (!$this ->smtp_eom()) return $this ->smtp_error("sending <CR><LF>.<CR><LF> [EOM]");
if (!$this ->smtp_putcmd("QUIT")) return $this ->smtp_error("sending QUIT command");
return true;
}
private function smtp_sockopen($address) {
if ($this ->relay_host=="") return $this ->smtp_sockopen_mx($address); else return $this ->smtp_sockopen_relay();
}
private function smtp_sockopen_relay() {
$this ->log_write("Trying to " . $this ->relay_host . ":" . $this ->smtp_port . "\n");
$this ->sock = @fsockopen($this ->relay_host, $this ->smtp_port, $errno, $errstr, $this ->time_out);
if (!($this ->sock && $this ->smtp_ok())) {
$this ->log_write("Error: Cannot connenct to relay host " . $this ->relay_host . "\n");
$this ->log_write("Error: " . $errstr . " (" . $errno . ")\n");
return false;
}
$this ->log_write("Connected to relay host " . $this ->relay_host . "\n");
return true;;
}
private function smtp_sockopen_mx($address) {
$domain = ereg_replace("^.+@([^@]+)$", "\\1", $address);
if (!@getmxrr($domain, $MXHOSTS)) {
$this ->log_write("Error: Cannot resolve MX \"" . $domain . "\"\n");
return false;
}
foreach ($MXHOSTS as $host) {
$this ->log_write("Trying to " . $host . ":" . $this ->smtp_port . "\n");
$this ->sock = @fsockopen($host, $this ->smtp_port, $errno, $errstr, $this ->time_out);
if (!($this ->sock && $this ->smtp_ok())) {
$this ->log_write("Warning: Cannot connect to mx host " . $host . "\n");
$this ->log_write("Error: " . $errstr . " (" . $errno . ")\n");
continue;
}
$this ->log_write("Connected to mx host " . $host . "\n");
return true;
}
$this ->log_write("Error: Cannot connect to any mx hosts (" . implode(", ", $MXHOSTS) . ")\n");
return false;
}
private function smtp_message($header) {
fputs($this ->sock, $header . "\r\n");
$this ->smtp_debug("> " . str_replace("\r\n", "\n" . "> ", $header . "\n>"));
return true;
}
private function smtp_sendbody($body) {
$head = "\r\n\r\n" . '--' . $this->part_boundary;
$head .= "\r\n" . 'Content-Type: text/html; charset="utf-8"';
$head .= "\r\n" . 'Content-Transfer-Encoding: base64';
$head .= "\r\n\r\n" . base64_encode($body);
return fputs($this ->sock, $head . "\r\n");
}
private function smtp_sendatt() {
$head = '';
foreach ($this->att as $n => $v) {
$head .= "\r\n\r\n" . '--' . $this->part_boundary;
$head .= "\r\n" . 'Content-Type: ' . get_mime(get_extname($n)) . '; charset="utf-8"; name="'.$n.'"';
$head .= "\r\n" . 'Content-Disposition: attachment; filename="'.$n.'"';
$head .= "\r\n" . 'Content-Transfer-Encoding: base64';
$head .= "\r\n\r\n" . base64_encode($v);
}
return fputs($this ->sock, $head . "\r\n");
}
private function smtp_sendend() {
return fputs($this ->sock, "\r\n\r\n" . '--' . $this->part_boundary . '--');
}
private function smtp_eom() {
fputs($this ->sock, "\r\n.\r\n");
$this ->smtp_debug(". [EOM]\n");
return $this ->smtp_ok();
}
private function smtp_ok() {
$response = str_replace("\r\n", "", fgets($this ->sock, 512));
$this ->smtp_debug($response . "\n");
if (!mb_ereg("^[23]", $response)) {
fputs($this ->sock, "QUIT\r\n");
fgets($this ->sock, 512);
$this ->log_write("Error: Remote host returned \"" . $response . "\"\n");
return false;
}
return true;
}
private function smtp_putcmd($cmd, $arg = "") {
if ($arg!="") {
if ($cmd=="") $cmd = $arg; else
$cmd = $cmd . " " . $arg;
}
fputs($this ->sock, $cmd . "\r\n");
$this ->smtp_debug("> " . $cmd . "\n");
return $this ->smtp_ok();
}
private function smtp_error($string) {
$this ->error .= "<br/>Error: Error occurred while " . $string . ".<br/>";
return false;
}
private function log_write($message) {
$this->log .= '<br/>'.$message.'<br/>';
return true;
}
private function strip_comment($address) {
$comment = "\\([^()]*\\)";
while (mb_ereg($comment, $address)) {
$address = mb_ereg_replace($comment, "", $address);
}
return $address;
}
private function get_address($address) {
$address = mb_ereg_replace("([ \t\r\n])+", "", $address);
$address = mb_ereg_replace("^.*<(.+)>.*$", "\\1", $address);
return $address;
}
public function smtp_debug($message) {
if ($this ->debug) {
return $message . "<br>";
}
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace lib\mail;
class Sendcloud {
private $apiUser;
private $apiKey;
function __construct($apiUser, $apiKey){
$this->apiUser = $apiUser;
$this->apiKey = $apiKey;
}
public function send($to, $sub, $msg, $from, $from_name){
if(empty($this->apiUser)||empty($this->apiKey))return false;
$url='http://api.sendcloud.net/apiv2/mail/send';
$data=array(
'apiUser' => $this->apiUser,
'apiKey' => $this->apiKey,
'from' => $from,
'fromName' => $from_name,
'to' => $to,
'subject' => $sub,
'html' => $msg);
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$json=curl_exec($ch);
curl_close($ch);
$arr=json_decode($json,true);
if($arr['statusCode']==200){
return true;
}else{
return implode("\n",$arr['message']);
}
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace lib\sms;
class Aliyun {
private $AccessKeyId;
private $AccessKeySecret;
function __construct($AccessKeyId, $AccessKeySecret){
$this->AccessKeyId = $AccessKeyId;
$this->AccessKeySecret = $AccessKeySecret;
}
private function aliyunSignature($parameters, $accessKeySecret, $method)
{
ksort($parameters);
$canonicalizedQueryString = '';
foreach ($parameters as $key => $value) {
$canonicalizedQueryString .= '&' . $this->percentEncode($key). '=' . $this->percentEncode($value);
}
$stringToSign = $method . '&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
$signature = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret."&", true));
return $signature;
}
private function percentEncode($str)
{
$res = urlencode($str);
$res = preg_replace('/\+/', '%20', $res);
$res = preg_replace('/\*/', '%2A', $res);
$res = preg_replace('/%7E/', '~', $res);
return $res;
}
public function send($phone, $code, $moban, $sign, $sitename){
if(empty($this->AccessKeyId)||empty($this->AccessKeySecret))return false;
$url='https://dysmsapi.aliyuncs.com/';
$TemplateParam = json_encode(['code'=>$code]);
$data=array(
'Action' => 'SendSms',
'PhoneNumbers' => $phone,
'SignName' => $sign,
'TemplateCode' => $moban,
'TemplateParam' => $TemplateParam,
'Format' => 'JSON',
'RegionId' => 'cn-hangzhou',
'Version' => '2017-05-25',
'AccessKeyId' => $this->AccessKeyId,
'SignatureMethod' => 'HMAC-SHA1',
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
'SignatureVersion' => '1.0',
'SignatureNonce' => random(8));
$data['Signature'] = $this->aliyunSignature($data, $this->AccessKeySecret, 'POST');
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$json=curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$arr=json_decode($json,true);
return $arr;
}
}

View File

@@ -0,0 +1,104 @@
<?php
/**
* 单发短信类
*
*/
namespace lib\sms;
class TencentSms
{
private $url;
private $appid;
private $appkey;
private $util;
/**
* 构造函数
*
* @param string $appid sdkappid
* @param string $appkey sdkappid对应的appkey
*/
public function __construct($appid, $appkey)
{
$this->url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms";
$this->appid = $appid;
$this->appkey = $appkey;
$this->util = new TencentSmsUtil();
}
/**
* 普通单发
*
* 普通单发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名。
*
* @param int $type 短信类型0 为普通短信1 营销短信
* @param string $nationCode 国家码,如 86 为中国
* @param string $phoneNumber 不带国家码的手机号
* @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
* @param string $extend 扩展码,可填空串
* @param string $ext 服务端原样返回的参数,可填空串
* @return string 应答json字符串详细内容参见腾讯云协议文档
*/
public function send($type, $nationCode, $phoneNumber, $msg, $extend = "", $ext = "")
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
// 按照协议组织 post 包体
$data = new stdClass();
$tel = new stdClass();
$tel->nationcode = "".$nationCode;
$tel->mobile = "".$phoneNumber;
$data->tel = $tel;
$data->type = (int)$type;
$data->msg = $msg;
$data->sig = hash("sha256",
"appkey=".$this->appkey."&random=".$random."&time="
.$curTime."&mobile=".$phoneNumber, FALSE);
$data->time = $curTime;
$data->extend = $extend;
$data->ext = $ext;
return $this->util->sendCurlPost($wholeUrl, $data);
}
/**
* 指定模板单发
*
* @param string $nationCode 国家码,如 86 为中国
* @param string $phoneNumber 不带国家码的手机号
* @param int $templId 模板 id
* @param array $params 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
* @param string $sign 签名,如果填空串,系统会使用默认签名
* @param string $extend 扩展码,可填空串
* @param string $ext 服务端原样返回的参数,可填空串
* @return string 应答json字符串详细内容参见腾讯云协议文档
*/
public function sendWithParam($nationCode, $phoneNumber, $templId = 0, $params,
$sign = "", $extend = "", $ext = "")
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
// 按照协议组织 post 包体
$data = new stdClass();
$tel = new stdClass();
$tel->nationcode = "".$nationCode;
$tel->mobile = "".$phoneNumber;
$data->tel = $tel;
$data->sig = $this->util->calculateSigForTempl($this->appkey, $random,
$curTime, $phoneNumber);
$data->tpl_id = $templId;
$data->params = $params;
$data->sign = $sign;
$data->time = $curTime;
$data->extend = $extend;
$data->ext = $ext;
return $this->util->sendCurlPost($wholeUrl, $data);
}
}

View File

@@ -0,0 +1,206 @@
<?php
/**
* 发送Util类
*
*/
namespace lib\sms;
class SmsSenderUtil
{
/**
* 生成随机数
*
* @return int 随机数结果
*/
public function getRandom()
{
return rand(100000, 999999);
}
/**
* 生成签名
*
* @param string $appkey sdkappid对应的appkey
* @param string $random 随机正整数
* @param string $curTime 当前时间
* @param array $phoneNumbers 手机号码
* @return string 签名结果
*/
public function calculateSig($appkey, $random, $curTime, $phoneNumbers)
{
$phoneNumbersString = $phoneNumbers[0];
for ($i = 1; $i < count($phoneNumbers); $i++) {
$phoneNumbersString .= ("," . $phoneNumbers[$i]);
}
return hash("sha256", "appkey=".$appkey."&random=".$random
."&time=".$curTime."&mobile=".$phoneNumbersString);
}
/**
* 生成签名
*
* @param string $appkey sdkappid对应的appkey
* @param string $random 随机正整数
* @param string $curTime 当前时间
* @param array $phoneNumbers 手机号码
* @return string 签名结果
*/
public function calculateSigForTemplAndPhoneNumbers($appkey, $random,
$curTime, $phoneNumbers)
{
$phoneNumbersString = $phoneNumbers[0];
for ($i = 1; $i < count($phoneNumbers); $i++) {
$phoneNumbersString .= ("," . $phoneNumbers[$i]);
}
return hash("sha256", "appkey=".$appkey."&random=".$random
."&time=".$curTime."&mobile=".$phoneNumbersString);
}
public function phoneNumbersToArray($nationCode, $phoneNumbers)
{
$i = 0;
$tel = array();
do {
$telElement = new stdClass();
$telElement->nationcode = $nationCode;
$telElement->mobile = $phoneNumbers[$i];
array_push($tel, $telElement);
} while (++$i < count($phoneNumbers));
return $tel;
}
/**
* 生成签名
*
* @param string $appkey sdkappid对应的appkey
* @param string $random 随机正整数
* @param string $curTime 当前时间
* @param array $phoneNumber 手机号码
* @return string 签名结果
*/
public function calculateSigForTempl($appkey, $random, $curTime, $phoneNumber)
{
$phoneNumbers = array($phoneNumber);
return $this->calculateSigForTemplAndPhoneNumbers($appkey, $random,
$curTime, $phoneNumbers);
}
/**
* 生成签名
*
* @param string $appkey sdkappid对应的appkey
* @param string $random 随机正整数
* @param string $curTime 当前时间
* @return string 签名结果
*/
public function calculateSigForPuller($appkey, $random, $curTime)
{
return hash("sha256", "appkey=".$appkey."&random=".$random
."&time=".$curTime);
}
/**
* 生成上传文件授权
*
* @param string $appkey sdkappid对应的appkey
* @param string $random 随机正整数
* @param string $curTime 当前时间
* @param array $fileSha1Sum 文件sha1sum
* @return string 授权结果
*/
public function calculateAuth($appkey, $random, $curTime, $fileSha1Sum)
{
return hash("sha256", "appkey=".$appkey."&random=".$random
."&time=".$curTime."&content-sha1=".$fileSha1Sum);
}
/**
* 生成sha1sum
*
* @param string $content 内容
* @return string 内容sha1散列值
*/
public function sha1sum($content)
{
return hash("sha1", $content);
}
/**
* 发送请求
*
* @param string $url 请求地址
* @param array $dataObj 请求内容
* @return string 应答json字符串
*/
public function sendCurlPost($url, $dataObj)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($dataObj));
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
$ret = curl_exec($curl);
if (false == $ret) {
// curl_exec failed
$result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
} else {
$rsp = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if (200 != $rsp) {
$result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
. " " . curl_error($curl) ."\"}";
} else {
$result = $ret;
}
}
curl_close($curl);
return $result;
}
/**
* 发送请求
*
* @param string $req 请求对象
* @return string 应答json字符串
*/
public function fetch($req)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $req->url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $req->headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $req->body);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
$result = curl_exec($curl);
if (false == $result) {
// curl_exec failed
$result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
} else {
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if (200 != $code) {
$result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $code
. " " . curl_error($curl) ."\"}";
}
}
curl_close($curl);
return $result;
}
}