-
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
class pluginVisitsStats extends Plugin
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
global $L;
|
||||
$this->dbFields = array(
|
||||
'label' => $L->g('Visits'),
|
||||
'excludeAdmins' => false
|
||||
);
|
||||
}
|
||||
|
||||
public function adminHead()
|
||||
{
|
||||
if ($GLOBALS['ADMIN_VIEW'] !== 'dashboard') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$html = $this->includeCSS('chart.min.css');
|
||||
$html .= $this->includeJS('chart.bundle.min.js');
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Plugin form for settings
|
||||
public function form()
|
||||
{
|
||||
global $L;
|
||||
|
||||
$html = '<div class="mb-3">';
|
||||
$html .= '<label class="form-label" for="label">' . $L->get('Label') . '</label>';
|
||||
$html .= '<input class="form-control" id="label" name="label" type="text" dir="auto" value="' . $this->getValue('label') . '">';
|
||||
$html .= '<div class="form-text">' . $L->get('This title is almost always used in the sidebar of the site') . '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
if (defined('BLUDIT_PRO')) {
|
||||
$html .= '<div class="mb-3">';
|
||||
$html .= '<label class="form-label" for="excludeAdmins">' . $L->get('Exclude administrators users') . '</label>';
|
||||
$html .= '<select class="form-select" id="excludeAdmins" name="excludeAdmins">';
|
||||
$html .= '<option value="true" ' . ($this->getValue('excludeAdmins') === true ? 'selected' : '') . '>' . $L->get('Enabled') . '</option>';
|
||||
$html .= '<option value="false" ' . ($this->getValue('excludeAdmins') === false ? 'selected' : '') . '>' . $L->get('Disabled') . '</option>';
|
||||
$html .= '</select>';
|
||||
$html .= '</div>';
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function siteBodyEnd()
|
||||
{
|
||||
$currentDate = Date::current('Y-m-d');
|
||||
$isNewDay = !file_exists($this->workspace() . $currentDate . '.log');
|
||||
$visitorAdded = $this->addVisitor();
|
||||
if ($isNewDay && $visitorAdded) {
|
||||
$this->deleteOldLogs();
|
||||
}
|
||||
}
|
||||
|
||||
// Delete log files older than 7 days
|
||||
public function deleteOldLogs()
|
||||
{
|
||||
$logs = Filesystem::listFiles($this->workspace(), '*', 'log', false);
|
||||
rsort($logs);
|
||||
$remove = array_slice($logs, 7);
|
||||
foreach ($remove as $log) {
|
||||
Filesystem::rmfile($log);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the number of visits for a given date (YYYY-MM-DD)
|
||||
public function visits($date)
|
||||
{
|
||||
$file = $this->workspace() . $date . '.log';
|
||||
if (!file_exists($file)) {
|
||||
return 0;
|
||||
}
|
||||
$handle = @fopen($file, 'rb');
|
||||
if ($handle === false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The amount of visits is the number of lines on the file
|
||||
$lines = 0;
|
||||
while (!feof($handle)) {
|
||||
$lines += substr_count(fread($handle, 8192), PHP_EOL);
|
||||
}
|
||||
@fclose($handle);
|
||||
return $lines;
|
||||
}
|
||||
|
||||
// Returns the number of unique visitors for a given date (YYYY-MM-DD)
|
||||
public function uniqueVisitors($date)
|
||||
{
|
||||
$file = $this->workspace() . $date . '.log';
|
||||
if (!file_exists($file)) {
|
||||
return 0;
|
||||
}
|
||||
$lines = @file($file);
|
||||
if (empty($lines)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$seen = array();
|
||||
foreach ($lines as $line) {
|
||||
$data = json_decode($line, true);
|
||||
if (is_array($data) && isset($data[0]) && is_string($data[0]) && $data[0] !== '') {
|
||||
$seen[$data[0]] = true;
|
||||
}
|
||||
}
|
||||
return count($seen);
|
||||
}
|
||||
|
||||
// Single-pass read of a day log returning [total, unique]
|
||||
private function readCounts($date)
|
||||
{
|
||||
$file = $this->workspace() . $date . '.log';
|
||||
if (!file_exists($file)) {
|
||||
return array(0, 0);
|
||||
}
|
||||
$handle = @fopen($file, 'rb');
|
||||
if ($handle === false) {
|
||||
return array(0, 0);
|
||||
}
|
||||
$total = 0;
|
||||
$seen = array();
|
||||
while (($line = fgets($handle)) !== false) {
|
||||
$total++;
|
||||
$data = json_decode($line, true);
|
||||
if (is_array($data) && isset($data[0]) && is_string($data[0]) && $data[0] !== '') {
|
||||
$seen[$data[0]] = true;
|
||||
}
|
||||
}
|
||||
@fclose($handle);
|
||||
return array($total, count($seen));
|
||||
}
|
||||
|
||||
// Returns visits and unique-visitor counts for the last $days days
|
||||
// Returns ['labels'=>[], 'visits'=>[], 'unique'=>[], 'total'=>int]
|
||||
public function getLastDaysData($days = 7)
|
||||
{
|
||||
$result = array('labels' => array(), 'visits' => array(), 'unique' => array(), 'total' => 0);
|
||||
for ($i = $days - 1; $i >= 0; $i--) {
|
||||
$date = Date::currentOffset('Y-m-d', '-' . $i . ' day');
|
||||
list($v, $u) = $this->readCounts($date);
|
||||
$result['labels'][] = Date::format($date, 'Y-m-d', 'D');
|
||||
$result['visits'][] = $v;
|
||||
$result['unique'][] = $u;
|
||||
$result['total'] += $v;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Add a line to the current day log file
|
||||
public function addVisitor()
|
||||
{
|
||||
global $security;
|
||||
if (Cookie::get('BLUDIT-KEY') && defined('BLUDIT_PRO') && $this->getValue('excludeAdmins')) {
|
||||
return false;
|
||||
}
|
||||
$currentTime = Date::current('Y-m-d H:i:s');
|
||||
$ip = $security->getUserIp();
|
||||
$hashIP = md5($ip);
|
||||
|
||||
$line = json_encode(array($hashIP, $currentTime));
|
||||
$currentDate = Date::current('Y-m-d');
|
||||
$logFile = $this->workspace() . $currentDate . '.log';
|
||||
|
||||
return file_put_contents($logFile, $line . PHP_EOL, FILE_APPEND | LOCK_EX) !== false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user