Add Larastan level 7 analysis
All checks were successful
Tests / Laravel tests (pull_request) Successful in 2m36s

This commit is contained in:
2026-06-03 22:09:33 +02:00
parent 53c4823b22
commit eb9c8796de
27 changed files with 341 additions and 71 deletions

View File

@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Auth\Events\Verified;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\EmailVerificationRequest;
use Illuminate\Http\RedirectResponse;
@@ -14,12 +15,18 @@ class VerifyEmailController extends Controller
*/
public function __invoke(EmailVerificationRequest $request): RedirectResponse
{
if ($request->user()->hasVerifiedEmail()) {
$user = $request->user();
if (! $user instanceof MustVerifyEmail) {
abort(403);
}
if ($user->hasVerifiedEmail()) {
return redirect()->intended(route('dashboard', absolute: false).'?verified=1');
}
if ($request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
if ($user->markEmailAsVerified()) {
event(new Verified($user));
}
return redirect()->intended(route('dashboard', absolute: false).'?verified=1');

View File

@@ -4,23 +4,25 @@ namespace App\Http\Controllers;
use App\Http\Requests\EducationRequest;
use App\Models\Education;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class EducationController extends Controller
{
public function index()
public function index(): View
{
$educations = Education::with('media')->latest()->get();
return view('educations.index', compact('educations'));
}
public function create()
public function create(): View
{
return view('educations.create');
}
public function store(EducationRequest $request)
public function store(EducationRequest $request): RedirectResponse
{
$education = Education::create($request->validated());
@@ -29,12 +31,12 @@ class EducationController extends Controller
return redirect()->route('educations.index')->with('success', 'Opleiding toegevoegd.');
}
public function edit(Education $education)
public function edit(Education $education): View
{
return view('educations.edit', compact('education'));
}
public function update(EducationRequest $request, Education $education)
public function update(EducationRequest $request, Education $education): RedirectResponse
{
$education->update($request->validated());
@@ -43,7 +45,7 @@ class EducationController extends Controller
return redirect()->route('educations.index')->with('success', 'Opleiding bijgewerkt.');
}
public function destroy(Education $education)
public function destroy(Education $education): RedirectResponse
{
$education->clearMediaCollection('image');
$education->delete();

View File

@@ -8,11 +8,13 @@ use App\Models\Education;
use App\Models\Personalia;
use App\Models\Skill;
use App\Models\WorkExperience;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class FrontendController extends Controller
{
public function index()
public function index(): View
{
$skills = Skill::all()->groupBy('type');
@@ -23,21 +25,20 @@ class FrontendController extends Controller
return view('welcome', compact('skills', 'personalia', 'education', 'experience'));
}
public function getPersonalia($id)
public function getPersonalia(Personalia $personalia): JsonResponse
{
$item = Personalia::findOrFail($id);
NotifyTelegramAboutPersonaliaClick::dispatch(
$item,
$personalia,
request()->ip(),
request()->userAgent()
);
return response()->json([
'value' => $item->value,
'value' => $personalia->value,
]);
}
public function message(Request $request)
public function message(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => 'required|string|max:255',

View File

@@ -2,24 +2,26 @@
namespace App\Http\Controllers;
use App\Models\Personalia;
use App\Http\Requests\PersonaliaRequest;
use App\Models\Personalia;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
class PersonaliaController extends Controller
{
public function index()
public function index(): View
{
$personalia = Personalia::all();
return view('personalia.index', compact('personalia'));
}
public function create()
public function create(): View
{
return view('personalia.create');
}
public function store(PersonaliaRequest $request)
public function store(PersonaliaRequest $request): RedirectResponse
{
$validated = $request->validated();
@@ -31,13 +33,13 @@ class PersonaliaController extends Controller
return redirect()->route('personalia.index')->with('success', 'Persoonlijk item toegevoegd.');
}
public function edit(Personalia $personalium)
public function edit(Personalia $personalium): View
{
return view('personalia.edit', ['personalia' => $personalium]);
}
public function update(PersonaliaRequest $request, Personalia $personalium)
public function update(PersonaliaRequest $request, Personalia $personalium): RedirectResponse
{
$validated = $request->validated();
@@ -45,10 +47,11 @@ class PersonaliaController extends Controller
...$validated,
'hidden' => $request->boolean('hidden'),
]);
return redirect()->route('personalia.index')->with('success', 'Persoonlijk item bijgewerkt.');
}
public function destroy(Personalia $personalium)
public function destroy(Personalia $personalium): RedirectResponse
{
$personalium->delete();

View File

@@ -2,23 +2,26 @@
namespace App\Http\Controllers;
use App\Models\Skill;
use App\Http\Requests\SkillRequest;
use App\Models\Skill;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
class SkillController extends Controller
{
public function index()
public function index(): View
{
$skills = Skill::latest()->get();
return view('skills.index', compact('skills'));
}
public function create()
public function create(): View
{
return view('skills.create');
}
public function store(SkillRequest $request)
public function store(SkillRequest $request): RedirectResponse
{
$skill = Skill::create($request->validated());
@@ -29,12 +32,12 @@ class SkillController extends Controller
return redirect()->route('skills.index')->with('success', 'Vaardigheid toegevoegd.');
}
public function edit(Skill $skill)
public function edit(Skill $skill): View
{
return view('skills.edit', compact('skill'));
}
public function update(SkillRequest $request, Skill $skill)
public function update(SkillRequest $request, Skill $skill): RedirectResponse
{
$skill->update($request->validated());
@@ -46,7 +49,7 @@ class SkillController extends Controller
return redirect()->route('skills.index')->with('success', 'Vaardigheid bijgewerkt.');
}
public function destroy(Skill $skill)
public function destroy(Skill $skill): RedirectResponse
{
$skill->clearMediaCollection('image');
$skill->delete();

View File

@@ -2,24 +2,26 @@
namespace App\Http\Controllers;
use App\Models\WorkExperience;
use App\Http\Requests\WorkExperienceRequest;
use App\Models\WorkExperience;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
class WorkExperienceController extends Controller
{
public function index()
public function index(): View
{
$experiences = WorkExperience::with('media')->latest()->get();
return view('work_experiences.index', compact('experiences'));
}
public function create()
public function create(): View
{
return view('work_experiences.create');
}
public function store(WorkExperienceRequest $request)
public function store(WorkExperienceRequest $request): RedirectResponse
{
$experience = WorkExperience::create($request->validated());
@@ -30,12 +32,12 @@ class WorkExperienceController extends Controller
return redirect()->route('work-experiences.index')->with('success', 'Ervaring toegevoegd.');
}
public function edit(WorkExperience $workExperience)
public function edit(WorkExperience $workExperience): View
{
return view('work_experiences.edit', compact('workExperience'));
}
public function update(WorkExperienceRequest $request, WorkExperience $workExperience)
public function update(WorkExperienceRequest $request, WorkExperience $workExperience): RedirectResponse
{
$workExperience->update($request->validated());
@@ -47,7 +49,7 @@ class WorkExperienceController extends Controller
return redirect()->route('work-experiences.index')->with('success', 'Ervaring bijgewerkt.');
}
public function destroy(WorkExperience $workExperience)
public function destroy(WorkExperience $workExperience): RedirectResponse
{
$workExperience->clearMediaCollection('image');
$workExperience->delete();

View File

@@ -11,6 +11,9 @@ class EducationRequest extends FormRequest
return true;
}
/**
* @return array<string, list<string>>
*/
public function rules(): array
{
return [
@@ -23,6 +26,9 @@ class EducationRequest extends FormRequest
];
}
/**
* @return array<string, string>
*/
public function messages(): array
{
return [

View File

@@ -11,6 +11,9 @@ class PersonaliaRequest extends FormRequest
return true;
}
/**
* @return array<string, list<string>>
*/
public function rules(): array
{
return [
@@ -21,6 +24,9 @@ class PersonaliaRequest extends FormRequest
];
}
/**
* @return array<string, string>
*/
public function messages(): array
{
return [
@@ -28,5 +34,4 @@ class PersonaliaRequest extends FormRequest
'value.required' => 'Een waarde is verplicht.',
];
}
}

View File

@@ -11,6 +11,9 @@ class SkillRequest extends FormRequest
return true;
}
/**
* @return array<string, list<string>>
*/
public function rules(): array
{
return [
@@ -21,6 +24,10 @@ class SkillRequest extends FormRequest
'type' => ['required', 'in:rating,tag,other'],
];
}
/**
* @return array<string, string>
*/
public function messages(): array
{
return [
@@ -29,5 +36,4 @@ class SkillRequest extends FormRequest
'type.in' => 'Het type moet rating, tag of other zijn.',
];
}
}

View File

@@ -11,6 +11,9 @@ class WorkExperienceRequest extends FormRequest
return true;
}
/**
* @return array<string, list<string>>
*/
public function rules(): array
{
return [
@@ -23,6 +26,9 @@ class WorkExperienceRequest extends FormRequest
];
}
/**
* @return array<string, string>
*/
public function messages(): array
{
return [

View File

@@ -21,9 +21,9 @@ class NotifyTelegramAboutContactMessage implements ShouldQueue
protected string $userAgent;
protected string $email;
protected ?string $email;
protected string $phone;
protected ?string $phone;
public function __construct(string $name, string $message, string $ip, string $userAgent, ?string $email = null, ?string $phone = null)
{
@@ -35,7 +35,7 @@ class NotifyTelegramAboutContactMessage implements ShouldQueue
$this->phone = $phone;
}
public function handle()
public function handle(): void
{
$email = $this->email ?? '';
$phone = $this->phone ?? '';

View File

@@ -14,27 +14,30 @@ class NotifyTelegramAboutPersonaliaClick implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $personalia;
protected Personalia $personalia;
protected $ip;
protected ?string $ip;
protected $userAgent;
protected ?string $userAgent;
public function __construct(Personalia $personalia, $ip, $userAgent)
public function __construct(Personalia $personalia, ?string $ip, ?string $userAgent)
{
$this->personalia = $personalia;
$this->ip = $ip;
$this->userAgent = $userAgent;
}
public function handle()
public function handle(): void
{
$ip = $this->ip ?? '';
$userAgent = $this->userAgent ?? '';
$message = <<<TEXT
👤 *Persoonlijke gegevens bekeken*
Naam: {$this->personalia->value}
IP: {$this->ip}
User Agent: `{$this->userAgent}`
IP: {$ip}
User Agent: `{$userAgent}`
📅 Tijdstip: *{now()->format('d-m-Y H:i')}*
TEXT;

View File

@@ -6,10 +6,13 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class Education extends Model implements HasMedia
{
/** @use HasFactory<\Database\Factories\EducationFactory> */
use HasFactory;
use InteractsWithMedia;
protected $table = 'education';
@@ -22,12 +25,12 @@ class Education extends Model implements HasMedia
'beschrijving',
];
public function image()
public function image(): ?Media
{
return $this->getFirstMedia('image');
}
public function imageUrl()
public function imageUrl(): ?string
{
return $this->image() ? $this->image()->getUrl() : null;
}

View File

@@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Model;
class Personalia extends Model
{
/** @use HasFactory<\Database\Factories\PersonaliaFactory> */
use HasFactory;
protected $fillable = ['key', 'value', 'hidden', 'icon'];
@@ -16,14 +17,4 @@ class Personalia extends Model
protected $casts = [
'hidden' => 'boolean',
];
public function image()
{
return $this->getFirstMedia('image');
}
public function imageUrl()
{
return $this->image() ? $this->image()->getUrl() : null;
}
}

View File

@@ -6,20 +6,23 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class Skill extends Model implements HasMedia
{
/** @use HasFactory<\Database\Factories\SkillFactory> */
use HasFactory;
use InteractsWithMedia;
protected $fillable = ['title', 'description', 'rating', 'type'];
public function image()
public function image(): ?Media
{
return $this->getFirstMedia('image');
}
public function imageUrl()
public function imageUrl(): ?string
{
return $this->image() ? $this->image()->getUrl() : null;
}

View File

@@ -2,11 +2,12 @@
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
class User extends Authenticatable implements MustVerifyEmail
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable;

View File

@@ -6,10 +6,13 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class WorkExperience extends Model implements HasMedia
{
/** @use HasFactory<\Database\Factories\WorkExperienceFactory> */
use HasFactory;
use InteractsWithMedia;
protected $fillable = [
@@ -20,12 +23,12 @@ class WorkExperience extends Model implements HasMedia
'beschrijving',
];
public function image()
public function image(): ?Media
{
return $this->getFirstMedia('image');
}
public function imageUrl()
public function imageUrl(): ?string
{
return $this->image() ? $this->image()->getUrl() : null;
}