Script erstellt

This commit is contained in:
Housemann
2025-08-10 18:09:07 +02:00
commit 2a15995cbb
196 changed files with 24790 additions and 0 deletions

View File

@@ -0,0 +1,212 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use App\Models\NailPolish;
use App\Models\Manufacturer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
class AdminController extends Controller
{
/**
* Dashboard für Administratoren
*/
public function dashboard()
{
$totalUsers = User::count();
$totalNailPolishes = NailPolish::count();
$totalManufacturers = Manufacturer::count();
$recentUsers = User::latest()->take(5)->get();
$recentNailPolishes = NailPolish::latest()->take(5)->get();
$recentManufacturers = Manufacturer::latest()->take(5)->get();
return view("admin.dashboard", compact("totalUsers", "totalNailPolishes", "totalManufacturers", "recentUsers", "recentNailPolishes", "recentManufacturers"));
}
/**
* Liste aller Benutzer
*/
public function users(Request $request)
{
$search = $request->get("search");
$users = User::when($search, function($query) use ($search) {
return $query->where("name", "like", "%{$search}%")
->orWhere("email", "like", "%{$search}%");
})->orderBy("name")->paginate(20);
return view("admin.users.index", compact("users", "search"));
}
/**
* Formular zum Erstellen eines neuen Benutzers
*/
public function createUser()
{
return view("admin.users.create");
}
/**
* Neuen Benutzer speichern
*/
public function storeUser(Request $request)
{
$request->validate([
"name" => "required|string|max:255",
"email" => "required|string|email|max:255|unique:users",
"password" => "required|string|min:8|confirmed",
]);
// Passwort für E-Mail speichern (wird nach dem Speichern gelöscht)
$plainPassword = $request->password;
// User erstellen
$user = User::create([
"name" => $request->name,
"email" => $request->email,
"password" => Hash::make($request->password),
"is_admin" => $request->has("is_admin"),
]);
// Willkommens-E-Mail senden
try {
Mail::send("emails.welcome-user", [
"user" => $user,
"password" => $plainPassword
], function($message) use ($user) {
$message->to($user->email, $user->name)
->subject("🎨 Willkommen bei der NeoNail DB - Ihre Login-Daten")
->from(config("mail.from.address"), config("mail.from.name"));
});
// Admin-Bestätigung senden
Mail::raw("Hallo Admin!
Ein neuer User wurde erfolgreich erstellt und eine Willkommens-E-Mail gesendet.
📋 User-Details:
- Name: {$user->name}
- E-Mail: {$user->email}
- Admin-Status: " . ($user->isAdmin() ? "Ja" : "Nein") . "
- Erstellt: " . now() . "
Die Willkommens-E-Mail enthält:
- Login-Daten (Website, E-Mail, Passwort)
- Aufforderung zum Passwort-Ändern
- Feature-Übersicht
- Direkte Links zur Anwendung
Viele Grüße,
NeoNail DB System", function($message) {
$message->to("oliver@vogt.de.com", "Admin")
->subject("✅ NeoNail DB - Neuer User erstellt")
->from(config("mail.from.address"), config("mail.from.name"));
});
$successMessage = "Benutzer erfolgreich erstellt! Willkommens-E-Mail wurde gesendet.";
} catch (\Exception $e) {
// User wurde erstellt, aber E-Mail fehlgeschlagen
\Log::error("Fehler beim Senden der Willkommens-E-Mail: " . $e->getMessage());
$successMessage = "Benutzer erfolgreich erstellt! E-Mail konnte nicht gesendet werden.";
}
return redirect()->route("admin.users.index")
->with("success", $successMessage);
}
/**
* Formular zum Bearbeiten eines Benutzers
*/
public function editUser(User $user)
{
return view("admin.users.edit", compact("user"));
}
/**
* Benutzer aktualisieren
*/
public function updateUser(Request $request, User $user)
{
$request->validate([
"name" => "required|string|max:255",
"email" => "required|string|email|max:255|unique:users,email," . $user->id,
"password" => "nullable|string|min:8|confirmed",
]);
$user->name = $request->name;
$user->email = $request->email;
$user->is_admin = $request->has("is_admin");
if ($request->filled("password")) {
$user->password = Hash::make($request->password);
}
$user->save();
return redirect()->route("admin.users.index")
->with("success", "Benutzer erfolgreich aktualisiert!");
}
/**
* Benutzer löschen
*/
public function destroyUser(User $user)
{
$userName = $user->name;
$userEmail = $user->email;
$user->delete();
// Admin-Benachrichtigung über gelöschten User
try {
Mail::raw("Hallo Admin!
Ein User wurde erfolgreich gelöscht.
📋 Gelöschter User:
- Name: {$userName}
- E-Mail: {$userEmail}
- Gelöscht: " . now() . "
Viele Grüße,
NeoNail DB System", function($message) {
$message->to("oliver@vogt.de.com", "Admin")
->subject("🗑️ NeoNail DB - User gelöscht")
->from(config("mail.from.address"), config("mail.from.name"));
});
} catch (\Exception $e) {
\Log::error("Fehler beim Senden der Lösch-Benachrichtigung: " . $e->getMessage());
}
return redirect()->route("admin.users.index")
->with("success", "Benutzer erfolgreich gelöscht!");
}
/**
* Statistiken anzeigen
*/
public function statistics()
{
$totalUsers = User::count();
$totalNailPolishes = NailPolish::count();
$usersWithCollections = User::has("nailPolishes")->count();
$averageCollectionSize = User::withCount("nailPolishes")->avg("nail_polishes_count");
$topUsers = User::withCount("nailPolishes")
->orderBy("nail_polishes_count", "desc")
->take(10)
->get();
return view("admin.statistics", compact(
"totalUsers",
"totalNailPolishes",
"usersWithCollections",
"averageCollectionSize",
"topUsers"
));
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function showLoginForm()
{
return view('auth.login');
}
public function login(Request $request)
{
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (Auth::attempt($credentials, $request->boolean('remember'))) {
$request->session()->regenerate();
return redirect()->intended(route('user-nail-polishes.index'));
}
return back()->withErrors([
'email' => 'Die angegebenen Anmeldedaten stimmen nicht überein.',
])->onlyInput('email');
}
public function logout(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace App\Http\Controllers;
abstract class Controller
{
//
}

View File

@@ -0,0 +1,154 @@
<?php
namespace App\Http\Controllers;
use App\Models\Manufacturer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ManufacturerController extends Controller
{
/**
* Zeigt alle Hersteller an
*/
public function index(Request $request)
{
$search = $request->get('search');
$query = Manufacturer::withCount('nailPolishes');
if ($search) {
$query->search($search);
}
$manufacturers = $query->orderBy('name')->paginate(20);
return view('manufacturers.index', compact('manufacturers', 'search'));
}
/**
* Zeigt das Formular zum Erstellen eines neuen Herstellers
*/
public function create()
{
return view('manufacturers.create');
}
/**
* Speichert einen neuen Hersteller
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255|unique:manufacturers',
'description' => 'nullable|string|max:1000',
'website' => 'nullable|url|max:255',
'country' => 'nullable|string|max:100',
]);
try {
$manufacturer = Manufacturer::create([
'name' => $request->name,
'description' => $request->description,
'website' => $request->website,
'country' => $request->country,
]);
return redirect()->route('manufacturers.index')
->with('success', "Hersteller '{$manufacturer->name}' wurde erfolgreich erstellt!");
} catch (\Exception $e) {
\Log::error("Fehler beim Erstellen des Herstellers: " . $e->getMessage());
return back()->with('error', 'Fehler beim Erstellen des Herstellers. Bitte versuchen Sie es erneut.')
->withInput();
}
}
/**
* Zeigt einen Hersteller an
*/
public function show(Manufacturer $manufacturer)
{
$manufacturer->load(['nailPolishes' => function($query) {
$query->orderBy('name');
}]);
return view('manufacturers.show', compact('manufacturer'));
}
/**
* Zeigt das Formular zum Bearbeiten eines Herstellers
*/
public function edit(Manufacturer $manufacturer)
{
return view('manufacturers.edit', compact('manufacturer'));
}
/**
* Aktualisiert einen Hersteller
*/
public function update(Request $request, Manufacturer $manufacturer)
{
$request->validate([
'name' => 'required|string|max:255|unique:manufacturers,name,' . $manufacturer->id,
'description' => 'nullable|string|max:1000',
'website' => 'nullable|url|max:255',
'country' => 'nullable|string|max:100',
]);
try {
$manufacturer->update([
'name' => $request->name,
'description' => $request->description,
'website' => $request->website,
'country' => $request->country,
]);
return redirect()->route('manufacturers.index')
->with('success', "Hersteller '{$manufacturer->name}' wurde erfolgreich aktualisiert!");
} catch (\Exception $e) {
\Log::error("Fehler beim Aktualisieren des Herstellers: " . $e->getMessage());
return back()->with('error', 'Fehler beim Aktualisieren des Herstellers. Bitte versuchen Sie es erneut.')
->withInput();
}
}
/**
* Löscht einen Hersteller
*/
public function destroy(Manufacturer $manufacturer)
{
try {
// Prüfe, ob der Hersteller noch Nagellacke hat
if ($manufacturer->hasNailPolishes()) {
return back()->with('error', "Hersteller '{$manufacturer->name}' kann nicht gelöscht werden, da noch Nagellacke zugeordnet sind.");
}
$name = $manufacturer->name;
$manufacturer->delete();
return redirect()->route('manufacturers.index')
->with('success', "Hersteller '{$name}' wurde erfolgreich gelöscht!");
} catch (\Exception $e) {
\Log::error("Fehler beim Löschen des Herstellers: " . $e->getMessage());
return back()->with('error', 'Fehler beim Löschen des Herstellers. Bitte versuchen Sie es erneut.');
}
}
/**
* API-Endpoint für AJAX-Suche nach Herstellern
*/
public function search(Request $request)
{
$search = $request->get('q');
$manufacturers = Manufacturer::where('name', 'like', "%{$search}%")
->orderBy('name')
->limit(10)
->get(['id', 'name']);
return response()->json($manufacturers);
}
}

View File

@@ -0,0 +1,165 @@
<?php
namespace App\Http\Controllers;
use App\Models\NailPolish;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;
class NailPolishController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$search = $request->get('search');
$nailPolishes = NailPolish::when($search, function($query) use ($search) {
return $query->search($search);
})->orderBy('name')->paginate(20);
return view('nail-polishes.index', compact('nailPolishes', 'search'));
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view('nail-polishes.create');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'number' => 'required|string|max:50|unique:nail_polishes',
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048'
]);
$nailPolish = new NailPolish();
$nailPolish->name = $request->name;
$nailPolish->number = $request->number;
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = time() . '_' . $image->getClientOriginalName();
// Bild optimieren und speichern
$optimizedImage = Image::make($image)
->resize(300, 300, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})
->encode('jpg', 80);
Storage::disk('public')->put('nail-polishes/' . $filename, $optimizedImage);
$nailPolish->image_path = 'nail-polishes/' . $filename;
}
$nailPolish->save();
return redirect()->route('nail-polishes.index')
->with('success', 'Nagellack erfolgreich hinzugefügt!');
}
/**
* Display the specified resource.
*/
public function show(NailPolish $nailPolish)
{
return view('nail-polishes.show', compact('nailPolish'));
}
/**
* Show the form for editing the specified resource.
*/
public function edit(NailPolish $nailPolish)
{
return view('nail-polishes.edit', compact('nailPolish'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, NailPolish $nailPolish)
{
$request->validate([
'name' => 'required|string|max:255',
'number' => 'required|string|max:50|unique:nail_polishes,number,' . $nailPolish->id,
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048'
]);
$nailPolish->name = $request->name;
$nailPolish->number = $request->number;
if ($request->hasFile('image')) {
// Altes Bild löschen
if ($nailPolish->image_path) {
Storage::disk('public')->delete($nailPolish->image_path);
}
$image = $request->file('image');
$filename = time() . '_' . $image->getClientOriginalName();
// Bild optimieren und speichern
$optimizedImage = Image::make($image)
->resize(300, 300, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})
->encode('jpg', 80);
Storage::disk('public')->put('nail-polishes/' . $filename, $optimizedImage);
$nailPolish->image_path = 'nail-polishes/' . $filename;
}
$nailPolish->save();
return redirect()->route('nail-polishes.index')
->with('success', 'Nagellack erfolgreich aktualisiert!');
}
/**
* Löscht einen Nagellack
*/
public function destroy(NailPolish $nailPolish)
{
try {
// Prüfe, ob der Lack von anderen Usern verwendet wird
$usersWithThisPolish = $nailPolish->users()->count();
if ($usersWithThisPolish > 0) {
return back()->with('error', "Dieser Lack kann nicht gelöscht werden, da er von {$usersWithThisPolish} Benutzer(n) in ihrer Sammlung verwendet wird. Bitte entfernen Sie ihn zuerst aus allen Sammlungen.");
}
// Lösche das Bild, falls vorhanden
if ($nailPolish->image_path && Storage::disk('public')->exists($nailPolish->image_path)) {
Storage::disk('public')->delete($nailPolish->image_path);
}
$nailPolish->delete();
return redirect()->route('nail-polishes.index')
->with('success', "Lack '{$nailPolish->name}' wurde erfolgreich gelöscht!");
} catch (\Exception $e) {
return back()->with('error', 'Fehler beim Löschen des Lackes: ' . $e->getMessage());
}
}
/**
* Zeigt an, welche User einen bestimmten Lack haben
*/
public function showUsers(NailPolish $nailPolish)
{
$users = $nailPolish->users()->paginate(20);
return view('nail-polishes.show-users', compact('nailPolish', 'users'));
}
}

