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>
This commit is contained in:
112
app/Http/Controllers/FileController.php
Normal file
112
app/Http/Controllers/FileController.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user