millions/stats.php

158 lines
5.1 KiB
PHP

<?php
if (!file_exists(__DIR__ . '/config.php')) {
die("ERROR: Millions not installed.");
}
$config = require 'config.php';
$pdo = new MyPDO('sqlite:' . __DIR__ . '/' . $config['database']);
$site = false;
if (!empty($_GET['for'])) {
$site = $pdo->run('SELECT * FROM sites WHERE host=?', [$_GET['for']])->fetch();
if ($site) {
// TODO - for now all stats are de-facto public, this should not be true
$labels = $visits = $uniques = [];
for ($d=14; $d>0; $d--) {
$labels[date('Y-m-d', strtotime('-'.$d.'days'))] = date('Dd', strtotime('-'.$d.'days'));
$visits[date('Y-m-d', strtotime('-'.$d.'days'))] = 0;
$uniques[date('Y-m-d', strtotime('-'.$d.'days'))] = 0;
}
$last14days = $pdo->run('SELECT date(datetime(ts, \'unixepoch\')) as date, COUNT(*) as visits
FROM visits
WHERE site_id=:site_id AND date>=:date_min AND date<=:date_max
GROUP BY date', [':site_id'=>$site['id'], ':date_min'=>date('Y-m-d', strtotime('-14 days')), ':date_max'=>date('Y-m-d')]);
foreach ($last14days as $stat) {
$visits[$stat['date']] = (int) $stat['visits'];
}
$last14daysUniq = $pdo->run('SELECT date(datetime(ts, \'unixepoch\')) as date, COUNT(*) as visits
FROM visits
WHERE site_id=:site_id AND is_unique=1 AND date>=:date_min AND date<=:date_max
GROUP BY date', [':site_id'=>$site['id'], ':date_min'=>date('Y-m-d', strtotime('-14 days')), ':date_max'=>date('Y-m-d')]);
foreach ($last14daysUniq as $stat) {
$uniques[$stat['date']] = (int) $stat['visits'];
}
} else {
$sites = $pdo->run('SELECT host, label, COUNT(*) AS visits, stats_public
FROM visits
INNER JOIN sites ON visits.site_id=sites.id
GROUP BY site_id
ORDER BY visits DESC');
}
} else {
$sites = $pdo->run('SELECT host, label, COUNT(*) AS visits, stats_public
FROM visits
INNER JOIN sites ON visits.site_id=sites.id
GROUP BY site_id
ORDER BY visits DESC');
}
?><!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<title>stats <?php if ($site) echo ' - ' . $site['label']; ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/yegor256/tacit@gh-pages/tacit-css-1.5.1.min.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
</head>
<body>
<section>
<a href="stats.php">Millions web counter</a>:
<?php if ($site) { ?>
<h1><?php echo $site['label']; ?></h1>
<canvas id="canvas"></canvas>
<script>
window.chartColors = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(75, 192, 192)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
};
var color = Chart.helpers.color;
var barChartData = {
labels: <?php echo json_encode(array_values($labels)); ?>,
datasets: [{
label: 'Total visitors',
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
borderColor: window.chartColors.red,
borderWidth: 1,
fill: false,
lineTension: 0,
data: <?php echo json_encode(array_values($visits)); ?>
}, {
label: 'Unique visitors',
backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),
borderColor: window.chartColors.blue,
borderWidth: 1,
fill: false,
lineTension: 0,
data: <?php echo json_encode(array_values($uniques)); ?>
}]
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'line',
data: barChartData,
options: {
responsive: true,
legend: {
position: 'top',
}
}
});
};
</script>
<?php
} else {
echo '<table><tr><th>Site</th><th>domain</th><th>#visits</th></tr>';
foreach ($sites as $site) {
echo '<tr><td>'.$site['label'].'</td><td>'.$site['host'].'</td><td>';
if ($site['stats_public']) echo '<a href="stats.php?for=' . $site['host'] . '">';
echo $site['visits'];
if ($site['stats_public']) echo '</a>';
echo '</td></tr>';
}
echo '</table>';
}
?>
</section>
</body>
</html>
<?php
class MyPDO extends PDO
{
public function __construct($dsn, $username = NULL, $password = NULL, $options = [])
{
$default_options = [
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
];
$options = array_replace($default_options, $options);
parent::__construct($dsn, $username, $password, $options);
}
public function run($sql, $args = NULL)
{
if (!$args)
{
return $this->query($sql);
}
$stmt = $this->prepare($sql);
$stmt->execute($args);
return $stmt;
}
}