View File

@@ -0,0 +1,186 @@
<?php
namespace App\Http\Controllers;
use App\Models\NailPolish;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
class UserNailPolishController extends Controller
{
/**
* Zeigt die Sammlung des aktuellen Benutzers an
*/
public function index(Request $request)
{
$user = Auth::user();
$search = $request->get("search");
$query = $user->nailPolishes();
if ($search) {
$query->where(function($q) use ($search) {
$q->where("name", "like", "%{$search}%")
->orWhere("number", "like", "%{$search}%");
});
}
$nailPolishes = $query->orderBy("name")->paginate(12);
return view("user-nail-polishes.index", compact("nailPolishes", "search"));
}
/**
* Zeigt alle verfügbaren Lacke an, die der User noch nicht hat
*/
public function available(Request $request)
{
$user = Auth::user();
$search = $request->get("search");
$query = NailPolish::whereNotIn("id", $user->nailPolishes()->pluck("nail_polishes.id"));
if ($search) {
$query->search($search);
}
$nailPolishes = $query->orderBy("name")->paginate(12);
return view("user-nail-polishes.available", compact("nailPolishes", "search"));
}
/**
* Fügt einen Lack zur Sammlung des Users hinzu
*/
public function add(NailPolish $nailPolish)
{
$user = Auth::user();
// Prüfe, ob der Lack bereits in der Sammlung ist
if ($user->nailPolishes()->where("nail_polish_id", $nailPolish->id)->exists()) {
return back()->with("warning", "Dieser Lack ist bereits in Ihrer Sammlung!");
}
$user->nailPolishes()->attach($nailPolish->id);
return back()->with("success", "Lack \"{$nailPolish->name}\" wurde zu Ihrer Sammlung hinzugefügt!");
}
/**
* Entfernt einen Lack aus der Sammlung des Users
*/
public function remove(NailPolish $nailPolish)
{
try {
$user = Auth::user();
// Prüfe, ob der Lack in der Sammlung ist
if (!$user->nailPolishes()->where("nail_polish_id", $nailPolish->id)->exists()) {
return back()->with("warning", "Dieser Lack ist nicht in Ihrer Sammlung!");
}
$user->nailPolishes()->detach($nailPolish->id);
return back()->with("success", "Lack \"{$nailPolish->name}\" wurde aus Ihrer Sammlung entfernt!");
} catch (\Exception $e) {
\Log::error("Fehler beim Entfernen des Lackes: " . $e->getMessage());
return back()->with("error", "Fehler beim Entfernen des Lackes. Bitte versuchen Sie es erneut.");
}
}
/**
* Zeigt das Formular zum Erstellen eines neuen Lackes
*/
public function create()
{
return view("user-nail-polishes.create");
}
/**
* Speichert einen neuen Lack (wird automatisch zum Hauptkatalog hinzugefügt)
*/
public function store(Request $request)
{
$request->validate([
"name" => "required|string|max:255",
"number" => "required|string|max:50",
"manufacturer_id" => "required_without:new_manufacturer|exists:manufacturers,id",
"new_manufacturer" => "required_without:manufacturer_id|string|max:255|unique:manufacturers,name",
"image" => "nullable|image|max:10240", // Max 10MB
], [
"name.required" => "Der Name des Lackes ist erforderlich.",
"number.required" => "Die Nummer des Lackes ist erforderlich.",
"manufacturer_id.required_without" => "Bitte wählen Sie einen Hersteller aus oder erstellen Sie einen neuen.",
"new_manufacturer.required_without" => "Bitte wählen Sie einen Hersteller aus oder erstellen Sie einen neuen.",
"new_manufacturer.unique" => "Ein Hersteller mit diesem Namen existiert bereits.",
"image.image" => "Die Datei muss ein Bild sein.",
"image.max" => "Das Bild darf maximal 10MB groß sein.",
]);
try {
// Hersteller verarbeiten
$manufacturerId = null;
if ($request->filled('new_manufacturer')) {
// Neuen Hersteller erstellen
$manufacturer = \App\Models\Manufacturer::create([
'name' => trim($request->new_manufacturer),
]);
$manufacturerId = $manufacturer->id;
} else {
$manufacturerId = $request->manufacturer_id;
}
$nailPolish = new NailPolish();
$nailPolish->name = trim($request->name);
$nailPolish->number = trim($request->number);
$nailPolish->manufacturer_id = $manufacturerId;
// Vereinfachte Bildverarbeitung ohne Intervention Image
if ($request->hasFile("image") && $request->file("image")->isValid()) {
$image = $request->file("image");
// Erstelle einen eindeutigen Dateinamen
$filename = "nail_polish_" . time() . "_" . uniqid() . "." . $image->getClientOriginalExtension();
$path = "nail_polishes/" . $filename;
// Speichere das Bild direkt ohne Verarbeitung
Storage::disk("public")->putFileAs("nail_polishes", $image, $filename);
$nailPolish->image_path = $path;
\Log::info("Bild erfolgreich gespeichert: " . $path);
}
$nailPolish->save();
// Füge den Lack automatisch zur Sammlung des Users hinzu
$user = Auth::user();
$user->nailPolishes()->attach($nailPolish->id);
$successMessage = "Lack \"{$nailPolish->name}\" wurde erfolgreich erstellt und zu Ihrer Sammlung hinzugefügt!";
if ($request->filled('new_manufacturer')) {
$successMessage .= " Neuer Hersteller \"{$request->new_manufacturer}\" wurde ebenfalls erstellt.";
}
return redirect()->route("user-nail-polishes.index")
->with("success", $successMessage);
} catch (\Exception $e) {
\Log::error("Fehler beim Erstellen des Lackes: " . $e->getMessage());
return back()->with("error", "Fehler beim Erstellen des Lackes: " . $e->getMessage())
->withInput();
}
}
/**
* Zeigt die Sammlung eines bestimmten Users (für Admin)
*/
public function showUserCollection(User $user)
{
$nailPolishes = $user->nailPolishes()->orderBy("name")->paginate(12);
return view("user-nail-polishes.show-user", compact("user", "nailPolishes"));
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
// Admin-Berechtigung mit is_admin Spalte
if (!auth()->check() || !auth()->user()->isAdmin()) {
abort(403, 'Zugriff verweigert. Admin-Berechtigung erforderlich.');
}
return $next($request);
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class Authenticate
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next, string ...$guards): Response
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (!Auth::guard($guard)->check()) {
return redirect()->route('login');
}
}
return $next($request);
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next, string ...$guards): Response
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return redirect()->route('user-nail-polishes.index');
}
}
return $next($request);
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Manufacturer extends Model
{
use HasFactory;
/**
* Die Tabelle, die dem Model zugeordnet ist.
*/
protected $table = 'manufacturers';
protected $fillable = [
'name',
'description',
'website',
'country',
];
/**
* Beziehung zu Nagellacken
*/
public function nailPolishes()
{
return $this->hasMany(NailPolish::class);
}
/**
* Scope für Suche nach Name
*/
public function scopeSearch($query, $search)
{
return $query->where('name', 'like', "%{$search}%")
->orWhere('description', 'like', "%{$search}%")
->orWhere('country', 'like', "%{$search}%");
}
/**
* Gibt den Namen des Herstellers zurück
*/
public function getDisplayNameAttribute()
{
return $this->name;
}
/**
* Prüft, ob der Hersteller Nagellacke hat
*/
public function hasNailPolishes()
{
return $this->nailPolishes()->exists();
}
/**
* Anzahl der Nagellacke dieses Herstellers
*/
public function getNailPolishCountAttribute()
{
return $this->nailPolishes()->count();
}
}

