diff --git a/app/AppService.php b/app/AppService.php
index 96556e8..392dfed 100644
--- a/app/AppService.php
+++ b/app/AppService.php
@@ -1,5 +1,6 @@
app->route->buildUrl($url);
}
- if(empty($msg)) $msg = '未知错误';
+ if (empty($msg)) {
+ $msg = '未知错误';
+ }
- if (request()->isApi) {
- return json(['code'=>$code=='success'?0:-1, 'msg'=>$msg]);
+ if ($this->request->isApi) {
+ return json(['code' => $code == 'success' ? 0 : -1, 'msg' => $msg]);
}
- if (request()->isAjax()) {
- return json(['code'=>$code=='success'?0:-1, 'msg'=>$msg, 'url'=>$url]);
+ if ($this->request->isAjax()) {
+ return json(['code' => $code == 'success' ? 0 : -1, 'msg' => $msg, 'url' => $url]);
}
-
+
View::assign([
'code' => $code,
'msg' => $msg,
diff --git a/app/ExceptionHandle.php b/app/ExceptionHandle.php
index 453d126..42a49aa 100644
--- a/app/ExceptionHandle.php
+++ b/app/ExceptionHandle.php
@@ -1,4 +1,5 @@
setName('dmtask')
- ->setDescription('容灾切换任务');
- }
-
- protected function execute(Input $input, Output $output)
- {
- $res = Db::name('config')->cache('configs',0)->column('value','key');
- Config::set($res, 'sys');
-
- config_set('run_error', '');
- if(!extension_loaded('swoole')){
- $output->writeln('[Error] 未安装Swoole扩展');
- config_set('run_error', '未安装Swoole扩展');
- return;
- }
- try{
- $output->writeln('进程启动成功.');
- $this->runtask();
- }catch(Exception $e){
- $output->writeln('[Error] '.$e->getMessage());
- config_set('run_error', $e->getMessage());
- }
- }
-
- private function runtask(){
- \Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]);
- \Co\run(function() {
- $date = date("Ymd");
- $count = config_get('run_count', null, true) ?? 0;
- while(true){
- sleep(1);
- if($date != date("Ymd")){
- $count = 0;
- $date = date("Ymd");
- }
-
- $rows = Db::name('dmtask')->where('checknexttime', '<=', time())->where('active', 1)->order('id', 'ASC')->select();
- foreach($rows as $row){
- \go(function () use($row) {
- try{
- (new TaskRunner())->execute($row);
- } catch (\Swoole\ExitException $e) {
- echo $e->getStatus()."\n";
- } catch (Exception $e) {
- echo $e->__toString()."\n";
- }
- });
- Db::name('dmtask')->where('id', $row['id'])->update([
- 'checktime' => time(),
- 'checknexttime' => time() + $row['frequency']
- ]);
- $count++;
- }
-
- config_set('run_time', date("Y-m-d H:i:s"));
- config_set('run_count', $count);
- }
- });
- }
-}
+setName('dmtask')
+ ->setDescription('容灾切换任务');
+ }
+
+ protected function execute(Input $input, Output $output)
+ {
+ $res = Db::name('config')->cache('configs', 0)->column('value', 'key');
+ Config::set($res, 'sys');
+
+ config_set('run_error', '');
+ if (!extension_loaded('swoole')) {
+ $output->writeln('[Error] 未安装Swoole扩展');
+ config_set('run_error', '未安装Swoole扩展');
+ return;
+ }
+ try {
+ $output->writeln('进程启动成功.');
+ $this->runtask();
+ } catch (Exception $e) {
+ $output->writeln('[Error] '.$e->getMessage());
+ config_set('run_error', $e->getMessage());
+ }
+ }
+
+ private function runtask()
+ {
+ \Co::set(['hook_flags' => SWOOLE_HOOK_ALL]);
+ \Co\run(function () {
+ $date = date("Ymd");
+ $count = config_get('run_count', null, true) ?? 0;
+ while (true) {
+ sleep(1);
+ if ($date != date("Ymd")) {
+ $count = 0;
+ $date = date("Ymd");
+ }
+
+ $rows = Db::name('dmtask')->where('checknexttime', '<=', time())->where('active', 1)->order('id', 'ASC')->select();
+ foreach ($rows as $row) {
+ \go(function () use ($row) {
+ try {
+ (new TaskRunner())->execute($row);
+ } catch (\Swoole\ExitException $e) {
+ echo $e->getStatus()."\n";
+ } catch (Exception $e) {
+ echo $e->__toString()."\n";
+ }
+ });
+ Db::name('dmtask')->where('id', $row['id'])->update([
+ 'checktime' => time(),
+ 'checknexttime' => time() + $row['frequency']
+ ]);
+ $count++;
+ }
+
+ config_set('run_time', date("Y-m-d H:i:s"));
+ config_set('run_count', $count);
+ }
+ });
+ }
+}
diff --git a/app/command/Opiptask.php b/app/command/Opiptask.php
index e227a56..dd62cc8 100644
--- a/app/command/Opiptask.php
+++ b/app/command/Opiptask.php
@@ -1,32 +1,33 @@
-setName('opiptask')
- ->setDescription('CF优选IP任务');
- }
-
- protected function execute(Input $input, Output $output)
- {
- $res = Db::name('config')->cache('configs',0)->column('value','key');
- Config::set($res, 'sys');
-
- (new OptimizeService())->execute();
- }
-}
+setName('opiptask')
+ ->setDescription('CF优选IP任务');
+ }
+
+ protected function execute(Input $input, Output $output)
+ {
+ $res = Db::name('config')->cache('configs', 0)->column('value', 'key');
+ Config::set($res, 'sys');
+
+ (new OptimizeService())->execute();
+ }
+}
diff --git a/app/common.php b/app/common.php
index b63c4a0..3eaba98 100644
--- a/app/common.php
+++ b/app/common.php
@@ -1,228 +1,257 @@
get($url);
+ } else {
+ $response = $client->post($url, [
+ 'form_params' => $post,
+ 'headers' => $header,
+ 'verify' => false
+ ]);
+ }
+
+ if ($nobody) {
+ $ret = $response->getHeaders();
+ } else {
+ $ret = $response->getBody()->getContents();
+ }
+ return $ret;
}
-function real_ip($type=0){
+function real_ip($type = 0)
+{
$ip = $_SERVER['REMOTE_ADDR'];
- if($type<=0 && isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
- foreach ($matches[0] AS $xip) {
+ if ($type <= 0 && isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
+ foreach ($matches[0] as $xip) {
if (filter_var($xip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
$ip = $xip;
break;
}
}
- } elseif ($type<=0 && isset($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
+ } elseif ($type <= 0 && isset($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
- } elseif ($type<=1 && isset($_SERVER['HTTP_CF_CONNECTING_IP']) && filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
+ } elseif ($type <= 1 && isset($_SERVER['HTTP_CF_CONNECTING_IP']) && filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
- } elseif ($type<=1 && isset($_SERVER['HTTP_X_REAL_IP']) && filter_var($_SERVER['HTTP_X_REAL_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
+ } elseif ($type <= 1 && isset($_SERVER['HTTP_X_REAL_IP']) && filter_var($_SERVER['HTTP_X_REAL_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
$ip = $_SERVER['HTTP_X_REAL_IP'];
}
return $ip;
}
-function strexists($string, $find) {
- return !(strpos($string, $find) === FALSE);
+function strexists($string, $find)
+{
+ return !(strpos($string, $find) === false);
}
-function dstrpos($string, $arr) {
- if(empty($string)) return false;
- foreach((array)$arr as $v) {
- if(strpos($string, $v) !== false) {
- return true;
- }
- }
- return false;
+function dstrpos($string, $arr)
+{
+ if (empty($string)) {
+ return false;
+ }
+ foreach ((array)$arr as $v) {
+ if (strpos($string, $v) !== false) {
+ return true;
+ }
+ }
+ return false;
}
-function checkmobile() {
- $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
- $ualist = array('android', 'midp', 'nokia', 'mobile', 'iphone', 'ipod', 'blackberry', 'windows phone');
- if((dstrpos($useragent, $ualist) || strexists($_SERVER['HTTP_ACCEPT'], "VND.WAP") || strexists($_SERVER['HTTP_VIA'],"wap")))
- return true;
- else
- return false;
+function checkmobile()
+{
+ $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
+ $ualist = array('android', 'midp', 'nokia', 'mobile', 'iphone', 'ipod', 'blackberry', 'windows phone');
+ if ((dstrpos($useragent, $ualist) || strexists($_SERVER['HTTP_ACCEPT'], "VND.WAP") || strexists($_SERVER['HTTP_VIA'], "wap"))) {
+ return true;
+ } else {
+ return false;
+ }
}
-function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
- $ckey_length = 4;
- $key = md5($key);
- $keya = md5(substr($key, 0, 16));
- $keyb = md5(substr($key, 16, 16));
- $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
- $cryptkey = $keya.md5($keya.$keyc);
- $key_length = strlen($cryptkey);
- $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
- $string_length = strlen($string);
- $result = '';
- $box = range(0, 255);
- $rndkey = array();
- for($i = 0; $i <= 255; $i++) {
- $rndkey[$i] = ord($cryptkey[$i % $key_length]);
- }
- for($j = $i = 0; $i < 256; $i++) {
- $j = ($j + $box[$i] + $rndkey[$i]) % 256;
- $tmp = $box[$i];
- $box[$i] = $box[$j];
- $box[$j] = $tmp;
- }
- for($a = $j = $i = 0; $i < $string_length; $i++) {
- $a = ($a + 1) % 256;
- $j = ($j + $box[$a]) % 256;
- $tmp = $box[$a];
- $box[$a] = $box[$j];
- $box[$j] = $tmp;
- $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
- }
- if($operation == 'DECODE') {
- if(((int)substr($result, 0, 10) == 0 || (int)substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
- return substr($result, 26);
- } else {
- return '';
- }
- } else {
- return $keyc.base64_encode($result);
- }
+function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0)
+{
+ $ckey_length = 4;
+ $key = md5($key);
+ $keya = md5(substr($key, 0, 16));
+ $keyb = md5(substr($key, 16, 16));
+ $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
+ $cryptkey = $keya.md5($keya.$keyc);
+ $key_length = strlen($cryptkey);
+ $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
+ $string_length = strlen($string);
+ $result = '';
+ $box = range(0, 255);
+ $rndkey = array();
+ for ($i = 0; $i <= 255; $i++) {
+ $rndkey[$i] = ord($cryptkey[$i % $key_length]);
+ }
+ for ($j = $i = 0; $i < 256; $i++) {
+ $j = ($j + $box[$i] + $rndkey[$i]) % 256;
+ $tmp = $box[$i];
+ $box[$i] = $box[$j];
+ $box[$j] = $tmp;
+ }
+ for ($a = $j = $i = 0; $i < $string_length; $i++) {
+ $a = ($a + 1) % 256;
+ $j = ($j + $box[$a]) % 256;
+ $tmp = $box[$a];
+ $box[$a] = $box[$j];
+ $box[$j] = $tmp;
+ $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
+ }
+ if ($operation == 'DECODE') {
+ if (((int)substr($result, 0, 10) == 0 || (int)substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
+ return substr($result, 26);
+ } else {
+ return '';
+ }
+ } else {
+ return $keyc.base64_encode($result);
+ }
}
-function random($length, $numeric = 0) {
- $seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
- $seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
- $hash = '';
- $max = strlen($seed) - 1;
- for($i = 0; $i < $length; $i++) {
- $hash .= $seed[mt_rand(0, $max)];
- }
- return $hash;
+function random($length, $numeric = 0)
+{
+ $seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
+ $seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
+ $hash = '';
+ $max = strlen($seed) - 1;
+ for ($i = 0; $i < $length; $i++) {
+ $hash .= $seed[mt_rand(0, $max)];
+ }
+ return $hash;
}
-function checkDomain($domain){
- if(empty($domain) || !preg_match('/^[-$a-z0-9_*.]{2,512}$/i', $domain) || (stripos($domain, '.') === false) || substr($domain, -1) == '.' || substr($domain, 0 ,1) == '.' || substr($domain, 0 ,1) == '*' && substr($domain, 1 ,1) != '.' || substr_count($domain, '*')>1 || strpos($domain, '*')>0 || strlen($domain)<4) return false;
- return true;
+function checkDomain($domain)
+{
+ if (empty($domain) || !preg_match('/^[-$a-z0-9_*.]{2,512}$/i', $domain) || (stripos($domain, '.') === false) || str_ends_with($domain, '.') || str_starts_with($domain, '.') || str_starts_with($domain, '*') && substr($domain, 1, 1) != '.' || substr_count($domain, '*') > 1 || strpos($domain, '*') > 0 || strlen($domain) < 4) {
+ return false;
+ }
+ return true;
}
function getSubstr($str, $leftStr, $rightStr)
{
- $left = strpos($str, $leftStr);
- $start = $left+strlen($leftStr);
- $right = strpos($str, $rightStr, $start);
- if($left < 0) return '';
- if($right>0){
- return substr($str, $start, $right-$start);
- }else{
- return substr($str, $start);
- }
+ $left = strpos($str, $leftStr);
+ $start = $left + strlen($leftStr);
+ $right = strpos($str, $rightStr, $start);
+ if ($left < 0) {
+ return '';
+ }
+ if ($right > 0) {
+ return substr($str, $start, $right - $start);
+ } else {
+ return substr($str, $start);
+ }
}
-function checkRefererHost(){
- if(!request()->header('referer'))return false;
- $url_arr = parse_url(request()->header('referer'));
- $http_host = request()->header('host');
- if(strpos($http_host,':'))$http_host = substr($http_host, 0, strpos($http_host, ':'));
+function checkRefererHost()
+{
+ if (!Request::header('referer')) {
+ return false;
+ }
+ $url_arr = parse_url(Request::header('referer'));
+ $http_host = Request::header('host');
+ if (strpos($http_host, ':')) {
+ $http_host = substr($http_host, 0, strpos($http_host, ':'));
+ }
return $url_arr['host'] === $http_host;
}
-function checkIfActive($string) {
- $array=explode(',',$string);
- $action = request()->action();
- if (in_array($action,$array)){
- return 'active';
- }else
- return null;
+function checkIfActive($string)
+{
+ $array = explode(',', $string);
+ $action = Request::action();
+ if (in_array($action, $array)) {
+ return 'active';
+ } else {
+ return null;
+ }
}
-function getSid() {
+function getSid()
+{
return md5(uniqid(mt_rand(), true) . microtime());
}
-function getMd5Pwd($pwd, $salt=null) {
+function getMd5Pwd($pwd, $salt = null)
+{
return md5(md5($pwd) . md5('1277180438'.$salt));
}
-function isNullOrEmpty($str){
- return $str === null || $str === '';
+function isNullOrEmpty($str)
+{
+ return $str === null || $str === '';
}
-function checkPermission($type, $domain = null){
- $user = request()->user;
- if(empty($user)) return false;
- if($user['level'] == 2) return true;
- if($type == 1 && $user['level'] == 1 || $type == 0 && $user['level'] >= 0){
- if($domain == null) return true;
- if(in_array($domain, $user['permission'])){
- return true;
- }
- }
- return false;
+function checkPermission($type, $domain = null)
+{
+ $user = Request()->user;
+ if (empty($user)) {
+ return false;
+ }
+ if ($user['level'] == 2) {
+ return true;
+ }
+ if ($type == 1 && $user['level'] == 1 || $type == 0 && $user['level'] >= 0) {
+ if ($domain == null) {
+ return true;
+ }
+ if (in_array($domain, $user['permission'])) {
+ return true;
+ }
+ }
+ return false;
}
-function getAdminSkin(){
- $skin = cookie('admin_skin');
- if(empty($skin)){
- $skin = config_get('admin_skin');
- }
- if(empty($skin)){
- $skin = 'skin-black-blue';
- }
- return $skin;
+function getAdminSkin()
+{
+ $skin = cookie('admin_skin');
+ if (empty($skin)) {
+ $skin = config_get('admin_skin');
+ }
+ if (empty($skin)) {
+ $skin = 'skin-black-blue';
+ }
+ return $skin;
}
function config_get($key, $default = null, $force = false)
{
- if ($force) {
- $value = Db::name('config')->where('key', $key)->value('value');
- } else {
- $value = config('sys.'.$key);
- }
+ if ($force) {
+ $value = Config::where('key', $key)->value('value');
+ } else {
+ $value = config("sys.$key");
+ }
return $value ?: $default;
}
function config_set($key, $value)
{
- $res = Db::name('config')->replace()->insert(['key'=>$key, 'value'=>$value]);
- return $res!==false;
+ $res = Db::name('config')->replace()->insert(['key' => $key, 'value' => $value]);
+ return $res !== false;
}
function getMillisecond()
@@ -231,24 +260,30 @@ function getMillisecond()
return (int)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
}
-function getDnsType($value){
- if(filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))return 'A';
- else if(filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))return 'AAAA';
- else return 'CNAME';
+function getDnsType($value)
+{
+ if (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
+ return 'A';
+ } elseif (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
+ return 'AAAA';
+ } else {
+ return 'CNAME';
+ }
}
-function convert_second($s){
- $m = floor($s/60);
- if($m == 0){
- return $s.'秒';
- }else{
- $s = $s%60;
- $h = floor($m/60);
- if($h == 0){
- return $m.'分钟'.$s.'秒';
- }else{
- $m = $m%60;
- return $h.'小时'.$m.'分钟'.$s.'秒';
- }
- }
-}
\ No newline at end of file
+function convert_second($s)
+{
+ $m = floor($s / 60);
+ if ($m == 0) {
+ return $s.'秒';
+ } else {
+ $s = $s % 60;
+ $h = floor($m / 60);
+ if ($h == 0) {
+ return $m.'分钟'.$s.'秒';
+ } else {
+ $m = $m % 60;
+ return $h.'小时'.$m.'分钟'.$s.'秒';
+ }
+ }
+}
diff --git a/app/controller/Auth.php b/app/controller/Auth.php
index 389cb2c..05e4835 100644
--- a/app/controller/Auth.php
+++ b/app/controller/Auth.php
@@ -1,61 +1,60 @@
getRuntimePath().'@login.lock';
+ $login_limit_file = app()->getRuntimePath() . '@login.lock';
- if(request()->islogin){
+ if ($this->request->islogin) {
return redirect('/');
}
- if(request()->isAjax()){
- $username = input('post.username',null,'trim');
- $password = input('post.password',null,'trim');
- $code = input('post.code',null,'trim');
-
- if(empty($username) || empty($password)){
- return json(['code'=>-1, 'msg'=>'用户名或密码不能为空']);
+ if ($this->request->isAjax()) {
+ $username = $this->request->post('username', null, 'trim');
+ $password = $this->request->post('password', null, 'trim');
+ $code = $this->request->post('code', null, 'trim');
+
+ if (empty($username) || empty($password)) {
+ return json(['code' => -1, 'msg' => '用户名或密码不能为空']);
}
- if(!captcha_check($code)){
- return json(['code'=>-1, 'msg'=>'验证码错误', 'vcode'=>1]);
+ if (!Captcha::check($code)) {
+ return json(['code' => -1, 'msg' => '验证码错误', 'vcode' => 1]);
}
if (file_exists($login_limit_file)) {
$login_limit = unserialize(file_get_contents($login_limit_file));
if ($login_limit['count'] >= $login_limit_count && $login_limit['time'] > time() - 7200) {
- exit(json_encode(['code' => -1, 'msg' => '多次登录失败,暂时禁止登录。可删除/runtime/@login.lock文件解除限制', 'vcode'=>1]));
+ return json(['code' => -1, 'msg' => '多次登录失败,暂时禁止登录。可删除/runtime/@login.lock文件解除限制', 'vcode' => 1]);
}
}
- $user = Db::name('user')->where('username', $username)->find();
- if($user && password_verify($password, $user['password'])){
- if($user['status'] == 0) return json(['code'=>-1, 'msg'=>'此用户已被封禁', 'vcode'=>1]);
- Db::name('log')->insert(['uid' => $user['id'], 'action' => '登录后台', 'data' => 'IP:'.$this->clientip, 'addtime' => date("Y-m-d H:i:s")]);
- DB::name('user')->where('id', $user['id'])->update(['lasttime' => date("Y-m-d H:i:s")]);
- $session = md5($user['id'].$user['password']);
- $expiretime = time()+2562000;
+ $user = User::where('username', $username)->find();
+ if ($user && password_verify($password, $user['password'])) {
+ if ($user['status'] == 0) {
+ return json(['code' => -1, 'msg' => '此用户已被封禁', 'vcode' => 1]);
+ }
+ Log::insert(['uid' => $user['id'], 'action' => '登录后台', 'data' => 'IP:' . $this->clientip, 'addtime' => date("Y-m-d H:i:s")]);
+ User::where('id', $user['id'])->update(['lasttime' => date("Y-m-d H:i:s")]);
+ $session = md5($user['id'] . $user['password']);
+ $expiretime = time() + 2562000;
$token = authcode("user\t{$user['id']}\t{$session}\t{$expiretime}", 'ENCODE', config_get('sys_key'));
cookie('user_token', $token, ['expire' => $expiretime, 'httponly' => true]);
if (file_exists($login_limit_file)) {
unlink($login_limit_file);
}
- return json(['code'=>0]);
- }else{
- if($user){
- Db::name('log')->insert(['uid' => $user['id'], 'action' => '登录失败', 'data' => 'IP:'.$this->clientip, 'addtime' => date("Y-m-d H:i:s")]);
+ return json(['code' => 0]);
+ } else {
+ if ($user) {
+ Log::insert(['uid' => $user['id'], 'action' => '登录失败', 'data' => 'IP:' . $this->clientip, 'addtime' => date("Y-m-d H:i:s")]);
}
if (!file_exists($login_limit_file)) {
$login_limit = ['count' => 0, 'time' => 0];
@@ -75,44 +74,49 @@ class Auth extends BaseController
return view();
}
- public function logout()
+ public function logout(): response
{
cookie('user_token', null);
return redirect('/login');
}
- public function quicklogin()
+ public function quicklogin(): response
{
- $domain = input('get.domain',null,'trim');
- $timestamp = input('get.timestamp',null,'trim');
- $token = input('get.token',null,'trim');
- $sign = input('get.sign',null,'trim');
- if(empty($domain) || empty($timestamp) || empty($token) || empty($sign)){
+ $domain = $this->request->get('domain', null, 'trim');
+ $timestamp = $this->request->get('timestamp', null, 'trim');
+ $token = $this->request->get('token', null, 'trim');
+ $sign = $this->request->get('sign', null, 'trim');
+ if (empty($domain) || empty($timestamp) || empty($token) || empty($sign)) {
return $this->alert('error', '参数错误');
}
- if($timestamp < time()-300 || $timestamp > time()+300){
+ if ($timestamp < time() - 300 || $timestamp > time() + 300) {
return $this->alert('error', '时间戳无效');
}
- if(md5(config_get('sys_key').$domain.$timestamp.$token.config_get('sys_key')) !== $sign){
+ if (md5(config_get('sys_key') . $domain . $timestamp . $token . config_get('sys_key')) !== $sign) {
return $this->alert('error', '签名错误');
}
- if($token != cache('quicklogin_'.$domain)){
+ if ($token != cache('quicklogin_' . $domain)) {
return $this->alert('error', 'Token无效');
}
- $row = Db::name('domain')->where('name', $domain)->find();
- if(!$row){
+ $row = DomainModel::where('name', $domain)->find();
+ if (!$row) {
return $this->alert('error', '该域名不存在');
}
- if(!$row['is_sso']){
+ if (!$row['is_sso']) {
return $this->alert('error', '该域名不支持快捷登录');
}
- Db::name('log')->insert(['uid' => 0, 'action' => '域名快捷登录', 'data' => 'IP:'.$this->clientip, 'addtime' => date("Y-m-d H:i:s"), 'domain' => $domain]);
+ Log::insert(['uid' => 0, 'action' => '域名快捷登录', 'data' => 'IP:' . $this->clientip, 'addtime' => date("Y-m-d H:i:s"), 'domain' => $domain]);
- $session = md5($row['id'].$row['name']);
- $expiretime = time()+2562000;
+ $session = md5($row['id'] . $row['name']);
+ $expiretime = time() + 2562000;
$token = authcode("domain\t{$row['id']}\t{$session}\t{$expiretime}", 'ENCODE', config_get('sys_key'));
cookie('user_token', $token, ['expire' => $expiretime, 'httponly' => true]);
- return redirect('/record/'.$row['id']);
+ return redirect('/record/' . $row['id']);
+ }
+
+ public function verifycode()
+ {
+ return Captcha::create();
}
}
diff --git a/app/controller/Dmonitor.php b/app/controller/Dmonitor.php
index a3c0344..180c27c 100644
--- a/app/controller/Dmonitor.php
+++ b/app/controller/Dmonitor.php
@@ -1,301 +1,309 @@
-alert('error', '无权限');
- $switch_count = Db::name('dmlog')->where('date', '>=', date("Y-m-d H:i:s",strtotime("-1 days")))->count();
- $fail_count = Db::name('dmlog')->where('date', '>=', date("Y-m-d H:i:s",strtotime("-1 days")))->where('action', 1)->count();
-
- $run_time = config_get('run_time', null, true);
- $run_state = $run_time ? (time()-strtotime($run_time) > 10 ? 0 : 1) : 0;
- View::assign('info', [
- 'run_count' => config_get('run_count', null, true) ?? 0,
- 'run_time' => $run_time ?? '无',
- 'run_state' => $run_state,
- 'run_error' => config_get('run_error', null, true),
- 'switch_count' => $switch_count,
- 'fail_count' => $fail_count,
- 'swoole' => extension_loaded('swoole') ? '已安装' : '未安装',
- ]);
- return View::fetch();
- }
-
- public function task()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- return View::fetch();
- }
-
- public function task_data(){
- if(!checkPermission(2)) return json(['total'=>0, 'rows'=>[]]);
- $type = input('post.type/d', 1);
- $kw = input('post.kw', null, 'trim');
- $offset = input('post.offset/d');
- $limit = input('post.limit/d');
-
- $select = Db::name('dmtask')->alias('A')->join('domain B','A.did = B.id');
- if(!empty($kw)){
- if($type == 1){
- $select->whereLike('rr|B.name', '%'.$kw.'%');
- }elseif($type == 2){
- $select->where('recordid', $kw);
- }elseif($type == 3){
- $select->where('main_value', $kw);
- }elseif($type == 4){
- $select->where('backup_value', $kw);
- }elseif($type == 5){
- $select->whereLike('remark', '%'.$kw.'%');
- }
- }
- $total = $select->count();
- $list = $select->order('A.id','desc')->limit($offset, $limit)->field('A.*,B.name domain')->select()->toArray();
-
- foreach($list as &$row){
- $row['checktimestr'] = date('Y-m-d H:i:s', $row['checktime']);
- }
-
- return json(['total'=>$total, 'rows'=>$list]);
- }
-
- public function taskform()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- $action = input('param.action');
- if(request()->isPost()){
- if($action == 'add'){
- $task = [
- 'did' => input('post.did/d'),
- 'rr' => input('post.rr', null, 'trim'),
- 'recordid' => input('post.recordid', null, 'trim'),
- 'type' => input('post.type/d'),
- 'main_value' => input('post.main_value', null, 'trim'),
- 'backup_value' => input('post.backup_value', null, 'trim'),
- 'checktype' => input('post.checktype/d'),
- 'checkurl' => input('post.checkurl', null, 'trim'),
- 'tcpport' => !empty(input('post.tcpport')) ? input('post.tcpport/d') : null,
- 'frequency' => input('post.frequency/d'),
- 'cycle' => input('post.cycle/d'),
- 'timeout' => input('post.timeout/d'),
- 'proxy' => input('post.proxy/d'),
- 'remark' => input('post.remark', null, 'trim'),
- 'recordinfo' => input('post.recordinfo', null, 'trim'),
- 'addtime' => time(),
- 'active' => 1
- ];
-
- if(empty($task['did']) || empty($task['rr']) || empty($task['recordid']) || empty($task['main_value']) || empty($task['frequency']) || empty($task['cycle'])){
- return json(['code'=>-1, 'msg'=>'必填项不能为空']);
- }
- if($task['checktype'] > 0 && $task['timeout'] > $task['frequency']){
- return json(['code'=>-1, 'msg'=>'为保障容灾切换任务正常运行,最大超时时间不能大于检测间隔']);
- }
- if($task['type'] == 2 && $task['backup_value'] == $task['main_value']){
- return json(['code'=>-1, 'msg'=>'主备地址不能相同']);
- }
- if(Db::name('dmtask')->where('recordid', $task['recordid'])->find()){
- return json(['code'=>-1, 'msg'=>'当前容灾切换策略已存在']);
- }
- Db::name('dmtask')->insert($task);
- return json(['code'=>0, 'msg'=>'添加成功']);
- }elseif($action == 'edit'){
- $id = input('post.id/d');
- $task = [
- 'did' => input('post.did/d'),
- 'rr' => input('post.rr', null, 'trim'),
- 'recordid' => input('post.recordid', null, 'trim'),
- 'type' => input('post.type/d'),
- 'main_value' => input('post.main_value', null, 'trim'),
- 'backup_value' => input('post.backup_value', null, 'trim'),
- 'checktype' => input('post.checktype/d'),
- 'checkurl' => input('post.checkurl', null, 'trim'),
- 'tcpport' => !empty(input('post.tcpport')) ? input('post.tcpport/d') : null,
- 'frequency' => input('post.frequency/d'),
- 'cycle' => input('post.cycle/d'),
- 'timeout' => input('post.timeout/d'),
- 'proxy' => input('post.proxy/d'),
- 'remark' => input('post.remark', null, 'trim'),
- 'recordinfo' => input('post.recordinfo', null, 'trim'),
- ];
-
- if(empty($task['did']) || empty($task['rr']) || empty($task['recordid']) || empty($task['main_value']) || empty($task['frequency']) || empty($task['cycle'])){
- return json(['code'=>-1, 'msg'=>'必填项不能为空']);
- }
- if($task['checktype'] > 0 && $task['timeout'] > $task['frequency']){
- return json(['code'=>-1, 'msg'=>'为保障容灾切换任务正常运行,最大超时时间不能大于检测间隔']);
- }
- if($task['type'] == 2 && $task['backup_value'] == $task['main_value']){
- return json(['code'=>-1, 'msg'=>'主备地址不能相同']);
- }
- if(Db::name('dmtask')->where('recordid', $task['recordid'])->where('id', '<>', $id)->find()){
- return json(['code'=>-1, 'msg'=>'当前容灾切换策略已存在']);
- }
- Db::name('dmtask')->where('id', $id)->update($task);
- return json(['code'=>0, 'msg'=>'修改成功']);
- }elseif($action == 'setactive'){
- $id = input('post.id/d');
- $active = input('post.active/d');
- Db::name('dmtask')->where('id', $id)->update(['active'=>$active]);
- return json(['code'=>0, 'msg'=>'设置成功']);
- }elseif($action == 'del'){
- $id = input('post.id/d');
- Db::name('dmtask')->where('id', $id)->delete();
- Db::name('dmlog')->where('taskid', $id)->delete();
- return json(['code'=>0, 'msg'=>'删除成功']);
- }else{
- return json(['code'=>-1, 'msg'=>'参数错误']);
- }
- }
- $task = null;
- if($action == 'edit'){
- $id = input('get.id/d');
- $task = Db::name('dmtask')->where('id', $id)->find();
- if(empty($task)) return $this->alert('error', '切换策略不存在');
- }
-
- $domains = [];
- foreach(Db::name('domain')->select() as $row){
- $domains[$row['id']] = $row['name'];
- }
- View::assign('domains', $domains);
-
- View::assign('info', $task);
- View::assign('action', $action);
- View::assign('support_ping', function_exists('exec')?'1':'0');
- return View::fetch();
- }
-
- public function taskinfo()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- $id = input('param.id/d');
- $task = Db::name('dmtask')->where('id', $id)->find();
- if(empty($task)) return $this->alert('error', '切换策略不存在');
-
- $switch_count = Db::name('dmlog')->where('taskid', $id)->where('date', '>=', date("Y-m-d H:i:s",strtotime("-1 days")))->count();
- $fail_count = Db::name('dmlog')->where('taskid', $id)->where('date', '>=', date("Y-m-d H:i:s",strtotime("-1 days")))->where('action', 1)->count();
-
- $task['switch_count'] = $switch_count;
- $task['fail_count'] = $fail_count;
- if($task['type'] == 3){
- $task['action_name'] = ['未知', '开启解析', '暂停解析'];
- }elseif($task['type'] == 2){
- $task['action_name'] = ['未知', '切换备用解析记录', '恢复主解析记录'];
- }else{
- $task['action_name'] = ['未知', '暂停解析', '启用解析'];
- }
- View::assign('info', $task);
- return View::fetch();
- }
-
- public function tasklog_data(){
- if(!checkPermission(2)) return json(['total'=>0, 'rows'=>[]]);
- $taskid = input('param.id/d');
- $offset = input('post.offset/d');
- $limit = input('post.limit/d');
- $action = input('post.action/d', 0);
-
- $select = Db::name('dmlog')->where('taskid', $taskid);
- if($action > 0){
- $select->where('action', $action);
- }
- $total = $select->count();
- $list = $select->order('id','desc')->limit($offset, $limit)->select();
-
- return json(['total'=>$total, 'rows'=>$list]);
- }
-
- public function noticeset()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- if(request()->isPost()){
- $params = input('post.');
- if(isset($params['mail_type']) && isset($params['mail_name2']) && $params['mail_type'] > 0){
- $params['mail_name'] = $params['mail_name2'];
- unset($params['mail_name2']);
- }
- foreach ($params as $key=>$value){
- if (empty($key)) {
- continue;
- }
- config_set($key, $value);
- Cache::delete('configs');
- }
- return json(['code'=>0, 'msg'=>'succ']);
- }
- return View::fetch();
- }
-
- public function proxyset()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- if(request()->isPost()){
- $params = input('post.');
- foreach ($params as $key=>$value){
- if (empty($key)) {
- continue;
- }
- config_set($key, $value);
- Cache::delete('configs');
- }
- return json(['code'=>0, 'msg'=>'succ']);
- }
- return View::fetch();
- }
-
- public function mailtest()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- $mail_name = config_get('mail_recv')?config_get('mail_recv'):config_get('mail_name');
- if(empty($mail_name)) return json(['code'=>-1, 'msg'=>'您还未设置邮箱!']);
- $result = \app\lib\MsgNotice::send_mail($mail_name,'邮件发送测试。','这是一封测试邮件!
来自:'.request()->root(true));
- if($result === true){
- return json(['code'=>0, 'msg'=>'邮件发送成功!']);
- }else{
- return json(['code'=>-1, 'msg'=>'邮件发送失败!'.$result]);
- }
- }
-
- public function tgbottest()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- $tgbot_token = config_get('tgbot_token');
- $tgbot_chatid = config_get('tgbot_chatid');
- if(empty($tgbot_token) || empty($tgbot_chatid)) return json(['code'=>-1, 'msg'=>'请先保存设置']);
- $content = "消息发送测试\n\n这是一封测试消息!\n\n来自:".request()->root(true);
- $result = \app\lib\MsgNotice::send_telegram_bot($content);
- if($result === true){
- return json(['code'=>0, 'msg'=>'消息发送成功!']);
- }else{
- return json(['code'=>-1, 'msg'=>'消息发送失败!'.$result]);
- }
- }
-
- public function clean()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- if(request()->isPost()){
- $days = input('post.days/d');
- if(!$days || $days < 0) return json(['code'=>-1, 'msg'=>'参数错误']);
- Db::execute("DELETE FROM `".config('database.connections.mysql.prefix')."dmlog` WHERE `date`<'".date("Y-m-d H:i:s",strtotime("-".$days." days"))."'");
- Db::execute("OPTIMIZE TABLE `".config('database.connections.mysql.prefix')."dmlog`");
- return json(['code'=>0, 'msg'=>'清理成功']);
- }
- }
-
- public function status()
- {
- $run_time = config_get('run_time', null, true);
- $run_state = $run_time ? (time()-strtotime($run_time) > 10 ? 0 : 1) : 0;
- return $run_state == 1 ? 'ok' : 'error';
- }
-}
\ No newline at end of file
+alert('error', '无权限');
+ }
+ $switch_count = Dmlog::where('date', '>=', date("Y-m-d H:i:s", strtotime("-1 days")))->count();
+ $fail_count = Dmlog::where('date', '>=', date("Y-m-d H:i:s", strtotime("-1 days")))->where('action', 1)->count();
+
+ $run_time = config_get('run_time', null, true);
+ $run_state = $run_time ? (time() - strtotime($run_time) > 10 ? 0 : 1) : 0;
+ View::assign('info', [
+ 'run_count' => config_get('run_count', null, true) ?? 0,
+ 'run_time' => $run_time ?? '无',
+ 'run_state' => $run_state,
+ 'run_error' => config_get('run_error', null, true),
+ 'switch_count' => $switch_count,
+ 'fail_count' => $fail_count,
+ 'swoole' => extension_loaded('swoole') ? '已安装' : '未安装',
+ ]);
+ return View::fetch();
+ }
+
+ public function task()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ return View::fetch();
+ }
+
+ public function task_data()
+ {
+ if (!checkPermission(2)) {
+ return json(['total' => 0, 'rows' => []]);
+ }
+ $type = $this->request->post('type', 1);
+ $kw = $this->request->post('kw', null, 'trim');
+ $offset = $this->request->post('offset');
+ $limit = $this->request->post('limit');
+
+ $select = Dmtask::alias('A')->join('domain B', 'A.did = B.id');
+ if (!empty($kw)) {
+ $select = match ($type) {
+ 1 => $select->where('rr', $kw),
+ 2 => $select->where('recordid', $kw),
+ 3 => $select->where('main_value', $kw),
+ 4 => $select->where('backup_value', $kw),
+ 5 => $select->where('remark', $kw),
+ default => throw new Exception('参数错误'),
+ };
+ }
+ $total = $select->count();
+ $list = $select->order('A.id', 'desc')->limit($offset, $limit)->field('A.*,B.name domain')->select()->toArray();
+
+ foreach ($list as &$row) {
+ $row['checktimestr'] = date('Y-m-d H:i:s', $row['checktime']);
+ }
+
+ return json(['total' => $total, 'rows' => $list]);
+ }
+
+ public function taskform()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ $action = $this->request->param('action');
+ if ($this->request->isPost()) {
+ if ($action == 'add') {
+ $task = $this->request->post();
+ $task['addtime'] = time();
+ $task['active'] = 1;
+
+ if (!isset($task['did'], $task['rr'], $task['recordid'], $task['main_value'], $task['frequency'], $task['cycle'])) {
+ return json(['code' => -1, 'msg' => '必填项不能为空']);
+ }
+ if ($task['checktype'] > 0 && $task['timeout'] > $task['frequency']) {
+ return json(['code' => -1, 'msg' => '为保障容灾切换任务正常运行,最大超时时间不能大于检测间隔']);
+ }
+ if ($task['type'] == 2 && $task['backup_value'] == $task['main_value']) {
+ return json(['code' => -1, 'msg' => '主备地址不能相同']);
+ }
+ if (Db::name('dmtask')->where('recordid', $task['recordid'])->find()) {
+ return json(['code' => -1, 'msg' => '当前容灾切换策略已存在']);
+ }
+ Db::name('dmtask')->insert($task);
+ return json(['code' => 0, 'msg' => '添加成功']);
+ } elseif ($action == 'edit') {
+ $id = $this->request->post('id');
+ $task = $this->request->post();
+ unset($task['id']);
+
+ if (!isset($task['did'], $task['rr'], $task['recordid'], $task['main_value'], $task['frequency'], $task['cycle'])) {
+ return json(['code' => -1, 'msg' => '必填项不能为空']);
+ }
+ if ($task['checktype'] > 0 && $task['timeout'] > $task['frequency']) {
+ return json(['code' => -1, 'msg' => '为保障容灾切换任务正常运行,最大超时时间不能大于检测间隔']);
+ }
+ if ($task['type'] == 2 && $task['backup_value'] == $task['main_value']) {
+ return json(['code' => -1, 'msg' => '主备地址不能相同']);
+ }
+ if (Dmtask::where('recordid', $task['recordid'])->where('id', '<>', $id)->find()) {
+ return json(['code' => -1, 'msg' => '当前容灾切换策略已存在']);
+ }
+ Dmtask::where('id', $id)->update($task);
+ return json(['code' => 0, 'msg' => '修改成功']);
+ } elseif ($action == 'setactive') {
+ $id = $this->request->post('id');
+ $active = $this->request->post('active');
+ Dmtask::where('id', $id)->update(['active' => $active]);
+ return json(['code' => 0, 'msg' => '设置成功']);
+ } elseif ($action == 'del') {
+ $id = $this->request->post('id');
+ Dmtask::where('id', $id)->delete();
+ Dmlog::where('taskid', $id)->delete();
+ return json(['code' => 0, 'msg' => '删除成功']);
+ } else {
+ return json(['code' => -1, 'msg' => '参数错误']);
+ }
+ }
+ $task = null;
+ if ($action == 'edit') {
+ $id = $this->request->get('id');
+ $task = Dmtask::where('id', $id)->find();
+ if (empty($task)) {
+ return $this->alert('error', '切换策略不存在');
+ }
+ }
+
+ $domains = [];
+ foreach (Domain::select() as $row) {
+ $domains[$row['id']] = $row['name'];
+ }
+ View::assign('domains', $domains);
+
+ View::assign('info', $task);
+ View::assign('action', $action);
+ View::assign('support_ping', function_exists('exec') ? '1' : '0');
+ return View::fetch();
+ }
+
+ public function taskinfo()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ $id = $this->request->param('id');
+ $task = Dmtask::where('id', $id)->find();
+ if (empty($task)) {
+ return $this->alert('error', '切换策略不存在');
+ }
+
+ $switch_count = Dmlog::where('taskid', $id)->where('date', '>=', date("Y-m-d H:i:s", strtotime("-1 days")))->count();
+ $fail_count = Dmlog::where('taskid', $id)->where('date', '>=', date("Y-m-d H:i:s", strtotime("-1 days")))->where('action', 1)->count();
+
+ $task['switch_count'] = $switch_count;
+ $task['fail_count'] = $fail_count;
+ if ($task['type'] == 3) {
+ $task['action_name'] = ['未知', '开启解析', '暂停解析'];
+ } elseif ($task['type'] == 2) {
+ $task['action_name'] = ['未知', '切换备用解析记录', '恢复主解析记录'];
+ } else {
+ $task['action_name'] = ['未知', '暂停解析', '启用解析'];
+ }
+ View::assign('info', $task);
+ return View::fetch();
+ }
+
+ public function tasklog_data()
+ {
+ if (!checkPermission(2)) {
+ return json(['total' => 0, 'rows' => []]);
+ }
+ $taskid = $this->request->param('id');
+ $offset = $this->request->post('offset');
+ $limit = $this->request->post('limit');
+ $action = $this->request->post('action', 0);
+
+ $select = Dmlog::where('taskid', $taskid);
+ if ($action > 0) {
+ $select->where('action', $action);
+ }
+ $total = $select->count();
+ $list = $select->order('id', 'desc')->limit($offset, $limit)->select();
+
+ return json(['total' => $total, 'rows' => $list]);
+ }
+
+ public function noticeset()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ if ($this->request->isPost()) {
+ $params = $this->request->post();
+ if (isset($params['mail_type']) && isset($params['mail_name2']) && $params['mail_type'] > 0) {
+ $params['mail_name'] = $params['mail_name2'];
+ unset($params['mail_name2']);
+ }
+ foreach ($params as $key => $value) {
+ if (empty($key)) {
+ continue;
+ }
+ config_set($key, $value);
+ Cache::delete('configs');
+ }
+ return json(['code' => 0, 'msg' => 'succ']);
+ }
+ return View::fetch();
+ }
+
+ public function proxyset()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ if ($this->request->isPost()) {
+ $params = $this->request->post();
+ foreach ($params as $key => $value) {
+ if (empty($key)) {
+ continue;
+ }
+ config_set($key, $value);
+ Cache::delete('configs');
+ }
+ return json(['code' => 0, 'msg' => 'succ']);
+ }
+ return View::fetch();
+ }
+
+ public function mailtest()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ $mail_name = config_get('mail_recv') ? config_get('mail_recv') : config_get('mail_name');
+ if (empty($mail_name)) {
+ return json(['code' => -1, 'msg' => '您还未设置邮箱!']);
+ }
+ $result = MsgNotice::send_mail($mail_name, '邮件发送测试。', '这是一封测试邮件!
来自:' . $this->request->root(true));
+ if ($result === true) {
+ return json(['code' => 0, 'msg' => '邮件发送成功!']);
+ } else {
+ return json(['code' => -1, 'msg' => '邮件发送失败!' . $result]);
+ }
+ }
+
+ public function tgbottest()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ $tgbot_token = config_get('tgbot_token');
+ $tgbot_chatid = config_get('tgbot_chatid');
+ if (empty($tgbot_token) || empty($tgbot_chatid)) {
+ return json(['code' => -1, 'msg' => '请先保存设置']);
+ }
+ $content = "消息发送测试\n\n这是一封测试消息!\n\n来自:" . $this->request->root(true);
+ $result = MsgNotice::send_telegram_bot($content);
+ if ($result === true) {
+ return json(['code' => 0, 'msg' => '消息发送成功!']);
+ } else {
+ return json(['code' => -1, 'msg' => '消息发送失败!' . $result]);
+ }
+ }
+
+ public function clean()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ if (Request::isPost()) {
+ $days = $this->request->post('days');
+ if (!$days || $days < 0) {
+ return json(['code' => -1, 'msg' => '参数错误']);
+ }
+ Dmlog::where('date', '<', date("Y-m-d H:i:s", strtotime("-" . $days . " days")))->delete();
+ Db::execute("OPTIMIZE TABLE `" . config('database.connections.mysql.prefix') . "dmlog`");
+ return json(['code' => 0, 'msg' => '清理成功']);
+ }
+ }
+
+ public function status()
+ {
+ $run_time = config_get('run_time', null, true);
+ $run_state = $run_time ? (time() - strtotime($run_time) > 10 ? 0 : 1) : 0;
+ return $run_state == 1 ? 'ok' : 'error';
+ }
+}
diff --git a/app/controller/Index.php b/app/controller/Index.php
index 339cec6..a31c7eb 100644
--- a/app/controller/Index.php
+++ b/app/controller/Index.php
@@ -1,38 +1,41 @@
user['type'] == 'domain'){
- return redirect('/record/'.request()->user['id']);
+ if ($this->request->user['type'] == 'domain') {
+ return redirect('/record/' . $this->request->user['id']);
}
- if(request()->isAjax()){
- if(input('post.do') == 'stat'){
- $stat = ['domains'=>0, 'users'=>0, 'records'=>0, 'types'=>count(DnsHelper::$dns_config)];
- if(request()->user['level'] == 2){
+ if ($this->request->isAjax()) {
+ if (input('post.do') == 'stat') {
+ $stat = ['domains' => 0, 'users' => 0, 'records' => 0, 'types' => count(DnsHelper::$dns_config)];
+ if ($this->request->user['level'] == 2) {
$stat['domains'] = Db::name('domain')->count();
$stat['users'] = Db::name('user')->count();
$stat['records'] = Db::name('domain')->sum('recordcount');
- }else{
- $stat['domains'] = Db::name('domain')->where('name', 'in', request()->user['permission'])->count();
+ } else {
+ $stat['domains'] = Db::name('domain')->where('name', 'in', $this->request->user['permission'])->count();
$stat['users'] = 1;
- $stat['records'] = Db::name('domain')->where('name', 'in', request()->user['permission'])->sum('recordcount');
+ $stat['records'] = Db::name('domain')->where('name', 'in', $this->request->user['permission'])->sum('recordcount');
}
return json($stat);
}
- return json(['code'=>-3]);
+ return json(['code' => -3]);
}
- if(config('app.dbversion') && config_get('version') != config('app.dbversion')){
+ if (config('app.dbversion') && config_get('version') != config('app.dbversion')) {
$this->db_update();
config_set('version', config('app.dbversion'));
Cache::clear();
@@ -49,74 +52,120 @@ class Index extends BaseController
'date' => date("Y-m-d H:i:s"),
];
View::assign('info', $info);
- View::assign('checkupdate', '//auth.cccyun.cc/app/dnsmgr.php?ver='.config('app.version'));
+ View::assign('checkupdate', '//auth.cccyun.cc/app/dnsmgr.php?ver=' . config('app.version'));
return view();
}
- private function db_update(){
- $sqls=file_get_contents(app()->getAppPath().'sql/update.sql');
+ private function db_update()
+ {
+ $sqls = file_get_contents(app()->getAppPath() . 'sql/update.sql');
$mysql_prefix = env('database.prefix', 'dnsmgr_');
- $sqls=explode(';', $sqls);
+ $sqls = explode(';', $sqls);
foreach ($sqls as $value) {
- $value=trim($value);
- if(empty($value))continue;
- $value = str_replace('dnsmgr_',$mysql_prefix,$value);
- try{
+ $value = trim($value);
+ if (empty($value)) {
+ continue;
+ }
+ $value = str_replace('dnsmgr_', $mysql_prefix, $value);
+ try {
Db::execute($value);
- }catch(Exception $e){
-
+ } catch (Exception $e) {
+
}
}
}
- public function changeskin(){
+ public function changeskin()
+ {
$skin = input('post.skin');
- if(request()->user['level'] == 2){
- if(cookie('admin_skin')){
+ if ($this->request->user['level'] == 2) {
+ if (cookie('admin_skin')) {
cookie('admin_skin', null);
}
config_set('admin_skin', $skin);
Cache::delete('configs');
- }else{
+ } else {
cookie('admin_skin', $skin);
}
- return json(['code'=>0,'msg'=>'succ']);
+ return json(['code' => 0, 'msg' => 'succ']);
}
- public function cleancache(){
- if(!checkPermission(1)) return $this->alert('error', '无权限');
+ public function cleancache()
+ {
+ if (!checkPermission(1)) {
+ return $this->alert('error', '无权限');
+ }
Cache::clear();
- return json(['code'=>0,'msg'=>'succ']);
+ $this->clearDirectory(app()->getRuntimePath().'cache/');
+ $this->clearDirectory(app()->getRuntimePath().'temp/');
+ return json(['code' => 0, 'msg' => 'succ']);
}
- public function doc(){
- if(!checkPermission(1)) return $this->alert('error', '无权限');
- View::assign('siteurl', request()->root(true));
+ public function doc()
+ {
+ if (!checkPermission(1)) {
+ return $this->alert('error', '无权限');
+ }
+ View::assign('siteurl', $this->request->root(true));
return view();
}
- public function setpwd(){
- if(!checkPermission(1)) return $this->alert('error', '无权限');
- if(request()->isPost()){
+ public function setpwd()
+ {
+ if (!checkPermission(1)) {
+ return $this->alert('error', '无权限');
+ }
+ if ($this->request->isPost()) {
$oldpwd = input('post.oldpwd');
$newpwd = input('post.newpwd');
$newpwd2 = input('post.newpwd2');
- if(empty($oldpwd) || empty($newpwd) || empty($newpwd2)){
- return json(['code'=>-1, 'msg'=>'密码不能为空']);
+ if (empty($oldpwd) || empty($newpwd) || empty($newpwd2)) {
+ return json(['code' => -1, 'msg' => '密码不能为空']);
}
- if($newpwd != $newpwd2){
- return json(['code'=>-1, 'msg'=>'两次输入的密码不一致']);
+ if ($newpwd != $newpwd2) {
+ return json(['code' => -1, 'msg' => '两次输入的密码不一致']);
}
- if(!password_verify($oldpwd, request()->user['password'])){
- return json(['code'=>-1, 'msg'=>'原密码错误']);
+ if (!password_verify($oldpwd, $this->request->user['password'])) {
+ return json(['code' => -1, 'msg' => '原密码错误']);
}
- Db::name('user')->where('id', request()->user['id'])->update(['password'=>password_hash($newpwd, PASSWORD_DEFAULT)]);
- return json(['code'=>0, 'msg'=>'succ']);
+ Db::name('user')->where('id', $this->request->user['id'])->update(['password' => password_hash($newpwd, PASSWORD_DEFAULT)]);
+ return json(['code' => 0, 'msg' => 'succ']);
}
return view();
}
- public function test(){
+ public function test()
+ {
}
+ private function clearDirectory($dir)
+ {
+ // 确保路径是目录
+ if (!is_dir($dir)) {
+ return false;
+ }
+
+ // 打开目录
+ $items = scandir($dir);
+ foreach ($items as $item) {
+ // 跳过 '.' 和 '..'
+ if ($item == '.' || $item == '..') {
+ continue;
+ }
+
+ // 完整路径
+ $path = $dir . DIRECTORY_SEPARATOR . $item;
+
+ // 如果是目录,递归删除其内容
+ if (is_dir($path)) {
+ clearDirectory($path);
+ // 删除空目录
+ rmdir($path);
+ } else {
+ // 删除文件
+ unlink($path);
+ }
+ }
+ return true;
+ }
}
diff --git a/app/controller/Install.php b/app/controller/Install.php
index c3dcae4..853e435 100644
--- a/app/controller/Install.php
+++ b/app/controller/Install.php
@@ -1,4 +1,5 @@
getRootPath().'.env')){
+ if (file_exists(app()->getRootPath() . '.env')) {
return '当前已经安装成功,如果需要重新安装,请手动删除根目录.env文件';
}
- if(request()->isPost()){
+ if (Request::isPost()) {
$mysql_host = Request::post('mysql_host');
$mysql_port = intval(Request::post('mysql_port', '3306'));
$mysql_user = Request::post('mysql_user', null, 'trim');
@@ -25,65 +26,66 @@ class Install extends BaseController
$admin_username = Request::post('admin_username', null, 'trim');
$admin_password = Request::post('admin_password', null, 'trim');
- if(!$mysql_host || !$mysql_user || !$mysql_pwd || !$mysql_name || !$admin_username || !$admin_password){
- return json(['code'=>0, 'msg'=>'必填项不能为空']);
+ if (!$mysql_host || !$mysql_user || !$mysql_pwd || !$mysql_name || !$admin_username || !$admin_password) {
+ return json(['code' => 0, 'msg' => '必填项不能为空']);
}
- $configData = file_get_contents(app()->getRootPath().'.example.env');
- $configData = str_replace(['{dbhost}','{dbname}','{dbuser}','{dbpwd}','{dbport}','{dbprefix}'], [$mysql_host, $mysql_name, $mysql_user, $mysql_pwd, $mysql_port, $mysql_prefix], $configData);
+ $configData = file_get_contents(app()->getRootPath() . '.example.env');
+ $configData = str_replace(['{dbhost}', '{dbname}', '{dbuser}', '{dbpwd}', '{dbport}', '{dbprefix}'], [$mysql_host, $mysql_name, $mysql_user, $mysql_pwd, $mysql_port, $mysql_prefix], $configData);
- try{
- $DB = Db::connect();
- $DB=new PDO("mysql:host=".$mysql_host.";dbname=".$mysql_name.";port=".$mysql_port,$mysql_user,$mysql_pwd);
- }catch(Exception $e){
- if($e->getCode() == 2002){
- $errorMsg='连接数据库失败:数据库地址填写错误!';
- }elseif($e->getCode() == 1045){
- $errorMsg='连接数据库失败:数据库用户名或密码填写错误!';
- }elseif($e->getCode() == 1049){
- $errorMsg='连接数据库失败:数据库名不存在!';
- }else{
- $errorMsg='连接数据库失败:'.$e->getMessage();
+ try {
+ $DB = new PDO("mysql:host=" . $mysql_host . ";dbname=" . $mysql_name . ";port=" . $mysql_port, $mysql_user, $mysql_pwd);
+ } catch (Exception $e) {
+ if ($e->getCode() == 2002) {
+ $errorMsg = '连接数据库失败:数据库地址填写错误!';
+ } elseif ($e->getCode() == 1045) {
+ $errorMsg = '连接数据库失败:数据库用户名或密码填写错误!';
+ } elseif ($e->getCode() == 1049) {
+ $errorMsg = '连接数据库失败:数据库名不存在!';
+ } else {
+ $errorMsg = '连接数据库失败:' . $e->getMessage();
}
- return json(['code'=>0, 'msg'=>$errorMsg]);
+ return json(['code' => 0, 'msg' => $errorMsg]);
}
$DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
$DB->exec("set sql_mode = ''");
$DB->exec("set names utf8");
- $sqls=file_get_contents(app()->getAppPath().'sql/install.sql');
- $sqls=explode(';', $sqls);
+ $sqls = file_get_contents(app()->getAppPath() . 'sql/install.sql');
+ $sqls = explode(';', $sqls);
$password = password_hash($admin_password, PASSWORD_DEFAULT);
- $sqls[]="REPLACE INTO `".$mysql_prefix."config` VALUES ('sys_key', '".random(16)."')";
- $sqls[]="INSERT INTO `".$mysql_prefix."user` (`username`,`password`,`level`,`regtime`,`lasttime`,`status`) VALUES ('".addslashes($admin_username)."', '$password', 2, NOW(), NOW(), 1)";
+ $sqls[] = "REPLACE INTO `" . $mysql_prefix . "config` VALUES ('sys_key', '" . random(16) . "')";
+ $sqls[] = "INSERT INTO `" . $mysql_prefix . "user` (`username`,`password`,`level`,`regtime`,`lasttime`,`status`) VALUES ('" . addslashes($admin_username) . "', '$password', 2, NOW(), NOW(), 1)";
$success = 0;
$error = 0;
$errorMsg = null;
foreach ($sqls as $value) {
- $value=trim($value);
- if(empty($value))continue;
- $value = str_replace('dnsmgr_',$mysql_prefix,$value);
- if($DB->exec($value)===false){
+ $value = trim($value);
+ if (empty($value)) {
+ continue;
+ }
+ $value = str_replace('dnsmgr_', $mysql_prefix, $value);
+ if ($DB->exec($value) === false) {
$error++;
- $dberror=$DB->errorInfo();
- $errorMsg.=$dberror[2]."\n";
- }else{
+ $dberror = $DB->errorInfo();
+ $errorMsg .= $dberror[2] . "\n";
+ } else {
$success++;
}
}
- if(empty($errorMsg)){
- if(!file_put_contents(app()->getRootPath().'.env', $configData)){
- return json(['code'=>0, 'msg'=>'保存失败,请确保网站根目录有写入权限']);
+ if (empty($errorMsg)) {
+ if (!file_put_contents(app()->getRootPath() . '.env', $configData)) {
+ return json(['code' => 0, 'msg' => '保存失败,请确保网站根目录有写入权限']);
}
Cache::clear();
- return json(['code'=>1, 'msg'=>'安装完成!成功执行SQL语句'.$success.'条']);
- }else{
- return json(['code'=>0, 'msg'=>$errorMsg]);
+ return json(['code' => 1, 'msg' => '安装完成!成功执行SQL语句' . $success . '条']);
+ } else {
+ return json(['code' => 0, 'msg' => $errorMsg]);
}
}
return view();
}
-
+
}
diff --git a/app/controller/Optimizeip.php b/app/controller/Optimizeip.php
index 695182d..0430279 100644
--- a/app/controller/Optimizeip.php
+++ b/app/controller/Optimizeip.php
@@ -1,174 +1,192 @@
-alert('error', '无权限');
- if(request()->isPost()){
- $params = input('post.');
- foreach ($params as $key=>$value){
- if (empty($key)) {
- continue;
- }
- config_set($key, $value);
- Cache::delete('configs');
- }
- return json(['code'=>0, 'msg'=>'succ']);
- }
- return View::fetch();
- }
-
- public function opiplist()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- return View::fetch();
- }
-
- public function opiplist_data(){
- if(!checkPermission(2)) return json(['total'=>0, 'rows'=>[]]);
- $type = input('post.type/d', 1);
- $kw = input('post.kw', null, 'trim');
- $offset = input('post.offset/d');
- $limit = input('post.limit/d');
-
- $select = Db::name('optimizeip')->alias('A')->join('domain B','A.did = B.id');
- if(!empty($kw)){
- if($type == 1){
- $select->whereLike('rr|B.name', '%'.$kw.'%');
- }elseif($type == 2){
- $select->whereLike('remark', '%'.$kw.'%');
- }
- }
- $total = $select->count();
- $list = $select->order('A.id','desc')->limit($offset, $limit)->field('A.*,B.name domain')->select();
-
- return json(['total'=>$total, 'rows'=>$list]);
- }
-
- public function opipform()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- $action = input('param.action');
- if(request()->isPost()){
- if($action == 'add'){
- $task = [
- 'did' => input('post.did/d'),
- 'rr' => input('post.rr', null, 'trim'),
- 'type' => input('post.type/d'),
- 'ip_type' => input('post.ip_type', null, 'trim'),
- 'cdn_type' => input('post.cdn_type/d'),
- 'recordnum' => input('post.recordnum/d'),
- 'ttl' => input('post.ttl/d'),
- 'remark' => input('post.remark', null, 'trim'),
- 'addtime' => date('Y-m-d H:i:s'),
- 'active' => 1
- ];
-
- if(empty($task['did']) || empty($task['rr']) || empty($task['ip_type']) || empty($task['recordnum']) || empty($task['ttl'])){
- return json(['code'=>-1, 'msg'=>'必填项不能为空']);
- }
- if($task['recordnum'] > 5){
- return json(['code'=>-1, 'msg'=>'解析数量不能超过5个']);
- }
- if(Db::name('optimizeip')->where('did', $task['did'])->where('rr', $task['rr'])->find()){
- return json(['code'=>-1, 'msg'=>'当前域名的优选IP任务已存在']);
- }
- Db::name('optimizeip')->insert($task);
- return json(['code'=>0, 'msg'=>'添加成功']);
- }elseif($action == 'edit'){
- $id = input('post.id/d');
- $task = [
- 'did' => input('post.did/d'),
- 'rr' => input('post.rr', null, 'trim'),
- 'type' => input('post.type/d'),
- 'ip_type' => input('post.ip_type', null, 'trim'),
- 'cdn_type' => input('post.cdn_type/d'),
- 'recordnum' => input('post.recordnum/d'),
- 'ttl' => input('post.ttl/d'),
- 'remark' => input('post.remark', null, 'trim'),
- ];
-
- if(empty($task['did']) || empty($task['rr']) || empty($task['ip_type']) || empty($task['recordnum']) || empty($task['ttl'])){
- return json(['code'=>-1, 'msg'=>'必填项不能为空']);
- }
- if($task['recordnum'] > 5){
- return json(['code'=>-1, 'msg'=>'解析数量不能超过5个']);
- }
- if(Db::name('optimizeip')->where('did', $task['did'])->where('rr', $task['rr'])->where('id', '<>', $id)->find()){
- return json(['code'=>-1, 'msg'=>'当前域名的优选IP任务已存在']);
- }
- Db::name('optimizeip')->where('id', $id)->update($task);
- return json(['code'=>0, 'msg'=>'修改成功']);
- }elseif($action == 'setactive'){
- $id = input('post.id/d');
- $active = input('post.active/d');
- Db::name('optimizeip')->where('id', $id)->update(['active'=>$active]);
- return json(['code'=>0, 'msg'=>'设置成功']);
- }elseif($action == 'del'){
- $id = input('post.id/d');
- Db::name('optimizeip')->where('id', $id)->delete();
- return json(['code'=>0, 'msg'=>'删除成功']);
- }elseif($action == 'run'){
- $id = input('post.id/d');
- $task = Db::name('optimizeip')->where('id', $id)->find();
- if(empty($task)) return json(['code'=>-1, 'msg'=>'任务不存在']);
- try{
- $result = (new OptimizeService())->execute_one($task);
- Db::name('optimizeip')->where('id', $id)->update(['status' => 1, 'errmsg' => null, 'updatetime' => date('Y-m-d H:i:s')]);
- return json(['code'=>0, 'msg'=>'优选任务执行成功:'.$result]);
- }catch(Exception $e){
- Db::name('optimizeip')->where('id', $id)->update(['status' => 2, 'errmsg' => $e->getMessage(), 'updatetime' => date('Y-m-d H:i:s')]);
- return json(['code'=>-1, 'msg'=>'优选任务执行失败:'.$e->getMessage(), 'stack'=>$e->__toString()]);
- }
- }else{
- return json(['code'=>-1, 'msg'=>'参数错误']);
- }
- }
- $task = null;
- if($action == 'edit'){
- $id = input('get.id/d');
- $task = Db::name('optimizeip')->where('id', $id)->find();
- if(empty($task)) return $this->alert('error', '任务不存在');
- }
-
- $domains = [];
- foreach(Db::name('domain')->alias('A')->join('account B','A.aid = B.id')->field('A.*')->where('B.type', '<>', 'cloudflare')->select() as $row){
- $domains[$row['id']] = $row['name'];
- }
- View::assign('domains', $domains);
-
- View::assign('info', $task);
- View::assign('action', $action);
- return View::fetch();
- }
-
- public function queryapi()
- {
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- $optimize_ip_api = input('post.optimize_ip_api/d');
- $optimize_ip_key = input('post.optimize_ip_key', null, 'trim');
- if(empty($optimize_ip_key)) return json(['code'=>-1, 'msg'=>'参数不能为空']);
- try{
- $result = (new OptimizeService())->get_license($optimize_ip_api, $optimize_ip_key);
- return json(['code'=>0, 'msg'=>'当前积分余额:'.$result]);
- }catch(Exception $e){
- return json(['code'=>-1, 'msg'=>$e->getMessage()]);
- }
- }
-
- public function status()
- {
- $run_time = Db::name('optimizeip')->where('active', 1)->order('updatetime', 'desc')->value('updatetime');
- $run_state = $run_time ? (time()-strtotime($run_time) > 3600 ? 0 : 1) : 0;
- return $run_state == 1 ? 'ok' : 'error';
- }
-}
\ No newline at end of file
+alert('error', '无权限');
+ }
+ if ($this->request->isPost()) {
+ $params = input('post.');
+ foreach ($params as $key => $value) {
+ if (empty($key)) {
+ continue;
+ }
+ config_set($key, $value);
+ Cache::delete('configs');
+ }
+ return json(['code' => 0, 'msg' => 'succ']);
+ }
+ return View::fetch();
+ }
+
+ public function opiplist()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ return View::fetch();
+ }
+
+ public function opiplist_data()
+ {
+ if (!checkPermission(2)) {
+ return json(['total' => 0, 'rows' => []]);
+ }
+ $type = input('post.type/d', 1);
+ $kw = input('post.kw', null, 'trim');
+ $offset = input('post.offset/d');
+ $limit = input('post.limit/d');
+
+ $select = Db::name('optimizeip')->alias('A')->join('domain B', 'A.did = B.id');
+ if (!empty($kw)) {
+ if ($type == 1) {
+ $select->whereLike('rr|B.name', '%' . $kw . '%');
+ } elseif ($type == 2) {
+ $select->whereLike('remark', '%' . $kw . '%');
+ }
+ }
+ $total = $select->count();
+ $list = $select->order('A.id', 'desc')->limit($offset, $limit)->field('A.*,B.name domain')->select();
+
+ return json(['total' => $total, 'rows' => $list]);
+ }
+
+ public function opipform()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ $action = input('param.action');
+ if ($this->request->isPost()) {
+ if ($action == 'add') {
+ $task = [
+ 'did' => input('post.did/d'),
+ 'rr' => input('post.rr', null, 'trim'),
+ 'type' => input('post.type/d'),
+ 'ip_type' => input('post.ip_type', null, 'trim'),
+ 'cdn_type' => input('post.cdn_type/d'),
+ 'recordnum' => input('post.recordnum/d'),
+ 'ttl' => input('post.ttl/d'),
+ 'remark' => input('post.remark', null, 'trim'),
+ 'addtime' => date('Y-m-d H:i:s'),
+ 'active' => 1
+ ];
+
+ if (empty($task['did']) || empty($task['rr']) || empty($task['ip_type']) || empty($task['recordnum']) || empty($task['ttl'])) {
+ return json(['code' => -1, 'msg' => '必填项不能为空']);
+ }
+ if ($task['recordnum'] > 5) {
+ return json(['code' => -1, 'msg' => '解析数量不能超过5个']);
+ }
+ if (Db::name('optimizeip')->where('did', $task['did'])->where('rr', $task['rr'])->find()) {
+ return json(['code' => -1, 'msg' => '当前域名的优选IP任务已存在']);
+ }
+ Db::name('optimizeip')->insert($task);
+ return json(['code' => 0, 'msg' => '添加成功']);
+ } elseif ($action == 'edit') {
+ $id = input('post.id/d');
+ $task = [
+ 'did' => input('post.did/d'),
+ 'rr' => input('post.rr', null, 'trim'),
+ 'type' => input('post.type/d'),
+ 'ip_type' => input('post.ip_type', null, 'trim'),
+ 'cdn_type' => input('post.cdn_type/d'),
+ 'recordnum' => input('post.recordnum/d'),
+ 'ttl' => input('post.ttl/d'),
+ 'remark' => input('post.remark', null, 'trim'),
+ ];
+
+ if (empty($task['did']) || empty($task['rr']) || empty($task['ip_type']) || empty($task['recordnum']) || empty($task['ttl'])) {
+ return json(['code' => -1, 'msg' => '必填项不能为空']);
+ }
+ if ($task['recordnum'] > 5) {
+ return json(['code' => -1, 'msg' => '解析数量不能超过5个']);
+ }
+ if (Db::name('optimizeip')->where('did', $task['did'])->where('rr', $task['rr'])->where('id', '<>', $id)->find()) {
+ return json(['code' => -1, 'msg' => '当前域名的优选IP任务已存在']);
+ }
+ Db::name('optimizeip')->where('id', $id)->update($task);
+ return json(['code' => 0, 'msg' => '修改成功']);
+ } elseif ($action == 'setactive') {
+ $id = input('post.id/d');
+ $active = input('post.active/d');
+ Db::name('optimizeip')->where('id', $id)->update(['active' => $active]);
+ return json(['code' => 0, 'msg' => '设置成功']);
+ } elseif ($action == 'del') {
+ $id = input('post.id/d');
+ Db::name('optimizeip')->where('id', $id)->delete();
+ return json(['code' => 0, 'msg' => '删除成功']);
+ } elseif ($action == 'run') {
+ $id = input('post.id/d');
+ $task = Db::name('optimizeip')->where('id', $id)->find();
+ if (empty($task)) {
+ return json(['code' => -1, 'msg' => '任务不存在']);
+ }
+ try {
+ $result = (new OptimizeService())->execute_one($task);
+ Db::name('optimizeip')->where('id', $id)->update(['status' => 1, 'errmsg' => null, 'updatetime' => date('Y-m-d H:i:s')]);
+ return json(['code' => 0, 'msg' => '优选任务执行成功:' . $result]);
+ } catch (Exception $e) {
+ Db::name('optimizeip')->where('id', $id)->update(['status' => 2, 'errmsg' => $e->getMessage(), 'updatetime' => date('Y-m-d H:i:s')]);
+ return json(['code' => -1, 'msg' => '优选任务执行失败:' . $e->getMessage(), 'stack' => $e->__toString()]);
+ }
+ } else {
+ return json(['code' => -1, 'msg' => '参数错误']);
+ }
+ }
+ $task = null;
+ if ($action == 'edit') {
+ $id = input('get.id/d');
+ $task = Db::name('optimizeip')->where('id', $id)->find();
+ if (empty($task)) {
+ return $this->alert('error', '任务不存在');
+ }
+ }
+
+ $domains = [];
+ foreach (Db::name('domain')->alias('A')->join('account B', 'A.aid = B.id')->field('A.*')->where('B.type', '<>', 'cloudflare')->select() as $row) {
+ $domains[$row['id']] = $row['name'];
+ }
+ View::assign('domains', $domains);
+
+ View::assign('info', $task);
+ View::assign('action', $action);
+ return View::fetch();
+ }
+
+ public function queryapi()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ $optimize_ip_api = input('post.optimize_ip_api/d');
+ $optimize_ip_key = input('post.optimize_ip_key', null, 'trim');
+ if (empty($optimize_ip_key)) {
+ return json(['code' => -1, 'msg' => '参数不能为空']);
+ }
+ try {
+ $result = (new OptimizeService())->get_license($optimize_ip_api, $optimize_ip_key);
+ return json(['code' => 0, 'msg' => '当前积分余额:' . $result]);
+ } catch (Exception $e) {
+ return json(['code' => -1, 'msg' => $e->getMessage()]);
+ }
+ }
+
+ public function status()
+ {
+ $run_time = Db::name('optimizeip')->where('active', 1)->order('updatetime', 'desc')->value('updatetime');
+ $run_state = $run_time ? (time() - strtotime($run_time) > 3600 ? 0 : 1) : 0;
+ return $run_state == 1 ? 'ok' : 'error';
+ }
+}
diff --git a/app/controller/User.php b/app/controller/User.php
index 99b8ab2..bffcbd1 100644
--- a/app/controller/User.php
+++ b/app/controller/User.php
@@ -1,164 +1,196 @@
-alert('error', '无权限');
- $list = Db::name('domain')->select();
- $domains = [];
- foreach($list as $row){
- $domains[] = $row['name'];
- }
- View::assign('domains', $domains);
- return view();
- }
-
- public function user_data(){
- if(!checkPermission(2)) return json(['total'=>0, 'rows'=>[]]);
- $kw = input('post.kw', null, 'trim');
- $offset = input('post.offset/d');
- $limit = input('post.limit/d');
-
- $select = Db::name('user');
- if(!empty($kw)){
- $select->whereLike('id|username', $kw);
- }
- $total = $select->count();
- $rows = $select->order('id','desc')->limit($offset, $limit)->select();
-
- return json(['total'=>$total, 'rows'=>$rows]);
- }
-
- public function user_op(){
- if(!checkPermission(2)) return $this->alert('error', '无权限');
- $act = input('param.act');
- if($act == 'get'){
- $id = input('post.id/d');
- $row = Db::name('user')->where('id', $id)->find();
- if(!$row) return json(['code'=>-1, 'msg'=>'用户不存在']);
- $row['permission'] = Db::name('permission')->where('uid', $id)->column('domain');
- return json(['code'=>0, 'data'=>$row]);
- }elseif($act == 'add'){
- $username = input('post.username', null, 'trim');
- $password = input('post.password', null, 'trim');
- $is_api = input('post.is_api/d');
- $apikey = input('post.apikey', null, 'trim');
- $level = input('post.level/d');
- if(empty($username) || empty($password)) return json(['code'=>-1, 'msg'=>'用户名或密码不能为空']);
- if($is_api ==1 && empty($apikey)) return json(['code'=>-1, 'msg'=>'API密钥不能为空']);
- if(Db::name('user')->where('username', $username)->find()){
- return json(['code'=>-1, 'msg'=>'用户名已存在']);
- }
- $uid = Db::name('user')->insertGetId([
- 'username' => $username,
- 'password' => password_hash($password, PASSWORD_DEFAULT),
- 'is_api' => $is_api,
- 'apikey' => $apikey,
- 'level' => $level,
- 'regtime' => date('Y-m-d H:i:s'),
- 'status' => 1,
- ]);
- if($level == 1){
- $permission = input('post.permission/a');
- if(!empty($permission)){
- $data = [];
- foreach($permission as $domain){
- $data[] = ['uid'=>$uid, 'domain'=>$domain];
- }
- Db::name('permission')->insertAll($data);
- }
- }
- return json(['code'=>0, 'msg'=>'添加用户成功!']);
- }elseif($act == 'edit'){
- $id = input('post.id/d');
- $row = Db::name('user')->where('id', $id)->find();
- if(!$row) return json(['code'=>-1, 'msg'=>'用户不存在']);
- $username = input('post.username', null, 'trim');
- $is_api = input('post.is_api/d');
- $apikey = input('post.apikey', null, 'trim');
- $level = input('post.level/d');
- $repwd = input('post.repwd', null, 'trim');
- if(empty($username)) return json(['code'=>-1, 'msg'=>'用户名不能为空']);
- if($is_api ==1 && empty($apikey)) return json(['code'=>-1, 'msg'=>'API密钥不能为空']);
- if(Db::name('user')->where('username', $username)->where('id', '<>', $id)->find()){
- return json(['code'=>-1, 'msg'=>'用户名已存在']);
- }
- if($level == 1 && ($id == 1000 || $id == request()->user['id'])) $level = 2;
- Db::name('user')->where('id', $id)->update([
- 'username' => $username,
- 'is_api' => $is_api,
- 'apikey' => $apikey,
- 'level' => $level,
- ]);
- Db::name('permission')->where(['uid'=>$id])->delete();
- if($level == 1){
- $permission = input('post.permission/a');
- if(!empty($permission)){
- $data = [];
- foreach($permission as $domain){
- $data[] = ['uid'=>$id, 'domain'=>$domain];
- }
- Db::name('permission')->insertAll($data);
- }
- }
- if(!empty($repwd)){
- Db::name('user')->where('id', $id)->update(['password'=>password_hash($repwd, PASSWORD_DEFAULT)]);
- }
- return json(['code'=>0, 'msg'=>'修改用户成功!']);
- }elseif($act == 'set'){
- $id = input('post.id/d');
- $status = input('post.status/d');
- if($id == 1000) return json(['code'=>-1, 'msg'=>'此用户无法修改状态']);
- if($id == request()->user['id']) return json(['code'=>-1, 'msg'=>'当前登录用户无法修改状态']);
- Db::name('user')->where('id', $id)->update(['status'=>$status]);
- return json(['code'=>0]);
- }elseif($act == 'del'){
- $id = input('post.id/d');
- if($id == 1000) return json(['code'=>-1, 'msg'=>'此用户无法删除']);
- if($id == request()->user['id']) return json(['code'=>-1, 'msg'=>'当前登录用户无法删除']);
- Db::name('user')->where('id', $id)->delete();
- return json(['code'=>0]);
- }
- return json(['code'=>-3]);
- }
-
- public function log(){
- return view();
- }
-
- public function log_data(){
- $uid = input('post.uid', null, 'trim');
- $kw = input('post.kw', null, 'trim');
- $domain = input('post.domain', null, 'trim');
- $offset = input('post.offset/d');
- $limit = input('post.limit/d');
-
- $select = Db::name('log');
- if(request()->user['type'] == 'domain'){
- $select->where('domain', request()->user['name']);
- }elseif(request()->user['level'] == 1){
- $select->where('uid', request()->user['id']);
- }elseif(!empty($uid)){
- $select->where('uid', $uid);
- }
- if(!empty($kw)){
- $select->whereLike('action|data', '%'.$kw.'%');
- }
- if(!empty($domain)){
- $select->where('domain', $domain);
- }
- $total = $select->count();
- $rows = $select->order('id','desc')->limit($offset, $limit)->select();
-
- return json(['total'=>$total, 'rows'=>$rows]);
- }
-
-}
\ No newline at end of file
+alert('error', '无权限');
+ }
+ $list = Db::name('domain')->select();
+ $domains = [];
+ foreach ($list as $row) {
+ $domains[] = $row['name'];
+ }
+ View::assign('domains', $domains);
+ return view();
+ }
+
+ public function user_data()
+ {
+ if (!checkPermission(2)) {
+ return json(['total' => 0, 'rows' => []]);
+ }
+ $kw = input('post.kw', null, 'trim');
+ $offset = input('post.offset/d');
+ $limit = input('post.limit/d');
+
+ $select = Db::name('user');
+ if (!empty($kw)) {
+ $select->whereLike('id|username', $kw);
+ }
+ $total = $select->count();
+ $rows = $select->order('id', 'desc')->limit($offset, $limit)->select();
+
+ return json(['total' => $total, 'rows' => $rows]);
+ }
+
+ public function user_op()
+ {
+ if (!checkPermission(2)) {
+ return $this->alert('error', '无权限');
+ }
+ $act = input('param.act');
+ if ($act == 'get') {
+ $id = input('post.id/d');
+ $row = Db::name('user')->where('id', $id)->find();
+ if (!$row) {
+ return json(['code' => -1, 'msg' => '用户不存在']);
+ }
+ $row['permission'] = Db::name('permission')->where('uid', $id)->column('domain');
+ return json(['code' => 0, 'data' => $row]);
+ } elseif ($act == 'add') {
+ $username = input('post.username', null, 'trim');
+ $password = input('post.password', null, 'trim');
+ $is_api = input('post.is_api/d');
+ $apikey = input('post.apikey', null, 'trim');
+ $level = input('post.level/d');
+ if (empty($username) || empty($password)) {
+ return json(['code' => -1, 'msg' => '用户名或密码不能为空']);
+ }
+ if ($is_api == 1 && empty($apikey)) {
+ return json(['code' => -1, 'msg' => 'API密钥不能为空']);
+ }
+ if (Db::name('user')->where('username', $username)->find()) {
+ return json(['code' => -1, 'msg' => '用户名已存在']);
+ }
+ $uid = Db::name('user')->insertGetId([
+ 'username' => $username,
+ 'password' => password_hash($password, PASSWORD_DEFAULT),
+ 'is_api' => $is_api,
+ 'apikey' => $apikey,
+ 'level' => $level,
+ 'regtime' => date('Y-m-d H:i:s'),
+ 'status' => 1,
+ ]);
+ if ($level == 1) {
+ $permission = input('post.permission/a');
+ if (!empty($permission)) {
+ $data = [];
+ foreach ($permission as $domain) {
+ $data[] = ['uid' => $uid, 'domain' => $domain];
+ }
+ Db::name('permission')->insertAll($data);
+ }
+ }
+ return json(['code' => 0, 'msg' => '添加用户成功!']);
+ } elseif ($act == 'edit') {
+ $id = input('post.id/d');
+ $row = Db::name('user')->where('id', $id)->find();
+ if (!$row) {
+ return json(['code' => -1, 'msg' => '用户不存在']);
+ }
+ $username = input('post.username', null, 'trim');
+ $is_api = input('post.is_api/d');
+ $apikey = input('post.apikey', null, 'trim');
+ $level = input('post.level/d');
+ $repwd = input('post.repwd', null, 'trim');
+ if (empty($username)) {
+ return json(['code' => -1, 'msg' => '用户名不能为空']);
+ }
+ if ($is_api == 1 && empty($apikey)) {
+ return json(['code' => -1, 'msg' => 'API密钥不能为空']);
+ }
+ if (Db::name('user')->where('username', $username)->where('id', '<>', $id)->find()) {
+ return json(['code' => -1, 'msg' => '用户名已存在']);
+ }
+ if ($level == 1 && ($id == 1000 || $id == $this->request->user['id'])) {
+ $level = 2;
+ }
+ Db::name('user')->where('id', $id)->update([
+ 'username' => $username,
+ 'is_api' => $is_api,
+ 'apikey' => $apikey,
+ 'level' => $level,
+ ]);
+ Db::name('permission')->where(['uid' => $id])->delete();
+ if ($level == 1) {
+ $permission = input('post.permission/a');
+ if (!empty($permission)) {
+ $data = [];
+ foreach ($permission as $domain) {
+ $data[] = ['uid' => $id, 'domain' => $domain];
+ }
+ Db::name('permission')->insertAll($data);
+ }
+ }
+ if (!empty($repwd)) {
+ Db::name('user')->where('id', $id)->update(['password' => password_hash($repwd, PASSWORD_DEFAULT)]);
+ }
+ return json(['code' => 0, 'msg' => '修改用户成功!']);
+ } elseif ($act == 'set') {
+ $id = input('post.id/d');
+ $status = input('post.status/d');
+ if ($id == 1000) {
+ return json(['code' => -1, 'msg' => '此用户无法修改状态']);
+ }
+ if ($id == $this->request->user['id']) {
+ return json(['code' => -1, 'msg' => '当前登录用户无法修改状态']);
+ }
+ Db::name('user')->where('id', $id)->update(['status' => $status]);
+ return json(['code' => 0]);
+ } elseif ($act == 'del') {
+ $id = input('post.id/d');
+ if ($id == 1000) {
+ return json(['code' => -1, 'msg' => '此用户无法删除']);
+ }
+ if ($id == $this->request->user['id']) {
+ return json(['code' => -1, 'msg' => '当前登录用户无法删除']);
+ }
+ Db::name('user')->where('id', $id)->delete();
+ return json(['code' => 0]);
+ }
+ return json(['code' => -3]);
+ }
+
+ public function log()
+ {
+ return view();
+ }
+
+ public function log_data()
+ {
+ $uid = input('post.uid', null, 'trim');
+ $kw = input('post.kw', null, 'trim');
+ $domain = input('post.domain', null, 'trim');
+ $offset = input('post.offset/d');
+ $limit = input('post.limit/d');
+
+ $select = Db::name('log');
+ if ($this->request->user['type'] == 'domain') {
+ $select->where('domain', $this->request->user['name']);
+ } elseif ($this->request->user['level'] == 1) {
+ $select->where('uid', $this->request->user['id']);
+ } elseif (!empty($uid)) {
+ $select->where('uid', $uid);
+ }
+ if (!empty($kw)) {
+ $select->whereLike('action|data', '%' . $kw . '%');
+ }
+ if (!empty($domain)) {
+ $select->where('domain', $domain);
+ }
+ $total = $select->count();
+ $rows = $select->order('id', 'desc')->limit($offset, $limit)->select();
+
+ return json(['total' => $total, 'rows' => $rows]);
+ }
+
+}
diff --git a/app/event.php b/app/event.php
index e9851bb..c3393e1 100644
--- a/app/event.php
+++ b/app/event.php
@@ -1,4 +1,5 @@
[
diff --git a/app/lib/CheckUtils.php b/app/lib/CheckUtils.php
index 2b4ba21..3c173c2 100644
--- a/app/lib/CheckUtils.php
+++ b/app/lib/CheckUtils.php
@@ -1,112 +1,120 @@
-= 400)){
- $status = false;
- $errmsg = 'http_code='.$httpcode;
- }
- $usetime = round(curl_getinfo($ch, CURLINFO_TOTAL_TIME) * 1000);
- curl_close($ch);
- return ['status'=>$status, 'errmsg'=>$errmsg, 'usetime'=>$usetime];
- }
-
- public static function tcp($target, $port, $timeout){
- if(!filter_var($target,FILTER_VALIDATE_IP) && checkDomain($target)){
- $target = gethostbyname($target);
- if(!$target)return ['status'=>false, 'error'=>'DNS resolve failed', 'usetime'=>0];
- }
- $starttime = getMillisecond();
- $fp = @fsockopen($target, $port, $errCode, $errStr, $timeout);
- if ($fp) {
- $status = true;
- fclose($fp);
- } else {
- $status = false;
- }
- $endtime = getMillisecond();
- $usetime = $endtime-$starttime;
- return ['status'=>$status, 'errmsg'=>$errStr, 'usetime'=>$usetime];
- }
-
- public static function ping($target){
- if(!function_exists('exec'))return ['status'=>false, 'error'=>'exec函数不可用', 'usetime'=>0];
- if(!filter_var($target,FILTER_VALIDATE_IP) && checkDomain($target)){
- $target = gethostbyname($target);
- if(!$target)return ['status'=>false, 'error'=>'DNS resolve failed', 'usetime'=>0];
- }
- if(!filter_var($target,FILTER_VALIDATE_IP)){
- return ['status'=>false, 'error'=>'Invalid IP address', 'usetime'=>0];
- }
- $timeout = 1;
- exec('ping -c 1 -w '.$timeout.' '.$target.'', $output, $return_var);
- $usetime = !empty($output[1]) ? round(getSubstr($output[1], 'time=', ' ms')) : 0;
- $errmsg = null;
- if($return_var !== 0){
- $usetime = $usetime == 0 ? $timeout*1000 : $usetime;
- $errmsg = 'ping timeout';
- }
- return ['status'=>$return_var===0, 'errmsg'=>$errmsg, 'usetime'=>$usetime];
- }
-}
\ No newline at end of file
+= 400)) {
+ $status = false;
+ $errmsg = 'http_code='.$httpcode;
+ }
+ $usetime = round(curl_getinfo($ch, CURLINFO_TOTAL_TIME) * 1000);
+ curl_close($ch);
+ return ['status' => $status, 'errmsg' => $errmsg, 'usetime' => $usetime];
+ }
+
+ public static function tcp($target, $port, $timeout)
+ {
+ if (!filter_var($target, FILTER_VALIDATE_IP) && checkDomain($target)) {
+ $target = gethostbyname($target);
+ if (!$target) {
+ return ['status' => false, 'error' => 'DNS resolve failed', 'usetime' => 0];
+ }
+ }
+ $starttime = getMillisecond();
+ $fp = @fsockopen($target, $port, $errCode, $errStr, $timeout);
+ if ($fp) {
+ $status = true;
+ fclose($fp);
+ } else {
+ $status = false;
+ }
+ $endtime = getMillisecond();
+ $usetime = $endtime - $starttime;
+ return ['status' => $status, 'errmsg' => $errStr, 'usetime' => $usetime];
+ }
+
+ public static function ping($target)
+ {
+ if (!function_exists('exec')) {
+ return ['status' => false, 'error' => 'exec函数不可用', 'usetime' => 0];
+ }
+ if (!filter_var($target, FILTER_VALIDATE_IP) && checkDomain($target)) {
+ $target = gethostbyname($target);
+ if (!$target) {
+ return ['status' => false, 'error' => 'DNS resolve failed', 'usetime' => 0];
+ }
+ }
+ if (!filter_var($target, FILTER_VALIDATE_IP)) {
+ return ['status' => false, 'error' => 'Invalid IP address', 'usetime' => 0];
+ }
+ $timeout = 1;
+ exec('ping -c 1 -w '.$timeout.' '.$target.'', $output, $return_var);
+ $usetime = !empty($output[1]) ? round(getSubstr($output[1], 'time=', ' ms')) : 0;
+ $errmsg = null;
+ if ($return_var !== 0) {
+ $usetime = $usetime == 0 ? $timeout * 1000 : $usetime;
+ $errmsg = 'ping timeout';
+ }
+ return ['status' => $return_var === 0, 'errmsg' => $errmsg, 'usetime' => $usetime];
+ }
+}
diff --git a/app/lib/DnsHelper.php b/app/lib/DnsHelper.php
index 8bcf329..840d80c 100644
--- a/app/lib/DnsHelper.php
+++ b/app/lib/DnsHelper.php
@@ -1,145 +1,151 @@
- [
- 'name' => '阿里云',
- 'config' => [
- 'ak' => 'AccessKeyId',
- 'sk' => 'AccessKeySecret'
- ],
- 'remark' => 1, //是否支持备注,1单独设置备注,2和记录一起设置
- 'status' => true, //是否支持启用暂停
- 'redirect' => true, //是否支持域名转发
- 'log' => true, //是否支持查看日志
- 'weight' => false, //是否支持权重
- ],
- 'dnspod' => [
- 'name' => '腾讯云',
- 'config' => [
- 'ak' => 'SecretId',
- 'sk' => 'SecretKey'
- ],
- 'remark' => 1,
- 'status' => true,
- 'redirect' => true,
- 'log' => true,
- 'weight' => true,
- ],
- 'huawei' => [
- 'name' => '华为云',
- 'config' => [
- 'ak' => 'AccessKeyId',
- 'sk' => 'SecretAccessKey'
- ],
- 'remark' => 2,
- 'status' => true,
- 'redirect' => false,
- 'log' => false,
- 'weight' => true,
- ],
- 'baidu' => [
- 'name' => '百度云',
- 'config' => [
- 'ak' => 'AccessKey',
- 'sk' => 'SecretKey'
- ],
- 'remark' => 2,
- 'status' => false,
- 'redirect' => false,
- 'log' => false,
- 'weight' => false,
- ],
- 'west' => [
- 'name' => '西部数码',
- 'config' => [
- 'ak' => '用户名',
- 'sk' => 'API密码'
- ],
- 'remark' => 0,
- 'status' => true,
- 'redirect' => false,
- 'log' => false,
- 'weight' => false,
- ],
- 'huoshan' => [
- 'name' => '火山引擎',
- 'config' => [
- 'ak' => 'AccessKeyId',
- 'sk' => 'SecretAccessKey'
- ],
- 'remark' => 2,
- 'status' => true,
- 'redirect' => false,
- 'log' => false,
- 'weight' => true,
- ],
- 'dnsla' => [
- 'name' => 'DNSLA',
- 'config' => [
- 'ak' => 'APIID',
- 'sk' => 'API密钥'
- ],
- 'remark' => 0,
- 'status' => true,
- 'redirect' => true,
- 'log' => false,
- 'weight' => true,
- ],
- 'cloudflare' => [
- 'name' => 'Cloudflare',
- 'config' => [
- 'ak' => '邮箱地址',
- 'sk' => 'API密钥/令牌'
- ],
- 'remark' => 2,
- 'status' => false,
- 'redirect' => false,
- 'log' => false,
- 'weight' => false,
- ],
- ];
-
- public static function getList()
- {
- return self::$dns_config;
- }
-
- private static function getConfig($aid){
- $account = Db::name('account')->where('id', $aid)->find();
- if(!$account) return false;
- return $account;
- }
-
- public static function getModel($aid, $domain = null, $domainid = null)
- {
- $config = self::getConfig($aid);
- if(!$config) return false;
- $dnstype = $config['type'];
- $class = "\\app\\lib\\dns\\{$dnstype}";
- if(class_exists($class)){
- $config['domain'] = $domain;
- $config['domainid'] = $domainid;
- $model = new $class($config);
- return $model;
- }
- return false;
- }
-
- public static function getModel2($config)
- {
- $dnstype = $config['type'];
- $class = "\\app\\lib\\dns\\{$dnstype}";
- if(class_exists($class)){
- $config['domain'] = $config['name'];
- $config['domainid'] = $config['thirdid'];
- $model = new $class($config);
- return $model;
- }
- return false;
- }
-}
\ No newline at end of file
+ [
+ 'name' => '阿里云',
+ 'config' => [
+ 'ak' => 'AccessKeyId',
+ 'sk' => 'AccessKeySecret'
+ ],
+ 'remark' => 1, //是否支持备注,1单独设置备注,2和记录一起设置
+ 'status' => true, //是否支持启用暂停
+ 'redirect' => true, //是否支持域名转发
+ 'log' => true, //是否支持查看日志
+ 'weight' => false, //是否支持权重
+ ],
+ 'dnspod' => [
+ 'name' => '腾讯云',
+ 'config' => [
+ 'ak' => 'SecretId',
+ 'sk' => 'SecretKey'
+ ],
+ 'remark' => 1,
+ 'status' => true,
+ 'redirect' => true,
+ 'log' => true,
+ 'weight' => true,
+ ],
+ 'huawei' => [
+ 'name' => '华为云',
+ 'config' => [
+ 'ak' => 'AccessKeyId',
+ 'sk' => 'SecretAccessKey'
+ ],
+ 'remark' => 2,
+ 'status' => true,
+ 'redirect' => false,
+ 'log' => false,
+ 'weight' => true,
+ ],
+ 'baidu' => [
+ 'name' => '百度云',
+ 'config' => [
+ 'ak' => 'AccessKey',
+ 'sk' => 'SecretKey'
+ ],
+ 'remark' => 2,
+ 'status' => false,
+ 'redirect' => false,
+ 'log' => false,
+ 'weight' => false,
+ ],
+ 'west' => [
+ 'name' => '西部数码',
+ 'config' => [
+ 'ak' => '用户名',
+ 'sk' => 'API密码'
+ ],
+ 'remark' => 0,
+ 'status' => true,
+ 'redirect' => false,
+ 'log' => false,
+ 'weight' => false,
+ ],
+ 'huoshan' => [
+ 'name' => '火山引擎',
+ 'config' => [
+ 'ak' => 'AccessKeyId',
+ 'sk' => 'SecretAccessKey'
+ ],
+ 'remark' => 2,
+ 'status' => true,
+ 'redirect' => false,
+ 'log' => false,
+ 'weight' => true,
+ ],
+ 'dnsla' => [
+ 'name' => 'DNSLA',
+ 'config' => [
+ 'ak' => 'APIID',
+ 'sk' => 'API密钥'
+ ],
+ 'remark' => 0,
+ 'status' => true,
+ 'redirect' => true,
+ 'log' => false,
+ 'weight' => true,
+ ],
+ 'cloudflare' => [
+ 'name' => 'Cloudflare',
+ 'config' => [
+ 'ak' => '邮箱地址',
+ 'sk' => 'API密钥/令牌'
+ ],
+ 'remark' => 2,
+ 'status' => false,
+ 'redirect' => false,
+ 'log' => false,
+ 'weight' => false,
+ ],
+ ];
+
+ public static function getList()
+ {
+ return self::$dns_config;
+ }
+
+ private static function getConfig($aid)
+ {
+ $account = Db::name('account')->where('id', $aid)->find();
+ if (!$account) {
+ return false;
+ }
+ return $account;
+ }
+
+ public static function getModel($aid, $domain = null, $domainid = null): DnsInterface|bool
+ {
+ $config = self::getConfig($aid);
+ if (!$config) {
+ return false;
+ }
+ $dnstype = $config['type'];
+ $class = "\\app\\lib\\dns\\$dnstype";
+ if (class_exists($class)) {
+ $config['domain'] = $domain;
+ $config['domainid'] = $domainid;
+ $model = new $class($config);
+ return $model;
+ }
+ return false;
+ }
+
+ public static function getModel2($config)
+ {
+ $dnstype = $config['type'];
+ $class = "\\app\\lib\\dns\\{$dnstype}";
+ if (class_exists($class)) {
+ $config['domain'] = $config['name'];
+ $config['domainid'] = $config['thirdid'];
+ $model = new $class($config);
+ return $model;
+ }
+ return false;
+ }
+}
diff --git a/app/lib/DnsInterface.php b/app/lib/DnsInterface.php
index 166030c..9411108 100644
--- a/app/lib/DnsInterface.php
+++ b/app/lib/DnsInterface.php
@@ -1,35 +1,35 @@
-您的域名 '.$task['domain'].' 的 '.$task['main_value'].' 记录发生了异常';
- if($task['type'] == 2){
- $mail_content .= ',已自动切换为备用解析记录 '.$task['backup_value'].' ';
- }elseif($task['type'] == 1){
- $mail_content .= ',已自动暂停解析';
- }else{
- $mail_content .= ',请及时处理';
- }
- if(!empty($result['errmsg'])){
- $mail_content .= '。
异常信息:'.$result['errmsg'];
- }
- }else{
- $mail_title = 'DNS容灾切换-恢复正常通知';
- $mail_content = '尊敬的系统管理员,您好:
您的域名 '.$task['domain'].' 的 '.$task['main_value'].' 记录已恢复正常';
- if($task['type'] == 2){
- $mail_content .= ',已自动切换回当前解析记录';
- }elseif($task['type'] == 1){
- $mail_content .= ',已自动开启解析';
- }
- $lasttime = convert_second(time() - $task['switchtime']);
- $mail_content .= '。
异常持续时间:'.$lasttime;
- }
- if(!empty($task['remark'])) $mail_title .= '('.$task['remark'].')';
- if(!empty($task['remark'])) $mail_content .= '
备注:'.$task['remark'];
- $mail_content .= '
'.self::$sitename.'
'.date('Y-m-d H:i:s');
-
- if(config_get('notice_mail') == 1){
- $mail_name = config_get('mail_recv')?config_get('mail_recv'):config_get('mail_name');
- self::send_mail($mail_name, $mail_title, $mail_content);
- }
- if(config_get('notice_wxtpl') == 1){
- $content = str_replace(['
', '', ''], ["\n\n", '**', '**'], $mail_content);
- self::send_wechat_tplmsg($mail_title, $content);
- }
- if(config_get('notice_tgbot') == 1){
- $content = str_replace('
', "\n", $mail_content);
- $content = "".$mail_title."\n".$content;
- self::send_telegram_bot($content);
- }
- }
-
- public static function send_mail($to, $sub, $msg){
- $mail_type = config_get('mail_type');
- if($mail_type == 1){
- $mail = new \app\lib\mail\Sendcloud(config_get('mail_apiuser'), config_get('mail_apikey'));
- return $mail->send($to, $sub, $msg, config_get('mail_name'), self::$sitename);
- }elseif($mail_type == 2){
- $mail = new \app\lib\mail\Aliyun(config_get('mail_apiuser'), config_get('mail_apikey'));
- return $mail->send($to, $sub, $msg, config_get('mail_name'), self::$sitename);
- }else{
- $mail_name = config_get('mail_name');
- $mail_port = intval(config_get('mail_port'));
- $mail_smtp = config_get('mail_smtp');
- $mail_pwd = config_get('mail_pwd');
- if(!$mail_name || !$mail_port || !$mail_smtp || !$mail_pwd)return false;
- $mail = new \app\lib\mail\PHPMailer\PHPMailer(true);
- try{
- $mail->SMTPDebug = 0;
- $mail->CharSet = 'UTF-8';
- $mail->Timeout = 5;
- $mail->isSMTP();
- $mail->Host = $mail_smtp;
- $mail->SMTPAuth = true;
- $mail->Username = $mail_name;
- $mail->Password = $mail_pwd;
- if($mail_port == 587) $mail->SMTPSecure = 'tls';
- else if($mail_port >= 465) $mail->SMTPSecure = 'ssl';
- else $mail->SMTPAutoTLS = false;
- $mail->Port = $mail_port;
- $mail->setFrom($mail_name, self::$sitename);
- $mail->addAddress($to);
- $mail->addReplyTo($mail_name, self::$sitename);
- $mail->isHTML(true);
- $mail->Subject = $sub;
- $mail->Body = $msg;
- $mail->send();
- return true;
- } catch (\Exception $e) {
- return $mail->ErrorInfo;
- }
- }
- }
-
- public static function send_wechat_tplmsg($title, $content){
- $wechat_apptoken = config_get('wechat_apptoken');
- $wechat_appuid = config_get('wechat_appuid');
- if(!$wechat_apptoken||!$wechat_appuid)return false;
- $url = 'https://wxpusher.zjiecode.com/api/send/message';
- $post = ['appToken'=>$wechat_apptoken, 'content'=>$content, 'summary'=>$title, 'contentType'=>3, 'uids'=>[$wechat_appuid]];
- $result = get_curl($url, json_encode($post),0,0,0,0,0,['Content-Type: application/json; charset=UTF-8']);
- $arr = json_decode($result, true);
- if(isset($arr['success']) && $arr['success']==true){
- return true;
- }else{
- return $arr['msg'];
- }
- }
-
- public static function send_telegram_bot($content){
- $tgbot_token = config_get('tgbot_token');
- $tgbot_chatid = config_get('tgbot_chatid');
- if(!$tgbot_token||!$tgbot_chatid)return false;
- $url = 'https://api.telegram.org/bot'.$tgbot_token.'/sendMessage';
- $post = ['chat_id'=>$tgbot_chatid, 'text'=>$content, 'parse_mode'=>'HTML'];
- $result = self::telegram_curl($url, http_build_query($post));
- $arr = json_decode($result, true);
- if(isset($arr['ok']) && $arr['ok']==true){
- return true;
- }else{
- return $arr['description'];
- }
- }
-
- private static function telegram_curl($url, $post){
- $ch = curl_init();
- if(config_get('tgbot_proxy') == 1){
- $proxy_server = config_get('proxy_server');
- $proxy_port = intval(config_get('proxy_port'));
- $proxy_userpwd = config_get('proxy_user').':'.config_get('proxy_pwd');
- $proxy_type = config_get('proxy_type');
- if($proxy_type == 'https'){
- $proxy_type = CURLPROXY_HTTPS;
- }elseif($proxy_type == 'sock4'){
- $proxy_type = CURLPROXY_SOCKS4;
- }elseif($proxy_type == 'sock5'){
- $proxy_type = CURLPROXY_SOCKS5;
- }else{
- $proxy_type = CURLPROXY_HTTP;
- }
- curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
- curl_setopt($ch, CURLOPT_PROXY, $proxy_server);
- curl_setopt($ch, CURLOPT_PROXYPORT, $proxy_port);
- if($proxy_userpwd != ':'){
- curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy_userpwd);
- }
- curl_setopt($ch, CURLOPT_PROXYTYPE, $proxy_type);
- }
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- $httpheader[] = "Accept: */*";
- $httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
- $httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
- $httpheader[] = "Connection: close";
- curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
- curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Linux; U; Android 4.0.4; es-mx; HTC_One_X Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0");
- curl_setopt($ch, CURLOPT_ENCODING, "gzip");
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- $ret = curl_exec($ch);
- curl_close($ch);
- return $ret;
- }
-}
\ No newline at end of file
+您的域名 '.$task['domain'].' 的 '.$task['main_value'].' 记录发生了异常';
+ if ($task['type'] == 2) {
+ $mail_content .= ',已自动切换为备用解析记录 '.$task['backup_value'].' ';
+ } elseif ($task['type'] == 1) {
+ $mail_content .= ',已自动暂停解析';
+ } else {
+ $mail_content .= ',请及时处理';
+ }
+ if (!empty($result['errmsg'])) {
+ $mail_content .= '。
异常信息:'.$result['errmsg'];
+ }
+ } else {
+ $mail_title = 'DNS容灾切换-恢复正常通知';
+ $mail_content = '尊敬的系统管理员,您好:
您的域名 '.$task['domain'].' 的 '.$task['main_value'].' 记录已恢复正常';
+ if ($task['type'] == 2) {
+ $mail_content .= ',已自动切换回当前解析记录';
+ } elseif ($task['type'] == 1) {
+ $mail_content .= ',已自动开启解析';
+ }
+ $lasttime = convert_second(time() - $task['switchtime']);
+ $mail_content .= '。
异常持续时间:'.$lasttime;
+ }
+ if (!empty($task['remark'])) {
+ $mail_title .= '('.$task['remark'].')';
+ }
+ if (!empty($task['remark'])) {
+ $mail_content .= '
备注:'.$task['remark'];
+ }
+ $mail_content .= '
'.self::$sitename.'
'.date('Y-m-d H:i:s');
+
+ if (config_get('notice_mail') == 1) {
+ $mail_name = config_get('mail_recv') ? config_get('mail_recv') : config_get('mail_name');
+ self::send_mail($mail_name, $mail_title, $mail_content);
+ }
+ if (config_get('notice_wxtpl') == 1) {
+ $content = str_replace(['
', '', ''], ["\n\n", '**', '**'], $mail_content);
+ self::send_wechat_tplmsg($mail_title, $content);
+ }
+ if (config_get('notice_tgbot') == 1) {
+ $content = str_replace('
', "\n", $mail_content);
+ $content = "".$mail_title."\n".$content;
+ self::send_telegram_bot($content);
+ }
+ }
+
+ public static function send_mail($to, $sub, $msg)
+ {
+ $mail_type = config_get('mail_type');
+ if ($mail_type == 1) {
+ $mail = new \app\lib\mail\Sendcloud(config_get('mail_apiuser'), config_get('mail_apikey'));
+ return $mail->send($to, $sub, $msg, config_get('mail_name'), self::$sitename);
+ } elseif ($mail_type == 2) {
+ $mail = new \app\lib\mail\Aliyun(config_get('mail_apiuser'), config_get('mail_apikey'));
+ return $mail->send($to, $sub, $msg, config_get('mail_name'), self::$sitename);
+ } else {
+ $mail_name = config_get('mail_name');
+ $mail_port = intval(config_get('mail_port'));
+ $mail_smtp = config_get('mail_smtp');
+ $mail_pwd = config_get('mail_pwd');
+ if (!$mail_name || !$mail_port || !$mail_smtp || !$mail_pwd) {
+ return false;
+ }
+ $mail = new \app\lib\mail\PHPMailer\PHPMailer(true);
+ try {
+ $mail->SMTPDebug = 0;
+ $mail->CharSet = 'UTF-8';
+ $mail->Timeout = 5;
+ $mail->isSMTP();
+ $mail->Host = $mail_smtp;
+ $mail->SMTPAuth = true;
+ $mail->Username = $mail_name;
+ $mail->Password = $mail_pwd;
+ if ($mail_port == 587) {
+ $mail->SMTPSecure = 'tls';
+ } elseif ($mail_port >= 465) {
+ $mail->SMTPSecure = 'ssl';
+ } else {
+ $mail->SMTPAutoTLS = false;
+ }
+ $mail->Port = $mail_port;
+ $mail->setFrom($mail_name, self::$sitename);
+ $mail->addAddress($to);
+ $mail->addReplyTo($mail_name, self::$sitename);
+ $mail->isHTML(true);
+ $mail->Subject = $sub;
+ $mail->Body = $msg;
+ $mail->send();
+ return true;
+ } catch (\Exception $e) {
+ return $mail->ErrorInfo;
+ }
+ }
+ }
+
+ public static function send_wechat_tplmsg($title, $content)
+ {
+ $wechat_apptoken = config_get('wechat_apptoken');
+ $wechat_appuid = config_get('wechat_appuid');
+ if (!$wechat_apptoken || !$wechat_appuid) {
+ return false;
+ }
+ $url = 'https://wxpusher.zjiecode.com/api/send/message';
+ $post = ['appToken' => $wechat_apptoken, 'content' => $content, 'summary' => $title, 'contentType' => 3, 'uids' => [$wechat_appuid]];
+
+ $result = (new \GuzzleHttp\Client())->post($url, ['json' => $post])->getBody()->getContents();
+ $arr = json_decode($result, true);
+ if (isset($arr['success']) && $arr['success'] == true) {
+ return true;
+ } else {
+ return $arr['msg'];
+ }
+ }
+
+ public static function send_telegram_bot($content)
+ {
+ $tgbot_token = config_get('tgbot_token');
+ $tgbot_chatid = config_get('tgbot_chatid');
+ if (!$tgbot_token || !$tgbot_chatid) {
+ return false;
+ }
+ $url = 'https://api.telegram.org/bot'.$tgbot_token.'/sendMessage';
+ $post = ['chat_id' => $tgbot_chatid, 'text' => $content, 'parse_mode' => 'HTML'];
+ $result = self::telegram_curl($url, http_build_query($post));
+ $arr = json_decode($result, true);
+ if (isset($arr['ok']) && $arr['ok'] == true) {
+ return true;
+ } else {
+ return $arr['description'];
+ }
+ }
+
+ private static function telegram_curl($url, $post)
+ {
+ $ch = curl_init();
+ if (config_get('tgbot_proxy') == 1) {
+ $proxy_server = config_get('proxy_server');
+ $proxy_port = intval(config_get('proxy_port'));
+ $proxy_userpwd = config_get('proxy_user').':'.config_get('proxy_pwd');
+ $proxy_type = config_get('proxy_type');
+ if ($proxy_type == 'https') {
+ $proxy_type = CURLPROXY_HTTPS;
+ } elseif ($proxy_type == 'sock4') {
+ $proxy_type = CURLPROXY_SOCKS4;
+ } elseif ($proxy_type == 'sock5') {
+ $proxy_type = CURLPROXY_SOCKS5;
+ } else {
+ $proxy_type = CURLPROXY_HTTP;
+ }
+ curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
+ curl_setopt($ch, CURLOPT_PROXY, $proxy_server);
+ curl_setopt($ch, CURLOPT_PROXYPORT, $proxy_port);
+ if ($proxy_userpwd != ':') {
+ curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy_userpwd);
+ }
+ curl_setopt($ch, CURLOPT_PROXYTYPE, $proxy_type);
+ }
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ $httpheader[] = "Accept: */*";
+ $httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
+ $httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
+ $httpheader[] = "Connection: close";
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
+ curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Linux; U; Android 4.0.4; es-mx; HTC_One_X Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0");
+ curl_setopt($ch, CURLOPT_ENCODING, "gzip");
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ $ret = curl_exec($ch);
+ curl_close($ch);
+ return $ret;
+ }
+}
diff --git a/app/lib/NewDb.php b/app/lib/NewDb.php
index 2a1d6d0..1538b7e 100644
--- a/app/lib/NewDb.php
+++ b/app/lib/NewDb.php
@@ -1,4 +1,5 @@
['DEF'=>'default', 'CT'=>'telecom', 'CU'=>'unicom', 'CM'=>'mobile', 'AB'=>'oversea'],
- 'dnspod' => ['DEF'=>'0', 'CT'=>'10=0', 'CU'=>'10=1', 'CM'=>'10=3', 'AB'=>'3=0'],
- 'huawei' => ['DEF'=>'default_view', 'CT'=>'Dianxin', 'CU'=>'Liantong', 'CM'=>'Yidong', 'AB'=>'Abroad'],
- 'west' => ['DEF'=>'', 'CT'=>'LTEL', 'CU'=>'LCNC', 'CM'=>'LMOB', 'AB'=>'LFOR'],
- 'dnsla' => ['DEF'=>'', 'CT'=>'84613316902921216', 'CU'=>'84613316923892736', 'CM'=>'84613316953252864', 'AB'=>''],
- 'huoshan' => ['DEF'=>'default', 'CT'=>'telecom', 'CU'=>'unicom', 'CM'=>'mobile', 'AB'=>'oversea'],
- 'baidu' => ['DEF'=>'default', 'CT'=>'ct', 'CU'=>'cnc', 'CM'=>'cmnet', 'AB'=>''],
- ];
-
- private $ip_address = [];
- private $add_num = 0;
- private $change_num = 0;
- private $del_num = 0;
-
- public static function get_license($api, $key){
- if($api == 2){
- throw new Exception('当前接口暂不支持');
- }elseif($api == 1){
- $url = 'https://api.hostmonit.com/get_license?license='.$key;
- }else{
- $url = 'https://www.wetest.vip/api/cf2dns/get_license?license='.$key;
- }
- $response = get_curl($url);
- $arr = json_decode($response, true);
- if(isset($arr['code']) && $arr['code'] == 200 && isset($arr['count'])){
- return $arr['count'];
- }elseif(isset($arr['info'])){
- throw new Exception('获取剩余请求次数失败,'.$arr['info']);
- }else{
- throw new Exception('获取剩余请求次数失败');
- }
- }
-
- public function get_ip_address($cdn_type = 1, $ip_type = 'v4'){
- $api = config_get('optimize_ip_api', 0);
- if($api == 2){
- $url = 'https://api.345673.xyz/get_data';
- }elseif($api == 1){
- $url = 'https://api.hostmonit.com/get_optimization_ip';
- }else{
- $url = 'https://www.wetest.vip/api/cf2dns/';
- if($cdn_type == 1){
- $url .= 'get_cloudflare_ip';
- }elseif($cdn_type == 2){
- $url .= 'get_cloudfront_ip';
- }elseif($cdn_type == 3){
- $url .= 'get_gcore_ip';
- }
- }
- $params = [
- 'key' => config_get('optimize_ip_key', 'o1zrmHAF'),
- 'type' => $ip_type,
- ];
- $response = get_curl($url, json_encode($params), 0, 0, 0, 0, 0, ['Content-Type: application/json; charset=UTF-8']);
- $arr = json_decode($response, true);
- if(isset($arr['code']) && $arr['code'] == 200){
- return $arr['info'];
- }elseif(isset($arr['info'])){
- throw new Exception('获取优选IP数据失败,'.$arr['info']);
- }elseif(isset($arr['msg'])){
- throw new Exception('获取优选IP数据失败,'.$arr['msg']);
- }else{
- throw new Exception('获取优选IP数据失败,原因未知');
- }
- }
-
- public function get_ip_address2($cdn_type = 1, $ip_type = 'v4'){
- $key = $cdn_type.'_'.$ip_type;
- if(!isset($this->ip_address[$key])){
- $info = $this->get_ip_address($cdn_type, $ip_type);
- $res = [];
- if(isset($info['DEF'])) $res['DEF'] = $info['DEF'];
- if(isset($info['CT'])) $res['CT'] = $info['CT'];
- if(isset($info['CU'])) $res['CU'] = $info['CU'];
- if(isset($info['CM'])) $res['CM'] = $info['CM'];
- $this->ip_address[$key] = $res;
- }
- return $this->ip_address[$key];
- }
-
- //批量执行优选任务
- public function execute(){
- $list = Db::name('optimizeip')->where('active', 1)->select();
- echo '开始执行IP优选任务,共获取到'.count($list).'个待执行任务'."\n";
- foreach($list as $row){
- try{
- $result = $this->execute_one($row);
- Db::name('optimizeip')->where('id', $row['id'])->update(['status' => 1, 'errmsg' => null, 'updatetime' => date('Y-m-d H:i:s')]);
- echo '优选任务'.$row['id'].'执行成功:'.$result."\n";
- }catch(Exception $e){
- Db::name('optimizeip')->where('id', $row['id'])->update(['status' => 2, 'errmsg' => $e->getMessage(), 'updatetime' => date('Y-m-d H:i:s')]);
- echo '优选任务'.$row['id'].'执行失败:'.$e->getMessage()."\n";
- }
- }
- }
-
- //执行单个优选任务
- public function execute_one($row){
- $this->add_num = 0;
- $this->change_num = 0;
- $this->del_num = 0;
- $ip_types = explode(',', $row['ip_type']);
- foreach($ip_types as $ip_type){
- if(empty($ip_type)) continue;
-
- $drow = Db::name('domain')->alias('A')->join('account B','A.aid = B.id')->where('A.id', $row['did'])->field('A.*,B.type,B.ak,B.sk,B.ext')->find();
- if(!$drow){
- throw new Exception('域名不存在(ID:'.$row['did'].')');
- }
- if(!isset(self::$line_name[$drow['type']])){
- throw new Exception('不支持的DNS服务商');
- }
-
- $info = $this->get_ip_address2($row['cdn_type'], $ip_type);
-
- $dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
- $domainRecords = $dns->getSubDomainRecords($row['rr'], 1, 100);
- if(!$domainRecords){
- throw new Exception('获取记录列表失败,'.$dns->getError());
- }
-
- if($row['type'] == 1 && isset($info['DEF']) && !empty($info['DEF'])) $row['type'] = 0;
-
- foreach($info as $line=>$iplist){
- if(empty($iplist)) continue;
- $get_ips = array_column($iplist, 'ip');
- if($drow['type']=='huawei') {sort($get_ips); $get_ips = [implode(',',$get_ips)]; $row['recordnum'] = 1;}
- if($row['type'] == 1 && $line == 'CT') $line = 'DEF';
- $line_name = self::$line_name[$drow['type']][$line];
- $this->process_dns_line($dns, $row, $domainRecords['list'], $get_ips, $line_name, $ip_type);
- }
- }
-
- return '成功添加'.$this->add_num.'条记录,修改'.$this->change_num.'条记录,删除'.$this->del_num.'条记录';
- }
-
- //处理单个线路的解析记录
- private function process_dns_line($dns, $row, $record_list, $get_ips, $line_name, $ip_type){
- $record_num = $row['recordnum'];
- $records = array_filter($record_list, function($v) use($line_name){
- return $v['Line'] == $line_name;
- });
-
- //删除CNAME记录
- $cname_records = array_filter($records, function($v){
- return $v['Type'] == 'CNAME';
- });
- if(!empty($cname_records)){
- foreach($cname_records as $record){
- $dns->deleteDomainRecord($record['RecordId']);
- }
- }
-
- //处理A/AAAA记录
- $ip_records = array_filter($records, function($v) use ($ip_type){
- return $v['Type'] == ($ip_type == 'v6' ? 'AAAA' : 'A');
- });
-
- if(!empty($ip_records) && is_array($ip_records[array_key_first($ip_records)]['Value'])){ //处理华为云记录
- foreach($ip_records as &$ip_record){
- sort($ip_record['Value']);
- $ip_record['Value'] = implode(',', $ip_record['Value']);
- }
- }
-
- $exist_ips = array_column($ip_records, 'Value');
- $add_ips = array_diff($get_ips, $exist_ips);
- $del_ips = array_diff($exist_ips, $get_ips);
- $correct_ips = array_diff($exist_ips, $del_ips);
- $correct_count = count($correct_ips);
- if(!empty($del_ips)){
- foreach($ip_records as $record){
- if(in_array($record['Value'], $del_ips)){
- $add_ip = array_pop($add_ips);
- if($add_ip){
- $res = $dns->updateDomainRecord($record['RecordId'], $row['rr'], $ip_type == 'v6' ? 'AAAA' : 'A', $add_ip, $line_name, $row['ttl']);
- if(!$res){
- throw new Exception('修改解析失败,'.$dns->getError());
- }
- $this->change_num++;
- $correct_count++;
- }else{
- $res = $dns->deleteDomainRecord($record['RecordId']);
- if(!$res){
- throw new Exception('删除解析失败,'.$dns->getError());
- }
- $this->del_num++;
- }
- }
- }
- }
- if($correct_count < $record_num && !empty($add_ips)){
- foreach($add_ips as $add_ip){
- $res = $dns->addDomainRecord($row['rr'], $ip_type == 'v6' ? 'AAAA' : 'A', $add_ip, $line_name, $row['ttl']);
- if(!$res){
- throw new Exception('添加解析失败,'.$dns->getError());
- }
- $this->add_num++;
- $correct_count++;
- if($correct_count >= $record_num) break;
- }
- }
- }
-}
\ No newline at end of file
+ ['DEF' => 'default', 'CT' => 'telecom', 'CU' => 'unicom', 'CM' => 'mobile', 'AB' => 'oversea'],
+ 'dnspod' => ['DEF' => '0', 'CT' => '10=0', 'CU' => '10=1', 'CM' => '10=3', 'AB' => '3=0'],
+ 'huawei' => ['DEF' => 'default_view', 'CT' => 'Dianxin', 'CU' => 'Liantong', 'CM' => 'Yidong', 'AB' => 'Abroad'],
+ 'west' => ['DEF' => '', 'CT' => 'LTEL', 'CU' => 'LCNC', 'CM' => 'LMOB', 'AB' => 'LFOR'],
+ 'dnsla' => ['DEF' => '', 'CT' => '84613316902921216', 'CU' => '84613316923892736', 'CM' => '84613316953252864', 'AB' => ''],
+ 'huoshan' => ['DEF' => 'default', 'CT' => 'telecom', 'CU' => 'unicom', 'CM' => 'mobile', 'AB' => 'oversea'],
+ 'baidu' => ['DEF' => 'default', 'CT' => 'ct', 'CU' => 'cnc', 'CM' => 'cmnet', 'AB' => ''],
+ ];
+
+ private $ip_address = [];
+ private $add_num = 0;
+ private $change_num = 0;
+ private $del_num = 0;
+
+ public static function get_license($api, $key)
+ {
+ if ($api == 2) {
+ throw new Exception('当前接口暂不支持');
+ } elseif ($api == 1) {
+ $url = 'https://api.hostmonit.com/get_license?license='.$key;
+ } else {
+ $url = 'https://www.wetest.vip/api/cf2dns/get_license?license='.$key;
+ }
+ $response = (new \GuzzleHttp\Client())->get($url)->getBody()->getContents();
+ $arr = json_decode($response, true);
+ if (isset($arr['code']) && $arr['code'] == 200 && isset($arr['count'])) {
+ return $arr['count'];
+ } elseif (isset($arr['info'])) {
+ throw new Exception('获取剩余请求次数失败,'.$arr['info']);
+ } else {
+ throw new Exception('获取剩余请求次数失败');
+ }
+ }
+
+ public function get_ip_address($cdn_type = 1, $ip_type = 'v4')
+ {
+ $api = config_get('optimize_ip_api', 0);
+ if ($api == 2) {
+ $url = 'https://api.345673.xyz/get_data';
+ } elseif ($api == 1) {
+ $url = 'https://api.hostmonit.com/get_optimization_ip';
+ } else {
+ $url = 'https://www.wetest.vip/api/cf2dns/';
+ if ($cdn_type == 1) {
+ $url .= 'get_cloudflare_ip';
+ } elseif ($cdn_type == 2) {
+ $url .= 'get_cloudfront_ip';
+ } elseif ($cdn_type == 3) {
+ $url .= 'get_gcore_ip';
+ }
+ }
+ $params = [
+ 'key' => config_get('optimize_ip_key', 'o1zrmHAF'),
+ 'type' => $ip_type,
+ ];
+ $response = (new \GuzzleHttp\Client())->post($url, ['json' => $params])->getBody()->getContents();
+ $arr = json_decode($response, true);
+ if (isset($arr['code']) && $arr['code'] == 200) {
+ return $arr['info'];
+ } elseif (isset($arr['info'])) {
+ throw new Exception('获取优选IP数据失败,'.$arr['info']);
+ } elseif (isset($arr['msg'])) {
+ throw new Exception('获取优选IP数据失败,'.$arr['msg']);
+ } else {
+ throw new Exception('获取优选IP数据失败,原因未知');
+ }
+ }
+
+ public function get_ip_address2($cdn_type = 1, $ip_type = 'v4')
+ {
+ $key = $cdn_type.'_'.$ip_type;
+ if (!isset($this->ip_address[$key])) {
+ $info = $this->get_ip_address($cdn_type, $ip_type);
+ $res = [];
+ if (isset($info['DEF'])) {
+ $res['DEF'] = $info['DEF'];
+ }
+ if (isset($info['CT'])) {
+ $res['CT'] = $info['CT'];
+ }
+ if (isset($info['CU'])) {
+ $res['CU'] = $info['CU'];
+ }
+ if (isset($info['CM'])) {
+ $res['CM'] = $info['CM'];
+ }
+ $this->ip_address[$key] = $res;
+ }
+ return $this->ip_address[$key];
+ }
+
+ //批量执行优选任务
+ public function execute()
+ {
+ $list = Db::name('optimizeip')->where('active', 1)->select();
+ echo '开始执行IP优选任务,共获取到'.count($list).'个待执行任务'."\n";
+ foreach ($list as $row) {
+ try {
+ $result = $this->execute_one($row);
+ Db::name('optimizeip')->where('id', $row['id'])->update(['status' => 1, 'errmsg' => null, 'updatetime' => date('Y-m-d H:i:s')]);
+ echo '优选任务'.$row['id'].'执行成功:'.$result."\n";
+ } catch (Exception $e) {
+ Db::name('optimizeip')->where('id', $row['id'])->update(['status' => 2, 'errmsg' => $e->getMessage(), 'updatetime' => date('Y-m-d H:i:s')]);
+ echo '优选任务'.$row['id'].'执行失败:'.$e->getMessage()."\n";
+ }
+ }
+ }
+
+ //执行单个优选任务
+ public function execute_one($row)
+ {
+ $this->add_num = 0;
+ $this->change_num = 0;
+ $this->del_num = 0;
+ $ip_types = explode(',', $row['ip_type']);
+ foreach ($ip_types as $ip_type) {
+ if (empty($ip_type)) {
+ continue;
+ }
+
+ $drow = Db::name('domain')->alias('A')->join('account B', 'A.aid = B.id')->where('A.id', $row['did'])->field('A.*,B.type,B.ak,B.sk,B.ext')->find();
+ if (!$drow) {
+ throw new Exception('域名不存在(ID:'.$row['did'].')');
+ }
+ if (!isset(self::$line_name[$drow['type']])) {
+ throw new Exception('不支持的DNS服务商');
+ }
+
+ $info = $this->get_ip_address2($row['cdn_type'], $ip_type);
+
+ $dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']);
+ $domainRecords = $dns->getSubDomainRecords($row['rr'], 1, 100);
+ if (!$domainRecords) {
+ throw new Exception('获取记录列表失败,'.$dns->getError());
+ }
+
+ if ($row['type'] == 1 && isset($info['DEF']) && !empty($info['DEF'])) {
+ $row['type'] = 0;
+ }
+
+ foreach ($info as $line => $iplist) {
+ if (empty($iplist)) {
+ continue;
+ }
+ $get_ips = array_column($iplist, 'ip');
+ if ($drow['type'] == 'huawei') {
+ sort($get_ips);
+ $get_ips = [implode(',', $get_ips)];
+ $row['recordnum'] = 1;
+ }
+ if ($row['type'] == 1 && $line == 'CT') {
+ $line = 'DEF';
+ }
+ $line_name = self::$line_name[$drow['type']][$line];
+ $this->process_dns_line($dns, $row, $domainRecords['list'], $get_ips, $line_name, $ip_type);
+ }
+ }
+
+ return '成功添加'.$this->add_num.'条记录,修改'.$this->change_num.'条记录,删除'.$this->del_num.'条记录';
+ }
+
+ //处理单个线路的解析记录
+ private function process_dns_line($dns, $row, $record_list, $get_ips, $line_name, $ip_type)
+ {
+ $record_num = $row['recordnum'];
+ $records = array_filter($record_list, function ($v) use ($line_name) {
+ return $v['Line'] == $line_name;
+ });
+
+ //删除CNAME记录
+ $cname_records = array_filter($records, function ($v) {
+ return $v['Type'] == 'CNAME';
+ });
+ if (!empty($cname_records)) {
+ foreach ($cname_records as $record) {
+ $dns->deleteDomainRecord($record['RecordId']);
+ }
+ }
+
+ //处理A/AAAA记录
+ $ip_records = array_filter($records, function ($v) use ($ip_type) {
+ return $v['Type'] == ($ip_type == 'v6' ? 'AAAA' : 'A');
+ });
+
+ if (!empty($ip_records) && is_array($ip_records[array_key_first($ip_records)]['Value'])) { //处理华为云记录
+ foreach ($ip_records as &$ip_record) {
+ sort($ip_record['Value']);
+ $ip_record['Value'] = implode(',', $ip_record['Value']);
+ }
+ }
+
+ $exist_ips = array_column($ip_records, 'Value');
+ $add_ips = array_diff($get_ips, $exist_ips);
+ $del_ips = array_diff($exist_ips, $get_ips);
+ $correct_ips = array_diff($exist_ips, $del_ips);
+ $correct_count = count($correct_ips);
+ if (!empty($del_ips)) {
+ foreach ($ip_records as $record) {
+ if (in_array($record['Value'], $del_ips)) {
+ $add_ip = array_pop($add_ips);
+ if ($add_ip) {
+ $res = $dns->updateDomainRecord($record['RecordId'], $row['rr'], $ip_type == 'v6' ? 'AAAA' : 'A', $add_ip, $line_name, $row['ttl']);
+ if (!$res) {
+ throw new Exception('修改解析失败,'.$dns->getError());
+ }
+ $this->change_num++;
+ $correct_count++;
+ } else {
+ $res = $dns->deleteDomainRecord($record['RecordId']);
+ if (!$res) {
+ throw new Exception('删除解析失败,'.$dns->getError());
+ }
+ $this->del_num++;
+ }
+ }
+ }
+ }
+ if ($correct_count < $record_num && !empty($add_ips)) {
+ foreach ($add_ips as $add_ip) {
+ $res = $dns->addDomainRecord($row['rr'], $ip_type == 'v6' ? 'AAAA' : 'A', $add_ip, $line_name, $row['ttl']);
+ if (!$res) {
+ throw new Exception('添加解析失败,'.$dns->getError());
+ }
+ $this->add_num++;
+ $correct_count++;
+ if ($correct_count >= $record_num) {
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/app/lib/TaskRunner.php b/app/lib/TaskRunner.php
index 8cef5b0..398c961 100644
--- a/app/lib/TaskRunner.php
+++ b/app/lib/TaskRunner.php
@@ -1,125 +1,126 @@
-conn){
- $this->conn = NewDb::connect();
- }
- return $this->conn;
- }
-
- private function closeDb()
- {
- if($this->conn){
- $this->conn->close();
- }
- }
-
- public function execute($row)
- {
- if($row['type'] == 3){ //条件开启解析
- $action = 0;
- $remain = $this->db()->name('dmtask')->where(['did'=>$row['did'], 'rr'=>$row['rr'], 'type'=>1, 'status'=>0])->count();
- if($remain<=$row['cycle'] && $row['status']==0){
- $action = 2;
- $this->db()->name('dmtask')->where('id', $row['id'])->update(['status'=>1, 'errcount'=>0, 'switchtime'=>time()]);
- }elseif($remain>$row['cycle'] && $row['status']==1){
- $action = 1;
- $this->db()->name('dmtask')->where('id', $row['id'])->update(['status'=>0, 'errcount'=>0, 'switchtime'=>time()]);
- }
- }else{
- if($row['checktype'] == 2){
- $result = CheckUtils::curl($row['checkurl'], $row['timeout'], $row['main_value'], $row['proxy'] == 1);
- }else if($row['checktype'] == 1){
- $result = CheckUtils::tcp($row['main_value'], $row['tcpport'], $row['timeout']);
- }else{
- $result = CheckUtils::ping($row['main_value']);
- }
-
- $action = 0;
- if($result['status'] && $row['status']==1){
- if($row['cycle'] <= 1 || $row['errcount'] >= $row['cycle']){
- $this->db()->name('dmtask')->where('id', $row['id'])->update(['status'=>0, 'errcount'=>0, 'switchtime'=>time()]);
- $action = 2;
- }else{
- $this->db()->name('dmtask')->where('id', $row['id'])->inc('errcount')->update();
- }
- }elseif(!$result['status'] && $row['status']==0){
- if($row['cycle'] <= 1 || $row['errcount'] >= $row['cycle']){
- $this->db()->name('dmtask')->where('id', $row['id'])->update(['status'=>1, 'errcount'=>0, 'switchtime'=>time()]);
- $action = 1;
- }else{
- $this->db()->name('dmtask')->where('id', $row['id'])->inc('errcount')->update();
- }
- }elseif($row['errcount'] > 0){
- $this->db()->name('dmtask')->where('id', $row['id'])->update(['errcount'=>0]);
- }
- }
-
- if($action > 0){
- $drow = $this->db()->name('domain')->alias('A')->join('account B','A.aid = B.id')->where('A.id', $row['did'])->field('A.*,B.type,B.ak,B.sk,B.ext')->find();
- if(!$drow){
- echo '域名不存在(ID:'.$row['did'].')'."\n";
- $this->closeDb();
- return;
- }
- $row['domain'] = $row['rr'] . '.' . $drow['name'];
- }
- if($action == 1){
- if($row['type'] == 2){
- $dns = DnsHelper::getModel2($drow);
- $recordinfo = json_decode($row['recordinfo'], true);
- $res = $dns->updateDomainRecord($row['recordid'], $row['rr'], getDnsType($row['backup_value']), $row['backup_value'], $recordinfo['Line'], $recordinfo['TTL']);
- if(!$res){
- $this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '修改解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
- }
- }elseif($row['type'] == 1 || $row['type'] == 3){
- $dns = DnsHelper::getModel2($drow);
- $res = $dns->setDomainRecordStatus($row['recordid'], '0');
- if(!$res){
- $this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '暂停解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
- }
- }
- }elseif($action == 2){
- if($row['type'] == 2){
- $dns = DnsHelper::getModel2($drow);
- $recordinfo = json_decode($row['recordinfo'], true);
- $res = $dns->updateDomainRecord($row['recordid'], $row['rr'], getDnsType($row['main_value']), $row['main_value'], $recordinfo['Line'], $recordinfo['TTL']);
- if(!$res){
- $this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '修改解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
- }
- }elseif($row['type'] == 1 || $row['type'] == 3){
- $dns = DnsHelper::getModel2($drow);
- $res = $dns->setDomainRecordStatus($row['recordid'], '1');
- if(!$res){
- $this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '启用解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
- }
- }
- }else{
- $this->closeDb();
- return;
- }
-
- $this->db()->name('dmlog')->insert([
- 'taskid' => $row['id'],
- 'action' => $action,
- 'errmsg' => isset($result) ? ($result['status'] ? null : $result['errmsg']) : null,
- 'date' => date('Y-m-d H:i:s')
- ]);
- $this->closeDb();
-
- if($row['type'] != 3){
- MsgNotice::send($action, $row, $result);
- }
- }
-}
\ No newline at end of file
+conn) {
+ $this->conn = NewDb::connect();
+ }
+ return $this->conn;
+ }
+
+ private function closeDb()
+ {
+ if ($this->conn) {
+ $this->conn->close();
+ }
+ }
+
+ public function execute($row)
+ {
+ if ($row['type'] == 3) { //条件开启解析
+ $action = 0;
+ $remain = $this->db()->name('dmtask')->where(['did' => $row['did'], 'rr' => $row['rr'], 'type' => 1, 'status' => 0])->count();
+ if ($remain <= $row['cycle'] && $row['status'] == 0) {
+ $action = 2;
+ $this->db()->name('dmtask')->where('id', $row['id'])->update(['status' => 1, 'errcount' => 0, 'switchtime' => time()]);
+ } elseif ($remain > $row['cycle'] && $row['status'] == 1) {
+ $action = 1;
+ $this->db()->name('dmtask')->where('id', $row['id'])->update(['status' => 0, 'errcount' => 0, 'switchtime' => time()]);
+ }
+ } else {
+ if ($row['checktype'] == 2) {
+ $result = CheckUtils::curl($row['checkurl'], $row['timeout'], $row['main_value'], $row['proxy'] == 1);
+ } elseif ($row['checktype'] == 1) {
+ $result = CheckUtils::tcp($row['main_value'], $row['tcpport'], $row['timeout']);
+ } else {
+ $result = CheckUtils::ping($row['main_value']);
+ }
+
+ $action = 0;
+ if ($result['status'] && $row['status'] == 1) {
+ if ($row['cycle'] <= 1 || $row['errcount'] >= $row['cycle']) {
+ $this->db()->name('dmtask')->where('id', $row['id'])->update(['status' => 0, 'errcount' => 0, 'switchtime' => time()]);
+ $action = 2;
+ } else {
+ $this->db()->name('dmtask')->where('id', $row['id'])->inc('errcount')->update();
+ }
+ } elseif (!$result['status'] && $row['status'] == 0) {
+ if ($row['cycle'] <= 1 || $row['errcount'] >= $row['cycle']) {
+ $this->db()->name('dmtask')->where('id', $row['id'])->update(['status' => 1, 'errcount' => 0, 'switchtime' => time()]);
+ $action = 1;
+ } else {
+ $this->db()->name('dmtask')->where('id', $row['id'])->inc('errcount')->update();
+ }
+ } elseif ($row['errcount'] > 0) {
+ $this->db()->name('dmtask')->where('id', $row['id'])->update(['errcount' => 0]);
+ }
+ }
+
+ if ($action > 0) {
+ $drow = $this->db()->name('domain')->alias('A')->join('account B', 'A.aid = B.id')->where('A.id', $row['did'])->field('A.*,B.type,B.ak,B.sk,B.ext')->find();
+ if (!$drow) {
+ echo '域名不存在(ID:'.$row['did'].')'."\n";
+ $this->closeDb();
+ return;
+ }
+ $row['domain'] = $row['rr'] . '.' . $drow['name'];
+ }
+ if ($action == 1) {
+ if ($row['type'] == 2) {
+ $dns = DnsHelper::getModel2($drow);
+ $recordinfo = json_decode($row['recordinfo'], true);
+ $res = $dns->updateDomainRecord($row['recordid'], $row['rr'], getDnsType($row['backup_value']), $row['backup_value'], $recordinfo['Line'], $recordinfo['TTL']);
+ if (!$res) {
+ $this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '修改解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
+ }
+ } elseif ($row['type'] == 1 || $row['type'] == 3) {
+ $dns = DnsHelper::getModel2($drow);
+ $res = $dns->setDomainRecordStatus($row['recordid'], '0');
+ if (!$res) {
+ $this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '暂停解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
+ }
+ }
+ } elseif ($action == 2) {
+ if ($row['type'] == 2) {
+ $dns = DnsHelper::getModel2($drow);
+ $recordinfo = json_decode($row['recordinfo'], true);
+ $res = $dns->updateDomainRecord($row['recordid'], $row['rr'], getDnsType($row['main_value']), $row['main_value'], $recordinfo['Line'], $recordinfo['TTL']);
+ if (!$res) {
+ $this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '修改解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
+ }
+ } elseif ($row['type'] == 1 || $row['type'] == 3) {
+ $dns = DnsHelper::getModel2($drow);
+ $res = $dns->setDomainRecordStatus($row['recordid'], '1');
+ if (!$res) {
+ $this->db()->name('log')->insert(['uid' => 0, 'domain' => $drow['name'], 'action' => '启用解析失败', 'data' => $dns->getError(), 'addtime' => date("Y-m-d H:i:s")]);
+ }
+ }
+ } else {
+ $this->closeDb();
+ return;
+ }
+
+ $this->db()->name('dmlog')->insert([
+ 'taskid' => $row['id'],
+ 'action' => $action,
+ 'errmsg' => isset($result) ? ($result['status'] ? null : $result['errmsg']) : null,
+ 'date' => date('Y-m-d H:i:s')
+ ]);
+ $this->closeDb();
+
+ if ($row['type'] != 3) {
+ MsgNotice::send($action, $row, $result);
+ }
+ }
+}
diff --git a/app/lib/dns/aliyun.php b/app/lib/dns/aliyun.php
index 6660353..4e903cc 100644
--- a/app/lib/dns/aliyun.php
+++ b/app/lib/dns/aliyun.php
@@ -1,314 +1,344 @@
AccessKeyId = $config['ak'];
- $this->AccessKeySecret = $config['sk'];
- $this->domain = $config['domain'];
- }
+ public function __construct($config)
+ {
+ $this->AccessKeyId = $config['ak'];
+ $this->AccessKeySecret = $config['sk'];
+ $this->domain = $config['domain'];
+ }
- public function getError(){
- return $this->error;
- }
+ public function getError()
+ {
+ return $this->error;
+ }
- public function check(){
- if($this->getDomainList() != false){
- return true;
- }
- return false;
- }
+ public function check()
+ {
+ if ($this->getDomainList() != false) {
+ return true;
+ }
+ return false;
+ }
- //获取域名列表
- public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
- $param = ['Action' => 'DescribeDomains', 'KeyWord' => $KeyWord, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize];
- $data = $this->request($param, true);
- if($data){
- $list = [];
- foreach($data['Domains']['Domain'] as $row){
- $list[] = [
- 'DomainId' => $row['DomainId'],
- 'Domain' => $row['DomainName'],
- 'RecordCount' => $row['RecordCount'],
- ];
- }
- return ['total' => $data['TotalCount'], 'list' => $list];
- }
- return false;
- }
+ //获取域名列表
+ public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
+ {
+ $param = ['Action' => 'DescribeDomains', 'KeyWord' => $KeyWord, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize];
+ $data = $this->request($param, true);
+ if ($data) {
+ $list = [];
+ foreach ($data['Domains']['Domain'] as $row) {
+ $list[] = [
+ 'DomainId' => $row['DomainId'],
+ 'Domain' => $row['DomainName'],
+ 'RecordCount' => $row['RecordCount'],
+ ];
+ }
+ return ['total' => $data['TotalCount'], 'list' => $list];
+ }
+ return false;
+ }
- //获取解析记录列表
- public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null){
- $param = ['Action' => 'DescribeDomainRecords', 'DomainName' => $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize];
- if(!empty($SubDomain) || !empty($Type) || !empty($Line) || !empty($Value)){
- $param += ['SearchMode' => 'ADVANCED', 'RRKeyWord' => $SubDomain, 'ValueKeyWord' => $Value, 'Type' => $Type, 'Line' => $Line];
- }elseif(!empty($KeyWord)){
- $param += ['KeyWord' => $KeyWord];
- }
- if(!isNullOrEmpty($Status)){
- $Status = $Status == '1' ? 'Enable' : 'Disable';
- $param += ['Status' => $Status];
- }
- $data = $this->request($param, true);
- if($data){
- $list = [];
- foreach($data['DomainRecords']['Record'] as $row){
- $list[] = [
- 'RecordId' => $row['RecordId'],
- 'Domain' => $row['DomainName'],
- 'Name' => $row['RR'],
- 'Type' => $row['Type'],
- 'Value' => $row['Value'],
- 'Line' => $row['Line'],
- 'TTL' => $row['TTL'],
- 'MX' => isset($row['Priority']) ? $row['Priority'] : null,
- 'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
- 'Weight' => isset($row['Weight']) ? $row['Weight'] : null,
- 'Remark' => isset($row['Remark']) ? $row['Remark'] : null,
- 'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', $row['UpdateTimestamp']/1000) : null,
- ];
- }
- return ['total' => $data['TotalCount'], 'list' => $list];
- }
- return false;
- }
+ //获取解析记录列表
+ public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
+ {
+ $param = ['Action' => 'DescribeDomainRecords', 'DomainName' => $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize];
+ if (!empty($SubDomain) || !empty($Type) || !empty($Line) || !empty($Value)) {
+ $param += ['SearchMode' => 'ADVANCED', 'RRKeyWord' => $SubDomain, 'ValueKeyWord' => $Value, 'Type' => $Type, 'Line' => $Line];
+ } elseif (!empty($KeyWord)) {
+ $param += ['KeyWord' => $KeyWord];
+ }
+ if (!isNullOrEmpty($Status)) {
+ $Status = $Status == '1' ? 'Enable' : 'Disable';
+ $param += ['Status' => $Status];
+ }
+ $data = $this->request($param, true);
+ if ($data) {
+ $list = [];
+ foreach ($data['DomainRecords']['Record'] as $row) {
+ $list[] = [
+ 'RecordId' => $row['RecordId'],
+ 'Domain' => $row['DomainName'],
+ 'Name' => $row['RR'],
+ 'Type' => $row['Type'],
+ 'Value' => $row['Value'],
+ 'Line' => $row['Line'],
+ 'TTL' => $row['TTL'],
+ 'MX' => isset($row['Priority']) ? $row['Priority'] : null,
+ 'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
+ 'Weight' => isset($row['Weight']) ? $row['Weight'] : null,
+ 'Remark' => isset($row['Remark']) ? $row['Remark'] : null,
+ 'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', $row['UpdateTimestamp'] / 1000) : null,
+ ];
+ }
+ return ['total' => $data['TotalCount'], 'list' => $list];
+ }
+ return false;
+ }
- //获取子域名解析记录列表
- public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
- $param = ['Action' => 'DescribeSubDomainRecords', 'SubDomain' => $SubDomain . '.' . $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'Type' => $Type, 'Line' => $Line];
- $data = $this->request($param, true);
- if($data){
- $list = [];
- foreach($data['DomainRecords']['Record'] as $row){
- $list[] = [
- 'RecordId' => $row['RecordId'],
- 'Domain' => $row['DomainName'],
- 'Name' => $row['RR'],
- 'Type' => $row['Type'],
- 'Value' => $row['Value'],
- 'Line' => $row['Line'],
- 'TTL' => $row['TTL'],
- 'MX' => isset($row['Priority']) ? $row['Priority'] : null,
- 'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
- 'Weight' => isset($row['Weight']) ? $row['Weight'] : null,
- 'Remark' => isset($row['Remark']) ? $row['Remark'] : null,
- 'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', $row['UpdateTimestamp']/1000) : null,
- ];
- }
- return ['total' => $data['TotalCount'], 'list' => $list];
- }
- return false;
- }
+ //获取子域名解析记录列表
+ public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
+ {
+ $param = ['Action' => 'DescribeSubDomainRecords', 'SubDomain' => $SubDomain . '.' . $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'Type' => $Type, 'Line' => $Line];
+ $data = $this->request($param, true);
+ if ($data) {
+ $list = [];
+ foreach ($data['DomainRecords']['Record'] as $row) {
+ $list[] = [
+ 'RecordId' => $row['RecordId'],
+ 'Domain' => $row['DomainName'],
+ 'Name' => $row['RR'],
+ 'Type' => $row['Type'],
+ 'Value' => $row['Value'],
+ 'Line' => $row['Line'],
+ 'TTL' => $row['TTL'],
+ 'MX' => isset($row['Priority']) ? $row['Priority'] : null,
+ 'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
+ 'Weight' => isset($row['Weight']) ? $row['Weight'] : null,
+ 'Remark' => isset($row['Remark']) ? $row['Remark'] : null,
+ 'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', $row['UpdateTimestamp'] / 1000) : null,
+ ];
+ }
+ return ['total' => $data['TotalCount'], 'list' => $list];
+ }
+ return false;
+ }
- //获取解析记录详细信息
- public function getDomainRecordInfo($RecordId){
- $param = ['Action' => 'DescribeDomainRecordInfo', 'RecordId' => $RecordId];
- $data = $this->request($param, true);
- if($data){
- return [
- 'RecordId' => $data['RecordId'],
- 'Domain' => $data['DomainName'],
- 'Name' => $data['RR'],
- 'Type' => $data['Type'],
- 'Value' => $data['Value'],
- 'Line' => $data['Line'],
- 'TTL' => $data['TTL'],
- 'MX' => isset($data['Priority']) ? $data['Priority'] : null,
- 'Status' => $data['Status'] == 'ENABLE' ? '1' : '0',
- 'Weight' => isset($data['Weight']) ? $data['Weight'] : null,
- 'Remark' => isset($data['Remark']) ? $data['Remark'] : null,
- 'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', $data['UpdateTimestamp']/1000) : null,
- ];
- }
- return false;
- }
+ //获取解析记录详细信息
+ public function getDomainRecordInfo($RecordId)
+ {
+ $param = ['Action' => 'DescribeDomainRecordInfo', 'RecordId' => $RecordId];
+ $data = $this->request($param, true);
+ if ($data) {
+ return [
+ 'RecordId' => $data['RecordId'],
+ 'Domain' => $data['DomainName'],
+ 'Name' => $data['RR'],
+ 'Type' => $data['Type'],
+ 'Value' => $data['Value'],
+ 'Line' => $data['Line'],
+ 'TTL' => $data['TTL'],
+ 'MX' => isset($data['Priority']) ? $data['Priority'] : null,
+ 'Status' => $data['Status'] == 'ENABLE' ? '1' : '0',
+ 'Weight' => isset($data['Weight']) ? $data['Weight'] : null,
+ 'Remark' => isset($data['Remark']) ? $data['Remark'] : null,
+ 'UpdateTime' => isset($row['UpdateTimestamp']) ? date('Y-m-d H:i:s', $data['UpdateTimestamp'] / 1000) : null,
+ ];
+ }
+ return false;
+ }
- //添加解析记录
- public function addDomainRecord($Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = null, $Weight = null, $Remark = null){
- $param = ['Action' => 'AddDomainRecord', 'DomainName' => $this->domain, 'RR' => $Name, 'Type' => $Type, 'Value' => $Value, 'Line' => $this->convertLineCode($Line), 'TTL' => intval($TTL)];
- if($MX){
- $param['Priority'] = intval($MX);
- }
- $data = $this->request($param, true);
- if($data){
- return $data['RecordId'];
- }
- return false;
- }
+ //添加解析记录
+ public function addDomainRecord($Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = null, $Weight = null, $Remark = null)
+ {
+ $param = ['Action' => 'AddDomainRecord', 'DomainName' => $this->domain, 'RR' => $Name, 'Type' => $Type, 'Value' => $Value, 'Line' => $this->convertLineCode($Line), 'TTL' => intval($TTL)];
+ if ($MX) {
+ $param['Priority'] = intval($MX);
+ }
+ $data = $this->request($param, true);
+ if ($data) {
+ return $data['RecordId'];
+ }
+ return false;
+ }
- //修改解析记录
- public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = null, $Weight = null, $Remark = null){
- $param = ['Action' => 'UpdateDomainRecord', 'RecordId' => $RecordId, 'RR' => $Name, 'Type' => $Type, 'Value' => $Value, 'Line' => $this->convertLineCode($Line), 'TTL' => intval($TTL)];
- if($MX){
- $param['Priority'] = intval($MX);
- }
- return $this->request($param);
- }
+ //修改解析记录
+ public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = 'default', $TTL = 600, $MX = null, $Weight = null, $Remark = null)
+ {
+ $param = ['Action' => 'UpdateDomainRecord', 'RecordId' => $RecordId, 'RR' => $Name, 'Type' => $Type, 'Value' => $Value, 'Line' => $this->convertLineCode($Line), 'TTL' => intval($TTL)];
+ if ($MX) {
+ $param['Priority'] = intval($MX);
+ }
+ return $this->request($param);
+ }
- //修改解析记录备注
- public function updateDomainRecordRemark($RecordId, $Remark){
- $param = ['Action' => 'UpdateDomainRecordRemark', 'RecordId' => $RecordId, 'Remark' => $Remark];
- return $this->request($param);
- }
+ //修改解析记录备注
+ public function updateDomainRecordRemark($RecordId, $Remark)
+ {
+ $param = ['Action' => 'UpdateDomainRecordRemark', 'RecordId' => $RecordId, 'Remark' => $Remark];
+ return $this->request($param);
+ }
- //删除解析记录
- public function deleteDomainRecord($RecordId){
- $param = ['Action' => 'DeleteDomainRecord', 'RecordId' => $RecordId];
- return $this->request($param);
- }
+ //删除解析记录
+ public function deleteDomainRecord($RecordId)
+ {
+ $param = ['Action' => 'DeleteDomainRecord', 'RecordId' => $RecordId];
+ return $this->request($param);
+ }
- //删除子域名的解析记录
- public function deleteSubDomainRecords($SubDomain){
- $param = ['Action' => 'DeleteSubDomainRecords', 'DomainName' => $this->domain, 'RR' => $SubDomain];
- return $this->request($param);
- }
+ //删除子域名的解析记录
+ public function deleteSubDomainRecords($SubDomain)
+ {
+ $param = ['Action' => 'DeleteSubDomainRecords', 'DomainName' => $this->domain, 'RR' => $SubDomain];
+ return $this->request($param);
+ }
- //设置解析记录状态
- public function setDomainRecordStatus($RecordId, $Status){
- $Status = $Status == '1' ? 'Enable' : 'Disable';
- $param = ['Action' => 'SetDomainRecordStatus', 'RecordId' => $RecordId, 'Status' => $Status];
- return $this->request($param);
- }
+ //设置解析记录状态
+ public function setDomainRecordStatus($RecordId, $Status)
+ {
+ $Status = $Status == '1' ? 'Enable' : 'Disable';
+ $param = ['Action' => 'SetDomainRecordStatus', 'RecordId' => $RecordId, 'Status' => $Status];
+ return $this->request($param);
+ }
- //获取解析记录操作日志
- public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
- $param = ['Action' => 'DescribeRecordLogs', 'DomainName' => $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'KeyWord' => $KeyWord, 'StartDate' => $StartDate, 'endDate' => $endDate, 'Lang' => 'zh'];
- $data = $this->request($param, true);
- if($data){
- $list = [];
- foreach($data['RecordLogs']['RecordLog'] as $row){
- $list[] = ['time'=>date('Y-m-d H:i:s', intval($row['ActionTimestamp']/1000)), 'data'=>$row['Message']];
- }
- return ['total' => $data['TotalCount'], 'list' => $list];
- }
- return false;
- }
+ //获取解析记录操作日志
+ public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
+ {
+ $param = ['Action' => 'DescribeRecordLogs', 'DomainName' => $this->domain, 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'KeyWord' => $KeyWord, 'StartDate' => $StartDate, 'endDate' => $endDate, 'Lang' => 'zh'];
+ $data = $this->request($param, true);
+ if ($data) {
+ $list = [];
+ foreach ($data['RecordLogs']['RecordLog'] as $row) {
+ $list[] = ['time' => date('Y-m-d H:i:s', intval($row['ActionTimestamp'] / 1000)), 'data' => $row['Message']];
+ }
+ return ['total' => $data['TotalCount'], 'list' => $list];
+ }
+ return false;
+ }
- //获取解析线路列表
- public function getRecordLine(){
- $data = $this->getDomainInfo();
- if($data){
- $list = [];
- foreach($data['RecordLines']['RecordLine'] as $row){
- $list[$row['LineCode']] = ['name'=>$row['LineDisplayName'], 'parent'=>isset($row['FatherCode']) ? $row['FatherCode'] : null];
- }
- return $list;
- }
- return false;
- }
+ //获取解析线路列表
+ public function getRecordLine()
+ {
+ $data = $this->getDomainInfo();
+ if ($data) {
+ $list = [];
+ foreach ($data['RecordLines']['RecordLine'] as $row) {
+ $list[$row['LineCode']] = ['name' => $row['LineDisplayName'], 'parent' => isset($row['FatherCode']) ? $row['FatherCode'] : null];
+ }
+ return $list;
+ }
+ return false;
+ }
- //获取域名信息
- public function getDomainInfo(){
- if(!empty($this->domainInfo)) return $this->domainInfo;
- $param = ['Action' => 'DescribeDomainInfo', 'DomainName' => $this->domain, 'NeedDetailAttributes' => 'true'];
- $data = $this->request($param, true);
- if($data){
- $this->domainInfo = $data;
- return $data;
- }
- return false;
- }
+ //获取域名信息
+ public function getDomainInfo()
+ {
+ if (!empty($this->domainInfo)) {
+ return $this->domainInfo;
+ }
+ $param = ['Action' => 'DescribeDomainInfo', 'DomainName' => $this->domain, 'NeedDetailAttributes' => 'true'];
+ $data = $this->request($param, true);
+ if ($data) {
+ $this->domainInfo = $data;
+ return $data;
+ }
+ return false;
+ }
- //获取域名最低TTL
- public function getMinTTL(){
- $data = $this->getDomainInfo();
- if($data){
- return $data['MinTtl'];
- }
- return false;
- }
+ //获取域名最低TTL
+ public function getMinTTL()
+ {
+ $data = $this->getDomainInfo();
+ if ($data) {
+ return $data['MinTtl'];
+ }
+ return false;
+ }
- private function convertLineCode($line){
- $convert_dict = ['0'=>'default', '10=1'=>'unicom', '10=0'=>'telecom', '10=3'=>'mobile', '10=2'=>'edu', '3=0'=>'oversea', '10=22'=>'btvn', '80=0'=>'search', '7=0'=>'internal'];
- if(array_key_exists($line, $convert_dict)){
- return $convert_dict[$line];
- }
- return $line;
- }
+ private function convertLineCode($line)
+ {
+ $convert_dict = ['0' => 'default', '10=1' => 'unicom', '10=0' => 'telecom', '10=3' => 'mobile', '10=2' => 'edu', '3=0' => 'oversea', '10=22' => 'btvn', '80=0' => 'search', '7=0' => 'internal'];
+ if (array_key_exists($line, $convert_dict)) {
+ return $convert_dict[$line];
+ }
+ return $line;
+ }
- private function aliyunSignature($parameters, $accessKeySecret, $method)
- {
- ksort($parameters);
- $canonicalizedQueryString = '';
- foreach ($parameters as $key => $value) {
- if($value === null) continue;
- $canonicalizedQueryString .= '&' . $this->percentEncode($key). '=' . $this->percentEncode($value);
- }
- $stringToSign = $method . '&%2F&' . $this->percentEncode(substr($canonicalizedQueryString, 1));
- $signature = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret."&", true));
+ private function aliyunSignature($parameters, $accessKeySecret, $method)
+ {
+ ksort($parameters);
+ $canonicalizedQueryString = '';
+ foreach ($parameters as $key => $value) {
+ if ($value === null) {
+ continue;
+ }
+ $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)
- {
- $search = ['+', '*', '%7E'];
- $replace = ['%20', '%2A', '~'];
- return str_replace($search, $replace, urlencode($str));
- }
- private function request($param, $returnData=false){
- if(empty($this->AccessKeyId)||empty($this->AccessKeySecret))return false;
- $result = $this->request_do($param, $returnData);
- if(!$returnData && $result!==true){
- usleep(50000);
- $result = $this->request_do($param, $returnData);
- }
- return $result;
- }
- private function request_do($param, $returnData=false){
- if(empty($this->AccessKeyId)||empty($this->AccessKeySecret))return false;
- $url='https://'.$this->Endpoint.'/';
- $data=array(
- 'Format' => 'JSON',
- 'Version' => $this->Version,
- 'AccessKeyId' => $this->AccessKeyId,
- 'SignatureMethod' => 'HMAC-SHA1',
- 'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
- 'SignatureVersion' => '1.0',
- 'SignatureNonce' => random(8));
- $data=array_merge($data, $param);
- $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));
- $response = curl_exec($ch);
- $errno = curl_errno($ch);
- $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
- if ($errno) {
- $this->setError('Curl error: ' . curl_error($ch));
- }
- curl_close($ch);
- if ($errno) return false;
+ return $signature;
+ }
+ private function percentEncode($str)
+ {
+ $search = ['+', '*', '%7E'];
+ $replace = ['%20', '%2A', '~'];
+ return str_replace($search, $replace, urlencode($str));
+ }
+ private function request($param, $returnData = false)
+ {
+ if (empty($this->AccessKeyId) || empty($this->AccessKeySecret)) {
+ return false;
+ }
+ $result = $this->request_do($param, $returnData);
+ if (!$returnData && $result !== true) {
+ usleep(50000);
+ $result = $this->request_do($param, $returnData);
+ }
+ return $result;
+ }
+ private function request_do($param, $returnData = false)
+ {
+ if (empty($this->AccessKeyId) || empty($this->AccessKeySecret)) {
+ return false;
+ }
+ $url = 'https://'.$this->Endpoint.'/';
+ $client = new Client([
+ 'base_uri' => $url
+ ]);
+ $data = [
+ 'Format' => 'JSON',
+ 'Version' => $this->Version,
+ 'AccessKeyId' => $this->AccessKeyId,
+ 'SignatureMethod' => 'HMAC-SHA1',
+ 'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
+ 'SignatureVersion' => '1.0',
+ 'SignatureNonce' => random(8)
+ ];
+ $data = array_merge($data, $param);
+ $data['Signature'] = $this->aliyunSignature($data, $this->AccessKeySecret, 'POST');
+ try {
+ $response = $client->post($url, [
+ 'form_params' => $data,
+ ]);
+ } catch (BadResponseException $e) {
+ $response = $e->getResponse();
+ $result = $response->getBody()->getContents();
+ $data = json_decode($result, true);
+ $this->setError($data['Message']);
+ return false;
+ } catch (\Exception $e) {
+ $errno = $e->getMessage();
+ $this->setError('Request error: ' . $errno);
+ return false;
+ }
+ $result = $response->getBody()->getContents();
+ $data = json_decode($result, true);
+ return $returnData ? $data : true;
+ }
- $arr = json_decode($response,true);
- if($httpCode==200){
- return $returnData ? $arr : true;
- }elseif($arr){
- $this->setError($arr['Message']);
- return false;
- }else{
- $this->setError('返回数据解析失败');
- return false;
- }
- }
-
- private function setError($message){
- $this->error = $message;
- //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
- }
+ private function setError($message)
+ {
+ $this->error = $message;
+ //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
+ }
}
diff --git a/app/lib/dns/baidu.php b/app/lib/dns/baidu.php
index 12796df..8318961 100644
--- a/app/lib/dns/baidu.php
+++ b/app/lib/dns/baidu.php
@@ -1,326 +1,366 @@
-AccessKeyId = $config['ak'];
- $this->SecretAccessKey = $config['sk'];
- $this->domain = $config['domain'];
- $this->domainid = $config['domainid'];
- }
-
- public function getError(){
- return $this->error;
- }
-
- public function check(){
- if($this->getDomainList() != false){
- return true;
- }
- return false;
- }
-
- //获取域名列表
- public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
- $query = ['name' => $KeyWord];
- $data = $this->send_reuqest('GET', '/v1/dns/zone', $query);
- if($data){
- $list = [];
- foreach($data['zones'] as $row){
- $list[] = [
- 'DomainId' => $row['id'],
- 'Domain' => rtrim($row['name'], '.'),
- 'RecordCount' => 0,
- ];
- }
- return ['total' => count($list), 'list' => $list];
- }
- return false;
- }
-
- //获取解析记录列表
- public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null){
- $query = ['rr' => $KeyWord];
- if(!isNullOrEmpty($SubDomain)){
- $query['rr'] = $SubDomain;
- }
- $data = $this->send_reuqest('GET', '/v1/dns/zone/'.$this->domain.'/record', $query);
- if($data){
- $list = [];
- foreach($data['records'] as $row){
- $list[] = [
- 'RecordId' => $row['id'],
- 'Domain' => $this->domain,
- 'Name' => $row['rr'],
- 'Type' => $row['type'],
- 'Value' => $row['value'],
- 'Line' => $row['line'],
- 'TTL' => $row['ttl'],
- 'MX' => $row['priority'],
- 'Status' => $row['status'] == 'running' ? '1' : '0',
- 'Weight' => null,
- 'Remark' => $row['description'],
- 'UpdateTime' => null,
- ];
- }
- return ['total' => count($list), 'list' => $list];
- }
- return false;
- }
-
- //获取子域名解析记录列表
- public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
- if($SubDomain == '')$SubDomain='@';
- return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
- }
-
- //获取解析记录详细信息
- public function getDomainRecordInfo($RecordId){
- $query = ['id' => $RecordId];
- $data = $this->send_reuqest('GET', '/v1/dns/zone/'.$this->domain.'/record', $query);
- if($data && !empty($data['records'])){
- $data = $data['records'][0];
- return [
- 'RecordId' => $data['id'],
- 'Domain' => rtrim($data['zone_name'], '.'),
- 'Name' => str_replace('.'.$data['zone_name'], '', $data['name']),
- 'Type' => $data['type'],
- 'Value' => $data['value'],
- 'Line' => $data['line'],
- 'TTL' => $data['ttl'],
- 'MX' => $data['priority'],
- 'Status' => $data['status'] == 'running' ? '1' : '0',
- 'Weight' => null,
- 'Remark' => $data['description'],
- 'UpdateTime' => null,
- ];
- }
- return false;
- }
-
- //添加解析记录
- public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $params = ['rr' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'line'=>$Line, 'ttl' => intval($TTL), 'description' => $Remark];
- if($Type == 'MX')$params['priority'] = intval($MX);
- $query = ['clientToken' => getSid()];
- return $this->send_reuqest('POST', '/v1/dns/zone/'.$this->domain.'/record', $query, $params);
- }
-
- //修改解析记录
- public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $params = ['rr' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'line'=>$Line, 'ttl' => intval($TTL), 'description' => $Remark];
- if($Type == 'MX')$params['priority'] = intval($MX);
- $query = ['clientToken' => getSid()];
- return $this->send_reuqest('PUT', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query, $params);
- }
-
- //修改解析记录备注
- public function updateDomainRecordRemark($RecordId, $Remark){
- return false;
- }
-
- //删除解析记录
- public function deleteDomainRecord($RecordId){
- $query = ['clientToken' => getSid()];
- return $this->send_reuqest('DELETE', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query);
- }
-
- //设置解析记录状态
- public function setDomainRecordStatus($RecordId, $Status){
- $Status = $Status == '1' ? 'enable' : 'disable';
- $query = [$Status => '', 'clientToken' => getSid()];
- return $this->send_reuqest('PUT', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query);
- }
-
- //获取解析记录操作日志
- public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
- return false;
- }
-
- //获取解析线路列表
- public function getRecordLine(){
- return [
- 'default'=>['name'=>'默认', 'parent'=>null],
- 'ct'=>['name'=>'电信', 'parent'=>null],
- 'cnc'=>['name'=>'联通', 'parent'=>null],
- 'cmnet'=>['name'=>'移动', 'parent'=>null],
- 'edu'=>['name'=>'教育网', 'parent'=>null],
- 'search'=>['name'=>'搜索引擎(百度)', 'parent'=>null],
- ];
- }
-
- //获取域名概览信息
- public function getDomainInfo(){
- $res = $this->getDomainList($this->domain);
- if($res && !empty($res['list'])){
- return $res['list'][0];
- }
- return false;
- }
-
- //获取域名最低TTL
- public function getMinTTL(){
- return false;
- }
-
- private function convertType($type){
- return $type;
- }
-
- private function send_reuqest($method, $path, $query = null, $params = null){
- if(!empty($query)){
- $query = array_filter($query, function($a){ return $a!==null;});
- }
- if(!empty($params)){
- $params = array_filter($params, function($a){ return $a!==null;});
- }
-
- $time = time();
- $date = gmdate("Y-m-d\TH:i:s\Z", $time);
- $body = !empty($params) ? json_encode($params) : '';
- $headers = [
- 'Host' => $this->endpoint,
- 'x-bce-date' => $date,
- ];
- if($body){
- $headers['Content-Type'] = 'application/json';
- }
-
- $authorization = $this->generateSign($method, $path, $query, $headers, $time);
- $headers['Authorization'] = $authorization;
-
- $url = 'https://'.$this->endpoint.$path;
- if(!empty($query)){
- $url .= '?'.http_build_query($query);
- }
- $header = [];
- foreach($headers as $key => $value){
- $header[] = $key.': '.$value;
- }
- return $this->curl($method, $url, $body, $header);
- }
-
- private function generateSign($method, $path, $query, $headers, $time){
- $algorithm = "bce-auth-v1";
-
- // step 1: build canonical request string
- $httpRequestMethod = $method;
- $canonicalUri = $this->getCanonicalUri($path);
- $canonicalQueryString = $this->getCanonicalQueryString($query);
- [$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
- $canonicalRequest = $httpRequestMethod."\n"
- .$canonicalUri."\n"
- .$canonicalQueryString."\n"
- .$canonicalHeaders;
-
- // step 2: calculate signing key
- $date = gmdate("Y-m-d\TH:i:s\Z", $time);
- $expirationInSeconds = 1800;
- $authString = $algorithm . '/' . $this->AccessKeyId . '/' . $date . '/' . $expirationInSeconds;
- $signingKey = hash_hmac('sha256', $authString, $this->SecretAccessKey);
-
- // step 3: sign string
- $signature = hash_hmac("sha256", $canonicalRequest, $signingKey);
-
- // step 4: build authorization
- $authorization = $authString . '/' . $signedHeaders . "/" . $signature;
-
- return $authorization;
- }
-
- private function escape($str)
- {
- $search = ['+', '*', '%7E'];
- $replace = ['%20', '%2A', '~'];
- return str_replace($search, $replace, urlencode($str));
- }
-
- private function getCanonicalUri($path)
- {
- if(empty($path)) return '/';
- $uri = str_replace('%2F', '/', $this->escape($path));
- if(substr($uri, 0, 1) !== '/') $uri = '/'.$uri;
- return $uri;
- }
-
- private function getCanonicalQueryString($parameters)
- {
- if(empty($parameters)) return '';
- ksort($parameters);
- $canonicalQueryString = '';
- foreach ($parameters as $key => $value) {
- if($key == 'authorization') continue;
- $canonicalQueryString .= '&' . $this->escape($key). '=' . $this->escape($value);
- }
- return substr($canonicalQueryString, 1);
- }
-
- private function getCanonicalHeaders($oldheaders){
- $headers = array();
- foreach ($oldheaders as $key => $value) {
- $headers[strtolower($key)] = trim($value);
- }
- ksort($headers);
-
- $canonicalHeaders = '';
- $signedHeaders = '';
- foreach ($headers as $key => $value) {
- $canonicalHeaders .= $this->escape($key) . ':' . $this->escape($value) . "\n";
- $signedHeaders .= $key . ';';
- }
- $canonicalHeaders = substr($canonicalHeaders, 0, -1);
- $signedHeaders = substr($signedHeaders, 0, -1);
- return [$canonicalHeaders, $signedHeaders];
- }
-
- private function curl($method, $url, $body, $header){
- $ch = curl_init($url);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_TIMEOUT, 10);
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
- if(!empty($body)){
- curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
- }
- $response = curl_exec($ch);
- $errno = curl_errno($ch);
- $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
- if ($errno) {
- $this->setError('Curl error: ' . curl_error($ch));
- }
- curl_close($ch);
- if ($errno) return false;
-
- if(empty($response) && $httpCode == 200){
- return true;
- }
- $arr=json_decode($response,true);
- if($arr){
- if(isset($arr['code']) && isset($arr['message'])){
- $this->setError($arr['message']);
- return false;
- }else{
- return $arr;
- }
- }else{
- $this->setError('返回数据解析失败');
- return false;
- }
- }
-
- private function setError($message){
- $this->error = $message;
- //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
- }
-}
\ No newline at end of file
+AccessKeyId = $config['ak'];
+ $this->SecretAccessKey = $config['sk'];
+ $this->domain = $config['domain'];
+ $this->domainid = $config['domainid'];
+ }
+
+ public function getError()
+ {
+ return $this->error;
+ }
+
+ public function check()
+ {
+ if ($this->getDomainList() != false) {
+ return true;
+ }
+ return false;
+ }
+
+ //获取域名列表
+ public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
+ {
+ $query = ['name' => $KeyWord];
+ $data = $this->send_reuqest('GET', '/v1/dns/zone', $query);
+ if ($data) {
+ $list = [];
+ foreach ($data['zones'] as $row) {
+ $list[] = [
+ 'DomainId' => $row['id'],
+ 'Domain' => rtrim($row['name'], '.'),
+ 'RecordCount' => 0,
+ ];
+ }
+ return ['total' => count($list), 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取解析记录列表
+ public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
+ {
+ $query = ['rr' => $KeyWord];
+ if (!isNullOrEmpty($SubDomain)) {
+ $query['rr'] = $SubDomain;
+ }
+ $data = $this->send_reuqest('GET', '/v1/dns/zone/'.$this->domain.'/record', $query);
+ if ($data) {
+ $list = [];
+ foreach ($data['records'] as $row) {
+ $list[] = [
+ 'RecordId' => $row['id'],
+ 'Domain' => $this->domain,
+ 'Name' => $row['rr'],
+ 'Type' => $row['type'],
+ 'Value' => $row['value'],
+ 'Line' => $row['line'],
+ 'TTL' => $row['ttl'],
+ 'MX' => $row['priority'],
+ 'Status' => $row['status'] == 'running' ? '1' : '0',
+ 'Weight' => null,
+ 'Remark' => $row['description'],
+ 'UpdateTime' => null,
+ ];
+ }
+ return ['total' => count($list), 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取子域名解析记录列表
+ public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
+ {
+ if ($SubDomain == '') {
+ $SubDomain = '@';
+ }
+ return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
+ }
+
+ //获取解析记录详细信息
+ public function getDomainRecordInfo($RecordId)
+ {
+ $query = ['id' => $RecordId];
+ $data = $this->send_reuqest('GET', '/v1/dns/zone/'.$this->domain.'/record', $query);
+ if ($data && !empty($data['records'])) {
+ $data = $data['records'][0];
+ return [
+ 'RecordId' => $data['id'],
+ 'Domain' => rtrim($data['zone_name'], '.'),
+ 'Name' => str_replace('.'.$data['zone_name'], '', $data['name']),
+ 'Type' => $data['type'],
+ 'Value' => $data['value'],
+ 'Line' => $data['line'],
+ 'TTL' => $data['ttl'],
+ 'MX' => $data['priority'],
+ 'Status' => $data['status'] == 'running' ? '1' : '0',
+ 'Weight' => null,
+ 'Remark' => $data['description'],
+ 'UpdateTime' => null,
+ ];
+ }
+ return false;
+ }
+
+ //添加解析记录
+ public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $params = ['rr' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'line' => $Line, 'ttl' => intval($TTL), 'description' => $Remark];
+ if ($Type == 'MX') {
+ $params['priority'] = intval($MX);
+ }
+ $query = ['clientToken' => getSid()];
+ return $this->send_reuqest('POST', '/v1/dns/zone/'.$this->domain.'/record', $query, $params);
+ }
+
+ //修改解析记录
+ public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $params = ['rr' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'line' => $Line, 'ttl' => intval($TTL), 'description' => $Remark];
+ if ($Type == 'MX') {
+ $params['priority'] = intval($MX);
+ }
+ $query = ['clientToken' => getSid()];
+ return $this->send_reuqest('PUT', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query, $params);
+ }
+
+ //修改解析记录备注
+ public function updateDomainRecordRemark($RecordId, $Remark)
+ {
+ return false;
+ }
+
+ //删除解析记录
+ public function deleteDomainRecord($RecordId)
+ {
+ $query = ['clientToken' => getSid()];
+ return $this->send_reuqest('DELETE', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query);
+ }
+
+ //设置解析记录状态
+ public function setDomainRecordStatus($RecordId, $Status)
+ {
+ $Status = $Status == '1' ? 'enable' : 'disable';
+ $query = [$Status => '', 'clientToken' => getSid()];
+ return $this->send_reuqest('PUT', '/v1/dns/zone/'.$this->domain.'/record/'.$RecordId, $query);
+ }
+
+ //获取解析记录操作日志
+ public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
+ {
+ return false;
+ }
+
+ //获取解析线路列表
+ public function getRecordLine()
+ {
+ return [
+ 'default' => ['name' => '默认', 'parent' => null],
+ 'ct' => ['name' => '电信', 'parent' => null],
+ 'cnc' => ['name' => '联通', 'parent' => null],
+ 'cmnet' => ['name' => '移动', 'parent' => null],
+ 'edu' => ['name' => '教育网', 'parent' => null],
+ 'search' => ['name' => '搜索引擎(百度)', 'parent' => null],
+ ];
+ }
+
+ //获取域名概览信息
+ public function getDomainInfo()
+ {
+ $res = $this->getDomainList($this->domain);
+ if ($res && !empty($res['list'])) {
+ return $res['list'][0];
+ }
+ return false;
+ }
+
+ //获取域名最低TTL
+ public function getMinTTL()
+ {
+ return false;
+ }
+
+ private function convertType($type)
+ {
+ return $type;
+ }
+
+ private function send_reuqest($method, $path, $query = null, $params = null)
+ {
+ if (!empty($query)) {
+ $query = array_filter($query, function ($a) { return $a !== null;});
+ }
+ if (!empty($params)) {
+ $params = array_filter($params, function ($a) { return $a !== null;});
+ }
+
+ $time = time();
+ $date = gmdate("Y-m-d\TH:i:s\Z", $time);
+ $body = !empty($params) ? json_encode($params) : '';
+ $headers = [
+ 'Host' => $this->endpoint,
+ 'x-bce-date' => $date,
+ ];
+ if ($body) {
+ $headers['Content-Type'] = 'application/json';
+ }
+
+ $authorization = $this->generateSign($method, $path, $query, $headers, $time);
+ $headers['Authorization'] = $authorization;
+
+ $url = 'https://'.$this->endpoint.$path;
+ if (!empty($query)) {
+ $url .= '?'.http_build_query($query);
+ }
+ $header = [];
+ foreach ($headers as $key => $value) {
+ $header[] = $key.': '.$value;
+ }
+ return $this->curl($method, $url, $body, $header);
+ }
+
+ private function generateSign($method, $path, $query, $headers, $time)
+ {
+ $algorithm = "bce-auth-v1";
+
+ // step 1: build canonical request string
+ $httpRequestMethod = $method;
+ $canonicalUri = $this->getCanonicalUri($path);
+ $canonicalQueryString = $this->getCanonicalQueryString($query);
+ [$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
+ $canonicalRequest = $httpRequestMethod."\n"
+ .$canonicalUri."\n"
+ .$canonicalQueryString."\n"
+ .$canonicalHeaders;
+
+ // step 2: calculate signing key
+ $date = gmdate("Y-m-d\TH:i:s\Z", $time);
+ $expirationInSeconds = 1800;
+ $authString = $algorithm . '/' . $this->AccessKeyId . '/' . $date . '/' . $expirationInSeconds;
+ $signingKey = hash_hmac('sha256', $authString, $this->SecretAccessKey);
+
+ // step 3: sign string
+ $signature = hash_hmac("sha256", $canonicalRequest, $signingKey);
+
+ // step 4: build authorization
+ $authorization = $authString . '/' . $signedHeaders . "/" . $signature;
+
+ return $authorization;
+ }
+
+ private function escape($str)
+ {
+ $search = ['+', '*', '%7E'];
+ $replace = ['%20', '%2A', '~'];
+ return str_replace($search, $replace, urlencode($str));
+ }
+
+ private function getCanonicalUri($path)
+ {
+ if (empty($path)) {
+ return '/';
+ }
+ $uri = str_replace('%2F', '/', $this->escape($path));
+ if (substr($uri, 0, 1) !== '/') {
+ $uri = '/'.$uri;
+ }
+ return $uri;
+ }
+
+ private function getCanonicalQueryString($parameters)
+ {
+ if (empty($parameters)) {
+ return '';
+ }
+ ksort($parameters);
+ $canonicalQueryString = '';
+ foreach ($parameters as $key => $value) {
+ if ($key == 'authorization') {
+ continue;
+ }
+ $canonicalQueryString .= '&' . $this->escape($key). '=' . $this->escape($value);
+ }
+ return substr($canonicalQueryString, 1);
+ }
+
+ private function getCanonicalHeaders($oldheaders)
+ {
+ $headers = array();
+ foreach ($oldheaders as $key => $value) {
+ $headers[strtolower($key)] = trim($value);
+ }
+ ksort($headers);
+
+ $canonicalHeaders = '';
+ $signedHeaders = '';
+ foreach ($headers as $key => $value) {
+ $canonicalHeaders .= $this->escape($key) . ':' . $this->escape($value) . "\n";
+ $signedHeaders .= $key . ';';
+ }
+ $canonicalHeaders = substr($canonicalHeaders, 0, -1);
+ $signedHeaders = substr($signedHeaders, 0, -1);
+ return [$canonicalHeaders, $signedHeaders];
+ }
+
+ private function curl($method, $url, $body, $header)
+ {
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ if (!empty($body)) {
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
+ }
+ $response = curl_exec($ch);
+ $errno = curl_errno($ch);
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ if ($errno) {
+ $this->setError('Curl error: ' . curl_error($ch));
+ }
+ curl_close($ch);
+ if ($errno) {
+ return false;
+ }
+
+ if (empty($response) && $httpCode == 200) {
+ return true;
+ }
+ $arr = json_decode($response, true);
+ if ($arr) {
+ if (isset($arr['code']) && isset($arr['message'])) {
+ $this->setError($arr['message']);
+ return false;
+ } else {
+ return $arr;
+ }
+ } else {
+ $this->setError('返回数据解析失败');
+ return false;
+ }
+ }
+
+ private function setError($message)
+ {
+ $this->error = $message;
+ //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
+ }
+}
diff --git a/app/lib/dns/dnsla.php b/app/lib/dns/dnsla.php
index 9652b8c..3173cde 100644
--- a/app/lib/dns/dnsla.php
+++ b/app/lib/dns/dnsla.php
@@ -1,256 +1,305 @@
- 'A', 2 => 'NS', 5 => 'CNAME', 15 => 'MX', 16 => 'TXT', 28 => 'AAAA', 33 => 'SRV', 257 => 'CAA', 256 => 'URL转发'];
- private $error;
- private $domain;
- private $domainid;
-
- function __construct($config){
- $this->apiid = $config['ak'];
- $this->apisecret = $config['sk'];
- $this->domain = $config['domain'];
- $this->domainid = $config['domainid'];
- }
-
- public function getError(){
- return $this->error;
- }
-
- public function check(){
- if($this->getDomainList() != false){
- return true;
- }
- return false;
- }
-
- //获取域名列表
- public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
- $param = ['pageIndex' => $PageNumber, 'pageSize' => $PageSize];
- $data = $this->execute('GET', '/api/domainList', $param);
- if($data){
- $list = [];
- foreach($data['results'] as $row){
- $list[] = [
- 'DomainId' => $row['id'],
- 'Domain' => rtrim($row['displayDomain'], '.'),
- 'RecordCount' => 0,
- ];
- }
- return ['total' => $data['total'], 'list' => $list];
- }
- return false;
- }
-
- //获取解析记录列表
- public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null){
- $param = ['domainId' => $this->domainid, 'pageIndex' => $PageNumber, 'pageSize' => $PageSize];
- if(!isNullOrEmpty(($KeyWord))){
- $param['host'] = $KeyWord;
- }
- if(!isNullOrEmpty(($Type))){
- $param['type'] = $this->convertType($Type);
- }
- if(!isNullOrEmpty(($Line))){
- $param['lineId'] = $Line;
- }
- if(!isNullOrEmpty(($SubDomain))){
- $param['host'] = $SubDomain;
- }
- if(!isNullOrEmpty(($Value))){
- $param['data'] = $Value;
- }
- $data = $this->execute('GET', '/api/recordList', $param);
- if($data){
- $list = [];
- foreach($data['results'] as $row){
- $list[] = [
- 'RecordId' => $row['id'],
- 'Domain' => $this->domain,
- 'Name' => $row['host'],
- 'Type' => $this->convertTypeId($row['type'], isset($row['domaint']) ? $row['domaint'] : false),
- 'Value' => $row['data'],
- 'Line' => $row['lineId'],
- 'TTL' => $row['ttl'],
- 'MX' => isset($row['preference']) ? $row['preference'] : null,
- 'Status' => $row['disable'] ? '0' : '1',
- 'Weight' => isset($row['weight']) ? $row['weight'] : null,
- 'Remark' => null,
- 'UpdateTime' => date('Y-m-d H:i:s', $row['updatedAt']),
- ];
- }
- return ['total' => $data['total'], 'list' => $list];
- }
- return false;
- }
-
- //获取子域名解析记录列表
- public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
- if($SubDomain == '')$SubDomain='@';
- return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
- }
-
- //获取解析记录详细信息
- public function getDomainRecordInfo($RecordId){
- return false;
- }
-
- //添加解析记录
- public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $param = ['domainId' => $this->domainid, 'type' => $this->convertType($Type), 'host' => $Name, 'data' => $Value, 'ttl' => intval($TTL), 'lineId' => $Line];
- if($Type == 'MX')$param['preference'] = intval($MX);
- if($Type == 'REDIRECT_URL'){$param['type'] = 256;$param['dominant'] = true;}
- elseif($Type == 'FORWARD_URL'){$param['type'] = 256;$param['dominant'] = false;}
- if($Weight > 0) $param['weight'] = $Weight;
- $data = $this->execute('POST', '/api/record', $param);
- return is_array($data) ? $data['id'] : false;
- }
-
- //修改解析记录
- public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $param = ['id' => $RecordId, 'type' => $this->convertType($Type), 'host' => $Name, 'data' => $Value, 'ttl' => intval($TTL), 'lineId' => $Line];
- if($Type == 'MX')$param['preference'] = intval($MX);
- if($Type == 'REDIRECT_URL'){$param['type'] = 256;$param['dominant'] = true;}
- elseif($Type == 'FORWARD_URL'){$param['type'] = 256;$param['dominant'] = false;}
- if($Weight > 0) $param['weight'] = $Weight;
- $data = $this->execute('PUT', '/api/record', $param);
- return $data!==false;
- }
-
- //修改解析记录备注
- public function updateDomainRecordRemark($RecordId, $Remark){
- return false;
- }
-
- //删除解析记录
- public function deleteDomainRecord($RecordId){
- $param = ['id' => $RecordId];
- $data = $this->execute('DELETE', '/api/record', $param);
- return $data!==false;
- }
-
- //设置解析记录状态
- public function setDomainRecordStatus($RecordId, $Status){
- $param = ['id' => $RecordId, 'disable' => $Status == '0' ? true : false];
- $data = $this->execute('PUT', '/api/recordDisable', $param);
- return $data!==false;
- }
-
- //获取解析记录操作日志
- public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
- return false;
- }
-
- //获取解析线路列表
- public function getRecordLine(){
- $param = ['domain' => $this->domain];
- $data = $this->execute('GET', '/api/availableLine', $param);
- if($data){
- array_multisort(array_column($data, 'order'), SORT_ASC, $data);
- $list = [];
- foreach($data as $row){
- if($row['id'] == '0') $row['id'] = '';
- $list[$row['id']] = ['name'=>$row['value'], 'parent'=>!empty($row['pid']) ? $row['pid'] : null];
- }
- return $list;
- }
- return false;
- }
-
- //获取域名信息
- public function getDomainInfo(){
- $param = ['id' => $this->domainid];
- $data = $this->execute('GET', '/api/domain', $param);
- return $data;
- }
-
- //获取域名最低TTL
- public function getMinTTL(){
- $param = ['id' => $this->domainid];
- $data = $this->execute('GET', '/api/dnsMeasures', $param);
- if($data && isset($data['minTTL'])){
- return $data['minTTL'];
- }
- return false;
- }
-
- private function convertType($type){
- $typeList = array_flip($this->typeList);
- return $typeList[$type];
- }
-
- private function convertTypeId($typeId, $domaint){
- if($typeId == 256) return $domaint ? 'REDIRECT_URL' : 'FORWARD_URL';
- return $this->typeList[$typeId];
- }
-
- private function execute($method, $path, $params = null){
- $token = base64_encode($this->apiid.':'.$this->apisecret);
- $header = ['Authorization: Basic '.$token, 'Content-Type: application/json; charset=utf-8'];
- if($method == 'POST' || $method == 'PUT'){
- $response = $this->curl($method, $path, $header, json_encode($params));
- }else{
- if($params){
- $path .= '?'.http_build_query($params);
- }
- $response = $this->curl($method, $path, $header);
- }
- if(!$response){
- return false;
- }
- $arr=json_decode($response,true);
- if($arr){
- if($arr['code'] == 200){
- return $arr['data'];
- }else{
- $this->setError($arr['msg']);
- return false;
- }
- }else{
- $this->setError('返回数据解析失败');
- return false;
- }
- }
-
- private function curl($method, $path, $header, $body = null, $isPut = false){
- $url = $this->baseUrl . $path;
- $ch = curl_init($url);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_TIMEOUT, 10);
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
- if ($body) {
- curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
- }
- $response = curl_exec($ch);
- $errno = curl_errno($ch);
- if ($errno) {
- $this->setError('Curl error: ' . curl_error($ch));
- }
- $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
- curl_close($ch);
- if ($errno) return false;
- if($httpCode==200){
- return $response;
- }elseif($httpCode==401){
- $this->setError('认证失败');
- return false;
- }else{
- $this->setError('http code: '.$httpCode);
- return false;
- }
- }
-
- private function setError($message){
- $this->error = $message;
- //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
- }
-}
\ No newline at end of file
+ 'A', 2 => 'NS', 5 => 'CNAME', 15 => 'MX', 16 => 'TXT', 28 => 'AAAA', 33 => 'SRV', 257 => 'CAA', 256 => 'URL转发'];
+ private $error;
+ private $domain;
+ private $domainid;
+
+ public function __construct($config)
+ {
+ $this->apiid = $config['ak'];
+ $this->apisecret = $config['sk'];
+ $this->domain = $config['domain'];
+ $this->domainid = $config['domainid'];
+ }
+
+ public function getError()
+ {
+ return $this->error;
+ }
+
+ public function check()
+ {
+ if ($this->getDomainList() != false) {
+ return true;
+ }
+ return false;
+ }
+
+ //获取域名列表
+ public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
+ {
+ $param = ['pageIndex' => $PageNumber, 'pageSize' => $PageSize];
+ $data = $this->execute('GET', '/api/domainList', $param);
+ if ($data) {
+ $list = [];
+ foreach ($data['results'] as $row) {
+ $list[] = [
+ 'DomainId' => $row['id'],
+ 'Domain' => rtrim($row['displayDomain'], '.'),
+ 'RecordCount' => 0,
+ ];
+ }
+ return ['total' => $data['total'], 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取解析记录列表
+ public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
+ {
+ $param = ['domainId' => $this->domainid, 'pageIndex' => $PageNumber, 'pageSize' => $PageSize];
+ if (!isNullOrEmpty(($KeyWord))) {
+ $param['host'] = $KeyWord;
+ }
+ if (!isNullOrEmpty(($Type))) {
+ $param['type'] = $this->convertType($Type);
+ }
+ if (!isNullOrEmpty(($Line))) {
+ $param['lineId'] = $Line;
+ }
+ if (!isNullOrEmpty(($SubDomain))) {
+ $param['host'] = $SubDomain;
+ }
+ if (!isNullOrEmpty(($Value))) {
+ $param['data'] = $Value;
+ }
+ $data = $this->execute('GET', '/api/recordList', $param);
+ if ($data) {
+ $list = [];
+ foreach ($data['results'] as $row) {
+ $list[] = [
+ 'RecordId' => $row['id'],
+ 'Domain' => $this->domain,
+ 'Name' => $row['host'],
+ 'Type' => $this->convertTypeId($row['type'], isset($row['domaint']) ? $row['domaint'] : false),
+ 'Value' => $row['data'],
+ 'Line' => $row['lineId'],
+ 'TTL' => $row['ttl'],
+ 'MX' => isset($row['preference']) ? $row['preference'] : null,
+ 'Status' => $row['disable'] ? '0' : '1',
+ 'Weight' => isset($row['weight']) ? $row['weight'] : null,
+ 'Remark' => null,
+ 'UpdateTime' => date('Y-m-d H:i:s', $row['updatedAt']),
+ ];
+ }
+ return ['total' => $data['total'], 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取子域名解析记录列表
+ public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
+ {
+ if ($SubDomain == '') {
+ $SubDomain = '@';
+ }
+ return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
+ }
+
+ //获取解析记录详细信息
+ public function getDomainRecordInfo($RecordId)
+ {
+ return false;
+ }
+
+ //添加解析记录
+ public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $param = ['domainId' => $this->domainid, 'type' => $this->convertType($Type), 'host' => $Name, 'data' => $Value, 'ttl' => intval($TTL), 'lineId' => $Line];
+ if ($Type == 'MX') {
+ $param['preference'] = intval($MX);
+ }
+ if ($Type == 'REDIRECT_URL') {
+ $param['type'] = 256;
+ $param['dominant'] = true;
+ } elseif ($Type == 'FORWARD_URL') {
+ $param['type'] = 256;
+ $param['dominant'] = false;
+ }
+ if ($Weight > 0) {
+ $param['weight'] = $Weight;
+ }
+ $data = $this->execute('POST', '/api/record', $param);
+ return is_array($data) ? $data['id'] : false;
+ }
+
+ //修改解析记录
+ public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $param = ['id' => $RecordId, 'type' => $this->convertType($Type), 'host' => $Name, 'data' => $Value, 'ttl' => intval($TTL), 'lineId' => $Line];
+ if ($Type == 'MX') {
+ $param['preference'] = intval($MX);
+ }
+ if ($Type == 'REDIRECT_URL') {
+ $param['type'] = 256;
+ $param['dominant'] = true;
+ } elseif ($Type == 'FORWARD_URL') {
+ $param['type'] = 256;
+ $param['dominant'] = false;
+ }
+ if ($Weight > 0) {
+ $param['weight'] = $Weight;
+ }
+ $data = $this->execute('PUT', '/api/record', $param);
+ return $data !== false;
+ }
+
+ //修改解析记录备注
+ public function updateDomainRecordRemark($RecordId, $Remark)
+ {
+ return false;
+ }
+
+ //删除解析记录
+ public function deleteDomainRecord($RecordId)
+ {
+ $param = ['id' => $RecordId];
+ $data = $this->execute('DELETE', '/api/record', $param);
+ return $data !== false;
+ }
+
+ //设置解析记录状态
+ public function setDomainRecordStatus($RecordId, $Status)
+ {
+ $param = ['id' => $RecordId, 'disable' => $Status == '0' ? true : false];
+ $data = $this->execute('PUT', '/api/recordDisable', $param);
+ return $data !== false;
+ }
+
+ //获取解析记录操作日志
+ public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
+ {
+ return false;
+ }
+
+ //获取解析线路列表
+ public function getRecordLine()
+ {
+ $param = ['domain' => $this->domain];
+ $data = $this->execute('GET', '/api/availableLine', $param);
+ if ($data) {
+ array_multisort(array_column($data, 'order'), SORT_ASC, $data);
+ $list = [];
+ foreach ($data as $row) {
+ if ($row['id'] == '0') {
+ $row['id'] = '';
+ }
+ $list[$row['id']] = ['name' => $row['value'], 'parent' => !empty($row['pid']) ? $row['pid'] : null];
+ }
+ return $list;
+ }
+ return false;
+ }
+
+ //获取域名信息
+ public function getDomainInfo()
+ {
+ $param = ['id' => $this->domainid];
+ $data = $this->execute('GET', '/api/domain', $param);
+ return $data;
+ }
+
+ //获取域名最低TTL
+ public function getMinTTL()
+ {
+ $param = ['id' => $this->domainid];
+ $data = $this->execute('GET', '/api/dnsMeasures', $param);
+ if ($data && isset($data['minTTL'])) {
+ return $data['minTTL'];
+ }
+ return false;
+ }
+
+ private function convertType($type)
+ {
+ $typeList = array_flip($this->typeList);
+ return $typeList[$type];
+ }
+
+ private function convertTypeId($typeId, $domaint)
+ {
+ if ($typeId == 256) {
+ return $domaint ? 'REDIRECT_URL' : 'FORWARD_URL';
+ }
+ return $this->typeList[$typeId];
+ }
+
+ private function execute($method, $path, $params = null)
+ {
+ $token = base64_encode($this->apiid.':'.$this->apisecret);
+ $header = ['Authorization: Basic '.$token, 'Content-Type: application/json; charset=utf-8'];
+ if ($method == 'POST' || $method == 'PUT') {
+ $response = $this->curl($method, $path, $header, json_encode($params));
+ } else {
+ if ($params) {
+ $path .= '?'.http_build_query($params);
+ }
+ $response = $this->curl($method, $path, $header);
+ }
+ if (!$response) {
+ return false;
+ }
+ $arr = json_decode($response, true);
+ if ($arr) {
+ if ($arr['code'] == 200) {
+ return $arr['data'];
+ } else {
+ $this->setError($arr['msg']);
+ return false;
+ }
+ } else {
+ $this->setError('返回数据解析失败');
+ return false;
+ }
+ }
+
+ private function curl($method, $path, $header, $body = null, $isPut = false)
+ {
+ $url = $this->baseUrl . $path;
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ if ($body) {
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
+ }
+ $response = curl_exec($ch);
+ $errno = curl_errno($ch);
+ if ($errno) {
+ $this->setError('Curl error: ' . curl_error($ch));
+ }
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ curl_close($ch);
+ if ($errno) {
+ return false;
+ }
+ if ($httpCode == 200) {
+ return $response;
+ } elseif ($httpCode == 401) {
+ $this->setError('认证失败');
+ return false;
+ } else {
+ $this->setError('http code: '.$httpCode);
+ return false;
+ }
+ }
+
+ private function setError($message)
+ {
+ $this->error = $message;
+ //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
+ }
+}
diff --git a/app/lib/dns/dnspod.php b/app/lib/dns/dnspod.php
index f3b1fe1..2d67e9e 100644
--- a/app/lib/dns/dnspod.php
+++ b/app/lib/dns/dnspod.php
@@ -1,407 +1,458 @@
-SecretId = $config['ak'];
- $this->SecretKey = $config['sk'];
- $this->domain = $config['domain'];
- }
-
- public function getError(){
- return $this->error;
- }
-
- public function check(){
- if($this->getDomainList() != false){
- return true;
- }
- return false;
- }
-
- //获取域名列表
- public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
- $action = 'DescribeDomainList';
- $offset = ($PageNumber-1)*$PageSize;
- $param = ['Offset' => $offset, 'Limit' => $PageSize, 'Keyword' => $KeyWord];
- $data = $this->send_reuqest($action, $param);
- if($data){
- $list = [];
- foreach($data['DomainList'] as $row){
- $list[] = [
- 'DomainId' => $row['DomainId'],
- 'Domain' => $row['Name'],
- 'RecordCount' => $row['RecordCount'],
- ];
- }
- return ['total' => $data['DomainCountInfo']['DomainTotal'], 'list' => $list];
- }
- return false;
- }
-
- //获取解析记录列表
- public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null){
- $offset = ($PageNumber-1)*$PageSize;
- if(!isNullOrEmpty($Status) || !isNullOrEmpty($Value)){
- $action = 'DescribeRecordFilterList';
- $param = ['Domain' => $this->domain, 'Offset' => $offset, 'Limit' => $PageSize, 'RecordValue' => $Value];
- if(!isNullOrEmpty($SubDomain)) $param['SubDomain'] = $SubDomain;
- if(!isNullOrEmpty($KeyWord)) $param['Keyword'] = $KeyWord;
- if(!isNullOrEmpty($Value)) $param['RecordValue'] = $Value;
- if(!isNullOrEmpty($Status)){
- $Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
- $param['RecordStatus'] = [$Status];
- }
- if(!isNullOrEmpty($Type)) $param['RecordType'] = [$this->convertType($Type)];
- if(!isNullOrEmpty($Line)) $param['RecordLine'] = [$Line];
- }else{
- $action = 'DescribeRecordList';
- $param = ['Domain' => $this->domain, 'Subdomain' => $SubDomain, 'RecordType' => $this->convertType($Type), 'RecordLineId' => $Line, 'Keyword' => $KeyWord, 'Offset' => $offset, 'Limit' => $PageSize];
- }
- $data = $this->send_reuqest($action, $param);
- if($data){
- $list = [];
- foreach($data['RecordList'] as $row){
- //if($row['Name'] == '@' && $row['Type'] == 'NS') continue;
- $list[] = [
- 'RecordId' => $row['RecordId'],
- 'Domain' => $this->domain,
- 'Name' => $row['Name'],
- 'Type' => $this->convertTypeId($row['Type']),
- 'Value' => $row['Value'],
- 'Line' => $row['LineId'],
- 'TTL' => $row['TTL'],
- 'MX' => $row['MX'],
- 'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
- 'Weight' => $row['Weight'],
- 'Remark' => $row['Remark'],
- 'UpdateTime' => $row['UpdatedOn'],
- ];
- }
- return ['total' => $data['RecordCountInfo']['TotalCount'], 'list' => $list];
- }elseif($this->error == '记录列表为空。' || $this->error == 'No records on the list.'){
- return ['total' => 0, 'list' => []];
- }
- return false;
- }
-
- //获取子域名解析记录列表
- public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
- if($SubDomain == '')$SubDomain='@';
- return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
- }
-
- //获取解析记录详细信息
- public function getDomainRecordInfo($RecordId){
- $action = 'DescribeRecord';
- $param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId)];
- $data = $this->send_reuqest($action, $param);
- if($data){
- return [
- 'RecordId' => $data['RecordInfo']['Id'],
- 'Domain' => $this->domain,
- 'Name' => $data['RecordInfo']['SubDomain'],
- 'Type' => $this->convertTypeId($data['RecordInfo']['RecordType']),
- 'Value' => $data['RecordInfo']['Value'],
- 'Line' => $data['RecordInfo']['RecordLineId'],
- 'TTL' => $data['RecordInfo']['TTL'],
- 'MX' => $data['RecordInfo']['MX'],
- 'Status' => $data['RecordInfo']['Enabled'] == 1 ? '1' : '0',
- 'Weight' => $data['RecordInfo']['Weight'],
- 'Remark' => $data['RecordInfo']['Remark'],
- 'UpdateTime' => $data['RecordInfo']['UpdatedOn'],
- ];
- }
- return false;
- }
-
- //添加解析记录
- public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $action = 'CreateRecord';
- $param = ['Domain' => $this->domain, 'SubDomain' => $Name, 'RecordType' => $this->convertType($Type), 'Value' => $Value, 'RecordLine'=>$Line, 'RecordLineId' => $this->convertLineCode($Line), 'TTL' => intval($TTL), 'Weight' => $Weight];
- if($Type == 'MX')$param['MX'] = intval($MX);
- $data = $this->send_reuqest($action, $param);
- return is_array($data) ? $data['RecordId'] : false;
- }
-
- //修改解析记录
- public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $action = 'ModifyRecord';
- $param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'SubDomain' => $Name, 'RecordType' => $this->convertType($Type), 'Value' => $Value, 'RecordLine'=>$Line, 'RecordLineId' => $this->convertLineCode($Line), 'TTL' => intval($TTL), 'Weight' => $Weight];
- if($Type == 'MX')$param['MX'] = intval($MX);
- $data = $this->send_reuqest($action, $param);
- return is_array($data);
- }
-
- //修改解析记录备注
- public function updateDomainRecordRemark($RecordId, $Remark){
- $action = 'ModifyRecordRemark';
- $param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'Remark' => $Remark];
- $data = $this->send_reuqest($action, $param);
- return is_array($data);
- }
-
- //删除解析记录
- public function deleteDomainRecord($RecordId){
- $action = 'DeleteRecord';
- $param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId)];
- $data = $this->send_reuqest($action, $param);
- return is_array($data);
- }
-
- //设置解析记录状态
- public function setDomainRecordStatus($RecordId, $Status){
- $Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
- $action = 'ModifyRecordStatus';
- $param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'Status' => $Status];
- $data = $this->send_reuqest($action, $param);
- return is_array($data);
- }
-
- //获取解析记录操作日志
- public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
- $action = 'DescribeDomainLogList';
- $offset = ($PageNumber-1)*$PageSize;
- $param = ['Domain' => $this->domain, 'Offset' => $offset, 'Limit' => $PageSize];
- $data = $this->send_reuqest($action, $param);
- if($data){
- $list = [];
- foreach($data['LogList'] as $row){
- $list[] = ['time'=>substr($row, 0, strpos($row,'(')), 'ip'=>substr($row, strpos($row,'(')+1, strpos($row,')')-strpos($row,'(')-1), 'data'=>substr($row, strpos($row,')')+1, strpos($row,' Uin:')-strpos($row,')')-1)];
- }
- return ['total' => $data['TotalCount'], 'list' => $list];
- }
- return false;
- }
-
- //获取解析线路列表
- public function getRecordLine(){
- $action = 'DescribeRecordLineCategoryList';
- $param = ['Domain' => $this->domain];
- $data = $this->send_reuqest($action, $param);
- if($data){
- $list = [];
- $this->processLineList($list, $data['LineList'], null);
- return $list;
- }else{
- $data = $this->getRecordLineByGrade();
- if($data){
- $list = [];
- foreach($data as $row){
- $list[$row['LineId']] = ['name'=>$row['Name'], 'parent'=>null];
- }
- return $list;
- }
- }
- return false;
- }
-
- private function processLineList(&$list, $line_list, $parent){
- foreach($line_list as $row){
- if(isNullOrEmpty($row['LineId'])) $row['LineId'] = 'N.'.$row['LineName'];
- if($row['Useful'] && !isset($list[$row['LineId']])){
- $list[$row['LineId']] = ['name'=>$row['LineName'], 'parent'=>$parent];
- if($row['SubGroup']){
- $this->processLineList($list, $row['SubGroup'], $row['LineId']);
- }
- }
- }
- }
-
- //获取域名概览信息
- public function getDomainInfo(){
- $action = 'DescribeDomain';
- $param = ['Domain' => $this->domain];
- $data = $this->send_reuqest($action, $param);
- if($data){
- $this->domainInfo = $data['DomainInfo'];
- return $data['DomainInfo'];
- }
- return false;
- }
-
- //获取域名权限
- public function getDomainPurview(){
- $action = 'DescribeDomainPurview';
- $param = ['Domain' => $this->domain];
- $data = $this->send_reuqest($action, $param);
- if($data){
- return $data['PurviewList'];
- }
- return false;
- }
-
- //获取域名最低TTL
- public function getMinTTL(){
- if($this->domainInfo){
- return $this->domainInfo['TTL'];
- }
- $PurviewList = $this->getDomainPurview();
- if($PurviewList){
- foreach($PurviewList as $row){
- if($row['Name'] == '记录 TTL 最低' || $row['Name'] == 'Min TTL value'){
- return intval($row['Value']);
- }
- }
- }
- return false;
- }
-
- //获取等级允许的线路
- public function getRecordLineByGrade(){
- $action = 'DescribeRecordLineList';
- $param = ['Domain' => $this->domain, 'DomainGrade' => ''];
- $data = $this->send_reuqest($action, $param);
- if($data){
- $line_list = $data['LineList'];
- if(!empty($data['LineGroupList'])){
- foreach($data['LineGroupList'] as $row){
- $line_list[] = ['Name' => $row['Name'], 'LineId' => $row['LineId']];
- }
- }
- return $line_list;
- }
- return false;
- }
-
- //获取用户信息
- public function getAccountInfo(){
- $action = 'DescribeUserDetail';
- $param = [];
- $data = $this->send_reuqest($action, $param);
- if($data){
- return $data['UserInfo'];
- }
- return false;
- }
-
- private function convertLineCode($line){
- $convert_dict = ['default'=>'0', 'unicom'=>'10=1', 'telecom'=>'10=0', 'mobile'=>'10=3', 'edu'=>'10=2', 'oversea'=>'3=0', 'btvn'=>'10=22', 'search'=>'80=0', 'internal'=>'7=0'];
- if(array_key_exists($line, $convert_dict)){
- return $convert_dict[$line];
- }
- return $line;
- }
-
- private function convertType($type){
- $convert_dict = ['REDIRECT_URL'=>'显性URL', 'FORWARD_URL'=>'隐性URL'];
- if(array_key_exists($type, $convert_dict)){
- return $convert_dict[$type];
- }
- return $type;
- }
-
- private function convertTypeId($type){
- $convert_dict = ['显性URL'=>'REDIRECT_URL', '隐性URL'=>'FORWARD_URL'];
- if(array_key_exists($type, $convert_dict)){
- return $convert_dict[$type];
- }
- return $type;
- }
-
-
- private function send_reuqest($action, $param){
- $param = array_filter($param, function($a){ return $a!==null;});
- if(!$param) $param = (object)[];
- $payload = json_encode($param);
- $time = time();
- $authorization = $this->generateSign($payload, $time);
- $header = [
- 'Authorization: '.$authorization,
- 'Content-Type: application/json; charset=utf-8',
- 'X-TC-Action: '.$action,
- 'X-TC-Timestamp: '.$time,
- 'X-TC-Version: '.$this->version,
- ];
- return $this->curl_post($payload, $header);
- }
-
- private function generateSign($payload, $time){
- $algorithm = "TC3-HMAC-SHA256";
-
- // step 1: build canonical request string
- $httpRequestMethod = "POST";
- $canonicalUri = "/";
- $canonicalQueryString = "";
- $canonicalHeaders = "content-type:application/json; charset=utf-8\n"."host:".$this->endpoint."\n";
- $signedHeaders = "content-type;host";
- $hashedRequestPayload = hash("SHA256", $payload);
- $canonicalRequest = $httpRequestMethod."\n"
- .$canonicalUri."\n"
- .$canonicalQueryString."\n"
- .$canonicalHeaders."\n"
- .$signedHeaders."\n"
- .$hashedRequestPayload;
-
- // step 2: build string to sign
- $date = gmdate("Y-m-d", $time);
- $credentialScope = $date."/".$this->service."/tc3_request";
- $hashedCanonicalRequest = hash("SHA256", $canonicalRequest);
- $stringToSign = $algorithm."\n"
- .$time."\n"
- .$credentialScope."\n"
- .$hashedCanonicalRequest;
-
- // step 3: sign string
- $secretDate = hash_hmac("SHA256", $date, "TC3".$this->SecretKey, true);
- $secretService = hash_hmac("SHA256", $this->service, $secretDate, true);
- $secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true);
- $signature = hash_hmac("SHA256", $stringToSign, $secretSigning);
-
- // step 4: build authorization
- $authorization = $algorithm
- ." Credential=".$this->SecretId."/".$credentialScope
- .", SignedHeaders=content-type;host, Signature=".$signature;
-
- return $authorization;
- }
-
- private function curl_post($payload, $header){
- $url = 'https://'.$this->endpoint.'/';
- $ch = curl_init($url);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_TIMEOUT, 10);
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
- $response = curl_exec($ch);
- $errno = curl_errno($ch);
- if ($errno) {
- $this->setError('Curl error: ' . curl_error($ch));
- }
- curl_close($ch);
- if ($errno) return false;
-
- $arr=json_decode($response,true);
- if($arr){
- if(isset($arr['Response']['Error'])){
- $this->setError($arr['Response']['Error']['Message']);
- return false;
- }else{
- return $arr['Response'];
- }
- }else{
- $this->setError('返回数据解析失败');
- return false;
- }
- }
-
- private function setError($message){
- $this->error = $message;
- //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
- }
-}
\ No newline at end of file
+SecretId = $config['ak'];
+ $this->SecretKey = $config['sk'];
+ $this->domain = $config['domain'];
+ }
+
+ public function getError()
+ {
+ return $this->error;
+ }
+
+ public function check()
+ {
+ if ($this->getDomainList() != false) {
+ return true;
+ }
+ return false;
+ }
+
+ //获取域名列表
+ public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
+ {
+ $action = 'DescribeDomainList';
+ $offset = ($PageNumber - 1) * $PageSize;
+ $param = ['Offset' => $offset, 'Limit' => $PageSize, 'Keyword' => $KeyWord];
+ $data = $this->send_reuqest($action, $param);
+ if ($data) {
+ $list = [];
+ foreach ($data['DomainList'] as $row) {
+ $list[] = [
+ 'DomainId' => $row['DomainId'],
+ 'Domain' => $row['Name'],
+ 'RecordCount' => $row['RecordCount'],
+ ];
+ }
+ return ['total' => $data['DomainCountInfo']['DomainTotal'], 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取解析记录列表
+ public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
+ {
+ $offset = ($PageNumber - 1) * $PageSize;
+ if (!isNullOrEmpty($Status) || !isNullOrEmpty($Value)) {
+ $action = 'DescribeRecordFilterList';
+ $param = ['Domain' => $this->domain, 'Offset' => $offset, 'Limit' => $PageSize, 'RecordValue' => $Value];
+ if (!isNullOrEmpty($SubDomain)) {
+ $param['SubDomain'] = $SubDomain;
+ }
+ if (!isNullOrEmpty($KeyWord)) {
+ $param['Keyword'] = $KeyWord;
+ }
+ if (!isNullOrEmpty($Value)) {
+ $param['RecordValue'] = $Value;
+ }
+ if (!isNullOrEmpty($Status)) {
+ $Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
+ $param['RecordStatus'] = [$Status];
+ }
+ if (!isNullOrEmpty($Type)) {
+ $param['RecordType'] = [$this->convertType($Type)];
+ }
+ if (!isNullOrEmpty($Line)) {
+ $param['RecordLine'] = [$Line];
+ }
+ } else {
+ $action = 'DescribeRecordList';
+ $param = ['Domain' => $this->domain, 'Subdomain' => $SubDomain, 'RecordType' => $this->convertType($Type), 'RecordLineId' => $Line, 'Keyword' => $KeyWord, 'Offset' => $offset, 'Limit' => $PageSize];
+ }
+ $data = $this->send_reuqest($action, $param);
+ if ($data) {
+ $list = [];
+ foreach ($data['RecordList'] as $row) {
+ //if($row['Name'] == '@' && $row['Type'] == 'NS') continue;
+ $list[] = [
+ 'RecordId' => $row['RecordId'],
+ 'Domain' => $this->domain,
+ 'Name' => $row['Name'],
+ 'Type' => $this->convertTypeId($row['Type']),
+ 'Value' => $row['Value'],
+ 'Line' => $row['LineId'],
+ 'TTL' => $row['TTL'],
+ 'MX' => $row['MX'],
+ 'Status' => $row['Status'] == 'ENABLE' ? '1' : '0',
+ 'Weight' => $row['Weight'],
+ 'Remark' => $row['Remark'],
+ 'UpdateTime' => $row['UpdatedOn'],
+ ];
+ }
+ return ['total' => $data['RecordCountInfo']['TotalCount'], 'list' => $list];
+ } elseif ($this->error == '记录列表为空。' || $this->error == 'No records on the list.') {
+ return ['total' => 0, 'list' => []];
+ }
+ return false;
+ }
+
+ //获取子域名解析记录列表
+ public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
+ {
+ if ($SubDomain == '') {
+ $SubDomain = '@';
+ }
+ return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
+ }
+
+ //获取解析记录详细信息
+ public function getDomainRecordInfo($RecordId)
+ {
+ $action = 'DescribeRecord';
+ $param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId)];
+ $data = $this->send_reuqest($action, $param);
+ if ($data) {
+ return [
+ 'RecordId' => $data['RecordInfo']['Id'],
+ 'Domain' => $this->domain,
+ 'Name' => $data['RecordInfo']['SubDomain'],
+ 'Type' => $this->convertTypeId($data['RecordInfo']['RecordType']),
+ 'Value' => $data['RecordInfo']['Value'],
+ 'Line' => $data['RecordInfo']['RecordLineId'],
+ 'TTL' => $data['RecordInfo']['TTL'],
+ 'MX' => $data['RecordInfo']['MX'],
+ 'Status' => $data['RecordInfo']['Enabled'] == 1 ? '1' : '0',
+ 'Weight' => $data['RecordInfo']['Weight'],
+ 'Remark' => $data['RecordInfo']['Remark'],
+ 'UpdateTime' => $data['RecordInfo']['UpdatedOn'],
+ ];
+ }
+ return false;
+ }
+
+ //添加解析记录
+ public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $action = 'CreateRecord';
+ $param = ['Domain' => $this->domain, 'SubDomain' => $Name, 'RecordType' => $this->convertType($Type), 'Value' => $Value, 'RecordLine' => $Line, 'RecordLineId' => $this->convertLineCode($Line), 'TTL' => intval($TTL), 'Weight' => $Weight];
+ if ($Type == 'MX') {
+ $param['MX'] = intval($MX);
+ }
+ $data = $this->send_reuqest($action, $param);
+ return is_array($data) ? $data['RecordId'] : false;
+ }
+
+ //修改解析记录
+ public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $action = 'ModifyRecord';
+ $param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'SubDomain' => $Name, 'RecordType' => $this->convertType($Type), 'Value' => $Value, 'RecordLine' => $Line, 'RecordLineId' => $this->convertLineCode($Line), 'TTL' => intval($TTL), 'Weight' => $Weight];
+ if ($Type == 'MX') {
+ $param['MX'] = intval($MX);
+ }
+ $data = $this->send_reuqest($action, $param);
+ return is_array($data);
+ }
+
+ //修改解析记录备注
+ public function updateDomainRecordRemark($RecordId, $Remark)
+ {
+ $action = 'ModifyRecordRemark';
+ $param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'Remark' => $Remark];
+ $data = $this->send_reuqest($action, $param);
+ return is_array($data);
+ }
+
+ //删除解析记录
+ public function deleteDomainRecord($RecordId)
+ {
+ $action = 'DeleteRecord';
+ $param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId)];
+ $data = $this->send_reuqest($action, $param);
+ return is_array($data);
+ }
+
+ //设置解析记录状态
+ public function setDomainRecordStatus($RecordId, $Status)
+ {
+ $Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
+ $action = 'ModifyRecordStatus';
+ $param = ['Domain' => $this->domain, 'RecordId' => intval($RecordId), 'Status' => $Status];
+ $data = $this->send_reuqest($action, $param);
+ return is_array($data);
+ }
+
+ //获取解析记录操作日志
+ public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
+ {
+ $action = 'DescribeDomainLogList';
+ $offset = ($PageNumber - 1) * $PageSize;
+ $param = ['Domain' => $this->domain, 'Offset' => $offset, 'Limit' => $PageSize];
+ $data = $this->send_reuqest($action, $param);
+ if ($data) {
+ $list = [];
+ foreach ($data['LogList'] as $row) {
+ $list[] = ['time' => substr($row, 0, strpos($row, '(')), 'ip' => substr($row, strpos($row, '(') + 1, strpos($row, ')') - strpos($row, '(') - 1), 'data' => substr($row, strpos($row, ')') + 1, strpos($row, ' Uin:') - strpos($row, ')') - 1)];
+ }
+ return ['total' => $data['TotalCount'], 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取解析线路列表
+ public function getRecordLine()
+ {
+ $action = 'DescribeRecordLineCategoryList';
+ $param = ['Domain' => $this->domain];
+ $data = $this->send_reuqest($action, $param);
+ if ($data) {
+ $list = [];
+ $this->processLineList($list, $data['LineList'], null);
+ return $list;
+ } else {
+ $data = $this->getRecordLineByGrade();
+ if ($data) {
+ $list = [];
+ foreach ($data as $row) {
+ $list[$row['LineId']] = ['name' => $row['Name'], 'parent' => null];
+ }
+ return $list;
+ }
+ }
+ return false;
+ }
+
+ private function processLineList(&$list, $line_list, $parent)
+ {
+ foreach ($line_list as $row) {
+ if (isNullOrEmpty($row['LineId'])) {
+ $row['LineId'] = 'N.'.$row['LineName'];
+ }
+ if ($row['Useful'] && !isset($list[$row['LineId']])) {
+ $list[$row['LineId']] = ['name' => $row['LineName'], 'parent' => $parent];
+ if ($row['SubGroup']) {
+ $this->processLineList($list, $row['SubGroup'], $row['LineId']);
+ }
+ }
+ }
+ }
+
+ //获取域名概览信息
+ public function getDomainInfo()
+ {
+ $action = 'DescribeDomain';
+ $param = ['Domain' => $this->domain];
+ $data = $this->send_reuqest($action, $param);
+ if ($data) {
+ $this->domainInfo = $data['DomainInfo'];
+ return $data['DomainInfo'];
+ }
+ return false;
+ }
+
+ //获取域名权限
+ public function getDomainPurview()
+ {
+ $action = 'DescribeDomainPurview';
+ $param = ['Domain' => $this->domain];
+ $data = $this->send_reuqest($action, $param);
+ if ($data) {
+ return $data['PurviewList'];
+ }
+ return false;
+ }
+
+ //获取域名最低TTL
+ public function getMinTTL()
+ {
+ if ($this->domainInfo) {
+ return $this->domainInfo['TTL'];
+ }
+ $PurviewList = $this->getDomainPurview();
+ if ($PurviewList) {
+ foreach ($PurviewList as $row) {
+ if ($row['Name'] == '记录 TTL 最低' || $row['Name'] == 'Min TTL value') {
+ return intval($row['Value']);
+ }
+ }
+ }
+ return false;
+ }
+
+ //获取等级允许的线路
+ public function getRecordLineByGrade()
+ {
+ $action = 'DescribeRecordLineList';
+ $param = ['Domain' => $this->domain, 'DomainGrade' => ''];
+ $data = $this->send_reuqest($action, $param);
+ if ($data) {
+ $line_list = $data['LineList'];
+ if (!empty($data['LineGroupList'])) {
+ foreach ($data['LineGroupList'] as $row) {
+ $line_list[] = ['Name' => $row['Name'], 'LineId' => $row['LineId']];
+ }
+ }
+ return $line_list;
+ }
+ return false;
+ }
+
+ //获取用户信息
+ public function getAccountInfo()
+ {
+ $action = 'DescribeUserDetail';
+ $param = [];
+ $data = $this->send_reuqest($action, $param);
+ if ($data) {
+ return $data['UserInfo'];
+ }
+ return false;
+ }
+
+ private function convertLineCode($line)
+ {
+ $convert_dict = ['default' => '0', 'unicom' => '10=1', 'telecom' => '10=0', 'mobile' => '10=3', 'edu' => '10=2', 'oversea' => '3=0', 'btvn' => '10=22', 'search' => '80=0', 'internal' => '7=0'];
+ if (array_key_exists($line, $convert_dict)) {
+ return $convert_dict[$line];
+ }
+ return $line;
+ }
+
+ private function convertType($type)
+ {
+ $convert_dict = ['REDIRECT_URL' => '显性URL', 'FORWARD_URL' => '隐性URL'];
+ if (array_key_exists($type, $convert_dict)) {
+ return $convert_dict[$type];
+ }
+ return $type;
+ }
+
+ private function convertTypeId($type)
+ {
+ $convert_dict = ['显性URL' => 'REDIRECT_URL', '隐性URL' => 'FORWARD_URL'];
+ if (array_key_exists($type, $convert_dict)) {
+ return $convert_dict[$type];
+ }
+ return $type;
+ }
+
+
+ private function send_reuqest($action, $param)
+ {
+ $param = array_filter($param, function ($a) { return $a !== null;});
+ if (!$param) {
+ $param = (object)[];
+ }
+ $payload = json_encode($param);
+ $time = time();
+ $authorization = $this->generateSign($payload, $time);
+ $header = [
+ 'Authorization: '.$authorization,
+ 'Content-Type: application/json; charset=utf-8',
+ 'X-TC-Action: '.$action,
+ 'X-TC-Timestamp: '.$time,
+ 'X-TC-Version: '.$this->version,
+ ];
+ return $this->curl_post($payload, $header);
+ }
+
+ private function generateSign($payload, $time)
+ {
+ $algorithm = "TC3-HMAC-SHA256";
+
+ // step 1: build canonical request string
+ $httpRequestMethod = "POST";
+ $canonicalUri = "/";
+ $canonicalQueryString = "";
+ $canonicalHeaders = "content-type:application/json; charset=utf-8\n"."host:".$this->endpoint."\n";
+ $signedHeaders = "content-type;host";
+ $hashedRequestPayload = hash("SHA256", $payload);
+ $canonicalRequest = $httpRequestMethod."\n"
+ .$canonicalUri."\n"
+ .$canonicalQueryString."\n"
+ .$canonicalHeaders."\n"
+ .$signedHeaders."\n"
+ .$hashedRequestPayload;
+
+ // step 2: build string to sign
+ $date = gmdate("Y-m-d", $time);
+ $credentialScope = $date."/".$this->service."/tc3_request";
+ $hashedCanonicalRequest = hash("SHA256", $canonicalRequest);
+ $stringToSign = $algorithm."\n"
+ .$time."\n"
+ .$credentialScope."\n"
+ .$hashedCanonicalRequest;
+
+ // step 3: sign string
+ $secretDate = hash_hmac("SHA256", $date, "TC3".$this->SecretKey, true);
+ $secretService = hash_hmac("SHA256", $this->service, $secretDate, true);
+ $secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true);
+ $signature = hash_hmac("SHA256", $stringToSign, $secretSigning);
+
+ // step 4: build authorization
+ $authorization = $algorithm
+ ." Credential=".$this->SecretId."/".$credentialScope
+ .", SignedHeaders=content-type;host, Signature=".$signature;
+
+ return $authorization;
+ }
+
+ private function curl_post($payload, $header)
+ {
+ $url = 'https://'.$this->endpoint.'/';
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
+ $response = curl_exec($ch);
+ $errno = curl_errno($ch);
+ if ($errno) {
+ $this->setError('Curl error: ' . curl_error($ch));
+ }
+ curl_close($ch);
+ if ($errno) {
+ return false;
+ }
+
+ $arr = json_decode($response, true);
+ if ($arr) {
+ if (isset($arr['Response']['Error'])) {
+ $this->setError($arr['Response']['Error']['Message']);
+ return false;
+ } else {
+ return $arr['Response'];
+ }
+ } else {
+ $this->setError('返回数据解析失败');
+ return false;
+ }
+ }
+
+ private function setError($message)
+ {
+ $this->error = $message;
+ //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
+ }
+}
diff --git a/app/lib/dns/huawei.php b/app/lib/dns/huawei.php
index c17d770..06b2c80 100644
--- a/app/lib/dns/huawei.php
+++ b/app/lib/dns/huawei.php
@@ -1,360 +1,415 @@
-AccessKeyId = $config['ak'];
- $this->SecretAccessKey = $config['sk'];
- $this->domain = $config['domain'];
- $this->domainid = $config['domainid'];
- }
-
- public function getError(){
- return $this->error;
- }
-
- public function check(){
- if($this->getDomainList() != false){
- return true;
- }
- return false;
- }
-
- //获取域名列表
- public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
- $offset = ($PageNumber-1)*$PageSize;
- $query = ['offset' => $offset, 'limit' => $PageSize, 'name' => $KeyWord];
- $data = $this->send_reuqest('GET', '/v2/zones', $query);
- if($data){
- $list = [];
- foreach($data['zones'] as $row){
- $list[] = [
- 'DomainId' => $row['id'],
- 'Domain' => rtrim($row['name'], '.'),
- 'RecordCount' => $row['record_num'],
- ];
- }
- return ['total' => $data['metadata']['total_count'], 'list' => $list];
- }
- return false;
- }
-
- //获取解析记录列表
- public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null){
- $offset = ($PageNumber-1)*$PageSize;
- $query = ['type' => $Type, 'line_id' => $Line, 'name' => $KeyWord, 'offset' => $offset, 'limit' => $PageSize];
- if(!isNullOrEmpty($Status)){
- $Status = $Status == '1' ? 'ACTIVE' : 'DISABLE';
- $query['status'] = $Status;
- }
- if(!isNullOrEmpty($SubDomain)){
- $SubDomain = $this->getHost($SubDomain);
- $query['name'] = $SubDomain;
- $query['search_mode'] = 'equal';
- }
- $data = $this->send_reuqest('GET', '/v2.1/zones/'.$this->domainid.'/recordsets', $query);
- if($data){
- $list = [];
- foreach($data['recordsets'] as $row){
- if($row['name'] == $row['zone_name']) $row['name'] = '@';
- if($row['type'] == 'MX') list($row['mx'], $row['records']) = explode(' ', $row['records'][0]);
- $list[] = [
- 'RecordId' => $row['id'],
- 'Domain' => rtrim($row['zone_name'], '.'),
- 'Name' => str_replace('.'.$row['zone_name'], '', $row['name']),
- 'Type' => $row['type'],
- 'Value' => $row['records'],
- 'Line' => $row['line'],
- 'TTL' => $row['ttl'],
- 'MX' => isset($row['mx']) ? $row['mx'] : null,
- 'Status' => $row['status'] == 'ACTIVE' ? '1' : '0',
- 'Weight' => $row['weight'],
- 'Remark' => $row['description'],
- 'UpdateTime' => $row['updated_at'],
- ];
- }
- return ['total' => $data['metadata']['total_count'], 'list' => $list];
- }
- return false;
- }
-
- //获取子域名解析记录列表
- public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
- return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
- }
-
- //获取解析记录详细信息
- public function getDomainRecordInfo($RecordId){
- $data = $this->send_reuqest('GET', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId);
- if($data){
- if($data['name'] == $data['zone_name']) $data['name'] = '@';
- if($data['type'] == 'MX') list($data['mx'], $data['records']) = explode(' ', $data['records'][0]);
- return [
- 'RecordId' => $data['id'],
- 'Domain' => rtrim($data['zone_name'], '.'),
- 'Name' => str_replace('.'.$data['zone_name'], '', $data['name']),
- 'Type' => $data['type'],
- 'Value' => $data['records'],
- 'Line' => $data['line'],
- 'TTL' => $data['ttl'],
- 'MX' => isset($data['mx']) ? $data['mx'] : null,
- 'Status' => $data['status'] == 'ACTIVE' ? '1' : '0',
- 'Weight' => $data['weight'],
- 'Remark' => $data['description'],
- 'UpdateTime' => $data['updated_at'],
- ];
- }
- return false;
- }
-
- //添加解析记录
- public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $Name = $this->getHost($Name);
- if($Type == 'TXT' && substr($Value, 0, 1) != '"') $Value = '"'.$Value.'"';
- $records = explode(',', $Value);
- $params = ['name' => $Name, 'type' => $this->convertType($Type), 'records' => $records, 'line'=>$Line, 'ttl' => intval($TTL), 'description' => $Remark];
- if($Type == 'MX') $params['records'][0] = intval($MX) . ' ' . $Value;
- if($Weight > 0) $params['weight'] = intval($Weight);
- $data = $this->send_reuqest('POST', '/v2.1/zones/'.$this->domainid.'/recordsets', null, $params);
- return is_array($data) ? $data['id'] : false;
- }
-
- //修改解析记录
- public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $Name = $this->getHost($Name);
- if($Type == 'TXT' && substr($Value, 0, 1) != '"') $Value = '"'.$Value.'"';
- $records = explode(',', $Value);
- $params = ['name' => $Name, 'type' => $this->convertType($Type), 'records' => $records, 'line'=>$Line, 'ttl' => intval($TTL), 'description' => $Remark];
- if($Type == 'MX') $params['records'][0] = intval($MX) . ' ' . $Value;
- if($Weight > 0) $params['weight'] = intval($Weight);
- $data = $this->send_reuqest('PUT', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId, null, $params);
- return is_array($data);
- }
-
- //修改解析记录备注
- public function updateDomainRecordRemark($RecordId, $Remark){
- return false;
- }
-
- //删除解析记录
- public function deleteDomainRecord($RecordId){
- $data = $this->send_reuqest('DELETE', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId);
- return is_array($data);
- }
-
- //设置解析记录状态
- public function setDomainRecordStatus($RecordId, $Status){
- $Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
- $params = ['status' => $Status];
- $data = $this->send_reuqest('PUT', '/v2.1/recordsets/'.$RecordId.'/statuses/set', null, $params);
- return is_array($data);
- }
-
- //获取解析记录操作日志
- public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
- return false;
- }
-
- //获取解析线路列表
- public function getRecordLine(){
- $file_path = app()->getBasePath().'data'.DIRECTORY_SEPARATOR.'huawei_line.json';
- $content = file_get_contents($file_path);
- $data = json_decode($content, true);
- if($data){
- return $data;
- $list = [$data['DEFAULT']['id'] => ['name'=>$data['DEFAULT']['zh'], 'parent'=>null]];
- $this->processLineList($list, $data['ISP'], null, 1, 1);
- $this->processLineList($list, $data['REGION'], null, null, 1);
- //file_put_contents($file_path, json_encode($list, JSON_UNESCAPED_UNICODE));
- return $list;
- }
- return false;
- }
-
- private function processLineList(&$list, $line_list, $parent, $rootId = null, $rootName = null){
- foreach($line_list as $row){
- if($rootId && $rootId!==1){
- $row['id'] = $rootId.'_'.$row['id'];
- }
- if($rootName && $rootName!==1){
- $row['zh'] = $rootName.'_'.$row['zh'];
- }
- $list[$row['id']] = ['name'=>$row['zh'], 'parent'=>$parent];
- if(isset($row['children']) && !empty($row['children'])){
- $this->processLineList($list, $row['children'], $row['id'], $rootId === 1 ? $row['id'] : $rootId, $rootName === 1 ? $row['zh'] : $rootName);
- }
- }
- }
-
- //获取域名概览信息
- public function getDomainInfo(){
- return $this->send_reuqest('GET', '/v2/zones/'.$this->domainid);
- }
-
- //获取域名最低TTL
- public function getMinTTL(){
- return false;
- }
-
- private function convertType($type){
- return $type;
- }
-
- private function getHost($Name){
- if($Name == '@') $Name = '';
- else $Name .= '.';
- $Name .= $this->domain . '.';
- return $Name;
- }
-
- private function send_reuqest($method, $path, $query = null, $params = null){
- if(!empty($query)){
- $query = array_filter($query, function($a){ return $a!==null;});
- }
- if(!empty($params)){
- $params = array_filter($params, function($a){ return $a!==null;});
- }
-
- $time = time();
- $date = gmdate("Ymd\THis\Z", $time);
- $body = !empty($params) ? json_encode($params) : '';
- $headers = [
- 'Host' => $this->endpoint,
- 'X-Sdk-Date' => $date,
- ];
- if($body){
- $headers['Content-Type'] = 'application/json';
- }
-
- $authorization = $this->generateSign($method, $path, $query, $headers, $body, $time);
- $headers['Authorization'] = $authorization;
-
- $url = 'https://'.$this->endpoint.$path;
- if(!empty($query)){
- $url .= '?'.http_build_query($query);
- }
- $header = [];
- foreach($headers as $key => $value){
- $header[] = $key.': '.$value;
- }
- return $this->curl($method, $url, $body, $header);
- }
-
- private function generateSign($method, $path, $query, $headers, $body, $time){
- $algorithm = "SDK-HMAC-SHA256";
-
- // step 1: build canonical request string
- $httpRequestMethod = $method;
- $canonicalUri = $path;
- if(substr($canonicalUri, -1) != "/") $canonicalUri .= "/";
- $canonicalQueryString = $this->getCanonicalQueryString($query);
- [$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
- $hashedRequestPayload = hash("sha256", $body);
- $canonicalRequest = $httpRequestMethod."\n"
- .$canonicalUri."\n"
- .$canonicalQueryString."\n"
- .$canonicalHeaders."\n"
- .$signedHeaders."\n"
- .$hashedRequestPayload;
-
- // step 2: build string to sign
- $date = gmdate("Ymd\THis\Z", $time);
- $hashedCanonicalRequest = hash("sha256", $canonicalRequest);
- $stringToSign = $algorithm."\n"
- .$date."\n"
- .$hashedCanonicalRequest;
-
- // step 3: sign string
- $signature = hash_hmac("sha256", $stringToSign, $this->SecretAccessKey);
-
- // step 4: build authorization
- $authorization = $algorithm . ' Access=' . $this->AccessKeyId . ", SignedHeaders=" . $signedHeaders . ", Signature=" . $signature;
-
- return $authorization;
- }
-
- private function escape($str)
- {
- $search = ['+', '*', '%7E'];
- $replace = ['%20', '%2A', '~'];
- return str_replace($search, $replace, urlencode($str));
- }
-
- private function getCanonicalQueryString($parameters)
- {
- if(empty($parameters)) return '';
- ksort($parameters);
- $canonicalQueryString = '';
- foreach ($parameters as $key => $value) {
- $canonicalQueryString .= '&' . $this->escape($key). '=' . $this->escape($value);
- }
- return substr($canonicalQueryString, 1);
- }
-
- private function getCanonicalHeaders($oldheaders){
- $headers = array();
- foreach ($oldheaders as $key => $value) {
- $headers[strtolower($key)] = trim($value);
- }
- ksort($headers);
-
- $canonicalHeaders = '';
- $signedHeaders = '';
- foreach ($headers as $key => $value) {
- $canonicalHeaders .= $key . ':' . $value . "\n";
- $signedHeaders .= $key . ';';
- }
- $signedHeaders = substr($signedHeaders, 0, -1);
- return [$canonicalHeaders, $signedHeaders];
- }
-
- private function curl($method, $url, $body, $header){
- $ch = curl_init($url);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_TIMEOUT, 10);
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
- if(!empty($body)){
- curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
- }
- $response = curl_exec($ch);
- $errno = curl_errno($ch);
- if ($errno) {
- $this->setError('Curl error: ' . curl_error($ch));
- }
- curl_close($ch);
- if ($errno) return false;
-
- $arr=json_decode($response,true);
- if($arr){
- if(isset($arr['error_msg'])){
- $this->setError($arr['error_msg']);
- return false;
- }elseif(isset($arr['message'])){
- $this->setError($arr['message']);
- return false;
- }else{
- return $arr;
- }
- }else{
- $this->setError('返回数据解析失败');
- return false;
- }
- }
-
- private function setError($message){
- $this->error = $message;
- //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
- }
-}
\ No newline at end of file
+AccessKeyId = $config['ak'];
+ $this->SecretAccessKey = $config['sk'];
+ $this->domain = $config['domain'];
+ $this->domainid = $config['domainid'];
+ }
+
+ public function getError()
+ {
+ return $this->error;
+ }
+
+ public function check()
+ {
+ if ($this->getDomainList() != false) {
+ return true;
+ }
+ return false;
+ }
+
+ //获取域名列表
+ public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
+ {
+ $offset = ($PageNumber - 1) * $PageSize;
+ $query = ['offset' => $offset, 'limit' => $PageSize, 'name' => $KeyWord];
+ $data = $this->send_reuqest('GET', '/v2/zones', $query);
+ if ($data) {
+ $list = [];
+ foreach ($data['zones'] as $row) {
+ $list[] = [
+ 'DomainId' => $row['id'],
+ 'Domain' => rtrim($row['name'], '.'),
+ 'RecordCount' => $row['record_num'],
+ ];
+ }
+ return ['total' => $data['metadata']['total_count'], 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取解析记录列表
+ public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
+ {
+ $offset = ($PageNumber - 1) * $PageSize;
+ $query = ['type' => $Type, 'line_id' => $Line, 'name' => $KeyWord, 'offset' => $offset, 'limit' => $PageSize];
+ if (!isNullOrEmpty($Status)) {
+ $Status = $Status == '1' ? 'ACTIVE' : 'DISABLE';
+ $query['status'] = $Status;
+ }
+ if (!isNullOrEmpty($SubDomain)) {
+ $SubDomain = $this->getHost($SubDomain);
+ $query['name'] = $SubDomain;
+ $query['search_mode'] = 'equal';
+ }
+ $data = $this->send_reuqest('GET', '/v2.1/zones/'.$this->domainid.'/recordsets', $query);
+ if ($data) {
+ $list = [];
+ foreach ($data['recordsets'] as $row) {
+ if ($row['name'] == $row['zone_name']) {
+ $row['name'] = '@';
+ }
+ if ($row['type'] == 'MX') {
+ list($row['mx'], $row['records']) = explode(' ', $row['records'][0]);
+ }
+ $list[] = [
+ 'RecordId' => $row['id'],
+ 'Domain' => rtrim($row['zone_name'], '.'),
+ 'Name' => str_replace('.'.$row['zone_name'], '', $row['name']),
+ 'Type' => $row['type'],
+ 'Value' => $row['records'],
+ 'Line' => $row['line'],
+ 'TTL' => $row['ttl'],
+ 'MX' => isset($row['mx']) ? $row['mx'] : null,
+ 'Status' => $row['status'] == 'ACTIVE' ? '1' : '0',
+ 'Weight' => $row['weight'],
+ 'Remark' => $row['description'],
+ 'UpdateTime' => $row['updated_at'],
+ ];
+ }
+ return ['total' => $data['metadata']['total_count'], 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取子域名解析记录列表
+ public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
+ {
+ return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
+ }
+
+ //获取解析记录详细信息
+ public function getDomainRecordInfo($RecordId)
+ {
+ $data = $this->send_reuqest('GET', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId);
+ if ($data) {
+ if ($data['name'] == $data['zone_name']) {
+ $data['name'] = '@';
+ }
+ if ($data['type'] == 'MX') {
+ list($data['mx'], $data['records']) = explode(' ', $data['records'][0]);
+ }
+ return [
+ 'RecordId' => $data['id'],
+ 'Domain' => rtrim($data['zone_name'], '.'),
+ 'Name' => str_replace('.'.$data['zone_name'], '', $data['name']),
+ 'Type' => $data['type'],
+ 'Value' => $data['records'],
+ 'Line' => $data['line'],
+ 'TTL' => $data['ttl'],
+ 'MX' => isset($data['mx']) ? $data['mx'] : null,
+ 'Status' => $data['status'] == 'ACTIVE' ? '1' : '0',
+ 'Weight' => $data['weight'],
+ 'Remark' => $data['description'],
+ 'UpdateTime' => $data['updated_at'],
+ ];
+ }
+ return false;
+ }
+
+ //添加解析记录
+ public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $Name = $this->getHost($Name);
+ if ($Type == 'TXT' && substr($Value, 0, 1) != '"') {
+ $Value = '"'.$Value.'"';
+ }
+ $records = explode(',', $Value);
+ $params = ['name' => $Name, 'type' => $this->convertType($Type), 'records' => $records, 'line' => $Line, 'ttl' => intval($TTL), 'description' => $Remark];
+ if ($Type == 'MX') {
+ $params['records'][0] = intval($MX) . ' ' . $Value;
+ }
+ if ($Weight > 0) {
+ $params['weight'] = intval($Weight);
+ }
+ $data = $this->send_reuqest('POST', '/v2.1/zones/'.$this->domainid.'/recordsets', null, $params);
+ return is_array($data) ? $data['id'] : false;
+ }
+
+ //修改解析记录
+ public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $Name = $this->getHost($Name);
+ if ($Type == 'TXT' && substr($Value, 0, 1) != '"') {
+ $Value = '"'.$Value.'"';
+ }
+ $records = explode(',', $Value);
+ $params = ['name' => $Name, 'type' => $this->convertType($Type), 'records' => $records, 'line' => $Line, 'ttl' => intval($TTL), 'description' => $Remark];
+ if ($Type == 'MX') {
+ $params['records'][0] = intval($MX) . ' ' . $Value;
+ }
+ if ($Weight > 0) {
+ $params['weight'] = intval($Weight);
+ }
+ $data = $this->send_reuqest('PUT', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId, null, $params);
+ return is_array($data);
+ }
+
+ //修改解析记录备注
+ public function updateDomainRecordRemark($RecordId, $Remark)
+ {
+ return false;
+ }
+
+ //删除解析记录
+ public function deleteDomainRecord($RecordId)
+ {
+ $data = $this->send_reuqest('DELETE', '/v2.1/zones/'.$this->domainid.'/recordsets/'.$RecordId);
+ return is_array($data);
+ }
+
+ //设置解析记录状态
+ public function setDomainRecordStatus($RecordId, $Status)
+ {
+ $Status = $Status == '1' ? 'ENABLE' : 'DISABLE';
+ $params = ['status' => $Status];
+ $data = $this->send_reuqest('PUT', '/v2.1/recordsets/'.$RecordId.'/statuses/set', null, $params);
+ return is_array($data);
+ }
+
+ //获取解析记录操作日志
+ public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
+ {
+ return false;
+ }
+
+ //获取解析线路列表
+ public function getRecordLine()
+ {
+ $file_path = app()->getBasePath().'data'.DIRECTORY_SEPARATOR.'huawei_line.json';
+ $content = file_get_contents($file_path);
+ $data = json_decode($content, true);
+ if ($data) {
+ return $data;
+ $list = [$data['DEFAULT']['id'] => ['name' => $data['DEFAULT']['zh'], 'parent' => null]];
+ $this->processLineList($list, $data['ISP'], null, 1, 1);
+ $this->processLineList($list, $data['REGION'], null, null, 1);
+ //file_put_contents($file_path, json_encode($list, JSON_UNESCAPED_UNICODE));
+ return $list;
+ }
+ return false;
+ }
+
+ private function processLineList(&$list, $line_list, $parent, $rootId = null, $rootName = null)
+ {
+ foreach ($line_list as $row) {
+ if ($rootId && $rootId !== 1) {
+ $row['id'] = $rootId.'_'.$row['id'];
+ }
+ if ($rootName && $rootName !== 1) {
+ $row['zh'] = $rootName.'_'.$row['zh'];
+ }
+ $list[$row['id']] = ['name' => $row['zh'], 'parent' => $parent];
+ if (isset($row['children']) && !empty($row['children'])) {
+ $this->processLineList($list, $row['children'], $row['id'], $rootId === 1 ? $row['id'] : $rootId, $rootName === 1 ? $row['zh'] : $rootName);
+ }
+ }
+ }
+
+ //获取域名概览信息
+ public function getDomainInfo()
+ {
+ return $this->send_reuqest('GET', '/v2/zones/'.$this->domainid);
+ }
+
+ //获取域名最低TTL
+ public function getMinTTL()
+ {
+ return false;
+ }
+
+ private function convertType($type)
+ {
+ return $type;
+ }
+
+ private function getHost($Name)
+ {
+ if ($Name == '@') {
+ $Name = '';
+ } else {
+ $Name .= '.';
+ }
+ $Name .= $this->domain . '.';
+ return $Name;
+ }
+
+ private function send_reuqest($method, $path, $query = null, $params = null)
+ {
+ if (!empty($query)) {
+ $query = array_filter($query, function ($a) { return $a !== null;});
+ }
+ if (!empty($params)) {
+ $params = array_filter($params, function ($a) { return $a !== null;});
+ }
+
+ $time = time();
+ $date = gmdate("Ymd\THis\Z", $time);
+ $body = !empty($params) ? json_encode($params) : '';
+ $headers = [
+ 'Host' => $this->endpoint,
+ 'X-Sdk-Date' => $date,
+ ];
+ if ($body) {
+ $headers['Content-Type'] = 'application/json';
+ }
+
+ $authorization = $this->generateSign($method, $path, $query, $headers, $body, $time);
+ $headers['Authorization'] = $authorization;
+
+ $url = 'https://'.$this->endpoint.$path;
+ if (!empty($query)) {
+ $url .= '?'.http_build_query($query);
+ }
+ $header = [];
+ foreach ($headers as $key => $value) {
+ $header[] = $key.': '.$value;
+ }
+ return $this->curl($method, $url, $body, $header);
+ }
+
+ private function generateSign($method, $path, $query, $headers, $body, $time)
+ {
+ $algorithm = "SDK-HMAC-SHA256";
+
+ // step 1: build canonical request string
+ $httpRequestMethod = $method;
+ $canonicalUri = $path;
+ if (substr($canonicalUri, -1) != "/") {
+ $canonicalUri .= "/";
+ }
+ $canonicalQueryString = $this->getCanonicalQueryString($query);
+ [$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
+ $hashedRequestPayload = hash("sha256", $body);
+ $canonicalRequest = $httpRequestMethod."\n"
+ .$canonicalUri."\n"
+ .$canonicalQueryString."\n"
+ .$canonicalHeaders."\n"
+ .$signedHeaders."\n"
+ .$hashedRequestPayload;
+
+ // step 2: build string to sign
+ $date = gmdate("Ymd\THis\Z", $time);
+ $hashedCanonicalRequest = hash("sha256", $canonicalRequest);
+ $stringToSign = $algorithm."\n"
+ .$date."\n"
+ .$hashedCanonicalRequest;
+
+ // step 3: sign string
+ $signature = hash_hmac("sha256", $stringToSign, $this->SecretAccessKey);
+
+ // step 4: build authorization
+ $authorization = $algorithm . ' Access=' . $this->AccessKeyId . ", SignedHeaders=" . $signedHeaders . ", Signature=" . $signature;
+
+ return $authorization;
+ }
+
+ private function escape($str)
+ {
+ $search = ['+', '*', '%7E'];
+ $replace = ['%20', '%2A', '~'];
+ return str_replace($search, $replace, urlencode($str));
+ }
+
+ private function getCanonicalQueryString($parameters)
+ {
+ if (empty($parameters)) {
+ return '';
+ }
+ ksort($parameters);
+ $canonicalQueryString = '';
+ foreach ($parameters as $key => $value) {
+ $canonicalQueryString .= '&' . $this->escape($key). '=' . $this->escape($value);
+ }
+ return substr($canonicalQueryString, 1);
+ }
+
+ private function getCanonicalHeaders($oldheaders)
+ {
+ $headers = array();
+ foreach ($oldheaders as $key => $value) {
+ $headers[strtolower($key)] = trim($value);
+ }
+ ksort($headers);
+
+ $canonicalHeaders = '';
+ $signedHeaders = '';
+ foreach ($headers as $key => $value) {
+ $canonicalHeaders .= $key . ':' . $value . "\n";
+ $signedHeaders .= $key . ';';
+ }
+ $signedHeaders = substr($signedHeaders, 0, -1);
+ return [$canonicalHeaders, $signedHeaders];
+ }
+
+ private function curl($method, $url, $body, $header)
+ {
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ if (!empty($body)) {
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
+ }
+ $response = curl_exec($ch);
+ $errno = curl_errno($ch);
+ if ($errno) {
+ $this->setError('Curl error: ' . curl_error($ch));
+ }
+ curl_close($ch);
+ if ($errno) {
+ return false;
+ }
+
+ $arr = json_decode($response, true);
+ if ($arr) {
+ if (isset($arr['error_msg'])) {
+ $this->setError($arr['error_msg']);
+ return false;
+ } elseif (isset($arr['message'])) {
+ $this->setError($arr['message']);
+ return false;
+ } else {
+ return $arr;
+ }
+ } else {
+ $this->setError('返回数据解析失败');
+ return false;
+ }
+ }
+
+ private function setError($message)
+ {
+ $this->error = $message;
+ //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
+ }
+}
diff --git a/app/lib/dns/huoshan.php b/app/lib/dns/huoshan.php
index 4f594fa..d7011d6 100644
--- a/app/lib/dns/huoshan.php
+++ b/app/lib/dns/huoshan.php
@@ -1,387 +1,440 @@
- ['level' => 1, 'name' => '免费版', 'ttl' => 600],
- 'professional_inner' => ['level' => 2, 'name' => '专业版', 'ttl' => 300],
- 'enterprise_inner' => ['level' => 3, 'name' => '企业版', 'ttl' => 60],
- 'ultimate_inner' => ['level' => 4, 'name' => '旗舰版', 'ttl' => 1],
- 'ultimate_exclusive_inner' => ['level' => 5, 'name' => '尊享版', 'ttl' => 1],
- ];
-
- function __construct($config){
- $this->AccessKeyId = $config['ak'];
- $this->SecretAccessKey = $config['sk'];
- $this->domain = $config['domain'];
- $this->domainid = $config['domainid'];
- }
-
- public function getError(){
- return $this->error;
- }
-
- public function check(){
- if($this->getDomainList() != false){
- return true;
- }
- return false;
- }
-
- //获取域名列表
- public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
- $query = ['PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'Key' => $KeyWord];
- $data = $this->send_reuqest('GET', 'ListZones', $query);
- if($data){
- $list = [];
- if(!empty($data['Zones'])){
- foreach($data['Zones'] as $row){
- $list[] = [
- 'DomainId' => $row['ZID'],
- 'Domain' => $row['ZoneName'],
- 'RecordCount' => $row['RecordCount'],
- ];
- }
- }
- return ['total' => $data['Total'], 'list' => $list];
- }
- return false;
- }
-
- //获取解析记录列表
- public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null){
- $query = ['ZID' => intval($this->domainid), 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'SearchOrder' => 'desc'];
- if(!empty($SubDomain) || !empty($Type) || !empty($Line) || !empty($Value)){
- $query += ['Host' => $SubDomain, 'Value' => $Value, 'Type' => $Type, 'Line' => $Line];
- }elseif(!empty($KeyWord)){
- $query += ['Host' => $KeyWord];
- }
- $data = $this->send_reuqest('GET', 'ListRecords', $query);
- if($data){
- $list = [];
- foreach($data['Records'] as $row){
- if($row['Type'] == 'MX') list($row['MX'], $row['Value']) = explode(' ', $row['Value']);
- $list[] = [
- 'RecordId' => $row['RecordID'],
- 'Domain' => $this->domain,
- 'Name' => $row['Host'],
- 'Type' => $row['Type'],
- 'Value' => $row['Value'],
- 'Line' => $row['Line'],
- 'TTL' => $row['TTL'],
- 'MX' => isset($row['MX']) ? $row['MX'] : null,
- 'Status' => $row['Enable'] ? '1' : '0',
- 'Weight' => $row['Weight'],
- 'Remark' => $row['Remark'],
- 'UpdateTime' => $row['UpdatedAt'],
- ];
- }
- return ['total' => $data['TotalCount'], 'list' => $list];
- }
- return false;
- }
-
- //获取子域名解析记录列表
- public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
- return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
- }
-
- //获取解析记录详细信息
- public function getDomainRecordInfo($RecordId){
- $data = $this->send_reuqest('GET', 'QueryRecord', ['RecordID' => $RecordId]);
- if($data){
- if($data['name'] == $data['zone_name']) $data['name'] = '@';
- if($data['Type'] == 'MX') list($data['MX'], $data['Value']) = explode(' ', $data['Value']);
- return [
- 'RecordId' => $data['RecordID'],
- 'Domain' => $this->domain,
- 'Name' => $data['Host'],
- 'Type' => $data['Type'],
- 'Value' => $data['Value'],
- 'Line' => $data['Line'],
- 'TTL' => $data['TTL'],
- 'MX' => isset($data['MX']) ? $data['MX'] : null,
- 'Status' => $data['Enable'] ? '1' : '0',
- 'Weight' => $data['Weight'],
- 'Remark' => $data['Remark'],
- 'UpdateTime' => $data['UpdatedAt'],
- ];
- }
- return false;
- }
-
- //添加解析记录
- public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $params = ['ZID' => intval($this->domainid), 'Host' => $Name, 'Type' => $this->convertType($Type), 'Value' => $Value, 'Line'=>$Line, 'TTL' => intval($TTL), 'Remark' => $Remark];
- if($Type == 'MX') $params['Value'] = intval($MX) . ' ' . $Value;
- if($Weight > 0) $params['Weight'] = $Weight;
- $data = $this->send_reuqest('POST', 'CreateRecord', $params);
- return is_array($data) ? $data['RecordID'] : false;
- }
-
- //修改解析记录
- public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $params = ['RecordID' => $RecordId, 'Host' => $Name, 'Type' => $this->convertType($Type), 'Value' => $Value, 'Line'=>$Line, 'TTL' => intval($TTL), 'Remark' => $Remark];
- if($Type == 'MX') $params['Value'] = intval($MX) . ' ' . $Value;
- if($Weight > 0) $params['Weight'] = $Weight;
- $data = $this->send_reuqest('POST', 'UpdateRecord', $params);
- return is_array($data);
- }
-
- //修改解析记录备注
- public function updateDomainRecordRemark($RecordId, $Remark){
- return false;
- }
-
- //删除解析记录
- public function deleteDomainRecord($RecordId){
- $data = $this->send_reuqest('POST', 'DeleteRecord', ['RecordID' => $RecordId]);
- return $data;
- }
-
- //设置解析记录状态
- public function setDomainRecordStatus($RecordId, $Status){
- $params = ['RecordID' => $RecordId, 'Enable' => $Status == '1'];
- $data = $this->send_reuqest('POST', 'UpdateRecordStatus', $params);
- return is_array($data);
- }
-
- //获取解析记录操作日志
- public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
- return false;
- }
-
- //获取解析线路列表
- public function getRecordLine(){
- $domainInfo = $this->getDomainInfo();
- if(!$domainInfo) return false;
- $level = $this->getTradeInfo($domainInfo['TradeCode'])['level'];
- $data = $this->send_reuqest('GET', 'ListLines', []);
- if($data){
- $list = [];
- $list['default'] = ['name' => '默认', 'parent' => null];
- foreach($data['Lines'] as $row){
- if($row['Value'] == 'default') continue;
- if($row['Level'] > $level) continue;
- $list[$row['Value']] = ['name' => $row['Name'], 'parent' => isset($row['FatherValue']) ? $row['FatherValue'] : null];
- }
-
- $data = $this->send_reuqest('GET', 'ListCustomLines', []);
- if($data && $data['TotalCount'] > 0){
- $list['N.customer_lines'] = ['name' => '自定义线路', 'parent' => null];
- foreach($data['CustomerLines'] as $row){
- $list[$row['Line']] = ['name' => $row['NameCN'], 'parent' => 'N.customer_lines'];
- }
- }
-
- return $list;
- }
- return false;
- }
-
- //获取域名概览信息
- public function getDomainInfo(){
- if(!empty($this->domainInfo)) return $this->domainInfo;
- $query = ['ZID' => intval($this->domainid)];
- $data = $this->send_reuqest('GET', 'QueryZone', $query);
- if($data){
- $this->domainInfo = $data;
- return $data;
- }
- return false;
- }
-
- //获取域名最低TTL
- public function getMinTTL(){
- $domainInfo = $this->getDomainInfo();
- if($domainInfo){
- $ttl = $this->getTradeInfo($domainInfo['TradeCode'])['ttl'];
- return $ttl;
- }
- return false;
- }
-
- private function convertType($type){
- return $type;
- }
-
- private function getTradeInfo($trade_code){
- if(array_key_exists($trade_code, self::$trade_code_list)){
- $trade_code = $trade_code;
- }else{
- $trade_code = 'free_inner';
- }
- return self::$trade_code_list[$trade_code];
- }
-
- private function send_reuqest($method, $action, $params = []){
- if(!empty($params)){
- $params = array_filter($params, function($a){ return $a!==null;});
- }
-
- $query = [
- 'Action' => $action,
- 'Version' => $this->version,
- ];
-
- $body = '';
- if($method == 'GET'){
- $query = array_merge($query, $params);
- }else{
- $body = !empty($params) ? json_encode($params) : '';
- }
-
- $time = time();
- $headers = [
- 'Host' => $this->endpoint,
- 'X-Date' => gmdate("Ymd\THis\Z", $time),
- //'X-Content-Sha256' => hash("sha256", $body),
- ];
- if($body){
- $headers['Content-Type'] = 'application/json';
- }
- $path = '/';
-
- $authorization = $this->generateSign($method, $path, $query, $headers, $body, $time);
- $headers['Authorization'] = $authorization;
-
- $url = 'https://'.$this->endpoint.$path.'?'.http_build_query($query);
- $header = [];
- foreach($headers as $key => $value){
- $header[] = $key.': '.$value;
- }
- return $this->curl($method, $url, $body, $header);
- }
-
- private function generateSign($method, $path, $query, $headers, $body, $time){
- $algorithm = "HMAC-SHA256";
-
- // step 1: build canonical request string
- $httpRequestMethod = $method;
- $canonicalUri = $path;
- if(substr($canonicalUri, -1) != "/") $canonicalUri .= "/";
- $canonicalQueryString = $this->getCanonicalQueryString($query);
- [$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
- $hashedRequestPayload = hash("sha256", $body);
- $canonicalRequest = $httpRequestMethod."\n"
- .$canonicalUri."\n"
- .$canonicalQueryString."\n"
- .$canonicalHeaders."\n"
- .$signedHeaders."\n"
- .$hashedRequestPayload;
-
- // step 2: build string to sign
- $date = gmdate("Ymd\THis\Z", $time);
- $shortDate = substr($date, 0, 8);
- $credentialScope = $shortDate . '/' .$this->region . '/' . $this->service . '/request';
- $hashedCanonicalRequest = hash("sha256", $canonicalRequest);
- $stringToSign = $algorithm."\n"
- .$date."\n"
- .$credentialScope."\n"
- .$hashedCanonicalRequest;
-
- // step 3: sign string
- $kDate = hash_hmac("sha256", $shortDate, $this->SecretAccessKey, true);
- $kRegion = hash_hmac("sha256", $this->region, $kDate, true);
- $kService = hash_hmac("sha256", $this->service, $kRegion, true);
- $kSigning = hash_hmac("sha256", "request", $kService, true);
- $signature = hash_hmac("sha256", $stringToSign, $kSigning);
-
- // step 4: build authorization
- $credential = $this->AccessKeyId . '/' . $shortDate . '/' . $this->region . '/' . $this->service . '/request';
- $authorization = $algorithm . ' Credential=' . $credential . ", SignedHeaders=" . $signedHeaders . ", Signature=" . $signature;
-
- return $authorization;
- }
-
- private function escape($str)
- {
- $search = ['+', '*', '%7E'];
- $replace = ['%20', '%2A', '~'];
- return str_replace($search, $replace, urlencode($str));
- }
-
- private function getCanonicalQueryString($parameters)
- {
- if(empty($parameters)) return '';
- ksort($parameters);
- $canonicalQueryString = '';
- foreach ($parameters as $key => $value) {
- $canonicalQueryString .= '&' . $this->escape($key). '=' . $this->escape($value);
- }
- return substr($canonicalQueryString, 1);
- }
-
- private function getCanonicalHeaders($oldheaders){
- $headers = array();
- foreach ($oldheaders as $key => $value) {
- $headers[strtolower($key)] = trim($value);
- }
- ksort($headers);
-
- $canonicalHeaders = '';
- $signedHeaders = '';
- foreach ($headers as $key => $value) {
- $canonicalHeaders .= $key . ':' . $value . "\n";
- $signedHeaders .= $key . ';';
- }
- $signedHeaders = substr($signedHeaders, 0, -1);
- return [$canonicalHeaders, $signedHeaders];
- }
-
- private function curl($method, $url, $body, $header){
- $ch = curl_init($url);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_TIMEOUT, 10);
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
- if(!empty($body)){
- curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
- }
- $response = curl_exec($ch);
- $errno = curl_errno($ch);
- if ($errno) {
- $this->setError('Curl error: ' . curl_error($ch));
- }
- curl_close($ch);
- if ($errno) return false;
-
- $arr=json_decode($response,true);
- if($arr){
- if(isset($arr['ResponseMetadata']['Error']['MessageCN'])){
- $this->setError($arr['ResponseMetadata']['Error']['MessageCN']);
- return false;
- }elseif(isset($arr['ResponseMetadata']['Error']['Message'])){
- $this->setError($arr['ResponseMetadata']['Error']['Message']);
- return false;
- }elseif(isset($arr['Result'])){
- return $arr['Result'];
- }else{
- return true;
- }
- }else{
- $this->setError('返回数据解析失败');
- return false;
- }
- }
-
- private function setError($message){
- $this->error = $message;
- //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
- }
-}
\ No newline at end of file
+ ['level' => 1, 'name' => '免费版', 'ttl' => 600],
+ 'professional_inner' => ['level' => 2, 'name' => '专业版', 'ttl' => 300],
+ 'enterprise_inner' => ['level' => 3, 'name' => '企业版', 'ttl' => 60],
+ 'ultimate_inner' => ['level' => 4, 'name' => '旗舰版', 'ttl' => 1],
+ 'ultimate_exclusive_inner' => ['level' => 5, 'name' => '尊享版', 'ttl' => 1],
+ ];
+
+ public function __construct($config)
+ {
+ $this->AccessKeyId = $config['ak'];
+ $this->SecretAccessKey = $config['sk'];
+ $this->domain = $config['domain'];
+ $this->domainid = $config['domainid'];
+ }
+
+ public function getError()
+ {
+ return $this->error;
+ }
+
+ public function check()
+ {
+ if ($this->getDomainList() != false) {
+ return true;
+ }
+ return false;
+ }
+
+ //获取域名列表
+ public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
+ {
+ $query = ['PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'Key' => $KeyWord];
+ $data = $this->send_reuqest('GET', 'ListZones', $query);
+ if ($data) {
+ $list = [];
+ if (!empty($data['Zones'])) {
+ foreach ($data['Zones'] as $row) {
+ $list[] = [
+ 'DomainId' => $row['ZID'],
+ 'Domain' => $row['ZoneName'],
+ 'RecordCount' => $row['RecordCount'],
+ ];
+ }
+ }
+ return ['total' => $data['Total'], 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取解析记录列表
+ public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
+ {
+ $query = ['ZID' => intval($this->domainid), 'PageNumber' => $PageNumber, 'PageSize' => $PageSize, 'SearchOrder' => 'desc'];
+ if (!empty($SubDomain) || !empty($Type) || !empty($Line) || !empty($Value)) {
+ $query += ['Host' => $SubDomain, 'Value' => $Value, 'Type' => $Type, 'Line' => $Line];
+ } elseif (!empty($KeyWord)) {
+ $query += ['Host' => $KeyWord];
+ }
+ $data = $this->send_reuqest('GET', 'ListRecords', $query);
+ if ($data) {
+ $list = [];
+ foreach ($data['Records'] as $row) {
+ if ($row['Type'] == 'MX') {
+ list($row['MX'], $row['Value']) = explode(' ', $row['Value']);
+ }
+ $list[] = [
+ 'RecordId' => $row['RecordID'],
+ 'Domain' => $this->domain,
+ 'Name' => $row['Host'],
+ 'Type' => $row['Type'],
+ 'Value' => $row['Value'],
+ 'Line' => $row['Line'],
+ 'TTL' => $row['TTL'],
+ 'MX' => isset($row['MX']) ? $row['MX'] : null,
+ 'Status' => $row['Enable'] ? '1' : '0',
+ 'Weight' => $row['Weight'],
+ 'Remark' => $row['Remark'],
+ 'UpdateTime' => $row['UpdatedAt'],
+ ];
+ }
+ return ['total' => $data['TotalCount'], 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取子域名解析记录列表
+ public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
+ {
+ return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
+ }
+
+ //获取解析记录详细信息
+ public function getDomainRecordInfo($RecordId)
+ {
+ $data = $this->send_reuqest('GET', 'QueryRecord', ['RecordID' => $RecordId]);
+ if ($data) {
+ if ($data['name'] == $data['zone_name']) {
+ $data['name'] = '@';
+ }
+ if ($data['Type'] == 'MX') {
+ list($data['MX'], $data['Value']) = explode(' ', $data['Value']);
+ }
+ return [
+ 'RecordId' => $data['RecordID'],
+ 'Domain' => $this->domain,
+ 'Name' => $data['Host'],
+ 'Type' => $data['Type'],
+ 'Value' => $data['Value'],
+ 'Line' => $data['Line'],
+ 'TTL' => $data['TTL'],
+ 'MX' => isset($data['MX']) ? $data['MX'] : null,
+ 'Status' => $data['Enable'] ? '1' : '0',
+ 'Weight' => $data['Weight'],
+ 'Remark' => $data['Remark'],
+ 'UpdateTime' => $data['UpdatedAt'],
+ ];
+ }
+ return false;
+ }
+
+ //添加解析记录
+ public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $params = ['ZID' => intval($this->domainid), 'Host' => $Name, 'Type' => $this->convertType($Type), 'Value' => $Value, 'Line' => $Line, 'TTL' => intval($TTL), 'Remark' => $Remark];
+ if ($Type == 'MX') {
+ $params['Value'] = intval($MX) . ' ' . $Value;
+ }
+ if ($Weight > 0) {
+ $params['Weight'] = $Weight;
+ }
+ $data = $this->send_reuqest('POST', 'CreateRecord', $params);
+ return is_array($data) ? $data['RecordID'] : false;
+ }
+
+ //修改解析记录
+ public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $params = ['RecordID' => $RecordId, 'Host' => $Name, 'Type' => $this->convertType($Type), 'Value' => $Value, 'Line' => $Line, 'TTL' => intval($TTL), 'Remark' => $Remark];
+ if ($Type == 'MX') {
+ $params['Value'] = intval($MX) . ' ' . $Value;
+ }
+ if ($Weight > 0) {
+ $params['Weight'] = $Weight;
+ }
+ $data = $this->send_reuqest('POST', 'UpdateRecord', $params);
+ return is_array($data);
+ }
+
+ //修改解析记录备注
+ public function updateDomainRecordRemark($RecordId, $Remark)
+ {
+ return false;
+ }
+
+ //删除解析记录
+ public function deleteDomainRecord($RecordId)
+ {
+ $data = $this->send_reuqest('POST', 'DeleteRecord', ['RecordID' => $RecordId]);
+ return $data;
+ }
+
+ //设置解析记录状态
+ public function setDomainRecordStatus($RecordId, $Status)
+ {
+ $params = ['RecordID' => $RecordId, 'Enable' => $Status == '1'];
+ $data = $this->send_reuqest('POST', 'UpdateRecordStatus', $params);
+ return is_array($data);
+ }
+
+ //获取解析记录操作日志
+ public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
+ {
+ return false;
+ }
+
+ //获取解析线路列表
+ public function getRecordLine()
+ {
+ $domainInfo = $this->getDomainInfo();
+ if (!$domainInfo) {
+ return false;
+ }
+ $level = $this->getTradeInfo($domainInfo['TradeCode'])['level'];
+ $data = $this->send_reuqest('GET', 'ListLines', []);
+ if ($data) {
+ $list = [];
+ $list['default'] = ['name' => '默认', 'parent' => null];
+ foreach ($data['Lines'] as $row) {
+ if ($row['Value'] == 'default') {
+ continue;
+ }
+ if ($row['Level'] > $level) {
+ continue;
+ }
+ $list[$row['Value']] = ['name' => $row['Name'], 'parent' => isset($row['FatherValue']) ? $row['FatherValue'] : null];
+ }
+
+ $data = $this->send_reuqest('GET', 'ListCustomLines', []);
+ if ($data && $data['TotalCount'] > 0) {
+ $list['N.customer_lines'] = ['name' => '自定义线路', 'parent' => null];
+ foreach ($data['CustomerLines'] as $row) {
+ $list[$row['Line']] = ['name' => $row['NameCN'], 'parent' => 'N.customer_lines'];
+ }
+ }
+
+ return $list;
+ }
+ return false;
+ }
+
+ //获取域名概览信息
+ public function getDomainInfo()
+ {
+ if (!empty($this->domainInfo)) {
+ return $this->domainInfo;
+ }
+ $query = ['ZID' => intval($this->domainid)];
+ $data = $this->send_reuqest('GET', 'QueryZone', $query);
+ if ($data) {
+ $this->domainInfo = $data;
+ return $data;
+ }
+ return false;
+ }
+
+ //获取域名最低TTL
+ public function getMinTTL()
+ {
+ $domainInfo = $this->getDomainInfo();
+ if ($domainInfo) {
+ $ttl = $this->getTradeInfo($domainInfo['TradeCode'])['ttl'];
+ return $ttl;
+ }
+ return false;
+ }
+
+ private function convertType($type)
+ {
+ return $type;
+ }
+
+ private function getTradeInfo($trade_code)
+ {
+ if (array_key_exists($trade_code, self::$trade_code_list)) {
+ $trade_code = $trade_code;
+ } else {
+ $trade_code = 'free_inner';
+ }
+ return self::$trade_code_list[$trade_code];
+ }
+
+ private function send_reuqest($method, $action, $params = [])
+ {
+ if (!empty($params)) {
+ $params = array_filter($params, function ($a) { return $a !== null;});
+ }
+
+ $query = [
+ 'Action' => $action,
+ 'Version' => $this->version,
+ ];
+
+ $body = '';
+ if ($method == 'GET') {
+ $query = array_merge($query, $params);
+ } else {
+ $body = !empty($params) ? json_encode($params) : '';
+ }
+
+ $time = time();
+ $headers = [
+ 'Host' => $this->endpoint,
+ 'X-Date' => gmdate("Ymd\THis\Z", $time),
+ //'X-Content-Sha256' => hash("sha256", $body),
+ ];
+ if ($body) {
+ $headers['Content-Type'] = 'application/json';
+ }
+ $path = '/';
+
+ $authorization = $this->generateSign($method, $path, $query, $headers, $body, $time);
+ $headers['Authorization'] = $authorization;
+
+ $url = 'https://'.$this->endpoint.$path.'?'.http_build_query($query);
+ $header = [];
+ foreach ($headers as $key => $value) {
+ $header[] = $key.': '.$value;
+ }
+ return $this->curl($method, $url, $body, $header);
+ }
+
+ private function generateSign($method, $path, $query, $headers, $body, $time)
+ {
+ $algorithm = "HMAC-SHA256";
+
+ // step 1: build canonical request string
+ $httpRequestMethod = $method;
+ $canonicalUri = $path;
+ if (substr($canonicalUri, -1) != "/") {
+ $canonicalUri .= "/";
+ }
+ $canonicalQueryString = $this->getCanonicalQueryString($query);
+ [$canonicalHeaders, $signedHeaders] = $this->getCanonicalHeaders($headers);
+ $hashedRequestPayload = hash("sha256", $body);
+ $canonicalRequest = $httpRequestMethod."\n"
+ .$canonicalUri."\n"
+ .$canonicalQueryString."\n"
+ .$canonicalHeaders."\n"
+ .$signedHeaders."\n"
+ .$hashedRequestPayload;
+
+ // step 2: build string to sign
+ $date = gmdate("Ymd\THis\Z", $time);
+ $shortDate = substr($date, 0, 8);
+ $credentialScope = $shortDate . '/' .$this->region . '/' . $this->service . '/request';
+ $hashedCanonicalRequest = hash("sha256", $canonicalRequest);
+ $stringToSign = $algorithm."\n"
+ .$date."\n"
+ .$credentialScope."\n"
+ .$hashedCanonicalRequest;
+
+ // step 3: sign string
+ $kDate = hash_hmac("sha256", $shortDate, $this->SecretAccessKey, true);
+ $kRegion = hash_hmac("sha256", $this->region, $kDate, true);
+ $kService = hash_hmac("sha256", $this->service, $kRegion, true);
+ $kSigning = hash_hmac("sha256", "request", $kService, true);
+ $signature = hash_hmac("sha256", $stringToSign, $kSigning);
+
+ // step 4: build authorization
+ $credential = $this->AccessKeyId . '/' . $shortDate . '/' . $this->region . '/' . $this->service . '/request';
+ $authorization = $algorithm . ' Credential=' . $credential . ", SignedHeaders=" . $signedHeaders . ", Signature=" . $signature;
+
+ return $authorization;
+ }
+
+ private function escape($str)
+ {
+ $search = ['+', '*', '%7E'];
+ $replace = ['%20', '%2A', '~'];
+ return str_replace($search, $replace, urlencode($str));
+ }
+
+ private function getCanonicalQueryString($parameters)
+ {
+ if (empty($parameters)) {
+ return '';
+ }
+ ksort($parameters);
+ $canonicalQueryString = '';
+ foreach ($parameters as $key => $value) {
+ $canonicalQueryString .= '&' . $this->escape($key). '=' . $this->escape($value);
+ }
+ return substr($canonicalQueryString, 1);
+ }
+
+ private function getCanonicalHeaders($oldheaders)
+ {
+ $headers = array();
+ foreach ($oldheaders as $key => $value) {
+ $headers[strtolower($key)] = trim($value);
+ }
+ ksort($headers);
+
+ $canonicalHeaders = '';
+ $signedHeaders = '';
+ foreach ($headers as $key => $value) {
+ $canonicalHeaders .= $key . ':' . $value . "\n";
+ $signedHeaders .= $key . ';';
+ }
+ $signedHeaders = substr($signedHeaders, 0, -1);
+ return [$canonicalHeaders, $signedHeaders];
+ }
+
+ private function curl($method, $url, $body, $header)
+ {
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ if (!empty($body)) {
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
+ }
+ $response = curl_exec($ch);
+ $errno = curl_errno($ch);
+ if ($errno) {
+ $this->setError('Curl error: ' . curl_error($ch));
+ }
+ curl_close($ch);
+ if ($errno) {
+ return false;
+ }
+
+ $arr = json_decode($response, true);
+ if ($arr) {
+ if (isset($arr['ResponseMetadata']['Error']['MessageCN'])) {
+ $this->setError($arr['ResponseMetadata']['Error']['MessageCN']);
+ return false;
+ } elseif (isset($arr['ResponseMetadata']['Error']['Message'])) {
+ $this->setError($arr['ResponseMetadata']['Error']['Message']);
+ return false;
+ } elseif (isset($arr['Result'])) {
+ return $arr['Result'];
+ } else {
+ return true;
+ }
+ } else {
+ $this->setError('返回数据解析失败');
+ return false;
+ }
+ }
+
+ private function setError($message)
+ {
+ $this->error = $message;
+ //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
+ }
+}
diff --git a/app/lib/dns/west.php b/app/lib/dns/west.php
index 54994e7..684487f 100644
--- a/app/lib/dns/west.php
+++ b/app/lib/dns/west.php
@@ -1,209 +1,235 @@
-username = $config['ak'];
- $this->api_password = $config['sk'];
- $this->domain = $config['domain'];
- }
-
- public function getError(){
- return $this->error;
- }
-
- public function check(){
- if($this->getDomainList() != false){
- return true;
- }
- return false;
- }
-
- //获取域名列表
- public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){
- $param = ['act' => 'getdomains', 'page' => $PageNumber, 'limit' => $PageSize, 'domain' => $KeyWord];
- $data = $this->execute('/domain/', $param);
- if($data){
- $list = [];
- foreach($data['items'] as $row){
- $list[] = [
- 'DomainId' => $row['domain'],
- 'Domain' => $row['domain'],
- 'RecordCount' => 0,
- ];
- }
- return ['total' => $data['total'], 'list' => $list];
- }
- return false;
- }
-
- //获取解析记录列表
- public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null){
- $param = ['act' => 'getdnsrecord', 'domain' => $this->domain, 'type' => $Type, 'line' => $Line, 'host' => $KeyWord, 'value' => $Value, 'pageno' => $PageNumber, 'limit' => $PageSize];
- if(!isNullOrEmpty(($SubDomain))){
- $param['host'] = $SubDomain;
- }
- $data = $this->execute('/domain/', $param);
- if($data){
- $list = [];
- foreach($data['items'] as $row){
- $list[] = [
- 'RecordId' => $row['id'],
- 'Domain' => $this->domain,
- 'Name' => $row['item'],
- 'Type' => $row['type'],
- 'Value' => $row['value'],
- 'Line' => $row['line'],
- 'TTL' => $row['ttl'],
- 'MX' => $row['level'],
- 'Status' => $row['pause'] == 1 ? '0' : '1',
- 'Weight' => null,
- 'Remark' => null,
- 'UpdateTime' => null,
- ];
- }
- return ['total' => $data['total'], 'list' => $list];
- }
- return false;
- }
-
- //获取子域名解析记录列表
- public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){
- if($SubDomain == '')$SubDomain='@';
- return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
- }
-
- //获取解析记录详细信息
- public function getDomainRecordInfo($RecordId){
- return false;
- }
-
- //添加解析记录
- public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $param = ['act' => 'adddnsrecord', 'domain' => $this->domain, 'host' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'level' => $MX, 'ttl' => intval($TTL), 'line' => $Line];
- $data = $this->execute('/domain/', $param);
- return is_array($data) ? $data['id'] : false;
- }
-
- //修改解析记录
- public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null){
- $param = ['act' => 'moddnsrecord', 'domain' => $this->domain, 'id' => $RecordId, 'type' => $this->convertType($Type), 'value' => $Value, 'level' => $MX, 'ttl' => intval($TTL), 'line' => $Line];
- $data = $this->execute('/domain/', $param);
- return is_array($data);
- }
-
- //修改解析记录备注
- public function updateDomainRecordRemark($RecordId, $Remark){
- return false;
- }
-
- //删除解析记录
- public function deleteDomainRecord($RecordId){
- $param = ['act' => 'deldnsrecord', 'domain' => $this->domain, 'id' => $RecordId];
- $data = $this->execute('/domain/', $param);
- return is_array($data);
- }
-
- //设置解析记录状态
- public function setDomainRecordStatus($RecordId, $Status){
- $param = ['act' => 'pause', 'domain' => $this->domain, 'id' => $RecordId, 'val' => $Status == '1' ? '0' : '1'];
- $data = $this->execute('/domain/', $param);
- return $data !== false;
- }
-
- //获取解析记录操作日志
- public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){
- return false;
- }
-
- //获取解析线路列表
- public function getRecordLine(){
- return [
- ''=>['name'=>'默认', 'parent'=>null],
- 'LTEL'=>['name'=>'电信', 'parent'=>null],
- 'LCNC'=>['name'=>'联通', 'parent'=>null],
- 'LMOB'=>['name'=>'移动', 'parent'=>null],
- 'LEDU'=>['name'=>'教育网', 'parent'=>null],
- 'LSEO'=>['name'=>'搜索引擎', 'parent'=>null],
- 'LFOR'=>['name'=>'境外', 'parent'=>null],
- ];
- }
-
- //获取域名信息
- public function getDomainInfo(){
- return false;
- }
-
- //获取域名最低TTL
- public function getMinTTL(){
- return false;
- }
-
- private function convertType($type){
- return $type;
- }
-
- private function execute($path, $params){
- $params['username'] = $this->username;
- $params['time'] = $this->getMillisecond();
- $params['token'] = md5($this->username.$this->api_password.$params['time']);
- $response = $this->curl($path, $params);
- $response = mb_convert_encoding($response, 'UTF-8', 'GBK');
- $arr=json_decode($response,true);
- if($arr){
- if($arr['result'] == 200){
- return isset($arr['data']) ? $arr['data'] : [];
- }else{
- $this->setError($arr['msg']);
- return false;
- }
- }else{
- $this->setError('返回数据解析失败');
- return false;
- }
- }
-
- private function curl($path, $params = null){
- $url = $this->baseUrl . $path;
- $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);
- if ($params) {
- curl_setopt($ch, CURLOPT_POST, true);
- curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
- }
- $response = curl_exec($ch);
- $errno = curl_errno($ch);
- if ($errno) {
- $this->setError('Curl error: ' . curl_error($ch));
- }
- curl_close($ch);
- if ($errno) return false;
- return $response;
- }
-
- private function getMillisecond()
- {
- list($s1, $s2) = explode(' ', microtime());
- return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
- }
-
- private function setError($message){
- $this->error = $message;
- //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
- }
-}
\ No newline at end of file
+username = $config['ak'];
+ $this->api_password = $config['sk'];
+ $this->domain = $config['domain'];
+ }
+
+ public function getError()
+ {
+ return $this->error;
+ }
+
+ public function check()
+ {
+ if ($this->getDomainList() != false) {
+ return true;
+ }
+ return false;
+ }
+
+ //获取域名列表
+ public function getDomainList($KeyWord = null, $PageNumber = 1, $PageSize = 20)
+ {
+ $param = ['act' => 'getdomains', 'page' => $PageNumber, 'limit' => $PageSize, 'domain' => $KeyWord];
+ $data = $this->execute('/domain/', $param);
+ if ($data) {
+ $list = [];
+ foreach ($data['items'] as $row) {
+ $list[] = [
+ 'DomainId' => $row['domain'],
+ 'Domain' => $row['domain'],
+ 'RecordCount' => 0,
+ ];
+ }
+ return ['total' => $data['total'], 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取解析记录列表
+ public function getDomainRecords($PageNumber = 1, $PageSize = 20, $KeyWord = null, $SubDomain = null, $Value = null, $Type = null, $Line = null, $Status = null)
+ {
+ $param = ['act' => 'getdnsrecord', 'domain' => $this->domain, 'type' => $Type, 'line' => $Line, 'host' => $KeyWord, 'value' => $Value, 'pageno' => $PageNumber, 'limit' => $PageSize];
+ if (!isNullOrEmpty(($SubDomain))) {
+ $param['host'] = $SubDomain;
+ }
+ $data = $this->execute('/domain/', $param);
+ if ($data) {
+ $list = [];
+ foreach ($data['items'] as $row) {
+ $list[] = [
+ 'RecordId' => $row['id'],
+ 'Domain' => $this->domain,
+ 'Name' => $row['item'],
+ 'Type' => $row['type'],
+ 'Value' => $row['value'],
+ 'Line' => $row['line'],
+ 'TTL' => $row['ttl'],
+ 'MX' => $row['level'],
+ 'Status' => $row['pause'] == 1 ? '0' : '1',
+ 'Weight' => null,
+ 'Remark' => null,
+ 'UpdateTime' => null,
+ ];
+ }
+ return ['total' => $data['total'], 'list' => $list];
+ }
+ return false;
+ }
+
+ //获取子域名解析记录列表
+ public function getSubDomainRecords($SubDomain, $PageNumber = 1, $PageSize = 20, $Type = null, $Line = null)
+ {
+ if ($SubDomain == '') {
+ $SubDomain = '@';
+ }
+ return $this->getDomainRecords($PageNumber, $PageSize, null, $SubDomain, null, $Type, $Line);
+ }
+
+ //获取解析记录详细信息
+ public function getDomainRecordInfo($RecordId)
+ {
+ return false;
+ }
+
+ //添加解析记录
+ public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $param = ['act' => 'adddnsrecord', 'domain' => $this->domain, 'host' => $Name, 'type' => $this->convertType($Type), 'value' => $Value, 'level' => $MX, 'ttl' => intval($TTL), 'line' => $Line];
+ $data = $this->execute('/domain/', $param);
+ return is_array($data) ? $data['id'] : false;
+ }
+
+ //修改解析记录
+ public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Weight = null, $Remark = null)
+ {
+ $param = ['act' => 'moddnsrecord', 'domain' => $this->domain, 'id' => $RecordId, 'type' => $this->convertType($Type), 'value' => $Value, 'level' => $MX, 'ttl' => intval($TTL), 'line' => $Line];
+ $data = $this->execute('/domain/', $param);
+ return is_array($data);
+ }
+
+ //修改解析记录备注
+ public function updateDomainRecordRemark($RecordId, $Remark)
+ {
+ return false;
+ }
+
+ //删除解析记录
+ public function deleteDomainRecord($RecordId)
+ {
+ $param = ['act' => 'deldnsrecord', 'domain' => $this->domain, 'id' => $RecordId];
+ $data = $this->execute('/domain/', $param);
+ return is_array($data);
+ }
+
+ //设置解析记录状态
+ public function setDomainRecordStatus($RecordId, $Status)
+ {
+ $param = ['act' => 'pause', 'domain' => $this->domain, 'id' => $RecordId, 'val' => $Status == '1' ? '0' : '1'];
+ $data = $this->execute('/domain/', $param);
+ return $data !== false;
+ }
+
+ //获取解析记录操作日志
+ public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null)
+ {
+ return false;
+ }
+
+ //获取解析线路列表
+ public function getRecordLine()
+ {
+ return [
+ '' => ['name' => '默认', 'parent' => null],
+ 'LTEL' => ['name' => '电信', 'parent' => null],
+ 'LCNC' => ['name' => '联通', 'parent' => null],
+ 'LMOB' => ['name' => '移动', 'parent' => null],
+ 'LEDU' => ['name' => '教育网', 'parent' => null],
+ 'LSEO' => ['name' => '搜索引擎', 'parent' => null],
+ 'LFOR' => ['name' => '境外', 'parent' => null],
+ ];
+ }
+
+ //获取域名信息
+ public function getDomainInfo()
+ {
+ return false;
+ }
+
+ //获取域名最低TTL
+ public function getMinTTL()
+ {
+ return false;
+ }
+
+ private function convertType($type)
+ {
+ return $type;
+ }
+
+ private function execute($path, $params)
+ {
+ $params['username'] = $this->username;
+ $params['time'] = $this->getMillisecond();
+ $params['token'] = md5($this->username.$this->api_password.$params['time']);
+ $response = $this->curl($path, $params);
+ $response = mb_convert_encoding($response, 'UTF-8', 'GBK');
+ $arr = json_decode($response, true);
+ if ($arr) {
+ if ($arr['result'] == 200) {
+ return isset($arr['data']) ? $arr['data'] : [];
+ } else {
+ $this->setError($arr['msg']);
+ return false;
+ }
+ } else {
+ $this->setError('返回数据解析失败');
+ return false;
+ }
+ }
+
+ private function curl($path, $params = null)
+ {
+ $url = $this->baseUrl . $path;
+ $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);
+ if ($params) {
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
+ }
+ $response = curl_exec($ch);
+ $errno = curl_errno($ch);
+ if ($errno) {
+ $this->setError('Curl error: ' . curl_error($ch));
+ }
+ curl_close($ch);
+ if ($errno) {
+ return false;
+ }
+ return $response;
+ }
+
+ private function getMillisecond()
+ {
+ list($s1, $s2) = explode(' ', microtime());
+ return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
+ }
+
+ private function setError($message)
+ {
+ $this->error = $message;
+ //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND);
+ }
+}
diff --git a/app/lib/mail/Aliyun.php b/app/lib/mail/Aliyun.php
index 82225f8..9506808 100644
--- a/app/lib/mail/Aliyun.php
+++ b/app/lib/mail/Aliyun.php
@@ -1,72 +1,77 @@
AccessKeyId = $AccessKeyId;
- $this->AccessKeySecret = $AccessKeySecret;
- }
- private function aliyunSignature($parameters, $accessKeySecret, $method)
- {
- ksort($parameters);
- $canonicalizedQueryString = '';
- foreach ($parameters as $key => $value) {
- if($value === null) continue;
- $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
- }
- $stringToSign = $method . '&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
- $signature = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret . "&", true));
+ public function __construct($AccessKeyId, $AccessKeySecret)
+ {
+ $this->AccessKeyId = $AccessKeyId;
+ $this->AccessKeySecret = $AccessKeySecret;
+ }
+ private function aliyunSignature($parameters, $accessKeySecret, $method)
+ {
+ ksort($parameters);
+ $canonicalizedQueryString = '';
+ foreach ($parameters as $key => $value) {
+ if ($value === null) {
+ continue;
+ }
+ $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)
- {
- $search = ['+', '*', '%7E'];
- $replace = ['%20', '%2A', '~'];
- return str_replace($search, $replace, urlencode($str));
- }
- 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'];
- }
- }
-}
\ No newline at end of file
+ return $signature;
+ }
+ private function percentEncode($str)
+ {
+ $search = ['+', '*', '%7E'];
+ $replace = ['%20', '%2A', '~'];
+ return str_replace($search, $replace, urlencode($str));
+ }
+ 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'];
+ }
+ }
+}
diff --git a/app/lib/mail/PHPMailer/Exception.php b/app/lib/mail/PHPMailer/Exception.php
index f784b9f..8ed7aba 100644
--- a/app/lib/mail/PHPMailer/Exception.php
+++ b/app/lib/mail/PHPMailer/Exception.php
@@ -1,2 +1,11 @@
' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "
\n"; } }
\ No newline at end of file
+
+namespace app\lib\mail\PHPMailer;
+
+class Exception extends \Exception
+{
+ public function errorMessage()
+ {
+ return '' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "
\n";
+ }
+}
diff --git a/app/lib/mail/PHPMailer/PHPMailer.php b/app/lib/mail/PHPMailer/PHPMailer.php
index 1a4e34f..aab7d73 100644
--- a/app/lib/mail/PHPMailer/PHPMailer.php
+++ b/app/lib/mail/PHPMailer/PHPMailer.php
@@ -1,2 +1,1903 @@
exceptions = (bool) $exceptions; } $this->Debugoutput = (strpos(PHP_SAPI, 'cli') !== false ? 'echo' : 'html'); } public function __destruct() { $this->smtpClose(); } private function mailPassthru($to, $subject, $body, $header, $params) { if ((int)ini_get('mbstring.func_overload') & 1) { $subject = $this->secureHeader($subject); } else { $subject = $this->encodeHeader($this->secureHeader($subject)); } $this->edebug('Sending with mail()'); $this->edebug('Sendmail path: ' . ini_get('sendmail_path')); $this->edebug("Envelope sender: {$this->Sender}"); $this->edebug("To: {$to}"); $this->edebug("Subject: {$subject}"); $this->edebug("Headers: {$header}"); if (!$this->UseSendmailOptions || null === $params) { $result = @mail($to, $subject, $body, $header); } else { $this->edebug("Additional params: {$params}"); $result = @mail($to, $subject, $body, $header, $params); } $this->edebug('Result: ' . ($result ? 'true' : 'false')); return $result; } protected function edebug($str) { if ($this->SMTPDebug <= 0) { return; } if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) { $this->Debugoutput->debug(rtrim($str, "\r\n")); return; } if (is_callable($this->Debugoutput) && !in_array($this->Debugoutput, ['error_log', 'html', 'echo'])) { call_user_func($this->Debugoutput, $str, $this->SMTPDebug); return; } switch ($this->Debugoutput) { case 'error_log': error_log($str); break; case 'html': echo htmlentities(preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, 'UTF-8'), "
\n"; break; case 'echo': default: $str = preg_replace('/\r\n|\r/m', "\n", $str); echo gmdate('Y-m-d H:i:s'), "\t", trim(str_replace("\n", "\n \t ", trim($str))), "\n"; } } public function isHTML($isHtml = true) { if ($isHtml) { $this->ContentType = static::CONTENT_TYPE_TEXT_HTML; } else { $this->ContentType = static::CONTENT_TYPE_PLAINTEXT; } } public function isSMTP() { $this->Mailer = 'smtp'; } public function isMail() { $this->Mailer = 'mail'; } public function isSendmail() { $ini_sendmail_path = ini_get('sendmail_path'); if (false === stripos($ini_sendmail_path, 'sendmail')) { $this->Sendmail = '/usr/sbin/sendmail'; } else { $this->Sendmail = $ini_sendmail_path; } $this->Mailer = 'sendmail'; } public function isQmail() { $ini_sendmail_path = ini_get('sendmail_path'); if (false === stripos($ini_sendmail_path, 'qmail')) { $this->Sendmail = '/var/qmail/bin/qmail-inject'; } else { $this->Sendmail = $ini_sendmail_path; } $this->Mailer = 'qmail'; } public function addAddress($address, $name = '') { return $this->addOrEnqueueAnAddress('to', $address, $name); } public function addCC($address, $name = '') { return $this->addOrEnqueueAnAddress('cc', $address, $name); } public function addBCC($address, $name = '') { return $this->addOrEnqueueAnAddress('bcc', $address, $name); } public function addReplyTo($address, $name = '') { return $this->addOrEnqueueAnAddress('Reply-To', $address, $name); } protected function addOrEnqueueAnAddress($kind, $address, $name) { $pos = false; if ($address !== null) { $address = trim($address); $pos = strrpos($address, '@'); } if (false === $pos) { $error_message = sprintf('%s (%s): %s', $this->lang('invalid_address'), $kind, $address); $this->setError($error_message); $this->edebug($error_message); if ($this->exceptions) { throw new Exception($error_message); } return false; } if ($name !== null && is_string($name)) { $name = trim(preg_replace('/[\r\n]+/', '', $name)); } else { $name = ''; } $params = [$kind, $address, $name]; if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) { if ('Reply-To' !== $kind) { if (!array_key_exists($address, $this->RecipientsQueue)) { $this->RecipientsQueue[$address] = $params; return true; } } elseif (!array_key_exists($address, $this->ReplyToQueue)) { $this->ReplyToQueue[$address] = $params; return true; } return false; } return call_user_func_array([$this, 'addAnAddress'], $params); } public function setBoundaries() { $this->uniqueid = $this->generateId(); $this->boundary[1] = 'b1=_' . $this->uniqueid; $this->boundary[2] = 'b2=_' . $this->uniqueid; $this->boundary[3] = 'b3=_' . $this->uniqueid; } protected function addAnAddress($kind, $address, $name = '') { if (!in_array($kind, ['to', 'cc', 'bcc', 'Reply-To'])) { $error_message = sprintf('%s: %s', $this->lang('Invalid recipient kind'), $kind); $this->setError($error_message); $this->edebug($error_message); if ($this->exceptions) { throw new Exception($error_message); } return false; } if (!static::validateAddress($address)) { $error_message = sprintf('%s (%s): %s', $this->lang('invalid_address'), $kind, $address); $this->setError($error_message); $this->edebug($error_message); if ($this->exceptions) { throw new Exception($error_message); } return false; } if ('Reply-To' !== $kind) { if (!array_key_exists(strtolower($address), $this->all_recipients)) { $this->{$kind}[] = [$address, $name]; $this->all_recipients[strtolower($address)] = true; return true; } } elseif (!array_key_exists(strtolower($address), $this->ReplyTo)) { $this->ReplyTo[strtolower($address)] = [$address, $name]; return true; } return false; } public static function parseAddresses($addrstr, $useimap = true, $charset = self::CHARSET_ISO88591) { $addresses = []; if ($useimap && function_exists('imap_rfc822_parse_adrlist')) { $list = imap_rfc822_parse_adrlist($addrstr, ''); imap_errors(); foreach ($list as $address) { if ('.SYNTAX-ERROR.' !== $address->host && static::validateAddress($address->mailbox . '@' . $address->host)) { if (property_exists($address, 'personal') && defined('MB_CASE_UPPER') && preg_match('/^=\?.*\?=$/s', $address->personal)) { $origCharset = mb_internal_encoding(); mb_internal_encoding($charset); $address->personal = str_replace('_', '=20', $address->personal); $address->personal = mb_decode_mimeheader($address->personal); mb_internal_encoding($origCharset); } $addresses[] = ['name' => (property_exists($address, 'personal') ? $address->personal : ''), 'address' => $address->mailbox . '@' . $address->host,]; } } } else { $list = explode(',', $addrstr); foreach ($list as $address) { $address = trim($address); if (strpos($address, '<') === false) { if (static::validateAddress($address)) { $addresses[] = ['name' => '', 'address' => $address,]; } } else { list($name, $email) = explode('<', $address); $email = trim(str_replace('>', '', $email)); $name = trim($name); if (static::validateAddress($email)) { if (defined('MB_CASE_UPPER') && preg_match('/^=\?.*\?=$/s', $name)) { $origCharset = mb_internal_encoding(); mb_internal_encoding($charset); $name = str_replace('_', '=20', $name); $name = mb_decode_mimeheader($name); mb_internal_encoding($origCharset); } $addresses[] = ['name' => trim($name, '\'" '), 'address' => $email,]; } } } } return $addresses; } public function setFrom($address, $name = '', $auto = true) { $address = trim((string)$address); $name = trim(preg_replace('/[\r\n]+/', '', $name)); $pos = strrpos($address, '@'); if ((false === $pos) || ((!$this->has8bitChars(substr($address, ++$pos)) || !static::idnSupported()) && !static::validateAddress($address))) { $error_message = sprintf('%s (From): %s', $this->lang('invalid_address'), $address); $this->setError($error_message); $this->edebug($error_message); if ($this->exceptions) { throw new Exception($error_message); } return false; } $this->From = $address; $this->FromName = $name; if ($auto && empty($this->Sender)) { $this->Sender = $address; } return true; } public function getLastMessageID() { return $this->lastMessageID; } public static function validateAddress($address, $patternselect = null) { if (null === $patternselect) { $patternselect = static::$validator; } if (is_callable($patternselect) && !is_string($patternselect)) { return call_user_func($patternselect, $address); } if (strpos($address, "\n") !== false || strpos($address, "\r") !== false) { return false; } switch ($patternselect) { case 'pcre': case 'pcre8': return (bool) preg_match('/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' . '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' . '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' . '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' . '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' . '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' . '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' . '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' . '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', $address); case 'html5': return (bool) preg_match('/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' . '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', $address); case 'php': default: return filter_var($address, FILTER_VALIDATE_EMAIL) !== false; } } public static function idnSupported() { return function_exists('idn_to_ascii') && function_exists('mb_convert_encoding'); } public function punyencodeAddress($address) { $pos = strrpos($address, '@'); if (!empty($this->CharSet) && false !== $pos && static::idnSupported()) { $domain = substr($address, ++$pos); if ($this->has8bitChars($domain) && @mb_check_encoding($domain, $this->CharSet)) { $domain = mb_convert_encoding($domain, self::CHARSET_UTF8, $this->CharSet); $errorcode = 0; if (defined('INTL_IDNA_VARIANT_UTS46')) { $punycode = idn_to_ascii($domain, \IDNA_DEFAULT | \IDNA_USE_STD3_RULES | \IDNA_CHECK_BIDI | \IDNA_CHECK_CONTEXTJ | \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46); } elseif (defined('INTL_IDNA_VARIANT_2003')) { $punycode = idn_to_ascii($domain, $errorcode, \INTL_IDNA_VARIANT_2003); } else { $punycode = idn_to_ascii($domain, $errorcode); } if (false !== $punycode) { return substr($address, 0, $pos) . $punycode; } } } return $address; } public function send() { try { if (!$this->preSend()) { return false; } return $this->postSend(); } catch (Exception $exc) { $this->mailHeader = ''; $this->setError($exc->getMessage()); if ($this->exceptions) { throw $exc; } return false; } } public function preSend() { if ('smtp' === $this->Mailer || ('mail' === $this->Mailer && (\PHP_VERSION_ID >= 80000 || stripos(PHP_OS, 'WIN') === 0))) { static::setLE(self::CRLF); } else { static::setLE(PHP_EOL); } if ('mail' === $this->Mailer && ((\PHP_VERSION_ID >= 70000 && \PHP_VERSION_ID < 70017) || (\PHP_VERSION_ID >= 70100 && \PHP_VERSION_ID < 70103)) && ini_get('mail.add_x_header') === '1' && stripos(PHP_OS, 'WIN') === 0) { trigger_error($this->lang('buggy_php'), E_USER_WARNING); } try { $this->error_count = 0; $this->mailHeader = ''; foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) { $params[1] = $this->punyencodeAddress($params[1]); call_user_func_array([$this, 'addAnAddress'], $params); } if (count($this->to) + count($this->cc) + count($this->bcc) < 1) { throw new Exception($this->lang('provide_address'), self::STOP_CRITICAL); } foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) { if ($this->{$address_kind} === null) { $this->{$address_kind} = ''; continue; } $this->{$address_kind} = trim($this->{$address_kind}); if (empty($this->{$address_kind})) { continue; } $this->{$address_kind} = $this->punyencodeAddress($this->{$address_kind}); if (!static::validateAddress($this->{$address_kind})) { $error_message = sprintf('%s (%s): %s', $this->lang('invalid_address'), $address_kind, $this->{$address_kind}); $this->setError($error_message); $this->edebug($error_message); if ($this->exceptions) { throw new Exception($error_message); } return false; } } if ($this->alternativeExists()) { $this->ContentType = static::CONTENT_TYPE_MULTIPART_ALTERNATIVE; } $this->setMessageType(); if (!$this->AllowEmpty && empty($this->Body)) { throw new Exception($this->lang('empty_message'), self::STOP_CRITICAL); } $this->Subject = trim($this->Subject); $this->MIMEHeader = ''; $this->MIMEBody = $this->createBody(); $tempheaders = $this->MIMEHeader; $this->MIMEHeader = $this->createHeader(); $this->MIMEHeader .= $tempheaders; if ('mail' === $this->Mailer) { if (count($this->to) > 0) { $this->mailHeader .= $this->addrAppend('To', $this->to); } else { $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;'); } $this->mailHeader .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject))); } if (!empty($this->DKIM_domain) && !empty($this->DKIM_selector) && (!empty($this->DKIM_private_string) || (!empty($this->DKIM_private) && static::isPermittedPath($this->DKIM_private) && file_exists($this->DKIM_private)))) { $header_dkim = $this->DKIM_Add($this->MIMEHeader . $this->mailHeader, $this->encodeHeader($this->secureHeader($this->Subject)), $this->MIMEBody); $this->MIMEHeader = static::stripTrailingWSP($this->MIMEHeader) . static::$LE . static::normalizeBreaks($header_dkim) . static::$LE; } return true; } catch (Exception $exc) { $this->setError($exc->getMessage()); if ($this->exceptions) { throw $exc; } return false; } } public function postSend() { try { switch ($this->Mailer) { case 'sendmail': case 'qmail': return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody); case 'smtp': return $this->smtpSend($this->MIMEHeader, $this->MIMEBody); case 'mail': return $this->mailSend($this->MIMEHeader, $this->MIMEBody); default: $sendMethod = $this->Mailer . 'Send'; if (method_exists($this, $sendMethod)) { return $this->{$sendMethod}($this->MIMEHeader, $this->MIMEBody); } return $this->mailSend($this->MIMEHeader, $this->MIMEBody); } } catch (Exception $exc) { $this->setError($exc->getMessage()); $this->edebug($exc->getMessage()); if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true && $this->smtp->connected()) { $this->smtp->reset(); } if ($this->exceptions) { throw $exc; } } return false; } protected function sendmailSend($header, $body) { if ($this->Mailer === 'qmail') { $this->edebug('Sending with qmail'); } else { $this->edebug('Sending with sendmail'); } $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; $sendmail_from_value = ini_get('sendmail_from'); if (empty($this->Sender) && !empty($sendmail_from_value)) { $this->Sender = ini_get('sendmail_from'); } if (!empty($this->Sender) && static::validateAddress($this->Sender) && self::isShellSafe($this->Sender)) { if ($this->Mailer === 'qmail') { $sendmailFmt = '%s -f%s'; } else { $sendmailFmt = '%s -oi -f%s -t'; } } else { $sendmailFmt = '%s -oi -t'; } $sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender); $this->edebug('Sendmail path: ' . $this->Sendmail); $this->edebug('Sendmail command: ' . $sendmail); $this->edebug('Envelope sender: ' . $this->Sender); $this->edebug("Headers: {$header}"); if ($this->SingleTo) { foreach ($this->SingleToArray as $toAddr) { $mail = @popen($sendmail, 'w'); if (!$mail) { throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); } $this->edebug("To: {$toAddr}"); fwrite($mail, 'To: ' . $toAddr . "\n"); fwrite($mail, $header); fwrite($mail, $body); $result = pclose($mail); $addrinfo = static::parseAddresses($toAddr, true, $this->CharSet); $this->doCallback(($result === 0), [[$addrinfo['address'], $addrinfo['name']]], $this->cc, $this->bcc, $this->Subject, $body, $this->From, []); $this->edebug("Result: " . ($result === 0 ? 'true' : 'false')); if (0 !== $result) { throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); } } } else { $mail = @popen($sendmail, 'w'); if (!$mail) { throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); } fwrite($mail, $header); fwrite($mail, $body); $result = pclose($mail); $this->doCallback(($result === 0), $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From, []); $this->edebug("Result: " . ($result === 0 ? 'true' : 'false')); if (0 !== $result) { throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); } } return true; } protected static function isShellSafe($string) { if (!function_exists('escapeshellarg') || !function_exists('escapeshellcmd')) { return false; } if (escapeshellcmd($string) !== $string || !in_array(escapeshellarg($string), ["'$string'", "\"$string\""])) { return false; } $length = strlen($string); for ($i = 0; $i < $length; ++$i) { $c = $string[$i]; if (!ctype_alnum($c) && strpos('@_-.', $c) === false) { return false; } } return true; } protected static function isPermittedPath($path) { return !preg_match('#^[a-z][a-z\d+.-]*://#i', $path); } protected static function fileIsAccessible($path) { if (!static::isPermittedPath($path)) { return false; } $readable = is_file($path); if (strpos($path, '\\\\') !== 0) { $readable = $readable && is_readable($path); } return $readable; } protected function mailSend($header, $body) { $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; $toArr = []; foreach ($this->to as $toaddr) { $toArr[] = $this->addrFormat($toaddr); } $to = trim(implode(', ', $toArr)); if ($to === '') { $to = 'undisclosed-recipients:;'; } $params = null; $sendmail_from_value = ini_get('sendmail_from'); if (empty($this->Sender) && !empty($sendmail_from_value)) { $this->Sender = ini_get('sendmail_from'); } if (!empty($this->Sender) && static::validateAddress($this->Sender)) { if (self::isShellSafe($this->Sender)) { $params = sprintf('-f%s', $this->Sender); } $old_from = ini_get('sendmail_from'); ini_set('sendmail_from', $this->Sender); } $result = false; if ($this->SingleTo && count($toArr) > 1) { foreach ($toArr as $toAddr) { $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params); $addrinfo = static::parseAddresses($toAddr, true, $this->CharSet); $this->doCallback($result, [[$addrinfo['address'], $addrinfo['name']]], $this->cc, $this->bcc, $this->Subject, $body, $this->From, []); } } else { $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params); $this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From, []); } if (isset($old_from)) { ini_set('sendmail_from', $old_from); } if (!$result) { throw new Exception($this->lang('instantiate'), self::STOP_CRITICAL); } return true; } public function getSMTPInstance() { if (!is_object($this->smtp)) { $this->smtp = new SMTP(); } return $this->smtp; } public function setSMTPInstance(SMTP $smtp) { $this->smtp = $smtp; return $this->smtp; } public function setSMTPXclientAttribute($name, $value) { if (!in_array($name, SMTP::$xclient_allowed_attributes)) { return false; } if (isset($this->SMTPXClient[$name]) && $value === null) { unset($this->SMTPXClient[$name]); } elseif ($value !== null) { $this->SMTPXClient[$name] = $value; } return true; } public function getSMTPXclientAttributes() { return $this->SMTPXClient; } protected function smtpSend($header, $body) { $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; $bad_rcpt = []; if (!$this->smtpConnect($this->SMTPOptions)) { throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); } if ('' === $this->Sender) { $smtp_from = $this->From; } else { $smtp_from = $this->Sender; } if (count($this->SMTPXClient)) { $this->smtp->xclient($this->SMTPXClient); } if (!$this->smtp->mail($smtp_from)) { $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError())); throw new Exception($this->ErrorInfo, self::STOP_CRITICAL); } $callbacks = []; foreach ([$this->to, $this->cc, $this->bcc] as $togroup) { foreach ($togroup as $to) { if (!$this->smtp->recipient($to[0], $this->dsn)) { $error = $this->smtp->getError(); $bad_rcpt[] = ['to' => $to[0], 'error' => $error['detail']]; $isSent = false; } else { $isSent = true; } $callbacks[] = ['issent' => $isSent, 'to' => $to[0], 'name' => $to[1]]; } } if ((count($this->all_recipients) > count($bad_rcpt)) && !$this->smtp->data($header . $body)) { throw new Exception($this->lang('data_not_accepted'), self::STOP_CRITICAL); } $smtp_transaction_id = $this->smtp->getLastTransactionID(); if ($this->SMTPKeepAlive) { $this->smtp->reset(); } else { $this->smtp->quit(); $this->smtp->close(); } foreach ($callbacks as $cb) { $this->doCallback($cb['issent'], [[$cb['to'], $cb['name']]], [], [], $this->Subject, $body, $this->From, ['smtp_transaction_id' => $smtp_transaction_id]); } if (count($bad_rcpt) > 0) { $errstr = ''; foreach ($bad_rcpt as $bad) { $errstr .= $bad['to'] . ': ' . $bad['error']; } throw new Exception($this->lang('recipients_failed') . $errstr, self::STOP_CONTINUE); } return true; } public function smtpConnect($options = null) { if (null === $this->smtp) { $this->smtp = $this->getSMTPInstance(); } if (null === $options) { $options = $this->SMTPOptions; } if ($this->smtp->connected()) { return true; } $this->smtp->setTimeout($this->Timeout); $this->smtp->setDebugLevel($this->SMTPDebug); $this->smtp->setDebugOutput($this->Debugoutput); $this->smtp->setVerp($this->do_verp); if ($this->Host === null) { $this->Host = 'localhost'; } $hosts = explode(';', $this->Host); $lastexception = null; foreach ($hosts as $hostentry) { $hostinfo = []; if (!preg_match('/^(?:(ssl|tls):\/\/)?(.+?)(?::(\d+))?$/', trim($hostentry), $hostinfo)) { $this->edebug($this->lang('invalid_hostentry') . ' ' . trim($hostentry)); continue; } if (!static::isValidHost($hostinfo[2])) { $this->edebug($this->lang('invalid_host') . ' ' . $hostinfo[2]); continue; } $prefix = ''; $secure = $this->SMTPSecure; $tls = (static::ENCRYPTION_STARTTLS === $this->SMTPSecure); if ('ssl' === $hostinfo[1] || ('' === $hostinfo[1] && static::ENCRYPTION_SMTPS === $this->SMTPSecure)) { $prefix = 'ssl://'; $tls = false; $secure = static::ENCRYPTION_SMTPS; } elseif ('tls' === $hostinfo[1]) { $tls = true; $secure = static::ENCRYPTION_STARTTLS; } $sslext = defined('OPENSSL_ALGO_SHA256'); if (static::ENCRYPTION_STARTTLS === $secure || static::ENCRYPTION_SMTPS === $secure) { if (!$sslext) { throw new Exception($this->lang('extension_missing') . 'openssl', self::STOP_CRITICAL); } } $host = $hostinfo[2]; $port = $this->Port; if (array_key_exists(3, $hostinfo) && is_numeric($hostinfo[3]) && $hostinfo[3] > 0 && $hostinfo[3] < 65536) { $port = (int) $hostinfo[3]; } if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) { try { if ($this->Helo) { $hello = $this->Helo; } else { $hello = $this->serverHostname(); } $this->smtp->hello($hello); if ($this->SMTPAutoTLS && $this->Host !== 'localhost' && $sslext && $secure !== 'ssl' && $this->smtp->getServerExt('STARTTLS')) { $tls = true; } if ($tls) { if (!$this->smtp->startTLS()) { $message = $this->getSmtpErrorMessage('connect_host'); throw new Exception($message); } $this->smtp->hello($hello); } if ($this->SMTPAuth && !$this->smtp->authenticate($this->Username, $this->Password, $this->AuthType, $this->oauth)) { throw new Exception($this->lang('authenticate')); } return true; } catch (Exception $exc) { $lastexception = $exc; $this->edebug($exc->getMessage()); $this->smtp->quit(); } } } $this->smtp->close(); if ($this->exceptions && null !== $lastexception) { throw $lastexception; } if ($this->exceptions) { $message = $this->getSmtpErrorMessage('connect_host'); throw new Exception($message); } return false; } public function smtpClose() { if ((null !== $this->smtp) && $this->smtp->connected()) { $this->smtp->quit(); $this->smtp->close(); } } public function setLanguage($langcode = 'en', $lang_path = '') { $renamed_langcodes = ['br' => 'pt_br', 'cz' => 'cs', 'dk' => 'da', 'no' => 'nb', 'se' => 'sv', 'rs' => 'sr', 'tg' => 'tl', 'am' => 'hy',]; if (array_key_exists($langcode, $renamed_langcodes)) { $langcode = $renamed_langcodes[$langcode]; } $PHPMAILER_LANG = ['authenticate' => 'SMTP Error: Could not authenticate.', 'buggy_php' => 'Your version of PHP is affected by a bug that may result in corrupted messages.' . ' To fix it, switch to sending using SMTP, disable the mail.add_x_header option in' . ' your php.ini, switch to MacOS or Linux, or upgrade your PHP to version 7.0.17+ or 7.1.3+.', 'connect_host' => 'SMTP Error: Could not connect to SMTP host.', 'data_not_accepted' => 'SMTP Error: data not accepted.', 'empty_message' => 'Message body empty', 'encoding' => 'Unknown encoding: ', 'execute' => 'Could not execute: ', 'extension_missing' => 'Extension missing: ', 'file_access' => 'Could not access file: ', 'file_open' => 'File Error: Could not open file: ', 'from_failed' => 'The following From address failed: ', 'instantiate' => 'Could not instantiate mail function.', 'invalid_address' => 'Invalid address: ', 'invalid_header' => 'Invalid header name or value', 'invalid_hostentry' => 'Invalid hostentry: ', 'invalid_host' => 'Invalid host: ', 'mailer_not_supported' => ' mailer is not supported.', 'provide_address' => 'You must provide at least one recipient email address.', 'recipients_failed' => 'SMTP Error: The following recipients failed: ', 'signing' => 'Signing Error: ', 'smtp_code' => 'SMTP code: ', 'smtp_code_ex' => 'Additional SMTP info: ', 'smtp_connect_failed' => 'SMTP connect() failed.', 'smtp_detail' => 'Detail: ', 'smtp_error' => 'SMTP server error: ', 'variable_set' => 'Cannot set or reset variable: ',]; $PHPMAILER_LANG['authenticate'] = 'SMTP登录失败:邮箱账号或密码错误。'; $PHPMAILER_LANG['buggy_php'] = '您的 PHP 版本存在漏洞,可能会导致消息损坏。为修复此问题,请切换到使用 SMTP 发送,在您的 php.ini 中禁用 mail.add_x_header 选项。切换到 MacOS 或 Linux,或将您的 PHP 升级到 7.0.17+ 或 7.1.3+ 版本。'; $PHPMAILER_LANG['connect_host'] = '无法连接到SMTP服务器。'; $PHPMAILER_LANG['data_not_accepted'] = '数据不被接受。'; $PHPMAILER_LANG['empty_message'] = '邮件正文为空。'; $PHPMAILER_LANG['encoding'] = '未知编码:'; $PHPMAILER_LANG['execute'] = '无法执行:'; $PHPMAILER_LANG['extension_missing'] = '缺少扩展名:'; $PHPMAILER_LANG['file_access'] = '无法访问文件:'; $PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:'; $PHPMAILER_LANG['from_failed'] = '发送地址错误:'; $PHPMAILER_LANG['instantiate'] = '未知函数调用。'; $PHPMAILER_LANG['invalid_address'] = '发送失败,电子邮箱地址是无效的:'; $PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。'; $PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。'; $PHPMAILER_LANG['recipients_failed'] = '收件人地址错误:'; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP服务器连接失败:SMTP服务器地址或端口错误。'; $PHPMAILER_LANG['smtp_error'] = 'SMTP服务器出错:'; $PHPMAILER_LANG['variable_set'] = '无法设置或重置变量:'; $PHPMAILER_LANG['invalid_header'] = '无效的标题名称或值'; $PHPMAILER_LANG['invalid_hostentry'] = '无效的hostentry: '; $PHPMAILER_LANG['invalid_host'] = '无效的主机:'; $PHPMAILER_LANG['signing'] = '签名错误:'; $PHPMAILER_LANG['smtp_code'] = 'SMTP代码: '; $PHPMAILER_LANG['smtp_code_ex'] = '附加SMTP信息: '; $PHPMAILER_LANG['smtp_detail'] = '详情:'; if (empty($lang_path)) { $lang_path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR; } $foundlang = true; $langcode = strtolower($langcode); if (!preg_match('/^(?P[a-z]{2})(?P