false, 'message' => 'Method not allowed']); exit; } $allowedTypes = ['Kampfrichter', 'Trainer', 'Wk_leitung', 'Otl', 'icon', 'logo-normal']; if (!isset($_POST['type']) || !in_array($_POST['type'], $allowedTypes)) { http_response_code(400); echo json_encode(['success' => false, 'message' => 'Typ nicht angegeben oder nicht erlaubt']); exit; } $pngs = ['icon', 'logo-normal']; $type = $_POST['type']; $isIcon = in_array($type, $pngs); // Check if $_FILES is empty entirely (can happen if post_max_size exceeded) if (empty($_FILES)) { http_response_code(400); echo json_encode([ 'success' => false, 'message' => 'No files received. The file may exceed the server upload limit).', ]); exit; } // Check specific file field if (!isset($_FILES['image'])) { http_response_code(400); echo json_encode([ 'success' => false, 'message' => 'No "image" field in upload. Received fields: ' . implode(', ', array_keys($_FILES)), ]); exit; } if ($_FILES['image']['error'] !== UPLOAD_ERR_OK) { http_response_code(400); $errors = [ UPLOAD_ERR_INI_SIZE => 'File exceeds upload_max_filesize', UPLOAD_ERR_FORM_SIZE => 'File exceeds form MAX_FILE_SIZE', UPLOAD_ERR_PARTIAL => 'File was only partially uploaded', UPLOAD_ERR_NO_FILE => 'No file was uploaded', UPLOAD_ERR_NO_TMP_DIR => 'Missing temp directory', UPLOAD_ERR_CANT_WRITE => 'Failed to write to disk', ]; $code = $_FILES['image']['error']; $msg = $errors[$code] ?? "Unknown error code: $code"; echo json_encode(['success' => false, 'message' => $msg]); exit; } $file = $_FILES['image']; $tmpPath = $file['tmp_name']; // Validate MIME type $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($tmpPath); $allowedMimes = ['image/jpeg', 'image/png', 'image/webp', 'image/gif']; if (!in_array($mime, $allowedMimes, true)) { http_response_code(415); echo json_encode(['success' => false, 'message' => "Unsupported file type: $mime"]); exit; } // Target directory if ($isIcon) { $uploadDir = $baseDir . '/intern/img/'; } else { $uploadDir = $baseDir . '/intern/img/login'; } if (!is_dir($uploadDir)) { mkdir($uploadDir, 0755, true); } // Load image into GD $srcImage = null; switch ($mime) { case 'image/jpeg': $srcImage = @imagecreatefromjpeg($tmpPath); break; case 'image/png': $srcImage = @imagecreatefrompng($tmpPath); break; case 'image/webp': $srcImage = @imagecreatefromwebp($tmpPath); break; case 'image/gif': $srcImage = @imagecreatefromgif($tmpPath); break; } if (!$srcImage) { http_response_code(500); echo json_encode(['success' => false, 'message' => 'Failed to load image into GD. It may be corrupt or too large.']); exit; } // ── Resize if needed ──────────────────────────────── $origW = imagesx($srcImage); $origH = imagesy($srcImage); $maxDimension = ($isIcon) ? MAX_DIMENSION_ICON : MAX_DIMENSION; if ($origW > $maxDimension || $origH > $maxDimension) { // Calculate new dimensions keeping aspect ratio if ($origW >= $origH) { $newW = $maxDimension; $newH = intval(round($origH * ($maxDimension / $origW))); } else { $newH = $maxDimension; $newW = intval(round($origW * ($maxDimension / $origH))); } $resized = imagecreatetruecolor($newW, $newH); // Preserve transparency imagealphablending($resized, false); imagesavealpha($resized, true); $transparent = imagecolorallocatealpha($resized, 0, 0, 0, 127); imagefill($resized, 0, 0, $transparent); imagecopyresampled($resized, $srcImage, 0, 0, 0, 0, $newW, $newH, $origW, $origH); imagedestroy($srcImage); $srcImage = $resized; } else { // Still preserve transparency imagepalettetotruecolor($srcImage); imagealphablending($srcImage, true); imagesavealpha($srcImage, true); } if ($isIcon) { // ── Save as PNG ──────────────────────────────────── $filename = $type . '.png'; $destPath = $uploadDir . '/' . $filename; $webPath = '/intern/img/' . $filename; $pngCompression = 6; $success = imagepng($srcImage, $destPath, $pngCompression); } else { // ── Save as WebP ──────────────────────────────────── $filename = 'bg' . $_POST['type'] . '.webp'; $destPath = $uploadDir . '/' . $filename; $webPath = '/intern/img/admin_upload/' . $filename; $success = imagewebp($srcImage, $destPath, WEBP_QUALITY); } imagedestroy($srcImage); if (!$success) { http_response_code(500); echo json_encode(['success' => false, 'message' => 'Failed to convert to WebP']); exit; } echo json_encode([ 'success' => true ]);