48
app/Models/NailPolish.php Executable file
View File

@@ -0,0 +1,48 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class NailPolish extends Model
{
use HasFactory;
/**
* Die Tabelle, die dem Model zugeordnet ist.
*/
protected $table = 'nail_polishes';
protected $fillable = [
'name',
'number',
'manufacturer_id',
'image_path',
];
/**
* Beziehung zu Benutzern
*/
public function users()
{
return $this->belongsToMany(User::class, 'user_nail_polishes', 'nail_polish_id', 'user_id');
}
/**
* Beziehung zum Hersteller
*/
public function manufacturer()
{
return $this->belongsTo(Manufacturer::class);
}
/**
* Scope für Suche nach Name oder Nummer
*/
public function scopeSearch($query, $search)
{
return $query->where('name', 'like', "%{$search}%")
->orWhere('number', 'like', "%{$search}%");
}
}

83
app/Models/User.php Executable file
View File

@@ -0,0 +1,83 @@
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var list<string>
*/
protected $fillable = [
'name',
'email',
'password',
'is_admin',
];
/**
* The attributes that should be hidden for serialization.
*
* @var list<string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
/**
* Beziehung zu Nagellacken
*/
public function nailPolishes()
{
return $this->belongsToMany(NailPolish::class, 'user_nail_polishes', 'user_id', 'nail_polish_id');
}
/**
* Prüft, ob der User ein Admin ist
*/
public function isAdmin()
{
return $this->is_admin || in_array($this->email, ['admin@neonail.com', 'neueradmin@neonail.com']);
}
/**
* Macht den User zum Admin
*/
public function makeAdmin()
{
$this->is_admin = true;
$this->save();
}
/**
* Entfernt Admin-Rechte
*/
public function removeAdmin()
{
$this->is_admin = false;
$this->save();
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\URL;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
if (config('app.env') === 'production') {
URL::forceScheme('https');
}
}
}