Fix PostgreSQL SUBSTRING on timestamp: use CAST AS DATE with native SQL

SUBSTRING does not work on timestamp in PostgreSQL. Use native SQL
with CAST(created_at AS DATE) for daily chart aggregation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-26 12:15:06 +01:00
parent 375357ddde
commit d4c897fd89

View File

@@ -768,25 +768,17 @@ class AdminController extends AbstractController
->getArrayResult();
// Daily chart data
$visitorsPerDay = $em->createQueryBuilder()
->select("SUBSTRING(v.createdAt, 1, 10) AS day, COUNT(v.id) AS cnt")
->from(AnalyticsUniqId::class, 'v')
->where('v.createdAt >= :since')
->setParameter('since', $since)
->groupBy('day')
->orderBy('day', 'ASC')
->getQuery()
->getArrayResult();
$conn = $em->getConnection();
$pageviewsPerDay = $em->createQueryBuilder()
->select("SUBSTRING(e.createdAt, 1, 10) AS day, COUNT(e.id) AS cnt")
->from(AnalyticsEvent::class, 'e')
->where('e.createdAt >= :since')
->setParameter('since', $since)
->groupBy('day')
->orderBy('day', 'ASC')
->getQuery()
->getArrayResult();
$visitorsPerDay = $conn->executeQuery(
'SELECT CAST(created_at AS DATE) AS day, COUNT(*) AS cnt FROM analytics_uniq_id WHERE created_at >= :since GROUP BY day ORDER BY day ASC',
['since' => $since->format('Y-m-d H:i:s')],
)->fetchAllAssociative();
$pageviewsPerDay = $conn->executeQuery(
'SELECT CAST(created_at AS DATE) AS day, COUNT(*) AS cnt FROM analytics_event WHERE created_at >= :since GROUP BY day ORDER BY day ASC',
['since' => $since->format('Y-m-d H:i:s')],
)->fetchAllAssociative();
// Merge into aligned arrays
$allDays = [];
@@ -794,8 +786,16 @@ class AdminController extends AbstractController
foreach ($pageviewsPerDay as $r) { $allDays[$r['day']] = true; }
ksort($allDays);
$visitorsMap = array_column($visitorsPerDay, 'cnt', 'day');
$pageviewsMap = array_column($pageviewsPerDay, 'cnt', 'day');
$visitorsMap = [];
foreach ($visitorsPerDay as $r) {
$d = $r['day'] instanceof \DateTimeInterface ? $r['day']->format('Y-m-d') : (string) $r['day'];
$visitorsMap[$d] = (int) $r['cnt'];
}
$pageviewsMap = [];
foreach ($pageviewsPerDay as $r) {
$d = $r['day'] instanceof \DateTimeInterface ? $r['day']->format('Y-m-d') : (string) $r['day'];
$pageviewsMap[$d] = (int) $r['cnt'];
}
$chartLabels = array_keys($allDays);
$chartVisitors = array_map(fn ($d) => (int) ($visitorsMap[$d] ?? 0), $chartLabels);