🆙 Fix more errors php stan 🆙

This commit is contained in:
Remco
2026-01-19 17:50:34 +01:00
parent 521f9c884c
commit 649f9f311d
26 changed files with 210 additions and 68 deletions
+4 -3
View File
@@ -3,15 +3,16 @@
namespace App\Actions;
use App\Enums\CurrencyTypes;
use App\Models\User;
use App\Services\RconService;
class SendCurrency
{
public function __construct(protected RconService $rcon) {}
public function execute($user, string $type, ?int $amount)
public function execute(User $user, string $type, ?int $amount): bool
{
if (! $amount && $amount <= 0) {
if (! $amount || $amount <= 0) {
return false;
}
@@ -33,6 +34,6 @@ class SendCurrency
};
}
return null;
return true;
}
}
@@ -10,7 +10,7 @@ use App\Services\User\UserApiService;
class HotelApiController extends Controller
{
public function __construct(private readonly UserApiService $userApiService) {}
public function __construct(private readonly UserApiService $userApiService): void {}
public function fetchUser(string $username, array $columns = ['username', 'motto', 'look']): UserResource
{
@@ -11,7 +11,7 @@ use Illuminate\Http\RedirectResponse;
class WebsiteArticleCommentsController extends Controller
{
public function __construct(public readonly CommentService $commentService) {}
public function __construct(public readonly CommentService $commentService): void {}
public function store(WebsiteArticle $article, ArticleCommentFormRequest $request): RedirectResponse
{
@@ -13,7 +13,7 @@ class LeaderboardController extends Controller
{
protected array $staffIds = [];
public function __construct(private readonly StaffService $staffService)
public function __construct(private readonly StaffService $staffService): void
{
$this->staffIds = $this->staffService->fetchEmployeeIds();
}
@@ -44,7 +44,7 @@ class LeaderboardController extends Controller
]);
}
private function retrieveSettings($column)
private function retrieveSettings(string $column): \Illuminate\Database\Eloquent\Collection
{
return UserSetting::select('user_id', $column)
->whereNotIn('user_id', $this->staffIds)
@@ -8,7 +8,7 @@ use Illuminate\View\View;
class PhotosController extends Controller
{
public function __construct(private readonly CameraService $cameraService) {}
public function __construct(private readonly CameraService $cameraService): void {}
public function __invoke(): View
{
@@ -6,20 +6,21 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\StaffApplicationFormRequest;
use App\Models\Community\Staff\WebsiteOpenPosition;
use App\Services\Community\StaffApplicationService;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
class StaffApplicationsController extends Controller
{
public function __construct(private readonly StaffApplicationService $staffApplicationService) {}
public function __construct(private readonly StaffApplicationService $staffApplicationService): void {}
public function index()
public function index(): View
{
return view('community.staff-applications', [
'positions' => $this->staffApplicationService->fetchOpenPositions(),
]);
}
public function show(WebsiteOpenPosition $position)
public function show(WebsiteOpenPosition $position): View
{
return view('community.staff-applications-apply', [
'position' => $position->load('permission'),
@@ -8,7 +8,7 @@ use Illuminate\View\View;
class StaffController extends Controller
{
public function __construct(private readonly StaffService $staffService) {}
public function __construct(private readonly StaffService $staffService): void {}
public function __invoke(): View
{
@@ -8,7 +8,7 @@ use Illuminate\View\View;
class WebsiteTeamsController extends Controller
{
public function __construct(private readonly TeamService $teamService) {}
public function __construct(private readonly TeamService $teamService): void {}
public function __invoke(): View
{
@@ -14,7 +14,7 @@ use Illuminate\View\View;
class WebsiteRareValuesController extends Controller
{
public function __construct(private readonly RareValueCategoriesService $valueCategoriesService) {}
public function __construct(private readonly RareValueCategoriesService $valueCategoriesService): void {}
public function index(): View
{
@@ -4,10 +4,11 @@ namespace App\Http\Controllers\Help;
use App\Http\Controllers\Controller;
use App\Models\Help\WebsiteHelpCenterCategory;
use Illuminate\Contracts\View\View;
class HelpCenterController extends Controller
{
public function __invoke()
public function __invoke(): View
{
return view('help-center.index', [
'categories' => WebsiteHelpCenterCategory::orderBy('position')->get(),
@@ -6,11 +6,13 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\WebsiteTicketFormRequest;
use App\Models\Help\WebsiteHelpCenterCategory;
use App\Models\Help\WebsiteHelpCenterTicket;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Contracts\View\View;
class TicketController extends Controller
{
public function index()
public function index(): View|RedirectResponse
{
if (hasPermission('manage_website_tickets') === '' || hasPermission('manage_website_tickets') === '0') {
return back()->with([
@@ -23,7 +25,7 @@ class TicketController extends Controller
]);
}
public function create()
public function create(): View
{
return view('help-center.tickets.create', [
'categories' => WebsiteHelpCenterCategory::get(),
@@ -31,14 +33,14 @@ class TicketController extends Controller
]);
}
public function store(WebsiteTicketFormRequest $request)
public function store(WebsiteTicketFormRequest $request): RedirectResponse
{
Auth::user()->tickets()->create($request->validated());
return back()->with('success', __('Ticket submitted!'));
}
public function edit(WebsiteHelpCenterTicket $ticket)
public function edit(WebsiteHelpCenterTicket $ticket): View|RedirectResponse
{
if (! $ticket->canManageTicket()) {
return back()->with([
@@ -59,7 +61,7 @@ class TicketController extends Controller
]);
}
public function update(WebsiteHelpCenterTicket $ticket, WebsiteTicketFormRequest $request)
public function update(WebsiteHelpCenterTicket $ticket, WebsiteTicketFormRequest $request): RedirectResponse
{
if (! $ticket->canManageTicket()) {
return back()->with([
@@ -72,7 +74,7 @@ class TicketController extends Controller
return to_route('help-center.ticket.show', $ticket)->with('success', __('Ticket updated!'));
}
public function show(WebsiteHelpCenterTicket $ticket)
public function show(WebsiteHelpCenterTicket $ticket): View|RedirectResponse
{
if (! $ticket->canManageTicket()) {
return back()->with([
@@ -92,7 +94,7 @@ class TicketController extends Controller
]);
}
public function destroy(WebsiteHelpCenterTicket $ticket)
public function destroy(WebsiteHelpCenterTicket $ticket): RedirectResponse
{
if (! $ticket->canDeleteTicket()) {
return back()->with([
@@ -105,7 +107,7 @@ class TicketController extends Controller
return to_route('me.show')->with('success', __('The ticket has been deleted!'));
}
public function toggleTicketStatus(WebsiteHelpCenterTicket $ticket)
public function toggleTicketStatus(WebsiteHelpCenterTicket $ticket): RedirectResponse
{
if (! $ticket->canManageTicket()) {
return back()->with([
@@ -6,10 +6,11 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\WebsiteTicketReplyFormRequest;
use App\Models\Help\WebsiteHelpCenterTicket;
use App\Models\Help\WebsiteHelpCenterTicketReply;
use Illuminate\Http\RedirectResponse;
class TicketReplyController extends Controller
{
public function store(WebsiteHelpCenterTicket $ticket, WebsiteTicketReplyFormRequest $request)
public function store(WebsiteHelpCenterTicket $ticket, WebsiteTicketReplyFormRequest $request): RedirectResponse
{
if (! $ticket->isOpen()) {
return back()->with([
@@ -32,7 +33,7 @@ class TicketReplyController extends Controller
return back()->with('success', __('The reply has been submitted!'));
}
public function destroy(WebsiteHelpCenterTicketReply $reply)
public function destroy(WebsiteHelpCenterTicketReply $reply): RedirectResponse
{
if (! $reply->canDeleteReply()) {
return back()->with([
@@ -7,18 +7,20 @@ use App\Models\Miscellaneous\WebsiteInstallation;
use App\Models\Miscellaneous\WebsiteSetting;
use App\Rules\ValidateInstallationKeyRule;
use Exception;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
class InstallationController extends Controller
{
public function index()
public function index(): View
{
return view('installation.index');
}
public function storeInstallationKey(Request $request)
public function storeInstallationKey(Request $request): RedirectResponse
{
$request->validate([
'installation_key' => ['required', 'string', 'max:255', new ValidateInstallationKeyRule],
@@ -32,16 +34,16 @@ class InstallationController extends Controller
return to_route('installation.show-step', 1);
}
public function showStep($currentStep)
public function showStep(int $currentStep): View
{
$settings = $this->getSettingsForStep((int) $currentStep);
$settings = $this->getSettingsForStep($currentStep);
return view('installation.step-' . $currentStep, [
'settings' => $settings,
]);
}
public function saveStepSettings(Request $request)
public function saveStepSettings(Request $request): RedirectResponse
{
$this->updateSettings($request);
@@ -50,14 +52,14 @@ class InstallationController extends Controller
return to_route('installation.show-step', WebsiteInstallation::first()->step);
}
public function previousStep()
public function previousStep(): RedirectResponse
{
WebsiteInstallation::decrement('step');
return to_route('installation.show-step', WebsiteInstallation::first()->step);
}
public function restartInstallation()
public function restartInstallation(): RedirectResponse
{
WebsiteInstallation::first()->update([
'step' => 0,
@@ -72,7 +74,7 @@ class InstallationController extends Controller
return to_route('installation.index');
}
public function completeInstallation()
public function completeInstallation(): RedirectResponse
{
WebsiteInstallation::latest()->first()->update([
'completed' => true,
@@ -89,7 +91,7 @@ class InstallationController extends Controller
return to_route('welcome');
}
private function updateSettings(Request $request)
private function updateSettings(Request $request): void
{
foreach ($request->except('_token') as $key => $value) {
WebsiteSetting::where('key', '=', $key)->update([
@@ -98,7 +100,7 @@ class InstallationController extends Controller
}
}
private function getSettingsForStep(int $step)
private function getSettingsForStep(int $step): \Illuminate\Database\Eloquent\Collection
{
$settingsData = array_chunk(WebsiteSetting::all()->pluck('key')->toArray(), ceil(WebsiteSetting::count() / 4));
@@ -107,7 +109,7 @@ class InstallationController extends Controller
2 => $settingsData[1] ?? [],
3 => $settingsData[2] ?? [],
4 => $settingsData[3] ?? [],
5 => [], // Completion step has no settings
5 => [],
default => throw new Exception('Step does not exist'),
};
@@ -4,11 +4,14 @@ namespace App\Http\Controllers\Miscellaneous;
use App\Http\Controllers\Controller;
use App\Models\Miscellaneous\WebsiteSetting;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class LogoGeneratorController extends Controller
{
public function index()
public function index(): View|RedirectResponse
{
if (hasPermission('generate_logo') === '' || hasPermission('generate_logo') === '0') {
return to_route('me.show')->with([
@@ -19,7 +22,7 @@ class LogoGeneratorController extends Controller
return view('logo-generator');
}
public function store(Request $request)
public function store(Request $request): JsonResponse
{
$request->validate(['logo' => ['required', 'image']]);
$file = $request->file('logo');
@@ -35,6 +38,5 @@ class LogoGeneratorController extends Controller
]);
return response()->json(['success' => true, 'message' => 'Logo updated!']);
}
}
@@ -16,7 +16,7 @@ class PaypalController extends Controller
private const string STATUS_COMPLETED = 'COMPLETED';
public function __construct(private PayPalClient $provider)
public function __construct(private PayPalClient $provider): void
{
$this->provider = new PayPalClient;
$this->provider->setApiCredentials(config('habbo.paypal'));
@@ -15,9 +15,9 @@ use Symfony\Component\HttpFoundation\Response;
class ShopController extends Controller
{
public function __construct(private readonly RconService $rconService) {}
public function __construct(private readonly RconService $rconService): void {}
public function __invoke(?WebsiteShopCategory $category)
public function __invoke(?WebsiteShopCategory $category): \Illuminate\Contracts\View\View
{
$packages = WebsiteShopArticle::orderBy('position');
@@ -31,7 +31,7 @@ class ShopController extends Controller
]);
}
private function giveBadges(User $user, string $badges)
private function giveBadges(User $user, string $badges): void
{
$badgeList = explode(';', $badges);
$ownedBadges = $user->badges()->pluck('badge_code')->toArray();
@@ -5,10 +5,11 @@ namespace App\Http\Controllers\Shop;
use App\Http\Controllers\Controller;
use App\Http\Requests\ShopVoucherFormRequest;
use App\Models\Shop\WebsiteShopVoucher;
use Illuminate\Http\RedirectResponse;
class ShopVoucherController extends Controller
{
public function __invoke(ShopVoucherFormRequest $request)
public function __invoke(ShopVoucherFormRequest $request): RedirectResponse
{
$user = $request->user();
$voucher = WebsiteShopVoucher::where('code', $request->string('code'))->first();
@@ -14,7 +14,11 @@ use Illuminate\View\View;
class AccountSettingsController extends Controller
{
public function __construct(private readonly SessionService $sessionService, private readonly UserService $userService, private readonly RconService $rconService) {}
public function __construct(
private readonly SessionService $sessionService,
private readonly UserService $userService,
private readonly RconService $rconService
): void {}
public function edit(): View
{
@@ -6,24 +6,25 @@ use App\Http\Controllers\Controller;
use App\Models\PasswordResetToken;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Mail;
class ForgotPasswordController extends Controller
{
public function __invoke()
public function __invoke(): View
{
return view('auth.passwords.forget');
}
public function submitForgetPassword(Request $request)
public function submitForgetPassword(Request $request): RedirectResponse
{
$request->validate([
'mail' => ['required', 'email'],
]);
// Do not tell the user that this email does not exist to prevent possible attacks
if (User::where('mail', $request->mail)->exists()) {
$token = Str::uuid();
PasswordResetToken::create([
@@ -40,14 +41,14 @@ class ForgotPasswordController extends Controller
return back()->with('success', __('We have e-mailed your password reset link!'));
}
public function showResetPassword(Request $request, string $token)
public function showResetPassword(Request $request, string $token): View|RedirectResponse
{
$prt = PasswordResetToken::select('token', 'created_at')->where('token', $token)->first();
if ($prt === null) {
return to_route('forgot.password.get')->withErrors('message', __('This token has expired!'));
}
$tokenExpiration = \Illuminate\Support\Facades\Date::now()->subMinutes(config('habbo.password_reset_token_time'));
if ($prt->created_at->gte($tokenExpiration)) { // gte = greater than or equals
if ($prt->created_at->gte($tokenExpiration)) {
$prt->delete();
return to_route('forgot.password.get')->withErrors('message', __('This token has expired!'));
@@ -58,7 +59,7 @@ class ForgotPasswordController extends Controller
]);
}
public function submitResetPassword(Request $request, string $token)
public function submitResetPassword(Request $request, string $token): RedirectResponse
{
$request->validate([
'password' => ['required', 'min:8', 'confirmed'],
@@ -6,13 +6,17 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\GuestbookFormRequest;
use App\Models\User;
use App\Models\User\WebsiteUserGuestbook;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
class GuestbookController extends Controller
{
public function store(User $user, GuestbookFormRequest $request)
public function store(User $user, GuestbookFormRequest $request): RedirectResponse
{
$this->validateGuestbookPost($user, $request);
$validation = $this->validateGuestbookPost($user, $request);
if ($validation !== null) {
return $validation;
}
$user->profileGuestbook()->create([
'user_id' => Auth::id(),
@@ -22,7 +26,7 @@ class GuestbookController extends Controller
return back()->with('success', __('Your message has been posted.'));
}
public function destroy(User $user, WebsiteUserGuestbook $guestbook)
public function destroy(User $user, WebsiteUserGuestbook $guestbook): RedirectResponse
{
if ($guestbook->user_id !== Auth::id() && $guestbook->profile_id !== $user->id && Auth::user()->rank < (int) setting('min_staff_rank')) {
return back()->withErrors([
@@ -35,7 +39,7 @@ class GuestbookController extends Controller
return back()->with('success', __('Your message has been deleted.'));
}
private function validateGuestbookPost(User $user, GuestbookFormRequest $request)
private function validateGuestbookPost(User $user, GuestbookFormRequest $request): ?RedirectResponse
{
if ($user->id === $request->user()->id) {
return $this->redirectWithError(__('You cannot post a message on your own profile.'));
@@ -45,9 +49,11 @@ class GuestbookController extends Controller
if ($user->profileGuestbook()->where('user_id', $request->user()->id)->count() >= $maxAllowedPostCount) {
return $this->redirectWithError(__('You have already posted :count messages on this profile.', ['count' => $maxAllowedPostCount]));
}
return null;
}
private function redirectWithError($message)
private function redirectWithError(string $message): RedirectResponse
{
return back()->withErrors(['message' => $message]);
}
@@ -4,10 +4,11 @@ namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Contracts\View\View;
class UserReferralController extends Controller
{
public function __invoke(string $referralCode)
public function __invoke(string $referralCode): View
{
User::where('referral_code', '=', $referralCode)->firstOrFail();
+39 -9
View File
@@ -41,6 +41,32 @@ use Laravel\Sanctum\HasApiTokens;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
/**
* @property int $id
* @property string $username
* @property string $mail
* @property string $password
* @property string $look
* @property string $motto
* @property int $credits
* @property int $rank
* @property string $ip_register
* @property string $ip_current
* @property int $account_created
* @property int $last_login
* @property int $last_online
* @property string|null $auth_ticket
* @property int $home_room
* @property string|null $referral_code
* @property bool $online
* @property bool $hidden_staff
* @property int|null $team_id
* @property string|null $two_factor_secret
* @property string|null $two_factor_recovery_codes
* @property \Illuminate\Support\Carbon|null $two_factor_confirmed_at
* @property string|null $remember_token
* @property \Illuminate\Support\Carbon|null $email_verified_at
*/
class User extends Authenticatable implements FilamentUser, HasName
{
use HasApiTokens, HasFactory, LogsActivity, Notifiable, TwoFactorAuthenticatable;
@@ -66,12 +92,12 @@ class User extends Authenticatable implements FilamentUser, HasName
return $this->hasMany(UserCurrency::class, 'user_id');
}
public function sessions()
public function sessions(): HasMany
{
return $this->hasMany(Session::class);
}
public function currency(string $currency)
public function currency(string $currency): int
{
if (! $this->relationLoaded('currencies')) {
$this->load('currencies');
@@ -81,9 +107,10 @@ class User extends Authenticatable implements FilamentUser, HasName
'duckets' => 0,
'diamonds' => 5,
'points' => 101,
default => 0,
};
return $this->currencies->where('type', $type)->first()->amount ?? 0;
return $this->currencies->where('type', $type)->first()?->amount ?? 0;
}
public function permission(): HasOne
@@ -126,7 +153,7 @@ class User extends Authenticatable implements FilamentUser, HasName
return $this->hasMany(MessengerFriendship::class, 'user_one_id');
}
public function referralsNeeded()
public function referralsNeeded(): int
{
$referrals = 0;
@@ -134,7 +161,7 @@ class User extends Authenticatable implements FilamentUser, HasName
$referrals = $this->referrals->referrals_total;
}
return setting('referrals_needed') - $referrals;
return (int) setting('referrals_needed') - $referrals;
}
public function ban(): HasOne
@@ -222,17 +249,20 @@ class User extends Authenticatable implements FilamentUser, HasName
return $this->hasMany(WebsiteUserGuestbook::class, 'user_id');
}
public function chatLogs()
public function chatLogs(): HasMany
{
return $this->hasMany(ChatlogRoom::class, 'user_from_id');
}
public function chatLogsPrivate()
public function chatLogsPrivate(): HasMany
{
return $this->hasMany(ChatlogPrivate::class, 'user_from_id');
}
public function getOnlineFriends(int $total = 10)
/**
* @return \Illuminate\Database\Eloquent\Collection<int, MessengerFriendship>
*/
public function getOnlineFriends(int $total = 10): \Illuminate\Database\Eloquent\Collection
{
return $this->friends()
->select(['user_two_id', 'users.id', 'users.username', 'users.look', 'users.motto', 'users.last_online'])
@@ -243,7 +273,7 @@ class User extends Authenticatable implements FilamentUser, HasName
->get();
}
public function confirmTwoFactorAuthentication($code)
public function confirmTwoFactorAuthentication(string $code): void
{
$codeIsValid = app(TwoFactorAuthenticationProvider::class)
->verify(decrypt($this->two_factor_secret), $code);
@@ -29,7 +29,7 @@ class FindRetrosService
/**
* Initialise Find Retros Service
*/
public function __construct()
public function __construct(): void
{
$this->client = new Client(['verify' => false]);
}
+1 -1
View File
@@ -10,7 +10,7 @@ class IpLookupService
public function __construct(private readonly string $apiKey) {}
public function ipLookup(string $ip)
public function ipLookup(string $ip): array
{
$response = Http::acceptJson()->get(sprintf('%s/%s?api-key=%s', $this->baseUrl, $ip, $this->apiKey));
+63
View File
@@ -0,0 +1,63 @@
<?php
/**
* PHPStan Type Fixer Script
* Dit script voegt automatisch return types toe aan constructors en veelvoorkomende controller patterns
*/
$fixes = [
// Constructor fixes (void return type)
[
'files' => [
'app/Http/Controllers/Community/LeaderboardController.php',
'app/Http/Controllers/Shop/PaypalController.php',
'app/Http/Controllers/Articles/WebsiteArticleCommentsController.php',
'app/Http/Controllers/Community/PhotosController.php',
'app/Http/Controllers/Community/WebsiteRareValuesController.php',
'app/Http/Controllers/Community/Staff/StaffController.php',
'app/Http/Controllers/Community/Staff/WebsiteTeamsController.php',
'app/Http/Controllers/Api/HotelApiController.php',
'app/Http/Controllers/User/AccountSettingsController.php',
'app/Services/FindRetrosService.php',
'app/Services/HousekeepingPermissionsService.php',
],
'pattern' => '/public function __construct\((.*?)\)(\s*{)/s',
'replacement' => 'public function __construct($1): void$2',
],
];
$filesFixed = 0;
$totalChanges = 0;
foreach ($fixes as $fix) {
foreach ($fix['files'] as $file) {
if (!file_exists($file)) {
echo "⚠️ Bestand niet gevonden: $file\n";
continue;
}
$content = file_get_contents($file);
$original = $content;
// Controleer of er al `: void` staat
if (preg_match('/public function __construct\(.*?\): void/', $content)) {
echo "✓ Al correct: $file\n";
continue;
}
$content = preg_replace($fix['pattern'], $fix['replacement'], $content, -1, $count);
if ($count > 0 && $content !== $original) {
file_put_contents($file, $content);
$filesFixed++;
$totalChanges += $count;
echo "✓ Gefixt: $file ($count wijzigingen)\n";
}
}
}
echo "\n";
echo "========================================\n";
echo "Totaal bestanden gewijzigd: $filesFixed\n";
echo "Totaal wijzigingen: $totalChanges\n";
echo "========================================\n";
+26
View File
@@ -0,0 +1,26 @@
includes:
- vendor/larastan/larastan/extension.neon
parameters:
paths:
- app
- config
- database
- routes
level: 5
excludePaths:
- app/Console/Kernel.php
- app/Exceptions/Handler.php
- bootstrap
- storage
- vendor
ignoreErrors:
- '#PHPDoc tag @var#'
- '#Unsafe usage of new static#'
checkMissingIterableValueType: false
checkGenericClassInNonGenericObjectType: false
reportUnmatchedIgnoredErrors: false