Add pureblog-stats.php
This commit is contained in:
parent
d8a5fad91a
commit
4a34410e21
1 changed files with 251 additions and 0 deletions
251
pureblog-stats.php
Normal file
251
pureblog-stats.php
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
<?php
|
||||
|
||||
require PUREBLOG_BASE_PATH . '/includes/header.php';
|
||||
render_masthead_layout($config, ['page' => null]);
|
||||
|
||||
?>
|
||||
|
||||
<main>
|
||||
<h1> Stats </h1>
|
||||
<?php
|
||||
|
||||
$publishedPosts = array_values(array_filter(get_all_posts(true), static fn(array $post): bool => ($post['status'] ?? 'draft') === 'published'));
|
||||
$publishedCount = count($publishedPosts);
|
||||
$tz = site_timezone_object($config);
|
||||
$now = new DateTimeImmutable('now', $tz);
|
||||
$currentYear = (int) $now->format('Y');
|
||||
|
||||
$publishedThisYear = 0;
|
||||
$totalWordsThisYear = 0;
|
||||
$tagCounts = [];
|
||||
$tagCountsThisYear = [];
|
||||
$tagDisplayNames = [];
|
||||
$totalWords = 0;
|
||||
$allTimeMonthCounts = array_fill(1, 12, 0);
|
||||
$allTimeDayCounts = array_fill(1, 7, 0); // 1=Mon … 7=Sun (ISO 8601)
|
||||
$yearCounts = [];
|
||||
|
||||
// Build rolling 12-month chart slots (oldest first)
|
||||
$chartMonths = [];
|
||||
$firstOfMonth = new DateTimeImmutable($now->format('Y-m-01'), $tz);
|
||||
for ($i = 11; $i >= 0; $i--) {
|
||||
$dt = $firstOfMonth->modify("-{$i} months");
|
||||
$month = (int) $dt->format('n');
|
||||
$chartMonths[] = [
|
||||
'year' => (int) $dt->format('Y'),
|
||||
'month' => $month,
|
||||
'label' => t('date.months_short.' . ($month - 1)),
|
||||
'count' => 0,
|
||||
];
|
||||
}
|
||||
$chartIndex = [];
|
||||
foreach ($chartMonths as $idx => $cm) {
|
||||
$chartIndex[$cm['year'] . '-' . $cm['month']] = $idx;
|
||||
}
|
||||
$recentCutoff = $firstOfMonth->modify('-11 months')->getTimestamp();
|
||||
|
||||
foreach ($publishedPosts as $post) {
|
||||
$content = (string) ($post['content'] ?? '');
|
||||
$totalWords += str_word_count($content);
|
||||
|
||||
$timestamp = (int) ($post['timestamp'] ?? 0);
|
||||
if ($timestamp > 0) {
|
||||
$dt = (new DateTimeImmutable('@' . $timestamp))->setTimezone($tz);
|
||||
$postYear = (int) $dt->format('Y');
|
||||
$postMon = (int) $dt->format('n');
|
||||
$postDay = (int) $dt->format('N'); // 1=Mon … 7=Sun
|
||||
|
||||
$chartKey = $postYear . '-' . $postMon;
|
||||
if (isset($chartIndex[$chartKey])) {
|
||||
$chartMonths[$chartIndex[$chartKey]]['count']++;
|
||||
}
|
||||
|
||||
if ($timestamp >= $recentCutoff) {
|
||||
$publishedThisYear++;
|
||||
$totalWordsThisYear += str_word_count($content);
|
||||
}
|
||||
|
||||
$allTimeMonthCounts[$postMon]++;
|
||||
$allTimeDayCounts[$postDay]++;
|
||||
$yearCounts[$postYear] = ($yearCounts[$postYear] ?? 0) + 1;
|
||||
}
|
||||
|
||||
$tags = $post['tags'] ?? [];
|
||||
if (!is_array($tags)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($tags as $tag) {
|
||||
$name = trim((string) $tag);
|
||||
if ($name !== '') {
|
||||
$slug = normalize_tag($name);
|
||||
$tagDisplayNames[$slug] ??= $name;
|
||||
$tagCounts[$slug] = ($tagCounts[$slug] ?? 0) + 1;
|
||||
if ($timestamp >= $recentCutoff) {
|
||||
$tagCountsThisYear[$slug] = ($tagCountsThisYear[$slug] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksort($yearCounts);
|
||||
$maxYearCount = !empty($yearCounts) ? max($yearCounts) : 1;
|
||||
|
||||
$avgWordsAllTime = $publishedCount > 0 ? (int) round($totalWords / $publishedCount) : 0;
|
||||
$avgWordsThisYear = $publishedThisYear > 0 ? (int) round($totalWordsThisYear / $publishedThisYear) : 0;
|
||||
$booksEquivalent = $totalWords > 0 ? round($totalWords / 80000, 1) : 0;
|
||||
$booksThisYear = $totalWordsThisYear > 0 ? round($totalWordsThisYear / 80000, 1) : 0;
|
||||
|
||||
// Last published time
|
||||
$lastTimestamp = 0;
|
||||
foreach ($publishedPosts as $post) {
|
||||
$ts = (int) ($post['timestamp'] ?? 0);
|
||||
if ($ts > $lastTimestamp) {
|
||||
$lastTimestamp = $ts;
|
||||
}
|
||||
}
|
||||
$lastPublishedAgo = $lastTimestamp > 0 ? relative_time($lastTimestamp) : t('admin.dashboard.no_posts_yet');
|
||||
|
||||
?>
|
||||
</main>
|
||||
<?php render_footer_layout($config, ['page' => null]); ?>
|
||||
</body>
|
||||
|
||||
|
||||
pj@laptop5:~/pureblog$ sudo docker compose up -d --force-recreate
|
||||
|
||||
|
||||
pj@laptop5:~/pureblog$ sudo docker compose up -d --force-recreate
|
||||
[+] up 1/1
|
||||
|
||||
|
||||
pj@laptop5:~/pureblog$ sudo docker compose up -d --force-recreate
|
||||
[+] up 1/1
|
||||
|
||||
|
||||
|
||||
pj@laptop5:~/pureblog$ sudo docker compose up -d --force-recreate
|
||||
pj@laptop5:~/pureblog$
|
||||
pj@laptop5:~/pureblog$ sudo docker compose up -d --force-recreate
|
||||
pj@laptop5:~/pureblog$ sudo cat content/includes/stats.php
|
||||
<?php 4.0s
|
||||
|
||||
require PUREBLOG_BASE_PATH . '/includes/header.php';
|
||||
render_masthead_layout($config, ['page' => null]);
|
||||
|
||||
?>
|
||||
|
||||
<main>
|
||||
<h1> Stats </h1>
|
||||
<?php
|
||||
|
||||
$publishedPosts = array_values(array_filter(get_all_posts(true), static fn(array $post): bool => ($post['status'] ?? 'draft') === 'published'));
|
||||
$publishedCount = count($publishedPosts);
|
||||
$tz = site_timezone_object($config);
|
||||
$now = new DateTimeImmutable('now', $tz);
|
||||
$currentYear = (int) $now->format('Y');
|
||||
|
||||
$publishedThisYear = 0;
|
||||
$totalWordsThisYear = 0;
|
||||
$tagCounts = [];
|
||||
$tagCountsThisYear = [];
|
||||
$tagDisplayNames = [];
|
||||
$totalWords = 0;
|
||||
$allTimeMonthCounts = array_fill(1, 12, 0);
|
||||
$allTimeDayCounts = array_fill(1, 7, 0); // 1=Mon … 7=Sun (ISO 8601)
|
||||
$yearCounts = [];
|
||||
|
||||
// Build rolling 12-month chart slots (oldest first)
|
||||
$chartMonths = [];
|
||||
$firstOfMonth = new DateTimeImmutable($now->format('Y-m-01'), $tz);
|
||||
for ($i = 11; $i >= 0; $i--) {
|
||||
$dt = $firstOfMonth->modify("-{$i} months");
|
||||
$month = (int) $dt->format('n');
|
||||
$chartMonths[] = [
|
||||
'year' => (int) $dt->format('Y'),
|
||||
'month' => $month,
|
||||
'label' => t('date.months_short.' . ($month - 1)),
|
||||
'count' => 0,
|
||||
];
|
||||
}
|
||||
$chartIndex = [];
|
||||
foreach ($chartMonths as $idx => $cm) {
|
||||
$chartIndex[$cm['year'] . '-' . $cm['month']] = $idx;
|
||||
}
|
||||
$recentCutoff = $firstOfMonth->modify('-11 months')->getTimestamp();
|
||||
|
||||
foreach ($publishedPosts as $post) {
|
||||
$content = (string) ($post['content'] ?? '');
|
||||
$totalWords += str_word_count($content);
|
||||
|
||||
$timestamp = (int) ($post['timestamp'] ?? 0);
|
||||
if ($timestamp > 0) {
|
||||
$dt = (new DateTimeImmutable('@' . $timestamp))->setTimezone($tz);
|
||||
$postYear = (int) $dt->format('Y');
|
||||
$postMon = (int) $dt->format('n');
|
||||
$postDay = (int) $dt->format('N'); // 1=Mon … 7=Sun
|
||||
|
||||
$chartKey = $postYear . '-' . $postMon;
|
||||
if (isset($chartIndex[$chartKey])) {
|
||||
$chartMonths[$chartIndex[$chartKey]]['count']++;
|
||||
}
|
||||
|
||||
if ($timestamp >= $recentCutoff) {
|
||||
$publishedThisYear++;
|
||||
$totalWordsThisYear += str_word_count($content);
|
||||
}
|
||||
|
||||
$allTimeMonthCounts[$postMon]++;
|
||||
$allTimeDayCounts[$postDay]++;
|
||||
$yearCounts[$postYear] = ($yearCounts[$postYear] ?? 0) + 1;
|
||||
}
|
||||
|
||||
$tags = $post['tags'] ?? [];
|
||||
if (!is_array($tags)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($tags as $tag) {
|
||||
$name = trim((string) $tag);
|
||||
if ($name !== '') {
|
||||
$slug = normalize_tag($name);
|
||||
$tagDisplayNames[$slug] ??= $name;
|
||||
$tagCounts[$slug] = ($tagCounts[$slug] ?? 0) + 1;
|
||||
if ($timestamp >= $recentCutoff) {
|
||||
$tagCountsThisYear[$slug] = ($tagCountsThisYear[$slug] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksort($yearCounts);
|
||||
$maxYearCount = !empty($yearCounts) ? max($yearCounts) : 1;
|
||||
|
||||
$avgWordsAllTime = $publishedCount > 0 ? (int) round($totalWords / $publishedCount) : 0;
|
||||
$avgWordsThisYear = $publishedThisYear > 0 ? (int) round($totalWordsThisYear / $publishedThisYear) : 0;
|
||||
$booksEquivalent = $totalWords > 0 ? round($totalWords / 80000, 1) : 0;
|
||||
$booksThisYear = $totalWordsThisYear > 0 ? round($totalWordsThisYear / 80000, 1) : 0;
|
||||
|
||||
// Last published time
|
||||
$lastTimestamp = 0;
|
||||
foreach ($publishedPosts as $post) {
|
||||
$ts = (int) ($post['timestamp'] ?? 0);
|
||||
if ($ts > $lastTimestamp) {
|
||||
$lastTimestamp = $ts;
|
||||
}
|
||||
}
|
||||
$lastPublishedAgo = $lastTimestamp > 0 ? relative_time($lastTimestamp) : t('admin.dashboard.no_posts_yet');
|
||||
|
||||
?>
|
||||
<div class="stats">
|
||||
|
||||
<h3> Published posts: </h3> <?= e(number_format($publishedCount)) ?><br>
|
||||
|
||||
<h3>Total words:</h3> <?= e(number_format($totalWords)) ?><br>
|
||||
<br>
|
||||
<h3>Average words per post:</h3> <?= e(number_format($avgWordsAllTime)) ?>
|
||||
<br><h3>Book equivalents (base 80,000):</h3> <?= e(number_format($booksEquivalent, 1)) ?><br>
|
||||
<h3>Last published:</h3> <?= e($lastPublishedAgo) ?></p>
|
||||
</div>
|
||||
</main>
|
||||
<?php render_footer_layout($config, ['page' => null]); ?>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue