bmc_hub/deploy/website/content.php

164 lines
4.3 KiB
PHP
Raw Permalink Normal View History

2026-08-28 20:49:55 +02:00
<?php
declare(strict_types=1);
require_once __DIR__ . '/bootstrap.php';
function outputCustomerLogo(PDO $pdo, int $id): void
{
$statement = $pdo->prepare(
'SELECT logo_blob, logo_mime_type, updated_at
FROM customer_references
WHERE id = ? AND is_active = 1 AND logo_blob IS NOT NULL
LIMIT 1'
);
$statement->execute([$id]);
$logo = $statement->fetch();
$allowed = ['image/png', 'image/jpeg', 'image/webp', 'image/gif'];
if (!$logo || !is_string($logo['logo_blob'])) {
http_response_code(404);
exit;
}
$mime = (string)($logo['logo_mime_type'] ?? '');
if (!in_array($mime, $allowed, true)) {
http_response_code(415);
exit;
}
$etag = '"' . sha1((string)$logo['updated_at'] . ':' . strlen($logo['logo_blob'])) . '"';
if (trim((string)($_SERVER['HTTP_IF_NONE_MATCH'] ?? '')) === $etag) {
http_response_code(304);
exit;
}
header('Content-Type: ' . $mime);
header('Content-Length: ' . strlen($logo['logo_blob']));
header('Cache-Control: public, max-age=3600');
header('ETag: ' . $etag);
header('X-Content-Type-Options: nosniff');
echo $logo['logo_blob'];
exit;
}
function outputCachedCustomerLogo(int $id): void
{
$types = ['png' => 'image/png', 'jpg' => 'image/jpeg', 'webp' => 'image/webp', 'gif' => 'image/gif'];
foreach ($types as $extension => $mime) {
$path = __DIR__ . '/content-cache-logos/' . $id . '.' . $extension;
if (!is_file($path)) {
continue;
}
header('Content-Type: ' . $mime);
header('Content-Length: ' . filesize($path));
header('Cache-Control: public, max-age=3600');
header('X-Content-Type-Options: nosniff');
readfile($path);
exit;
}
http_response_code(404);
exit;
}
function cachedContent(): ?array
{
$path = __DIR__ . '/content-cache.json';
if (!is_file($path)) {
return null;
}
$decoded = json_decode((string)file_get_contents($path), true);
return is_array($decoded) ? $decoded : null;
}
if (isset($_GET['logo'])) {
$logoId = filter_input(INPUT_GET, 'logo', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
if (!$logoId) {
http_response_code(400);
exit;
}
try {
outputCustomerLogo(bmc_db(), $logoId);
} catch (Throwable $e) {
outputCachedCustomerLogo($logoId);
}
}
function fetchCustomers(PDO $pdo): array
{
$sql = "SELECT customer_name, logo_url, website_url
FROM customer_references
WHERE is_active = 1
ORDER BY sort_order ASC, customer_name ASC
LIMIT 50";
return $pdo->query($sql)->fetchAll();
}
function fetchCurrentOperation(PDO $pdo): ?array
{
$sql = "SELECT title, severity, message, starts_at, ends_at, updated_at
FROM operations_status
WHERE is_active = 1
AND (starts_at IS NULL OR starts_at <= NOW())
AND (ends_at IS NULL OR ends_at >= NOW())
ORDER BY updated_at DESC
LIMIT 1";
$row = $pdo->query($sql)->fetch();
return $row ?: null;
}
function fetchOperationHistory(PDO $pdo): array
{
$sql = "SELECT title, severity, message, starts_at, ends_at, updated_at
FROM operations_incidents
WHERE is_public = 1
ORDER BY updated_at DESC
LIMIT 20";
return $pdo->query($sql)->fetchAll();
}
try {
$pdo = bmc_db();
$customers = [];
$current = null;
$history = [];
try {
$customers = fetchCustomers($pdo);
} catch (Throwable $e) {
$customers = [];
}
try {
$current = fetchCurrentOperation($pdo);
} catch (Throwable $e) {
$current = null;
}
try {
$history = fetchOperationHistory($pdo);
} catch (Throwable $e) {
$history = [];
}
bmc_json_response([
'meta' => [
'generated_at' => gmdate('c'),
],
'customers' => $customers,
'operations' => [
'current' => $current,
'history' => $history,
],
]);
} catch (Throwable $e) {
$cached = cachedContent();
if ($cached !== null) {
bmc_json_response($cached);
}
bmc_json_response([
'error' => 'content_unavailable',
'message' => 'Kunne ikke hente dynamisk indhold.',
], 503);
}