1.4 修复referer问题,添加删除日志功能

This commit is contained in:
Kokororin 2016-11-08 13:27:19 +08:00
parent c359f1b22c
commit a0ffc19ee1
5 changed files with 181 additions and 39 deletions

View File

@ -8,7 +8,6 @@ class Access_Extend
protected $request;
protected $pageSize;
protected $isDrop;
private static $_instance = null;
public $action;
public $title;
public $logs = array();
@ -283,4 +282,23 @@ class Access_Extend
}
}
public function isAdmin()
{
$hasLogin = Typecho_Widget::widget('Widget_User')->hasLogin();
if (!$hasLogin) {
return false;
}
$isAdmin = Typecho_Widget::widget('Widget_User')->pass('administrator', true);
return $isAdmin;
}
public function deleteLogs($ids)
{
foreach ($ids as $id) {
$this->db->query($this->db->delete($this->table)
->where('id = ?', $id)
);
}
}
}

View File

@ -4,11 +4,14 @@ class Access_Action implements Widget_Interface_Do
private $response;
private $request;
private $extend;
public function __construct()
{
$this->response = Typecho_Response::getInstance();
$this->request = Typecho_Request::getInstance();
require_once __DIR__ . '/Access.php';
$this->extend = new Access_Extend();
}
public function execute()
@ -21,9 +24,51 @@ class Access_Action implements Widget_Interface_Do
public function ip()
{
$ip = $this->request->get('ip');
$response = file_get_contents('http://ip.taobao.com/service/getIpInfo.php?ip=' . $ip);
exit($response);
$this->response->setContentType('application/json');
try {
$this->checkAuth();
$ip = $this->request->get('ip');
$response = file_get_contents('http://ip.taobao.com/service/getIpInfo.php?ip=' . $ip);
if (!$response) {
throw new Exception('HTTP request failed');
}
exit($response);
} catch (Exception $e) {
exit(Json::encode(array(
'code' => 100,
'message' => $e->getMessage(),
)));
}
}
public function deleteLogs()
{
$this->response->setContentType('application/json');
try {
$this->checkAuth();
$data = @file_get_contents('php://input');
$data = Json::decode($data, true);
if (!is_array($data)) {
throw new Exception('params invalid');
}
$this->extend->deleteLogs($data);
exit(Json::encode(array(
'code' => 0,
)));
} catch (Exception $e) {
exit(Json::encode(array(
'code' => 100,
'message' => $e->getMessage(),
)));
}
}
protected function checkAuth()
{
if (!$this->extend->isAdmin()) {
throw new Exception('Access Denied');
}
}
}

View File

