mirror of
https://github.com/helloxz/onenav.git
synced 2026-06-13 21:01:42 +08:00
1012 lines
32 KiB
PHP
Executable File
1012 lines
32 KiB
PHP
Executable File
<?php
|
||
/**
|
||
* name:API核心类
|
||
* update:2020/12
|
||
* author:xiaoz<xiaoz93@outlook.com>
|
||
* blog:xiaoz.me
|
||
*/
|
||
class Api {
|
||
protected $db;
|
||
public function __construct($db){
|
||
$this->db = $db;
|
||
//返回json类型
|
||
header('Content-Type:application/json; charset=utf-8');
|
||
}
|
||
/**
|
||
* name:创建分类目录
|
||
*/
|
||
public function add_category($token,$name,$property = 0,$weight = 0,$description = '',$font_icon = '',$fid = 0){
|
||
$this->auth($token);
|
||
//分类名称不允许为空
|
||
if( empty($name) ) {
|
||
$this->err_msg(-2000,'分类名称不能为空!');
|
||
}
|
||
$data = [
|
||
'name' => htmlspecialchars($name,ENT_QUOTES),
|
||
'add_time' => time(),
|
||
'weight' => $weight,
|
||
'property' => $property,
|
||
'description' => htmlspecialchars($description,ENT_QUOTES),
|
||
'font_icon' => $font_icon,
|
||
'fid' => $fid
|
||
];
|
||
//插入分类目录
|
||
$this->db->insert("on_categorys",$data);
|
||
//返回ID
|
||
$id = $this->db->id();
|
||
//如果id为空(NULL),说明插入失败了,姑且认为是name重复导致
|
||
if( empty($id) ){
|
||
$this->err_msg(-1000,'Categorie already exist!');
|
||
}
|
||
else{
|
||
//成功并返回json格式
|
||
$data = [
|
||
'code' => 0,
|
||
'id' => intval($id)
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
|
||
}
|
||
/**
|
||
* 修改分类目录
|
||
*
|
||
*/
|
||
public function edit_category($token,$id,$name,$property = 0,$weight = 0,$description = '',$font_icon = '',$fid = 0){
|
||
$this->auth($token);
|
||
//如果id为空
|
||
if( empty($id) ){
|
||
$this->err_msg(-1003,'The category ID cannot be empty!');
|
||
}
|
||
//如果分类名为空
|
||
elseif( empty($name ) ){
|
||
$this->err_msg(-1004,'The category name cannot be empty!');
|
||
}
|
||
|
||
//更新数据库
|
||
else{
|
||
//根据分类ID查询改分类下面是否已经存在子分类,如果存在子分类了则不允许设置为子分类,实用情况:一级分类下存在二级分类,无法再将改一级分类修改为二级分类
|
||
$count = $this->db->count("on_categorys", [
|
||
"fid" => $id
|
||
]);
|
||
if( $count > 0 ) {
|
||
$this->err_msg(-2000,'修改失败,该分类下已存在子分类!');
|
||
}
|
||
$data = [
|
||
'name' => htmlspecialchars($name,ENT_QUOTES),
|
||
'up_time' => time(),
|
||
'weight' => $weight,
|
||
'property' => $property,
|
||
'description' => htmlspecialchars($description,ENT_QUOTES),
|
||
'font_icon' => $font_icon,
|
||
'fid' => $fid
|
||
];
|
||
$re = $this->db->update('on_categorys',$data,[ 'id' => $id]);
|
||
//var_dump( $this->db->log() );
|
||
//获取影响行数
|
||
$row = $re->rowCount();
|
||
if($row) {
|
||
$data = [
|
||
'code' => 0,
|
||
'msg' => 'successful'
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
else{
|
||
$this->err_msg(-1005,'The category name already exists!');
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* 删除分类目录
|
||
*/
|
||
public function del_category($token,$id) {
|
||
//验证授权
|
||
$this->auth($token);
|
||
//如果id为空
|
||
if( empty($id) ){
|
||
$this->err_msg(-1003,'The category ID cannot be empty!');
|
||
}
|
||
//如果分类目录下存在数据
|
||
$count = $this->db->count("on_links", [
|
||
"fid" => $id
|
||
]);
|
||
//如果分类目录下存在数据,则不允许删除
|
||
if($count > 0) {
|
||
$this->err_msg(-1006,'The category is not empty and cannot be deleted!');
|
||
}
|
||
else{
|
||
$data = $this->db->delete('on_categorys',[ 'id' => $id] );
|
||
//返回影响行数
|
||
$row = $data->rowCount();
|
||
if($row) {
|
||
$data = [
|
||
'code' => 0,
|
||
'msg' => 'successful'
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
else{
|
||
$this->err_msg(-1007,'The category delete failed!');
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* name:返回错误(json)
|
||
*
|
||
*/
|
||
protected function err_msg($code,$err_msg){
|
||
$data = [
|
||
'code' => $code,
|
||
'err_msg' => $err_msg
|
||
];
|
||
//返回json类型
|
||
header('Content-Type:application/json; charset=utf-8');
|
||
exit(json_encode($data));
|
||
}
|
||
/**
|
||
* name:验证方法
|
||
*/
|
||
protected function auth($token){
|
||
//计算正确的token:用户名 + TOKEN
|
||
$SecretKey = @$this->db->get('on_options','*',[ 'key' => 'SecretKey' ])['value'];
|
||
$token_yes = md5(USER.$SecretKey);
|
||
//如果token为空,则验证cookie
|
||
if(empty($token)) {
|
||
if( !$this->is_login() ) {
|
||
$this->err_msg(-1002,'Authorization failure!');
|
||
}
|
||
}
|
||
else if ( empty($SecretKey) ) {
|
||
$this->err_msg(-2000,'请先生成SecretKey!');
|
||
}
|
||
else if($token != $token_yes){
|
||
$this->err_msg(-1002,'Authorization failure!');
|
||
}
|
||
else{
|
||
return true;
|
||
}
|
||
}
|
||
/**
|
||
* name:添加链接
|
||
*/
|
||
public function add_link($token,$fid,$title,$url,$description = '',$weight = 0,$property = 0,$url_standby = ''){
|
||
$this->auth($token);
|
||
$fid = intval($fid);
|
||
//检测链接是否合法
|
||
//$this->check_link($fid,$title,$url);
|
||
$this->check_link([
|
||
'fid' => $fid,
|
||
'title' => $title,
|
||
'url' => $url,
|
||
'url_standby' => $url_standby
|
||
]);
|
||
|
||
//合并数据
|
||
$data = [
|
||
'fid' => $fid,
|
||
'title' => htmlspecialchars($title,ENT_QUOTES),
|
||
'url' => htmlspecialchars($url,ENT_QUOTES),
|
||
'url_standby' => htmlspecialchars($url_standby,ENT_QUOTES),
|
||
'description' => htmlspecialchars($description,ENT_QUOTES),
|
||
'add_time' => time(),
|
||
'weight' => $weight,
|
||
'property' => $property
|
||
];
|
||
//插入数据库
|
||
$re = $this->db->insert('on_links',$data);
|
||
//返回影响行数
|
||
$row = $re->rowCount();
|
||
//如果为真
|
||
if( $row ){
|
||
$id = $this->db->id();
|
||
$data = [
|
||
'code' => 0,
|
||
'id' => $id
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
//如果插入失败
|
||
else{
|
||
$this->err_msg(-1011,'The URL already exists!');
|
||
}
|
||
}
|
||
/**
|
||
* 批量导入链接
|
||
*/
|
||
public function imp_link($token,$filename,$fid,$property = 0){
|
||
//过滤$filename
|
||
$filename = str_replace('../','',$filename);
|
||
$filename = str_replace('./','',$filename);
|
||
$this->auth($token);
|
||
//检查文件是否存在
|
||
if ( !file_exists($filename) ) {
|
||
$this->err_msg(-1016,'File does not exist!');
|
||
}
|
||
//解析HTML数据
|
||
$content = file_get_contents($filename);
|
||
|
||
$pattern = "/<A.*<\/A>/i";
|
||
|
||
preg_match_all($pattern,$content,$arr);
|
||
//失败次数
|
||
$fail = 0;
|
||
//成功次数
|
||
$success = 0;
|
||
//总数
|
||
$total = count($arr[0]);
|
||
foreach( $arr[0] as $link )
|
||
{
|
||
$pattern = "/http.*\"? ADD_DATE/i";
|
||
preg_match($pattern,$link,$urls);
|
||
$url = str_replace('" ADD_DATE','',$urls[0]);
|
||
$pattern = "/>.*<\/a>$/i";
|
||
preg_match($pattern,$link,$titles);
|
||
|
||
$title = str_replace('>','',$titles[0]);
|
||
$title = str_replace('</A','',$title);
|
||
|
||
//如果标题或者链接为空,则不导入
|
||
if( ($title == '') || ($url == '') ) {
|
||
$fail++;
|
||
continue;
|
||
}
|
||
$data = [
|
||
'fid' => $fid,
|
||
'description' => '',
|
||
'add_time' => time(),
|
||
'weight' => 0,
|
||
'property' => $property
|
||
];
|
||
$data['title'] = $title;
|
||
$data['url'] = $url;
|
||
|
||
//插入数据库
|
||
$re = $this->db->insert('on_links',$data);
|
||
//返回影响行数
|
||
$row = $re->rowCount();
|
||
//如果为真
|
||
if( $row ){
|
||
$id = $this->db->id();
|
||
$data = [
|
||
'code' => 0,
|
||
'id' => $id
|
||
];
|
||
$success++;
|
||
|
||
}
|
||
//如果插入失败
|
||
else{
|
||
$fail++;
|
||
}
|
||
}
|
||
//删除书签
|
||
unlink($filename);
|
||
$data = [
|
||
'code' => 0,
|
||
'msg' => '总数:'.$total.' 成功:'.$success.' 失败:'.$fail
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
/**
|
||
* 书签上传
|
||
* type:上传类型,默认为上传书签,后续类型保留使用
|
||
*/
|
||
public function upload($token,$type){
|
||
$this->auth($token);
|
||
if ($_FILES["file"]["error"] > 0)
|
||
{
|
||
$this->err_msg(-1015,'File upload failed!');
|
||
}
|
||
else
|
||
{
|
||
$filename = $_FILES["file"]["name"];
|
||
//获取文件后缀
|
||
$suffix = explode('.',$filename);
|
||
$suffix = strtolower(end($suffix));
|
||
|
||
//临时文件位置
|
||
$temp = $_FILES["file"]["tmp_name"];
|
||
if( $suffix != 'html' ) {
|
||
//删除临时文件
|
||
unlink($filename);
|
||
$this->err_msg(-1014,'Unsupported file suffix name!');
|
||
}
|
||
|
||
if( copy($temp,'data/'.$filename) ) {
|
||
$data = [
|
||
'code' => 0,
|
||
'file_name' => 'data/'.$filename
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* name:修改链接
|
||
*/
|
||
public function edit_link($token,$id,$fid,$title,$url,$description = '',$weight = 0,$property = 0,$url_standby = ''){
|
||
$this->auth($token);
|
||
$fid = intval($fid);
|
||
//检测链接是否合法
|
||
//$this->check_link($fid,$title,$url);
|
||
$this->check_link([
|
||
'fid' => $fid,
|
||
'title' => htmlspecialchars($title,ENT_QUOTES),
|
||
'url' => htmlspecialchars($url,ENT_QUOTES),
|
||
'url_standby' => htmlspecialchars($url_standby,ENT_QUOTES)
|
||
]);
|
||
//查询ID是否存在
|
||
$count = $this->db->count('on_links',[ 'id' => $id]);
|
||
//如果id不存在
|
||
if( (empty($id)) || ($count == false) ) {
|
||
$this->err_msg(-1012,'link id not exists!');
|
||
}
|
||
//合并数据
|
||
$data = [
|
||
'fid' => $fid,
|
||
'title' => htmlspecialchars($title,ENT_QUOTES),
|
||
'url' => $url,
|
||
'url_standby' => $url_standby,
|
||
'description' => htmlspecialchars($description,ENT_QUOTES),
|
||
'up_time' => time(),
|
||
'weight' => $weight,
|
||
'property' => $property
|
||
];
|
||
//插入数据库
|
||
$re = $this->db->update('on_links',$data,[ 'id' => $id]);
|
||
//返回影响行数
|
||
$row = $re->rowCount();
|
||
//如果为真
|
||
if( $row ){
|
||
$id = $this->db->id();
|
||
$data = [
|
||
'code' => 0,
|
||
'msg' => 'successful'
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
//如果插入失败
|
||
else{
|
||
$this->err_msg(-1011,'The URL already exists!');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 删除链接
|
||
*/
|
||
public function del_link($token,$id){
|
||
//验证token是否合法
|
||
$this->auth($token);
|
||
//查询ID是否存在
|
||
$count = $this->db->count('on_links',[ 'id' => $id]);
|
||
//如果id不存在
|
||
if( (empty($id)) || ($count == false) ) {
|
||
$this->err_msg(-1010,'link id not exists!');
|
||
}
|
||
else{
|
||
$re = $this->db->delete('on_links',[ 'id' => $id] );
|
||
if($re) {
|
||
$data = [
|
||
'code' => 0,
|
||
'msg' => 'successful'
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
else{
|
||
$this->err_msg(-1010,'link id not exists!');
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* 验证链接合法性
|
||
* 接收一个数组作为参数
|
||
*/
|
||
protected function check_link($data){
|
||
$fid = $data['fid'];
|
||
$title = $data['title'];
|
||
$url = $data['url'];
|
||
$url_standby = @$data['url_standby'];
|
||
|
||
//如果父及(分类)ID不存在
|
||
if( empty($fid )) {
|
||
$this->err_msg(-1007,'The category id(fid) not exist!');
|
||
}
|
||
//如果父及ID不存在数据库中
|
||
//验证分类目录是否存在
|
||
$count = $this->db->count("on_categorys", [
|
||
"id" => $fid
|
||
]);
|
||
if ( empty($count) ){
|
||
$this->err_msg(-1007,'The category not exist!');
|
||
}
|
||
//如果链接标题为空
|
||
if( empty($title) ){
|
||
$this->err_msg(-1008,'The title cannot be empty!');
|
||
}
|
||
//链接不能为空
|
||
if( empty($url) ){
|
||
$this->err_msg(-1009,'URL cannot be empty!');
|
||
}
|
||
//通过正则匹配链接是否合法,支持http/https/ftp/magnet:?|ed2k|tcp/udp/thunder/rtsp/rtmp/sftp
|
||
$pattern = "/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|magnet:?|ed2k:\/\/|tcp:\/\/|udp:\/\/|thunder:\/\/|rtsp:\/\/|rtmp:\/\/|sftp:\/\/).+/";
|
||
// if( !filter_var($url, FILTER_VALIDATE_URL) ) {
|
||
// $this->err_msg(-1010,'URL is not valid!');
|
||
// }
|
||
if ( !preg_match($pattern,$url) ) {
|
||
$this->err_msg(-1010,'URL is not valid!');
|
||
}
|
||
//备用链接不合法
|
||
if ( ( !empty($url_standby) ) && ( !preg_match($pattern, $url_standby) ) ) {
|
||
$this->err_msg(-1010,'URL is not valid!');
|
||
}
|
||
return true;
|
||
}
|
||
/**
|
||
* 查询分类目录
|
||
*/
|
||
public function category_list($page,$limit){
|
||
$token = @$_POST['token'];
|
||
$offset = ($page - 1) * $limit;
|
||
//如果成功登录,则查询所有
|
||
if( $this->is_login() ){
|
||
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = a.fid LIMIT 1) AS fname FROM on_categorys as a ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
|
||
//统计总数
|
||
$count = $this->db->count('on_categorys','*');
|
||
}
|
||
//如果存在token,则验证
|
||
else if( !empty($token) ) {
|
||
$this->auth($token);
|
||
//查询所有分类
|
||
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = a.fid LIMIT 1) AS fname FROM on_categorys as a ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
|
||
//统计总数
|
||
$count = $this->db->count('on_categorys','*');
|
||
}
|
||
else{
|
||
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = a.fid LIMIT 1) AS fname FROM on_categorys as a WHERE property = 0 ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
|
||
//统计总数
|
||
$count = $this->db->count('on_categorys','*',[
|
||
"property" => 0
|
||
]);
|
||
}
|
||
|
||
//原生查询
|
||
$datas = $this->db->query($sql)->fetchAll();
|
||
$datas = [
|
||
'code' => 0,
|
||
'msg' => '',
|
||
'count' => $count,
|
||
'data' => $datas
|
||
];
|
||
exit(json_encode($datas));
|
||
}
|
||
/**
|
||
* 生成
|
||
*/
|
||
public function create_sk() {
|
||
//验证是否登录
|
||
$this->auth('');
|
||
$sk = md5(USER.USER.time());
|
||
|
||
$result = $this->set_option_bool('SecretKey',$sk);
|
||
if( $result ){
|
||
$datas = [
|
||
'code' => 0,
|
||
'data' => $sk
|
||
];
|
||
exit(json_encode($datas));
|
||
}
|
||
else{
|
||
$this->err_msg(-2000,'SecretKey生成失败!');
|
||
}
|
||
|
||
}
|
||
/**
|
||
* 查询链接
|
||
* 接收一个数组作为参数
|
||
*/
|
||
public function link_list($data){
|
||
$limit = $data['limit'];
|
||
$token = $data['token'];
|
||
$offset = ($data['page'] - 1) * $data['limit'];
|
||
$fid = @$data['category_id'];
|
||
|
||
//如果存在分类ID,则根据分类ID进行查询
|
||
if ($data['category_id'] != null) {
|
||
|
||
$cid_sql = "WHERE fid = $fid";
|
||
//统计链接总数
|
||
$count = $this->db->count('on_links','*',[
|
||
'fid' => $fid
|
||
]);
|
||
}
|
||
else{
|
||
//统计链接总数,没有分类ID的情况
|
||
$count = $this->db->count('on_links','*');
|
||
}
|
||
//如果成功登录,但token为空
|
||
if( ($this->is_login()) && (empty($token)) ){
|
||
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links ${cid_sql} ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
|
||
}
|
||
|
||
//如果token验证通过
|
||
elseif( (!empty($token)) && ($this->auth($token)) ) {
|
||
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links ${cid_sql} ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
|
||
}
|
||
//如果即没有登录成功,又没有token,则默认为游客
|
||
else{
|
||
$cid_sql = empty($fid) ? null : "AND fid = $fid";
|
||
if($cid_sql == null) {
|
||
//统计链接总数,不存在分类ID的情况
|
||
$count = $this->db->count('on_links','*',[ 'property' => 0 ]);
|
||
}
|
||
else{
|
||
//统计链接总数,存在分类ID的情况
|
||
$count = $this->db->count('on_links','*',[
|
||
'property' => 0,
|
||
'fid' => $fid
|
||
]);
|
||
}
|
||
|
||
$sql = "SELECT *,(SELECT name FROM on_categorys WHERE id = on_links.fid) AS category_name FROM on_links WHERE property = 0 ${cid_sql} ORDER BY weight DESC,id DESC LIMIT {$limit} OFFSET {$offset}";
|
||
}
|
||
|
||
//打印SQL
|
||
//echo $sql;
|
||
|
||
//如果查询的总数大于limit,则以limit为准
|
||
//$count = ( $count > $limit) ? $limit : $count;
|
||
|
||
//原生查询
|
||
$datas = $this->db->query($sql)->fetchAll();
|
||
$datas = [
|
||
'code' => 0,
|
||
'msg' => '',
|
||
'count' => $count,
|
||
'data' => $datas
|
||
];
|
||
exit(json_encode($datas));
|
||
}
|
||
/**
|
||
* 查询单个链接
|
||
* 此函数接收一个数组
|
||
*/
|
||
public function get_a_link($data) {
|
||
$id = $data['id'];
|
||
$token = $data['token'];
|
||
$link_info = $this->db->get("on_links","*",[
|
||
"id" => $id
|
||
]);
|
||
//打印链接信息
|
||
//var_dump($link_info);
|
||
//如果是公开链接,则直接返回
|
||
if ( $link_info['property'] == "0" ) {
|
||
$datas = [
|
||
'code' => 0,
|
||
'data' => $link_info
|
||
];
|
||
|
||
}
|
||
//如果是私有链接,并且认证通过
|
||
elseif( $link_info['property'] == "1" ) {
|
||
if ( ( $this->auth($token) ) || ( $this->is_login() ) ) {
|
||
$datas = [
|
||
'code' => 0,
|
||
'data' => $link_info
|
||
];
|
||
}
|
||
|
||
//exit(json_encode($datas));
|
||
}
|
||
//如果是其它情况,则显示为空
|
||
else{
|
||
$datas = [
|
||
'code' => 0,
|
||
'data' => []
|
||
];
|
||
//exit(json_encode($datas));
|
||
}
|
||
exit(json_encode($datas));
|
||
}
|
||
/**
|
||
* 查询单个分类信息
|
||
* 此函数接收一个数组
|
||
*/
|
||
public function get_a_category($data) {
|
||
$id = $data['id'];
|
||
$token = $data['token'];
|
||
|
||
$category_info = $this->db->get("on_categorys","*",[
|
||
"id" => $id
|
||
]);
|
||
|
||
//var_dump($category_info);
|
||
|
||
//如果是公开分类,则直接返回
|
||
if ( $category_info['property'] == "0" ) {
|
||
$datas = [
|
||
'code' => 0,
|
||
'data' => $category_info
|
||
];
|
||
|
||
}
|
||
//如果是私有链接,并且认证通过
|
||
elseif( $category_info['property'] == "1" ) {
|
||
if ( ( $this->auth($token) ) || ( $this->is_login() ) ) {
|
||
$datas = [
|
||
'code' => 0,
|
||
'data' => $category_info
|
||
];
|
||
}
|
||
|
||
//exit(json_encode($datas));
|
||
}
|
||
//如果是其它情况,则显示为空
|
||
else{
|
||
$datas = [
|
||
'code' => 0,
|
||
'data' => []
|
||
];
|
||
//exit(json_encode($datas));
|
||
}
|
||
exit(json_encode($datas));
|
||
}
|
||
/**
|
||
* 验证是否登录
|
||
*/
|
||
protected function is_login(){
|
||
$key = md5(USER.PASSWORD.'onenav');
|
||
//获取session
|
||
$session = $_COOKIE['key'];
|
||
//如果已经成功登录
|
||
if($session == $key) {
|
||
return true;
|
||
}
|
||
else{
|
||
return false;
|
||
}
|
||
}
|
||
/**
|
||
* 获取链接信息
|
||
*/
|
||
public function get_link_info($token,$url){
|
||
$this->auth($token);
|
||
//检查链接是否合法
|
||
$pattern = "/^(http:\/\/|https:\/\/).*/";
|
||
//链接不合法
|
||
if( empty($url) ) {
|
||
$this->err_msg(-2000,'URL不能为空!');
|
||
}
|
||
if( !preg_match($pattern,$url) ){
|
||
$this->err_msg(-1010,'只支持识别http/https协议的链接!');
|
||
}
|
||
//获取网站标题
|
||
$c = curl_init();
|
||
curl_setopt($c, CURLOPT_URL, $url);
|
||
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
|
||
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
|
||
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);
|
||
//设置超时时间
|
||
curl_setopt($c , CURLOPT_TIMEOUT, 10);
|
||
$data = curl_exec($c);
|
||
curl_close($c);
|
||
$pos = strpos($data,'utf-8');
|
||
if($pos===false){$data = iconv("gbk","utf-8",$data);}
|
||
preg_match("/<title>(.*)<\/title>/i",$data, $title);
|
||
|
||
$link['title'] = $title[1];
|
||
|
||
//获取网站描述
|
||
$tags = get_meta_tags($url);
|
||
$link['description'] = $tags['description'];
|
||
|
||
$data = [
|
||
'code' => 0,
|
||
'data' => $link
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
/**
|
||
* 自定义js
|
||
*/
|
||
public function add_js($token,$content){
|
||
$this->auth($token);
|
||
//如果内容为空
|
||
// if( $content == '' ){
|
||
// $this->err_msg(-1013,'The content cannot be empty!');
|
||
// }
|
||
//写入文件
|
||
try{
|
||
file_put_contents("data/extend.js",$content);
|
||
$data = [
|
||
'code' => 0,
|
||
'data' => 'success'
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
catch(Exception $e){
|
||
$this->err_msg(-2000,$e->getMessage());
|
||
}
|
||
}
|
||
/**
|
||
* 获取IP
|
||
*/
|
||
//获取访客IP
|
||
protected function getIP() {
|
||
if (getenv('HTTP_CLIENT_IP')) {
|
||
$ip = getenv('HTTP_CLIENT_IP');
|
||
}
|
||
elseif (getenv('HTTP_X_FORWARDED_FOR')) {
|
||
$ip = getenv('HTTP_X_FORWARDED_FOR');
|
||
}
|
||
elseif (getenv('HTTP_X_FORWARDED')) {
|
||
$ip = getenv('HTTP_X_FORWARDED');
|
||
}
|
||
elseif (getenv('HTTP_FORWARDED_FOR')) {
|
||
$ip = getenv('HTTP_FORWARDED_FOR');
|
||
}
|
||
elseif (getenv('HTTP_FORWARDED')) {
|
||
$ip = getenv('HTTP_FORWARDED');
|
||
}
|
||
else {
|
||
$ip = $_SERVER['REMOTE_ADDR'];
|
||
}
|
||
return $ip;
|
||
}
|
||
|
||
/**
|
||
* name:检查弱密码
|
||
*/
|
||
public function check_weak_password($token){
|
||
$this->auth($token);
|
||
//如果用户名、密码为初始密码,则提示修改
|
||
if ( ( USER == 'xiaoz' ) && ( PASSWORD == 'xiaoz.me' ) ) {
|
||
$this->err_msg(-1,'Weak password!');
|
||
}
|
||
}
|
||
/**
|
||
* 获取SQL更新列表
|
||
* 循环读取db/sql/目录下的.sql文件
|
||
*/
|
||
public function get_sql_update_list($data) {
|
||
//鉴权
|
||
if( !$this->is_login() ) {
|
||
$this->err_msg(-1002,'Authorization failure!');
|
||
}
|
||
//待更新的数据库文件目录
|
||
$sql_dir = 'db/sql/';
|
||
//待更新的sql文件列表,默认为空
|
||
$sql_files_all = [];
|
||
//打开一个目录,读取里面的文件列表
|
||
if (is_dir($sql_dir)){
|
||
if ($dh = opendir($sql_dir)){
|
||
while (($file = readdir($dh)) !== false){
|
||
//排除.和..
|
||
if ( ($file != ".") && ($file != "..") ) {
|
||
array_push($sql_files_all,$file);
|
||
|
||
}
|
||
}
|
||
//关闭句柄
|
||
closedir($dh);
|
||
}
|
||
}
|
||
//判断数据库日志表是否存在
|
||
$sql = "SELECT count(*) AS num FROM sqlite_master WHERE type='table' AND name='on_db_logs'";
|
||
//查询结果
|
||
$q_result = $this->db->query($sql)->fetchAll();
|
||
//如果数量为0,则说明on_db_logs这个表不存在,需要提前导入
|
||
$num = intval($q_result[0]['num']);
|
||
if ( $num === 0 ) {
|
||
$data = [
|
||
"code" => 0,
|
||
"data" => ['on_db_logs.sql']
|
||
];
|
||
exit(json_encode($data));
|
||
}else{
|
||
//如果不为0,则需要查询数据库更新表里面的数据进行差集比对
|
||
$get_on_db_logs = $this->db->select("on_db_logs",[
|
||
"sql_name"
|
||
],[
|
||
"status" => "TRUE"
|
||
]);
|
||
//声明一个空数组,存储已更新的数据库列表
|
||
$already_dbs = [];
|
||
foreach ($get_on_db_logs as $value) {
|
||
array_push($already_dbs,$value['sql_name']);
|
||
}
|
||
|
||
//array_diff() 函数返回两个数组的差集数组
|
||
$diff_result = array_diff($sql_files_all,$already_dbs);
|
||
//去掉键
|
||
$diff_result = array_values($diff_result);
|
||
sort($diff_result);
|
||
|
||
$data = [
|
||
"code" => 0,
|
||
"data" => $diff_result
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
|
||
}
|
||
/**
|
||
* 执行SQL更新语句,只执行单条更新
|
||
*/
|
||
public function exe_sql($data) {
|
||
//鉴权
|
||
if( !$this->is_login() ) {
|
||
$this->err_msg(-1002,'Authorization failure!');
|
||
}
|
||
//数据库sql目录
|
||
$sql_dir = 'db/sql/';
|
||
$name = $data['name'];
|
||
//查询sql是否已经执行过
|
||
$count = $this->db->count("on_db_logs",[
|
||
"sql_name" => $name
|
||
]);
|
||
if( $count >= 1 ) {
|
||
$this->err_msg(-2000,$name."已经更新过!");
|
||
}
|
||
$sql_name = $sql_dir.$name;
|
||
//如果文件不存在,直接返回错误
|
||
if ( !file_exists($sql_name) ) {
|
||
$this->err_msg(-2000,$name.'不存在!');
|
||
}
|
||
//读取需要更新的SQL内容
|
||
try {
|
||
//读取一个SQL文件,并将单个SQL文件拆分成单条SQL语句循环执行
|
||
switch ($name) {
|
||
case '20220414.sql':
|
||
$sql_content = explode("\n",file_get_contents($sql_name));
|
||
break;
|
||
default:
|
||
$sql_content = explode(';',file_get_contents($sql_name));
|
||
break;
|
||
}
|
||
|
||
//计算SQL总数
|
||
$num = count($sql_content) - 1;
|
||
//初始数量设置为0
|
||
$init_num = 0;
|
||
//遍历执行SQL语句
|
||
foreach ($sql_content as $sql) {
|
||
//如果SQL为空,则跳过此次循环不执行
|
||
if( empty($sql) ) {
|
||
continue;
|
||
}
|
||
$result = $this->db->query($sql);
|
||
//只要单条SQL执行成功了就增加初始数量
|
||
if( $result ) {
|
||
$init_num++;
|
||
}
|
||
}
|
||
|
||
//无论最后结果如何,都将更新信息写入数据库
|
||
$insert_re = $this->db->insert("on_db_logs",[
|
||
"sql_name" => $name,
|
||
"update_time" => time(),
|
||
"status" => "TRUE"
|
||
]);
|
||
if( $insert_re ) {
|
||
$data = [
|
||
"code" => 0,
|
||
"data" => $name."更新完成!总数${num},成功:${init_num}"
|
||
];
|
||
exit(json_encode($data));
|
||
}
|
||
else {
|
||
$this->err_msg(-2000,$name."更新失败,请人工检查!");
|
||
}
|
||
|
||
} catch(Exception $e){
|
||
$this->err_msg(-2000,$e->getMessage());
|
||
}
|
||
}
|
||
/**
|
||
* 更新option
|
||
*/
|
||
public function set_option($key,$value = '') {
|
||
$key = htmlspecialchars(trim($key));
|
||
//如果key是空的
|
||
if( empty($key) ) {
|
||
$this->err_msg(-2000,'键不能为空!');
|
||
}
|
||
//鉴权
|
||
if( !$this->is_login() ) {
|
||
$this->err_msg(-1002,'Authorization failure!');
|
||
}
|
||
|
||
$count = $this->db->count("on_options", [
|
||
"key" => $key
|
||
]);
|
||
|
||
//如果数量是0,则插入,否则就是更新
|
||
if( $count === 0 ) {
|
||
try {
|
||
$this->db->insert("on_options",[
|
||
"key" => $key,
|
||
"value" => $value
|
||
]);
|
||
$data = [
|
||
"code" => 0,
|
||
"data" => "设置成功!"
|
||
];
|
||
exit(json_encode($data));
|
||
} catch (\Throwable $th) {
|
||
$this->err_msg(-2000,$th);
|
||
}
|
||
}
|
||
//更新数据
|
||
else if( $count === 1 ) {
|
||
try {
|
||
$this->db->update("on_options",[
|
||
"value" => $value
|
||
],[
|
||
"key" => $key
|
||
]);
|
||
$data = [
|
||
"code" => 0,
|
||
"data" => "设置已更新!"
|
||
];
|
||
exit(json_encode($data));
|
||
} catch (\Throwable $th) {
|
||
$this->err_msg(-2000,$th);
|
||
}
|
||
}
|
||
|
||
}
|
||
/**
|
||
* 更新option,返回BOOL值
|
||
*/
|
||
protected function set_option_bool($key,$value = '') {
|
||
$key = htmlspecialchars(trim($key));
|
||
//如果key是空的
|
||
if( empty($key) ) {
|
||
return FALSE;
|
||
}
|
||
|
||
$count = $this->db->count("on_options", [
|
||
"key" => $key
|
||
]);
|
||
|
||
//如果数量是0,则插入,否则就是更新
|
||
if( $count === 0 ) {
|
||
try {
|
||
$this->db->insert("on_options",[
|
||
"key" => $key,
|
||
"value" => $value
|
||
]);
|
||
$data = [
|
||
"code" => 0,
|
||
"data" => "设置成功!"
|
||
];
|
||
return TRUE;
|
||
} catch (\Throwable $th) {
|
||
return FALSE;
|
||
}
|
||
}
|
||
//更新数据
|
||
else if( $count === 1 ) {
|
||
try {
|
||
$this->db->update("on_options",[
|
||
"value" => $value
|
||
],[
|
||
"key" => $key
|
||
]);
|
||
$data = [
|
||
"code" => 0,
|
||
"data" => "设置已更新!"
|
||
];
|
||
return TRUE;
|
||
} catch (\Throwable $th) {
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|