@@ -16,9 +16,6 @@ if (preg_match("#PHP (.*) Development Server#", $_SERVER['SERVER_SOFTWARE'])) { | |||
} | |||
require_once(dirname(__FILE__)."/config.php"); | |||
require_once(DEDEINC.'/dedetag.class.php'); | |||
$defaultIcoFile = DEDEDATA.'/admin/quickmenu.txt'; | |||
$myIcoFile = DEDEDATA.'/admin/quickmenu-'.$cuserLogin->getUserID().'.txt'; | |||
if (!file_exists($myIcoFile)) $myIcoFile = $defaultIcoFile; | |||
require(DEDEADMIN.'/inc/inc_menu_map.php'); | |||
include(DEDEADMIN.'/templets/index.htm'); | |||
exit(); |
@@ -11,9 +11,6 @@ | |||
require(dirname(__FILE__).'/config.php'); | |||
require(DEDEINC.'/image.func.php'); | |||
require(DEDEINC.'/dedetag.class.php'); | |||
$defaultIcoFile = DEDEDATA.'/admin/quickmenu.txt'; | |||
$myIcoFile = DEDEDATA.'/admin/quickmenu-'.$cuserLogin->getUserID().'.txt'; | |||
if (!file_exists($myIcoFile)) $myIcoFile = $defaultIcoFile; | |||
//默认主页 | |||
if (empty($dopost)) { | |||
require(DEDEINC.'/inc/inc_fun_funAdmin.php'); | |||
@@ -30,92 +27,6 @@ if (empty($dopost)) { | |||
include DedeInclude('templets/index_body.htm'); | |||
exit(); | |||
} | |||
/*----------------------- | |||
增加新项 | |||
function _AddNew() { } | |||
-------------------------*/ | |||
else if ($dopost == 'addnew') { | |||
if (empty($link) || empty($title)) { | |||
ShowMsg("链接网址或标题不能为空", "-1"); | |||
exit(); | |||
} | |||
$fp = fopen($myIcoFile, 'r'); | |||
$oldct = trim(fread($fp, filesize($myIcoFile))); | |||
fclose($fp); | |||
$link = preg_replace("#['\"]#", '`', $link); | |||
$title = preg_replace("#['\"]#", '`', $title); | |||
$ico = preg_replace("#['\"]#", '`', $ico); | |||
$oldct .= "\r\n<menu:item ico=\"{$ico}\" link=\"{$link}\" title=\"{$title}\">"; | |||
$myIcoFileTrue = DEDEDATA.'/admin/quickmenu-'.$cuserLogin->getUserID().'.txt'; | |||
$fp = fopen($myIcoFileTrue, 'w'); | |||
fwrite($fp, $oldct); | |||
fclose($fp); | |||
ShowMsg("成功增加一个项目", "index_body.php?".time()); | |||
exit(); | |||
} | |||
/*--------------------------- | |||
保存修改的项 | |||
function _EditSave() { } | |||
----------------------------*/ | |||
else if ($dopost == 'editsave') { | |||
$quickmenu = stripslashes($quickmenu); | |||
$myIcoFileTrue = DEDEDATA.'/admin/quickmenu-'.$cuserLogin->getUserID().'.txt'; | |||
$fp = fopen($myIcoFileTrue, 'w'); | |||
fwrite($fp, $quickmenu); | |||
fclose($fp); | |||
ShowMsg("成功修改快捷操作项目", "index_body.php?".time()); | |||
exit(); | |||
} | |||
/*--------------------------- | |||
保存修改的项 | |||
function _EditSave() { } | |||
----------------------------*/ | |||
else if ($dopost == 'movesave') { | |||
$movedata = str_replace('\\', "", $sortorder); | |||
$movedata = json_decode($movedata, TRUE); | |||
$movedata = serialize($movedata); | |||
$myIcoFileTrue = DEDEDATA.'/admin/move-'.$cuserLogin->getUserID().'.txt'; | |||
$fp = fopen($myIcoFileTrue, 'w'); | |||
fwrite($fp, $movedata); | |||
fclose($fp); | |||
} | |||
/*----------------------------- | |||
显示修改表单 | |||
function _EditShow() { } | |||
-----------------------------*/ | |||
else if ($dopost == 'editshow') { | |||
$fp = fopen($myIcoFile, 'r'); | |||
$oldct = trim(fread($fp, filesize($myIcoFile))); | |||
fclose($fp); | |||
?> | |||
<form name="editform" action="index_body.php" method="post"> | |||
<input type="hidden" name="dopost" value="editsave"> | |||
<table width="100%" border="0" cellspacing="0" cellpadding="0"> | |||
<tr> | |||
<td height="30" background="images/tbg.gif"> | |||
<div style="float:left;margin-left:10px">修改快捷操作项</div> | |||
<div style="float:right;padding:2px 10px 0 0"> | |||
<a href="javascript:CloseTab('editTab')"><img src="images/close.gif"></a> | |||
</div> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td style="height:10px;border-top:1px solid #8DA659"></td> | |||
</tr> | |||
<tr> | |||
<td align="center"><textarea name="quickmenu" rows="10" cols="50"><?php echo $oldct; ?></textarea></td> | |||
</tr> | |||
<tr> | |||
<td height="36" align="center"> | |||
<input type="submit" name="Submit" value="保存项目" class="np coolbg" style="width:80px;cursor:pointer"> | |||
<input type="reset" name="reset" value="重设" class="np coolbg" style="width:50px;cursor:pointer"> | |||
</td> | |||
</tr> | |||
</table> | |||
</form> | |||
<?php | |||
exit(); | |||
} | |||
/*--------------------------------- | |||
载入右边内容 | |||
function _getRightSide() { } | |||
@@ -247,5 +158,17 @@ exit; | |||
)); | |||
} | |||
} | |||
} | |||
} elseif ($dopost == 'get_statistics') { | |||
require_once(DEDEINC."/libraries/statistics.class.php"); | |||
//获取统计信息 | |||
$sdate = empty($sdate) ? 0 : intval($sdate); | |||
$stat = new DedeStatistics; | |||
$rs = $stat->GetInfoByDate($sdate); | |||
echo json_encode(array( | |||
"code" => 200, | |||
"msg" => "", | |||
"result" => $rs, | |||
)); | |||
exit; | |||
} | |||
?> |
@@ -90,25 +90,6 @@ | |||
<iframe src="index_body.php" id="main" name="main" frameborder="0"></iframe> | |||
</div> | |||
</div> | |||
<div class="qucikmenu" id="qucikmenu"> | |||
<ul> | |||
<?php | |||
$dtp = new DedeTagparse(); | |||
$dtp->SetNameSpace('menu','<','>'); | |||
$dtp->LoadTemplet($myIcoFile); | |||
if(is_array($dtp->CTags)) | |||
{ | |||
foreach($dtp->CTags as $ctag) | |||
{ | |||
$title = $ctag->GetAtt('title'); | |||
$ico = $ctag->GetAtt('ico'); | |||
$link = $ctag->GetAtt('link'); | |||
echo "<li><a target='main' href='{$link}'>{$title}</a></li>"; | |||
} | |||
} | |||
?> | |||
</ul> | |||
</div> | |||
<script> | |||
function JumpFrame(url1, url2) { | |||
jQuery('#menufra').get(0).src = url1; | |||
@@ -12,18 +12,74 @@ | |||
<script src="../static/js/jquery.js"></script> | |||
<script src="../static/js/bootstrap.bundle.js"></script> | |||
<script src="../static/js/webajax.js"></script> | |||
<script src="../static/js/chart.min.js"></script> | |||
<script src="js/indexbody.js"></script> | |||
<script src="js/main.js"></script> | |||
<style> | |||
.row{display:flex;flex-wrap:wrap} | |||
.row>[class*='col-']{display:flex;flex-direction:column} | |||
.table{margin-bottom:0} | |||
.stattable{width: 100%;} | |||
table.stattable td { | |||
padding: 0 5px; | |||
height: 25px; | |||
line-height: 25px; | |||
border-bottom: 1px solid #f0f0f0; | |||
font-size: 12px; | |||
text-align: right; | |||
} | |||
table.stattable td.today { | |||
font-size: 12px; | |||
color: #000; | |||
height: 25px; | |||
line-height: 25px; | |||
font-weight: 700; | |||
} | |||
</style> | |||
</head> | |||
<body> | |||
<div class="container-fluid"> | |||
<div class="row"> | |||
<div id="__testEvn" class="col-md-12"></div> | |||
<div class="col-md-12 mt-3"> | |||
<div class="card"> | |||
<div class="card-header">流量统计 <a title="点击查看流量统计图" href="#statChart"><i class="fa fa-line-chart" aria-hidden="true"></i></a></div> | |||
<div class="card-body"> | |||
<table class="stattable"> | |||
<tbody> | |||
<tr class="title"> | |||
<td width="10%"></td> | |||
<td width="20%">浏览次数(PV)</td> | |||
<td width="20%">独立访客(UV)</td> | |||
<td width="20%">IP</td> | |||
<td width="18%" >访问次数</td> | |||
</tr> | |||
<tr class="bg-white"> | |||
<td class="today">今日</td> | |||
<td class="today" id="today_pv">...</td> | |||
<td class="today" id="today_uv">...</td> | |||
<td class="today" id="today_ip">...</td> | |||
<td class="today" id="today_vv">...</td> | |||
</tr> | |||
<tr class="bg-white"> | |||
<td class="">昨日</td> | |||
<td id="yestoday_pv">...</td> | |||
<td id="yestoday_uv">...</td> | |||
<td id="yestoday_ip">...</td> | |||
<td id="yestoday_vv">...</td> | |||
</tr> | |||
<tr class="bg-white grey9 hide" style="display: table-row;"> | |||
<td class="">历史累计</td> | |||
<td id="total_pv">...</td> | |||
<td id="total_uv">...</td> | |||
<td id="total_ip">...</td> | |||
<td id="total_vv">...</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-md-6 mt-3 updatenews"> | |||
<div class="card"> | |||
<div class="card-header">更新消息</div> | |||
@@ -44,27 +100,6 @@ | |||
<div class="card-body" id="_systeminfo">正在载入</div> | |||
</div> | |||
</div> | |||
<div class="col-md-6 mt-3"> | |||
<div class="card"> | |||
<div class="card-header">快捷操作<span class="float-right"><a href="javascript:AddNew()" class="btn btn-success btn-sm">新增</a><a href="javascript:ListAll()" class="btn btn-success btn-sm">管理</a></span></div> | |||
<div class="card-body"> | |||
<ul class="nav"> | |||
<?php | |||
$dtp = new DedeTagparse(); | |||
$dtp->SetNameSpace('menu','<','>'); | |||
$dtp->LoadTemplet($myIcoFile); | |||
if(is_array($dtp->CTags)){ | |||
foreach($dtp->CTags as $ctag){ | |||
$title = $ctag->GetAtt('title'); | |||
$link = $ctag->GetAtt('link'); | |||
echo "<a href='{$link}' class='btn btn-success btn-sm'>{$title}</a>"; | |||
} | |||
} | |||
?> | |||
</ul> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-md-6 mt-3"> | |||
<div class="card"> | |||
<div class="card-header">信息统计</div> | |||
@@ -138,9 +173,17 @@ | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-md-6 mt-3"> | |||
<div class="card"> | |||
<div class="card-header"><a name="statChart">流量统计图</a></div> | |||
<div class="card-body"> | |||
<canvas id="statChart" style="height: 260px;"></canvas> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="footer"> | |||
<div class="footer mt-2"> | |||
<div id="loaddiv" style="display:none"> | |||
<p align="center"><img src="images/loadinglit.gif">请稍后,正在下载更新文件列表</p> | |||
</div> | |||
@@ -188,6 +231,21 @@ | |||
}); | |||
</script> | |||
<script> | |||
Date.prototype.Format = function (fmt) { //author: meizz | |||
var o = { | |||
"M+": this.getMonth() + 1, //月份 | |||
"d+": this.getDate(), //日 | |||
"h+": this.getHours(), //小时 | |||
"m+": this.getMinutes(), //分 | |||
"s+": this.getSeconds(), //秒 | |||
"q+": Math.floor((this.getMonth() + 3) / 3), //季度 | |||
"S": this.getMilliseconds() //毫秒 | |||
}; | |||
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); | |||
for (var k in o) | |||
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); | |||
return fmt; | |||
} | |||
var dedebizInfo; | |||
function ViewDedeBIZ(){ | |||
console.log(dedebizInfo); | |||
@@ -280,11 +338,128 @@ | |||
} | |||
}); | |||
} | |||
function LoadStat() { | |||
$.get("index_body.php?dopost=get_statistics", function(data){ | |||
let rsp = JSON.parse(data); | |||
if (rsp.code == 200) { | |||
var tpv = parseInt(rsp.result.pv); | |||
var tuv = parseInt(rsp.result.uv); | |||
var tip = parseInt(rsp.result.ip); | |||
var tvv = parseInt(rsp.result.vv); | |||
$("#today_pv").html(tpv); | |||
$("#today_uv").html(tuv); | |||
$("#today_ip").html(tip); | |||
$("#today_vv").html(tvv); | |||
$.get("index_body.php?dopost=get_statistics&sdate=-1", function(data){ | |||
let rsp = JSON.parse(data); | |||
if (rsp.code == 200) { | |||
$("#total_pv").html(parseInt(rsp.result.pv)+tpv); | |||
$("#total_uv").html(parseInt(rsp.result.uv)+tuv); | |||
$("#total_ip").html(parseInt(rsp.result.ip)+tip); | |||
$("#total_vv").html(parseInt(rsp.result.vv)+tvv); | |||
} | |||
}); | |||
} | |||
}); | |||
var d = new Date(); | |||
d.setDate(d.getDate() - 1); | |||
var s = d.Format("yyyy-MM-dd"); | |||
s = s.replaceAll("-",""); | |||
$.get("index_body.php?dopost=get_statistics&sdate="+s, function(data){ | |||
let rsp = JSON.parse(data); | |||
if (rsp.code == 200) { | |||
$("#yestoday_pv").html(rsp.result.pv); | |||
$("#yestoday_uv").html(rsp.result.uv); | |||
$("#yestoday_ip").html(rsp.result.ip); | |||
$("#yestoday_vv").html(rsp.result.vv); | |||
} | |||
}); | |||
} | |||
async function LoadStatChart() { | |||
const ctx = document.getElementById('statChart').getContext('2d'); | |||
let labels = []; | |||
let pvs = []; | |||
let ips = []; | |||
let uvs = []; | |||
let vvs = []; | |||
for (let i = 15; i > 0; i--) { | |||
var d = new Date(); | |||
d.setDate(d.getDate() - i); | |||
var s = d.Format("yyyy-MM-dd"); | |||
labels.push(d.Format("MM-dd")); | |||
s = s.replaceAll("-",""); | |||
let resp = await fetch("index_body.php?dopost=get_statistics&sdate="+s); | |||
let data = await resp.json(); | |||
if (data.code == 200) { | |||
pvs.push(typeof data.result.pv=="undefined"? 0 : data.result.pv); | |||
ips.push(typeof data.result.ip=="undefined"? 0 : data.result.ip); | |||
uvs.push(typeof data.result.uv=="undefined"? 0 : data.result.uv); | |||
vvs.push(typeof data.result.vv=="undefined"? 0 : data.result.vv); | |||
} | |||
} | |||
console.log(pvs); | |||
console.log(ips); | |||
console.log(uvs); | |||
console.log(vvs); | |||
const myChart = new Chart(ctx, { | |||
type: 'line', | |||
options: { | |||
responsive: true, | |||
plugins: { | |||
legend: { | |||
position: 'top', | |||
}, | |||
title: { | |||
display: true, | |||
text: '<?php echo $cfg_webname; ?>流量统计图' | |||
} | |||
} | |||
}, | |||
data: { | |||
labels: labels, | |||
datasets: [{ | |||
label: 'IP', | |||
data: ips, | |||
borderColor: 'rgba(255, 99, 132, 1)', | |||
backgroundColor :'rgba(255, 99, 132, 0.2)', | |||
borderWidth: 1 | |||
}, | |||
{ | |||
label: 'PV', | |||
data: pvs, | |||
borderColor: 'rgba(54, 162, 235, 1)', | |||
backgroundColor :'rgba(54, 162, 235, 0.2)', | |||
borderWidth: 1 | |||
},{ | |||
label: 'UV', | |||
data: uvs, | |||
borderColor: 'rgba(255, 206, 86, 1)', | |||
backgroundColor: 'rgba(255, 206, 86, 0.2)', | |||
borderWidth: 1 | |||
},{ | |||
label: '访问次数', | |||
data: vvs, | |||
borderColor: 'rgba(75, 192, 192, 1)', | |||
backgroundColor: 'rgba(75, 192, 192, 0.2)', | |||
borderWidth: 1 | |||
} | |||
] | |||
}, | |||
}); | |||
} | |||
$(document).ready(function(){ | |||
LoadServer(); | |||
LoadStat(); | |||
LoadStatChart(); | |||
setInterval(function(){ | |||
LoadServer(); | |||
}, 5000) | |||
}, 60000) | |||
}); | |||
</script> | |||
</body> |
@@ -0,0 +1,28 @@ | |||
<?php | |||
/** | |||
* | |||
* 统计程序 | |||
* | |||
* @version $Id: statistics.php$ | |||
* @package DedeBIZ.Site | |||
* @copyright Copyright (c) 2022, DedeBIZ.COM | |||
* @license https://www.dedebiz.com/license | |||
* @link https://www.dedebiz.com | |||
*/ | |||
require_once(dirname(__FILE__)."/../system/common.inc.php"); | |||
require_once(DEDEINC."/libraries/statistics.class.php"); | |||
if (empty($dopost)) $dopost = ''; | |||
$stat = new DedeStatistics; | |||
if ($dopost == "stat") { | |||
$rs = $stat->Record(); | |||
$result = array( | |||
"code" => 200, | |||
"data" => "success", | |||
); | |||
echo json_encode($result); | |||
exit; | |||
} | |||
$v = $stat->GetStat(); | |||
echo $v; |
@@ -17,7 +17,7 @@ if(file_exists(INSLOCKFILE)) | |||
$verMsg = 'V6'; | |||
$dfDbname = 'DedeBIZ'; | |||
$cfg_version_detail = '6.1.6'; //详细版本号 | |||
$cfg_version_detail = '6.1.7beta'; //详细版本号 | |||
$errmsg = ''; | |||
if (version_compare(PHP_VERSION, '8.0.0', '>=')) { | |||
mysqli_report(MYSQLI_REPORT_OFF); | |||
@@ -50,13 +50,14 @@ class Archives | |||
*/ | |||
function __construct($aid) | |||
{ | |||
global $dsql; | |||
global $dsql,$envs; | |||
$this->IsError = FALSE; | |||
$this->ArcID = $aid; | |||
$this->PreNext = array(); | |||
$this->dsql = $dsql; | |||
$query = "SELECT channel,typeid FROM `#@__arctiny` WHERE id='$aid' "; | |||
$arr = $this->dsql->GetOne($query); | |||
$envs['url_type'] = 2; | |||
if (!is_array($arr)) { | |||
$this->IsError = TRUE; | |||
} else { | |||
@@ -50,7 +50,8 @@ class ListView | |||
*/ | |||
function __construct($typeid, $uppage = 1) | |||
{ | |||
global $dsql; | |||
global $dsql,$envs; | |||
$envs['url_type'] = 1; | |||
$this->TypeID = $typeid; | |||
$this->dsql = &$dsql; | |||
$this->CrossID = ''; | |||
@@ -76,7 +76,7 @@ class SearchView | |||
$kwtype = 1, | |||
$mid = 0 | |||
) { | |||
global $cfg_search_max, $cfg_search_maxrc, $cfg_search_time; | |||
global $cfg_search_max, $cfg_search_maxrc, $cfg_search_time,$envs; | |||
if (empty($upagesize)) { | |||
$upagesize = 10; | |||
} | |||
@@ -131,6 +131,8 @@ class SearchView | |||
if ($this->PageNo == 1) { | |||
$this->dsql->ExecuteNoneQuery("UPDATE `#@__search_keywords` SET result='".$this->TotalResult."' WHERE keyword='".addslashes($keyword)."'; "); | |||
} | |||
$envs['url_type'] = 3; | |||
$envs['value'] = $keyword; | |||
} | |||
//php4构造函数 | |||
function SearchView( | |||
@@ -51,7 +51,8 @@ class SgListView | |||
*/ | |||
function __construct($typeid, $searchArr = array()) | |||
{ | |||
global $dsql; | |||
global $dsql,$envs; | |||
$envs['url_type'] = 1; | |||
$this->TypeID = $typeid; | |||
$this->dsql = $dsql; | |||
$this->CrossID = ''; | |||
@@ -45,7 +45,7 @@ class TagList | |||
*/ | |||
function __construct($keyword, $templet) | |||
{ | |||
global $dsql; | |||
global $dsql,$envs; | |||
$this->Templet = $templet; | |||
$this->Tag = $keyword; | |||
$this->dsql = $dsql; | |||
@@ -90,6 +90,8 @@ class TagList | |||
} | |||
$this->dtp->LoadTemplate($tempfile); | |||
$this->TempletsFile = preg_replace("#^".$GLOBALS['cfg_basedir']."#", '', $tempfile); | |||
$envs['url_type'] = 4; | |||
$envs['value'] = $keyword; | |||
} | |||
function TagPinyinExists($tag) | |||
{ | |||
@@ -192,7 +192,7 @@ $cfg_soft_dir = $cfg_medias_dir.'/soft'; | |||
$cfg_other_medias = $cfg_medias_dir.'/media'; | |||
//软件摘要信息,****请不要删除本项**** 否则系统无法正确接收系统漏洞或升级信息 | |||
$cfg_version = 'V6'; | |||
$cfg_version_detail = '6.1.6'; //详细版本号 | |||
$cfg_version_detail = '6.1.7beta'; //详细版本号 | |||
$cfg_soft_lang = 'utf-8'; | |||
$cfg_soft_public = 'base'; | |||
$cfg_softname = '织梦内容管理系统'; | |||
@@ -0,0 +1,416 @@ | |||
<?php | |||
if (!defined('DEDEINC')) exit('dedebiz'); | |||
require_once(DEDEINC."/libraries/crawlerdetect.class.php"); | |||
require_once(DEDEINC."/libraries/mobiledetect.class.php"); | |||
// copyright https://github.com/jenssegers/agent | |||
use BadMethodCallException; | |||
class Agent extends Mobile_Detect | |||
{ | |||
/** | |||
* List of desktop devices. | |||
* @var array | |||
*/ | |||
protected static $desktopDevices = [ | |||
'Macintosh' => 'Macintosh', | |||
]; | |||
/** | |||
* List of additional operating systems. | |||
* @var array | |||
*/ | |||
protected static $additionalOperatingSystems = [ | |||
'Windows' => 'Windows', | |||
'Windows NT' => 'Windows NT', | |||
'OS X' => 'Mac OS X', | |||
'Debian' => 'Debian', | |||
'Ubuntu' => 'Ubuntu', | |||
'Macintosh' => 'PPC', | |||
'OpenBSD' => 'OpenBSD', | |||
'Linux' => 'Linux', | |||
'ChromeOS' => 'CrOS', | |||
]; | |||
/** | |||
* List of additional browsers. | |||
* @var array | |||
*/ | |||
protected static $additionalBrowsers = [ | |||
'Opera Mini' => 'Opera Mini', | |||
'Opera' => 'Opera|OPR', | |||
'Edge' => 'Edge|Edg', | |||
'Coc Coc' => 'coc_coc_browser', | |||
'UCBrowser' => 'UCBrowser', | |||
'Vivaldi' => 'Vivaldi', | |||
'Chrome' => 'Chrome', | |||
'Firefox' => 'Firefox', | |||
'Safari' => 'Safari', | |||
'IE' => 'MSIE|IEMobile|MSIEMobile|Trident/[.0-9]+', | |||
'Netscape' => 'Netscape', | |||
'Mozilla' => 'Mozilla', | |||
'WeChat' => 'MicroMessenger', | |||
]; | |||
/** | |||
* List of additional properties. | |||
* @var array | |||
*/ | |||
protected static $additionalProperties = [ | |||
// Operating systems | |||
'Windows' => 'Windows NT [VER]', | |||
'Windows NT' => 'Windows NT [VER]', | |||
'OS X' => 'OS X [VER]', | |||
'BlackBerryOS' => ['BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'], | |||
'AndroidOS' => 'Android [VER]', | |||
'ChromeOS' => 'CrOS x86_64 [VER]', | |||
// Browsers | |||
'Opera Mini' => 'Opera Mini/[VER]', | |||
'Opera' => [' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]', 'Opera [VER]'], | |||
'Netscape' => 'Netscape/[VER]', | |||
'Mozilla' => 'rv:[VER]', | |||
'IE' => ['IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];', 'rv:[VER]'], | |||
'Edge' => ['Edge/[VER]', 'Edg/[VER]'], | |||
'Vivaldi' => 'Vivaldi/[VER]', | |||
'Coc Coc' => 'coc_coc_browser/[VER]', | |||
]; | |||
/** | |||
* @var CrawlerDetect | |||
*/ | |||
protected static $crawlerDetect; | |||
/** | |||
* Get all detection rules. These rules include the additional | |||
* platforms and browsers and utilities. | |||
* @return array | |||
*/ | |||
public static function getDetectionRulesExtended() | |||
{ | |||
static $rules; | |||
if (!$rules) { | |||
$rules = static::mergeRules( | |||
static::$desktopDevices, // NEW | |||
static::$phoneDevices, | |||
static::$tabletDevices, | |||
static::$operatingSystems, | |||
static::$additionalOperatingSystems, // NEW | |||
static::$browsers, | |||
static::$additionalBrowsers, // NEW | |||
static::$utilities | |||
); | |||
} | |||
return $rules; | |||
} | |||
public function getRules() | |||
{ | |||
if ($this->detectionType === static::DETECTION_TYPE_EXTENDED) { | |||
return static::getDetectionRulesExtended(); | |||
} | |||
return static::getMobileDetectionRules(); | |||
} | |||
/** | |||
* @return CrawlerDetect | |||
*/ | |||
public function getCrawlerDetect() | |||
{ | |||
if (static::$crawlerDetect === null) { | |||
static::$crawlerDetect = new CrawlerDetect(); | |||
} | |||
return static::$crawlerDetect; | |||
} | |||
public static function getBrowsers() | |||
{ | |||
return static::mergeRules( | |||
static::$additionalBrowsers, | |||
static::$browsers | |||
); | |||
} | |||
public static function getOperatingSystems() | |||
{ | |||
return static::mergeRules( | |||
static::$operatingSystems, | |||
static::$additionalOperatingSystems | |||
); | |||
} | |||
public static function getPlatforms() | |||
{ | |||
return static::mergeRules( | |||
static::$operatingSystems, | |||
static::$additionalOperatingSystems | |||
); | |||
} | |||
public static function getDesktopDevices() | |||
{ | |||
return static::$desktopDevices; | |||
} | |||
public static function getProperties() | |||
{ | |||
return static::mergeRules( | |||
static::$additionalProperties, | |||
static::$properties | |||
); | |||
} | |||
/** | |||
* Get accept languages. | |||
* @param string $acceptLanguage | |||
* @return array | |||
*/ | |||
public function languages($acceptLanguage = null) | |||
{ | |||
if ($acceptLanguage === null) { | |||
$acceptLanguage = $this->getHttpHeader('HTTP_ACCEPT_LANGUAGE'); | |||
} | |||
if (!$acceptLanguage) { | |||
return []; | |||
} | |||
$languages = []; | |||
// Parse accept language string. | |||
foreach (explode(',', $acceptLanguage) as $piece) { | |||
$parts = explode(';', $piece); | |||
$language = strtolower($parts[0]); | |||
$priority = empty($parts[1]) ? 1. : floatval(str_replace('q=', '', $parts[1])); | |||
$languages[$language] = $priority; | |||
} | |||
// Sort languages by priority. | |||
arsort($languages); | |||
return array_keys($languages); | |||
} | |||
/** | |||
* Match a detection rule and return the matched key. | |||
* @param array $rules | |||
* @param string|null $userAgent | |||
* @return string|bool | |||
*/ | |||
protected function findDetectionRulesAgainstUA(array $rules, $userAgent = null) | |||
{ | |||
// Loop given rules | |||
foreach ($rules as $key => $regex) { | |||
if (empty($regex)) { | |||
continue; | |||
} | |||
// Check match | |||
if ($this->match($regex, $userAgent)) { | |||
return $key ?: reset((array)$this->matchesArray); | |||
} | |||
} | |||
return false; | |||
} | |||
/** | |||
* Get the browser name. | |||
* @param string|null $userAgent | |||
* @return string|bool | |||
*/ | |||
public function browser($userAgent = null) | |||
{ | |||
return $this->findDetectionRulesAgainstUA(static::getBrowsers(), $userAgent); | |||
} | |||
/** | |||
* Get the platform name. | |||
* @param string|null $userAgent | |||
* @return string|bool | |||
*/ | |||
public function platform($userAgent = null) | |||
{ | |||
return $this->findDetectionRulesAgainstUA(static::getPlatforms(), $userAgent); | |||
} | |||
/** | |||
* Get the device name. | |||
* @param string|null $userAgent | |||
* @return string|bool | |||
*/ | |||
public function device($userAgent = null) | |||
{ | |||
$rules = static::mergeRules( | |||
static::getDesktopDevices(), | |||
static::getPhoneDevices(), | |||
static::getTabletDevices(), | |||
static::getUtilities() | |||
); | |||
return $this->findDetectionRulesAgainstUA($rules, $userAgent); | |||
} | |||
/** | |||
* Check if the device is a desktop computer. | |||
* @param string|null $userAgent deprecated | |||
* @param array $httpHeaders deprecated | |||
* @return bool | |||
*/ | |||
public function isDesktop($userAgent = null, $httpHeaders = null) | |||
{ | |||
// Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront' | |||
if ($this->getUserAgent() === 'Amazon CloudFront') { | |||
$cfHeaders = $this->getCfHeaders(); | |||
if(array_key_exists('HTTP_CLOUDFRONT_IS_DESKTOP_VIEWER', $cfHeaders)) { | |||
return $cfHeaders['HTTP_CLOUDFRONT_IS_DESKTOP_VIEWER'] === 'true'; | |||
} | |||
} | |||
return !$this->isMobile($userAgent, $httpHeaders) && !$this->isTablet($userAgent, $httpHeaders) && !$this->isRobot($userAgent); | |||
} | |||
/** | |||
* Check if the device is a mobile phone. | |||
* @param string|null $userAgent deprecated | |||
* @param array $httpHeaders deprecated | |||
* @return bool | |||
*/ | |||
public function isPhone($userAgent = null, $httpHeaders = null) | |||
{ | |||
return $this->isMobile($userAgent, $httpHeaders) && !$this->isTablet($userAgent, $httpHeaders); | |||
} | |||
/** | |||
* Get the robot name. | |||
* @param string|null $userAgent | |||
* @return string|bool | |||
*/ | |||
public function robot($userAgent = null) | |||
{ | |||
if ($this->getCrawlerDetect()->isCrawler($userAgent ?: $this->userAgent)) { | |||
return ucfirst($this->getCrawlerDetect()->getMatches()); | |||
} | |||
return false; | |||
} | |||
/** | |||
* Check if device is a robot. | |||
* @param string|null $userAgent | |||
* @return bool | |||
*/ | |||
public function isRobot($userAgent = null) | |||
{ | |||
return $this->getCrawlerDetect()->isCrawler($userAgent ?: $this->userAgent); | |||
} | |||
/** | |||
* Get the device type | |||
* @param null $userAgent | |||
* @param null $httpHeaders | |||
* @return string | |||
*/ | |||
public function deviceType($userAgent = null, $httpHeaders = null) | |||
{ | |||
if ($this->isDesktop($userAgent, $httpHeaders)) { | |||
return "desktop"; | |||
} elseif ($this->isPhone($userAgent, $httpHeaders)) { | |||
return "phone"; | |||
} elseif ($this->isTablet($userAgent, $httpHeaders)) { | |||
return "tablet"; | |||
} elseif ($this->isRobot($userAgent)) { | |||
return "robot"; | |||
} | |||
return "other"; | |||
} | |||
public function version($propertyName, $type = self::VERSION_TYPE_STRING) | |||
{ | |||
if (empty($propertyName)) { | |||
return false; | |||
} | |||
// set the $type to the default if we don't recognize the type | |||
if ($type !== self::VERSION_TYPE_STRING && $type !== self::VERSION_TYPE_FLOAT) { | |||
$type = self::VERSION_TYPE_STRING; | |||
} | |||
$properties = self::getProperties(); | |||
// Check if the property exists in the properties array. | |||
if (true === isset($properties[$propertyName])) { | |||
// Prepare the pattern to be matched. | |||
// Make sure we always deal with an array (string is converted). | |||
$properties[$propertyName] = (array) $properties[$propertyName]; | |||
foreach ($properties[$propertyName] as $propertyMatchString) { | |||
if (is_array($propertyMatchString)) { | |||
$propertyMatchString = implode("|", $propertyMatchString); | |||
} | |||
$propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString); | |||
// Identify and extract the version. | |||
preg_match(sprintf('#%s#is', $propertyPattern), $this->userAgent, $match); | |||
if (false === empty($match[1])) { | |||
$version = ($type === self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo($match[1]) : $match[1]); | |||
return $version; | |||
} | |||
} | |||
} | |||
return false; | |||
} | |||
/** | |||
* Merge multiple rules into one array. | |||
* @param array $all | |||
* @return array | |||
*/ | |||
protected static function mergeRules(...$all) | |||
{ | |||
$merged = []; | |||
foreach ($all as $rules) { | |||
foreach ($rules as $key => $value) { | |||
if (empty($merged[$key])) { | |||
$merged[$key] = $value; | |||
} elseif (is_array($merged[$key])) { | |||
$merged[$key][] = $value; | |||
} else { | |||
$merged[$key] .= '|' . $value; | |||
} | |||
} | |||
} | |||
return $merged; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function __call($name, $arguments) | |||
{ | |||
// Make sure the name starts with 'is', otherwise | |||
if (strpos($name, 'is') !== 0) { | |||
throw new BadMethodCallException("No such method exists: $name"); | |||
} | |||
$this->setDetectionType(self::DETECTION_TYPE_EXTENDED); | |||
$key = substr($name, 2); | |||
return $this->matchUAAgainstKey($key); | |||
} | |||
} |
@@ -0,0 +1,185 @@ | |||
<?php | |||
if (!defined('DEDEINC')) exit('dedebiz'); | |||
/* | |||
* This file is part of Crawler Detect - the web crawler detection library. | |||
* | |||
* (c) Mark Beech <m@rkbee.ch> | |||
* | |||
* This source file is subject to the MIT license that is bundled | |||
* with this source code in the file LICENSE. | |||
*/ | |||
require_once(DEDEINC."/libraries/fixtures/crawlers.php"); | |||
require_once(DEDEINC."/libraries/fixtures/exclusions.php"); | |||
require_once(DEDEINC."/libraries/fixtures/headers.php"); | |||
class CrawlerDetect | |||
{ | |||
/** | |||
* The user agent. | |||
* | |||
* @var string|null | |||
*/ | |||
protected $userAgent; | |||
/** | |||
* Headers that contain a user agent. | |||
* | |||
* @var array | |||
*/ | |||
protected $httpHeaders = array(); | |||
/** | |||
* Store regex matches. | |||
* | |||
* @var array | |||
*/ | |||
protected $matches = array(); | |||
/** | |||
* Crawlers object. | |||
* | |||
* @var \Jaybizzle\CrawlerDetect\Fixtures\Crawlers | |||
*/ | |||
protected $crawlers; | |||
/** | |||
* Exclusions object. | |||
* | |||
* @var \Jaybizzle\CrawlerDetect\Fixtures\Exclusions | |||
*/ | |||
protected $exclusions; | |||
/** | |||
* Headers object. | |||
* | |||
* @var \Jaybizzle\CrawlerDetect\Fixtures\Headers | |||
*/ | |||
protected $uaHttpHeaders; | |||
/** | |||
* The compiled regex string. | |||
* | |||
* @var string | |||
*/ | |||
protected $compiledRegex; | |||
/** | |||
* The compiled exclusions regex string. | |||
* | |||
* @var string | |||
*/ | |||
protected $compiledExclusions; | |||
/** | |||
* Class constructor. | |||
*/ | |||
public function __construct(array $headers = null, $userAgent = null) | |||
{ | |||
$this->crawlers = new Crawlers(); | |||
$this->exclusions = new Exclusions(); | |||
$this->uaHttpHeaders = new Headers(); | |||
$this->compiledRegex = $this->compileRegex($this->crawlers->getAll()); | |||
$this->compiledExclusions = $this->compileRegex($this->exclusions->getAll()); | |||
$this->setHttpHeaders($headers); | |||
$this->setUserAgent($userAgent); | |||
} | |||
/** | |||
* Compile the regex patterns into one regex string. | |||
* | |||
* @param array | |||
* | |||
* @return string | |||
*/ | |||
public function compileRegex($patterns) | |||
{ | |||
return '('.implode('|', $patterns).')'; | |||
} | |||
/** | |||
* Set HTTP headers. | |||
* | |||
* @param array|null $httpHeaders | |||
*/ | |||
public function setHttpHeaders($httpHeaders) | |||
{ | |||
// Use global _SERVER if $httpHeaders aren't defined. | |||
if (! is_array($httpHeaders) || ! count($httpHeaders)) { | |||
$httpHeaders = $_SERVER; | |||
} | |||
// Clear existing headers. | |||
$this->httpHeaders = array(); | |||
// Only save HTTP headers. In PHP land, that means | |||
// only _SERVER vars that start with HTTP_. | |||
foreach ($httpHeaders as $key => $value) { | |||
if (strpos($key, 'HTTP_') === 0) { | |||
$this->httpHeaders[$key] = $value; | |||
} | |||
} | |||
} | |||
/** | |||
* Return user agent headers. | |||
* | |||
* @return array | |||
*/ | |||
public function getUaHttpHeaders() | |||
{ | |||
return $this->uaHttpHeaders->getAll(); | |||
} | |||
/** | |||
* Set the user agent. | |||
* | |||
* @param string|null $userAgent | |||
*/ | |||
public function setUserAgent($userAgent) | |||
{ | |||
if (is_null($userAgent)) { | |||
foreach ($this->getUaHttpHeaders() as $altHeader) { | |||
if (isset($this->httpHeaders[$altHeader])) { | |||
$userAgent .= $this->httpHeaders[$altHeader].' '; | |||
} | |||
} | |||
} | |||
return $this->userAgent = $userAgent; | |||
} | |||
/** | |||
* Check user agent string against the regex. | |||
* | |||
* @param string|null $userAgent | |||
* | |||
* @return bool | |||
*/ | |||
public function isCrawler($userAgent = null) | |||
{ | |||
$agent = trim(preg_replace( | |||
"/{$this->compiledExclusions}/i", | |||
'', | |||
$userAgent ?: $this->userAgent ?: '' | |||
)); | |||
if ($agent === '') { | |||
return false; | |||
} | |||
return (bool) preg_match("/{$this->compiledRegex}/i", $agent, $this->matches); | |||
} | |||
/** | |||
* Return the matches. | |||
* | |||
* @return string|null | |||
*/ | |||
public function getMatches() | |||
{ | |||
return isset($this->matches[0]) ? $this->matches[0] : null; | |||
} | |||
} |
@@ -0,0 +1,30 @@ | |||
<?php | |||
if (!defined('DEDEINC')) exit('dedebiz'); | |||
/* | |||
* This file is part of Crawler Detect - the web crawler detection library. | |||
* | |||
* (c) Mark Beech <m@rkbee.ch> | |||
* | |||
* This source file is subject to the MIT license that is bundled | |||
* with this source code in the file LICENSE. | |||
*/ | |||
abstract class AbstractProvider | |||
{ | |||
/** | |||
* The data set. | |||
* | |||
* @var array | |||
*/ | |||
protected $data; | |||
/** | |||
* Return the data set. | |||
* | |||
* @return array | |||
*/ | |||
public function getAll() | |||
{ | |||
return $this->data; | |||
} | |||
} |
@@ -0,0 +1,71 @@ | |||
<?php | |||
if (!defined('DEDEINC')) exit('dedebiz'); | |||
/* | |||
* This file is part of Crawler Detect - the web crawler detection library. | |||
* | |||
* (c) Mark Beech <m@rkbee.ch> | |||
* | |||
* This source file is subject to the MIT license that is bundled | |||
* with this source code in the file LICENSE. | |||
*/ | |||
require_once(DEDEINC."/libraries/fixtures/abstractprovider.php"); | |||
class Exclusions extends AbstractProvider | |||
{ | |||
/** | |||
* List of strings to remove from the user agent before running the crawler regex | |||
* Over a large list of user agents, this gives us about a 55% speed increase! | |||
* | |||
* @var array | |||
*/ | |||
protected $data = array( | |||
'Safari.[\d\.]*', | |||
'Firefox.[\d\.]*', | |||
' Chrome.[\d\.]*', | |||
'Chromium.[\d\.]*', | |||
'MSIE.[\d\.]', | |||
'Opera\/[\d\.]*', | |||
'Mozilla.[\d\.]*', | |||
'AppleWebKit.[\d\.]*', | |||
'Trident.[\d\.]*', | |||
'Windows NT.[\d\.]*', | |||
'Android [\d\.]*', | |||
'Macintosh.', | |||
'Ubuntu', | |||
'Linux', | |||
'[ ]Intel', | |||
'Mac OS X [\d_]*', | |||
'(like )?Gecko(.[\d\.]*)?', | |||
'KHTML,', | |||
'CriOS.[\d\.]*', | |||
'CPU iPhone OS ([0-9_])* like Mac OS X', | |||
'CPU OS ([0-9_])* like Mac OS X', | |||
'iPod', | |||
'compatible', | |||
'x86_..', | |||
'i686', | |||
'x64', | |||
'X11', | |||
'rv:[\d\.]*', | |||
'Version.[\d\.]*', | |||
'WOW64', | |||
'Win64', | |||
'Dalvik.[\d\.]*', | |||
' \.NET CLR [\d\.]*', | |||
'Presto.[\d\.]*', | |||
'Media Center PC', | |||
'BlackBerry', | |||
'Build', | |||
'Opera Mini\/\d{1,2}\.\d{1,2}\.[\d\.]*\/\d{1,2}\.', | |||
'Opera', | |||
' \.NET[\d\.]*', | |||
'cubot', | |||
'; M bot', | |||
'; CRONO', | |||
'; B bot', | |||
'; IDbot', | |||
'; ID bot', | |||
'; POWER BOT', | |||
'OCTOPUS-CORE', | |||
); | |||
} |
@@ -0,0 +1,37 @@ | |||
<?php | |||
if (!defined('DEDEINC')) exit('dedebiz'); | |||
/* | |||
* This file is part of Crawler Detect - the web crawler detection library. | |||
* | |||
* (c) Mark Beech <m@rkbee.ch> | |||
* | |||
* This source file is subject to the MIT license that is bundled | |||
* with this source code in the file LICENSE. | |||
*/ | |||
require_once(DEDEINC."/libraries/fixtures/abstractprovider.php"); | |||
class Headers extends AbstractProvider | |||
{ | |||
/** | |||
* All possible HTTP headers that represent the user agent string. | |||
* | |||
* @var array | |||
*/ | |||
protected $data = array( | |||
// The default User-Agent string. | |||
'HTTP_USER_AGENT', | |||
// Header can occur on devices using Opera Mini. | |||
'HTTP_X_OPERAMINI_PHONE_UA', | |||
// Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/ | |||
'HTTP_X_DEVICE_USER_AGENT', | |||
'HTTP_X_ORIGINAL_USER_AGENT', | |||
'HTTP_X_SKYFIRE_PHONE', | |||
'HTTP_X_BOLT_PHONE_UA', | |||
'HTTP_DEVICE_STOCK_UA', | |||
'HTTP_X_UCBROWSER_DEVICE_UA', | |||
// Sometimes, bots (especially Google) use a genuine user agent, but fill this header in with their email address | |||
'HTTP_FROM', | |||
'HTTP_X_SCANNER', // Seen in use by Netsparker | |||
); | |||
} |
@@ -0,0 +1,150 @@ | |||
<?php | |||
if (!defined('DEDEINC')) exit('dedebiz'); | |||
require_once(DEDEINC."/libraries/agent.class.php"); | |||
/** | |||
* 流量统计 | |||
* 一个轻量级流量统计功能 | |||
* | |||
* @version $Id: statistics.class.php 1 11:42 2022年03月26日Z tianya $ | |||
* @package DedeBIZ.Libraries | |||
* @copyright Copyright (c) 2022, DedeBIZ.COM | |||
* @license https://www.dedebiz.com/license | |||
* @link https://www.dedebiz.com | |||
*/ | |||
class DedeStatistics { | |||
function __construct() | |||
{ | |||
} | |||
// 获取统计JS | |||
function GetStat() | |||
{ | |||
global $envs,$cfg_cookie_encode; | |||
$agent = new Agent(); | |||
$pm = array(); | |||
$pm['dduuid'] = GetCookie("DedeStUUID"); | |||
if (empty($pm['dduuid'])) { | |||
$pm['dduuid'] = $this->_uniqidReal(); | |||
PutCookie('DedeStUUID', $pm['dduuid'], 60 * 24 * 365); | |||
} | |||
$pm['ssid'] = session_id(); | |||
if (empty($pm['ssid'])) { | |||
session_start(); | |||
$pm['ssid'] = session_id(); | |||
} | |||
$url_type = isset($_GET['url_type'])? $_GET['url_type'] : 0; | |||
$typeid = isset($_GET['typeid'])? $_GET['typeid'] : 0; | |||
$aid = isset($_GET['aid'])? $_GET['aid'] : 0; | |||
$value = isset($_GET['value'])? $_GET['value'] : ''; | |||
$pm['browser'] = $agent->browser(); | |||
$pm['device'] = $agent->device(); | |||
$pm['device_type'] = $agent->deviceType(); | |||
$pm['os'] = $agent->platform(); | |||
$pm['t'] = time(); | |||
$pm['created_date'] = MyDate("Ymd",$pm['t']); | |||
$pm['created_hour'] = MyDate("H",$pm['t']); | |||
$pm['url_type'] = isset($envs['url_type'])? $envs['url_type'] : $url_type; | |||
$pm['typeid'] = isset($envs['typeid'])? $envs['typeid'] : $typeid; | |||
$pm['aid'] = isset($envs['aid'])? $envs['aid'] : $aid; | |||
$pm['value'] = isset($envs['value'])? $envs['value'] : $value; | |||
ksort($pm); | |||
$pm['sign'] = sha1(http_build_query($pm).md5($cfg_cookie_encode)); | |||
$pm['dopost'] = "stat"; | |||
$url = $GLOBALS['cfg_cmspath'].'/apps/statistics.php?'.http_build_query($pm); | |||
return <<<EOT | |||
(function() { | |||
let u = '{$url}'; | |||
fetch(u); | |||
})(); | |||
EOT; | |||
} | |||
// 统计 | |||
function Record() | |||
{ | |||
global $dsql,$cfg_cookie_encode; | |||
// 进行统计 | |||
$pm = array('dduuid','ssid','browser','device','device_type','os','t','created_date','created_hour','url_type','typeid','aid','value','sign'); | |||
$pmvalue = array(); | |||
foreach ($pm as $v) { | |||
$pmvalue[$v] = $_GET[$v]; | |||
} | |||
ksort($pmvalue); | |||
$sign = $pmvalue['sign']; | |||
unset($pmvalue['sign']); | |||
$cs = sha1(http_build_query($pmvalue).md5($cfg_cookie_encode)); | |||
if ($sign !== $cs) { | |||
die("DedeBIZ:check sign failed"); | |||
} | |||
$pmvalue['ip'] = GetIP(); | |||
$kstr = $vstr = array(); | |||
foreach ($pmvalue as $key => $value) { | |||
$kstr[] = "`{$key}`"; | |||
$vstr[] = "'".addslashes($value)."'"; | |||
} | |||
$insql = "INSERT INTO `#@__statistics_detail`(".implode(",",$kstr).") VALUES (".implode(",",$vstr).")"; | |||
return $dsql->ExecuteNoneQuery($insql); | |||
} | |||
// 生成uuid | |||
function _uniqidReal($lenght = 13) { | |||
if (function_exists("random_bytes")) { | |||
$bytes = random_bytes(ceil($lenght / 2)); | |||
} elseif (function_exists("openssl_random_pseudo_bytes")) { | |||
$bytes = openssl_random_pseudo_bytes(ceil($lenght / 2)); | |||
} else { | |||
throw new Exception("no cryptographically secure random function available"); | |||
} | |||
return substr(bin2hex($bytes), 0, $lenght); | |||
} | |||
// 获取某天的统计信息 | |||
function GetInfoByDate($d=0) | |||
{ | |||
global $dsql; | |||
if ($d == -1) { | |||
$pv = $dsql->GetOne("SELECT SUM(pv) as total FROM `#@__statistics`"); | |||
$uv = $dsql->GetOne("SELECT SUM(uv) as total FROM `#@__statistics`"); | |||
$ip = $dsql->GetOne("SELECT SUM(ip) as total FROM `#@__statistics`"); | |||
$vv = $dsql->GetOne("SELECT SUM(vv) as total FROM `#@__statistics`"); | |||
return array( | |||
"sdate" => $d, | |||
"pv" => $pv['total'], | |||
"uv" => $uv['total'], | |||
"ip" => $ip['total'], | |||
"vv" => $vv['total'], | |||
); | |||
} | |||
$today = MyDate("Ymd",time()); | |||
if ($d==0) { | |||
$d = $today; | |||
} | |||
$d = intval($d); | |||
// 如果统计数据中存在,则直接查询统计表 | |||
$info = $dsql->GetOne("SELECT * FROM `#@__statistics` WHERE sdate = $d"); | |||
if (is_array($info)) { | |||
return $info; | |||
} | |||
$pv = $dsql->GetOne("SELECT COUNT(*) as total FROM `#@__statistics_detail` WHERE created_date = $d"); | |||
$uv = $dsql->GetOne("SELECT COUNT(DISTINCT dduuid) as total FROM `#@__statistics_detail` WHERE created_date = $d"); | |||
$ip = $dsql->GetOne("SELECT COUNT(DISTINCT ip) as total FROM `#@__statistics_detail` WHERE created_date = $d"); | |||
$vv = $dsql->GetOne("SELECT COUNT(DISTINCT ssid) as total FROM `#@__statistics_detail` WHERE created_date = $d"); | |||
if ($d < intval($today)) { | |||
$insql = "INSERT INTO `#@__statistics`(`sdate`,`pv`,`uv`,`ip`,`vv`) VALUES ('$d', '{$pv['total']}','{$uv['total']}','{$ip['total']}','{$vv['total']}')"; | |||
// var_dump($insql); | |||
return $dsql->ExecuteNoneQuery($insql); | |||
} | |||
return array( | |||
"sdate" => $d, | |||
"pv" => $pv['total'], | |||
"uv" => $uv['total'], | |||
"ip" => $ip['total'], | |||
"vv" => $vv['total'], | |||
); | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
<?php | |||
if (!defined('DEDEINC')) exit('dedebiz'); | |||
require_once(DEDEINC."/libraries/statistics.class.php"); | |||
/** | |||
* 统计标签 | |||
* | |||
* @version $Id: statistics.lib.php 1 9:29 2022年3月26日Z tianya $ | |||
* @package DedeBIZ.Taglib | |||
* @copyright Copyright (c) 2022, DedeBIZ.COM | |||
* @license https://www.dedebiz.com/license | |||
* @link https://www.dedebiz.com | |||
*/ | |||
function lib_statistics(&$ctag, &$refObj) | |||
{ | |||
global $envs; | |||
//属性处理 | |||
$attlist = ""; | |||
FillAttsDefault($ctag->CAttribute->Items, $attlist); | |||
extract($ctag->CAttribute->Items, EXTR_SKIP); | |||
$pms = array(); | |||
$pms['url_type'] = isset($envs['url_type'])? $envs['url_type'] : 0; | |||
$pms['typeid'] = isset($envs['typeid'])? $envs['typeid'] : 0; | |||
$pms['aid'] = isset($envs['aid'])? $envs['aid'] : 0; | |||
$pms['value'] = isset($envs['value'])? $envs['value'] : ''; | |||
$revalue = '<script async src="'.$GLOBALS['cfg_cmspath'].'/apps/statistics.php?'.http_build_query($pms).'"></script>'; | |||
return $revalue; | |||
} |
@@ -13,10 +13,9 @@ | |||
</button> | |||
</div> | |||
<!-- /.scroll-top --> | |||
<script src="{dede:global.cfg_cmsurl/}/static/js/bootstrap.bundle.js"></script> | |||
<script src="{dede:global.cfg_cmsurl/}/static/js/style.js"></script> | |||
{dede:statistics/} | |||
<script> | |||
//校验是否登录 | |||
function CheckLogin() { | |||