diff --git a/app/Community/Concerns/ActsAsCommunityMember.php b/app/Community/Concerns/ActsAsCommunityMember.php index 50fcffbae5..b88cc729a0 100644 --- a/app/Community/Concerns/ActsAsCommunityMember.php +++ b/app/Community/Concerns/ActsAsCommunityMember.php @@ -21,6 +21,7 @@ use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\Pivot; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Spatie\Permission\Models\Role as SpatieRole; @@ -88,7 +89,7 @@ public function gameListEntries(?UserGameListType $type = null): HasMany */ public function displayableRoles(): BelongsToMany { - /** @var BelongsToMany */ + /** @var BelongsToMany */ return $this->roles()->where('display', '>', 0); } diff --git a/app/Filament/Resources/GameResource/RelationManagers/AchievementSetsRelationManager.php b/app/Filament/Resources/GameResource/RelationManagers/AchievementSetsRelationManager.php index 15b5f2c2ba..e0a5601953 100644 --- a/app/Filament/Resources/GameResource/RelationManagers/AchievementSetsRelationManager.php +++ b/app/Filament/Resources/GameResource/RelationManagers/AchievementSetsRelationManager.php @@ -161,6 +161,7 @@ public function table(Table $table): Table ->orWhere('achievements_unpublished', '>', 0); }) ->whereDoesntHave('gameAchievementSets', function (Builder $query) use ($attachedAchievementSetIds) { + /** @var Builder $query */ $query->core()->whereIn('achievement_set_id', $attachedAchievementSetIds); }) ->orderBy('Title') diff --git a/app/Helpers/database/user-auth.php b/app/Helpers/database/user-auth.php index 5b2d86fc3c..091fee375c 100644 --- a/app/Helpers/database/user-auth.php +++ b/app/Helpers/database/user-auth.php @@ -70,6 +70,9 @@ function authenticateFromCookie( * TOKEN */ +/** + * @param-out int|null $permissionOut + */ function authenticateFromAppToken( ?string &$userOut, string $token, diff --git a/app/Helpers/util/database.php b/app/Helpers/util/database.php index 145c17cf0c..a4e94398f2 100644 --- a/app/Helpers/util/database.php +++ b/app/Helpers/util/database.php @@ -150,6 +150,7 @@ function getMysqliConnection(): mysqli /** * @deprecated + * @param string &...$inputs */ function sanitize_sql_inputs(int|string|null &...$inputs): void { diff --git a/app/Helpers/util/string.php b/app/Helpers/util/string.php index 10f5f840cc..70120edbe5 100644 --- a/app/Helpers/util/string.php +++ b/app/Helpers/util/string.php @@ -3,6 +3,9 @@ use App\Support\Rules\CtypeAlnum; use Illuminate\Support\Facades\Validator; +/** + * @param string &...$outputs + */ function sanitize_outputs(string|int|null &...$outputs): void { /** @var string $output */ diff --git a/app/Models/EventAchievement.php b/app/Models/EventAchievement.php index 4ba8e5f9b5..b47ea5e767 100644 --- a/app/Models/EventAchievement.php +++ b/app/Models/EventAchievement.php @@ -163,6 +163,7 @@ public function scopeActive(Builder $query, ?Carbon $timestamp = null): Builder public function scopePublished(Builder $query): Builder { return $query->whereHas('achievement', function ($q) { + /** @var Builder $q */ $q->published(); }); } diff --git a/app/Models/EventAward.php b/app/Models/EventAward.php index 406ea688d6..d451ee429e 100644 --- a/app/Models/EventAward.php +++ b/app/Models/EventAward.php @@ -6,6 +6,7 @@ use App\Community\Enums\AwardType; use App\Support\Database\Eloquent\BaseModel; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -32,6 +33,7 @@ public function getBadgeCountAttribute(): int ->where('AwardData', $this->event_id) ->where('AwardDataExtra', $this->tier_index) ->whereHas('user', function ($query) { + /** @var Builder $query */ $query->tracked(); }) ->count(); diff --git a/app/Platform/Actions/UpdateAchievementMetricsAction.php b/app/Platform/Actions/UpdateAchievementMetricsAction.php index c7e201489c..7bc09d479b 100644 --- a/app/Platform/Actions/UpdateAchievementMetricsAction.php +++ b/app/Platform/Actions/UpdateAchievementMetricsAction.php @@ -7,7 +7,9 @@ use App\Models\Achievement; use App\Models\Game; use App\Models\PlayerAchievement; +use App\Models\User; use App\Platform\Services\SearchIndexingService; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; @@ -37,7 +39,10 @@ public function update(Game $game, Collection $achievements): void $achievementIds = $achievements->pluck('ID')->all(); $unlockStats = PlayerAchievement::query() ->whereIn('player_achievements.achievement_id', $achievementIds) - ->whereHas('user', function ($query) { $query->tracked(); }) + ->whereHas('user', function ($query) { + /** @var Builder $query */ + $query->tracked(); + }) ->groupBy('player_achievements.achievement_id') ->selectRaw(' player_achievements.achievement_id, diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 350bbac1b5..b952ac9a28 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,14 +1,8 @@ parameters: ignoreErrors: - - message: '#^Call to an undefined method Illuminate\\Database\\Eloquent\\Builder\\:\:core\(\)\.$#' - identifier: method.notFound - count: 1 - path: app/Filament/Resources/GameResource/RelationManagers/AchievementSetsRelationManager.php - - - - message: '#^Parameter &\$permissionOut by\-ref type of function authenticateFromAppToken\(\) expects int\|null, Illuminate\\Database\\Eloquent\\Collection\ given\.$#' - identifier: parameterByRef.type + message: '#^Parameter &\$permissionOut @param\-out type of function authenticateFromAppToken\(\) expects int\|null, Illuminate\\Database\\Eloquent\\Collection\ given\.$#' + identifier: paramOut.type count: 1 path: app/Helpers/database/user-auth.php @@ -72,12 +66,6 @@ parameters: count: 1 path: app/Models/Achievement.php - - - message: '#^Return type \(Illuminate\\Database\\Eloquent\\Relations\\BelongsTo\\) of method App\\Models\\Achievement\:\:currentTrigger\(\) should be compatible with return type \(Illuminate\\Database\\Eloquent\\Relations\\BelongsTo\\) of method App\\Platform\\Contracts\\HasVersionedTrigger\\:\:currentTrigger\(\)$#' - identifier: method.childReturnType - count: 1 - path: app/Models/Achievement.php - - message: '#^Unable to resolve the template type TNewPivotModel in call to method Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany\\:\:using\(\)$#' identifier: argument.templateType @@ -126,18 +114,6 @@ parameters: count: 1 path: app/Models/Event.php - - - message: '#^Call to an undefined method Illuminate\\Database\\Eloquent\\Builder\\:\:published\(\)\.$#' - identifier: method.notFound - count: 1 - path: app/Models/EventAchievement.php - - - - message: '#^Call to an undefined method Illuminate\\Database\\Eloquent\\Builder\\:\:tracked\(\)\.$#' - identifier: method.notFound - count: 1 - path: app/Models/EventAward.php - - message: '#^Parameter \#1 \$class of method Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany\\:\:using\(\) expects class\-string\, string given\.$#' identifier: argument.type @@ -174,12 +150,6 @@ parameters: count: 1 path: app/Models/Game.php - - - message: '#^Return type \(Illuminate\\Database\\Eloquent\\Relations\\BelongsTo\\) of method App\\Models\\Game\:\:currentTrigger\(\) should be compatible with return type \(Illuminate\\Database\\Eloquent\\Relations\\BelongsTo\\) of method App\\Platform\\Contracts\\HasVersionedTrigger\\:\:currentTrigger\(\)$#' - identifier: method.childReturnType - count: 1 - path: app/Models/Game.php - - message: '#^Unable to resolve the template type TNewPivotModel in call to method Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany\\:\:using\(\)$#' identifier: argument.templateType @@ -222,12 +192,6 @@ parameters: count: 1 path: app/Models/Leaderboard.php - - - message: '#^Return type \(Illuminate\\Database\\Eloquent\\Relations\\BelongsTo\\) of method App\\Models\\Leaderboard\:\:currentTrigger\(\) should be compatible with return type \(Illuminate\\Database\\Eloquent\\Relations\\BelongsTo\\) of method App\\Platform\\Contracts\\HasVersionedTrigger\\:\:currentTrigger\(\)$#' - identifier: method.childReturnType - count: 1 - path: app/Models/Leaderboard.php - - message: '#^Parameter \#1 \$class of method Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany\\:\:using\(\) expects class\-string\, string given\.$#' identifier: argument.type @@ -258,12 +222,6 @@ parameters: count: 1 path: app/Models/Trigger.php - - - message: '#^Method App\\Models\\User\:\:displayableRoles\(\) should return Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany\ but returns Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany\\.$#' - identifier: return.type - count: 1 - path: app/Models/User.php - - message: '#^Method App\\Models\\User\:\:whereName\(\) should return Illuminate\\Database\\Eloquent\\Builder\ but returns Illuminate\\Database\\Eloquent\\Builder\\.$#' identifier: return.type @@ -282,12 +240,6 @@ parameters: count: 1 path: app/Models/User.php - - - message: '#^Type string in generic type Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany\ in PHPDoc tag @var is not subtype of template type TPivotModel of Illuminate\\Database\\Eloquent\\Relations\\Pivot \= Illuminate\\Database\\Eloquent\\Relations\\Pivot of class Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany\.$#' - identifier: generics.notSubtype - count: 1 - path: app/Models/User.php - - message: '#^Unable to resolve the template type TNewPivotModel in call to method Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany\\:\:using\(\)$#' identifier: argument.templateType @@ -306,18 +258,6 @@ parameters: count: 1 path: app/Platform/Actions/BuildGameListAction.php - - - message: '#^PHPDoc tag @var with type array\ is not subtype of native type array\\.$#' - identifier: varTag.nativeType - count: 1 - path: app/Platform/Actions/BuildPlayerGameActivityDataAction.php - - - - message: '#^Call to an undefined method Illuminate\\Database\\Eloquent\\Builder\\:\:tracked\(\)\.$#' - identifier: method.notFound - count: 1 - path: app/Platform/Actions/UpdateAchievementMetricsAction.php - - message: '#^Parameter \#2 \$syncData of method App\\Platform\\Actions\\UpsertGameCoreAchievementSetFromLegacyFlagsAction\:\:syncAchievementSetAchievements\(\) expects Illuminate\\Support\\Collection\, Illuminate\\Support\\Collection\ given\.$#' identifier: argument.type diff --git a/phpstan.neon b/phpstan.neon index 7cd07d71c0..8efcd96ffa 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -42,6 +42,11 @@ parameters: # lib/database/user-activity.php - '#Offset (.*) does not exist on#' - '#Unable to resolve the template type TMapWithKeysValue in call to method Illuminate\\Support\\Collection<\*NEVER\*,\*NEVER\*>::mapWithKeys\(\)#' + # False positives from PHPStan being overly strict about closure type hints + - identifier: varTag.nativeType + # Laravel template covariance limitations - these are framework-level issues we can't resolve + - identifier: method.childReturnType + - '#Template type.*is not covariant#' excludePaths: # unrelated directories