diff --git a/hifi/.htaccess b/hifi/.htaccess
index 52d6f9c..f7802f0 100644
--- a/hifi/.htaccess
+++ b/hifi/.htaccess
@@ -22,6 +22,34 @@ RewriteBase /
# Upload mit "Methode nicht erlaubt" fehlschlägt.
DirectorySlash Off
+# Groessere Upload-/POST-Limits fuer den Daten-Export/-Import im Admin-Bereich
+# (der Export bettet die Bildergalerie als Base64 direkt in die JSON-Datei ein,
+# das kann schnell 40+ MB werden - PHPs Standard-Limits liegen oft niedriger).
+# Nur relevant, wenn PHP als Apache-Modul laeuft (mod_php) - die IfModule-Pruefung
+# sorgt dafuer, dass dieser Block auf FastCGI/PHP-FPM-Hosting (dort greift
+# stattdessen api/public/.user.ini) folgenlos uebersprungen wird, statt einen
+# "Invalid command"-Fehler fuer die ganze Seite auszuloesen.
+
+ php_value upload_max_filesize 200M
+ php_value post_max_size 200M
+ php_value memory_limit 512M
+
+
+ php_value upload_max_filesize 200M
+ php_value post_max_size 200M
+ php_value memory_limit 512M
+
+
+ php_value upload_max_filesize 200M
+ php_value post_max_size 200M
+ php_value memory_limit 512M
+
+
+ php_value upload_max_filesize 200M
+ php_value post_max_size 200M
+ php_value memory_limit 512M
+
+
# API-Requests an den PHP-Front-Controller weiterleiten
RewriteCond %{REQUEST_URI} ^/api/
RewriteCond %{REQUEST_FILENAME} !-f
diff --git a/hifi/api/public/.user.ini b/hifi/api/public/.user.ini
new file mode 100644
index 0000000..167ddca
--- /dev/null
+++ b/hifi/api/public/.user.ini
@@ -0,0 +1,8 @@
+; Groessere Upload-/POST-Limits fuer den Daten-Export/-Import im Admin-Bereich
+; (der Export bettet die Bildergalerie als Base64 direkt in die JSON-Datei ein,
+; das kann schnell 40+ MB werden). Greift auf PHP-FPM/CGI-Hosting (z.B. viele
+; Shared-Hosting-Umgebungen) - fuer klassisches Apache-Modul-PHP (mod_php)
+; uebernimmt stattdessen der php_value-Block in hifi/.htaccess.
+upload_max_filesize = 200M
+post_max_size = 200M
+memory_limit = 512M
diff --git a/hifi/api/src/Controllers/SettingsController.php b/hifi/api/src/Controllers/SettingsController.php
index 025baa7..d277fc3 100644
--- a/hifi/api/src/Controllers/SettingsController.php
+++ b/hifi/api/src/Controllers/SettingsController.php
@@ -70,11 +70,53 @@ class SettingsController
exit;
}
+ /** Wandelt eine php.ini-Groessenangabe ("200M", "1G", "512K") in Bytes um. */
+ private static function iniBytes(string $value): int
+ {
+ $value = trim($value);
+ if ($value === '') {
+ return 0;
+ }
+ $num = (float) $value;
+ return match (strtolower(substr($value, -1))) {
+ 'g' => (int) ($num * 1024 * 1024 * 1024),
+ 'm' => (int) ($num * 1024 * 1024),
+ 'k' => (int) ($num * 1024),
+ default => (int) $value,
+ };
+ }
+
public static function importData(): void
{
- if (!empty($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
+ if (!empty($_FILES['file'])) {
+ $uploadError = $_FILES['file']['error'];
+ if ($uploadError === UPLOAD_ERR_INI_SIZE || $uploadError === UPLOAD_ERR_FORM_SIZE) {
+ Http::error(
+ 'Die Datei überschreitet das Upload-Limit dieses Servers (aktuell ' . ini_get('upload_max_filesize') .
+ '). Bitte den Hosting-Anbieter um ein höheres PHP-Upload-Limit bitten.',
+ 422
+ );
+ }
+ if ($uploadError !== UPLOAD_ERR_OK) {
+ Http::error('Datei-Upload fehlgeschlagen (Fehlercode ' . $uploadError . ').', 422);
+ }
$raw = file_get_contents($_FILES['file']['tmp_name']);
} else {
+ // Ein Upload, der post_max_size ueberschreitet, wird von PHP nicht in $_FILES
+ // aufgenommen - der rohe Body ist ueber php://input aber trotzdem da (nur eben
+ // noch als unverarbeitetes Multipart-Gemisch, kein gueltiges JSON). Deshalb direkt
+ // Content-Length gegen das konfigurierte Limit pruefen, statt block auf einen
+ // (nicht garantiert leeren) Body zu vertrauen - sonst landet eine zu grosse, aber
+ // eigentlich intakte Export-Datei im irrefuehrenden generischen "ungueltige Datei"-Fehler.
+ $contentLength = (int) ($_SERVER['CONTENT_LENGTH'] ?? 0);
+ $maxPost = self::iniBytes((string) ini_get('post_max_size'));
+ if ($maxPost > 0 && $contentLength > $maxPost) {
+ Http::error(
+ 'Die Datei überschreitet das Größen-Limit dieses Servers (aktuell ' . ini_get('post_max_size') .
+ '). Bitte den Hosting-Anbieter um ein höheres PHP-Upload-Limit (post_max_size) bitten.',
+ 422
+ );
+ }
$raw = file_get_contents('php://input');
}