- 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>
113 lines
3.2 KiB
PHP
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);
|
|
}
|
|
}
|
|
}
|