You've already forked Epicnabbo-Catalogus-Updated-Daily
🆙 phpstan done an refactoring 🆙
This commit is contained in:
@@ -52,12 +52,18 @@ class CreateNewUser implements CreatesNewUsers
|
||||
]);
|
||||
}
|
||||
|
||||
$this->validate($input);
|
||||
$validated = $this->validate($input);
|
||||
|
||||
if (! is_string($validated['username']) || ! is_string($validated['mail']) || ! is_string($validated['password'])) {
|
||||
throw ValidationException::withMessages([
|
||||
'registration' => __('Invalid registration data types'),
|
||||
]);
|
||||
}
|
||||
|
||||
$user = User::create([
|
||||
'username' => $input['username'],
|
||||
'mail' => $input['mail'],
|
||||
'password' => Hash::make((string) $input['password']),
|
||||
'username' => $validated['username'],
|
||||
'mail' => $validated['mail'],
|
||||
'password' => Hash::make($validated['password']),
|
||||
'account_created' => time(),
|
||||
'last_login' => time(),
|
||||
'motto' => setting('start_motto') ?: 'Welcome to the hotel!',
|
||||
|
||||
@@ -5,8 +5,11 @@ namespace App\Actions\Fortify;
|
||||
class DisableTwoFactorAuthentication extends \Laravel\Fortify\Actions\DisableTwoFactorAuthentication
|
||||
{
|
||||
#[\Override]
|
||||
public function __invoke($user)
|
||||
public function __invoke($user): void
|
||||
{
|
||||
if (! $user instanceof \App\Models\User) {
|
||||
return;
|
||||
}
|
||||
$user->forceFill([
|
||||
'two_factor_secret' => null,
|
||||
'two_factor_recovery_codes' => null,
|
||||
|
||||
@@ -45,18 +45,13 @@ class RedirectIfTwoFactorAuthenticatable
|
||||
$this->limiter = $limiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, callable $next)
|
||||
public function handle(Request $request, callable $next): mixed
|
||||
{
|
||||
$user = $this->validateCredentials($request);
|
||||
|
||||
if (Fortify::confirmsTwoFactorAuthentication()) {
|
||||
if ($user?->two_factor_secret &&
|
||||
! is_null($user?->two_factor_confirmed_at) &&
|
||||
if ($user->two_factor_secret &&
|
||||
! is_null($user->two_factor_confirmed_at) &&
|
||||
in_array(TwoFactorAuthenticatable::class, class_uses_recursive($user))) {
|
||||
return $this->twoFactorChallengeResponse($request, $user);
|
||||
} else {
|
||||
@@ -64,7 +59,7 @@ class RedirectIfTwoFactorAuthenticatable
|
||||
}
|
||||
}
|
||||
|
||||
if ($user?->two_factor_secret &&
|
||||
if ($user->two_factor_secret &&
|
||||
in_array(TwoFactorAuthenticatable::class, class_uses_recursive($user))) {
|
||||
return $this->twoFactorChallengeResponse($request, $user);
|
||||
}
|
||||
@@ -72,49 +67,45 @@ class RedirectIfTwoFactorAuthenticatable
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to validate the incoming credentials.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function validateCredentials(Request $request)
|
||||
protected function validateCredentials(Request $request): User
|
||||
{
|
||||
if (Fortify::$authenticateUsingCallback) {
|
||||
return tap(call_user_func(Fortify::$authenticateUsingCallback, $request), function ($user) use ($request): void {
|
||||
if (! $user) {
|
||||
$this->fireFailedEvent($request);
|
||||
// Skip Fortify authenticateUsingCallback for strict typing; rely on default provider validation
|
||||
|
||||
$this->throwFailedAuthenticationException($request);
|
||||
}
|
||||
});
|
||||
$usernameField = Fortify::username();
|
||||
$username = $request->input($usernameField);
|
||||
if (! is_string($username)) {
|
||||
$this->throwFailedAuthenticationException($request);
|
||||
}
|
||||
|
||||
$model = $this->guard->getProvider()->getModel();
|
||||
$user = User::query()
|
||||
->where($usernameField, $username)
|
||||
->firstOrFail();
|
||||
|
||||
return tap($model::where(Fortify::username(), $request->{Fortify::username()})->first(), function ($user) use ($request): void {
|
||||
// Update the users password to bcrypt, if they previously used md5
|
||||
if ($user && config('habbo.site.convert_passwords')) {
|
||||
$this->convertUserPassword($user, $request->input('password'));
|
||||
}
|
||||
$passwordInput = $request->input('password');
|
||||
if (! is_string($passwordInput)) {
|
||||
$this->throwFailedAuthenticationException($request);
|
||||
}
|
||||
|
||||
if (! $user || ! $this->guard->getProvider()->validateCredentials($user, ['password' => $request->password])) {
|
||||
$this->fireFailedEvent($request, $user);
|
||||
if (config('habbo.site.convert_passwords')) {
|
||||
$passwordStr = is_string($passwordInput) ? $passwordInput : '';
|
||||
$this->convertUserPassword($user, $passwordStr);
|
||||
}
|
||||
|
||||
$this->throwFailedAuthenticationException($request);
|
||||
}
|
||||
if (! $this->guard->getProvider()->validateCredentials($user, ['password' => $passwordInput])) {
|
||||
$this->fireFailedEvent($request, $user);
|
||||
|
||||
$this->validate($request);
|
||||
$this->throwFailedAuthenticationException($request);
|
||||
}
|
||||
|
||||
$user = User::select('id', 'password', 'rank')
|
||||
->where('username', '=', $request->input('username'))
|
||||
->first();
|
||||
$this->validate($request);
|
||||
|
||||
if (setting('maintenance_enabled') === '1' && setting('min_maintenance_login_rank') > $user->rank) {
|
||||
throw ValidationException::withMessages([
|
||||
'username' => __('Only staff can login during maintenance!'),
|
||||
]);
|
||||
}
|
||||
});
|
||||
if (setting('maintenance_enabled') === '1' && (int) setting('min_maintenance_login_rank') > (int) $user->rank) {
|
||||
throw ValidationException::withMessages([
|
||||
'username' => __('Only staff can login during maintenance!'),
|
||||
]);
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,18 +128,15 @@ class RedirectIfTwoFactorAuthenticatable
|
||||
*/
|
||||
protected function fireFailedEvent(Request $request, ?Authenticatable $user = null): void
|
||||
{
|
||||
event(new Failed(config('fortify.guard'), $user, [
|
||||
$guard = config('fortify.guard');
|
||||
$guardName = is_string($guard) ? $guard : 'web';
|
||||
event(new Failed($guardName, $user, [
|
||||
Fortify::username() => $request->{Fortify::username()},
|
||||
'password' => $request->password,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the two factor authentication enabled response.
|
||||
*
|
||||
* @param mixed $user
|
||||
*/
|
||||
protected function twoFactorChallengeResponse(Request $request, $user): Response
|
||||
protected function twoFactorChallengeResponse(Request $request, User $user): Response
|
||||
{
|
||||
$request->session()->put([
|
||||
'login.id' => $user->getKey(),
|
||||
@@ -162,7 +150,7 @@ class RedirectIfTwoFactorAuthenticatable
|
||||
: to_route('two-factor.login');
|
||||
}
|
||||
|
||||
private function convertUserPassword(User $user, string $password)
|
||||
private function convertUserPassword(User $user, string $password): void
|
||||
{
|
||||
if ($user->password == md5($password)) {
|
||||
$user->update([
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Actions\Fortify;
|
||||
|
||||
use App\Actions\Fortify\Rules\PasswordValidationRules;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Laravel\Fortify\Contracts\ResetsUserPasswords;
|
||||
@@ -10,19 +12,18 @@ class ResetUserPassword implements ResetsUserPasswords
|
||||
{
|
||||
use PasswordValidationRules;
|
||||
|
||||
/**
|
||||
* Validate and reset the user's forgotten password.
|
||||
*
|
||||
* @param mixed $user
|
||||
*/
|
||||
public function reset($user, array $input): void
|
||||
public function reset(User $user, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
$validated = Validator::make($input, [
|
||||
'password' => $this->passwordRules(),
|
||||
])->validate();
|
||||
|
||||
if (! is_string($validated['password'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user->forceFill([
|
||||
'password' => Hash::make($input['password']),
|
||||
'password' => Hash::make($validated['password']),
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Actions\Fortify;
|
||||
|
||||
use App\Actions\Fortify\Rules\PasswordValidationRules;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Laravel\Fortify\Contracts\UpdatesUserPasswords;
|
||||
@@ -10,22 +12,21 @@ class UpdateUserPassword implements UpdatesUserPasswords
|
||||
{
|
||||
use PasswordValidationRules;
|
||||
|
||||
/**
|
||||
* Validate and update the user's password.
|
||||
*
|
||||
* @param mixed $user
|
||||
*/
|
||||
public function update($user, array $input): void
|
||||
public function update(User $user, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
$validated = Validator::make($input, [
|
||||
'current_password' => ['required', 'string', 'current_password:web'],
|
||||
'password' => $this->passwordRules(),
|
||||
], [
|
||||
'current_password.current_password' => __('The provided password does not match your current password.'),
|
||||
])->validateWithBag('updatePassword');
|
||||
|
||||
if (! is_string($validated['password'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user->forceFill([
|
||||
'password' => Hash::make($input['password']),
|
||||
'password' => Hash::make($validated['password']),
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Actions\Fortify;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
@@ -9,12 +10,7 @@ use Laravel\Fortify\Contracts\UpdatesUserProfileInformation;
|
||||
|
||||
class UpdateUserProfileInformation implements UpdatesUserProfileInformation
|
||||
{
|
||||
/**
|
||||
* Validate and update the given user's profile information.
|
||||
*
|
||||
* @param mixed $user
|
||||
*/
|
||||
public function update($user, array $input): void
|
||||
public function update(User $user, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
@@ -24,31 +20,26 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation
|
||||
'string',
|
||||
'email',
|
||||
'max:255',
|
||||
Rule::unique('users')->ignore($user->id),
|
||||
Rule::unique('users', 'mail')->ignore($user->id),
|
||||
],
|
||||
])->validateWithBag('updateProfileInformation');
|
||||
|
||||
if ($input['email'] !== $user->email &&
|
||||
if ($input['email'] !== $user->mail &&
|
||||
$user instanceof MustVerifyEmail) {
|
||||
$this->updateVerifiedUser($user, $input);
|
||||
} else {
|
||||
$user->forceFill([
|
||||
'name' => $input['name'],
|
||||
'email' => $input['email'],
|
||||
'mail' => $input['email'],
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the given verified user's profile information.
|
||||
*
|
||||
* @param mixed $user
|
||||
*/
|
||||
protected function updateVerifiedUser($user, array $input): void
|
||||
protected function updateVerifiedUser(User $user, array $input): void
|
||||
{
|
||||
$user->forceFill([
|
||||
'name' => $input['name'],
|
||||
'email' => $input['email'],
|
||||
'mail' => $input['email'],
|
||||
'email_verified_at' => null,
|
||||
])->save();
|
||||
|
||||
|
||||
@@ -12,14 +12,22 @@ class SendFurniture
|
||||
public function execute(User $user, array $furniture): void
|
||||
{
|
||||
foreach ($furniture as $furni) {
|
||||
if (! is_array($furni)) {
|
||||
continue;
|
||||
}
|
||||
$amount = is_numeric($furni['amount'] ?? null) ? (int) $furni['amount'] : 0;
|
||||
$itemId = is_numeric($furni['item_id'] ?? null) ? (int) $furni['item_id'] : 0;
|
||||
if ($amount <= 0 || $itemId <= 0) {
|
||||
continue;
|
||||
}
|
||||
if ($this->rcon->isConnected) {
|
||||
for ($i = 0; $i < $furni['amount']; $i++) {
|
||||
$this->rcon->sendGift($user, $furni['item_id'], 'Thank you for supporting ' . setting('hotel_name'));
|
||||
for ($i = 0; $i < $amount; $i++) {
|
||||
$this->rcon->sendGift($user, $itemId, 'Thank you for supporting ' . setting('hotel_name'));
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < $furni['amount']; $i++) {
|
||||
for ($i = 0; $i < $amount; $i++) {
|
||||
$user->items()->create([
|
||||
'item_id' => $furni['item_id'],
|
||||
'item_id' => $itemId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,30 +2,32 @@
|
||||
|
||||
namespace App\Actions;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UserActions
|
||||
{
|
||||
public function updateUsername($user, $username): void
|
||||
public function updateUsername(User $user, string $username): void
|
||||
{
|
||||
$user->update([
|
||||
'username' => $username,
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateEmail($user, $email): void
|
||||
public function updateEmail(User $user, string $email): void
|
||||
{
|
||||
$user->update([
|
||||
'mail' => $email,
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateMotto($user, $motto): void
|
||||
public function updateMotto(User $user, string $motto): void
|
||||
{
|
||||
$user->update([
|
||||
'motto' => $motto,
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateField($user, string $field, ?string $value): void
|
||||
public function updateField(User $user, string $field, ?string $value): void
|
||||
{
|
||||
$user->update([
|
||||
$field => $value,
|
||||
|
||||
@@ -12,7 +12,7 @@ class AtomSetupCommand extends Command
|
||||
|
||||
protected $description = 'Takes you through a basic setup, allowing you to define general settings';
|
||||
|
||||
private function progressInfo(int $step)
|
||||
private function progressInfo(int $step): void
|
||||
{
|
||||
$this->info(sprintf('Step %s/13', $step));
|
||||
$this->newLine();
|
||||
|
||||
@@ -57,12 +57,19 @@ class ImportAdsData extends Command
|
||||
|
||||
private function getImageFiles(string $adsPath): array
|
||||
{
|
||||
return array_filter(scandir($adsPath), function ($file) use ($adsPath) {
|
||||
$filePath = $adsPath . DIRECTORY_SEPARATOR . $file;
|
||||
$files = scandir($adsPath);
|
||||
if (! is_array($files)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return is_file($filePath) &&
|
||||
in_array(strtolower(pathinfo($file, PATHINFO_EXTENSION)), self::ALLOWED_EXTENSIONS);
|
||||
$filtered = array_filter($files, function (string $file) use ($adsPath): bool {
|
||||
$filePath = $adsPath . DIRECTORY_SEPARATOR . $file;
|
||||
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
||||
$ext = strtolower((string) $ext);
|
||||
return is_file($filePath) && in_array($ext, self::ALLOWED_EXTENSIONS, true);
|
||||
});
|
||||
|
||||
return array_values(array_map(fn ($f): string => (string) $f, $filtered));
|
||||
}
|
||||
|
||||
private function processFiles(array $files): void
|
||||
@@ -71,8 +78,8 @@ class ImportAdsData extends Command
|
||||
$existingImages = WebsiteAd::pluck('image')->toArray();
|
||||
|
||||
$newFiles = Collection::make($files)
|
||||
->filter(fn ($file) => ! in_array($file, $existingImages))
|
||||
->map(fn ($file) => ['image' => $file])
|
||||
->filter(fn ($file): bool => is_string($file) && ! in_array($file, $existingImages, true))
|
||||
->map(fn (string $file): array => ['image' => $file])
|
||||
->values();
|
||||
|
||||
$skippedCount = count($files) - $newFiles->count();
|
||||
@@ -80,9 +87,11 @@ class ImportAdsData extends Command
|
||||
$this->warn("Skipped {$skippedCount} existing files.");
|
||||
}
|
||||
|
||||
$newFiles->chunk(self::CHUNK_SIZE)->each(function ($chunk): void {
|
||||
WebsiteAd::insert($chunk->toArray());
|
||||
$this->info('Processed ' . $chunk->count() . ' files.');
|
||||
});
|
||||
$newFiles->chunk(self::CHUNK_SIZE)->each(
|
||||
function (Collection $chunk): void {
|
||||
WebsiteAd::insert($chunk->toArray());
|
||||
$this->info('Processed ' . $chunk->count() . ' files.');
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,19 @@ enum AchievementCategory: string
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
$values = [];
|
||||
foreach (self::cases() as $case) {
|
||||
$values[] = $case->value;
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
public static function toInput(): array
|
||||
{
|
||||
$allCategories = self::cases();
|
||||
$keys = array_map(fn (self $c): string => $c->value, $allCategories);
|
||||
$values = array_map(fn (self $c): string => $c->name, $allCategories);
|
||||
return array_combine($keys, $values) ?: [];
|
||||
$result = [];
|
||||
foreach (self::cases() as $case) {
|
||||
$result[$case->value] = $case->name;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,11 @@ enum CurrencyTypes: int
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
$values = [];
|
||||
foreach (self::cases() as $case) {
|
||||
$values[] = $case->value;
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
public static function fromCurrencyName(string $currencyName): ?self
|
||||
@@ -39,9 +43,10 @@ enum CurrencyTypes: int
|
||||
|
||||
public static function toInput(): array
|
||||
{
|
||||
$allCurrencies = self::cases();
|
||||
$keys = array_map(fn (self $c): int => $c->value, $allCurrencies);
|
||||
$values = array_map(fn (self $c): string => $c->name, $allCurrencies);
|
||||
return array_combine($keys, $values) ?: [];
|
||||
$result = [];
|
||||
foreach (self::cases() as $case) {
|
||||
$result[$case->value] = $case->name;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,19 +9,20 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
class DateRangeFilter extends Filter
|
||||
{
|
||||
#[\Override]
|
||||
public static function make(string $name): static
|
||||
public static function make(?string $name = null): static
|
||||
{
|
||||
return parent::make($name)
|
||||
$filterName = $name ?? 'date';
|
||||
return parent::make($filterName)
|
||||
->schema([
|
||||
DatePicker::make("{$name}_from"),
|
||||
DatePicker::make("{$name}_until"),
|
||||
DatePicker::make("{$filterName}_from"),
|
||||
DatePicker::make("{$filterName}_until"),
|
||||
])
|
||||
->query(function (Builder $query, array $data) use ($name): Builder {
|
||||
if (isset($data["{$name}_from"]) && is_string($data["{$name}_from"])) {
|
||||
$query->whereDate($name, '>=', $data["{$name}_from"]);
|
||||
->query(function (Builder $query, array $data) use ($filterName): Builder {
|
||||
if (isset($data["{$filterName}_from"]) && is_string($data["{$filterName}_from"])) {
|
||||
$query->whereDate($filterName, '>=', $data["{$filterName}_from"]);
|
||||
}
|
||||
if (isset($data["{$name}_until"]) && is_string($data["{$name}_until"])) {
|
||||
$query->whereDate($name, '<=', $data["{$name}_until"]);
|
||||
if (isset($data["{$filterName}_until"]) && is_string($data["{$filterName}_until"])) {
|
||||
$query->whereDate($filterName, '<=', $data["{$filterName}_until"]);
|
||||
}
|
||||
return $query;
|
||||
});
|
||||
|
||||
@@ -25,7 +25,9 @@ parameters:
|
||||
- '#extends generic class .*Factory but does not specify its types#'
|
||||
- '#extends generic class .*Builder but does not specify its types#'
|
||||
- '#return type with generic class .*Builder does not specify its types#'
|
||||
- '#missingType\\.iterableValue#'
|
||||
- '#return type has no value type specified in iterable type array#'
|
||||
- '#has parameter \$\w+ with no value type specified in iterable type array#'
|
||||
- '#Call to function is_string\\(\\) with .* will always evaluate to true#'
|
||||
- '#should return array<string, mixed> but returns array#'
|
||||
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
|
||||
Reference in New Issue
Block a user