@ -4,7 +4,7 @@
*
* @package Access
* @author Kokororin
* @version 1.3
* @version 1.4
* @link https://kotori.love
*/
class Access_Plugin implements Typecho_Plugin_Interface
@ -15,6 +15,7 @@ class Access_Plugin implements Typecho_Plugin_Interface
$msg = Access_Plugin::install();
Helper::addPanel(1, self::$panel, 'Access控制台', 'Access插件控制台', 'subscriber');
Helper::addRoute("access_ip", "/access/ip.json", "Access_Action", 'ip');
Helper::addRoute("access_delete_logs", "/access/log/delete", "Access_Action", 'deleteLogs');
Typecho_Plugin::factory('Widget_Archive')->header = array('Access_Plugin', 'start');
Typecho_Plugin::factory('admin/footer.php')->end = array('Access_Plugin', 'adminFooter');
return _t($msg);
@ -31,20 +32,27 @@ class Access_Plugin implements Typecho_Plugin_Interface
}
Helper::removePanel(1, self::$panel);
Helper::removeRoute("access_ip");
Helper::removeRoute("access_delete_logs");
}
public static function config(Typecho_Widget_Helper_Form $form)
{
$pageSize = new Typecho_Widget_Helper_Form_Element_Text(
'pageSize', null, '',
'pageSize', null, '10',
'分页数量', '每页显示的日志数量');
$isDrop = new Typecho_Widget_Helper_Form_Element_Radio(
'isDrop', array(
'0' => '删除',
'1' => '不删除',
), '', '删除数据表:', '请选择是否在禁用插件时,删除日志数据表');
), '1', '删除数据表:', '请选择是否在禁用插件时,删除日志数据表');
$canAnalytize = new Typecho_Widget_Helper_Form_Element_Radio(
'canAnalytize', array(
'0' => '不允许',
'1' => '允许',
), '1', '允许统计使用情况:', '请选择是否允许插件作者统计使用情况');
$form->addInput($pageSize);
$form->addInput($isDrop);
$form->addInput($canAnalytize);
}
public static function personalConfig(Typecho_Widget_Helper_Form $form)
@ -94,48 +102,42 @@ class Access_Plugin implements Typecho_Plugin_Interface
}
}
public static function hasLogin()
{
$cookieUid = Typecho_Cookie::get('__typecho_uid');
if (null !== $cookieUid) {
$db = Typecho_Db::get();
$user = $db->fetchRow($db->select()->from('table.users')
->where('uid = ?', intval($cookieUid))
->limit(1));
$cookieAuthCode = Typecho_Cookie::get('__typecho_authCode');
if ($user && Typecho_Common::hashValidate($user['authCode'], $cookieAuthCode)) {
return true;
}
Typecho_Cookie::delete('__typecho_uid');
Typecho_Cookie::delete('__typecho_authCode');
}
return false;
}
public static function start()
{
if (self::hasLogin()) {
require_once __DIR__ . '/Access.php';
$extend = new Access_Extend();
if ($extend->isAdmin()) {
return;
}
$config = Typecho_Widget::widget('Widget_Options')->plugin('Access');
$request = Typecho_Request::getInstance();
$ip = $request->getIp();
$url = $_SERVER['REQUEST_URI'];
$url = $request->getServer('REQUEST_URI');
if ($ip == null) {
$ip = 'UnKnow';
$ip = 'UnKnown';
}
$options = Typecho_Widget::widget('Widget_Options');
$timeStamp = $options->gmtTime;
$offset = $options->timezone - $options->serverTimezone;
$gtime = $timeStamp + $offset;
$db = Typecho_Db::get();
$referer = Typecho_Cookie::get('__typecho_access_referer');
if ($referer == null) {
$referer = $request->getReferer();
if (strpos($referer, rtrim(Helper::options()->siteUrl, '/')) !== false) {
$referer = null;
}
if ($referer != null) {
Typecho_Cookie::set('__typecho_access_referer', $referer);
}
}
$rows = array(
'ua' => $request->getAgent(),
'url' => $url,
'ip' => $ip,
'referer' => $request->getReferer(),
'referer' => $referer,
'referer_domain' => parse_url($request->getReferer(), PHP_URL_HOST),
'date' => $gtime,
);

View File

@ -8,7 +8,21 @@
* ip归属地使用淘宝API
* 管理员登录时不记录日志
* 查看来源页和来源域名排名
* 修复Referer记录错误的bug
* 添加删除日志的功能
### 使用须知
插件目录名请修改为Access
* 插件更新升级时,请先禁用插件后再上传
* 插件目录名请修改为Access
### 图示
![](https://kotori.love/usr/uploads/2015/12/4187563925.jpg)
![A75B8F39-C8B6-4CD2-AFFC-784B3E27B8A4.png](https://kotori.love/usr/uploads/2015/12/2019049143.png)
![](https://kotori.love/usr/uploads/2016/08/1564663056.png)
![](https://kotori.love/usr/uploads/2016/08/1121750290.png)
![BDEF004E-157E-4ADF-99C0-5EE65BDA61A6.png](https://kotori.love/usr/uploads/2016/11/3973345673.png)

View File

@ -31,7 +31,7 @@ $extend = new Access_Extend();
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些记录吗?'); ?>" href="javascript:alert('这个功能并没有开发呢')"><?php _e('删除'); ?></a></li>
<li><a data-action="delete" href="javascript:;"><?php _e('删除'); ?></a></li>
</ul>
</div>
</div>
@ -75,8 +75,8 @@ $extend = new Access_Extend();
<tbody>
<?php if(!empty($extend->logs['list'])): ?>
<?php foreach ($extend->logs['list'] as $log): ?>
<tr id="<?php echo $log['id']; ?>">
<td><input type="checkbox" value="<?php echo $log['id']; ?>" name="id[]"/></td>
<tr id="<?php echo $log['id']; ?>" data-id="<?php echo $log['id']; ?>">
<td><input type="checkbox" data-id="<?php echo $log['id']; ?>" value="<?php echo $log['id']; ?>" name="id[]"/></td>
<td><a target="_blank" href="<?php echo str_replace("%23", "#", $log['url']); ?>"><?php echo urldecode(str_replace("%23", "#", $log['url'])); ?></a></td>
<td><a data-action="ua" href="#" title="<?php echo $log['ua'];?>"><?php echo $extend->parseUA($log['ua']); ?></a></td>
<td><a data-action="ip" data-ip="<?php echo $log['ip']; ?>" href="#"><?php echo $log['ip']; ?></a></td>
@ -102,7 +102,7 @@ $extend = new Access_Extend();
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些记录吗?'); ?>" href="javascript:alert('这个功能并没有开发呢')"><?php _e('删除'); ?></a></li>
<li><a data-action="delete" href="javascript:;"><?php _e('删除'); ?></a></li>
</ul>
</div>
</div>
@ -265,18 +265,18 @@ $(document).ready(function() {
dataType: 'json',
data: {ip: $(this).data('ip')},
success: function(data) {
if (data.code == 0){
if (data.code == 0) {
swal({
title: "IP查询成功",
text: data.data.country + data.data.area + data.data.city + data.data.country + data.data.isp,
type: "info",
type: "success",
confirmButtonText: "OK"
});
} else {
swal({
title: "IP查询失败",
text: '接口返回状态码错误',
type: "info",
type: "warning",
confirmButtonText: "OK"
});
}
@ -285,13 +285,61 @@ $(document).ready(function() {
swal({
title: "IP查询失败",
text: '网络异常或PHP环境配置异常',
type: "info",
type: "warning",
confirmButtonText: "OK"
});
}
});
return false;
});
$('.dropdown-menu a[data-action="delete"]').click(function() {
swal({
title: "你确定?",
text: "你确认要删除这些记录吗?",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "是的",
cancelButtonText: "算啦",
closeOnConfirm: false
}, function() {
var ids = [];
$('.typecho-list-table input[type="checkbox"]').each(function(index, elem) {
if (elem.checked) {
ids.push($(elem).data('id'));
}
});
if (ids.length == 0) {
return swal("错误", "你并没有勾选任何内容", "warning");
}
$.ajax({
url: '<?php echo rtrim(Helper::options()->index, '/').'/access/log/delete';?>',
method: 'post',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(ids),
success: function(data) {
if (data.code == 0) {
swal("删除成功", "所选记录已删除", "success");
$.each(ids, function(index, elem) {
$('.typecho-list-table tbody tr[data-id="' + elem + '"]').fadeOut(500).remove();
});
} else {
swal({
title: "错误",
text: '发生错误了',
type: "warning",
confirmButtonText: "OK"
});
}
}
});
});
var t = $(this);
t.parents('.dropdown-menu').hide().prev().removeClass('active');
});
});
</script>
<script src="<?php $options->pluginUrl('Access/lib/sweetalert/sweetalert.min.js')?>"></script>
@ -346,6 +394,21 @@ $(document).ready(function() {
</script>
<?php endif;?>
<?php if (Typecho_Widget::widget('Widget_Options')->plugin('Access') == 1):?>
<script type="text/javascript">
var _paq = _paq || [];
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//analytics.kotori.love/";
_paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['setSiteId', '3']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<noscript><p><img src="//analytics.kotori.love/piwik.php?idsite=3" style="border:0;" alt="" /></p></noscript>
<?php endif;?>
<?php
include 'footer.php';
?>