| Server IP : 213.255.246.8 / Your IP : 216.73.217.0 Web Server : Apache System : Linux dublin.stapolin.com 5.14.0-362.18.1.el9_3.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Jan 29 07:05:48 EST 2024 x86_64 User : stapolin ( 1019) PHP Version : 8.4.24 Disable Function : exec,passthru,shell_exec,system MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/stapolin/public_html/tracking.stapolin.com/admin/ |
Upload File : |
<?php
declare(strict_types=1);
require_once __DIR__ . '/../includes/bootstrap.php';
$currentUser = require_login();
$pageTitle = 'Countries';
[$fromUtc, $toUtc, $fromDate, $toDate] = report_date_range();
[$websiteSql, $websiteTypes, $websiteParams] = selected_website_sql('s');
$countryRows = db_fetch_all(
'SELECT COALESCE(NULLIF(s.country, ""), "Unknown") AS country,
COUNT(*) AS sessions,
COUNT(DISTINCT s.visitor_id) AS visitors,
SUM(s.page_views) AS page_views,
AVG(TIMESTAMPDIFF(SECOND, s.started_at, COALESCE(s.ended_at, s.last_activity_at))) AS avg_duration
FROM sessions s
WHERE s.started_at BETWEEN ? AND ?' . $websiteSql . '
GROUP BY country
ORDER BY sessions DESC
LIMIT 100',
'ss' . $websiteTypes,
array_merge([$fromUtc, $toUtc], $websiteParams)
);
$regionRows = db_fetch_all(
'SELECT COALESCE(NULLIF(s.country, ""), "Unknown") AS country,
COALESCE(NULLIF(s.region, ""), "Unknown") AS region,
COUNT(*) AS sessions,
COUNT(DISTINCT s.visitor_id) AS visitors,
SUM(s.page_views) AS page_views
FROM sessions s
WHERE s.started_at BETWEEN ? AND ?' . $websiteSql . '
GROUP BY country, region
ORDER BY sessions DESC
LIMIT 100',
'ss' . $websiteTypes,
array_merge([$fromUtc, $toUtc], $websiteParams)
);
$cityRows = db_fetch_all(
'SELECT COALESCE(NULLIF(s.country, ""), "Unknown") AS country,
COALESCE(NULLIF(s.region, ""), "Unknown") AS region,
COALESCE(NULLIF(s.city, ""), "Unknown") AS city,
COUNT(*) AS sessions,
COUNT(DISTINCT s.visitor_id) AS visitors,
SUM(s.page_views) AS page_views
FROM sessions s
WHERE s.started_at BETWEEN ? AND ?' . $websiteSql . '
GROUP BY country, region, city
ORDER BY sessions DESC
LIMIT 100',
'ss' . $websiteTypes,
array_merge([$fromUtc, $toUtc], $websiteParams)
);
$countryLabels = array_map(static fn (array $row): string => country_label((string) $row['country']), $countryRows);
$countryValues = array_map(static fn (array $row): int => (int) $row['sessions'], $countryRows);
function country_label(string $code): string
{
$countries = [
'IE' => 'Ireland',
'GB' => 'United Kingdom',
'US' => 'United States',
'CA' => 'Canada',
'AU' => 'Australia',
'NZ' => 'New Zealand',
'FR' => 'France',
'DE' => 'Germany',
'ES' => 'Spain',
'IT' => 'Italy',
'NL' => 'Netherlands',
'BE' => 'Belgium',
'PT' => 'Portugal',
'SE' => 'Sweden',
'NO' => 'Norway',
'DK' => 'Denmark',
'FI' => 'Finland',
'PL' => 'Poland',
'IN' => 'India',
'BR' => 'Brazil',
];
return $countries[$code] ?? $code;
}
require APP_ROOT . '/templates/admin_header.php';
?>
<h1 class="h3 mb-3">Countries</h1>
<?= report_filter_form('admin/countries.php', $fromDate, $toDate) ?>
<div class="row g-4 mb-4">
<section class="col-lg-5">
<div class="card">
<div class="card-header bg-white">Top countries</div>
<div class="card-body chart-panel">
<canvas data-chart="doughnut" data-labels="<?= e(json_encode($countryLabels, JSON_THROW_ON_ERROR)) ?>" data-values="<?= e(json_encode($countryValues, JSON_THROW_ON_ERROR)) ?>"></canvas>
</div>
</div>
</section>
<section class="col-lg-7">
<div class="card">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead><tr><th>Country</th><th class="text-end">Sessions</th><th class="text-end">Visitors</th><th class="text-end">Page views</th><th class="text-end">Avg session</th></tr></thead>
<tbody>
<?php if ($countryRows === []): ?><tr><td colspan="5" class="text-center text-muted py-5">No country data for this range.</td></tr><?php endif; ?>
<?php foreach ($countryRows as $row): ?>
<tr>
<td><?= e(country_label((string) $row['country'])) ?></td>
<td class="text-end"><?= (int) $row['sessions'] ?></td>
<td class="text-end"><?= (int) $row['visitors'] ?></td>
<td class="text-end"><?= (int) $row['page_views'] ?></td>
<td class="text-end"><?= e(seconds_to_duration((float) $row['avg_duration'])) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</section>
</div>
<div class="card mb-4">
<div class="card-header bg-white">Cities</div>
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead><tr><th>Country</th><th>Region</th><th>City</th><th class="text-end">Sessions</th><th class="text-end">Visitors</th><th class="text-end">Page views</th></tr></thead>
<tbody>
<?php if ($cityRows === []): ?><tr><td colspan="6" class="text-center text-muted py-5">No city data for this range.</td></tr><?php endif; ?>
<?php foreach ($cityRows as $row): ?>
<tr>
<td><?= e(country_label((string) $row['country'])) ?></td>
<td><?= e($row['region']) ?></td>
<td><?= e($row['city']) ?></td>
<td class="text-end"><?= (int) $row['sessions'] ?></td>
<td class="text-end"><?= (int) $row['visitors'] ?></td>
<td class="text-end"><?= (int) $row['page_views'] ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<div class="card">
<div class="card-header bg-white">Regions</div>
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead><tr><th>Country</th><th>Region</th><th class="text-end">Sessions</th><th class="text-end">Visitors</th><th class="text-end">Page views</th></tr></thead>
<tbody>
<?php if ($regionRows === []): ?><tr><td colspan="5" class="text-center text-muted py-5">No region data for this range.</td></tr><?php endif; ?>
<?php foreach ($regionRows as $row): ?>
<tr>
<td><?= e(country_label((string) $row['country'])) ?></td>
<td><?= e($row['region']) ?></td>
<td class="text-end"><?= (int) $row['sessions'] ?></td>
<td class="text-end"><?= (int) $row['visitors'] ?></td>
<td class="text-end"><?= (int) $row['page_views'] ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php require APP_ROOT . '/templates/admin_footer.php'; ?>