Files
WebAPP/app/Http/Controllers/FileController.php
Rhino 2e24a40d68 Stand: SMTP-Test, Admin-Mail-Tab, Notifiable-Fix, Lazy-Quill
- Fix: Notifiable-Trait zum User-Model hinzugefuegt (behebt notify()-500er)
- Installer: SMTP-Verbindungstest mit EsmtpTransport + Ueberspringen-Link
- Admin: Neuer E-Mail-Tab mit SMTP-Konfiguration + Verbindungstest
- Admin: Lazy Quill-Initialisierung (nur sichtbare Locale wird geladen)
- Uebersetzungen: 17 neue Mail-Keys in allen 6 Sprachen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 07:30:37 +01:00

113 lines
3.2 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\File;
use App\Models\FileCategory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\StreamedResponse;
class FileController extends Controller
{
public function index(Request $request): View
{
$categories = FileCategory::active()
->ordered()
->withCount('files')
->get();
$activeCategory = $request->query('category');
$query = File::with(['category', 'uploader'])
->whereHas('category', fn ($q) => $q->where('is_active', true))
->latest();
if ($activeCategory) {
$query->whereHas('category', fn ($q) => $q->where('slug', $activeCategory));
}
// Nicht-Staff-Nutzer sehen nur Dateien ohne Team-Zuordnung oder aus eigenen Teams
$user = auth()->user();
if (!$user->canAccessAdminPanel()) {
$userTeamIds = $user->accessibleTeamIds();
$query->where(function ($q) use ($userTeamIds) {
$q->whereDoesntHave('teams')
->orWhereHas('teams', fn ($tq) => $tq->whereIn('teams.id', $userTeamIds));
});
}
$files = $query->paginate(25)->withQueryString();
return view('files.index', compact('categories', 'files', 'activeCategory'));
}
public function download(File $file): StreamedResponse
{
$this->authorizeFileAccess($file);
$path = $file->getStoragePath();
if (!Storage::disk('local')->exists($path)) {
abort(404);
}
return Storage::disk('local')->download($path, $file->original_name);
}
public function preview(File $file)
{
$this->authorizeFileAccess($file);
if (!$file->isImage() && !$file->isPdf()) {
abort(404);
}
$path = $file->getStoragePath();
if (!Storage::disk('local')->exists($path)) {
abort(404);
}
return response()->file(
Storage::disk('local')->path($path),
['Content-Type' => $file->mime_type]
);
}
/**
* Autorisierung: User muss Zugriff auf die Datei-Kategorie haben.
* Admins/Coaches duerfen alles, Eltern nur Dateien aus aktiven Kategorien
* die einem ihrer Teams zugeordnet sind oder allgemein verfuegbar sind.
*/
private function authorizeFileAccess(File $file): void
{
$user = auth()->user();
// Staff darf alles
if ($user->canAccessAdminPanel()) {
return;
}
// Datei muss zu einer aktiven Kategorie gehoeren
if (!$file->category || !$file->category->is_active) {
abort(403);
}
// Pruefen ob Datei einem Team zugeordnet ist, auf das der User Zugriff hat
$userTeamIds = $user->accessibleTeamIds();
$fileTeamIds = $file->teams()->pluck('teams.id');
// Datei ohne Team-Zuordnung = allgemein verfuegbar
if ($fileTeamIds->isEmpty()) {
return;
}
// Mindestens ein Team muss uebereinstimmen
if ($fileTeamIds->intersect($userTeamIds)->isEmpty()) {
abort(403);
}
}
}