Besucherzähler um Page Views erweitert

- Zwei separate Zähler: Unique Visitors (Session) + Page Views (jeden Aufruf)
- Footer zeigt beide Werte an
- Neue Datendateien in .gitignore aufgenommen

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
architeur
2025-12-29 14:00:33 +01:00
parent dd230196ff
commit 3c7ad68be2
3 changed files with 23 additions and 15 deletions

2
.gitignore vendored
View File

@@ -16,6 +16,8 @@ node_modules/
# Counter data # Counter data
api/counter.txt api/counter.txt
api/visitors.txt
api/pageviews.txt
kostenschaetzung/ kostenschaetzung/
schadendokumentation/ schadendokumentation/
zeitwert/ zeitwert/

View File

@@ -1,33 +1,37 @@
<?php <?php
/** /**
* Besucherzähler API für SPA-Landing * Besucherzähler API für SPA-Landing
* Gibt den aktuellen Zählerstand als JSON zurück und zählt bei neuen Sessions * Zählt Unique Visitors (Session-basiert) und Page Views (jeden Aufruf)
*/ */
header('Content-Type: application/json'); header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Origin: *');
$counterFile = __DIR__ . '/counter.txt'; $visitorsFile = __DIR__ . '/visitors.txt';
$pageviewsFile = __DIR__ . '/pageviews.txt';
// Zähler lesen oder initialisieren // Zähler lesen oder initialisieren
if (file_exists($counterFile)) { $visitors = file_exists($visitorsFile) ? (int) file_get_contents($visitorsFile) : 0;
$count = (int) file_get_contents($counterFile); $pageviews = file_exists($pageviewsFile) ? (int) file_get_contents($pageviewsFile) : 0;
} else {
$count = 0;
}
// Session starten für Duplikat-Erkennung // Page Views immer erhöhen
$pageviews++;
file_put_contents($pageviewsFile, $pageviews);
// Session starten für Unique Visitors
session_start(); session_start();
// Nur zählen wenn noch nicht in dieser Session gezählt // Unique Visitors nur bei neuer Session zählen
if (!isset($_SESSION['spa_counted'])) { if (!isset($_SESSION['spa_counted'])) {
$count++; $visitors++;
file_put_contents($counterFile, $count); file_put_contents($visitorsFile, $visitors);
$_SESSION['spa_counted'] = true; $_SESSION['spa_counted'] = true;
} }
// JSON-Antwort // JSON-Antwort
echo json_encode([ echo json_encode([
'count' => $count, 'visitors' => $visitors,
'formatted' => number_format($count, 0, ',', '.') 'visitors_formatted' => number_format($visitors, 0, ',', '.'),
'pageviews' => $pageviews,
'pageviews_formatted' => number_format($pageviews, 0, ',', '.')
]); ]);

View File

@@ -280,7 +280,7 @@
</main> </main>
<footer class="footer"> <footer class="footer">
<p>artetui.de · SPA Platform · Alle Daten werden lokal gespeichert</p> <p>artetui.de · SPA Platform · Alle Daten werden lokal gespeichert</p>
<p style="margin-top:0.5rem;font-size:0.85rem;opacity:0.7;">Besucher: <span id="visitor-count">...</span></p> <p style="margin-top:0.5rem;font-size:0.85rem;opacity:0.7;">Besucher: <span id="visitor-count">...</span> · Aufrufe: <span id="pageview-count">...</span></p>
<p style="text-align:center;margin-top:0.5rem;font-size:0.85rem;"> <p style="text-align:center;margin-top:0.5rem;font-size:0.85rem;">
<a href="#" onclick="openImpressum();return false;" style="color:#6b7280;text-decoration:none;">Impressum</a> <a href="#" onclick="openImpressum();return false;" style="color:#6b7280;text-decoration:none;">Impressum</a>
<span style="color:#d1d5db;margin:0 0.5rem;">|</span> <span style="color:#d1d5db;margin:0 0.5rem;">|</span>
@@ -303,10 +303,12 @@
fetch('/api/counter.php') fetch('/api/counter.php')
.then(r => r.json()) .then(r => r.json())
.then(data => { .then(data => {
document.getElementById('visitor-count').textContent = data.formatted; document.getElementById('visitor-count').textContent = data.visitors_formatted;
document.getElementById('pageview-count').textContent = data.pageviews_formatted;
}) })
.catch(() => { .catch(() => {
document.getElementById('visitor-count').textContent = '-'; document.getElementById('visitor-count').textContent = '-';
document.getElementById('pageview-count').textContent = '-';
}); });
</script> </script>