prepare intranet for first Dokploy deployment

This commit is contained in:
2026-08-26 12:59:51 +02:00
parent 5cfe688bdc
commit 29dfb85fef
1321 changed files with 227234 additions and 0 deletions
@@ -0,0 +1,133 @@
<?php
// Prüft, ob ein Basisname dem von der Anwendung erzeugten Format entspricht.
function isValidNewsFileBase(string $fileBase): bool
{
return preg_match(
'/^\d{4}-\d{2}-\d{2}-[A-Za-z0-9_-]+$/D',
$fileBase
) === 1;
}
/**
* Löscht eine News vollständig:
*
* - Original-PDF
* - alle daraus erzeugten PNG-Seiten
*/
function deleteNewsFiles(string $fileBase): bool
{
if (!isValidNewsFileBase($fileBase)) {
error_log('Ungültiger News-Dateiname beim Löschen: ' . $fileBase);
return false;
}
$newsDirectory = __DIR__ . '/news';
$pngDirectory = $newsDirectory . '/png';
$success = true;
// Alle erzeugten PNG-Seiten löschen
$pngFiles = glob(
$pngDirectory . '/' . $fileBase . '_page_*.png'
) ?: [];
foreach ($pngFiles as $pngFile) {
if (is_file($pngFile) && !unlink($pngFile)) {
error_log('News-PNG konnte nicht gelöscht werden: ' . $pngFile);
$success = false;
}
}
// Original-PDF löschen
$pdfFile = $newsDirectory . '/' . $fileBase . '.pdf';
if (is_file($pdfFile) && !unlink($pdfFile)) {
error_log('News-PDF konnte nicht gelöscht werden: ' . $pdfFile);
$success = false;
}
return $success;
}
/**
* Löscht alle abgelaufenen News.
*
* Wichtig:
* Es werden sowohl vorhandene PDFs als auch page_1-PNGs betrachtet.
* Dadurch werden auch verwaiste PDFs ohne PNG zuverlässig gefunden.
*/
function cleanupExpiredNews(): void
{
$newsDirectory = __DIR__ . '/news';
$pngDirectory = $newsDirectory . '/png';
$fileBases = [];
// PDFs erfassen
foreach (glob($newsDirectory . '/*.pdf') ?: [] as $pdfFile) {
$fileBase = pathinfo($pdfFile, PATHINFO_FILENAME);
if (isValidNewsFileBase($fileBase)) {
$fileBases[$fileBase] = true;
}
}
// Zusätzlich PNGs erfassen.
// Damit funktioniert die Bereinigung auch, falls die PDF bereits fehlt.
foreach (glob($pngDirectory . '/*_page_1.png') ?: [] as $pngFile) {
$fileName = basename($pngFile);
$suffix = '_page_1.png';
if (!str_ends_with($fileName, $suffix)) {
continue;
}
$fileBase = substr($fileName, 0, -strlen($suffix));
if (isValidNewsFileBase($fileBase)) {
$fileBases[$fileBase] = true;
}
}
$now = new DateTimeImmutable();
foreach (array_keys($fileBases) as $fileBase) {
// YYYY-MM-DD aus dem Dateinamen holen
$expiryDateString = substr($fileBase, 0, 10);
$expiryDate = DateTimeImmutable::createFromFormat(
'!Y-m-d',
$expiryDateString
);
// Zusätzlich prüfen, ob wirklich ein gültiges Datum entstanden ist
if (
$expiryDate === false ||
$expiryDate->format('Y-m-d') !== $expiryDateString
) {
error_log(
'Ungültiges Ablaufdatum bei News-Datei: ' . $fileBase
);
continue;
}
/*
* Aushang bleibt den gesamten angegebenen Tag sichtbar.
* Beispiel Ablaufdatum 2026-09-05:
* Löschung ab 2026-09-06 00:00 Uhr.
*/
$deleteFrom = $expiryDate->modify('+1 day');
if ($now >= $deleteFrom) {
if (!deleteNewsFiles($fileBase)) {
error_log(
'Abgelaufene News konnte nicht vollständig gelöscht werden: '
. $fileBase
);
}
}
}
}