From f4c444c9b04b8737ae349feb9cb834442d44b583 Mon Sep 17 00:00:00 2001 From: DariusIII Date: Wed, 11 Feb 2026 14:02:26 +0100 Subject: [PATCH] Update phpstan level to 6 --- app/Console/Commands/CleanNZB.php | 4 +- app/Console/Commands/CollectStats.php | 2 +- .../Commands/CreateManticoreIndexes.php | 2 + app/Console/Commands/CreateMediaIndexes.php | 2 + app/Console/Commands/DeleteReleases.php | 6 + .../Commands/FindSizeMismatchedReleases.php | 4 +- app/Console/Commands/GetArticleRange.php | 3 + app/Console/Commands/MatchPrefiles.php | 2 +- app/Console/Commands/NntmuxOffsetPopulate.php | 12 +- app/Console/Commands/NntmuxOffsetWorker.php | 10 +- app/Console/Commands/NntmuxOptimizeTables.php | 6 +- .../Commands/NntmuxPopulateSearchIndexes.php | 28 +- .../Commands/NntmuxPopulateSteamApps.php | 6 +- .../Commands/NntmuxResetPostProcessing.php | 12 +- app/Console/Commands/ProcessBackfill.php | 2 +- app/Console/Commands/RecategorizeReleases.php | 5 +- app/Console/Commands/RedisMonitor.php | 2 + app/Console/Commands/RefreshAnimeData.php | 2 +- .../Commands/ReleasesFixNamesGroup.php | 2 +- app/Console/Commands/SteamLookupGame.php | 2 + app/Console/Commands/TmuxMonitor.php | 12 + app/Console/Commands/UpdateNNTmux.php | 4 + .../Commands/UpdateReleasesIndexSchema.php | 15 +- .../Commands/UpdateReleasesIndexSchemaES.php | 6 +- app/Events/UserAccessedApi.php | 2 +- app/Events/UserLoggedIn.php | 9 +- .../helper/age_verification_helpers.php | 6 +- app/Extensions/helper/helpers.php | 39 +- app/Facades/Categorization.php | 2 +- app/Facades/Elasticsearch.php | 2 +- app/Facades/Search.php | 2 +- app/Facades/TvProcessing.php | 2 +- app/Facades/Yenc.php | 2 +- .../Controllers/Admin/AdminAjaxController.php | 5 +- .../Admin/AdminBlacklistController.php | 2 +- .../Admin/AdminCategoryController.php | 2 +- .../Admin/AdminCategoryRegexesController.php | 2 +- .../AdminCollectionRegexesController.php | 4 +- .../Admin/AdminContentController.php | 13 +- .../Admin/AdminFailedReleasesController.php | 2 +- .../Controllers/Admin/AdminGameController.php | 4 +- .../Admin/AdminGroupController.php | 8 +- .../Admin/AdminInvitationController.php | 4 + .../Admin/AdminMovieController.php | 2 +- .../Admin/AdminMusicController.php | 4 +- .../Controllers/Admin/AdminPageController.php | 22 +- .../AdminReleaseNamingRegexesController.php | 4 +- .../Admin/AdminReleasesController.php | 4 +- .../Controllers/Admin/AdminRoleController.php | 6 +- .../Controllers/Admin/AdminSiteController.php | 2 +- .../Controllers/Admin/AdminTmuxController.php | 2 +- .../Controllers/Admin/AdminUserController.php | 2 +- .../Admin/AdminUserRoleHistoryController.php | 4 +- .../Admin/DeletedUsersController.php | 14 +- app/Http/Controllers/AdultController.php | 4 +- app/Http/Controllers/Api/ApiController.php | 12 +- app/Http/Controllers/Api/RSS.php | 12 +- app/Http/Controllers/Api/XML_Response.php | 14 +- .../Auth/ForgotPasswordController.php | 2 +- app/Http/Controllers/Auth/LoginController.php | 2 +- .../Controllers/Auth/RegisterController.php | 5 +- .../Auth/ResetPasswordController.php | 4 +- app/Http/Controllers/BasePageController.php | 12 +- app/Http/Controllers/BooksController.php | 4 +- app/Http/Controllers/BrowseController.php | 6 +- .../Controllers/BrowseGroupController.php | 2 +- app/Http/Controllers/CartController.php | 5 +- app/Http/Controllers/ConsoleController.php | 4 +- app/Http/Controllers/ContactUsController.php | 2 +- app/Http/Controllers/ContentController.php | 12 +- app/Http/Controllers/DetailsController.php | 2 +- app/Http/Controllers/GamesController.php | 2 +- app/Http/Controllers/GetNzbController.php | 6 +- app/Http/Controllers/MovieController.php | 9 +- app/Http/Controllers/MusicController.php | 4 +- app/Http/Controllers/MyMoviesController.php | 2 +- app/Http/Controllers/MyShowsController.php | 4 +- app/Http/Controllers/NfoController.php | 2 +- .../PasswordSecurityController.php | 2 +- app/Http/Controllers/ProfileController.php | 4 +- app/Http/Controllers/RssController.php | 27 +- app/Http/Controllers/SearchController.php | 6 +- app/Http/Controllers/SeriesController.php | 7 +- app/Http/Middleware/ClearanceMiddleware.php | 4 +- app/Http/Requests/Auth/LoginLoginRequest.php | 2 + .../Requests/Auth/RegisterRegisterRequest.php | 2 + ...owLinkRequestFormForgotPasswordRequest.php | 2 +- app/Http/Requests/ContactContactURequest.php | 2 + .../Disable2faPasswordSecurityRequest.php | 2 + app/Jobs/SendAccountWillExpireEmail.php | 8 +- app/Jobs/SendContactUsEmail.php | 8 +- app/Jobs/SendInviteEmail.php | 11 +- app/Jobs/SendPasswordForgottenEmail.php | 9 +- app/Mail/AccountDeleted.php | 2 +- app/Mail/AccountExpired.php | 8 +- app/Mail/AccountWillExpire.php | 18 +- app/Mail/ContactUs.php | 2 +- app/Mail/ForgottenPassword.php | 16 +- app/Mail/NewAccountCreatedEmail.php | 2 +- app/Mail/PasswordReset.php | 2 +- app/Mail/SendInvite.php | 2 +- app/Models/AnidbEpisode.php | 6 + app/Models/AnidbInfo.php | 4 + app/Models/AnidbTitle.php | 3 + app/Models/BookInfo.php | 5 + app/Models/Category.php | 63 +- app/Models/ConsoleInfo.php | 11 +- app/Models/Content.php | 8 +- app/Models/DnzbFailure.php | 8 +- app/Models/DownloadStat.php | 5 +- app/Models/Forumpost.php | 30 +- app/Models/GamesInfo.php | 7 + app/Models/Genre.php | 19 +- app/Models/GrabStat.php | 5 +- app/Models/Invitation.php | 24 +- app/Models/MediaInfo.php | 4 +- app/Models/MusicInfo.php | 6 + app/Models/PasswordSecurity.php | 5 +- app/Models/Payment.php | 2 +- app/Models/Predb.php | 18 +- app/Models/PredbHash.php | 3 + app/Models/Release.php | 75 +- app/Models/ReleaseComment.php | 25 +- app/Models/ReleaseFile.php | 17 +- app/Models/ReleaseNfo.php | 5 +- app/Models/ReleaseReport.php | 12 +- app/Models/ReleaseStat.php | 5 +- app/Models/ReleasesGroups.php | 6 + app/Models/RoleExpirationEmail.php | 5 +- app/Models/RolePromotion.php | 19 +- app/Models/RolePromotionStat.php | 18 +- app/Models/RoleStat.php | 5 +- app/Models/RootCategory.php | 5 +- app/Models/Settings.php | 12 +- app/Models/SignupStat.php | 5 +- app/Models/SiteStat.php | 2 +- app/Models/SteamApp.php | 3 + app/Models/SystemMetric.php | 10 +- app/Models/TvEpisode.php | 6 + app/Models/UsenetGroup.php | 40 +- app/Models/User.php | 84 +- app/Models/UserActivityStat.php | 10 +- app/Models/UserDownload.php | 14 +- app/Models/UserExcludedCategory.php | 6 + app/Models/UserMovie.php | 22 +- app/Models/UserRequest.php | 7 +- app/Models/UserRoleHistory.php | 12 +- app/Models/UserSerie.php | 23 +- app/Models/UsersRelease.php | 21 +- app/Models/Video.php | 20 +- app/Models/VideoAlias.php | 3 + app/Models/XxxInfo.php | 9 +- app/Policies/CategoryPolicy.php | 20 +- app/Policies/ForumPolicy.php | 28 +- app/Policies/PostPolicy.php | 6 +- app/Policies/ThreadPolicy.php | 16 +- .../AdditionalProcessingOrchestrator.php | 12 +- .../ArchiveExtractionService.php | 48 +- .../DTO/ReleaseProcessingContext.php | 18 + .../MediaExtractionService.php | 2 + .../AdditionalProcessing/NzbContentParser.php | 28 +- .../ReleaseFileManager.php | 4 + .../UsenetDownloadService.php | 16 +- .../AdultProcessingPassable.php | 5 + .../AdultProcessingPipeline.php | 34 +- .../AdultProcessing/AdultProcessingResult.php | 9 + .../AdultProcessing/AdultReleaseContext.php | 2 + .../AgeVerificationManager.php | 12 + .../Pipes/AbstractAdultProviderPipe.php | 39 +- .../AdultProcessing/Pipes/AdePipe.php | 24 + .../AdultProcessing/Pipes/AdmPipe.php | 21 + .../AdultProcessing/Pipes/AebnPipe.php | 32 + .../AdultProcessing/Pipes/Data18Pipe.php | 26 + .../AdultProcessing/Pipes/HotmoviesPipe.php | 21 + .../AdultProcessing/Pipes/IafdPipe.php | 26 + .../AdultProcessing/Pipes/PoppornPipe.php | 24 + app/Services/AnidbService.php | 4 +- app/Services/AnimeProcessor.php | 6 +- app/Services/ArchiveProcessingService.php | 4 + .../Archives/SevenZipPartialParser.php | 82 +- app/Services/Backfill/BackfillService.php | 26 +- app/Services/Binaries/BinariesService.php | 86 +- app/Services/Binaries/BinaryHandler.php | 18 +- app/Services/Binaries/CollectionHandler.php | 16 + app/Services/Binaries/HeaderParser.php | 11 +- .../Binaries/HeaderStorageService.php | 13 +- app/Services/Binaries/MissedPartHandler.php | 12 +- app/Services/Binaries/PartHandler.php | 17 + app/Services/BlacklistService.php | 26 +- app/Services/BookService.php | 33 +- .../Categorization/CategorizationPipeline.php | 7 +- .../Categorization/CategorizationResult.php | 4 +- .../Categorization/CategorizationService.php | 10 +- .../Categorizers/AbstractCategorizer.php | 3 + .../Pipes/AbstractCategorizationPipe.php | 2 + .../Pipes/CategorizationPassable.php | 5 + app/Services/CollectionsCleaningService.php | 8 +- app/Services/ConsoleService.php | 35 +- app/Services/FanartTvService.php | 18 +- app/Services/ForkingService.php | 4 + app/Services/GamesService.php | 40 +- app/Services/GenreService.php | 10 +- app/Services/IGDBService.php | 44 +- app/Services/IRCClient.php | 18 +- app/Services/IRCScraper.php | 8 +- app/Services/ImdbScraper.php | 5 +- app/Services/InvitationService.php | 12 +- app/Services/ItunesService.php | 37 +- app/Services/MediaProcessingService.php | 3 + app/Services/MovieBrowseService.php | 15 +- app/Services/MovieService.php | 27 +- app/Services/MusicService.php | 27 +- app/Services/NNTP/NNTPService.php | 16 +- app/Services/NameFixing/DTO/NameFixResult.php | 3 + app/Services/NameFixing/FilePrioritizer.php | 14 +- .../NameFixing/NameCheckerService.php | 2 + app/Services/NameFixing/NameFixingService.php | 12 +- .../NameFixing/Patterns/AppPatterns.php | 6 + .../NameFixing/Patterns/GamePatterns.php | 6 + .../NameFixing/Patterns/MoviePatterns.php | 4 + .../NameFixing/Patterns/TvPatterns.php | 4 + .../NameFixing/ReleaseUpdateService.php | 12 +- app/Services/NfoService.php | 32 +- app/Services/Nzb/NzbContentsService.php | 2 +- app/Services/Nzb/NzbImportService.php | 15 +- app/Services/Nzb/NzbParserService.php | 12 +- app/Services/Nzb/NzbService.php | 2 +- app/Services/PopulateAniListService.php | 16 +- app/Services/RedisMonitorService.php | 9 + app/Services/RegexService.php | 14 +- app/Services/ReleaseCleaningService.php | 10 +- app/Services/ReleaseExtraService.php | 4 +- app/Services/ReleaseProcessingService.php | 9 + app/Services/ReleaseRemoverService.php | 21 +- .../Releases/ReleaseBrowseService.php | 39 +- .../Releases/ReleaseManagementService.php | 17 +- .../Releases/ReleaseSearchService.php | 85 +- app/Services/Runners/BackfillRunner.php | 7 +- app/Services/Runners/BaseRunner.php | 2 + app/Services/Runners/BinariesRunner.php | 4 +- app/Services/Runners/PostProcessRunner.php | 9 +- app/Services/Runners/ReleasesRunner.php | 6 +- .../Contracts/SearchServiceInterface.php | 70 +- .../Search/Drivers/ElasticSearchDriver.php | 147 ++-- .../Search/Drivers/ManticoreSearchDriver.php | 112 ++- app/Services/Search/MediaSearchService.php | 28 +- app/Services/Search/SearchService.php | 61 +- app/Services/SteamService.php | 93 +- app/Services/SystemMetricsService.php | 13 +- app/Services/TmdbClient.php | 48 +- app/Services/Tmux/Tmux.php | 30 +- app/Services/Tmux/TmuxLayoutBuilder.php | 4 + app/Services/Tmux/TmuxMonitorService.php | 11 + app/Services/Tmux/TmuxOutput.php | 13 +- app/Services/Tmux/TmuxSessionManager.php | 2 + app/Services/Tmux/TmuxTaskRunner.php | 44 +- app/Services/TraktService.php | 42 +- app/Services/TurnstileService.php | 2 + .../Pipes/AbstractTvProviderPipe.php | 3 + .../TvProcessing/Pipes/LocalDbPipe.php | 2 + app/Services/TvProcessing/Pipes/TmdbPipe.php | 2 + app/Services/TvProcessing/Pipes/TraktPipe.php | 2 + .../TvProcessing/Pipes/TvMazePipe.php | 2 + app/Services/TvProcessing/Pipes/TvdbPipe.php | 2 + .../Providers/AbstractTvProvider.php | 40 +- .../Providers/BaseVideoProvider.php | 14 +- .../Providers/LocalDbProvider.php | 18 +- .../TvProcessing/Providers/TmdbProvider.php | 25 +- .../TvProcessing/Providers/TraktProvider.php | 20 +- .../TvProcessing/Providers/TvMazeProvider.php | 26 +- .../TvProcessing/Providers/TvdbProvider.php | 19 +- .../TvProcessing/TvProcessingPassable.php | 12 + .../TvProcessing/TvProcessingPipeline.php | 18 +- .../TvProcessing/TvProcessingResult.php | 9 + .../TvProcessing/TvReleaseContext.php | 2 + app/Services/TvProcessor.php | 10 +- app/Services/UserStatsService.php | 18 + app/Services/XXXProcessor.php | 2 +- app/Services/XrefService.php | 4 + app/Services/XxxBrowseService.php | 18 +- app/Support/CaptchaHelper.php | 4 + app/Support/DTOs/SteamGameData.php | 4 + app/Support/DTOs/SteamPriceData.php | 4 + app/Support/Google2FAAuthenticator.php | 2 +- app/Support/UpdatePerformanceHelper.php | 17 +- app/Transformers/ApiTransformer.php | 8 +- app/Transformers/CategoryTransformer.php | 2 + app/Transformers/DetailsTransformer.php | 6 +- app/View/Components/SortDropdown.php | 9 + phpstan-baseline.neon | 811 ++++++++++++++++++ phpstan.neon | 3 +- 291 files changed, 3684 insertions(+), 1089 deletions(-) create mode 100644 phpstan-baseline.neon diff --git a/app/Console/Commands/CleanNZB.php b/app/Console/Commands/CleanNZB.php index c794c2de4..370203b05 100644 --- a/app/Console/Commands/CleanNZB.php +++ b/app/Console/Commands/CleanNZB.php @@ -48,7 +48,7 @@ class CleanNZB extends Command } } - private function GetNZBsWithNoDatabaseEntry($delete = false) + private function GetNZBsWithNoDatabaseEntry(mixed $delete = false): void { $this->info('Getting list of NZB files on disk to check if they exist in database'); $releases = new Release; @@ -76,7 +76,7 @@ class CleanNZB extends Command $this->info("Checked: $checked / Deleted: $deleted"); } - private function GetReleasesWithNoNZBOnDisk($delete = false) + private function GetReleasesWithNoNZBOnDisk(mixed $delete = false): void { // Setup $nzb = app(NzbService::class); diff --git a/app/Console/Commands/CollectStats.php b/app/Console/Commands/CollectStats.php index 36b9095d6..1249ad3ba 100644 --- a/app/Console/Commands/CollectStats.php +++ b/app/Console/Commands/CollectStats.php @@ -29,7 +29,7 @@ class CollectStats extends Command /** * Execute the console command. */ - public function handle() + public function handle(): void { $this->info('Collecting site stats...'); GrabStat::insertTopGrabbers(); diff --git a/app/Console/Commands/CreateManticoreIndexes.php b/app/Console/Commands/CreateManticoreIndexes.php index efd09ce40..a79b50bcd 100644 --- a/app/Console/Commands/CreateManticoreIndexes.php +++ b/app/Console/Commands/CreateManticoreIndexes.php @@ -154,6 +154,8 @@ class CreateManticoreIndexes extends Command /** * Create a single index with error handling. + * + * @param array $schema */ protected function createIndex(string $indexName, array $schema, bool $dropExisting): bool { diff --git a/app/Console/Commands/CreateMediaIndexes.php b/app/Console/Commands/CreateMediaIndexes.php index ecbc309ba..ffcce5c0a 100644 --- a/app/Console/Commands/CreateMediaIndexes.php +++ b/app/Console/Commands/CreateMediaIndexes.php @@ -141,6 +141,8 @@ class CreateMediaIndexes extends Command /** * Create a single Manticore index. + * + * @param array $schema */ private function createManticoreIndex(Client $client, string $indexName, array $schema, bool $dropExisting): bool { diff --git a/app/Console/Commands/DeleteReleases.php b/app/Console/Commands/DeleteReleases.php index 38354faac..28d9febcb 100644 --- a/app/Console/Commands/DeleteReleases.php +++ b/app/Console/Commands/DeleteReleases.php @@ -174,6 +174,8 @@ class DeleteReleases extends Command /** * Perform a dry run to show what releases would be deleted. + * + * @param array $criteria */ protected function performDryRun(array $criteria): int { @@ -234,6 +236,8 @@ class DeleteReleases extends Command /** * Build the SQL query from criteria array. + * + * @param array $criteria */ protected function buildQueryFromCriteria(array $criteria): ?string { @@ -396,6 +400,8 @@ class DeleteReleases extends Command /** * Build criteria array from simple command options. + * + * @return array */ protected function buildCriteriaFromOptions(): array { diff --git a/app/Console/Commands/FindSizeMismatchedReleases.php b/app/Console/Commands/FindSizeMismatchedReleases.php index 016829721..5d67d2a8e 100644 --- a/app/Console/Commands/FindSizeMismatchedReleases.php +++ b/app/Console/Commands/FindSizeMismatchedReleases.php @@ -14,7 +14,7 @@ class FindSizeMismatchedReleases extends Command protected $description = 'Find releases where size differs significantly from release_files total. Use --direction=bigger|smaller|any'; - public function handle() + public function handle(): void { $threshold = $this->option('threshold'); // Percentage difference threshold $limit = $this->option('limit'); @@ -124,7 +124,7 @@ class FindSizeMismatchedReleases extends Command return null; } - private function outputReleaseIdsAsCsv($mismatches): void + private function outputReleaseIdsAsCsv(mixed $mismatches): void { $releaseIds = $mismatches->pluck('id')->join(','); $this->line("\nRelease IDs in CSV format:"); diff --git a/app/Console/Commands/GetArticleRange.php b/app/Console/Commands/GetArticleRange.php index 80d446ad3..e19df87be 100644 --- a/app/Console/Commands/GetArticleRange.php +++ b/app/Console/Commands/GetArticleRange.php @@ -87,6 +87,9 @@ class GetArticleRange extends Command /** * Update group records based on mode. + * + * @param array $groupMySQL + * @param array $return */ private function updateGroupRecords(string $mode, array $groupMySQL, array $return): void { diff --git a/app/Console/Commands/MatchPrefiles.php b/app/Console/Commands/MatchPrefiles.php index 312269164..868ee1be3 100644 --- a/app/Console/Commands/MatchPrefiles.php +++ b/app/Console/Commands/MatchPrefiles.php @@ -52,7 +52,7 @@ class MatchPrefiles extends Command try { $nameFixingService = new NameFixingService; - $nameFixingService->getPreFileNames($argv); + $nameFixingService->getPreFileNames($argv); // @phpstan-ignore argument.type return 0; } catch (Exception $e) { diff --git a/app/Console/Commands/NntmuxOffsetPopulate.php b/app/Console/Commands/NntmuxOffsetPopulate.php index 45fef61e4..b1457f6ef 100644 --- a/app/Console/Commands/NntmuxOffsetPopulate.php +++ b/app/Console/Commands/NntmuxOffsetPopulate.php @@ -96,7 +96,7 @@ class NntmuxOffsetPopulate extends Command // Start parallel processes foreach ($ranges as $i => $range) { - $command = $this->buildWorkerCommand($engine, $index, $range['offset'], $range['limit'], $i); + $command = $this->buildWorkerCommand($engine, $index, $range['offset'], $range['limit'], $i); // @phpstan-ignore argument.type $this->info("Starting worker process {$i}: processing {$range['limit']} records from offset {$range['offset']}"); $process = Process::start($command); @@ -108,7 +108,7 @@ class NntmuxOffsetPopulate extends Command } // Monitor processes - $this->monitorProcesses($processes); + $this->monitorProcesses($processes); // @phpstan-ignore argument.type // Verify final count $this->verifyIndexPopulation($engine, $index, $total); @@ -120,6 +120,8 @@ class NntmuxOffsetPopulate extends Command /** * Create offset-based ranges for parallel execution + * + * @return array */ private function createOffsetRanges(int $total, int $processes): array { @@ -144,6 +146,8 @@ class NntmuxOffsetPopulate extends Command /** * Build worker command for offset-based parallel processing + * + * @return list>> */ private function buildWorkerCommand(string $engine, string $index, int $offset, int $limit, int $workerId): string { @@ -176,6 +180,8 @@ class NntmuxOffsetPopulate extends Command /** * Monitor parallel processes + * + * @param array $processes */ private function monitorProcesses(array $processes): void { @@ -353,6 +359,8 @@ class NntmuxOffsetPopulate extends Command /** * Get index mappings + * + * @return array */ private function getIndexMappings(string $indexName): array { diff --git a/app/Console/Commands/NntmuxOffsetWorker.php b/app/Console/Commands/NntmuxOffsetWorker.php index cfb743e5f..6678fae09 100644 --- a/app/Console/Commands/NntmuxOffsetWorker.php +++ b/app/Console/Commands/NntmuxOffsetWorker.php @@ -104,7 +104,7 @@ class NntmuxOffsetWorker extends Command $processed++; if (count($batchData) >= $batchSize) { - $this->processSearchBatch($batchData, $workerId); + $this->processSearchBatch($batchData, $workerId); // @phpstan-ignore argument.type $this->info("Worker {$workerId}: Inserted batch of ".count($batchData).' records'); $batchData = []; } @@ -117,7 +117,7 @@ class NntmuxOffsetWorker extends Command // Process remaining items if (! empty($batchData)) { - $this->processSearchBatch($batchData, $workerId); + $this->processSearchBatch($batchData, $workerId); // @phpstan-ignore argument.type $this->info("Worker {$workerId}: Inserted final batch of ".count($batchData).' records'); } @@ -161,7 +161,7 @@ class NntmuxOffsetWorker extends Command /** * Build offset-based query */ - private function buildOffsetQuery(string $index, int $offset, int $limit) + private function buildOffsetQuery(string $index, int $offset, int $limit): mixed { if ($index === 'releases') { return Release::query() @@ -247,6 +247,8 @@ class NntmuxOffsetWorker extends Command /** * Process search batch + * + * @param array $data */ private function processSearchBatch(array $data, int $workerId): void { @@ -269,6 +271,8 @@ class NntmuxOffsetWorker extends Command /** * Process ElasticSearch batch + * + * @param array $data */ private function processElasticBatch(array $data, int $workerId): void { diff --git a/app/Console/Commands/NntmuxOptimizeTables.php b/app/Console/Commands/NntmuxOptimizeTables.php index 304e52e27..2e944c1ec 100644 --- a/app/Console/Commands/NntmuxOptimizeTables.php +++ b/app/Console/Commands/NntmuxOptimizeTables.php @@ -32,7 +32,7 @@ class NntmuxOptimizeTables extends Command if (empty($table) || $table[0] === 'all') { $this->optimizeAllTables(); } else { - $this->optimizeTable($table); + $this->optimizeTable($table); // @phpstan-ignore argument.type } } @@ -49,6 +49,8 @@ class NntmuxOptimizeTables extends Command /** * Optimize a single table. + * + * @param array $tables */ private function optimizeTable(array|string $tables): void { @@ -61,7 +63,7 @@ class NntmuxOptimizeTables extends Command } } - private function tableCheck($table): void + private function tableCheck(mixed $table): void { $this->info('Checking table: '.$table); $tableCheck = DB::select('CHECK TABLE '.$table); diff --git a/app/Console/Commands/NntmuxPopulateSearchIndexes.php b/app/Console/Commands/NntmuxPopulateSearchIndexes.php index e16892e61..e52a9d2b1 100644 --- a/app/Console/Commands/NntmuxPopulateSearchIndexes.php +++ b/app/Console/Commands/NntmuxPopulateSearchIndexes.php @@ -355,7 +355,7 @@ class NntmuxPopulateSearchIndexes extends Command /** * Process data for ManticoreSearch with optimizations */ - private function processManticoreData(string $indexName, int $total, $query, callable $transformer): int + private function processManticoreData(string $indexName, int $total, mixed $query, callable $transformer): int { $chunkSize = $this->getChunkSize(); $batchSize = $this->getBatchSize(); @@ -388,7 +388,7 @@ class NntmuxPopulateSearchIndexes extends Command // Process in optimized batch sizes if (count($batchData) >= $batchSize) { - $this->processBatch($indexName, $batchData); + $this->processBatch($indexName, $batchData); // @phpstan-ignore argument.type $batchData = []; } } catch (Exception $e) { @@ -403,7 +403,7 @@ class NntmuxPopulateSearchIndexes extends Command // Process remaining items if (! empty($batchData)) { - $this->processBatch($indexName, $batchData); + $this->processBatch($indexName, $batchData); // @phpstan-ignore argument.type } $bar->finish(); @@ -431,7 +431,7 @@ class NntmuxPopulateSearchIndexes extends Command /** * Process data for ManticoreSearch movies index */ - private function processManticoreMoviesData(string $indexName, int $total, $query, callable $transformer): int + private function processManticoreMoviesData(string $indexName, int $total, mixed $query, callable $transformer): int { $chunkSize = $this->getChunkSize(); $batchSize = $this->getBatchSize(); @@ -463,7 +463,7 @@ class NntmuxPopulateSearchIndexes extends Command // Process in optimized batch sizes if (count($batchData) >= $batchSize) { - $this->processMoviesBatch($batchData); + $this->processMoviesBatch($batchData); // @phpstan-ignore argument.type $batchData = []; } } catch (Exception $e) { @@ -478,7 +478,7 @@ class NntmuxPopulateSearchIndexes extends Command // Process remaining items if (! empty($batchData)) { - $this->processMoviesBatch($batchData); + $this->processMoviesBatch($batchData); // @phpstan-ignore argument.type } $bar->finish(); @@ -506,7 +506,7 @@ class NntmuxPopulateSearchIndexes extends Command /** * Process data for ManticoreSearch TV shows index */ - private function processManticoreTvShowsData(string $indexName, int $total, $query, callable $transformer): int + private function processManticoreTvShowsData(string $indexName, int $total, mixed $query, callable $transformer): int { $chunkSize = $this->getChunkSize(); $batchSize = $this->getBatchSize(); @@ -538,7 +538,7 @@ class NntmuxPopulateSearchIndexes extends Command // Process in optimized batch sizes if (count($batchData) >= $batchSize) { - $this->processTvShowsBatch($batchData); + $this->processTvShowsBatch($batchData); // @phpstan-ignore argument.type $batchData = []; } } catch (Exception $e) { @@ -553,7 +553,7 @@ class NntmuxPopulateSearchIndexes extends Command // Process remaining items if (! empty($batchData)) { - $this->processTvShowsBatch($batchData); + $this->processTvShowsBatch($batchData); // @phpstan-ignore argument.type } $bar->finish(); @@ -666,7 +666,7 @@ class NntmuxPopulateSearchIndexes extends Command /** * Process data for ElasticSearch with optimizations */ - private function processElasticData(string $indexName, int $total, $query, callable $transformer): int + private function processElasticData(string $indexName, int $total, mixed $query, callable $transformer): int { $chunkSize = $this->getChunkSize(); $batchSize = $this->getBatchSize(); @@ -748,6 +748,8 @@ class NntmuxPopulateSearchIndexes extends Command /** * Process search index batch with retry logic + * + * @param array $data */ private function processBatch(string $indexName, array $data): void { @@ -777,6 +779,8 @@ class NntmuxPopulateSearchIndexes extends Command /** * Process movies batch with retry logic + * + * @param array $data */ private function processMoviesBatch(array $data): void { @@ -799,6 +803,8 @@ class NntmuxPopulateSearchIndexes extends Command /** * Process TV shows batch with retry logic + * + * @param array $data */ private function processTvShowsBatch(array $data): void { @@ -821,6 +827,8 @@ class NntmuxPopulateSearchIndexes extends Command /** * Process ElasticSearch batch with retry logic + * + * @param array $data */ private function processElasticBatch(array $data, int &$errorCount): void { diff --git a/app/Console/Commands/NntmuxPopulateSteamApps.php b/app/Console/Commands/NntmuxPopulateSteamApps.php index ce0f51fab..eb42b6293 100644 --- a/app/Console/Commands/NntmuxPopulateSteamApps.php +++ b/app/Console/Commands/NntmuxPopulateSteamApps.php @@ -38,9 +38,9 @@ class NntmuxPopulateSteamApps extends Command $this->info(sprintf( 'Added %d new steam app(s), %d skipped, %d errors', - $stats['inserted'], - $stats['skipped'], - $stats['errors'] + $stats['inserted'], // @phpstan-ignore offsetAccess.notFound + $stats['skipped'], // @phpstan-ignore offsetAccess.notFound + $stats['errors'] // @phpstan-ignore offsetAccess.notFound )); } catch (\Exception $e) { $this->error($e->getMessage()); diff --git a/app/Console/Commands/NntmuxResetPostProcessing.php b/app/Console/Commands/NntmuxResetPostProcessing.php index 84eee74bc..12bb62552 100644 --- a/app/Console/Commands/NntmuxResetPostProcessing.php +++ b/app/Console/Commands/NntmuxResetPostProcessing.php @@ -9,9 +9,9 @@ use Illuminate\Console\Command; class NntmuxResetPostProcessing extends Command { /** - * @var array + * @var array */ - private static $allowedCategories = [ + private static $allowedCategories = [ // @phpstan-ignore property.defaultValue 'music', 'console', 'movie', @@ -96,7 +96,7 @@ class NntmuxResetPostProcessing extends Command $this->info('No releases to reset'); } } else { - $normalized = $this->normalizeCategories($raw); + $normalized = $this->normalizeCategories($raw); // @phpstan-ignore argument.type // Validate $invalid = $this->invalidCategories($normalized); @@ -154,6 +154,9 @@ class NntmuxResetPostProcessing extends Command * Normalize raw category options into a unique, lowercased list. * Handles comma-separated values, repeated options, casing, simple plurals, * and values provided as key=value (e.g. category=tv or the single-dash typo -category=tv). + * + * @param array $raw + * @return array */ private function normalizeCategories(array $raw): array { @@ -190,6 +193,9 @@ class NntmuxResetPostProcessing extends Command /** * Return invalid categories from a normalized list. * Keeps 'all' as a special allowed token. + * + * @param array $normalized + * @return array */ private function invalidCategories(array $normalized): array { diff --git a/app/Console/Commands/ProcessBackfill.php b/app/Console/Commands/ProcessBackfill.php index 08cbfe765..9b1711b37 100644 --- a/app/Console/Commands/ProcessBackfill.php +++ b/app/Console/Commands/ProcessBackfill.php @@ -38,7 +38,7 @@ class ProcessBackfill extends Command } try { - (new ForkingService)->backfill($options); + (new ForkingService)->backfill($options); // @phpstan-ignore argument.type return self::SUCCESS; } catch (\Exception $e) { diff --git a/app/Console/Commands/RecategorizeReleases.php b/app/Console/Commands/RecategorizeReleases.php index 2a4136705..d68b7e646 100644 --- a/app/Console/Commands/RecategorizeReleases.php +++ b/app/Console/Commands/RecategorizeReleases.php @@ -97,8 +97,9 @@ class RecategorizeReleases extends Command $this->line(''); $this->output->writeln('ID : '.$result->id); $this->output->writeln('Release : '.$result->searchname); - $this->output->writeln('Group : '.$result->group->name); // @phpstan-ignore property.notFound - $oldCategoryTitle = $result->category?->parent ? ($result->category->parent->title.' -> '.$result->category->title) : ($result->category?->title ?? 'N/A'); // @phpstan-ignore property.notFound, property.notFound, property.notFound, nullsafe.neverNull + $this->output->writeln('Group : '.$result->group->name); + $oldCategoryTitle = $result->category?->parent ? ($result->category->parent->title.' -> '.$result->category->title) : ($result->category?->title ?? 'N/A'); // @phpstan-ignore nullsafe.neverNull + $newCategoryTitle = $newCatName?->parent ? ($newCatName->parent->title.' -> '.$newCatName->title) : ($newCatName?->title ?? 'N/A'); // @phpstan-ignore nullsafe.neverNull $this->output->writeln('Category : '.$oldCategoryTitle.' '.$newCategoryTitle.''); $this->line(''); diff --git a/app/Console/Commands/RedisMonitor.php b/app/Console/Commands/RedisMonitor.php index 3b2137efb..177ba91d8 100644 --- a/app/Console/Commands/RedisMonitor.php +++ b/app/Console/Commands/RedisMonitor.php @@ -64,6 +64,8 @@ class RedisMonitor extends Command /** * Display stats in table format (for --once mode). + * + * @param array $stats */ protected function displayStats(array $stats): void { diff --git a/app/Console/Commands/RefreshAnimeData.php b/app/Console/Commands/RefreshAnimeData.php index 3acc078da..89ad9a730 100644 --- a/app/Console/Commands/RefreshAnimeData.php +++ b/app/Console/Commands/RefreshAnimeData.php @@ -200,7 +200,7 @@ class RefreshAnimeData extends Command continue; } - $anilistData = $searchResults[0]; + $anilistData = $searchResults[0]; // @phpstan-ignore offsetAccess.notFound $anilistId = $anilistData['id'] ?? null; if (! $anilistId) { diff --git a/app/Console/Commands/ReleasesFixNamesGroup.php b/app/Console/Commands/ReleasesFixNamesGroup.php index e5315486d..93c6027ea 100644 --- a/app/Console/Commands/ReleasesFixNamesGroup.php +++ b/app/Console/Commands/ReleasesFixNamesGroup.php @@ -325,7 +325,7 @@ class ReleasesFixNamesGroup extends Command /** * Fetch releases for processing */ - protected function fetchReleases(string $guidChar, int $maxPerRun) + protected function fetchReleases(string $guidChar, int $maxPerRun): mixed { return Release::fromQuery(sprintf(" SELECT diff --git a/app/Console/Commands/SteamLookupGame.php b/app/Console/Commands/SteamLookupGame.php index a9600dfea..6509695f2 100644 --- a/app/Console/Commands/SteamLookupGame.php +++ b/app/Console/Commands/SteamLookupGame.php @@ -93,6 +93,8 @@ class SteamLookupGame extends Command /** * Display game details in a formatted way. + * + * @param array $details */ protected function displayGameDetails(array $details): void { diff --git a/app/Console/Commands/TmuxMonitor.php b/app/Console/Commands/TmuxMonitor.php index 4250bbc6d..625f3178c 100644 --- a/app/Console/Commands/TmuxMonitor.php +++ b/app/Console/Commands/TmuxMonitor.php @@ -142,6 +142,8 @@ class TmuxMonitor extends Command /** * Run tasks in appropriate panes + * + * @param array $runVar */ private function runPaneTasks(array $runVar): void { @@ -165,6 +167,8 @@ class TmuxMonitor extends Command /** * Run IRC scraper + * + * @param array $runVar */ private function runIRCScraper(array $runVar): void { @@ -175,6 +179,8 @@ class TmuxMonitor extends Command /** * Run full non-sequential tasks + * + * @param array $runVar */ private function runFullTasks(array $runVar): void { @@ -193,6 +199,8 @@ class TmuxMonitor extends Command /** * Run basic sequential tasks + * + * @param array $runVar */ private function runBasicTasks(array $runVar): void { @@ -205,6 +213,8 @@ class TmuxMonitor extends Command /** * Run stripped sequential tasks + * + * @param array $runVar */ private function runSequentialTasks(array $runVar): void { @@ -214,6 +224,8 @@ class TmuxMonitor extends Command /** * Run post-processing tasks (common to most modes) + * + * @param array $runVar */ private function runPostProcessingTasks(array $runVar): void { diff --git a/app/Console/Commands/UpdateNNTmux.php b/app/Console/Commands/UpdateNNTmux.php index 58ca91e15..a3f433a9b 100644 --- a/app/Console/Commands/UpdateNNTmux.php +++ b/app/Console/Commands/UpdateNNTmux.php @@ -304,6 +304,8 @@ class UpdateNNTmux extends Command /** * Parse environment file into key-value pairs + * + * @return array */ private function parseEnvFile(string $path): array { @@ -329,6 +331,8 @@ class UpdateNNTmux extends Command /** * Add missing environment variables to .env file + * + * @param array $missingKeys */ private function addMissingEnvVars(string $envPath, array $missingKeys): void { diff --git a/app/Console/Commands/UpdateReleasesIndexSchema.php b/app/Console/Commands/UpdateReleasesIndexSchema.php index cde6ecc5c..449824c51 100644 --- a/app/Console/Commands/UpdateReleasesIndexSchema.php +++ b/app/Console/Commands/UpdateReleasesIndexSchema.php @@ -35,6 +35,8 @@ class UpdateReleasesIndexSchema extends Command /** * The expected schema fields for releases_rt + * + * @var array */ private array $expectedFields = [ 'name' => ['type' => 'text'], @@ -386,7 +388,7 @@ class UpdateReleasesIndexSchema extends Command // Process batch when it reaches the threshold if (count($batch) >= 1000) { - $result = $this->processBatch($indexName, $batch); + $result = $this->processBatch($indexName, $batch); // @phpstan-ignore argument.type $updated += $result['updated']; $errors += $result['errors']; $batch = []; @@ -397,7 +399,7 @@ class UpdateReleasesIndexSchema extends Command // Process remaining batch if (! empty($batch)) { - $result = $this->processBatch($indexName, $batch); + $result = $this->processBatch($indexName, $batch); // @phpstan-ignore argument.type $updated += $result['updated']; $errors += $result['errors']; } @@ -417,8 +419,10 @@ class UpdateReleasesIndexSchema extends Command /** * Prepare media data for a release + * + * @return array */ - private function prepareMediaData($release): array + private function prepareMediaData(mixed $release): array { return [ 'imdbid' => (int) ($release->imdbid ?: 0), @@ -462,6 +466,9 @@ class UpdateReleasesIndexSchema extends Command /** * Process a batch of updates + * + * @param array $batch + * @return array */ private function processBatch(string $indexName, array $batch): array { @@ -494,6 +501,8 @@ class UpdateReleasesIndexSchema extends Command /** * Insert or replace a document in the index * This is used as a fallback when UPDATE fails + * + * @param array $mediaData */ private function insertOrReplaceDocument(string $indexName, int $id, array $mediaData): void { diff --git a/app/Console/Commands/UpdateReleasesIndexSchemaES.php b/app/Console/Commands/UpdateReleasesIndexSchemaES.php index be0fd2e57..8adbb4bb8 100644 --- a/app/Console/Commands/UpdateReleasesIndexSchemaES.php +++ b/app/Console/Commands/UpdateReleasesIndexSchemaES.php @@ -34,6 +34,8 @@ class UpdateReleasesIndexSchemaES extends Command /** * The media fields that should exist in the releases index + * + * @var array */ private array $mediaFields = [ 'imdbid' => ['type' => 'integer'], @@ -570,8 +572,10 @@ class UpdateReleasesIndexSchemaES extends Command /** * Prepare media data for a release + * + * @return array */ - private function prepareMediaData($release): array + private function prepareMediaData(mixed $release): array { return [ 'imdbid' => (int) ($release->imdbid ?: 0), diff --git a/app/Events/UserAccessedApi.php b/app/Events/UserAccessedApi.php index 255694208..36e75cb59 100644 --- a/app/Events/UserAccessedApi.php +++ b/app/Events/UserAccessedApi.php @@ -20,7 +20,7 @@ class UserAccessedApi /** * Create a new event instance. */ - public function __construct($user, ?string $ip = null) + public function __construct(mixed $user, ?string $ip = null) { $this->user = $user; $this->ip = $ip; diff --git a/app/Events/UserLoggedIn.php b/app/Events/UserLoggedIn.php index 0c540c642..4679c9f38 100644 --- a/app/Events/UserLoggedIn.php +++ b/app/Events/UserLoggedIn.php @@ -10,17 +10,14 @@ class UserLoggedIn { use Dispatchable, InteractsWithSockets, SerializesModels; - /** - * @var \App\Models\User - */ - public $user; + public \App\Models\User $user; - public $ip; + public string $ip; /** * Create a new event instance. */ - public function __construct($user, $ip = '') + public function __construct(\App\Models\User $user, string $ip = '') { $this->user = $user; $this->ip = $ip; diff --git a/app/Extensions/helper/age_verification_helpers.php b/app/Extensions/helper/age_verification_helpers.php index cce1329bc..5a4c3c802 100644 --- a/app/Extensions/helper/age_verification_helpers.php +++ b/app/Extensions/helper/age_verification_helpers.php @@ -19,7 +19,7 @@ if (! function_exists('getRawHtmlWithAgeVerification')) { * @param string $url URL to fetch * @param string|false $cookie Optional cookie string (legacy support) * @param string|null $postData Optional POST data - * @return string|array|false + * @return string|array|false */ function getRawHtmlWithAgeVerification($url, $cookie = false, $postData = null) { @@ -106,7 +106,7 @@ if (! function_exists('initializeAdultSiteCookies')) { * Initialize age verification cookies for all adult sites * Run this once during application setup * - * @return array Statistics about initialized cookies + * @return array Statistics about initialized cookies */ function initializeAdultSiteCookies(): array { @@ -156,7 +156,7 @@ if (! function_exists('getAdultSiteCookieStats')) { /** * Get statistics about stored adult site cookies * - * @return array Cookie statistics + * @return array Cookie statistics */ function getAdultSiteCookieStats(): array { diff --git a/app/Extensions/helper/helpers.php b/app/Extensions/helper/helpers.php index 01432a0ce..a40777168 100644 --- a/app/Extensions/helper/helpers.php +++ b/app/Extensions/helper/helpers.php @@ -20,7 +20,7 @@ if (! function_exists('getRawHtml')) { * @param bool $cookie * @return bool|mixed|string */ - function getRawHtml($url, $cookie = false, $postData = null) + function getRawHtml(mixed $url, $cookie = false, mixed $postData = null) { // Check if this is an adult site that needs age verification $adultSites = [ @@ -112,7 +112,7 @@ if (! function_exists('makeFieldLinks')) { * * @throws Exception */ - function makeFieldLinks($data, $field, $type) + function makeFieldLinks(mixed $data, mixed $field, mixed $type) { $tmpArr = explode(', ', $data[$field]); $newArr = []; @@ -139,6 +139,7 @@ if (! function_exists('makeFieldLinks')) { if (! function_exists('getUserBrowseOrder')) { /** * @param string $orderBy + * @return array */ function getUserBrowseOrder($orderBy): array { @@ -163,6 +164,9 @@ if (! function_exists('getUserBrowseOrder')) { } if (! function_exists('getUserBrowseOrdering')) { + /** + * @return array + */ function getUserBrowseOrdering(): array { return [ @@ -206,7 +210,7 @@ if (! function_exists('human_filesize')) { /** * @param int $decimals */ - function human_filesize($bytes, $decimals = 0): string + function human_filesize(mixed $bytes, $decimals = 0): string { $size = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; $factor = (int) floor((\strlen((string) $bytes) - 1) / 3); @@ -219,7 +223,7 @@ if (! function_exists('bcdechex')) { /** * @return string */ - function bcdechex($dec) + function bcdechex(mixed $dec) { $hex = ''; do { @@ -262,7 +266,7 @@ if (! function_exists('runCmd')) { if (! function_exists('escapeString')) { - function escapeString($string): string + function escapeString(mixed $string): string { return DB::connection()->getPdo()->quote($string); } @@ -270,7 +274,7 @@ if (! function_exists('escapeString')) { if (! function_exists('realDuration')) { - function realDuration($milliseconds): string + function realDuration(mixed $milliseconds): string { $time = round($milliseconds / 1000); @@ -282,7 +286,7 @@ if (! function_exists('is_it_json')) { /** * @throws JsonException */ - function is_it_json($isIt): bool + function is_it_json(mixed $isIt): bool { if (is_array($isIt)) { return false; @@ -295,6 +299,8 @@ if (! function_exists('is_it_json')) { if (! function_exists('getStreamingZip')) { /** + * @param array $guids + * * @throws Exception */ function getStreamingZip(array $guids = []): STS\ZipStream\Builder @@ -461,7 +467,7 @@ if (! function_exists('getReleaseCover')) { /** * Get the cover image URL for a release based on its type and ID * - * @param object|array $release The release object or array + * @param object|array $release The release object or array * @return string The cover image URL or placeholder if no cover exists */ function getReleaseCover($release): string @@ -524,6 +530,10 @@ if (! function_exists('getReleaseCover')) { } if (! function_exists('sanitize')) { + /** + * @param array $doNotSanitize + * @param array $phrases + */ function sanitize(array|string $phrases, array $doNotSanitize = []): string { if (! is_array($phrases)) { @@ -658,7 +668,7 @@ if (! function_exists('getAvailableTimezones')) { /** * Get a list of available timezones grouped by region * - * @return array Array of timezones grouped by region + * @return array Array of timezones grouped by region */ function getAvailableTimezones(): array { @@ -737,7 +747,7 @@ if (! function_exists('streamSslContextOptions')) { * when connecting to a tls or ssl connection when using stream functions (fopen/file_get_contents/etc). * * @param bool $forceIgnore Force ignoring of verification (useful for self-signed certs in development). - * @return array Stream context options for SSL/TLS connections + * @return array Stream context options for SSL/TLS connections */ function streamSslContextOptions(bool $forceIgnore = false): array { @@ -775,6 +785,9 @@ if (! function_exists('streamSslContextOptions')) { } if (! function_exists('getCoverURL')) { + /** + * @param array $options + */ function getCoverURL(array $options = []): string { $defaults = [ @@ -845,7 +858,7 @@ if (! function_exists('imdb_trailers')) { /** * Fetches an embeddable video to a IMDB trailer from http://www.traileraddict.com. */ - function imdb_trailers($imdbID): string + function imdb_trailers(mixed $imdbID): string { $xml = getRawHtml('https://api.traileraddict.com/?imdb='.$imdbID); if ($xml !== false && preg_match('#(v\.traileraddict\.com/\d+)#i', $xml, $html)) { @@ -857,7 +870,7 @@ if (! function_exists('imdb_trailers')) { } if (! function_exists('showApiError')) { - function showApiError(int $errorCode = 900, string $errorText = '') + function showApiError(int $errorCode = 900, string $errorText = ''): mixed { $errorHeader = 'HTTP 1.1 400 Bad Request'; if ($errorText === '') { @@ -942,7 +955,7 @@ if (! function_exists('showApiError')) { } if (! function_exists('getRange')) { - function getRange($tableName): \Illuminate\Contracts\Pagination\LengthAwarePaginator + function getRange(mixed $tableName): \Illuminate\Contracts\Pagination\LengthAwarePaginator // @phpstan-ignore missingType.generics { $range = \Illuminate\Support\Facades\DB::table($tableName); if ($tableName === 'xxxinfo') { diff --git a/app/Facades/Categorization.php b/app/Facades/Categorization.php index 2922653ad..d0fce2f16 100644 --- a/app/Facades/Categorization.php +++ b/app/Facades/Categorization.php @@ -12,7 +12,7 @@ use Illuminate\Support\Facades\Facade; * * @see \App\Services\Categorization\CategorizationPipeline */ -class Categorization extends Facade +class Categorization extends Facade // @phpstan-ignore missingType.iterableValue, missingType.generics { protected static function getFacadeAccessor(): string { diff --git a/app/Facades/Elasticsearch.php b/app/Facades/Elasticsearch.php index be8d2bac9..9b4ec8321 100644 --- a/app/Facades/Elasticsearch.php +++ b/app/Facades/Elasticsearch.php @@ -16,7 +16,7 @@ use Illuminate\Support\Facades\Facade; * * @see \Mailerlite\LaravelElasticsearch\Manager */ -class Elasticsearch extends Facade +class Elasticsearch extends Facade // @phpstan-ignore missingType.iterableValue { protected static function getFacadeAccessor(): string { diff --git a/app/Facades/Search.php b/app/Facades/Search.php index 016cafad5..60efc2391 100644 --- a/app/Facades/Search.php +++ b/app/Facades/Search.php @@ -38,7 +38,7 @@ use Illuminate\Support\Facades\Facade; * * @see \App\Services\Search\SearchService */ -class Search extends Facade +class Search extends Facade // @phpstan-ignore missingType.iterableValue { /** * Get the registered name of the component. diff --git a/app/Facades/TvProcessing.php b/app/Facades/TvProcessing.php index d347fab6e..20aa44e1e 100644 --- a/app/Facades/TvProcessing.php +++ b/app/Facades/TvProcessing.php @@ -14,7 +14,7 @@ use Illuminate\Support\Facades\Facade; * * @see \App\Services\TvProcessing\TvProcessingPipeline */ -class TvProcessing extends Facade +class TvProcessing extends Facade // @phpstan-ignore missingType.iterableValue, missingType.generics { /** * Get the registered name of the component. diff --git a/app/Facades/Yenc.php b/app/Facades/Yenc.php index 9fd3ac754..ba65776e9 100644 --- a/app/Facades/Yenc.php +++ b/app/Facades/Yenc.php @@ -16,7 +16,7 @@ use Illuminate\Support\Facades\Facade; * * @see \App\Services\YencService */ -class Yenc extends Facade +class Yenc extends Facade // @phpstan-ignore missingType.iterableValue { /** * Get the registered name of the component. diff --git a/app/Http/Controllers/Admin/AdminAjaxController.php b/app/Http/Controllers/Admin/AdminAjaxController.php index eb9c3073c..d48cff3bb 100644 --- a/app/Http/Controllers/Admin/AdminAjaxController.php +++ b/app/Http/Controllers/Admin/AdminAjaxController.php @@ -13,7 +13,7 @@ class AdminAjaxController extends BasePageController /** * @throws \Throwable */ - public function ajaxAction(Request $request) + public function ajaxAction(Request $request): mixed { if ($request->missing('action')) { return response()->json(['success' => false, 'message' => 'No action specified'], 400); @@ -127,5 +127,8 @@ class AdminAjaxController extends BasePageController } catch (\Exception $e) { return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } + + return null; + } } diff --git a/app/Http/Controllers/Admin/AdminBlacklistController.php b/app/Http/Controllers/Admin/AdminBlacklistController.php index 3dfd70cdc..955f857d9 100644 --- a/app/Http/Controllers/Admin/AdminBlacklistController.php +++ b/app/Http/Controllers/Admin/AdminBlacklistController.php @@ -13,7 +13,7 @@ class AdminBlacklistController extends BasePageController /** * @throws \Exception */ - public function index() + public function index(): mixed { $this->setAdminPrefs(); $svc = new BlacklistService; diff --git a/app/Http/Controllers/Admin/AdminCategoryController.php b/app/Http/Controllers/Admin/AdminCategoryController.php index 78eb212b9..61e33d16a 100644 --- a/app/Http/Controllers/Admin/AdminCategoryController.php +++ b/app/Http/Controllers/Admin/AdminCategoryController.php @@ -12,7 +12,7 @@ class AdminCategoryController extends BasePageController /** * @throws \Exception */ - public function index() + public function index(): mixed { $this->setAdminPrefs(); $meta_title = $title = 'Category List'; diff --git a/app/Http/Controllers/Admin/AdminCategoryRegexesController.php b/app/Http/Controllers/Admin/AdminCategoryRegexesController.php index 8701a673a..988f82279 100644 --- a/app/Http/Controllers/Admin/AdminCategoryRegexesController.php +++ b/app/Http/Controllers/Admin/AdminCategoryRegexesController.php @@ -12,7 +12,7 @@ class AdminCategoryRegexesController extends BasePageController /** * @throws \Exception */ - public function index(Request $request) + public function index(Request $request): mixed { $this->setAdminPrefs(); $regexes = new RegexService('category_regexes'); diff --git a/app/Http/Controllers/Admin/AdminCollectionRegexesController.php b/app/Http/Controllers/Admin/AdminCollectionRegexesController.php index 9adb49e32..cf9618f1d 100644 --- a/app/Http/Controllers/Admin/AdminCollectionRegexesController.php +++ b/app/Http/Controllers/Admin/AdminCollectionRegexesController.php @@ -12,7 +12,7 @@ class AdminCollectionRegexesController extends BasePageController /** * @throws \Exception */ - public function index(Request $request) + public function index(Request $request): mixed { $this->setAdminPrefs(); $regexes = new RegexService('collection_regexes'); @@ -101,7 +101,7 @@ class AdminCollectionRegexesController extends BasePageController /** * @throws \Exception */ - public function testRegex(Request $request) + public function testRegex(Request $request): mixed { $this->setAdminPrefs(); $meta_title = $title = 'Collections Regex Test'; diff --git a/app/Http/Controllers/Admin/AdminContentController.php b/app/Http/Controllers/Admin/AdminContentController.php index b7dae178f..c306c06ed 100644 --- a/app/Http/Controllers/Admin/AdminContentController.php +++ b/app/Http/Controllers/Admin/AdminContentController.php @@ -13,7 +13,7 @@ class AdminContentController extends BasePageController * * @throws \Exception */ - public function index() + public function index(): mixed { $this->setAdminPrefs(); @@ -116,7 +116,7 @@ class AdminContentController extends BasePageController /** * Toggle content status (enable/disable). */ - public function toggleStatus(Request $request) + public function toggleStatus(Request $request): mixed { if ($request->has('id')) { $content = Content::query()->find($request->input('id')); @@ -145,7 +145,7 @@ class AdminContentController extends BasePageController /** * Delete content by ID. */ - public function destroy(Request $request) + public function destroy(Request $request): mixed { if ($request->has('id')) { $content = Content::query()->find($request->input('id')); @@ -180,6 +180,8 @@ class AdminContentController extends BasePageController /** * Add new content. + * + * @param array $data */ protected function addContent(array $data): int { @@ -208,6 +210,8 @@ class AdminContentController extends BasePageController /** * Update existing content. + * + * @param array $data */ protected function updateContent(array $data): int { @@ -240,6 +244,9 @@ class AdminContentController extends BasePageController /** * Normalize content URL to ensure proper formatting. + * + * @param array $data + * @return array */ protected function normalizeContentUrl(array $data): array { diff --git a/app/Http/Controllers/Admin/AdminFailedReleasesController.php b/app/Http/Controllers/Admin/AdminFailedReleasesController.php index 6c1550077..08d86cf3a 100644 --- a/app/Http/Controllers/Admin/AdminFailedReleasesController.php +++ b/app/Http/Controllers/Admin/AdminFailedReleasesController.php @@ -10,7 +10,7 @@ class AdminFailedReleasesController extends BasePageController /** * Display a listing of failed releases */ - public function index() + public function index(): mixed { $meta_title = $title = 'Failed Releases List'; $releaselist = Release::getFailedRange(); diff --git a/app/Http/Controllers/Admin/AdminGameController.php b/app/Http/Controllers/Admin/AdminGameController.php index e26965330..7f0d2665e 100644 --- a/app/Http/Controllers/Admin/AdminGameController.php +++ b/app/Http/Controllers/Admin/AdminGameController.php @@ -13,7 +13,7 @@ class AdminGameController extends BasePageController /** * Display a listing of games */ - public function index(Request $request) + public function index(Request $request): mixed { $game = new GamesService; @@ -36,7 +36,7 @@ class AdminGameController extends BasePageController /** * Show the form for editing a game */ - public function edit(Request $request) + public function edit(Request $request): mixed { $games = new GamesService; $gen = new GenreService; diff --git a/app/Http/Controllers/Admin/AdminGroupController.php b/app/Http/Controllers/Admin/AdminGroupController.php index b8390a4e2..53c854cd8 100644 --- a/app/Http/Controllers/Admin/AdminGroupController.php +++ b/app/Http/Controllers/Admin/AdminGroupController.php @@ -11,7 +11,7 @@ class AdminGroupController extends BasePageController /** * @throws \Exception */ - public function index(Request $request) + public function index(Request $request): mixed { $groupname = $request->input('groupname') ?? ''; $grouplist = UsenetGroup::getGroupsRange($groupname); @@ -23,7 +23,7 @@ class AdminGroupController extends BasePageController /** * @throws \Exception */ - public function createBulk(Request $request) + public function createBulk(Request $request): mixed { // set the current action $action = $request->input('action') ?? 'view'; @@ -97,7 +97,7 @@ class AdminGroupController extends BasePageController /** * @throws \Exception */ - public function active(Request $request) + public function active(Request $request): mixed { $gname = ''; if (! empty($request->input('groupname'))) { @@ -114,7 +114,7 @@ class AdminGroupController extends BasePageController /** * @throws \Exception */ - public function inactive(Request $request) + public function inactive(Request $request): mixed { $gname = ''; if (! empty($request->input('groupname'))) { diff --git a/app/Http/Controllers/Admin/AdminInvitationController.php b/app/Http/Controllers/Admin/AdminInvitationController.php index 5c74910aa..f1135afba 100644 --- a/app/Http/Controllers/Admin/AdminInvitationController.php +++ b/app/Http/Controllers/Admin/AdminInvitationController.php @@ -125,6 +125,8 @@ class AdminInvitationController extends BasePageController /** * Get overall invitation statistics with caching + * + * @return array */ private function getOverallStats(): array { @@ -149,6 +151,8 @@ class AdminInvitationController extends BasePageController /** * Get top inviters statistics with caching + * + * @return array */ private function getTopInviters(int $limit = 10): array { diff --git a/app/Http/Controllers/Admin/AdminMovieController.php b/app/Http/Controllers/Admin/AdminMovieController.php index 0e1d8d645..78a9411ef 100644 --- a/app/Http/Controllers/Admin/AdminMovieController.php +++ b/app/Http/Controllers/Admin/AdminMovieController.php @@ -21,7 +21,7 @@ class AdminMovieController extends BasePageController /** * @throws \Exception */ - public function index(Request $request) + public function index(Request $request): mixed { $lastSearch = $request->input('moviesearch', ''); diff --git a/app/Http/Controllers/Admin/AdminMusicController.php b/app/Http/Controllers/Admin/AdminMusicController.php index bd376980c..38a5d46c2 100644 --- a/app/Http/Controllers/Admin/AdminMusicController.php +++ b/app/Http/Controllers/Admin/AdminMusicController.php @@ -13,7 +13,7 @@ class AdminMusicController extends BasePageController /** * Display a listing of music */ - public function index(Request $request) + public function index(Request $request): mixed { $meta_title = $title = 'Music List'; @@ -34,7 +34,7 @@ class AdminMusicController extends BasePageController /** * Show the form for editing music */ - public function edit(Request $request) + public function edit(Request $request): mixed { $music = new MusicService; $gen = new GenreService; diff --git a/app/Http/Controllers/Admin/AdminPageController.php b/app/Http/Controllers/Admin/AdminPageController.php index 138873bd9..326ca8518 100644 --- a/app/Http/Controllers/Admin/AdminPageController.php +++ b/app/Http/Controllers/Admin/AdminPageController.php @@ -23,7 +23,7 @@ class AdminPageController extends BasePageController /** * @throws \Exception */ - public function index() + public function index(): mixed { $this->setAdminPrefs(); @@ -52,6 +52,8 @@ class AdminPageController extends BasePageController /** * Get recent user activity from the user_activities table with caching + * + * @return array */ protected function getRecentUserActivity(): array { @@ -78,7 +80,7 @@ class AdminPageController extends BasePageController /** * API endpoint to get recent user activity (for auto-refresh) */ - public function getRecentActivity() + public function getRecentActivity(): mixed { $activities = $this->getRecentUserActivity(); @@ -101,6 +103,8 @@ class AdminPageController extends BasePageController /** * Get default dashboard statistics with caching for expensive queries + * + * @return array */ protected function getDefaultStats(): array { @@ -179,6 +183,8 @@ class AdminPageController extends BasePageController /** * Get system metrics (CPU and RAM usage) with caching + * + * @return array */ protected function getSystemMetrics(): array { @@ -297,6 +303,8 @@ class AdminPageController extends BasePageController /** * Get detailed CPU information (cores, threads, model) + * + * @return array */ protected function getCpuInfo(): array { @@ -366,6 +374,8 @@ class AdminPageController extends BasePageController /** * Get system load average + * + * @return array */ protected function getLoadAverage(): array { @@ -405,6 +415,8 @@ class AdminPageController extends BasePageController /** * Get RAM usage information + * + * @return array */ protected function getRamUsage(): array { @@ -460,7 +472,7 @@ class AdminPageController extends BasePageController /** * Get minute-to-minute user activity data (API endpoint) */ - public function getUserActivityMinutes() + public function getUserActivityMinutes(): mixed { $downloadsPerMinute = $this->userStatsService->getDownloadsPerMinute(60); $apiHitsPerMinute = $this->userStatsService->getApiHitsPerMinute(60); @@ -474,7 +486,7 @@ class AdminPageController extends BasePageController /** * Get current system metrics (API endpoint) */ - public function getCurrentMetrics() + public function getCurrentMetrics(): mixed { $cpuUsage = $this->getCpuUsage(); $ramUsage = $this->getRamUsage(); @@ -501,7 +513,7 @@ class AdminPageController extends BasePageController /** * Get historical system metrics (API endpoint) */ - public function getHistoricalMetrics() + public function getHistoricalMetrics(): mixed { $timeRange = request('range', '24h'); // 24h or 30d diff --git a/app/Http/Controllers/Admin/AdminReleaseNamingRegexesController.php b/app/Http/Controllers/Admin/AdminReleaseNamingRegexesController.php index e80733fc8..ce4e90848 100644 --- a/app/Http/Controllers/Admin/AdminReleaseNamingRegexesController.php +++ b/app/Http/Controllers/Admin/AdminReleaseNamingRegexesController.php @@ -12,7 +12,7 @@ class AdminReleaseNamingRegexesController extends BasePageController /** * @throws \Exception */ - public function index(Request $request) + public function index(Request $request): mixed { $this->setAdminPrefs(); $regexes = new RegexService('release_naming_regexes'); @@ -108,7 +108,7 @@ class AdminReleaseNamingRegexesController extends BasePageController /** * @throws \Exception */ - public function testRegex(Request $request) + public function testRegex(Request $request): mixed { $this->setAdminPrefs(); $meta_title = $title = 'Release Naming Regex Test'; diff --git a/app/Http/Controllers/Admin/AdminReleasesController.php b/app/Http/Controllers/Admin/AdminReleasesController.php index 55717af86..f72bb0fec 100644 --- a/app/Http/Controllers/Admin/AdminReleasesController.php +++ b/app/Http/Controllers/Admin/AdminReleasesController.php @@ -21,7 +21,7 @@ class AdminReleasesController extends BasePageController /** * @throws \Exception */ - public function index(Request $request) + public function index(Request $request): mixed { $this->setAdminPrefs(); @@ -91,7 +91,7 @@ class AdminReleasesController extends BasePageController ]); } - public function destroy($id) + public function destroy(mixed $id): mixed { try { if ($id) { diff --git a/app/Http/Controllers/Admin/AdminRoleController.php b/app/Http/Controllers/Admin/AdminRoleController.php index f1316c313..20a53261f 100644 --- a/app/Http/Controllers/Admin/AdminRoleController.php +++ b/app/Http/Controllers/Admin/AdminRoleController.php @@ -11,7 +11,7 @@ class AdminRoleController extends BasePageController /** * @throws \Exception */ - public function index() + public function index(): mixed { $this->setAdminPrefs(); @@ -32,7 +32,7 @@ class AdminRoleController extends BasePageController /** * @throws \Exception */ - public function create(Request $request) + public function create(Request $request): mixed { $this->setAdminPrefs(); @@ -114,7 +114,7 @@ class AdminRoleController extends BasePageController /** * @throws \Exception */ - public function edit(Request $request) + public function edit(Request $request): mixed { $this->setAdminPrefs(); diff --git a/app/Http/Controllers/Admin/AdminSiteController.php b/app/Http/Controllers/Admin/AdminSiteController.php index 725dec81d..dfd001b4d 100644 --- a/app/Http/Controllers/Admin/AdminSiteController.php +++ b/app/Http/Controllers/Admin/AdminSiteController.php @@ -139,7 +139,7 @@ class AdminSiteController extends BasePageController /** * @throws \Exception */ - public function stats() + public function stats(): mixed { $meta_title = $title = 'Site Stats'; diff --git a/app/Http/Controllers/Admin/AdminTmuxController.php b/app/Http/Controllers/Admin/AdminTmuxController.php index 3d4aa2e46..0b1d2a045 100644 --- a/app/Http/Controllers/Admin/AdminTmuxController.php +++ b/app/Http/Controllers/Admin/AdminTmuxController.php @@ -11,7 +11,7 @@ class AdminTmuxController extends BasePageController /** * @throws \Exception */ - public function edit(Request $request) + public function edit(Request $request): mixed { $this->setAdminPrefs(); diff --git a/app/Http/Controllers/Admin/AdminUserController.php b/app/Http/Controllers/Admin/AdminUserController.php index f0b0952e5..6dfbb5b7c 100644 --- a/app/Http/Controllers/Admin/AdminUserController.php +++ b/app/Http/Controllers/Admin/AdminUserController.php @@ -18,7 +18,7 @@ class AdminUserController extends BasePageController /** * @throws \Throwable */ - public function index(Request $request) + public function index(Request $request): mixed { $this->setAdminPrefs(); diff --git a/app/Http/Controllers/Admin/AdminUserRoleHistoryController.php b/app/Http/Controllers/Admin/AdminUserRoleHistoryController.php index 4ab0a9784..a7ae37763 100644 --- a/app/Http/Controllers/Admin/AdminUserRoleHistoryController.php +++ b/app/Http/Controllers/Admin/AdminUserRoleHistoryController.php @@ -13,7 +13,7 @@ class AdminUserRoleHistoryController extends BasePageController /** * Display user role history list */ - public function index(Request $request) + public function index(Request $request): mixed { $this->setAdminPrefs(); @@ -83,7 +83,7 @@ class AdminUserRoleHistoryController extends BasePageController /** * Display role history for a specific user */ - public function show(Request $request, int $userId) + public function show(Request $request, int $userId): mixed { $this->setAdminPrefs(); diff --git a/app/Http/Controllers/Admin/DeletedUsersController.php b/app/Http/Controllers/Admin/DeletedUsersController.php index 19cb0a380..66c0f09fe 100644 --- a/app/Http/Controllers/Admin/DeletedUsersController.php +++ b/app/Http/Controllers/Admin/DeletedUsersController.php @@ -12,7 +12,7 @@ class DeletedUsersController extends BasePageController /** * Display a listing of soft-deleted users with filtering, sorting and pagination. */ - public function index(Request $request) + public function index(Request $request): mixed { $this->setAdminPrefs(); @@ -71,7 +71,7 @@ class DeletedUsersController extends BasePageController }); // Sorting - [$orderField, $orderSort] = $this->getSortOrder($orderBy); + [$orderField, $orderSort] = $this->getSortOrder($orderBy); // @phpstan-ignore offsetAccess.notFound $deletedUsers = $deletedUsers->orderBy($orderField, $orderSort) ->paginate(25) ->appends($request->except('page')); @@ -103,7 +103,7 @@ class DeletedUsersController extends BasePageController /** * Bulk restore or permanent delete. */ - public function bulkAction(Request $request) + public function bulkAction(Request $request): mixed { $action = $request->input('action'); $userIds = $request->input('user_ids', []); @@ -136,7 +136,7 @@ class DeletedUsersController extends BasePageController /** * Restore single user. */ - public function restore($id) + public function restore(mixed $id): mixed { $user = User::onlyTrashed()->find($id); if ($user) { @@ -151,7 +151,7 @@ class DeletedUsersController extends BasePageController /** * Permanently delete single user. */ - public function permanentDelete($id) + public function permanentDelete(mixed $id): mixed { $user = User::onlyTrashed()->find($id); if ($user) { @@ -166,6 +166,8 @@ class DeletedUsersController extends BasePageController /** * Parse and validate sort order. + * + * @return array */ private function getSortOrder(string $orderBy): array { @@ -198,6 +200,6 @@ class DeletedUsersController extends BasePageController } } - return [$orderField, $orderSort]; + return [$orderField, $orderSort]; // @phpstan-ignore return.type } } diff --git a/app/Http/Controllers/AdultController.php b/app/Http/Controllers/AdultController.php index 2be007d7f..51dd03e4f 100644 --- a/app/Http/Controllers/AdultController.php +++ b/app/Http/Controllers/AdultController.php @@ -21,7 +21,7 @@ class AdultController extends BasePageController /** * @throws \Exception */ - public function show(Request $request, string $id = '') + public function show(Request $request, string $id = ''): mixed { $moviecats = Category::getChildren(Category::XXX_ROOT); $mtmp = []; @@ -48,7 +48,7 @@ class AdultController extends BasePageController $page = $request->has('page') && is_numeric($request->input('page')) ? $request->input('page') : 1; $offset = ($page - 1) * config('nntmux.items_per_page'); - $rslt = $this->xxxBrowseService->getXXXRange($page, $catarray, $offset, config('nntmux.items_per_page'), $orderby, -1, $this->userdata['categoryexclusions']); + $rslt = $this->xxxBrowseService->getXXXRange($page, $catarray, $offset, config('nntmux.items_per_page'), $orderby, -1, $this->userdata['categoryexclusions']); // @phpstan-ignore argument.type $results = $this->paginate($rslt, $rslt[0]->_totalcount ?? 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query()); $title = ($request->has('title') && ! empty($request->input('title'))) ? stripslashes($request->input('title')) : ''; diff --git a/app/Http/Controllers/Api/ApiController.php b/app/Http/Controllers/Api/ApiController.php index 3457e916a..26f8bc95b 100644 --- a/app/Http/Controllers/Api/ApiController.php +++ b/app/Http/Controllers/Api/ApiController.php @@ -219,6 +219,7 @@ class ApiController extends BasePageController 'trakt' => $request->input('traktid') ?? '0', 'tvrage' => $request->input('rid') ?? '0', 'tvmaze' => $request->input('tvmazeid') ?? '0', + /** @phpstan-ignore argument.templateType */ 'imdb' => Str::replace('tt', '', $request->input('imdbid')) ?? '0', 'tmdb' => $request->input('tmdbid') ?? '0', ]; @@ -393,11 +394,12 @@ class ApiController extends BasePageController } /** + * @param array $params * @return Response|void * * @throws \Exception */ - public function output($data, array $params, bool $xml, int $offset, string $type = '') + public function output(mixed $data, array $params, bool $xml, int $offset, string $type = '') { $this->type = $type; $options = [ @@ -431,6 +433,8 @@ class ApiController extends BasePageController * Collect and return various capability information for usage in API. * * + * @return array + * * @throws \Exception */ public function getForMenu(): array @@ -487,6 +491,8 @@ class ApiController extends BasePageController /** * Verify cat parameter. + * + * @return array */ public function categoryID(Request $request): array { @@ -507,6 +513,8 @@ class ApiController extends BasePageController * Verify groupName parameter. * * + * @return list + * * @throws \Exception */ public function group(Request $request): string|int|bool @@ -560,7 +568,7 @@ class ApiController extends BasePageController } } - public function addCoverURL(&$releases, callable $getCoverURL): void + public function addCoverURL(mixed &$releases, callable $getCoverURL): void { if ($releases && \count($releases)) { foreach ($releases as $key => $release) { diff --git a/app/Http/Controllers/Api/RSS.php b/app/Http/Controllers/Api/RSS.php index 722b4ca0c..037bb77cb 100644 --- a/app/Http/Controllers/Api/RSS.php +++ b/app/Http/Controllers/Api/RSS.php @@ -6,7 +6,6 @@ use App\Models\Category; use App\Models\Release; use App\Services\Releases\ReleaseBrowseService; use App\Services\Releases\ReleaseSearchService; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; @@ -29,7 +28,7 @@ class RSS extends ApiController /** * @return Release[]|Collection|mixed */ - public function getRss($cat, $videosId, $aniDbID, int $userID = 0, int $airDate = -1, int $limit = 100, int $offset = 0) + public function getRss(mixed $cat, mixed $videosId, mixed $aniDbID, int $userID = 0, int $airDate = -1, int $limit = 100, int $offset = 0) { $catSearch = $cartSearch = ''; $catLimit = 'AND r.categories_id BETWEEN '.Category::TV_ROOT.' AND '.Category::TV_OTHER; @@ -93,9 +92,9 @@ class RSS extends ApiController } /** - * @return Builder|Collection + * @param array $excludedCats */ - public function getShowsRss(int $limit, int $userID = 0, array $excludedCats = [], int $airDate = -1) + public function getShowsRss(int $limit, int $userID = 0, array $excludedCats = [], int $airDate = -1): mixed { $sql = sprintf( @@ -122,6 +121,7 @@ class RSS extends ApiController } /** + * @param array $excludedCats * @return Release[]|Collection|mixed */ public function getMyMoviesRss(int $limit, int $userID = 0, array $excludedCats = []) @@ -152,7 +152,7 @@ class RSS extends ApiController /** * Get trending movies RSS (top 15 most downloaded in last 48 hours) * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function getTrendingMoviesRss() { @@ -216,7 +216,7 @@ class RSS extends ApiController /** * Get trending TV shows RSS (top 15 most downloaded in last 48 hours) * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function getTrendingShowsRss() { diff --git a/app/Http/Controllers/Api/XML_Response.php b/app/Http/Controllers/Api/XML_Response.php index 5d701695a..4a4312188 100644 --- a/app/Http/Controllers/Api/XML_Response.php +++ b/app/Http/Controllers/Api/XML_Response.php @@ -76,6 +76,8 @@ class XML_Response /** * XMLReturn constructor. + * + * @param array $options */ public function __construct(array $options = []) { @@ -203,7 +205,7 @@ class XML_Response /** * Starts a new element, loops through the attribute data and ends the element. * - * @param array $element An array with the name of the element and the attribute data + * @param array $element An array with the name of the element and the attribute data */ protected function addNode(array $element): void { @@ -217,7 +219,7 @@ class XML_Response /** * Starts a new element, loops through the attribute data and ends the element. * - * @param array $element An array with the name of the element and the attribute data + * @param array $element An array with the name of the element and the attribute data */ protected function addNodes(array $element): void { @@ -593,7 +595,7 @@ class XML_Response { $movieCol = ['rating', 'plot', 'year', 'genre', 'director', 'actors']; - $cData = $this->buildCdata($movieCol); + $cData = $this->buildCdata($movieCol); // @phpstan-ignore argument.type $this->cdata .= "\t
  • Imdb Info: @@ -614,7 +616,7 @@ class XML_Response $musicCol = ['mu_artist', 'mu_genre', 'mu_publisher', 'mu_releasedate', 'mu_review']; - $cData = $this->buildCdata($musicCol); + $cData = $this->buildCdata($musicCol); // @phpstan-ignore argument.type if ($this->release->mu_url !== '') { $cDataUrl = "
  • Amazon: release->mu_url}\">{$this->release->mu_title}
  • "; @@ -651,7 +653,7 @@ class XML_Response { $gamesCol = ['co_genre', 'co_publisher', 'year', 'co_review']; - $cData = $this->buildCdata($gamesCol); + $cData = $this->buildCdata($gamesCol); // @phpstan-ignore argument.type $this->cdata .= "
  • Console Info: @@ -665,7 +667,7 @@ class XML_Response /** * Accepts an array of values to loop through to build cData from the release info. * - * @param array $columns The columns in the release we need to insert + * @param array $columns The columns in the release we need to insert * @return string The HTML format cData */ protected function buildCdata(array $columns): string diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index 15fba19aa..8634d66f8 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -35,7 +35,7 @@ class ForgotPasswordController extends Controller /** * @throws \Exception */ - public function showLinkRequestForm(Request $request) + public function showLinkRequestForm(Request $request): mixed { // If it's a GET request, just show the form if ($request->isMethod('get')) { diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index ffb04b81e..d089eea95 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -186,7 +186,7 @@ class LoginController extends Controller return redirect()->to('login'); } - public function showLoginForm() + public function showLoginForm(): mixed { return view('auth.login'); } diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index a5ea40cc4..25957901a 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -52,6 +52,9 @@ class RegisterController extends Controller $this->middleware('guest', ['except' => ['getVerification', 'getVerificationError']]); } + /** + * @param array $data + */ protected function create(array $data): User { $user = User::create([ @@ -243,7 +246,7 @@ class RegisterController extends Controller return $this->showRegistrationForm($request, $error, $showRegister); } - public function showRegistrationForm(Request $request, string $error = '', int $showRegister = 0) + public function showRegistrationForm(Request $request, string $error = '', int $showRegister = 0): mixed { $inviteCode = ''; if ($request->has('invitecode')) { diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php index afe7aa143..32eb901c4 100644 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -41,7 +41,7 @@ class ResetPasswordController extends Controller /** * @throws \Exception */ - public function reset(Request $request) + public function reset(Request $request): mixed { if ($request->missing('guid')) { return redirect()->route('password.request')->withErrors(['error' => 'No reset code provided.']); @@ -69,7 +69,7 @@ class ResetPasswordController extends Controller ->with('message_type', 'success'); } - public function showResetForm(Request $request, $token = null) + public function showResetForm(Request $request, mixed $token = null): mixed { return view('auth.passwords.reset')->with([ 'token' => $token, diff --git a/app/Http/Controllers/BasePageController.php b/app/Http/Controllers/BasePageController.php index ffbd6d5d9..2155786ef 100644 --- a/app/Http/Controllers/BasePageController.php +++ b/app/Http/Controllers/BasePageController.php @@ -13,7 +13,10 @@ use Illuminate\View\View; class BasePageController extends Controller { - public \Illuminate\Support\Collection $settings; + /** + * @var Collection + */ + public \Illuminate\Support\Collection $settings; // @phpstan-ignore property.phpDocType, class.notFound, missingType.generics public string $title = ''; @@ -39,6 +42,8 @@ class BasePageController extends Controller /** * View data array for Blade templates + * + * @var array */ protected array $viewData = []; @@ -85,7 +90,10 @@ class BasePageController extends Controller }); } - public function paginate($query, $totalCount, $items, $page, $path, $reqQuery): LengthAwarePaginator + /** + * @return LengthAwarePaginator + */ + public function paginate(mixed $query, mixed $totalCount, mixed $items, mixed $page, mixed $path, mixed $reqQuery): LengthAwarePaginator { return new LengthAwarePaginator($query, $totalCount, $items, $page, ['path' => $path, 'query' => $reqQuery]); } diff --git a/app/Http/Controllers/BooksController.php b/app/Http/Controllers/BooksController.php index 83a97ff75..de3b93fab 100644 --- a/app/Http/Controllers/BooksController.php +++ b/app/Http/Controllers/BooksController.php @@ -12,7 +12,7 @@ class BooksController extends BasePageController /** * @throws \Exception */ - public function index(Request $request, string $id = '') + public function index(Request $request, string $id = ''): mixed { $bookService = new BookService; @@ -44,7 +44,7 @@ class BooksController extends BasePageController $books = []; $page = $request->has('page') && is_numeric($request->input('page')) ? $request->input('page') : 1; $offset = ($page - 1) * config('nntmux.items_per_cover_page'); - $rslt = $bookService->getBookRange($page, $catarray, $offset, config('nntmux.items_per_cover_page'), $orderby, (array) $this->userdata->categoryexclusions); + $rslt = $bookService->getBookRange($page, $catarray, $offset, config('nntmux.items_per_cover_page'), $orderby, (array) $this->userdata->categoryexclusions); // @phpstan-ignore argument.type $results = $this->paginate($rslt, $rslt[0]->_totalcount ?? 0, config('nntmux.items_per_cover_page'), $page, $request->url(), $request->query()); $maxwords = 50; foreach ($results as $result) { diff --git a/app/Http/Controllers/BrowseController.php b/app/Http/Controllers/BrowseController.php index 88161d31d..11687640e 100644 --- a/app/Http/Controllers/BrowseController.php +++ b/app/Http/Controllers/BrowseController.php @@ -20,7 +20,7 @@ class BrowseController extends BasePageController /** * @throws \Exception */ - public function index(Request $request) + public function index(Request $request): mixed { $ordering = $this->releaseBrowseService->getBrowseOrdering(); $orderBy = $request->has('ob') && ! empty($request->input('ob')) ? $request->input('ob') : ''; @@ -52,7 +52,7 @@ class BrowseController extends BasePageController /** * @throws \Exception */ - public function show(Request $request, string $parentCategory, string $id = 'All') + public function show(Request $request, string $parentCategory, string $id = 'All'): mixed { $parentId = RootCategory::query()->where('title', $parentCategory)->value('id'); @@ -158,7 +158,7 @@ class BrowseController extends BasePageController /** * @throws \Exception */ - public function group(Request $request) + public function group(Request $request): mixed { if ($request->has('g')) { $group = $request->input('g'); diff --git a/app/Http/Controllers/BrowseGroupController.php b/app/Http/Controllers/BrowseGroupController.php index e63e17615..6dbc23846 100644 --- a/app/Http/Controllers/BrowseGroupController.php +++ b/app/Http/Controllers/BrowseGroupController.php @@ -10,7 +10,7 @@ class BrowseGroupController extends BasePageController /** * @throws \Exception */ - public function show(Request $request) + public function show(Request $request): mixed { // Get the search term from the request $search = $request->get('search', '') ?? ''; diff --git a/app/Http/Controllers/CartController.php b/app/Http/Controllers/CartController.php index b9a606b06..da757392f 100644 --- a/app/Http/Controllers/CartController.php +++ b/app/Http/Controllers/CartController.php @@ -13,10 +13,9 @@ class CartController extends BasePageController /** * @throws \Exception */ - public function index() + public function index(): mixed { $results = UsersRelease::getCart(Auth::id()) - /** @phpstan-ignore property.notFound */ ->filter(fn ($item) => $item->release !== null); $this->viewData = array_merge($this->viewData, [ @@ -65,6 +64,8 @@ class CartController extends BasePageController } /** + * @param array $id + * * @throws \Exception */ public function destroy(array|string $id): RedirectResponse diff --git a/app/Http/Controllers/ConsoleController.php b/app/Http/Controllers/ConsoleController.php index 690f933e3..e836f806a 100644 --- a/app/Http/Controllers/ConsoleController.php +++ b/app/Http/Controllers/ConsoleController.php @@ -21,7 +21,7 @@ class ConsoleController extends BasePageController /** * @throws \Exception */ - public function show(Request $request, string $id = '') + public function show(Request $request, string $id = ''): mixed { if ($id === 'WiiVare') { $id = 'WiiVareVC'; @@ -55,7 +55,7 @@ class ConsoleController extends BasePageController $offset = ($page - 1) * config('nntmux.items_per_cover_page'); $consoles = []; - $rslt = $this->consoleService->getConsoleRange($page, $catarray, $offset, config('nntmux.items_per_cover_page'), $orderby, (array) $this->userdata->categoryexclusions); + $rslt = $this->consoleService->getConsoleRange($page, $catarray, $offset, config('nntmux.items_per_cover_page'), $orderby, (array) $this->userdata->categoryexclusions); // @phpstan-ignore argument.type $results = $this->paginate($rslt, $rslt[0]->_totalcount ?? 0, config('nntmux.items_per_cover_page'), $page, $request->url(), $request->query()); $maxwords = 50; diff --git a/app/Http/Controllers/ContactUsController.php b/app/Http/Controllers/ContactUsController.php index 92181a489..fa92342dd 100644 --- a/app/Http/Controllers/ContactUsController.php +++ b/app/Http/Controllers/ContactUsController.php @@ -10,7 +10,7 @@ class ContactUsController extends BasePageController /** * @throws \Illuminate\Validation\ValidationException */ - public function contact(ContactContactURequest $request) + public function contact(ContactContactURequest $request): mixed { $msg = ''; diff --git a/app/Http/Controllers/ContentController.php b/app/Http/Controllers/ContentController.php index a72e5c079..329dc6f56 100644 --- a/app/Http/Controllers/ContentController.php +++ b/app/Http/Controllers/ContentController.php @@ -79,8 +79,10 @@ class ContentController extends BasePageController /** * Get all active content ordered by type and ordinal. + * + * @return Collection */ - protected function getActiveContent(): \Illuminate\Database\Eloquent\Collection + protected function getActiveContent(): \Illuminate\Database\Eloquent\Collection // @phpstan-ignore class.notFound, missingType.generics, return.phpDocType { return Content::active() ->orderByRaw('contenttype, COALESCE(ordinal, 1000000)') @@ -89,8 +91,10 @@ class ContentController extends BasePageController /** * Get all content except the front page. + * + * @return Collection */ - protected function getAllButFront(): \Illuminate\Database\Eloquent\Collection + protected function getAllButFront(): \Illuminate\Database\Eloquent\Collection // @phpstan-ignore class.notFound, missingType.generics, return.phpDocType { return Content::query() ->where('id', '<>', 1) @@ -111,8 +115,10 @@ class ContentController extends BasePageController /** * Get front page content. + * + * @return Collection */ - protected function getFrontPageContent(): \Illuminate\Database\Eloquent\Collection + protected function getFrontPageContent(): \Illuminate\Database\Eloquent\Collection // @phpstan-ignore class.notFound, missingType.generics, return.phpDocType { return Content::frontPage()->get(); } diff --git a/app/Http/Controllers/DetailsController.php b/app/Http/Controllers/DetailsController.php index e4533645c..174f9e77f 100644 --- a/app/Http/Controllers/DetailsController.php +++ b/app/Http/Controllers/DetailsController.php @@ -48,7 +48,7 @@ class DetailsController extends BasePageController $this->releaseExtraService = $releaseExtraService; } - public function show(Request $request, string $guid) + public function show(Request $request, string $guid): mixed { $data = Release::getByGuid($guid); $releaseRegex = ''; diff --git a/app/Http/Controllers/GamesController.php b/app/Http/Controllers/GamesController.php index 76c2f1234..08f13d1ce 100644 --- a/app/Http/Controllers/GamesController.php +++ b/app/Http/Controllers/GamesController.php @@ -12,7 +12,7 @@ class GamesController extends BasePageController /** * @throws \Exception */ - public function show(Request $request) + public function show(Request $request): mixed { $games = new GamesService; $gen = new GenreService; diff --git a/app/Http/Controllers/GetNzbController.php b/app/Http/Controllers/GetNzbController.php index 152d860c7..427859333 100644 --- a/app/Http/Controllers/GetNzbController.php +++ b/app/Http/Controllers/GetNzbController.php @@ -206,13 +206,13 @@ class GetNzbController extends BasePageController return showApiError(501); } - $zip = getStreamingZip($guids); + $zip = getStreamingZip($guids); // @phpstan-ignore argument.type if ($zip === '') { // @phpstan-ignore identical.alwaysFalse return response()->json(['message' => 'Unable to create .zip file'], 404); } // Update statistics - $this->updateZipDownloadStatistics($request, $uid, $guids); + $this->updateZipDownloadStatistics($request, $uid, $guids); // @phpstan-ignore argument.type Log::channel('zipped')->info("User {$userName} downloaded zipped files from site with IP: {$request->ip()}"); @@ -221,6 +221,8 @@ class GetNzbController extends BasePageController /** * Update statistics for zip downloads + * + * @param array $guids */ private function updateZipDownloadStatistics(Request $request, int $uid, array $guids): void { diff --git a/app/Http/Controllers/MovieController.php b/app/Http/Controllers/MovieController.php index 6ecca17a7..be00c0184 100644 --- a/app/Http/Controllers/MovieController.php +++ b/app/Http/Controllers/MovieController.php @@ -23,7 +23,7 @@ class MovieController extends BasePageController /** * @throws \Exception */ - public function showMovies(Request $request, string $id = '') + public function showMovies(Request $request, string $id = ''): mixed { $moviecats = Category::getChildren(Category::MOVIE_ROOT)->map(function ($mcat) { return ['id' => $mcat->id, 'title' => $mcat->title]; @@ -102,7 +102,7 @@ class MovieController extends BasePageController * * @throws \Exception */ - public function showMovie(Request $request, string $imdbid) + public function showMovie(Request $request, string $imdbid): mixed { // Get movie info $movieInfo = $this->movieService->getMovieInfo($imdbid); @@ -115,6 +115,7 @@ class MovieController extends BasePageController $rslt = $this->movieBrowseService->getMovieRange(1, [], 0, 1000, '', -1, (array) $this->userdata->categoryexclusions); // Filter to only this movie's IMDB ID + /** @phpstan-ignore argument.templateType */ $movieData = collect($rslt)->firstWhere('imdbid', $imdbid); if (! $movieData) { @@ -219,7 +220,7 @@ class MovieController extends BasePageController * * @throws \Exception */ - public function showTrending(Request $request) + public function showTrending(Request $request): mixed { // Cache key for trending movies (48 hours) @@ -284,7 +285,7 @@ class MovieController extends BasePageController /** * Update user's movie layout preference */ - public function updateLayout(Request $request) + public function updateLayout(Request $request): mixed { $request->validate([ 'layout' => 'required|integer|in:1,2', diff --git a/app/Http/Controllers/MusicController.php b/app/Http/Controllers/MusicController.php index 24c50f556..fcdca6d19 100644 --- a/app/Http/Controllers/MusicController.php +++ b/app/Http/Controllers/MusicController.php @@ -13,7 +13,7 @@ class MusicController extends BasePageController /** * @throws \Exception */ - public function show(Request $request, string $id = '') + public function show(Request $request, string $id = ''): mixed { $music = new MusicService; $gen = new GenreService; @@ -46,7 +46,7 @@ class MusicController extends BasePageController $orderby = $request->has('ob') && \in_array($request->input('ob'), $ordering, false) ? $request->input('ob') : ''; $musics = []; - $rslt = $music->getMusicRange($page, $catarray, $offset, config('nntmux.items_per_cover_page'), $orderby, (array) $this->userdata->categoryexclusions); + $rslt = $music->getMusicRange($page, $catarray, $offset, config('nntmux.items_per_cover_page'), $orderby, (array) $this->userdata->categoryexclusions); // @phpstan-ignore argument.type $results = $this->paginate($rslt ?? [], $rslt[0]->_totalcount ?? 0, config('nntmux.items_per_cover_page'), $page, $request->url(), $request->query()); $artist = ($request->has('artist') && ! empty($request->input('artist'))) ? stripslashes($request->input('artist')) : ''; diff --git a/app/Http/Controllers/MyMoviesController.php b/app/Http/Controllers/MyMoviesController.php index 0816b6bf7..a0bf1de52 100644 --- a/app/Http/Controllers/MyMoviesController.php +++ b/app/Http/Controllers/MyMoviesController.php @@ -24,7 +24,7 @@ class MyMoviesController extends BasePageController $this->movieBrowseService = $movieBrowseService; } - public function show(Request $request) + public function show(Request $request): mixed { $action = $request->input('id') ?? ''; $imdbid = $request->input('imdb') ?? ''; diff --git a/app/Http/Controllers/MyShowsController.php b/app/Http/Controllers/MyShowsController.php index ec978fb2b..f6122445c 100644 --- a/app/Http/Controllers/MyShowsController.php +++ b/app/Http/Controllers/MyShowsController.php @@ -19,7 +19,7 @@ class MyShowsController extends BasePageController $this->releaseBrowseService = $releaseBrowseService; } - public function show(Request $request) + public function show(Request $request): mixed { $action = $request->input('action') ?? ''; $videoId = $request->input('id') ?? ''; @@ -167,7 +167,7 @@ class MyShowsController extends BasePageController /** * @throws \Exception */ - public function browse(Request $request) + public function browse(Request $request): mixed { $title = 'Browse My Shows'; $meta_title = 'My Shows'; diff --git a/app/Http/Controllers/NfoController.php b/app/Http/Controllers/NfoController.php index df26c9feb..7a1ea2322 100644 --- a/app/Http/Controllers/NfoController.php +++ b/app/Http/Controllers/NfoController.php @@ -11,7 +11,7 @@ class NfoController extends BasePageController /** * @throws \Exception */ - public function showNfo(Request $request, string $id = '') + public function showNfo(Request $request, string $id = ''): mixed { if ($id) { $rel = Release::getByGuid($id); diff --git a/app/Http/Controllers/PasswordSecurityController.php b/app/Http/Controllers/PasswordSecurityController.php index ab58c4ce8..5e8b72b0f 100644 --- a/app/Http/Controllers/PasswordSecurityController.php +++ b/app/Http/Controllers/PasswordSecurityController.php @@ -273,7 +273,7 @@ class PasswordSecurityController extends Controller * Display the 2FA verification form for a user who has already authenticated with username/password * but needs to enter their 2FA code. */ - public function getVerify2fa(Request $request) + public function getVerify2fa(Request $request): mixed { // Check if user ID is stored in the session if (! $request->session()->has('2fa:user:id')) { diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 7bc281f78..f11b05715 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -25,7 +25,7 @@ class ProfileController extends BasePageController /** * @throws \Throwable */ - public function show(Request $request) + public function show(Request $request): mixed { $userID = $this->userdata->id; @@ -346,7 +346,7 @@ class ProfileController extends BasePageController /** * Update user's dark mode preference */ - public function updateTheme(Request $request) + public function updateTheme(Request $request): mixed { $user = Auth::user(); diff --git a/app/Http/Controllers/RssController.php b/app/Http/Controllers/RssController.php index 2b67ddc71..b7b954758 100644 --- a/app/Http/Controllers/RssController.php +++ b/app/Http/Controllers/RssController.php @@ -91,7 +91,7 @@ class RssController extends BasePageController /** * @throws \Exception */ - public function showRssDesc() + public function showRssDesc(): mixed { $rss = app(RSS::class); @@ -120,7 +120,7 @@ class RssController extends BasePageController /** * @throws \Throwable */ - public function cartRss(Request $request) + public function cartRss(Request $request): mixed { $rss = app(RSS::class); $offset = 0; @@ -141,12 +141,14 @@ class RssController extends BasePageController $relData = $rss->getRss([-2], $userShow, $userAnidb, $user['user_id'], $userAirDate, $userLimit, $userNum); $rss->output($relData, $user['params'], $outputXML, $offset, 'rss'); + + return null; } /** * @throws \Throwable */ - public function categoryFeedRss(Request $request) + public function categoryFeedRss(Request $request): mixed { $rss = app(RSS::class); $offset = 0; @@ -171,12 +173,19 @@ class RssController extends BasePageController $outputXML = (! ($request->has('o') && $request->input('o') === 'json')); $relData = $rss->getRss($categoryId, $userShow, $userAnidb, $user['user_id'], $userAirDate, $userLimit, $userNum); $rss->output($relData, $user['params'], $outputXML, $offset, 'rss'); + + return null; + + return null; + + return null; + } /** * @throws \Throwable */ - public function trendingMoviesRss(Request $request) + public function trendingMoviesRss(Request $request): mixed { $rss = app(RSS::class); $offset = 0; @@ -189,12 +198,15 @@ class RssController extends BasePageController $relData = $rss->getTrendingMoviesRss(); $rss->output($relData, $user['params'], $outputXML, $offset, 'rss'); + + return null; + } /** * @throws \Throwable */ - public function trendingShowsRss(Request $request) + public function trendingShowsRss(Request $request): mixed { $rss = app(RSS::class); $offset = 0; @@ -207,9 +219,14 @@ class RssController extends BasePageController $relData = $rss->getTrendingShowsRss(); $rss->output($relData, $user['params'], $outputXML, $offset, 'rss'); + + return null; + } /** + * @return array + * * @throws \Throwable */ private function userCheck(Request $request): JsonResponse|array diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 710df2355..ed8e27173 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -31,7 +31,7 @@ class SearchController extends BasePageController /** * @throws \Exception */ - public function search(Request $request) + public function search(Request $request): mixed { $results = []; @@ -94,7 +94,7 @@ class SearchController extends BasePageController -1, $this->userdata->categoryexclusions ?? [], 'basic', - $categoryID); + $categoryID); // @phpstan-ignore argument.type $results = $this->paginate($rslt ?? [], $rslt[0]->_totalrows ?? 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query()); $category = $categoryID; @@ -199,7 +199,7 @@ class SearchController extends BasePageController -1, $this->userdata->categoryexclusions ?? [], 'advanced', - [$searchVars['searchadvcat'] === '' ? -1 : $searchVars['searchadvcat']] + [$searchVars['searchadvcat'] === '' ? -1 : $searchVars['searchadvcat']] // @phpstan-ignore argument.type ); $results = $this->paginate($rslt ?? [], $rslt[0]->_totalrows ?? 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query()); diff --git a/app/Http/Controllers/SeriesController.php b/app/Http/Controllers/SeriesController.php index d87d00aa3..2387bb3a2 100644 --- a/app/Http/Controllers/SeriesController.php +++ b/app/Http/Controllers/SeriesController.php @@ -23,7 +23,7 @@ class SeriesController extends BasePageController /** * @throws \Exception */ - public function index(Request $request, string $id = '') + public function index(Request $request, string $id = ''): mixed { if ($id && ctype_digit($id)) { @@ -40,7 +40,7 @@ class SeriesController extends BasePageController $page = max($page, 1); $offset = $seriesLimit > 0 ? ($page - 1) * $seriesLimit : 0; - $rel = $this->releaseSearchService->tvSearch(['id' => $id], '', '', '', $offset, $seriesLimit, '', $catarray, -1); + $rel = $this->releaseSearchService->tvSearch(['id' => $id], '', '', '', $offset, $seriesLimit, '', $catarray, -1); // @phpstan-ignore argument.type $show = Video::getByVideoID($id); @@ -60,6 +60,7 @@ class SeriesController extends BasePageController // Hydrate missing season/episode numbers if tv_episodes_id is set but series/episode missing or zero. $episodeMeta = collect(); + /** @phpstan-ignore argument.templateType */ $episodeIds = collect($rel)->pluck('tv_episodes_id')->filter(fn ($v) => $v > 0)->unique()->values(); if ($episodeIds->isNotEmpty()) { $episodeMeta = TvEpisode::whereIn('id', $episodeIds)->get()->keyBy('id'); @@ -303,7 +304,7 @@ class SeriesController extends BasePageController * * @throws \Exception */ - public function showTrending(Request $request) + public function showTrending(Request $request): mixed { // Cache key for trending TV shows (48 hours) $cacheKey = 'trending_tv_top_15_48h'; diff --git a/app/Http/Middleware/ClearanceMiddleware.php b/app/Http/Middleware/ClearanceMiddleware.php index 26debca6a..aeb356cc3 100644 --- a/app/Http/Middleware/ClearanceMiddleware.php +++ b/app/Http/Middleware/ClearanceMiddleware.php @@ -145,7 +145,7 @@ class ClearanceMiddleware * * @return string|null The blocked category name, or null if allowed */ - protected function checkMainCategoryPermission($user, string $parentCategoryName): ?string + protected function checkMainCategoryPermission(mixed $user, string $parentCategoryName): ?string { $categoryPermissions = [ 'movies' => 'view movies', @@ -184,7 +184,7 @@ class ClearanceMiddleware * * @return string|null The blocked subcategory name, or null if allowed */ - protected function checkSubcategoryExclusion($user, string $parentCategoryName, string $subcategoryName): ?string + protected function checkSubcategoryExclusion(mixed $user, string $parentCategoryName, string $subcategoryName): ?string { // Get the root category ID $rootCategory = RootCategory::query() diff --git a/app/Http/Requests/Auth/LoginLoginRequest.php b/app/Http/Requests/Auth/LoginLoginRequest.php index 65af78495..6217fa2e6 100644 --- a/app/Http/Requests/Auth/LoginLoginRequest.php +++ b/app/Http/Requests/Auth/LoginLoginRequest.php @@ -9,6 +9,8 @@ class LoginLoginRequest extends FormRequest { /** * Get the validation rules that apply to the request. + * + * @return array */ public function rules(): array { diff --git a/app/Http/Requests/Auth/RegisterRegisterRequest.php b/app/Http/Requests/Auth/RegisterRegisterRequest.php index ee2d2535d..9663f8968 100644 --- a/app/Http/Requests/Auth/RegisterRegisterRequest.php +++ b/app/Http/Requests/Auth/RegisterRegisterRequest.php @@ -9,6 +9,8 @@ class RegisterRegisterRequest extends FormRequest { /** * Get the validation rules that apply to the request. + * + * @return array */ public function rules(): array { diff --git a/app/Http/Requests/Auth/ShowLinkRequestFormForgotPasswordRequest.php b/app/Http/Requests/Auth/ShowLinkRequestFormForgotPasswordRequest.php index 70959f5ba..4d7fcd90a 100644 --- a/app/Http/Requests/Auth/ShowLinkRequestFormForgotPasswordRequest.php +++ b/app/Http/Requests/Auth/ShowLinkRequestFormForgotPasswordRequest.php @@ -10,7 +10,7 @@ class ShowLinkRequestFormForgotPasswordRequest extends FormRequest /** * Get the validation rules that apply to the request. * - * @return array + * @return array */ public function rules() { diff --git a/app/Http/Requests/ContactContactURequest.php b/app/Http/Requests/ContactContactURequest.php index 2162b53af..a380df292 100644 --- a/app/Http/Requests/ContactContactURequest.php +++ b/app/Http/Requests/ContactContactURequest.php @@ -9,6 +9,8 @@ class ContactContactURequest extends FormRequest { /** * Get the validation rules that apply to the request. + * + * @return array */ public function rules(): array { diff --git a/app/Http/Requests/Disable2faPasswordSecurityRequest.php b/app/Http/Requests/Disable2faPasswordSecurityRequest.php index 0016ffe89..cf62de00b 100644 --- a/app/Http/Requests/Disable2faPasswordSecurityRequest.php +++ b/app/Http/Requests/Disable2faPasswordSecurityRequest.php @@ -8,6 +8,8 @@ class Disable2faPasswordSecurityRequest extends FormRequest { /** * Get the validation rules that apply to the request. + * + * @return array */ public function rules(): array { diff --git a/app/Jobs/SendAccountWillExpireEmail.php b/app/Jobs/SendAccountWillExpireEmail.php index b5ba6b645..9c02cf7f6 100644 --- a/app/Jobs/SendAccountWillExpireEmail.php +++ b/app/Jobs/SendAccountWillExpireEmail.php @@ -14,16 +14,14 @@ class SendAccountWillExpireEmail implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - private $days; + private int $days; - private $user; + private \App\Models\User $user; /** * Create a new job instance. - * - * @return void */ - public function __construct($user, $days) + public function __construct(\App\Models\User $user, int $days) { $this->user = $user; $this->days = $days; diff --git a/app/Jobs/SendContactUsEmail.php b/app/Jobs/SendContactUsEmail.php index 485582e50..e66a4d0a9 100644 --- a/app/Jobs/SendContactUsEmail.php +++ b/app/Jobs/SendContactUsEmail.php @@ -14,16 +14,16 @@ class SendContactUsEmail implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - private $email; + private string $email; - private $mailTo; + private string $mailTo; - private $mailBody; + private string $mailBody; /** * SendContactUsEmail constructor. */ - public function __construct($email, $mailTo, $mailBody) + public function __construct(string $email, string $mailTo, string $mailBody) { $this->email = $email; $this->mailTo = $mailTo; diff --git a/app/Jobs/SendInviteEmail.php b/app/Jobs/SendInviteEmail.php index 92539635c..b1e7055e5 100644 --- a/app/Jobs/SendInviteEmail.php +++ b/app/Jobs/SendInviteEmail.php @@ -14,19 +14,16 @@ class SendInviteEmail implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - private $email; + private string $email; - private $url; + private string $url; - /** - * @var \App\Models\User - */ - private $user; + private \App\Models\User $user; /** * SendInviteEmail constructor. */ - public function __construct($email, $user, $url) + public function __construct(string $email, \App\Models\User $user, string $url) { $this->email = $email; $this->user = $user; diff --git a/app/Jobs/SendPasswordForgottenEmail.php b/app/Jobs/SendPasswordForgottenEmail.php index 3f89925a3..d1dbbb458 100644 --- a/app/Jobs/SendPasswordForgottenEmail.php +++ b/app/Jobs/SendPasswordForgottenEmail.php @@ -15,17 +15,14 @@ class SendPasswordForgottenEmail implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - private $resetLink; + private string $resetLink; - /** - * @var User - */ - private $user; + private User $user; /** * Create a new job instance. */ - public function __construct(User $user, $resetLink) + public function __construct(User $user, string $resetLink) { $this->user = $user; $this->resetLink = $resetLink; diff --git a/app/Mail/AccountDeleted.php b/app/Mail/AccountDeleted.php index da5993307..adefd70b9 100644 --- a/app/Mail/AccountDeleted.php +++ b/app/Mail/AccountDeleted.php @@ -28,7 +28,7 @@ class AccountDeleted extends Mailable /** * Create a new message instance. */ - public function __construct($user) + public function __construct(mixed $user) { $this->user = $user; $this->siteEmail = config('mail.from.address'); diff --git a/app/Mail/AccountExpired.php b/app/Mail/AccountExpired.php index 14e87b2cd..25487fdfc 100644 --- a/app/Mail/AccountExpired.php +++ b/app/Mail/AccountExpired.php @@ -10,16 +10,16 @@ class AccountExpired extends Mailable { use Queueable, SerializesModels; - public $user; + public \App\Models\User $user; - private $siteEmail; + private mixed $siteEmail; - private $siteTitle; + private mixed $siteTitle; /** * Create a new message instance. */ - public function __construct($user) + public function __construct(\App\Models\User $user) { $this->user = $user; $this->siteEmail = config('mail.from.address'); diff --git a/app/Mail/AccountWillExpire.php b/app/Mail/AccountWillExpire.php index d81899377..d041b8530 100644 --- a/app/Mail/AccountWillExpire.php +++ b/app/Mail/AccountWillExpire.php @@ -10,26 +10,18 @@ class AccountWillExpire extends Mailable { use Queueable, SerializesModels; - private $days; + private int $days; - private $user; + private \App\Models\User $user; - /** - * @var mixed - */ - private $siteEmail; + private mixed $siteEmail; - /** - * @var mixed - */ - private $siteTitle; + private mixed $siteTitle; /** * Create a new message instance. - * - * @return void */ - public function __construct($user, $days) + public function __construct(\App\Models\User $user, int $days) { $this->user = $user; $this->days = $days; diff --git a/app/Mail/ContactUs.php b/app/Mail/ContactUs.php index 9fa21d292..efac85db7 100644 --- a/app/Mail/ContactUs.php +++ b/app/Mail/ContactUs.php @@ -19,7 +19,7 @@ class ContactUs extends Mailable /** * Create a new message instance. */ - public function __construct($mailTo, $mailFrom, $mailBody) + public function __construct(mixed $mailTo, mixed $mailFrom, mixed $mailBody) { $this->mailTo = $mailTo; $this->mailFrom = $mailFrom; diff --git a/app/Mail/ForgottenPassword.php b/app/Mail/ForgottenPassword.php index 32a9bddd6..810324694 100644 --- a/app/Mail/ForgottenPassword.php +++ b/app/Mail/ForgottenPassword.php @@ -10,24 +10,18 @@ class ForgottenPassword extends Mailable { use Queueable, SerializesModels; - public $user; + public mixed $user; - public $resetLink; + public string $resetLink; - /** - * @var mixed - */ - private $siteEmail; + private mixed $siteEmail; - /** - * @var mixed - */ - private $siteTitle; + private mixed $siteTitle; /** * Create a new message instance. */ - public function __construct($resetLink) + public function __construct(string $resetLink) { $this->resetLink = $resetLink; $this->siteEmail = config('mail.from.address'); diff --git a/app/Mail/NewAccountCreatedEmail.php b/app/Mail/NewAccountCreatedEmail.php index 07a9bad63..0a8668ff0 100644 --- a/app/Mail/NewAccountCreatedEmail.php +++ b/app/Mail/NewAccountCreatedEmail.php @@ -30,7 +30,7 @@ class NewAccountCreatedEmail extends Mailable * * @return void */ - public function __construct($user) + public function __construct(mixed $user) { $this->user = $user; $this->siteEmail = config('mail.from.address'); diff --git a/app/Mail/PasswordReset.php b/app/Mail/PasswordReset.php index b804566ef..d609895d4 100644 --- a/app/Mail/PasswordReset.php +++ b/app/Mail/PasswordReset.php @@ -34,7 +34,7 @@ class PasswordReset extends Mailable /** * PasswordReset constructor. */ - public function __construct(User $user, $newPass) + public function __construct(User $user, mixed $newPass) { $this->user = $user; $this->newPass = $newPass; diff --git a/app/Mail/SendInvite.php b/app/Mail/SendInvite.php index e068ffb71..f28312a92 100644 --- a/app/Mail/SendInvite.php +++ b/app/Mail/SendInvite.php @@ -34,7 +34,7 @@ class SendInvite extends Mailable /** * SendInvite constructor. */ - public function __construct(User $user, $invite) + public function __construct(User $user, mixed $invite) { $this->user = $user; $this->invite = $invite; diff --git a/app/Models/AnidbEpisode.php b/app/Models/AnidbEpisode.php index e128e9765..b1d980a2c 100644 --- a/app/Models/AnidbEpisode.php +++ b/app/Models/AnidbEpisode.php @@ -53,11 +53,17 @@ class AnidbEpisode extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\AnidbTitle, $this> + */ public function title(): BelongsTo { return $this->belongsTo(AnidbTitle::class, 'anidbid'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\AnidbInfo, $this> + */ public function info(): HasMany { return $this->hasMany(AnidbInfo::class, 'anidbid'); diff --git a/app/Models/AnidbInfo.php b/app/Models/AnidbInfo.php index 4702cb9bf..ab9415a11 100644 --- a/app/Models/AnidbInfo.php +++ b/app/Models/AnidbInfo.php @@ -84,6 +84,8 @@ class AnidbInfo extends Model /** * Get the title associated with this info. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\AnidbTitle, $this> */ public function title(): BelongsTo { @@ -92,6 +94,8 @@ class AnidbInfo extends Model /** * Get the releases associated with this anime. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> */ public function releases(): HasMany { diff --git a/app/Models/AnidbTitle.php b/app/Models/AnidbTitle.php index 386df3207..af61050ad 100644 --- a/app/Models/AnidbTitle.php +++ b/app/Models/AnidbTitle.php @@ -49,6 +49,9 @@ class AnidbTitle extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\AnidbInfo, $this> + */ public function info(): HasMany { return $this->hasMany(AnidbInfo::class, 'anidbid'); diff --git a/app/Models/BookInfo.php b/app/Models/BookInfo.php index 8df920765..007e4f485 100644 --- a/app/Models/BookInfo.php +++ b/app/Models/BookInfo.php @@ -70,6 +70,9 @@ class BookInfo extends Model return 'ix_bookinfo_author_title_ft'; } + /** + * @return array + */ public function toSearchableArray(): array { return [ @@ -80,6 +83,8 @@ class BookInfo extends Model /** * Get the releases associated with this book. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> */ public function releases(): HasMany { diff --git a/app/Models/Category.php b/app/Models/Category.php index 4db963d6f..8c363a0ee 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -269,20 +269,23 @@ class Category extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> + */ public function releases(): HasMany { return $this->hasMany(Release::class, 'categories_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\RootCategory, $this> + */ public function parent(): BelongsTo { return $this->belongsTo(RootCategory::class, 'root_categories_id'); } - /** - * @return \Illuminate\Database\Eloquent\Collection - */ - public static function getRecentlyAdded() + public static function getRecentlyAdded(): mixed { $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); $result = Cache::get(md5('RecentlyAdded')); @@ -304,7 +307,11 @@ class Category extends Model return $result; } - public static function getCategorySearch(array $cat = [], ?string $searchType = null, $builder = false): string|array|null + /** + * @param array $cat + * @return array + */ + public static function getCategorySearch(array $cat = [], ?string $searchType = null, mixed $builder = false): string|array|null { // Generate a cache key based on the input parameters $cacheKey = 'cat_search_'.md5(serialize($cat).$searchType.($builder ? '1' : '0')); @@ -390,7 +397,7 @@ class Category extends Model /** * @return mixed */ - public static function getCategoryValue($category) + public static function getCategoryValue(mixed $category) { return \constant('self::'.$category); } @@ -398,7 +405,7 @@ class Category extends Model /** * Check if category is parent. */ - public static function isParent($cid): bool + public static function isParent(mixed $cid): bool { // Cache the parent category check to avoid repeated DB queries $cacheKey = 'cat_is_parent_'.$cid; @@ -416,10 +423,7 @@ class Category extends Model return $isParent; } - /** - * @return \Illuminate\Database\Eloquent\Collection - */ - public static function getFlat() + public static function getFlat(): mixed { return self::query()->get(); } @@ -430,7 +434,7 @@ class Category extends Model * * @return mixed */ - public static function getChildren($categoryId) + public static function getChildren(mixed $categoryId) { $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); $result = Cache::get(md5($categoryId)); @@ -446,21 +450,16 @@ class Category extends Model /** * Get names of enabled parent categories. - * - * @return \Illuminate\Database\Eloquent\Collection */ - public static function getEnabledParentNames() + public static function getEnabledParentNames(): mixed { return RootCategory::query()->where('status', '=', 1)->get(['title']); } /** * Returns category ID's for site disabled categories. - * - * - * @return \Illuminate\Database\Eloquent\Collection */ - public static function getDisabledIDs() + public static function getDisabledIDs(): mixed { return self::query() ->where('status', '=', 2) @@ -469,10 +468,8 @@ class Category extends Model /** * Get multiple categories. - * - * @return bool|\Illuminate\Database\Eloquent\Collection */ - public static function getByIds($ids) + public static function getByIds(mixed $ids): mixed { if (\count($ids) > 0) { $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); @@ -493,7 +490,7 @@ class Category extends Model /** * Return the parent and category name from the supplied categoryID. */ - public static function getNameByID($categoryId): string + public static function getNameByID(mixed $categoryId): string { $cat = self::query()->where('id', $categoryId)->first(); @@ -503,7 +500,7 @@ class Category extends Model /** * @return bool|mixed */ - public static function getIdByName($title, $parent) + public static function getIdByName(mixed $title, mixed $parent) { $cat = self::query()->where('title', $title)->with('parent.'.$parent)->first(['id']); @@ -513,7 +510,7 @@ class Category extends Model /** * Update a category. */ - public static function updateCategory($id, $status, $desc, $disablepreview, $minsize, $maxsize): int + public static function updateCategory(mixed $id, mixed $status, mixed $desc, mixed $disablepreview, mixed $minsize, mixed $maxsize): int { return self::query()->where('id', $id)->update( [ @@ -526,6 +523,10 @@ class Category extends Model ); } + /** + * @param array $excludedCats + * @return array + */ public static function getForMenu(array $excludedCats = []): array { $categoriesResult = []; @@ -546,9 +547,9 @@ class Category extends Model } /** - * @return mixed + * @return list */ - public static function getForApi() + public static function getForApi(): mixed { $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); $result = Cache::get(md5('ForApi')); @@ -565,6 +566,8 @@ class Category extends Model /** * Return a list of categories for use in a dropdown. + * + * @return array */ public static function getForSelect(bool $blnIncludeNoneSelected = true): array { @@ -582,7 +585,11 @@ class Category extends Model return $temp_array; } - public static function getCategories(bool $activeOnly = false, array $excludedCats = []): \Illuminate\Database\Eloquent\Collection + /** + * @param array $excludedCats + * @return array + */ + public static function getCategories(bool $activeOnly = false, array $excludedCats = []): \Illuminate\Database\Eloquent\Collection // @phpstan-ignore missingType.generics { $sql = self::query() ->with('parent') diff --git a/app/Models/ConsoleInfo.php b/app/Models/ConsoleInfo.php index 7df6de12f..a1afb82d4 100644 --- a/app/Models/ConsoleInfo.php +++ b/app/Models/ConsoleInfo.php @@ -67,6 +67,9 @@ class ConsoleInfo extends Model return 'ix_consoleinfo_title_platform_ft'; } + /** + * @return array + */ public function toSearchableArray(): array { return [ @@ -81,6 +84,8 @@ class ConsoleInfo extends Model /** * Get the genre for the console info. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Genre, $this> */ public function genre(): BelongsTo { @@ -89,6 +94,8 @@ class ConsoleInfo extends Model /** * Get the releases for the console info. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> */ public function releases(): HasMany { @@ -102,7 +109,7 @@ class ConsoleInfo extends Model /** * Scope a query to only include consoles with covers. */ - public function scopeWithCover($query) + public function scopeWithCover(mixed $query): mixed { return $query->where('cover', 1); } @@ -110,7 +117,7 @@ class ConsoleInfo extends Model /** * Scope a query to only include consoles for a specific platform. */ - public function scopeForPlatform($query, string $platform) + public function scopeForPlatform(mixed $query, string $platform): mixed { return $query->where('platform', $platform); } diff --git a/app/Models/Content.php b/app/Models/Content.php index 3e8ad7f61..bb9e7d56f 100644 --- a/app/Models/Content.php +++ b/app/Models/Content.php @@ -89,7 +89,7 @@ class Content extends Model /** * Scope: Get only active content. */ - public function scopeActive(Builder $query): Builder + public function scopeActive(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->where('status', self::STATUS_ENABLED); } @@ -97,7 +97,7 @@ class Content extends Model /** * Scope: Get content of a specific type. */ - public function scopeOfType(Builder $query, int $type): Builder + public function scopeOfType(Builder $query, int $type): Builder // @phpstan-ignore missingType.generics { return $query->where('contenttype', $type); } @@ -105,7 +105,7 @@ class Content extends Model /** * Scope: Get content accessible by a specific role. */ - public function scopeForRole(Builder $query, int $role): Builder + public function scopeForRole(Builder $query, int $role): Builder // @phpstan-ignore missingType.generics { // Admins and moderators can see everything if (\in_array($role, [User::ROLE_ADMIN, User::ROLE_MODERATOR], true)) { @@ -122,7 +122,7 @@ class Content extends Model /** * Scope: Get front page content. */ - public function scopeFrontPage(Builder $query): Builder + public function scopeFrontPage(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->active() // @phpstan-ignore method.notFound ->ofType(self::TYPE_INDEX) diff --git a/app/Models/DnzbFailure.php b/app/Models/DnzbFailure.php index e9e58165e..1992d39bd 100644 --- a/app/Models/DnzbFailure.php +++ b/app/Models/DnzbFailure.php @@ -46,11 +46,17 @@ class DnzbFailure extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Release, $this> + */ public function release(): BelongsTo { return $this->belongsTo(Release::class, 'release_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> + */ public function user(): BelongsTo { return $this->belongsTo(User::class, 'users_id'); @@ -62,7 +68,7 @@ class DnzbFailure extends Model * * @return bool|mixed */ - public static function getFailedCount($relId) + public static function getFailedCount(mixed $relId) { $result = self::query()->where('release_id', $relId)->value('failed'); if (! empty($result)) { diff --git a/app/Models/DownloadStat.php b/app/Models/DownloadStat.php index 35e263cf8..55fd0cfce 100644 --- a/app/Models/DownloadStat.php +++ b/app/Models/DownloadStat.php @@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model; class DownloadStat extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $guarded = []; @@ -33,6 +33,9 @@ class DownloadStat extends Model } } + /** + * @return array + */ public static function getTopDownloads(): array { return self::query()->select(['searchname', 'guid', 'adddate', 'grabs'])->get()->toArray(); diff --git a/app/Models/Forumpost.php b/app/Models/Forumpost.php index 989143deb..4f5d26a2f 100644 --- a/app/Models/Forumpost.php +++ b/app/Models/Forumpost.php @@ -52,7 +52,7 @@ class Forumpost extends Model */ protected $guarded = []; - public static function add($parentId, $userid, $subject, $message, int $locked = 0, int $sticky = 0, int $replies = 0): int + public static function add(mixed $parentId, mixed $userid, mixed $subject, mixed $message, int $locked = 0, int $sticky = 0, int $replies = 0): int { if ($message === '') { return -1; @@ -87,7 +87,7 @@ class Forumpost extends Model * * @return Model|null|static */ - public static function getParent($parent) + public static function getParent(mixed $parent) { return self::query() ->where('forumpost.id', $parent) @@ -98,11 +98,8 @@ class Forumpost extends Model /** * Get forum posts for a parent category. - * - * - * @return \Illuminate\Database\Eloquent\Collection */ - public static function getPosts($parent) + public static function getPosts(mixed $parent): mixed { return self::query() ->where('forumpost.id', $parent) @@ -121,7 +118,7 @@ class Forumpost extends Model * * @return Model|null|static */ - public static function getPost($id) + public static function getPost(mixed $id) { return self::query()->where('id', $id)->first(); } @@ -132,7 +129,7 @@ class Forumpost extends Model * * @param $start */ - public static function getBrowseRange(): LengthAwarePaginator + public static function getBrowseRange(): LengthAwarePaginator // @phpstan-ignore missingType.generics { return self::query() ->where('forumpost.parentid', '=', 0) @@ -146,7 +143,7 @@ class Forumpost extends Model /** * Delete parent category from forum. */ - public static function deleteParent($parent): void + public static function deleteParent(mixed $parent): void { self::query()->where('id', $parent)->orWhere('parentid', $parent)->delete(); } @@ -154,7 +151,7 @@ class Forumpost extends Model /** * Delete post from forum. */ - public static function deletePost($id): void + public static function deletePost(mixed $id): void { $post = self::getPost($id); if ($post) { @@ -169,12 +166,12 @@ class Forumpost extends Model /** * Delete user from forum. */ - public static function deleteUser($id): void + public static function deleteUser(mixed $id): void { self::query()->where('users_id', $id)->delete(); } - public static function getCountForUser($uid): int + public static function getCountForUser(mixed $uid): int { $res = self::query()->where('users_id', $uid)->count('id'); @@ -183,11 +180,8 @@ class Forumpost extends Model /** * Get range of posts for user. - * - * - * @return \Illuminate\Database\Eloquent\Collection */ - public static function getForUserRange($uid, $start, $num) + public static function getForUserRange(mixed $uid, mixed $start, mixed $num): mixed { $range = self::query() ->where('forumpost.users_id', $uid) @@ -204,7 +198,7 @@ class Forumpost extends Model /** * Edit forum post for user. */ - public static function editPost($id, $message, $uid): void + public static function editPost(mixed $id, mixed $message, mixed $uid): void { $post = self::getPost($id); if ($post) { @@ -215,7 +209,7 @@ class Forumpost extends Model /** * Lock forum topic. */ - public static function lockUnlockTopic($id, $lock): void + public static function lockUnlockTopic(mixed $id, mixed $lock): void { self::query()->where('id', $id)->orWhere('parentid', $id)->update(['locked' => $lock]); } diff --git a/app/Models/GamesInfo.php b/app/Models/GamesInfo.php index 8225b1991..6df724d6f 100644 --- a/app/Models/GamesInfo.php +++ b/app/Models/GamesInfo.php @@ -78,6 +78,8 @@ class GamesInfo extends Model /** * Get the genre for this game. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Genre, $this> */ public function genre(): BelongsTo { @@ -86,6 +88,8 @@ class GamesInfo extends Model /** * Get the releases for this game. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> */ public function releases(): HasMany { @@ -97,6 +101,9 @@ class GamesInfo extends Model return 'ix_title_ft'; } + /** + * @return array + */ public function toSearchableArray(): array { return [ diff --git a/app/Models/Genre.php b/app/Models/Genre.php index bba7d2a76..dc841adfc 100644 --- a/app/Models/Genre.php +++ b/app/Models/Genre.php @@ -45,16 +45,25 @@ class Genre extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\MusicInfo, $this> + */ public function music(): HasMany { return $this->hasMany(MusicInfo::class, 'genres_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\ConsoleInfo, $this> + */ public function consoleInfo(): HasMany { return $this->hasMany(ConsoleInfo::class, 'genres_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\GamesInfo, $this> + */ public function gamesInfo(): HasMany { return $this->hasMany(GamesInfo::class, 'genres_id'); @@ -63,7 +72,7 @@ class Genre extends Model /** * Scope to filter disabled genres. */ - public function scopeDisabled(Builder $query): Builder + public function scopeDisabled(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->where('disabled', '=', 1); } @@ -71,7 +80,7 @@ class Genre extends Model /** * Scope to filter enabled genres. */ - public function scopeEnabled(Builder $query): Builder + public function scopeEnabled(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->where('disabled', '=', 0); } @@ -79,7 +88,7 @@ class Genre extends Model /** * Scope to filter by type. */ - public function scopeOfType(Builder $query, string $type): Builder + public function scopeOfType(Builder $query, string $type): Builder // @phpstan-ignore missingType.generics { if (! empty($type)) { return $query->where('type', '=', $type); @@ -91,7 +100,7 @@ class Genre extends Model /** * Get filtered genres based on type and active status. */ - public static function getFiltered(string $type = '', bool $activeOnly = false): Collection + public static function getFiltered(string $type = '', bool $activeOnly = false): Collection // @phpstan-ignore missingType.generics { if ($activeOnly) { return self::getActiveGenres($type); @@ -127,7 +136,7 @@ class Genre extends Model /** * Get genres that are actively used in musicinfo, consoleinfo, or gamesinfo. */ - private static function getActiveGenres(string $type = ''): Collection + private static function getActiveGenres(string $type = ''): Collection // @phpstan-ignore missingType.generics { $typeSql = ! empty($type) ? ' AND g.type = '.intval($type) : ''; diff --git a/app/Models/GrabStat.php b/app/Models/GrabStat.php index 5fee9d420..67000fbec 100644 --- a/app/Models/GrabStat.php +++ b/app/Models/GrabStat.php @@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model; class GrabStat extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $guarded = []; @@ -20,6 +20,9 @@ class GrabStat extends Model } } + /** + * @return array + */ public static function getTopGrabbers(): array { return self::query()->select(['username', 'grabs'])->orderByDesc('grabs')->limit(10)->get()->toArray(); diff --git a/app/Models/Invitation.php b/app/Models/Invitation.php index 5257b5df4..3c1646f4d 100644 --- a/app/Models/Invitation.php +++ b/app/Models/Invitation.php @@ -33,7 +33,7 @@ use Illuminate\Support\Str; * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Invitation unused() * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Invitation used() */ -class Invitation extends Model +class Invitation extends Model // @phpstan-ignore missingType.iterableValue { public const DEFAULT_INVITES = 1; @@ -64,9 +64,9 @@ class Invitation extends Model ]; /** - * @var array + * @var array */ - protected $dates = [ + protected $dates = [ // @phpstan-ignore property.defaultValue 'expires_at', 'used_at', 'created_at', @@ -75,6 +75,8 @@ class Invitation extends Model /** * Get the user who created this invitation + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> */ public function invitedBy(): BelongsTo { @@ -83,6 +85,8 @@ class Invitation extends Model /** * Get the user who used this invitation + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> */ public function usedBy(): BelongsTo { @@ -92,7 +96,7 @@ class Invitation extends Model /** * Scope to get only active invitations */ - public function scopeActive(Builder $query): Builder + public function scopeActive(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->where('is_active', true); } @@ -100,7 +104,7 @@ class Invitation extends Model /** * Scope to get valid (active and not expired) invitations */ - public function scopeValid(Builder $query): Builder + public function scopeValid(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->active() // @phpstan-ignore method.notFound ->where('expires_at', '>', now()) @@ -110,7 +114,7 @@ class Invitation extends Model /** * Scope to get expired invitations */ - public function scopeExpired(Builder $query): Builder + public function scopeExpired(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->where('expires_at', '<=', now()); } @@ -118,7 +122,7 @@ class Invitation extends Model /** * Scope to get unused invitations */ - public function scopeUnused(Builder $query): Builder + public function scopeUnused(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->whereNull('used_at'); } @@ -126,7 +130,7 @@ class Invitation extends Model /** * Scope to get used invitations */ - public function scopeUsed(Builder $query): Builder + public function scopeUsed(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->whereNotNull('used_at'); } @@ -181,6 +185,8 @@ class Invitation extends Model /** * Create a new invitation + * + * @param array $metadata */ public static function createInvitation( string $email, @@ -270,6 +276,8 @@ class Invitation extends Model /** * Get invitation statistics + * + * @return array */ public static function getStats(): array { diff --git a/app/Models/MediaInfo.php b/app/Models/MediaInfo.php index be22aed5b..59179ff0f 100644 --- a/app/Models/MediaInfo.php +++ b/app/Models/MediaInfo.php @@ -8,11 +8,11 @@ use Mhor\MediaInfo\Container\MediaInfoContainer; class MediaInfo extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $guarded = []; - public static function addData($id, MediaInfoContainer $xmlArray): void + public static function addData(mixed $id, MediaInfoContainer $xmlArray): void { $mediainfoArray = $xmlArray->getGeneral(); if (! $mediainfoArray) { diff --git a/app/Models/MusicInfo.php b/app/Models/MusicInfo.php index b80efe656..ab1f51252 100644 --- a/app/Models/MusicInfo.php +++ b/app/Models/MusicInfo.php @@ -70,6 +70,9 @@ class MusicInfo extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Genre, $this> + */ public function genre(): BelongsTo { return $this->belongsTo(Genre::class, 'genres_id'); @@ -80,6 +83,9 @@ class MusicInfo extends Model return 'ix_musicinfo_artist_title_ft'; } + /** + * @return array + */ public function toSearchableArray(): array { return [ diff --git a/app/Models/PasswordSecurity.php b/app/Models/PasswordSecurity.php index 2769ad9ff..d514c821a 100644 --- a/app/Models/PasswordSecurity.php +++ b/app/Models/PasswordSecurity.php @@ -8,13 +8,16 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; class PasswordSecurity extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics /** * @var array */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> + */ public function user(): BelongsTo { return $this->belongsTo(User::class); diff --git a/app/Models/Payment.php b/app/Models/Payment.php index 0e1589c5a..8b913080c 100644 --- a/app/Models/Payment.php +++ b/app/Models/Payment.php @@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model; class Payment extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $guarded = []; } diff --git a/app/Models/Predb.php b/app/Models/Predb.php index 0738f6f35..b25dd0c4b 100644 --- a/app/Models/Predb.php +++ b/app/Models/Predb.php @@ -83,11 +83,17 @@ class Predb extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\PredbHash, $this> + */ public function hash(): HasMany { return $this->hasMany(PredbHash::class, 'predb_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> + */ public function release(): HasMany { return $this->hasMany(Release::class, 'predb_id'); @@ -145,7 +151,7 @@ class Predb extends Model /** * Try to match a single release to a PreDB title when the release is created. * - * @return array|false Array with title/id from PreDB if found, false if not found. + * @return array|false Array with title/id from PreDB if found, false if not found. */ public static function matchPre(string $cleanerName) { @@ -205,11 +211,8 @@ class Predb extends Model /** * Get all PRE's for a release. - * - * - * @return \Illuminate\Database\Eloquent\Collection */ - public static function getForRelease($preID) + public static function getForRelease(mixed $preID): mixed { return self::query()->where('id', $preID)->get(); } @@ -220,7 +223,7 @@ class Predb extends Model * * @return Model|null|static */ - public static function getOne($preID) + public static function getOne(mixed $preID) { return self::query()->where('id', $preID)->first(); } @@ -230,6 +233,9 @@ class Predb extends Model return 'ft_predb_filename'; } + /** + * @return array + */ public function toSearchableArray(): array { return [ diff --git a/app/Models/PredbHash.php b/app/Models/PredbHash.php index 34a4551ae..9afff02fd 100644 --- a/app/Models/PredbHash.php +++ b/app/Models/PredbHash.php @@ -45,6 +45,9 @@ class PredbHash extends Model */ protected $primaryKey = 'hash'; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Predb, $this> + */ public function predb(): BelongsTo { return $this->belongsTo(Predb::class, 'predb_id'); diff --git a/app/Models/Release.php b/app/Models/Release.php index 59ba58ea2..1c5ae1a8c 100644 --- a/app/Models/Release.php +++ b/app/Models/Release.php @@ -46,7 +46,7 @@ use Illuminate\Support\Facades\DB; */ class Release extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $dateFormat = false; @@ -60,71 +60,113 @@ class Release extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\UsenetGroup, $this> + */ public function group(): BelongsTo { return $this->belongsTo(UsenetGroup::class, 'groups_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\UserDownload, $this> + */ public function download(): HasMany { return $this->hasMany(UserDownload::class, 'releases_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\UsersRelease, $this> + */ public function userRelease(): HasMany { return $this->hasMany(UsersRelease::class, 'releases_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\ReleaseFile, $this> + */ public function file(): HasMany { return $this->hasMany(ReleaseFile::class, 'releases_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Category, $this> + */ public function category(): BelongsTo { return $this->belongsTo(Category::class, 'categories_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Predb, $this> + */ public function predb(): BelongsTo { return $this->belongsTo(Predb::class, 'predb_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\DnzbFailure, $this> + */ public function failed(): HasMany { return $this->hasMany(DnzbFailure::class, 'release_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasOne<\App\Models\ReleaseNfo, $this> + */ public function nfo(): HasOne { return $this->hasOne(ReleaseNfo::class, 'releases_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\ReleaseComment, $this> + */ public function comment(): HasMany { return $this->hasMany(ReleaseComment::class, 'releases_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\ReleaseReport, $this> + */ public function reports(): HasMany { return $this->hasMany(ReleaseReport::class, 'releases_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\ReleasesGroups, $this> + */ public function releaseGroup(): HasMany { return $this->hasMany(ReleasesGroups::class, 'releases_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Video, $this> + */ public function video(): BelongsTo { return $this->belongsTo(Video::class, 'videos_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasOne<\App\Models\VideoData, $this> + */ public function videoData(): HasOne { return $this->hasOne(VideoData::class, 'releases_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\TvEpisode, $this> + */ public function episode(): BelongsTo { return $this->belongsTo(TvEpisode::class, 'tv_episodes_id'); @@ -133,7 +175,7 @@ class Release extends Model /** * Insert a single release returning the ID on success or false on failure. * - * @param array $parameters Insert parameters, must be escaped if string. + * @param array $parameters Insert parameters, must be escaped if string. * @return bool|int * * @throws \Exception @@ -174,7 +216,7 @@ class Release extends Model /** * @throws \Exception */ - public static function updateRelease($id, $name, $searchName, $fromName, $categoryId, $parts, $grabs, $size, $postedDate, $addedDate, $videoId, $episodeId, $imDbId, $aniDbId): void + public static function updateRelease(mixed $id, mixed $name, mixed $searchName, mixed $fromName, mixed $categoryId, mixed $parts, mixed $grabs, mixed $size, mixed $postedDate, mixed $addedDate, mixed $videoId, mixed $episodeId, mixed $imDbId, mixed $aniDbId): void { $movieInfoId = null; if (! empty($imDbId)) { @@ -216,25 +258,22 @@ class Release extends Model /** * @return Model|null|static */ - public static function getCatByRelId($id) + public static function getCatByRelId(mixed $id) { return self::whereId($id)->first(['categories_id']); } - public static function removeVideoIdFromReleases($videoId): int + public static function removeVideoIdFromReleases(mixed $videoId): int { return self::whereVideosId($videoId)->update(['videos_id' => 0, 'tv_episodes_id' => 0]); } - public static function removeAnidbIdFromReleases($anidbID): int + public static function removeAnidbIdFromReleases(mixed $anidbID): int { return self::whereAnidbid($anidbID)->update(['anidbid' => -1]); } - /** - * @return \Illuminate\Database\Eloquent\Collection - */ - public static function getTopDownloads() + public static function getTopDownloads(): mixed { $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); $releases = Cache::get(md5('topDownloads')); @@ -256,10 +295,7 @@ class Release extends Model return $releases; } - /** - * @return \Illuminate\Database\Eloquent\Collection - */ - public static function getTopComments() + public static function getTopComments(): mixed { $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); $releases = Cache::get(md5('topComments')); @@ -345,7 +381,7 @@ class Release extends Model return $releases; } - public static function getByGuid($guid) + public static function getByGuid(mixed $guid): mixed { $query = self::with([ 'group:id,name', @@ -380,9 +416,10 @@ class Release extends Model $release->parent_category = $release->category->parent->title ?? null; $release->sub_category = $release->category->title ?? null; $release->category_name = $release->parent_category.' > '.$release->sub_category; - $release->category_ids = $release->category ? ($release->category->parentid.','.$release->category->id) : ''; // @phpstan-ignore property.notFound, property.notFound + $release->category_ids = $release->category ? ($release->category->parentid.','.$release->category->id) : ''; + $release->group_names = $release->releaseGroup->map(function ($relGroup) { - return $relGroup->group ? $relGroup->group->name : null; // @phpstan-ignore property.notFound + return $relGroup->group ? $relGroup->group->name : null; })->implode(','); }); @@ -392,7 +429,7 @@ class Release extends Model /** * Get a range of releases. used in admin manage list. */ - public static function getFailedRange(): LengthAwarePaginator + public static function getFailedRange(): LengthAwarePaginator // @phpstan-ignore missingType.generics { $failedList = self::query() ->select(['name', 'searchname', 'size', 'guid', 'totalpart', 'postdate', 'adddate', 'grabs', 'cp.title as parent_category', 'c.title as sub_category', DB::raw("CONCAT(cp.title, ' > ', c.title) AS category_name")]) @@ -431,7 +468,7 @@ class Release extends Model return false; } - public static function checkGuidForApi($guid): bool + public static function checkGuidForApi(mixed $guid): bool { $check = self::whereGuid($guid)->first(); diff --git a/app/Models/ReleaseComment.php b/app/Models/ReleaseComment.php index 588a403a0..f4a74e3df 100644 --- a/app/Models/ReleaseComment.php +++ b/app/Models/ReleaseComment.php @@ -64,11 +64,17 @@ class ReleaseComment extends Model protected $dateFormat = false; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Release, $this> + */ public function release(): BelongsTo { return $this->belongsTo(Release::class, 'releases_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> + */ public function user(): BelongsTo { return $this->belongsTo(User::class, 'users_id'); @@ -80,12 +86,15 @@ class ReleaseComment extends Model * * @return Model|null|static */ - public static function getCommentById($id) + public static function getCommentById(mixed $id) { return self::query()->where('id', $id)->first(); } - public static function getComments($id): array + /** + * @return array + */ + public static function getComments(mixed $id): array { return self::query()->where('releases_id', $id)->orderByDesc('created_at')->get()->toArray(); } @@ -98,7 +107,7 @@ class ReleaseComment extends Model /** * Delete single comment on the site. */ - public static function deleteComment($id): void + public static function deleteComment(mixed $id): void { $res = self::getCommentById($id); if ($res) { @@ -114,7 +123,7 @@ class ReleaseComment extends Model * * @throws \Exception */ - public static function addComment($id, $gid, $text, $userid, $host): int + public static function addComment(mixed $id, mixed $gid, mixed $text, mixed $userid, mixed $host): int { if (config('nntmux:settings.store_user_ip') === false) { $host = ''; @@ -144,7 +153,7 @@ class ReleaseComment extends Model /** * Get release_comments rows by limit. */ - public static function getCommentsRange(): LengthAwarePaginator + public static function getCommentsRange(): LengthAwarePaginator // @phpstan-ignore missingType.generics { $range = self::query() ->select(['release_comments.*', 'releases.guid']) @@ -157,7 +166,7 @@ class ReleaseComment extends Model /** * Update the denormalised count of comments for a release. */ - public static function updateReleaseCommentCount($gid): void + public static function updateReleaseCommentCount(mixed $gid): void { $commentCount = self::query()->where('gid', '=', 'releases.gid')->where('isvisible', '=', 1)->count('id'); Release::query()->where('gid', $gid)->update(['comments' => $commentCount]); @@ -166,14 +175,14 @@ class ReleaseComment extends Model /** * Get a count of all comments for a user. */ - public static function getCommentCountForUser($uid): int + public static function getCommentCountForUser(mixed $uid): int { $res = self::query()->where(['users_id' => $uid, 'isvisible' => 1])->count('id'); return $res; } - public static function getCommentsForUserRange($uid): LengthAwarePaginator + public static function getCommentsForUserRange(mixed $uid): LengthAwarePaginator // @phpstan-ignore missingType.generics { return self::query() ->select(['release_comments.*', 'r.guid', 'r.searchname', 'u.username']) diff --git a/app/Models/ReleaseFile.php b/app/Models/ReleaseFile.php index 4b39508b2..93de7911b 100644 --- a/app/Models/ReleaseFile.php +++ b/app/Models/ReleaseFile.php @@ -48,26 +48,23 @@ class ReleaseFile extends Model */ protected $primaryKey = 'releases_id'; - public function release(): \Illuminate\Database\Eloquent\Relations\BelongsTo + /** + * @return BelongsTo + */ + public function release(): \Illuminate\Database\Eloquent\Relations\BelongsTo // @phpstan-ignore class.notFound, missingType.generics, return.phpDocType { return $this->belongsTo(Release::class, 'releases_id'); } /** * Get releasefiles row by id. - * - * - * @return \Illuminate\Database\Eloquent\Collection */ - public static function getReleaseFiles($id) + public static function getReleaseFiles(mixed $id): mixed { return self::query()->where('releases_id', $id)->orderBy('name')->get(); } - /** - * @return \Illuminate\Database\Eloquent\Collection - */ - public static function getByGuid($guid) + public static function getByGuid(mixed $guid): mixed { return self::query() ->join('releases', 'releases.id', '=', 'release_files.releases_id') @@ -82,7 +79,7 @@ class ReleaseFile extends Model * * @throws \Exception */ - public static function addReleaseFiles($id, $name, $size, $createdTime, $hasPassword, string $hash = '', string $crc = ''): int + public static function addReleaseFiles(mixed $id, mixed $name, mixed $size, mixed $createdTime, mixed $hasPassword, string $hash = '', string $crc = ''): int { // Check if we already have this data in table $duplicateCheck = self::query()->where('releases_id', $id)->where('name', $name)->first(); diff --git a/app/Models/ReleaseNfo.php b/app/Models/ReleaseNfo.php index 22309db40..4f5478a12 100644 --- a/app/Models/ReleaseNfo.php +++ b/app/Models/ReleaseNfo.php @@ -37,6 +37,9 @@ class ReleaseNfo extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Release, $this> + */ public function release(): BelongsTo { return $this->belongsTo(Release::class, 'releases_id'); @@ -45,7 +48,7 @@ class ReleaseNfo extends Model /** * @return Model|null|static */ - public static function getReleaseNfo($id, bool $getNfoString = true) + public static function getReleaseNfo(mixed $id, bool $getNfoString = true) { $nfo = self::query()->where('releases_id', $id)->whereNotNull('nfo')->select(['releases_id']); if ($getNfoString === true) { diff --git a/app/Models/ReleaseReport.php b/app/Models/ReleaseReport.php index 9da6e49bd..bbec1ce34 100644 --- a/app/Models/ReleaseReport.php +++ b/app/Models/ReleaseReport.php @@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; class ReleaseReport extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics /** * The table associated with the model. @@ -72,6 +72,8 @@ class ReleaseReport extends Model /** * Get the release that was reported. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Release, $this> */ public function release(): BelongsTo { @@ -80,6 +82,8 @@ class ReleaseReport extends Model /** * Get the user who reported the release. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> */ public function user(): BelongsTo { @@ -88,6 +92,8 @@ class ReleaseReport extends Model /** * Get the admin who reviewed the report. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> */ public function reviewer(): BelongsTo { @@ -97,7 +103,7 @@ class ReleaseReport extends Model /** * Get a paginated list of reports with optional filters. */ - public static function getReportsRange( + public static function getReportsRange(// @phpstan-ignore missingType.generics ?string $status = null, int $perPage = 50 ): LengthAwarePaginator { @@ -114,6 +120,8 @@ class ReleaseReport extends Model /** * Get report count by status. + * + * @return array */ public static function getCountByStatus(): array { diff --git a/app/Models/ReleaseStat.php b/app/Models/ReleaseStat.php index b75381d5f..8eb81fc6c 100644 --- a/app/Models/ReleaseStat.php +++ b/app/Models/ReleaseStat.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\DB; class ReleaseStat extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $guarded = []; @@ -45,6 +45,9 @@ class ReleaseStat extends Model } } + /** + * @return array + */ public static function getRecentlyAdded(): array { return self::query()->select(['category', 'count'])->get()->toArray(); diff --git a/app/Models/ReleasesGroups.php b/app/Models/ReleasesGroups.php index bcff99aa6..3fb930870 100644 --- a/app/Models/ReleasesGroups.php +++ b/app/Models/ReleasesGroups.php @@ -67,11 +67,17 @@ class ReleasesGroups extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Release, $this> + */ public function release(): BelongsTo { return $this->belongsTo(Release::class, 'releases_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\UsenetGroup, $this> + */ public function group(): BelongsTo { return $this->belongsTo(UsenetGroup::class, 'groups_id'); diff --git a/app/Models/RoleExpirationEmail.php b/app/Models/RoleExpirationEmail.php index a3a7ce77c..48d1758f2 100644 --- a/app/Models/RoleExpirationEmail.php +++ b/app/Models/RoleExpirationEmail.php @@ -31,7 +31,10 @@ use Illuminate\Database\Eloquent\Model; */ class RoleExpirationEmail extends Model { - public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo + /** + * @return BelongsTo + */ + public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo // @phpstan-ignore class.notFound, missingType.generics, return.phpDocType { return $this->belongsTo(User::class, 'users_id'); } diff --git a/app/Models/RolePromotion.php b/app/Models/RolePromotion.php index 7cf9e4731..42d1d02d5 100644 --- a/app/Models/RolePromotion.php +++ b/app/Models/RolePromotion.php @@ -22,7 +22,7 @@ use Spatie\Permission\Models\Role; * @property \Carbon\Carbon|null $updated_at * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\RolePromotionStat[] $statistics */ -class RolePromotion extends Model +class RolePromotion extends Model // @phpstan-ignore missingType.iterableValue { protected $fillable = [ 'name', @@ -44,6 +44,8 @@ class RolePromotion extends Model /** * Get the statistics for this promotion + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\RolePromotionStat, $this> */ public function statistics(): HasMany { @@ -53,7 +55,7 @@ class RolePromotion extends Model /** * Get the roles this promotion applies to */ - public function getApplicableRolesModels() + public function getApplicableRolesModels(): mixed { if (empty($this->applicable_roles)) { return static::getCustomRoles(); @@ -65,7 +67,7 @@ class RolePromotion extends Model /** * Scope to get only valid (non-expired) promotions */ - public function scopeValid($query) + public function scopeValid(mixed $query): mixed { $now = Carbon::now(); @@ -83,7 +85,7 @@ class RolePromotion extends Model /** * Get custom roles (excluding system roles) */ - public static function getCustomRoles() + public static function getCustomRoles(): mixed { $systemRoles = ['Admin', 'User', 'Moderator', 'Disabled', 'Friend']; @@ -115,7 +117,7 @@ class RolePromotion extends Model /** * Get active promotions for a specific role */ - public static function getActivePromotions(?int $roleId = null) + public static function getActivePromotions(?int $roleId = null): mixed { $query = static::where('is_active', true); @@ -153,6 +155,8 @@ class RolePromotion extends Model /** * Get summary statistics for this promotion + * + * @return array */ public function getSummaryStatistics(): array { @@ -204,6 +208,8 @@ class RolePromotion extends Model /** * Get statistics grouped by role + * + * @return array> */ public function getStatisticsByRole(): array { @@ -229,10 +235,11 @@ class RolePromotion extends Model /** * Get statistics for a specific time period + * + * @return array */ public function getStatisticsForPeriod(Carbon $startDate, Carbon $endDate): array { - /** @phpstan-ignore method.notFound */ $stats = $this->statistics() ->appliedBetween($startDate, $endDate) ->get(); diff --git a/app/Models/RolePromotionStat.php b/app/Models/RolePromotionStat.php index 41469ab83..f0cbe7883 100644 --- a/app/Models/RolePromotionStat.php +++ b/app/Models/RolePromotionStat.php @@ -43,6 +43,8 @@ class RolePromotionStat extends Model /** * Get the user that received the promotion + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> */ public function user(): BelongsTo { @@ -51,6 +53,8 @@ class RolePromotionStat extends Model /** * Get the promotion that was applied + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\RolePromotion, $this> */ public function promotion(): BelongsTo { @@ -60,7 +64,7 @@ class RolePromotionStat extends Model /** * Get the role that was upgraded */ - public function role(): BelongsTo + public function role(): BelongsTo // @phpstan-ignore missingType.generics { return $this->belongsTo(\Spatie\Permission\Models\Role::class); } @@ -68,7 +72,7 @@ class RolePromotionStat extends Model /** * Scope to get stats for a specific promotion */ - public function scopeForPromotion($query, int $promotionId) + public function scopeForPromotion(mixed $query, int $promotionId): mixed { return $query->where('role_promotion_id', $promotionId); } @@ -76,7 +80,7 @@ class RolePromotionStat extends Model /** * Scope to get stats for a specific user */ - public function scopeForUser($query, int $userId) + public function scopeForUser(mixed $query, int $userId): mixed { return $query->where('user_id', $userId); } @@ -84,7 +88,7 @@ class RolePromotionStat extends Model /** * Scope to get stats for a specific role */ - public function scopeForRole($query, int $roleId) + public function scopeForRole(mixed $query, int $roleId): mixed { return $query->where('role_id', $roleId); } @@ -92,13 +96,15 @@ class RolePromotionStat extends Model /** * Scope to get stats within a date range */ - public function scopeAppliedBetween($query, $startDate, $endDate) + public function scopeAppliedBetween(mixed $query, mixed $startDate, mixed $endDate): mixed { return $query->whereBetween('applied_at', [$startDate, $endDate]); } /** * Get statistics summary for a promotion + * + * @return array */ public static function getPromotionSummary(int $promotionId): array { @@ -116,6 +122,8 @@ class RolePromotionStat extends Model /** * Get statistics summary for a user + * + * @return array */ public static function getUserSummary(int $userId): array { diff --git a/app/Models/RoleStat.php b/app/Models/RoleStat.php index 34d646fc3..416519ab8 100644 --- a/app/Models/RoleStat.php +++ b/app/Models/RoleStat.php @@ -8,7 +8,7 @@ use Spatie\Permission\Models\Role; class RoleStat extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $guarded = []; @@ -26,6 +26,9 @@ class RoleStat extends Model } } + /** + * @return array + */ public static function getUsersByRole(): array { return self::query()->select(['role', 'users'])->get()->toArray(); diff --git a/app/Models/RootCategory.php b/app/Models/RootCategory.php index feece883e..914bf31dd 100644 --- a/app/Models/RootCategory.php +++ b/app/Models/RootCategory.php @@ -31,7 +31,10 @@ class RootCategory extends Model { protected $guarded = []; - public function categories(): \Illuminate\Database\Eloquent\Relations\HasMany + /** + * @return HasMany + */ + public function categories(): \Illuminate\Database\Eloquent\Relations\HasMany // @phpstan-ignore class.notFound, missingType.generics, return.phpDocType { return $this->hasMany(Category::class, 'root_categories_id'); } diff --git a/app/Models/Settings.php b/app/Models/Settings.php index ea94cffd6..eb79b7105 100644 --- a/app/Models/Settings.php +++ b/app/Models/Settings.php @@ -90,7 +90,10 @@ class Settings extends Model */ protected $guarded = []; - protected static $settingsCollection; + /** + * @var Collection + */ + protected static ?\Illuminate\Support\Collection $settingsCollection = null; // @phpstan-ignore generics.notGeneric, property.phpDocType, missingType.generics /** * Get the value attribute and convert empty strings to null and numeric strings to numbers. @@ -124,6 +127,8 @@ class Settings extends Model /** * Return a simple key-value array of all settings. * + * @return array + * * @throws \RuntimeException */ public static function toTree(bool $excludeUnsectioned = true): array @@ -139,7 +144,7 @@ class Settings extends Model return $results; } - public static function settingValue($setting): mixed + public static function settingValue(mixed $setting): mixed { $value = self::query()->where('name', $setting)->value('value'); @@ -178,6 +183,9 @@ class Settings extends Model return $value; } + /** + * @param array $data + */ public static function settingsUpdate(array $data = []): void { foreach ($data as $key => $value) { diff --git a/app/Models/SignupStat.php b/app/Models/SignupStat.php index b8d21ce30..8c37f760d 100644 --- a/app/Models/SignupStat.php +++ b/app/Models/SignupStat.php @@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model; class SignupStat extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $guarded = []; @@ -29,6 +29,9 @@ class SignupStat extends Model } } + /** + * @return array + */ public static function getUsersByMonth(): array { return self::query() diff --git a/app/Models/SiteStat.php b/app/Models/SiteStat.php index 385cbfa17..06424a796 100644 --- a/app/Models/SiteStat.php +++ b/app/Models/SiteStat.php @@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model; class SiteStat extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $guarded = []; } diff --git a/app/Models/SteamApp.php b/app/Models/SteamApp.php index e80d11998..a4114c96d 100644 --- a/app/Models/SteamApp.php +++ b/app/Models/SteamApp.php @@ -46,6 +46,9 @@ class SteamApp extends Model return 'ix_name_ft'; } + /** + * @return array + */ public function toSearchableArray(): array { return [ diff --git a/app/Models/SystemMetric.php b/app/Models/SystemMetric.php index 83273e4bd..00fc87455 100644 --- a/app/Models/SystemMetric.php +++ b/app/Models/SystemMetric.php @@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model; class SystemMetric extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $fillable = [ 'metric_type', @@ -23,7 +23,7 @@ class SystemMetric extends Model /** * Scope to get CPU metrics */ - public function scopeCpu($query) + public function scopeCpu(mixed $query): mixed { return $query->where('metric_type', 'cpu'); } @@ -31,7 +31,7 @@ class SystemMetric extends Model /** * Scope to get RAM metrics */ - public function scopeRam($query) + public function scopeRam(mixed $query): mixed { return $query->where('metric_type', 'ram'); } @@ -39,7 +39,7 @@ class SystemMetric extends Model /** * Scope to get metrics for a specific time period */ - public function scopeForPeriod($query, int $hours) + public function scopeForPeriod(mixed $query, int $hours): mixed { return $query->where('recorded_at', '>=', now()->subHours($hours)); } @@ -47,7 +47,7 @@ class SystemMetric extends Model /** * Scope to get metrics for a specific date range */ - public function scopeBetweenDates($query, $startDate, $endDate) + public function scopeBetweenDates(mixed $query, mixed $startDate, mixed $endDate): mixed { return $query->whereBetween('recorded_at', [$startDate, $endDate]); } diff --git a/app/Models/TvEpisode.php b/app/Models/TvEpisode.php index 713e0251c..a1033fd82 100644 --- a/app/Models/TvEpisode.php +++ b/app/Models/TvEpisode.php @@ -49,11 +49,17 @@ class TvEpisode extends Model */ public $timestamps = false; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Video, $this> + */ public function video(): BelongsTo { return $this->belongsTo(Video::class, 'videos_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> + */ public function release(): HasMany { return $this->hasMany(Release::class, 'tv_episodes_id'); diff --git a/app/Models/UsenetGroup.php b/app/Models/UsenetGroup.php index af62dd954..63ac05e13 100644 --- a/app/Models/UsenetGroup.php +++ b/app/Models/UsenetGroup.php @@ -63,12 +63,12 @@ class UsenetGroup extends Model protected $guarded = []; /** - * @var array + * @var array */ - protected static $cbpm = ['collections', 'binaries', 'parts', 'missed_parts']; + protected static $cbpm = ['collections', 'binaries', 'parts', 'missed_parts']; // @phpstan-ignore property.defaultValue /** - * @var array + * @var array */ protected static $cbppTableNames; @@ -87,6 +87,9 @@ class UsenetGroup extends Model parent::__construct(); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> + */ public function release(): HasMany { return $this->hasMany(Release::class, 'groups_id'); @@ -94,6 +97,8 @@ class UsenetGroup extends Model /** * Returns an associative array of groups for list selection. + * + * @return array */ public static function getGroupsForSelect(): array { @@ -115,26 +120,20 @@ class UsenetGroup extends Model * * @return Model|null|static */ - public static function getGroupByID($id) + public static function getGroupByID(mixed $id) { return self::query()->where('id', $id)->first(); } - /** - * @return \Illuminate\Database\Eloquent\Collection - */ - public static function getActive() + public static function getActive(): mixed { return self::query()->where('active', '=', 1)->orderBy('name')->get(); } /** * Get active backfill groups ordered by name ascending. - * - * - * @return array|\Illuminate\Database\Eloquent\Collection */ - public static function getActiveBackfill($order) + public static function getActiveBackfill(mixed $order): mixed { switch ($order) { case '': @@ -149,11 +148,8 @@ class UsenetGroup extends Model /** * Get all active group IDs. - * - * - * @return \Illuminate\Database\Eloquent\Collection */ - public static function getActiveIDs() + public static function getActiveIDs(): mixed { return self::query()->where('active', '=', 1)->orderBy('name')->get(['id']); } @@ -164,7 +160,7 @@ class UsenetGroup extends Model * * @return Model|null|static */ - public static function getByName($grp) + public static function getByName(mixed $grp) { return self::query()->where('name', $grp)->first(); } @@ -217,7 +213,7 @@ class UsenetGroup extends Model return $res === null ? 0 : $res->count('id'); } - public static function getGroupsRange(string $groupname = '', $active = null): LengthAwarePaginator + public static function getGroupsRange(string $groupname = '', mixed $active = null): LengthAwarePaginator // @phpstan-ignore missingType.generics { $groups = self::query()->groupBy('id')->orderBy('name'); @@ -237,7 +233,7 @@ class UsenetGroup extends Model /** * Update an existing group. */ - public static function updateGroup($group): int + public static function updateGroup(mixed $group): int { return self::query()->where('id', $group['id'])->update( [ @@ -276,7 +272,7 @@ class UsenetGroup extends Model * * @return int|mixed */ - public static function addGroup($group) + public static function addGroup(mixed $group) { $checkOld = UsenetGroup::query()->where('name', trim($group['name']))->first(); if (empty($checkOld)) { @@ -377,7 +373,7 @@ class UsenetGroup extends Model * * @throws \Exception */ - public static function purge($id = false) + public static function purge($id = false): void { if ($id === false) { self::resetall(); @@ -411,7 +407,7 @@ class UsenetGroup extends Model /** * Adds new newsgroups based on a regular expression match against USP available. * - * @return array|string + * @return array|string * * @throws \Exception */ diff --git a/app/Models/User.php b/app/Models/User.php index 53d85e712..fafcf62a6 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -118,7 +118,7 @@ use Spatie\Permission\Traits\HasRoles; */ final class User extends Authenticatable { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics use HasRoles; use Notifiable; use SoftDeletes; @@ -197,61 +197,97 @@ final class User extends Authenticatable // ===== Relationships ===== + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\Spatie\Permission\Models\Role, $this> + */ public function role(): BelongsTo { return $this->belongsTo(Role::class, 'roles_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\UserRequest, $this> + */ public function requests(): HasMany { return $this->hasMany(UserRequest::class, 'users_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\UserDownload, $this> + */ public function downloads(): HasMany { return $this->hasMany(UserDownload::class, 'users_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\UsersRelease, $this> + */ public function releases(): HasMany { return $this->hasMany(UsersRelease::class, 'users_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\UserSerie, $this> + */ public function series(): HasMany { return $this->hasMany(UserSerie::class, 'users_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Invitation, $this> + */ public function invitations(): HasMany { return $this->hasMany(Invitation::class, 'invited_by'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\DnzbFailure, $this> + */ public function failedReleases(): HasMany { return $this->hasMany(DnzbFailure::class, 'users_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\ReleaseComment, $this> + */ public function comments(): HasMany { return $this->hasMany(ReleaseComment::class, 'users_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\RolePromotionStat, $this> + */ public function promotionStats(): HasMany { return $this->hasMany(RolePromotionStat::class); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\UserRoleHistory, $this> + */ public function roleHistory(): HasMany { return $this->hasMany(UserRoleHistory::class); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasOne<\App\Models\PasswordSecurity, $this> + */ public function passwordSecurity(): HasOne { return $this->hasOne(PasswordSecurity::class); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\UserExcludedCategory, $this> + */ public function excludedCategories(): HasMany { return $this->hasMany(UserExcludedCategory::class, 'users_id'); @@ -259,32 +295,32 @@ final class User extends Authenticatable // ===== Backward Compatibility Aliases ===== - public function request(): HasMany + public function request(): HasMany // @phpstan-ignore missingType.generics { return $this->requests(); } - public function download(): HasMany + public function download(): HasMany // @phpstan-ignore missingType.generics { return $this->downloads(); } - public function release(): HasMany + public function release(): HasMany // @phpstan-ignore missingType.generics { return $this->releases(); } - public function invitation(): HasMany + public function invitation(): HasMany // @phpstan-ignore missingType.generics { return $this->invitations(); } - public function failedRelease(): HasMany + public function failedRelease(): HasMany // @phpstan-ignore missingType.generics { return $this->failedReleases(); } - public function comment(): HasMany + public function comment(): HasMany // @phpstan-ignore missingType.generics { return $this->comments(); } @@ -294,7 +330,7 @@ final class User extends Authenticatable /** * Scope to get active (non-disabled) users. */ - public function scopeActive(Builder $query): Builder + public function scopeActive(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->where('roles_id', '!=', UserRole::DISABLED->value); } @@ -302,7 +338,7 @@ final class User extends Authenticatable /** * Scope to get verified users. */ - public function scopeVerified(Builder $query): Builder + public function scopeVerified(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->where('verified', true); } @@ -310,7 +346,7 @@ final class User extends Authenticatable /** * Scope to filter users by role. */ - public function scopeWithRole(Builder $query, int|string $role): Builder + public function scopeWithRole(Builder $query, int|string $role): Builder // @phpstan-ignore missingType.generics { if (is_numeric($role)) { return $query->where('roles_id', (int) $role); @@ -322,7 +358,7 @@ final class User extends Authenticatable /** * Scope to get users with roles expiring within specified days. */ - public function scopeExpiringSoon(Builder $query, int $days = 7): Builder + public function scopeExpiringSoon(Builder $query, int $days = 7): Builder // @phpstan-ignore missingType.generics { return $query->whereNotNull('rolechangedate') ->whereBetween('rolechangedate', [now(), now()->addDays($days)]); @@ -331,7 +367,7 @@ final class User extends Authenticatable /** * Scope to get users with expired roles. */ - public function scopeExpired(Builder $query): Builder + public function scopeExpired(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->whereNotNull('rolechangedate') ->where('rolechangedate', '<', now()); @@ -340,7 +376,7 @@ final class User extends Authenticatable /** * Scope to exclude sharing email. */ - public function scopeExcludeSharing(Builder $query): Builder + public function scopeExcludeSharing(Builder $query): Builder // @phpstan-ignore missingType.generics { return $query->where('email', '!=', 'sharing@nZEDb.com'); } @@ -350,7 +386,7 @@ final class User extends Authenticatable /** * Get the user's full name. */ - protected function fullName(): Attribute + protected function fullName(): Attribute // @phpstan-ignore missingType.generics { return Attribute::make( get: fn (): string => trim("{$this->firstname} {$this->lastname}") ?: $this->username, @@ -360,7 +396,7 @@ final class User extends Authenticatable /** * Get the user's timezone or default. */ - protected function effectiveTimezone(): Attribute + protected function effectiveTimezone(): Attribute // @phpstan-ignore missingType.generics { return Attribute::make( get: fn (): string => $this->timezone ?? 'UTC', @@ -370,7 +406,7 @@ final class User extends Authenticatable /** * Check if user has admin privileges. */ - protected function isAdmin(): Attribute + protected function isAdmin(): Attribute // @phpstan-ignore missingType.generics { return Attribute::make( get: fn (): bool => $this->roles_id === UserRole::ADMIN->value, @@ -380,7 +416,7 @@ final class User extends Authenticatable /** * Check if user is disabled. */ - protected function isDisabled(): Attribute + protected function isDisabled(): Attribute // @phpstan-ignore missingType.generics { return Attribute::make( get: fn (): bool => $this->roles_id === UserRole::DISABLED->value, @@ -390,7 +426,7 @@ final class User extends Authenticatable /** * Check if role is expired. */ - protected function isRoleExpired(): Attribute + protected function isRoleExpired(): Attribute // @phpstan-ignore missingType.generics { return Attribute::make( get: fn (): bool => $this->rolechangedate?->isPast() ?? false, @@ -400,7 +436,7 @@ final class User extends Authenticatable /** * Get days until role expires. */ - protected function daysUntilExpiry(): Attribute + protected function daysUntilExpiry(): Attribute // @phpstan-ignore missingType.generics { return Attribute::make( get: fn (): ?int => $this->rolechangedate @@ -413,7 +449,7 @@ final class User extends Authenticatable * Get country code from IP address lookup. * Uses ip-api.com with caching to minimize API calls. */ - protected function countryCode(): Attribute + protected function countryCode(): Attribute // @phpstan-ignore missingType.generics { return Attribute::make( get: fn (): ?string => $this->getCountryFromIp()['countryCode'] ?? null, @@ -424,7 +460,7 @@ final class User extends Authenticatable * Get country name from IP address lookup. * Uses ip-api.com with caching to minimize API calls. */ - protected function countryName(): Attribute + protected function countryName(): Attribute // @phpstan-ignore missingType.generics { return Attribute::make( get: fn (): ?string => $this->getCountryFromIp()['country'] ?? null, @@ -435,7 +471,7 @@ final class User extends Authenticatable * Get country flag emoji from country code. * Converts 2-letter country code to Unicode regional indicator symbols. */ - protected function countryFlag(): Attribute + protected function countryFlag(): Attribute // @phpstan-ignore missingType.generics { return Attribute::make( get: function (): ?string { @@ -1104,7 +1140,7 @@ final class User extends Authenticatable $days = $now->diffInDays($period, true); foreach ($users as $user) { - SendAccountWillExpireEmail::dispatch($user, $days)->onQueue('emails'); + SendAccountWillExpireEmail::dispatch($user, $days)->onQueue('emails'); // @phpstan-ignore argument.type } } } @@ -1587,6 +1623,8 @@ final class User extends Authenticatable /** * Get excluded categories for API request. * + * @return array + * * @throws \Exception */ public static function getCategoryExclusionForApi(Request $request): array diff --git a/app/Models/UserActivityStat.php b/app/Models/UserActivityStat.php index 639afb86c..94ae5f75c 100644 --- a/app/Models/UserActivityStat.php +++ b/app/Models/UserActivityStat.php @@ -9,7 +9,7 @@ use Illuminate\Support\Facades\DB; class UserActivityStat extends Model { - use HasFactory; + use HasFactory; // @phpstan-ignore missingType.generics protected $guarded = []; @@ -47,6 +47,8 @@ class UserActivityStat extends Model /** * Get download stats for the last N days + * + * @return array */ public static function getDownloadsPerDay(int $days = 30): array { @@ -75,6 +77,8 @@ class UserActivityStat extends Model /** * Get API hits stats for the last N days + * + * @return list> */ public static function getApiHitsPerDay(int $days = 30): array { @@ -167,6 +171,8 @@ class UserActivityStat extends Model /** * Get download stats per hour for the last N hours + * + * @return array */ public static function getDownloadsPerHour(int $hours = 168): array { @@ -209,6 +215,8 @@ class UserActivityStat extends Model /** * Get API hits stats per hour for the last N hours + * + * @return list> */ public static function getApiHitsPerHour(int $hours = 168): array { diff --git a/app/Models/UserDownload.php b/app/Models/UserDownload.php index 90a5fd26a..cd0e3aa2d 100644 --- a/app/Models/UserDownload.php +++ b/app/Models/UserDownload.php @@ -43,11 +43,17 @@ class UserDownload extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> + */ public function user(): BelongsTo { return $this->belongsTo(User::class, 'users_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Release, $this> + */ public function release(): BelongsTo { return $this->belongsTo(Release::class, 'releases_id'); @@ -71,7 +77,7 @@ class UserDownload extends Model /** * Get hourly download counts for the last 24 hours. * - * @return array Array of hourly counts indexed by hour + * @return array Array of hourly counts indexed by hour * * @throws \Exception */ @@ -104,7 +110,7 @@ class UserDownload extends Model /** * @return \Illuminate\Database\Eloquent\Collection */ - public static function getDownloadRequestsForUser($userID) + public static function getDownloadRequestsForUser(mixed $userID) { return self::whereUsersId($userID)->with('release')->orderByDesc('timestamp')->get(); } @@ -115,7 +121,7 @@ class UserDownload extends Model * * @return int|\Illuminate\Database\Eloquent\Builder */ - public static function addDownloadRequest($userID, $releaseID) + public static function addDownloadRequest(mixed $userID, mixed $releaseID) // @phpstan-ignore missingType.generics { return self::query() ->insertGetId( @@ -140,7 +146,7 @@ class UserDownload extends Model /** * @throws \Exception */ - public static function delDownloadRequests($userID): void + public static function delDownloadRequests(mixed $userID): void { self::whereUsersId($userID)->delete(); } diff --git a/app/Models/UserExcludedCategory.php b/app/Models/UserExcludedCategory.php index 2d60aa512..ac3ecd805 100644 --- a/app/Models/UserExcludedCategory.php +++ b/app/Models/UserExcludedCategory.php @@ -38,11 +38,17 @@ class UserExcludedCategory extends Model ]; } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> + */ public function user(): BelongsTo { return $this->belongsTo(User::class, 'users_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Category, $this> + */ public function category(): BelongsTo { return $this->belongsTo(Category::class, 'categories_id'); diff --git a/app/Models/UserMovie.php b/app/Models/UserMovie.php index e5903589a..399035410 100644 --- a/app/Models/UserMovie.php +++ b/app/Models/UserMovie.php @@ -37,9 +37,10 @@ class UserMovie extends Model protected $dateFormat = false; /** + * @param array $catID * @return int|\Illuminate\Database\Eloquent\Builder */ - public static function addMovie($uid, $imdbid, array $catID = []) + public static function addMovie(mixed $uid, mixed $imdbid, array $catID = []) // @phpstan-ignore missingType.generics { return self::query() ->insertGetId( @@ -52,7 +53,10 @@ class UserMovie extends Model ); } - public static function getMovies($uid): array + /** + * @return array + */ + public static function getMovies(mixed $uid): array { return self::query() ->where('users_id', $uid) @@ -65,12 +69,15 @@ class UserMovie extends Model /** * @return mixed */ - public static function delMovie($uid, $imdbid) + public static function delMovie(mixed $uid, mixed $imdbid) { return self::query()->where(['users_id' => $uid, 'imdbid' => $imdbid])->delete(); } - public static function getMovie($uid, $imdbid): array + /** + * @return array + */ + public static function getMovie(mixed $uid, mixed $imdbid): array { $result = self::query() ->where(['user_movies.users_id' => $uid, 'user_movies.imdbid' => $imdbid]) @@ -80,12 +87,15 @@ class UserMovie extends Model return $result ? $result->toArray() : []; } - public static function delMovieForUser($uid) + public static function delMovieForUser(mixed $uid): void { self::query()->where('users_id', $uid)->delete(); } - public static function updateMovie($uid, $imdbid, array $catID = []) + /** + * @param array $catID + */ + public static function updateMovie(mixed $uid, mixed $imdbid, array $catID = []): void { self::query() ->where(['users_id' => $uid, 'imdbid' => $imdbid]) diff --git a/app/Models/UserRequest.php b/app/Models/UserRequest.php index 30d82434d..4e05c32ff 100644 --- a/app/Models/UserRequest.php +++ b/app/Models/UserRequest.php @@ -46,6 +46,9 @@ class UserRequest extends Model */ protected $fillable = ['id', 'users_id', 'request', 'hosthash', 'timestamp']; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> + */ public function user(): BelongsTo { return $this->belongsTo(User::class, 'users_id'); @@ -54,7 +57,7 @@ class UserRequest extends Model /** * @throws \Throwable */ - public static function delApiRequests($userID): void + public static function delApiRequests(mixed $userID): void { DB::transaction(function () use ($userID) { self::query()->where('users_id', $userID)->delete(); @@ -80,7 +83,7 @@ class UserRequest extends Model /** * Get hourly API request counts for the last 24 hours. * - * @return array Array of hourly counts indexed by hour + * @return array Array of hourly counts indexed by hour * * @throws \Exception */ diff --git a/app/Models/UserRoleHistory.php b/app/Models/UserRoleHistory.php index f56092163..d0aa3e2a0 100644 --- a/app/Models/UserRoleHistory.php +++ b/app/Models/UserRoleHistory.php @@ -49,6 +49,8 @@ class UserRoleHistory extends Model /** * Get the user this history belongs to + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> */ public function user(): BelongsTo { @@ -57,6 +59,8 @@ class UserRoleHistory extends Model /** * Get the admin who made this change + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> */ public function changedByUser(): BelongsTo { @@ -66,7 +70,7 @@ class UserRoleHistory extends Model /** * Get the old role */ - public function oldRole(): BelongsTo + public function oldRole(): BelongsTo // @phpstan-ignore missingType.generics { return $this->belongsTo(\Spatie\Permission\Models\Role::class, 'old_role_id'); } @@ -74,7 +78,7 @@ class UserRoleHistory extends Model /** * Get the new role */ - public function newRole(): BelongsTo + public function newRole(): BelongsTo // @phpstan-ignore missingType.generics { return $this->belongsTo(\Spatie\Permission\Models\Role::class, 'new_role_id'); } @@ -109,7 +113,7 @@ class UserRoleHistory extends Model /** * Get role history for a user */ - public static function getUserHistory(int $userId) + public static function getUserHistory(int $userId): mixed { return static::where('user_id', $userId) ->orderBy('effective_date', 'desc') @@ -119,7 +123,7 @@ class UserRoleHistory extends Model /** * Get stacked role changes for a user */ - public static function getUserStackedChanges(int $userId) + public static function getUserStackedChanges(int $userId): mixed { return static::where('user_id', $userId) ->where('is_stacked', true) diff --git a/app/Models/UserSerie.php b/app/Models/UserSerie.php index 906fee983..164e39f49 100644 --- a/app/Models/UserSerie.php +++ b/app/Models/UserSerie.php @@ -38,6 +38,9 @@ class UserSerie extends Model protected $dateFormat = false; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> + */ public function user(): BelongsTo { return $this->belongsTo(User::class, 'users_id'); @@ -47,9 +50,10 @@ class UserSerie extends Model * When a user wants to add a show to "my shows" insert it into the user series table. * * + * @param array $catID * @return int|\Illuminate\Database\Eloquent\Builder */ - public static function addShow($userId, $videoId, array $catID = []) + public static function addShow(mixed $userId, mixed $videoId, array $catID = []) // @phpstan-ignore missingType.generics { return self::query() ->insertGetId( @@ -65,11 +69,8 @@ class UserSerie extends Model /** * Get all the user's "my shows". - * - * - * @return \Illuminate\Database\Eloquent\Collection */ - public static function getShows($userId) + public static function getShows(mixed $userId): mixed { return self::query() ->where('user_series.users_id', $userId) @@ -82,7 +83,7 @@ class UserSerie extends Model /** * Delete a tv show from the user's "my shows". */ - public static function delShow($users_id, $videos_id): void + public static function delShow(mixed $users_id, mixed $videos_id): void { self::query()->where(compact('users_id', 'videos_id'))->delete(); } @@ -93,7 +94,7 @@ class UserSerie extends Model * * @return Model|null|static */ - public static function getShow($userId, $videoId) + public static function getShow(mixed $userId, mixed $videoId) { return self::query() ->where(['user_series.users_id' => $userId, 'user_series.videos_id' => $videoId]) @@ -104,7 +105,7 @@ class UserSerie extends Model /** * Delete all shows from the user's "my shows". */ - public static function delShowForUser($userId): void + public static function delShowForUser(mixed $userId): void { self::query()->where('users_id', $userId)->delete(); } @@ -112,7 +113,7 @@ class UserSerie extends Model /** * Delete TV shows from all user's "my shows" that match a TV id. */ - public static function delShowForSeries($videoId): void + public static function delShowForSeries(mixed $videoId): void { self::query()->where('videos_id', $videoId)->delete(); } @@ -120,9 +121,9 @@ class UserSerie extends Model /** * Update a TV show category ID for a user's "my show" TV show. * - * @param array $catID List of category ID's. + * @param array $catID List of category ID's. */ - public static function updateShow($users_id, $videos_id, array $catID = []): void + public static function updateShow(mixed $users_id, mixed $videos_id, array $catID = []): void { self::query()->where(compact('users_id', 'videos_id'))->update(['categories' => ! empty($catID) ? implode('|', $catID) : 'NULL']); } diff --git a/app/Models/UsersRelease.php b/app/Models/UsersRelease.php index 794f022bb..50ba46632 100644 --- a/app/Models/UsersRelease.php +++ b/app/Models/UsersRelease.php @@ -37,17 +37,23 @@ class UsersRelease extends Model */ protected $guarded = ['id']; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User, $this> + */ public function user(): BelongsTo { return $this->belongsTo(User::class, 'users_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Release, $this> + */ public function release(): BelongsTo { return $this->belongsTo(Release::class, 'releases_id'); } - public static function delCartForUser($uid): void + public static function delCartForUser(mixed $uid): void { self::query()->where('users_id', $uid)->delete(); } @@ -55,7 +61,7 @@ class UsersRelease extends Model /** * @return int|\Illuminate\Database\Eloquent\Builder */ - public static function addCart($uid, $releaseid) + public static function addCart(mixed $uid, mixed $releaseid) // @phpstan-ignore missingType.generics { return self::query()->insertGetId( [ @@ -67,10 +73,7 @@ class UsersRelease extends Model ); } - /** - * @return \Illuminate\Database\Eloquent\Collection - */ - public static function getCart($uid) + public static function getCart(mixed $uid): mixed { return self::query() ->with('release') @@ -82,7 +85,7 @@ class UsersRelease extends Model /** * @return bool|mixed */ - public static function delCartByGuid($guids, $userID) + public static function delCartByGuid(mixed $guids, mixed $userID) { if (! \is_array($guids)) { return false; @@ -99,7 +102,7 @@ class UsersRelease extends Model return self::query()->whereIn('releases_id', $del)->where('users_id', $userID)->delete() === 1; } - public static function delCartByUserAndRelease($guid, $uid): void + public static function delCartByUserAndRelease(mixed $guid, mixed $uid): void { $rel = Release::query()->where('guid', $guid)->first(['id']); if ($rel) { @@ -107,7 +110,7 @@ class UsersRelease extends Model } } - public static function delCartForRelease($rid): void + public static function delCartForRelease(mixed $rid): void { self::query()->where('releases_id', $rid)->delete(); } diff --git a/app/Models/Video.php b/app/Models/Video.php index e3d71e331..d63037b9a 100644 --- a/app/Models/Video.php +++ b/app/Models/Video.php @@ -61,21 +61,33 @@ class Video extends Model */ public $timestamps = false; + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\VideoAlias, $this> + */ public function alias(): HasMany { return $this->hasMany(VideoAlias::class, 'videos_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> + */ public function release(): HasMany { return $this->hasMany(Release::class, 'videos_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\TvEpisode, $this> + */ public function episode(): HasMany { return $this->hasMany(TvEpisode::class, 'videos_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasOne<\App\Models\TvInfo, $this> + */ public function tvInfo(): HasOne { return $this->hasOne(TvInfo::class, 'videos_id'); @@ -87,7 +99,7 @@ class Video extends Model * * @return Model|null|static */ - public static function getByVideoID($id) + public static function getByVideoID(mixed $id) { return self::query() ->select(['videos.*', 'tv_info.summary', 'tv_info.publisher', 'tv_info.image']) @@ -99,7 +111,7 @@ class Video extends Model /** * Retrieves a range of all shows for the show-edit admin list. */ - public static function getRange(string $showname = ''): LengthAwarePaginator + public static function getRange(string $showname = ''): LengthAwarePaginator // @phpstan-ignore missingType.generics { $sql = self::query() ->select(['videos.*', 'tv_info.summary', 'tv_info.publisher', 'tv_info.image']) @@ -128,8 +140,10 @@ class Video extends Model /** * Retrieves and returns a list of shows with eligible releases. + * + * @return array */ - public static function getSeriesList($uid, string $letter = '', string $showname = ''): array + public static function getSeriesList(mixed $uid, string $letter = '', string $showname = ''): array { $params = [ 'uid' => $uid, diff --git a/app/Models/VideoAlias.php b/app/Models/VideoAlias.php index f9a5d2d35..3daf2e0b1 100644 --- a/app/Models/VideoAlias.php +++ b/app/Models/VideoAlias.php @@ -35,6 +35,9 @@ class VideoAlias extends Model */ protected $guarded = []; + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Video, $this> + */ public function video(): BelongsTo { return $this->belongsTo(Video::class, 'videos_id'); diff --git a/app/Models/XxxInfo.php b/app/Models/XxxInfo.php index 4bec8a594..29f506350 100644 --- a/app/Models/XxxInfo.php +++ b/app/Models/XxxInfo.php @@ -64,6 +64,8 @@ class XxxInfo extends Model /** * Get releases associated with this XXX info. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> */ public function releases(): HasMany { @@ -121,6 +123,8 @@ class XxxInfo extends Model /** * Get all genres for search-filter.tpl. + * + * @return array */ public static function getAllGenres(bool $activeOnly = false): array { @@ -144,6 +148,9 @@ class XxxInfo extends Model /** * Get a specific genre. + * + * @return list + * @return array */ public static function getGenres(bool $activeOnly = false, ?int $gid = null): mixed { @@ -165,7 +172,7 @@ class XxxInfo extends Model /** * Get Genre id's of the title. * - * @param array|string $arr - Array or String + * @param array|string $arr - Array or String * @return string - If array .. 1,2,3,4 if string .. 1 */ public static function getGenreID(array|string $arr): string diff --git a/app/Policies/CategoryPolicy.php b/app/Policies/CategoryPolicy.php index 5d2354395..39e43727f 100644 --- a/app/Policies/CategoryPolicy.php +++ b/app/Policies/CategoryPolicy.php @@ -15,52 +15,52 @@ class CategoryPolicy extends \TeamTeaTime\Forum\Policies\CategoryPolicy // } - public function manageThreads($user, Category $category): bool + public function manageThreads(mixed $user, Category $category): bool { return $user->hasRole('Admin'); } - public function deleteThreads($user, Category $category): bool + public function deleteThreads(mixed $user, Category $category): bool { return $user->hasRole('Admin'); } - public function restoreThreads($user, Category $category): bool + public function restoreThreads(mixed $user, Category $category): bool { return $user->hasRole('Admin'); } - public function enableThreads($user, Category $category): bool + public function enableThreads(mixed $user, Category $category): bool { return $user->hasRole('Admin'); } - public function moveThreadsFrom($user, Category $category): bool + public function moveThreadsFrom(mixed $user, Category $category): bool { return $user->hasRole('Admin'); } - public function moveThreadsTo($user, Category $category): bool + public function moveThreadsTo(mixed $user, Category $category): bool { return $user->hasRole('Admin'); } - public function lockThreads($user, Category $category): bool + public function lockThreads(mixed $user, Category $category): bool { return $user->hasRole('Admin'); } - public function pinThreads($user, Category $category): bool + public function pinThreads(mixed $user, Category $category): bool { return $user->hasRole('Admin'); } - public function view($user, Category $category): bool + public function view(mixed $user, Category $category): bool { return $user->hasAnyRole(['Admin', 'Moderator']); } - public function delete($user, Category $category): bool + public function delete(mixed $user, Category $category): bool { return $user->hasRole('Admin'); } diff --git a/app/Policies/ForumPolicy.php b/app/Policies/ForumPolicy.php index 9fbd5d921..efe79cbbf 100644 --- a/app/Policies/ForumPolicy.php +++ b/app/Policies/ForumPolicy.php @@ -12,72 +12,72 @@ class ForumPolicy extends \TeamTeaTime\Forum\Policies\ForumPolicy // } - public function createCategories($user): bool + public function createCategories(mixed $user): bool { return $user->hasRole('Admin'); } - public function manageCategories($user): bool + public function manageCategories(mixed $user): bool { return $user->hasRole('Admin'); } - public function moveCategories($user): bool + public function moveCategories(mixed $user): bool { return $user->hasRole('Admin'); } - public function renameCategories($user): bool + public function renameCategories(mixed $user): bool { return $user->hasRole('Admin'); } - public function viewTrashedThreads($user): bool + public function viewTrashedThreads(mixed $user): bool { return $user->hasRole('Admin'); } - public function viewTrashedPosts($user): bool + public function viewTrashedPosts(mixed $user): bool { return $user->hasRole('Admin'); } - public function deleteCategories($user): bool + public function deleteCategories(mixed $user): bool { return $user->hasRole('Admin'); } - public function deletePosts($user): bool + public function deletePosts(mixed $user): bool { return $user->hasRole('Admin'); } - public function deleteThreads($user): bool + public function deleteThreads(mixed $user): bool { return $user->hasRole('Admin'); } - public function restorePosts($user): bool + public function restorePosts(mixed $user): bool { return $user->hasRole('Admin'); } - public function restoreThreads($user): bool + public function restoreThreads(mixed $user): bool { return $user->hasRole('Admin'); } - public function purgePosts($user): bool + public function purgePosts(mixed $user): bool { return $user->hasRole('Admin'); } - public function purgeThreads($user): bool + public function purgeThreads(mixed $user): bool { return $user->hasRole('Admin'); } - public function deleteThrashedPosts($user): bool + public function deleteThrashedPosts(mixed $user): bool { return $user->hasRole('Admin'); } diff --git a/app/Policies/PostPolicy.php b/app/Policies/PostPolicy.php index 006047d78..69dc139db 100644 --- a/app/Policies/PostPolicy.php +++ b/app/Policies/PostPolicy.php @@ -6,19 +6,19 @@ use TeamTeaTime\Forum\Models\Post; class PostPolicy extends \TeamTeaTime\Forum\Policies\PostPolicy { - public function edit($user, Post $post): bool + public function edit(mixed $user, Post $post): bool { // Admins can edit any post; users can edit their own return $user->hasRole('Admin') || ($user->getKey() === $post->author_id); // @phpstan-ignore property.notFound } - public function delete($user, Post $post): bool + public function delete(mixed $user, Post $post): bool { // Admins can delete any post; users can delete their own return $user->hasRole('Admin') || ($user->getKey() === $post->author_id); // @phpstan-ignore property.notFound } - public function restore($user, Post $post): bool + public function restore(mixed $user, Post $post): bool { // Admins can restore any post; users can restore their own return $user->hasRole('Admin') || ($user->getKey() === $post->author_id); // @phpstan-ignore property.notFound diff --git a/app/Policies/ThreadPolicy.php b/app/Policies/ThreadPolicy.php index f0c6c1943..338133aed 100644 --- a/app/Policies/ThreadPolicy.php +++ b/app/Policies/ThreadPolicy.php @@ -6,49 +6,49 @@ use TeamTeaTime\Forum\Models\Thread; class ThreadPolicy extends \TeamTeaTime\Forum\Policies\ThreadPolicy { - public function view($user, Thread $thread): bool + public function view(mixed $user, Thread $thread): bool { // Everyone (including Admin) can view by default return parent::view($user, $thread); } - public function rename($user, Thread $thread): bool + public function rename(mixed $user, Thread $thread): bool { // Admins can rename any thread; users can rename their own return $user->hasRole('Admin') || ($user->getKey() === $thread->author_id); // @phpstan-ignore property.notFound } - public function reply($user, Thread $thread): bool + public function reply(mixed $user, Thread $thread): bool { // Admins can reply even if locked; otherwise respect lock state return $user->hasRole('Admin') || (! $thread->locked); } - public function replyWithoutApproval($user, Thread $thread): bool + public function replyWithoutApproval(mixed $user, Thread $thread): bool { // Admins can reply to unapproved threads; otherwise only thread author return $user->hasRole('Admin') || ($user->getKey() === $thread->author_id); // @phpstan-ignore property.notFound } - public function delete($user, Thread $thread): bool + public function delete(mixed $user, Thread $thread): bool { // Admins can delete any thread; users can delete their own return $user->hasRole('Admin') || ($user->getKey() === $thread->author_id); // @phpstan-ignore property.notFound } - public function restore($user, Thread $thread): bool + public function restore(mixed $user, Thread $thread): bool { // Admins can restore any thread; users can restore their own return $user->hasRole('Admin') || ($user->getKey() === $thread->author_id); // @phpstan-ignore property.notFound } - public function deletePosts($user, Thread $thread): bool + public function deletePosts(mixed $user, Thread $thread): bool { // Admins can delete posts in any thread; otherwise fall back to default (true) return $user->hasRole('Admin') || parent::deletePosts($user, $thread); } - public function restorePosts($user, Thread $thread): bool + public function restorePosts(mixed $user, Thread $thread): bool { // Admins can restore posts in any thread; otherwise fall back to default (true) return $user->hasRole('Admin') || parent::restorePosts($user, $thread); diff --git a/app/Services/AdditionalProcessing/AdditionalProcessingOrchestrator.php b/app/Services/AdditionalProcessing/AdditionalProcessingOrchestrator.php index b255b4ae5..da04d04e7 100644 --- a/app/Services/AdditionalProcessing/AdditionalProcessingOrchestrator.php +++ b/app/Services/AdditionalProcessing/AdditionalProcessingOrchestrator.php @@ -24,12 +24,18 @@ class AdditionalProcessingOrchestrator { public const int MAX_COMPRESSED_FILES_TO_CHECK = 10; + /** + * @var Collection + */ private Collection $releases; private int $totalReleases = 0; private string $mainTmpPath = ''; + /** + * @var array + */ private array $triedCompressedMids = []; public function __construct( @@ -462,7 +468,7 @@ class AdditionalProcessingOrchestrator // Download $result = $this->downloadService->downloadCompressedFile( - $messageIDs, + $messageIDs, // @phpstan-ignore argument.type $context->releaseGroupName, $context->release->id, $title @@ -578,6 +584,8 @@ class AdditionalProcessingOrchestrator /** * Find and process JPG/PNG files from archive file list to create sample/preview. + * + * @param array $files */ private function processJpgFromArchiveFileList( string $compressedData, @@ -691,7 +699,7 @@ class AdditionalProcessingOrchestrator // Download the compressed file $result = $this->downloadService->downloadCompressedFile( - $messageIDs, + $messageIDs, // @phpstan-ignore argument.type $context->releaseGroupName, $context->release->id, $title diff --git a/app/Services/AdditionalProcessing/ArchiveExtractionService.php b/app/Services/AdditionalProcessing/ArchiveExtractionService.php index 5a015eae7..475db5e95 100644 --- a/app/Services/AdditionalProcessing/ArchiveExtractionService.php +++ b/app/Services/AdditionalProcessing/ArchiveExtractionService.php @@ -35,7 +35,7 @@ class ArchiveExtractionService /** * Process compressed data and extract file information. * - * @return array{success: bool, files: array, hasPassword: bool, passwordStatus: int, archiveMarker?: string, dataSummary?: array, standaloneVideoType?: string, standaloneVideoData?: string} + * @return array */ public function processCompressedData( string $compressedData, @@ -65,7 +65,7 @@ class ArchiveExtractionService if ($this->config->sevenZipPath) { $extractResult = $this->extractViaSevenZip($compressedData, $archiveType, $tmpPath); - if ($extractResult['success']) { + if ($extractResult['success']) { // @phpstan-ignore offsetAccess.notFound return $extractResult; } } @@ -200,6 +200,8 @@ class ArchiveExtractionService /** * Process a 7z archive using external binary and internal header parsing. + * + * @return array */ private function processSevenZipArchive( string $compressedData, @@ -267,6 +269,8 @@ class ArchiveExtractionService /** * List entries of a 7z archive using external 7z binary. + * + * @return array */ public function listSevenZipEntries(string $compressedData, string $tmpPath): array { @@ -284,7 +288,7 @@ class ArchiveExtractionService $exitCode = 0; $stdout = null; $stderr = null; - $ok = $this->execCommand($cmd, $exitCode, $stdout, $stderr); + $ok = $this->execCommand($cmd, $exitCode, $stdout, $stderr); // @phpstan-ignore argument.type if (! $ok || $exitCode !== 0 || empty($stdout)) { // Try plain listing fallback @@ -308,6 +312,8 @@ class ArchiveExtractionService /** * Plain 7z listing fallback. + * + * @return list> */ private function listSevenZipPlain(string $tmpFile): array { @@ -315,7 +321,7 @@ class ArchiveExtractionService $exitCode = 0; $stdout = null; $stderr = null; - $ok = $this->execCommand($cmd, $exitCode, $stdout, $stderr); + $ok = $this->execCommand($cmd, $exitCode, $stdout, $stderr); // @phpstan-ignore argument.type if (! $ok || $exitCode !== 0 || empty($stdout)) { return []; @@ -352,6 +358,8 @@ class ArchiveExtractionService /** * Parse structured 7z output. + * + * @return list> */ private function parseSevenZipStructuredOutput(string $output): array { @@ -400,6 +408,9 @@ class ArchiveExtractionService /** * Filter 7z files using extension whitelist. + * + * @param array $files + * @return list */ private function filterSevenZipFiles(array $files): array { @@ -446,6 +457,8 @@ class ArchiveExtractionService /** * Scan for filenames in 7z raw data. + * + * @return list, pass: 0, crc32: '', source: '7z-list'}> */ private function scanSevenZipFilenames(string $data): array { @@ -482,6 +495,8 @@ class ArchiveExtractionService /** * Extract using 7zip binary. + * + * @return list */ public function extractViaSevenZip(string $compressedData, string $type, string $tmpPath): array { @@ -514,7 +529,7 @@ class ArchiveExtractionService $exitCode = 0; $stdout = null; $stderr = null; - $this->execCommand($cmd, $exitCode, $stdout, $stderr); + $this->execCommand($cmd, $exitCode, $stdout, $stderr); // @phpstan-ignore argument.type $files = []; if (File::isDirectory($extractDir)) { @@ -533,9 +548,9 @@ class ArchiveExtractionService File::delete($fileName); if (! empty($files)) { - return [ + return [ // @phpstan-ignore return.type 'success' => true, - 'files' => $this->filterExtractedFiles($files), + 'files' => $this->filterExtractedFiles($files), // @phpstan-ignore argument.type 'hasPassword' => false, 'passwordStatus' => ReleaseBrowseService::PASSWD_NONE, 'archiveMarker' => $marker, @@ -552,6 +567,9 @@ class ArchiveExtractionService /** * Filter extracted files by allowed extensions. + * + * @param array $files + * @return array{success: false, files: array{}, hasPassword: false, passwordStatus: 0} */ private function filterExtractedFiles(array $files): array { @@ -580,6 +598,8 @@ class ArchiveExtractionService /** * Get list of allowed file extensions. + * + * @return list */ private function getAllowedExtensions(): array { @@ -639,8 +659,8 @@ class ArchiveExtractionService /** * Sort files to prioritize NFO files for processing. * - * @param array $files Array of file info arrays. - * @return array Sorted array with NFO files first. + * @param array $files Array of file info arrays. + * @return array Sorted array with NFO files first. */ public function sortFilesWithNfoPriority(array $files): array { @@ -663,6 +683,8 @@ class ArchiveExtractionService /** * Prepare extraction directories. + * + * @return list */ private function prepareExtractionDirectories(string $tmpPath): void { @@ -690,6 +712,8 @@ class ArchiveExtractionService /** * Extract archive based on type. + * + * @param array $dataSummary */ private function extractArchive(string $compressedData, array $dataSummary, string $tmpPath): string { @@ -852,7 +876,7 @@ class ArchiveExtractionService $exitCode = 0; $stdout = null; $stderr = null; - $this->execCommand($cmd, $exitCode, $stdout, $stderr); + $this->execCommand($cmd, $exitCode, $stdout, $stderr); // @phpstan-ignore argument.type File::delete($archiveFile); @@ -991,6 +1015,8 @@ class ArchiveExtractionService * @param-out int $exitCode * @param-out string|null $stdout * @param-out string|null $stderr + * + * @param array $cmd */ private function execCommand(array $cmd, ?int &$exitCode, ?string &$stdout, ?string &$stderr): bool { @@ -999,7 +1025,7 @@ class ArchiveExtractionService 2 => ['pipe', 'w'], ]; - $process = @proc_open($cmd, $descriptorSpec, $pipes, null, null, ['bypass_shell' => true]); + $process = @proc_open($cmd, $descriptorSpec, $pipes, null, null, ['bypass_shell' => true]); // @phpstan-ignore argument.type if (! is_resource($process)) { $exitCode = -1; diff --git a/app/Services/AdditionalProcessing/DTO/ReleaseProcessingContext.php b/app/Services/AdditionalProcessing/DTO/ReleaseProcessingContext.php index f13cc4be4..3e28fce25 100644 --- a/app/Services/AdditionalProcessing/DTO/ReleaseProcessingContext.php +++ b/app/Services/AdditionalProcessing/DTO/ReleaseProcessingContext.php @@ -44,17 +44,35 @@ class ReleaseProcessingContext // NZB state public bool $nzbHasCompressedFile = false; + /** + * @var array + */ public array $nzbContents = []; // Message IDs for downloading + /** + * @var array + */ public array $sampleMessageIDs = []; + /** + * @var array + */ public array $jpgMessageIDs = []; + /** + * @var array + */ public string|array $mediaInfoMessageIDs = []; + /** + * @var array + */ public string|array $audioInfoMessageIDs = []; + /** + * @var array + */ public array $rarFileMessageIDs = []; public string $audioInfoExtension = ''; diff --git a/app/Services/AdditionalProcessing/MediaExtractionService.php b/app/Services/AdditionalProcessing/MediaExtractionService.php index 09b3782d6..5b464b2f8 100644 --- a/app/Services/AdditionalProcessing/MediaExtractionService.php +++ b/app/Services/AdditionalProcessing/MediaExtractionService.php @@ -394,6 +394,8 @@ class MediaExtractionService /** * Process a video file for sample, video clip, and media info. + * + * @return array */ public function processVideoFile( string $fileLocation, diff --git a/app/Services/AdditionalProcessing/NzbContentParser.php b/app/Services/AdditionalProcessing/NzbContentParser.php index 384754833..92b9d7905 100644 --- a/app/Services/AdditionalProcessing/NzbContentParser.php +++ b/app/Services/AdditionalProcessing/NzbContentParser.php @@ -24,7 +24,7 @@ class NzbContentParser * Parse an NZB file and return its contents as an array of files. * * @param string $guid The release GUID to find the NZB for - * @return array{contents: array, error: string|null} + * @return array{contents: array, error: string|null} */ public function parseNzb(string $guid): array { @@ -144,15 +144,16 @@ class NzbContentParser /** * Process NZB contents to extract message IDs for different file types. * - * @return array{ - * hasCompressedFile: bool, - * sampleMessageIDs: array, - * jpgMessageIDs: array, - * mediaInfoMessageID: string, - * audioInfoMessageID: string, - * audioInfoExtension: string, - * bookFileCount: int - * } + * @param array $nzbContents + * @return array + * hasCompressedFile: bool, + * sampleMessageIDs: array, + * jpgMessageIDs: array, + * mediaInfoMessageID: string, + * audioInfoMessageID: string, + * audioInfoExtension: string, + * bookFileCount: int + * } */ public function extractMessageIDs( array $nzbContents, @@ -241,6 +242,9 @@ class NzbContentParser /** * Extract segment message IDs up to a limit. + * + * @param array $segments + * @return array */ private function extractSegments(array $segments, int $limit): array { @@ -250,7 +254,7 @@ class NzbContentParser if ($i > $segCount) { break; } - $ids[] = (string) $segments[$i]; + $ids[] = (string) $segments[$i]; // @phpstan-ignore offsetAccess.notFound } return $ids; @@ -258,6 +262,8 @@ class NzbContentParser /** * Get the NZB path for a GUID. + * + * @return list */ public function getNzbPath(string $guid): string|false { diff --git a/app/Services/AdditionalProcessing/ReleaseFileManager.php b/app/Services/AdditionalProcessing/ReleaseFileManager.php index 4cdd6d152..ada669dbd 100644 --- a/app/Services/AdditionalProcessing/ReleaseFileManager.php +++ b/app/Services/AdditionalProcessing/ReleaseFileManager.php @@ -37,6 +37,8 @@ class ReleaseFileManager /** * Add file information to the database. * + * @param array $file + * * @throws \Exception */ public function addFileInfo( @@ -448,6 +450,8 @@ class ReleaseFileManager /** * Handle release name extraction from RAR file content. + * + * @param array $dataSummary */ public function processReleaseNameFromRar( array $dataSummary, diff --git a/app/Services/AdditionalProcessing/UsenetDownloadService.php b/app/Services/AdditionalProcessing/UsenetDownloadService.php index 8f88a24bb..a5de739b3 100644 --- a/app/Services/AdditionalProcessing/UsenetDownloadService.php +++ b/app/Services/AdditionalProcessing/UsenetDownloadService.php @@ -24,7 +24,7 @@ class UsenetDownloadService /** * Download binary content from usenet using message IDs. * - * @param array|string $messageIDs Single or array of message IDs + * @param array|string $messageIDs Single or array of message IDs * @param string $groupName Group name for logging * @param int|null $releaseId Release ID for logging * @return array{success: bool, data: string|null, groupUnavailable: bool, error: string|null} @@ -107,6 +107,9 @@ class UsenetDownloadService /** * Download sample video content. + * + * @param array $messageIDs + * @return array */ public function downloadSample( array $messageIDs, @@ -118,6 +121,9 @@ class UsenetDownloadService /** * Download media info video content. + * + * @param array $messageID + * @return array */ public function downloadMediaInfo( string|array $messageID, @@ -129,6 +135,9 @@ class UsenetDownloadService /** * Download audio content. + * + * @param array $messageID + * @return array */ public function downloadAudio( string|array $messageID, @@ -140,6 +149,9 @@ class UsenetDownloadService /** * Download JPG content. + * + * @param array $messageIDs + * @return array */ public function downloadJPG( array $messageIDs, @@ -152,7 +164,7 @@ class UsenetDownloadService /** * Download compressed file content (RAR, ZIP, etc.). * - * @param array $messageIDs Message IDs to download + * @param array $messageIDs Message IDs to download * @param string $groupName Group name for logging * @param int|null $releaseId Release ID for logging * @param string|null $fileTitle File title for logging diff --git a/app/Services/AdultProcessing/AdultProcessingPassable.php b/app/Services/AdultProcessing/AdultProcessingPassable.php index 71b7f28b5..1918256c1 100644 --- a/app/Services/AdultProcessing/AdultProcessingPassable.php +++ b/app/Services/AdultProcessing/AdultProcessingPassable.php @@ -13,6 +13,9 @@ class AdultProcessingPassable public bool $debug; + /** + * @var array + */ public array $providerResults = []; public ?string $cookie = null; @@ -70,6 +73,8 @@ class AdultProcessingPassable /** * Build the final result array. + * + * @return array */ public function toArray(): array { diff --git a/app/Services/AdultProcessing/AdultProcessingPipeline.php b/app/Services/AdultProcessing/AdultProcessingPipeline.php index fd7f8e9fb..945783d86 100644 --- a/app/Services/AdultProcessing/AdultProcessingPipeline.php +++ b/app/Services/AdultProcessing/AdultProcessingPipeline.php @@ -34,7 +34,7 @@ class AdultProcessingPipeline /** * @var Collection */ - protected Collection $pipes; + protected Collection $pipes; // @phpstan-ignore missingType.generics protected int $movieQty; @@ -50,6 +50,8 @@ class AdultProcessingPipeline /** * Processing statistics. + * + * @var array */ protected array $stats = [ 'processed' => 0, @@ -65,6 +67,7 @@ class AdultProcessingPipeline */ public function __construct(iterable $pipes = [], bool $echoOutput = true) { + /** @phpstan-ignore argument.templateType */ $this->pipes = collect($pipes); if ($this->pipes->isEmpty()) { @@ -104,6 +107,8 @@ class AdultProcessingPipeline /** * Get the default pipes in priority order. + * + * @return Collection */ protected function getDefaultPipes(): Collection { @@ -134,7 +139,7 @@ class AdultProcessingPipeline * * @param string $movie Movie title to search for * @param bool $debug Whether to include debug information - * @return array Processing result + * @return array Processing result */ public function processMovie(string $movie, bool $debug = false): array { @@ -158,10 +163,10 @@ class AdultProcessingPipeline /** * Process a single release through the pipeline. * - * @param array|object $release Release data + * @param array|object $release Release data * @param string $cleanTitle Cleaned movie title * @param bool $debug Whether to include debug information - * @return array Processing result + * @return array Processing result */ public function processRelease(array|object $release, string $cleanTitle, bool $debug = false): array { @@ -216,7 +221,7 @@ class AdultProcessingPipeline if ($this->echoOutput) { cli()->info('Processing batch '.($batchIndex + 1).' of '.count($batches)); } - $this->processBatch($batch); + $this->processBatch($batch); // @phpstan-ignore argument.type } } catch (\Throwable $e) { Log::error('processXXXReleases failed: '.$e->getMessage(), [ @@ -244,6 +249,8 @@ class AdultProcessingPipeline * Note: Due to serialization limitations with DOMDocument and HtmlDomParser, * we process releases sequentially within the batch but can process multiple * batches concurrently using async tasks that create fresh instances. + * + * @param array $batch */ protected function processBatch(array $batch): void { @@ -334,6 +341,9 @@ class AdultProcessingPipeline /** * Process a release in a child process with fresh instances. * This is a static method to avoid serializing $this. + * + * @param array $releaseData + * @return array */ protected static function processReleaseInChildProcess( array $releaseData, @@ -389,6 +399,7 @@ class AdultProcessingPipeline /** * Process a single release item. * + * @param array $release * @return int XXX info ID or error code */ protected function processReleaseItem(array $release): int @@ -467,6 +478,7 @@ class AdultProcessingPipeline /** * Update XXX information from pipeline results. * + * @param array $release * @return int|false XXX info ID or false on failure */ public function updateXXXInfo(string $movie, ?array $release = null): int|false @@ -594,8 +606,10 @@ class AdultProcessingPipeline /** * Get releases to process. + * + * @return Collection */ - protected function getReleasesToProcess(): \Illuminate\Database\Eloquent\Collection + protected function getReleasesToProcess(): \Illuminate\Database\Eloquent\Collection // @phpstan-ignore missingType.generics, return.phpDocType { return Release::query() ->where(['xxxinfo_id' => 0]) @@ -627,6 +641,8 @@ class AdultProcessingPipeline /** * Check if XXX info already exists in database. + * + * @return array */ protected function checkXXXInfoExists(string $releaseName): ?array { @@ -645,6 +661,8 @@ class AdultProcessingPipeline /** * Get Genre ID from genre names. + * + * @param array $arr */ protected function getGenreID(array|string $arr): string { @@ -754,6 +772,8 @@ class AdultProcessingPipeline /** * Get processing statistics. + * + * @return array */ public function getStats(): array { @@ -762,6 +782,8 @@ class AdultProcessingPipeline /** * Get all registered pipes. + * + * @return Collection */ public function getPipes(): Collection { diff --git a/app/Services/AdultProcessing/AdultProcessingResult.php b/app/Services/AdultProcessing/AdultProcessingResult.php index a4b3748bc..d6c4fc0a3 100644 --- a/app/Services/AdultProcessing/AdultProcessingResult.php +++ b/app/Services/AdultProcessing/AdultProcessingResult.php @@ -17,6 +17,10 @@ class AdultProcessingResult public const STATUS_PENDING = 'pending'; + /** + * @param array $debug + * @param array $movieData + */ public function __construct( public readonly string $status, public readonly ?string $title = null, @@ -27,6 +31,9 @@ class AdultProcessingResult /** * Create a successful match result. + * + * @param array $debug + * @param array $movieData */ public static function matched( string $title, @@ -45,6 +52,8 @@ class AdultProcessingResult /** * Create a not found result. + * + * @param array $debug */ public static function notFound(?string $providerName = null, array $debug = []): self { diff --git a/app/Services/AdultProcessing/AdultReleaseContext.php b/app/Services/AdultProcessing/AdultReleaseContext.php index f6fec48cb..98818a209 100644 --- a/app/Services/AdultProcessing/AdultReleaseContext.php +++ b/app/Services/AdultProcessing/AdultReleaseContext.php @@ -16,6 +16,8 @@ class AdultReleaseContext /** * Create from a Release model array/object. + * + * @param array $release */ public static function fromRelease(array|object $release, string $cleanTitle): self { diff --git a/app/Services/AdultProcessing/AgeVerificationManager.php b/app/Services/AdultProcessing/AgeVerificationManager.php index db363c35b..9353e5d39 100644 --- a/app/Services/AdultProcessing/AgeVerificationManager.php +++ b/app/Services/AdultProcessing/AgeVerificationManager.php @@ -25,11 +25,15 @@ class AgeVerificationManager /** * Cookie jar instances per site + * + * @var array */ private array $cookieJars = []; /** * Site-specific age verification configurations + * + * @var array */ private array $siteConfigs = [ 'adultdvdempire.com' => [ @@ -121,6 +125,8 @@ class AgeVerificationManager /** * Make HTTP request with automatic age verification handling + * + * @param array $options */ public function makeRequest(string $url, array $options = []): string|false { @@ -315,6 +321,8 @@ class AgeVerificationManager /** * Get list of domains with stored cookies + * + * @return array */ public function getStoredDomains(): array { @@ -332,6 +340,8 @@ class AgeVerificationManager /** * Check if cookies exist for a domain + * + * @return list */ public function hasCookies(string $domain): bool { @@ -342,6 +352,8 @@ class AgeVerificationManager /** * Get cookie statistics + * + * @return array */ public function getCookieStats(): array { diff --git a/app/Services/AdultProcessing/Pipes/AbstractAdultProviderPipe.php b/app/Services/AdultProcessing/Pipes/AbstractAdultProviderPipe.php index c4430a646..b00b07369 100644 --- a/app/Services/AdultProcessing/Pipes/AbstractAdultProviderPipe.php +++ b/app/Services/AdultProcessing/Pipes/AbstractAdultProviderPipe.php @@ -73,6 +73,8 @@ abstract class AbstractAdultProviderPipe /** * Last request timestamp for rate limiting. + * + * @var array */ protected static array $lastRequestTime = []; @@ -205,12 +207,14 @@ abstract class AbstractAdultProviderPipe /** * Search for a movie on this provider. * - * @return array|false Returns array with 'title' and 'url' keys on success, false on failure + * @return array|false Returns array with 'title' and 'url' keys on success, false on failure */ abstract protected function search(string $movie): array|false; /** * Get all movie information from the provider. + * + * @return array */ abstract protected function getMovieInfo(): array|false; @@ -234,6 +238,8 @@ abstract class AbstractAdultProviderPipe /** * Get cached search result if available. + * + * @return array */ protected function getCachedSearch(string $movie): array|false|null { @@ -257,6 +263,8 @@ abstract class AbstractAdultProviderPipe /** * Cache a search result. + * + * @param array $result */ protected function cacheSearchResult(string $movie, array|false $result): void { @@ -270,6 +278,8 @@ abstract class AbstractAdultProviderPipe /** * Fetch raw HTML from a URL with retry support. + * + * @param array $postData */ protected function fetchHtml(string $url, ?string $cookie = null, ?array $postData = null): string|false { @@ -393,6 +403,8 @@ abstract class AbstractAdultProviderPipe /** * Get default HTTP headers. + * + * @return array */ protected function getDefaultHeaders(): array { @@ -624,8 +636,10 @@ abstract class AbstractAdultProviderPipe /** * Extract form data for age verification submission. + * + * @return array */ - protected function extractAgeVerificationFormData($form): array + protected function extractAgeVerificationFormData(mixed $form): array { $data = []; @@ -773,32 +787,49 @@ abstract class AbstractAdultProviderPipe /** * Extract movie information from the loaded HTML. + * + * @return array */ protected function extractCovers(): array { return []; } + /** + * @return array + */ protected function extractSynopsis(): array { return []; } + /** + * @return array + */ protected function extractCast(): array { return []; } + /** + * @return array + */ protected function extractGenres(): array { return []; } + /** + * @return array + */ protected function extractProductInfo(bool $extras = false): array { return []; } + /** + * @return array + */ protected function extractTrailers(): array { return []; @@ -830,6 +861,8 @@ abstract class AbstractAdultProviderPipe /** * Parse JSON-LD structured data from HTML. + * + * @return array */ protected function extractJsonLd(string $html): ?array { @@ -853,6 +886,8 @@ abstract class AbstractAdultProviderPipe /** * Extract Open Graph meta data from HTML. + * + * @return array */ protected function extractOpenGraph(string $html): array { diff --git a/app/Services/AdultProcessing/Pipes/AdePipe.php b/app/Services/AdultProcessing/Pipes/AdePipe.php index 20a86db8a..920de35e9 100644 --- a/app/Services/AdultProcessing/Pipes/AdePipe.php +++ b/app/Services/AdultProcessing/Pipes/AdePipe.php @@ -78,6 +78,9 @@ class AdePipe extends AbstractAdultProviderPipe ); } + /** + * @return array + */ protected function search(string $movie): array|false { if (empty($movie)) { @@ -142,6 +145,9 @@ class AdePipe extends AbstractAdultProviderPipe return false; } + /** + * @return array + */ protected function getMovieInfo(): array|false { $results = []; @@ -168,6 +174,9 @@ class AdePipe extends AbstractAdultProviderPipe return $results; } + /** + * @return array + */ protected function extractTrailers(): array { $res = []; @@ -192,6 +201,9 @@ class AdePipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractCovers(): array { $res = []; @@ -218,6 +230,9 @@ class AdePipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractSynopsis(): array { $res = []; @@ -242,6 +257,9 @@ class AdePipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractCast(): array { $res = []; @@ -274,6 +292,9 @@ class AdePipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractGenres(): array { $res = []; @@ -307,6 +328,9 @@ class AdePipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractProductInfo(bool $extras = false): array { $res = []; diff --git a/app/Services/AdultProcessing/Pipes/AdmPipe.php b/app/Services/AdultProcessing/Pipes/AdmPipe.php index 4fcddc405..bfc07ed0f 100644 --- a/app/Services/AdultProcessing/Pipes/AdmPipe.php +++ b/app/Services/AdultProcessing/Pipes/AdmPipe.php @@ -78,6 +78,9 @@ class AdmPipe extends AbstractAdultProviderPipe ); } + /** + * @return array + */ protected function search(string $movie): array|false { if (empty($movie)) { @@ -130,6 +133,9 @@ class AdmPipe extends AbstractAdultProviderPipe return false; } + /** + * @return array + */ protected function getMovieInfo(): array|false { $results = []; @@ -155,6 +161,9 @@ class AdmPipe extends AbstractAdultProviderPipe return $results; } + /** + * @return array + */ protected function extractCovers(): array { $res = []; @@ -186,6 +195,9 @@ class AdmPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractSynopsis(): array { $res = []; @@ -212,6 +224,9 @@ class AdmPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractProductInfo(bool $extras = false): array { $res = []; @@ -233,6 +248,9 @@ class AdmPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractCast(): array { $res = []; @@ -258,6 +276,9 @@ class AdmPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractGenres(): array { $res = []; diff --git a/app/Services/AdultProcessing/Pipes/AebnPipe.php b/app/Services/AdultProcessing/Pipes/AebnPipe.php index 4f382ac6b..52faf4495 100644 --- a/app/Services/AdultProcessing/Pipes/AebnPipe.php +++ b/app/Services/AdultProcessing/Pipes/AebnPipe.php @@ -25,10 +25,16 @@ class AebnPipe extends AbstractAdultProviderPipe protected string $title = ''; + /** + * @var array + */ protected array $res = []; protected string $response = ''; + /** + * @var array + */ protected ?array $jsonLdData = null; public function getName(): string @@ -108,6 +114,9 @@ class AebnPipe extends AbstractAdultProviderPipe ); } + /** + * @return array + */ protected function search(string $movie): array|false { if (empty($movie)) { @@ -187,6 +196,9 @@ class AebnPipe extends AbstractAdultProviderPipe return false; } + /** + * @return array + */ protected function getMovieInfo(): array|false { $results = []; @@ -243,6 +255,8 @@ class AebnPipe extends AbstractAdultProviderPipe /** * Extract data from JSON-LD structured data. + * + * @return array */ protected function extractFromJsonLd(): array { @@ -317,6 +331,9 @@ class AebnPipe extends AbstractAdultProviderPipe return $results; } + /** + * @return array + */ protected function extractTrailers(): array { $res = []; @@ -341,6 +358,9 @@ class AebnPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractCovers(): array { $res = []; @@ -379,6 +399,9 @@ class AebnPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractGenres(): array { $res = []; @@ -415,6 +438,9 @@ class AebnPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractCast(): array { $res = []; @@ -464,6 +490,9 @@ class AebnPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractProductInfo(bool $extras = false): array { $res = []; @@ -509,6 +538,9 @@ class AebnPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractSynopsis(): array { $res = []; diff --git a/app/Services/AdultProcessing/Pipes/Data18Pipe.php b/app/Services/AdultProcessing/Pipes/Data18Pipe.php index 1dfb60d98..40b464ec6 100644 --- a/app/Services/AdultProcessing/Pipes/Data18Pipe.php +++ b/app/Services/AdultProcessing/Pipes/Data18Pipe.php @@ -25,6 +25,9 @@ class Data18Pipe extends AbstractAdultProviderPipe protected string $response = ''; + /** + * @var array + */ protected ?array $jsonLdData = null; public function getName(): string @@ -104,6 +107,9 @@ class Data18Pipe extends AbstractAdultProviderPipe ); } + /** + * @return array + */ protected function search(string $movie): array|false { if (empty($movie)) { @@ -181,6 +187,9 @@ class Data18Pipe extends AbstractAdultProviderPipe return false; } + /** + * @return array + */ protected function getMovieInfo(): array|false { $results = []; @@ -232,6 +241,8 @@ class Data18Pipe extends AbstractAdultProviderPipe /** * Extract data from JSON-LD structured data. + * + * @return array */ protected function extractFromJsonLd(): array { @@ -305,6 +316,9 @@ class Data18Pipe extends AbstractAdultProviderPipe return $results; } + /** + * @return array + */ protected function extractCovers(): array { $res = []; @@ -347,6 +361,9 @@ class Data18Pipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractSynopsis(): array { $res = []; @@ -376,6 +393,9 @@ class Data18Pipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractCast(): array { $res = []; @@ -411,6 +431,9 @@ class Data18Pipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractGenres(): array { $res = []; @@ -446,6 +469,9 @@ class Data18Pipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractProductInfo(bool $extras = false): array { $res = []; diff --git a/app/Services/AdultProcessing/Pipes/HotmoviesPipe.php b/app/Services/AdultProcessing/Pipes/HotmoviesPipe.php index 5161f3006..8a4059d09 100644 --- a/app/Services/AdultProcessing/Pipes/HotmoviesPipe.php +++ b/app/Services/AdultProcessing/Pipes/HotmoviesPipe.php @@ -80,6 +80,9 @@ class HotmoviesPipe extends AbstractAdultProviderPipe ); } + /** + * @return array + */ protected function search(string $movie): array|false { if (empty($movie)) { @@ -144,6 +147,9 @@ class HotmoviesPipe extends AbstractAdultProviderPipe return false; } + /** + * @return array + */ protected function getMovieInfo(): array|false { $results = []; @@ -169,6 +175,9 @@ class HotmoviesPipe extends AbstractAdultProviderPipe return $results; } + /** + * @return array + */ protected function extractSynopsis(): array { $res = []; @@ -197,6 +206,9 @@ class HotmoviesPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractProductInfo(bool $extras = false): array { $res = []; @@ -242,6 +254,9 @@ class HotmoviesPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractCast(): array { $res = []; @@ -276,6 +291,9 @@ class HotmoviesPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractGenres(): array { $res = []; @@ -294,6 +312,9 @@ class HotmoviesPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractCovers(): array { $res = []; diff --git a/app/Services/AdultProcessing/Pipes/IafdPipe.php b/app/Services/AdultProcessing/Pipes/IafdPipe.php index 34e4511ff..5fb92e5ba 100644 --- a/app/Services/AdultProcessing/Pipes/IafdPipe.php +++ b/app/Services/AdultProcessing/Pipes/IafdPipe.php @@ -25,6 +25,9 @@ class IafdPipe extends AbstractAdultProviderPipe protected string $response = ''; + /** + * @var array + */ protected ?array $jsonLdData = null; public function getName(): string @@ -104,6 +107,9 @@ class IafdPipe extends AbstractAdultProviderPipe ); } + /** + * @return array + */ protected function search(string $movie): array|false { if (empty($movie)) { @@ -171,6 +177,9 @@ class IafdPipe extends AbstractAdultProviderPipe return false; } + /** + * @return array + */ protected function getMovieInfo(): array|false { $results = []; @@ -222,6 +231,8 @@ class IafdPipe extends AbstractAdultProviderPipe /** * Extract data from JSON-LD structured data. + * + * @return array */ protected function extractFromJsonLd(): array { @@ -285,6 +296,9 @@ class IafdPipe extends AbstractAdultProviderPipe return $results; } + /** + * @return array + */ protected function extractCovers(): array { $res = []; @@ -320,6 +334,9 @@ class IafdPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractSynopsis(): array { $res = []; @@ -347,6 +364,9 @@ class IafdPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractCast(): array { $res = []; @@ -395,6 +415,9 @@ class IafdPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractGenres(): array { $res = []; @@ -428,6 +451,9 @@ class IafdPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractProductInfo(bool $extras = false): array { $res = []; diff --git a/app/Services/AdultProcessing/Pipes/PoppornPipe.php b/app/Services/AdultProcessing/Pipes/PoppornPipe.php index f860d1b25..2d6fc6253 100644 --- a/app/Services/AdultProcessing/Pipes/PoppornPipe.php +++ b/app/Services/AdultProcessing/Pipes/PoppornPipe.php @@ -78,6 +78,9 @@ class PoppornPipe extends AbstractAdultProviderPipe ); } + /** + * @return array + */ protected function search(string $movie): array|false { if (empty($movie)) { @@ -138,6 +141,9 @@ class PoppornPipe extends AbstractAdultProviderPipe return false; } + /** + * @return array + */ protected function getMovieInfo(): array|false { $results = []; @@ -164,6 +170,9 @@ class PoppornPipe extends AbstractAdultProviderPipe return $results; } + /** + * @return array + */ protected function extractCovers(): array { $res = []; @@ -207,6 +216,9 @@ class PoppornPipe extends AbstractAdultProviderPipe return $res; // @phpstan-ignore deadCode.unreachable } + /** + * @return array + */ protected function extractSynopsis(): array { $res = []; @@ -248,6 +260,9 @@ class PoppornPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractTrailers(): array { $res = []; @@ -281,6 +296,9 @@ class PoppornPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractProductInfo(bool $extras = false): array { $res = []; @@ -371,6 +389,9 @@ class PoppornPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractCast(): array { $res = []; @@ -413,6 +434,9 @@ class PoppornPipe extends AbstractAdultProviderPipe return $res; } + /** + * @return array + */ protected function extractGenres(): array { $res = []; diff --git a/app/Services/AnidbService.php b/app/Services/AnidbService.php index c8cded549..379972545 100644 --- a/app/Services/AnidbService.php +++ b/app/Services/AnidbService.php @@ -80,6 +80,8 @@ class AnidbService /** * Retrieves a list of Anime titles, optionally filtered by starting character and title. + * + * @return array */ public function getAnimeList(string $letter = '', string $animeTitle = ''): array { @@ -118,7 +120,7 @@ class AnidbService /** * Retrieves a range of Anime titles for site display. */ - public function getAnimeRange(string $animeTitle = ''): LengthAwarePaginator + public function getAnimeRange(string $animeTitle = ''): LengthAwarePaginator // @phpstan-ignore missingType.generics { $query = AnidbTitle::query() ->where('at.lang', '=', 'en'); diff --git a/app/Services/AnimeProcessor.php b/app/Services/AnimeProcessor.php index b39bc69a0..74432af55 100644 --- a/app/Services/AnimeProcessor.php +++ b/app/Services/AnimeProcessor.php @@ -119,6 +119,8 @@ class AnimeProcessor * Extracts anime title from release searchname. * Returns ['title' => string] on success else empty array. * Note: AniList doesn't support episode lookups, so we only extract the title. + * + * @return array */ private function extractTitleEpisode(string $cleanName = ''): array { @@ -317,7 +319,7 @@ class AnimeProcessor try { $searchResults = $this->palist->searchAnime($searchName, 1); if ($searchResults) { - $anilistData = $searchResults[0]; + $anilistData = $searchResults[0]; // @phpstan-ignore offsetAccess.notFound $anilistId = $anilistData['id'] ?? null; if ($anilistId) { @@ -361,7 +363,7 @@ class AnimeProcessor * * @throws \Exception */ - private function matchAnimeRelease($release): bool + private function matchAnimeRelease(mixed $release): bool { $matched = false; $type = 'Local'; diff --git a/app/Services/ArchiveProcessingService.php b/app/Services/ArchiveProcessingService.php index b44c7e2b7..0d5a044a6 100644 --- a/app/Services/ArchiveProcessingService.php +++ b/app/Services/ArchiveProcessingService.php @@ -11,6 +11,8 @@ class ArchiveProcessingService /** * Analyze compressed data (RAR/ZIP/etc.). * Returns an array with: ok(bool), error(?string), summary(?array), is_encrypted(bool) + * + * @return array */ public function analyze(string $compressedData): array { @@ -29,6 +31,8 @@ class ArchiveProcessingService /** * Get file list from currently analyzed archive. + * + * @return array */ public function getFileList(): array { diff --git a/app/Services/Archives/SevenZipPartialParser.php b/app/Services/Archives/SevenZipPartialParser.php index 5aaa05839..7be7daed7 100644 --- a/app/Services/Archives/SevenZipPartialParser.php +++ b/app/Services/Archives/SevenZipPartialParser.php @@ -20,22 +20,49 @@ class SevenZipPartialParser private int $len; + /** + * @var array + */ private array $names = []; + /** + * @var array + */ private array $files = []; // Extended file info with metadata + /** + * @var array + */ private array $sizes = []; // Uncompressed sizes + /** + * @var array + */ private array $packedSizes = []; // Compressed sizes + /** + * @var array + */ private array $crcs = []; // CRC32 values + /** + * @var array + */ private array $attributes = []; // File attributes (directory, readonly, etc.) + /** + * @var array + */ private array $mtimes = []; // Modification times + /** + * @var array + */ private array $ctimes = []; // Creation times + /** + * @var array + */ private array $atimes = []; // Access times private bool $parsed = false; @@ -50,6 +77,9 @@ class SevenZipPartialParser private int $numFiles = 0; // Total number of files detected + /** + * @var array + */ private array $compressionMethods = []; // Detected compression methods private int $totalUnpackedSize = 0; // Total unpacked size @@ -158,6 +188,8 @@ class SevenZipPartialParser /** * Public accessor: returns recovered filenames (UTF-8) or empty array. + * + * @return array */ public function getFileNames(): array { @@ -171,7 +203,7 @@ class SevenZipPartialParser /** * Returns detailed file information with all available metadata. * - * @return array + * @return array */ public function getFiles(): array { @@ -184,6 +216,8 @@ class SevenZipPartialParser /** * Returns uncompressed file sizes indexed by file index. + * + * @return array */ public function getSizes(): array { @@ -196,6 +230,8 @@ class SevenZipPartialParser /** * Returns CRC32 values as hex strings indexed by file index. + * + * @return array */ public function getCRCs(): array { @@ -208,6 +244,8 @@ class SevenZipPartialParser /** * Returns file attributes indexed by file index. + * + * @return array */ public function getAttributes(): array { @@ -220,6 +258,8 @@ class SevenZipPartialParser /** * Returns modification times (Unix timestamps) indexed by file index. + * + * @return array */ public function getModificationTimes(): array { @@ -232,6 +272,8 @@ class SevenZipPartialParser /** * Returns detected compression methods used in the archive. + * + * @return array */ public function getCompressionMethods(): array { @@ -1014,27 +1056,27 @@ class SevenZipPartialParser break; case self::K_MTIME: - $this->mtimes = $this->parseFileTimes($cursor, $propSize, $numFiles); + $this->mtimes = $this->parseFileTimes($cursor, $propSize, $numFiles); // @phpstan-ignore assign.propertyType $cursor = $propStart + $propSize; break; case self::K_CTIME: - $this->ctimes = $this->parseFileTimes($cursor, $propSize, $numFiles); + $this->ctimes = $this->parseFileTimes($cursor, $propSize, $numFiles); // @phpstan-ignore assign.propertyType $cursor = $propStart + $propSize; break; case self::K_ATIME: - $this->atimes = $this->parseFileTimes($cursor, $propSize, $numFiles); + $this->atimes = $this->parseFileTimes($cursor, $propSize, $numFiles); // @phpstan-ignore assign.propertyType $cursor = $propStart + $propSize; break; case self::K_WIN_ATTRIBUTES: - $this->attributes = $this->parseAttributes($cursor, $propSize, $numFiles); + $this->attributes = $this->parseAttributes($cursor, $propSize, $numFiles); // @phpstan-ignore assign.propertyType $cursor = $propStart + $propSize; break; case self::K_CRC: - $this->crcs = $this->parseCRCs($cursor, $propSize, $numFiles); + $this->crcs = $this->parseCRCs($cursor, $propSize, $numFiles); // @phpstan-ignore assign.propertyType $cursor = $propStart + $propSize; break; @@ -1047,7 +1089,7 @@ class SevenZipPartialParser // Assign collected names if (! empty($names)) { - $this->names = array_values(array_unique($names)); + $this->names = array_values(array_unique($names)); // @phpstan-ignore assign.propertyType } return $cursor; @@ -1055,6 +1097,8 @@ class SevenZipPartialParser /** * Parse file names from K_NAME property. + * + * @return array */ private function parseNames(int $cursor, int $propSize, int $numFiles): array { @@ -1123,7 +1167,7 @@ class SevenZipPartialParser /** * Parse a bit vector from property data. * - * @return array + * @return list */ private function parseBitVector(int $cursor, int $propSize, int $numItems): array { @@ -1158,7 +1202,7 @@ class SevenZipPartialParser /** * Parse file times from property data. * - * @return array + * @return array, bool> */ private function parseFileTimes(int $cursor, int $propSize, int $numFiles): array { @@ -1220,7 +1264,7 @@ class SevenZipPartialParser /** * Parse Windows attributes from property data. * - * @return array + * @return array, int|null> */ private function parseAttributes(int $cursor, int $propSize, int $numFiles): array { @@ -1432,10 +1476,10 @@ class SevenZipPartialParser } // Also try to find NFO files specifically (common in releases) - $this->scanForNfoFiles($found); + $this->scanForNfoFiles($found); // @phpstan-ignore argument.type if (! empty($found)) { - $this->names = array_values(array_unique($found)); + $this->names = array_values(array_unique($found)); // @phpstan-ignore assign.propertyType } } @@ -1504,6 +1548,8 @@ class SevenZipPartialParser /** * Scan for NFO files which are very common in release archives. + * + * @param array $found */ private function scanForNfoFiles(array &$found): void { @@ -1523,7 +1569,7 @@ class SevenZipPartialParser if (strlen($nameData) > 2 && strlen($nameData) < 256) { $utf8 = @iconv('UTF-16LE', 'UTF-8//IGNORE', $nameData); if ($utf8 !== false && $this->isValidFilename($utf8)) { - $found[] = str_replace('\\', '/', $utf8); + $found[] = str_replace('\\', '/', $utf8); // @phpstan-ignore parameterByRef.type } } } @@ -1626,6 +1672,8 @@ class SevenZipPartialParser /** * Extract a summary of archive information as an associative array. * Useful for quick inspection of archive contents. + * + * @return array */ public function getSummary(): array { @@ -1664,7 +1712,7 @@ class SevenZipPartialParser /** * Get files matching a specific extension. * - * @return array + * @return array> */ public function getFilesByExtension(string $extension): array { @@ -1691,6 +1739,8 @@ class SevenZipPartialParser /** * Check if archive contains any files with given extension. + * + * @return array */ public function hasFileWithExtension(string $extension): bool { @@ -1700,7 +1750,7 @@ class SevenZipPartialParser /** * Get all directory entries from the archive. * - * @return array + * @return array */ public function getDirectories(): array { @@ -1713,6 +1763,8 @@ class SevenZipPartialParser /** * Get the largest file in the archive. + * + * @return array */ public function getLargestFile(): ?array { diff --git a/app/Services/Backfill/BackfillService.php b/app/Services/Backfill/BackfillService.php index cf32c9b6e..ec1da6d1a 100644 --- a/app/Services/Backfill/BackfillService.php +++ b/app/Services/Backfill/BackfillService.php @@ -65,8 +65,8 @@ final class BackfillService $startTime = now(); foreach ($groups as $index => $group) { - $this->logGroupProgress($groupName, $index + 1, $groupCount); - $this->backfillGroup($group->toArray(), $groupCount - $index - 1, $articles); + $this->logGroupProgress($groupName, $index + 1, $groupCount); // @phpstan-ignore binaryOp.invalid + $this->backfillGroup($group->toArray(), $groupCount - $index - 1, $articles); // @phpstan-ignore binaryOp.invalid } $this->logBackfillComplete($startTime); @@ -75,7 +75,7 @@ final class BackfillService /** * Backfill a single group. * - * @param array $groupArr Group data array + * @param array $groupArr Group data array * @param int $remainingGroups Number of groups remaining after this one * @param int|string $articles Number of articles to backfill, or empty for date-based * @@ -141,6 +141,8 @@ final class BackfillService /** * Get groups to backfill based on criteria. + * + * @return array */ private function getGroupsToBackfill(string $groupName, string $type): array { @@ -175,6 +177,8 @@ final class BackfillService /** * Validate that group is in a valid state for backfilling. + * + * @param array $groupArr */ private function validateGroupState(array $groupArr, string $shortGroupName): bool { @@ -192,6 +196,8 @@ final class BackfillService /** * Select NNTP group and return server data. + * + * @return array */ private function selectNntpGroup(string $groupName): ?array { @@ -209,6 +215,9 @@ final class BackfillService /** * Calculate target post number based on articles count or date. + * + * @param array $groupArr + * @param array $serverData */ private function calculateTargetPost(array $groupArr, int|string $articles, array $serverData): int { @@ -224,6 +233,9 @@ final class BackfillService /** * Validate that target post is achievable. + * + * @param array $groupArr + * @param array $serverData */ private function validateTargetPost(array $groupArr, int $targetPost, array $serverData, string $shortGroupName): bool { @@ -247,6 +259,8 @@ final class BackfillService /** * Process backfill in chunks. + * + * @param array $groupArr */ private function processBackfillChunks(array $groupArr, int $targetPost, int $remainingGroups, string $shortGroupName): void { @@ -274,6 +288,9 @@ final class BackfillService /** * Update group record with new first_record and postdate. + * + * @param array $groupArr + * @param array $scanResult */ private function updateGroupRecord(array $groupArr, int $first, ?array $scanResult): void { @@ -335,6 +352,9 @@ final class BackfillService /** * Log group info before processing. + * + * @param array $groupArr + * @param array $serverData */ private function logGroupInfo(array $groupArr, array $serverData, int $targetPost, string $shortGroupName): void { diff --git a/app/Services/Binaries/BinariesService.php b/app/Services/Binaries/BinariesService.php index 67e5e3f2c..2fca4c4bb 100644 --- a/app/Services/Binaries/BinariesService.php +++ b/app/Services/Binaries/BinariesService.php @@ -49,6 +49,9 @@ class BinariesService private \DateTime $startUpdate; // Scan state + /** + * @var array + */ private array $groupMySQL = []; private int $first = 0; @@ -59,6 +62,9 @@ class BinariesService private int $headersBlackListed = 0; + /** + * @var array + */ private array $headersReceived = []; public function __construct( @@ -182,7 +188,7 @@ class BinariesService /** * Download new headers for a single group. * - * @param array $groupMySQL Array of MySQL results for a single group. + * @param array $groupMySQL Array of MySQL results for a single group. * @param int $maxHeaders (Optional) How many headers to download max. * * @throws \Exception @@ -246,12 +252,12 @@ class BinariesService /** * Loop over range of wanted headers, insert headers into DB. * - * @param array $groupMySQL The group info from mysql. + * @param array $groupMySQL The group info from mysql. * @param int $first The oldest wanted header. * @param int $last The newest wanted header. * @param string $type Is this part repair or update or backfill? - * @param array|null $missingParts If we are running in part repair, the list of missing article numbers. - * @return array Empty on failure. + * @param array|null $missingParts If we are running in part repair, the list of missing article numbers. + * @return array Empty on failure. * * @throws \Exception * @throws \Throwable @@ -294,8 +300,8 @@ class BinariesService $this->headerParser->reset(); $parseResult = $this->headerParser->parse($headers, $groupMySQL['name'], $partRepair, $missingParts); - $this->headersReceived = array_column($headers, 'Number'); - $this->headersReceived = array_filter($this->headersReceived); + $this->headersReceived = array_column($headers, 'Number'); // @phpstan-ignore assign.propertyType + $this->headersReceived = array_filter($this->headersReceived); // @phpstan-ignore assign.propertyType $this->notYEnc = $parseResult['notYEnc']; $this->headersBlackListed = $parseResult['blacklisted']; @@ -342,7 +348,7 @@ class BinariesService /** * Attempt to get missing article headers. * - * @param array $groupArr The info for this group from mysql. + * @param array $groupArr The info for this group from mysql. * * @throws \Exception * @throws \Throwable @@ -375,7 +381,7 @@ class BinariesService } // Calculate parts repaired - $lastPartNumber = $missingParts[$missingCount - 1]->numberid; + $lastPartNumber = $missingParts[$missingCount - 1]->numberid; // @phpstan-ignore offsetAccess.notFound $remainingCount = $this->missedPartHandler->getCount($groupArr['id'], $lastPartNumber); $partsRepaired = $missingCount - $remainingCount; @@ -396,7 +402,7 @@ class BinariesService * Returns unix time for an article number. * * @param int|string $post The article number to get the time from. - * @param array $groupData Usenet group info from NNTP selectGroup method. + * @param array $groupData Usenet group info from NNTP selectGroup method. * @return int Timestamp. * * @throws \Exception @@ -452,7 +458,7 @@ class BinariesService * Returns article number based on # of days. * * @param int $days How many days back we want to go. - * @param array $data Group data from usenet. + * @param array $data Group data from usenet. * * @throws \Exception */ @@ -481,6 +487,10 @@ class BinariesService // ==================== Private Helper Methods ==================== + /** + * @param array $groupMySQL + * @return array + */ private function selectNntpGroup(array &$groupMySQL, NNTPService $nntp): ?array { $groupNNTP = $nntp->selectGroup($groupMySQL['name']); @@ -500,6 +510,11 @@ class BinariesService return $groupNNTP; } + /** + * @param array $groupMySQL + * @param array $groupNNTP + * @return array + */ private function calculateArticleRange(array $groupMySQL, array $groupNNTP, int $maxHeaders): array { if ((int) $groupMySQL['last_record'] === 0) { @@ -509,6 +524,10 @@ class BinariesService return $this->calculateExistingGroupRange($groupMySQL, $groupNNTP, $maxHeaders); } + /** + * @param array $groupNNTP + * @return array + */ private function calculateNewGroupRange(array $groupNNTP): array { if ($this->config->newGroupScanByDays) { @@ -540,6 +559,11 @@ class BinariesService ]; } + /** + * @param array $groupMySQL + * @param array $groupNNTP + * @return array + */ private function calculateExistingGroupRange(array $groupMySQL, array $groupNNTP, int $maxHeaders): array { $first = (int) $groupMySQL['last_record']; @@ -577,6 +601,11 @@ class BinariesService ]; } + /** + * @param array $groupMySQL + * @param array $groupNNTP + * @param array $range + */ private function processArticleRange(array &$groupMySQL, array $groupNNTP, array $range): void { $first = (int) $range['first']; @@ -614,6 +643,11 @@ class BinariesService } } + /** + * @param array $groupMySQL + * @param array $groupNNTP + * @param array $scanSummary + */ private function updateGroupAfterScan(array &$groupMySQL, array $groupNNTP, array $scanSummary, int $last): void { if (! empty($scanSummary)) { @@ -649,6 +683,9 @@ class BinariesService } } + /** + * @return array + */ private function downloadHeaders(bool $partRepair): ?array { $nntp = $this->getNntp(); @@ -689,6 +726,10 @@ class BinariesService return $headers; } + /** + * @param array $headersNotInserted + * @param array $parsedHeaders + */ private function handlePartRepairTracking(array $headersNotInserted, array $parsedHeaders): void { $notInsertedCount = \count($headersNotInserted); @@ -704,7 +745,7 @@ class BinariesService $notReceivedCount = \count($rangeNotReceived); if ($notReceivedCount > 0) { - $this->missedPartHandler->addMissingParts($rangeNotReceived, $this->groupMySQL['id']); + $this->missedPartHandler->addMissingParts($rangeNotReceived, $this->groupMySQL['id']); // @phpstan-ignore argument.type if ($this->config->echoCli) { cli()->alternate( @@ -715,11 +756,15 @@ class BinariesService } } + /** + * @param array $missingParts + * @return array + */ private function groupMissingPartsIntoRanges(array $missingParts): array { $ranges = []; $partList = []; - $firstPart = $lastNum = $missingParts[0]->numberid; + $firstPart = $lastNum = $missingParts[0]->numberid; // @phpstan-ignore offsetAccess.notFound foreach ($missingParts as $part) { if (($part->numberid - $firstPart) > ($this->config->messageBuffer / 4)) { @@ -744,6 +789,10 @@ class BinariesService return $ranges; } + /** + * @param array $groupData + * @return list> + */ private function getNextArticleToTry(int $currentPost, array $groupData): ?int { if (abs($currentPost - $groupData['first']) > abs($groupData['last'] - $currentPost)) { @@ -766,6 +815,9 @@ class BinariesService return $tempPost; } + /** + * @param array $data + */ private function binarySearchArticleByDate(int $goalTime, array $data): string { $wantedArticle = (int) round(($data['last'] + $data['first']) / 2); @@ -824,6 +876,11 @@ class BinariesService // ==================== Output Methods ==================== + /** + * @param array $groupMySQL + * @param array $groupNNTP + * @param array $range + */ private function outputNoNewArticles(array $groupMySQL, array $groupNNTP, array $range): void { if ($this->config->echoCli) { @@ -836,6 +893,11 @@ class BinariesService } } + /** + * @param array $groupMySQL + * @param array $groupNNTP + * @param array $range + */ private function outputNewArticlesInfo(array $groupMySQL, array $groupNNTP, array $range): void { if (! $this->config->echoCli) { diff --git a/app/Services/Binaries/BinaryHandler.php b/app/Services/Binaries/BinaryHandler.php index d256d9943..9a7065c0d 100644 --- a/app/Services/Binaries/BinaryHandler.php +++ b/app/Services/Binaries/BinaryHandler.php @@ -36,6 +36,7 @@ final class BinaryHandler /** * Get or create a binary for the given header. * + * @param array $header * @return int|null Binary ID or null on failure */ public function getOrCreateBinary( @@ -85,6 +86,9 @@ final class BinaryHandler return null; } + /** + * @param array $header + */ private function insertOrGetBinary( string $driver, string $hash, @@ -203,10 +207,10 @@ final class BinaryHandler try { if ($driver === 'sqlite') { - return $this->flushUpdatesSqlite($updates); + return $this->flushUpdatesSqlite($updates); // @phpstan-ignore argument.type } - return $this->flushUpdatesMysql($updates, $chunkSize); + return $this->flushUpdatesMysql($updates, $chunkSize); // @phpstan-ignore argument.type } catch (\Throwable $e) { if (config('app.debug') === true) { Log::error('Binaries aggregate update failed: '.$e->getMessage()); @@ -216,6 +220,9 @@ final class BinaryHandler } } + /** + * @param array $updates + */ private function flushUpdatesSqlite(array $updates): bool { foreach ($updates as $row) { @@ -228,6 +235,9 @@ final class BinaryHandler return true; } + /** + * @param array $updates + */ private function flushUpdatesMysql(array $updates, int $chunkSize): bool { foreach (array_chunk($updates, $chunkSize) as $chunk) { @@ -275,6 +285,8 @@ final class BinaryHandler /** * Get IDs created in this batch. + * + * @return list */ public function getInsertedIds(): array { @@ -283,6 +295,8 @@ final class BinaryHandler /** * Get pending binary updates that haven't been flushed. + * + * @return list> */ private function getPendingUpdates(): array { diff --git a/app/Services/Binaries/CollectionHandler.php b/app/Services/Binaries/CollectionHandler.php index 0c5ae7cef..2db995fa8 100644 --- a/app/Services/Binaries/CollectionHandler.php +++ b/app/Services/Binaries/CollectionHandler.php @@ -49,6 +49,7 @@ final class CollectionHandler /** * Get or create a collection for the given header. * + * @param array $header * @return int|null Collection ID or null on failure */ public function getOrCreateCollection( @@ -116,6 +117,9 @@ final class CollectionHandler return null; } + /** + * @param array $headerTokens + */ private function insertOrGetCollection( string $driver, string $subject, @@ -157,6 +161,9 @@ final class CollectionHandler ); } + /** + * @param array $headerTokens + */ private function insertCollectionSqlite( string $subject, string $fromName, @@ -193,6 +200,9 @@ final class CollectionHandler return (int) (Collection::whereCollectionhash($collectionHash)->value('id') ?? 0); } + /** + * @param array $headerTokens + */ private function insertCollectionMysql( string $subject, string $fromName, @@ -241,6 +251,8 @@ final class CollectionHandler /** * Get IDs created in this batch. + * + * @return list */ public function getInsertedIds(): array { @@ -249,6 +261,8 @@ final class CollectionHandler /** * Get all collection IDs processed this batch. + * + * @return list */ public function getAllIds(): array { @@ -257,6 +271,8 @@ final class CollectionHandler /** * Get all collection hashes processed this batch. + * + * @return list */ public function getBatchHashes(): array { diff --git a/app/Services/Binaries/HeaderParser.php b/app/Services/Binaries/HeaderParser.php index e8dad0898..eace871b6 100644 --- a/app/Services/Binaries/HeaderParser.php +++ b/app/Services/Binaries/HeaderParser.php @@ -34,11 +34,11 @@ final class HeaderParser /** * Parse and filter raw headers from NNTP. * - * @param array $headers Raw headers from NNTP + * @param array $headers Raw headers from NNTP * @param string $groupName The newsgroup name * @param bool $partRepair Whether this is a part repair scan - * @param array|null $missingParts Missing part numbers if part repair - * @return array Filtered and parsed headers with article info + * @param array|null $missingParts Missing part numbers if part repair + * @return array Filtered and parsed headers with article info */ public function parse( array $headers, @@ -110,7 +110,7 @@ final class HeaderParser { $ids = $this->blacklistService->getAndClearIdsToUpdate(); if (! empty($ids)) { - $this->blacklistService->updateBlacklistUsage($ids); + $this->blacklistService->updateBlacklistUsage($ids); // @phpstan-ignore argument.type } } @@ -132,6 +132,9 @@ final class HeaderParser /** * Extract highest and lowest article info from headers. + * + * @param array $headers + * @return array */ public function getArticleRange(array $headers): array { diff --git a/app/Services/Binaries/HeaderStorageService.php b/app/Services/Binaries/HeaderStorageService.php index ac255d292..afe792451 100644 --- a/app/Services/Binaries/HeaderStorageService.php +++ b/app/Services/Binaries/HeaderStorageService.php @@ -41,10 +41,10 @@ final class HeaderStorageService /** * Store parsed headers to the database. * - * @param array $headers Parsed headers with 'matches' already populated - * @param array $groupMySQL Group info from database + * @param array $headers Parsed headers with 'matches' already populated + * @param array $groupMySQL Group info from database * @param bool $addToPartRepair Whether to track failed inserts - * @return array Article numbers that failed to insert + * @return array Article numbers that failed to insert */ public function store(array $headers, array $groupMySQL, bool $addToPartRepair = true): array { @@ -110,6 +110,10 @@ final class HeaderStorageService )); } + /** + * @param array $groupMySQL + * @param array $header + */ private function processHeader(array $header, array $groupMySQL, HeaderStorageTransaction $transaction): bool { // Get file count from subject @@ -160,6 +164,9 @@ final class HeaderStorageService return true; } + /** + * @return array + */ private function getFileCount(string $subject): array { if (! preg_match('/[[(\s](\d{1,5})(\/|[\s_]of[\s_]|-)(\d{1,5})[])[\s$:]/i', $subject, $fileCount)) { diff --git a/app/Services/Binaries/MissedPartHandler.php b/app/Services/Binaries/MissedPartHandler.php index 9e2e9d46a..7d427163e 100644 --- a/app/Services/Binaries/MissedPartHandler.php +++ b/app/Services/Binaries/MissedPartHandler.php @@ -25,6 +25,8 @@ final class MissedPartHandler /** * Add missing article numbers to the repair queue. + * + * @param array $numbers */ public function addMissingParts(array $numbers, int $groupId): void { @@ -43,6 +45,9 @@ final class MissedPartHandler $this->addMissingPartsMysql($numbers, $groupId); } + /** + * @param array $numbers + */ private function addMissingPartsSqlite(array $numbers, int $groupId): void { foreach ($numbers as $number) { @@ -53,6 +58,9 @@ final class MissedPartHandler } } + /** + * @param array $numbers + */ private function addMissingPartsMysql(array $numbers, int $groupId): void { $insertStr = 'INSERT INTO missed_parts (numberid, groups_id) VALUES '; @@ -65,6 +73,8 @@ final class MissedPartHandler /** * Remove successfully repaired parts from the queue. + * + * @param array $numbers */ public function removeRepairedParts(array $numbers, int $groupId): void { @@ -91,7 +101,7 @@ final class MissedPartHandler /** * Get parts that need repair for a group. * - * @return array Array of missed parts + * @return array Array of missed parts */ public function getMissingParts(int $groupId): array { diff --git a/app/Services/Binaries/PartHandler.php b/app/Services/Binaries/PartHandler.php index b56c6ddcc..2357f8ac9 100644 --- a/app/Services/Binaries/PartHandler.php +++ b/app/Services/Binaries/PartHandler.php @@ -13,12 +13,21 @@ use Illuminate\Support\Facades\Log; final class PartHandler { /** @var array Pending parts to insert */ + /** + * @var array + */ private array $parts = []; /** @var array Part numbers successfully inserted */ + /** + * @var array + */ private array $insertedPartNumbers = []; /** @var array Part numbers that failed to insert */ + /** + * @var array + */ private array $failedPartNumbers = []; private int $chunkSize; @@ -53,6 +62,7 @@ final class PartHandler /** * Add a part to the pending insert queue. * + * @param array $header * @return bool True if chunk was flushed successfully (or not needed), false on flush failure */ public function addPart(int $binaryId, array $header): bool @@ -99,6 +109,9 @@ final class PartHandler return $success; } + /** + * @param array $parts + */ private function insertChunk(array $parts): bool { $placeholders = []; @@ -133,6 +146,8 @@ final class PartHandler /** * Get numbers of successfully inserted parts. + * + * @return array */ public function getInsertedNumbers(): array { @@ -141,6 +156,8 @@ final class PartHandler /** * Get numbers of failed part inserts. + * + * @return array */ public function getFailedNumbers(): array { diff --git a/app/Services/BlacklistService.php b/app/Services/BlacklistService.php index 7a87a6870..3e3e7130d 100644 --- a/app/Services/BlacklistService.php +++ b/app/Services/BlacklistService.php @@ -10,20 +10,32 @@ class BlacklistService { /** * Cache of lists per group name. + * + * @var array */ private array $blackList = []; + /** + * @var array + */ private array $whiteList = []; + /** + * @var array + */ private array $listsFound = []; /** * Track blacklist IDs to update last_activity for. + * + * @var array */ private array $idsToUpdate = []; /** * Check if an article (OVER header) is blacklisted for the given group. + * + * @param array $msg */ public function isBlackListed(array $msg, string $groupName): bool { @@ -68,6 +80,8 @@ class BlacklistService /** * Get and reset collected blacklist IDs that matched during checks. + * + * @return list */ public function getAndClearIdsToUpdate(): array { @@ -79,6 +93,8 @@ class BlacklistService /** * Update last_activity timestamp for given blacklist IDs. + * + * @param array $ids */ public function updateBlacklistUsage(array $ids): void { @@ -90,6 +106,8 @@ class BlacklistService /** * Query blacklists from DB. + * + * @return array */ public function getBlacklist(bool $activeOnly = true, int|string $opType = -1, string $groupName = '', bool $groupRegex = false): array { @@ -116,7 +134,7 @@ class BlacklistService return DB::select($sql); } - public function getBlacklistByID(int $id) + public function getBlacklistByID(int $id): mixed { return BinaryBlacklist::query()->where('id', $id)->first(); } @@ -126,6 +144,9 @@ class BlacklistService BinaryBlacklist::query()->where('id', $id)->delete(); } + /** + * @param array $blacklistArray + */ public function updateBlacklist(array $blacklistArray): void { BinaryBlacklist::query()->where('id', $blacklistArray['id'])->update( @@ -140,6 +161,9 @@ class BlacklistService ); } + /** + * @param array $blacklistArray + */ public function addBlacklist(array $blacklistArray): void { BinaryBlacklist::query()->insert( diff --git a/app/Services/BookService.php b/app/Services/BookService.php index 97931e396..ac0ae25b0 100644 --- a/app/Services/BookService.php +++ b/app/Services/BookService.php @@ -33,6 +33,9 @@ class BookService public string $renamed; + /** + * @var array + */ public array $failCache; /** @@ -89,6 +92,10 @@ class BookService /** * Get book range with pagination. + * + * @param array $cat + * @param array $excludedCats + * @return array */ public function getBookRange(int $page, array $cat, int $start, int $num, string $orderBy, array $excludedCats = []): array { @@ -97,7 +104,7 @@ class BookService $browseby = $this->getBrowseBy(); $catsrch = ''; - if (\count($cat) > 0 && $cat[0] !== -1) { + if (\count($cat) > 0 && $cat[0] !== -1) { // @phpstan-ignore offsetAccess.notFound $catsrch = Category::getCategorySearch($cat); } $exccatlist = ''; @@ -121,8 +128,8 @@ class BookService $browseby, $catsrch, $exccatlist, - $order[0], - $order[1], + $order[0], // @phpstan-ignore offsetAccess.notFound + $order[1], // @phpstan-ignore offsetAccess.notFound ($start === false ? '' : ' LIMIT '.$num.' OFFSET '.$start) ); $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium')); @@ -162,8 +169,8 @@ class BookService ! empty($bookIDs) ? implode(',', $bookIDs) : -1, ! empty($releaseIDs) ? implode(',', $releaseIDs) : -1, $catsrch, - $order[0], - $order[1] + $order[0], // @phpstan-ignore offsetAccess.notFound + $order[1] // @phpstan-ignore offsetAccess.notFound ); $return = Cache::get(md5($sql.$page)); if ($return !== null) { @@ -180,6 +187,8 @@ class BookService /** * Get book order array. + * + * @return array */ public function getBookOrder(string $orderBy): array { @@ -201,6 +210,8 @@ class BookService /** * Get book ordering options. + * + * @return array */ public function getBookOrdering(): array { @@ -224,6 +235,8 @@ class BookService /** * Get browse by options. + * + * @return array */ public function getBrowseByOptions(): array { @@ -256,7 +269,7 @@ class BookService ?string $url, ?string $author, ?string $publisher, - $publishdate, + mixed $publishdate, int $cover ): bool { return BookInfo::query()->where('id', $id)->update([ @@ -313,7 +326,7 @@ class BookService * * @throws \Exception */ - protected function processBookReleasesHelper($res, $categoryID): void + protected function processBookReleasesHelper(mixed $res, mixed $categoryID): void { if ($res->count() > 0) { if ($this->echooutput) { @@ -381,7 +394,7 @@ class BookService * * @return bool|string */ - public function parseTitle($release_name, $releaseID, $releasetype) + public function parseTitle(mixed $release_name, mixed $releaseID, mixed $releasetype) { $a = preg_replace('/\d{1,2} \d{1,2} \d{2,4}|(19|20)\d\d|anybody got .+?[a-z]\? |[ ._-](Novel|TIA)([ ._-]|$)|([ \.])HQ([-\. ])|[\(\)\.\-_ ](AVI|AZW3?|DOC|EPUB|LIT|MOBI|NFO|RETAIL|(si)?PDF|RTF|TXT)[\)\]\.\-_ ](?![a-z0-9])|compleet|DAGSTiDNiNGEN|DiRFiX|\+ extra|r?e ?Books?([\.\-_ ]English|ers)?|azw3?|ePu([bp])s?|html|mobi|^NEW[\.\-_ ]|PDF([\.\-_ ]English)?|Please post more|Post description|Proper|Repack(fix)?|[\.\-_ ](Chinese|English|French|German|Italian|Retail|Scan|Swedish)|^R4 |Repost|Skytwohigh|TIA!+|TruePDF|V413HAV|(would someone )?please (re)?post.+? "|with the authors name right/i', '', $release_name); $b = preg_replace('/^(As Req |conversion |eq |Das neue Abenteuer \d+|Fixed version( ignore previous post)?|Full |Per Req As Found|(\s+)?R4 |REQ |revised |version |\d+(\s+)?$)|(COMPLETE|INTERNAL|RELOADED| (AZW3|eB|docx|ENG?|exe|FR|Fix|gnv64|MU|NIV|R\d\s+\d{1,2} \d{1,2}|R\d|Req|TTL|UC|v(\s+)?\d))(\s+)?$/i', '', $a); @@ -437,7 +450,7 @@ class BookService * * @throws \Exception */ - public function updateBookInfo(string $bookInfo = '', $amazdata = null) + public function updateBookInfo(string $bookInfo = '', mixed $amazdata = null) { $ri = new ReleaseImageService; @@ -521,7 +534,7 @@ class BookService /** * Fetch book properties from iTunes. * - * @return array|bool + * @return array|bool */ public function fetchItunesBookProperties(string $bookInfo) { diff --git a/app/Services/Categorization/CategorizationPipeline.php b/app/Services/Categorization/CategorizationPipeline.php index d74e9dbf3..f50d9624a 100644 --- a/app/Services/Categorization/CategorizationPipeline.php +++ b/app/Services/Categorization/CategorizationPipeline.php @@ -22,7 +22,7 @@ class CategorizationPipeline /** * @var Collection */ - protected Collection $pipes; + protected Collection $pipes; // @phpstan-ignore missingType.generics protected bool $categorizeForeign; @@ -33,6 +33,7 @@ class CategorizationPipeline */ public function __construct(iterable $pipes = []) { + /** @phpstan-ignore argument.templateType */ $this->pipes = collect($pipes) ->sortBy(fn (AbstractCategorizationPipe $p) => $p->getPriority()); @@ -58,7 +59,7 @@ class CategorizationPipeline * @param string $releaseName The name of the release * @param string|null $poster The poster name * @param bool $debug Whether to include debug information - * @return array The categorization result + * @return array The categorization result */ public function categorize( int|string $groupId, @@ -93,7 +94,7 @@ class CategorizationPipeline * * @return Collection */ - public function getCategorizers(): Collection + public function getCategorizers(): Collection // @phpstan-ignore missingType.generics { return $this->pipes; } diff --git a/app/Services/Categorization/CategorizationResult.php b/app/Services/Categorization/CategorizationResult.php index 0e9b90566..4d1f13e70 100644 --- a/app/Services/Categorization/CategorizationResult.php +++ b/app/Services/Categorization/CategorizationResult.php @@ -13,7 +13,7 @@ class CategorizationResult * @param int $categoryId The determined category ID * @param float $confidence Confidence level (0.0 to 1.0) * @param string $matchedBy Description of what matched - * @param array $debug Additional debug information + * @param array $debug Additional debug information */ public function __construct( public readonly int $categoryId = Category::OTHER_MISC, @@ -58,6 +58,8 @@ class CategorizationResult /** * Create a result with debug info merged. + * + * @param array $additionalDebug */ public function withDebug(array $additionalDebug): self { diff --git a/app/Services/Categorization/CategorizationService.php b/app/Services/Categorization/CategorizationService.php index 9b39ab8b3..553616d49 100644 --- a/app/Services/Categorization/CategorizationService.php +++ b/app/Services/Categorization/CategorizationService.php @@ -27,7 +27,7 @@ class CategorizationService * @param string $releaseName The name of the release * @param string|null $poster The poster name * @param bool $debug Whether to include debug information - * @return array The categorization result with category ID and optional debug info + * @return array The categorization result with category ID and optional debug info */ public function determineCategory( int|string $groupId, @@ -41,8 +41,8 @@ class CategorizationService /** * Batch categorize multiple releases. * - * @param array $releases Array of ['group_id' => x, 'name' => y, 'poster' => z] - * @return array Array of categorization results + * @param array $releases Array of ['group_id' => x, 'name' => y, 'poster' => z] + * @return array Array of categorization results */ public function batchCategorize(array $releases): array { @@ -64,6 +64,8 @@ class CategorizationService /** * Get the underlying pipeline. + * + * @return list> */ public function getPipeline(): CategorizationPipeline { @@ -131,6 +133,8 @@ class CategorizationService /** * Get statistics about categorizer usage. + * + * @return array */ public function getCategorizerStats(): array { diff --git a/app/Services/Categorization/Categorizers/AbstractCategorizer.php b/app/Services/Categorization/Categorizers/AbstractCategorizer.php index f26ac5e06..de3b45667 100644 --- a/app/Services/Categorization/Categorizers/AbstractCategorizer.php +++ b/app/Services/Categorization/Categorizers/AbstractCategorizer.php @@ -20,6 +20,9 @@ abstract class AbstractCategorizer implements CategorizerInterface return false; } + /** + * @param array $debug + */ protected function matched(int $categoryId, float $confidence, string $matchedBy, array $debug = []): CategorizationResult { return new CategorizationResult($categoryId, $confidence, $matchedBy, $debug); diff --git a/app/Services/Categorization/Pipes/AbstractCategorizationPipe.php b/app/Services/Categorization/Pipes/AbstractCategorizationPipe.php index 50ef7f00b..9d8e7f75f 100644 --- a/app/Services/Categorization/Pipes/AbstractCategorizationPipe.php +++ b/app/Services/Categorization/Pipes/AbstractCategorizationPipe.php @@ -67,6 +67,8 @@ abstract class AbstractCategorizationPipe /** * Create a successful categorization result. + * + * @param array $debug */ protected function matched(int $categoryId, float $confidence, string $matchedBy, array $debug = []): CategorizationResult { diff --git a/app/Services/Categorization/Pipes/CategorizationPassable.php b/app/Services/Categorization/Pipes/CategorizationPassable.php index 516cb2b7e..0c172f243 100644 --- a/app/Services/Categorization/Pipes/CategorizationPassable.php +++ b/app/Services/Categorization/Pipes/CategorizationPassable.php @@ -16,6 +16,9 @@ class CategorizationPassable public bool $debug; + /** + * @var array + */ public array $allResults = []; public function __construct(ReleaseContext $context, bool $debug = false) @@ -53,6 +56,8 @@ class CategorizationPassable /** * Build the final result array. + * + * @return array */ public function toArray(): array { diff --git a/app/Services/CollectionsCleaningService.php b/app/Services/CollectionsCleaningService.php index b34f19ef1..124ed3780 100644 --- a/app/Services/CollectionsCleaningService.php +++ b/app/Services/CollectionsCleaningService.php @@ -88,7 +88,7 @@ class CollectionsCleaningService * * @param string $subject The raw subject line to clean * @param string $groupName The newsgroup name (optional, used for context-specific cleaning) - * @return array Returns ['id' => regex_id, 'name' => cleaned_name] + * @return array Returns ['id' => regex_id, 'name' => cleaned_name] * * @throws \Exception */ @@ -115,7 +115,7 @@ class CollectionsCleaningService * * If no regexes matched on collectionsCleaner, this method applies generic cleaning patterns. * - * @return array Returns ['id' => match_type, 'name' => cleaned_name] + * @return array Returns ['id' => match_type, 'name' => cleaned_name] */ protected function generic(): array { @@ -139,7 +139,7 @@ class CollectionsCleaningService /** * Clean non-music group subjects. * - * @return array Returns ['id' => match_type, 'name' => cleaned_name] + * @return array Returns ['id' => match_type, 'name' => cleaned_name] */ protected function cleanGenericSubject(): array { @@ -170,7 +170,7 @@ class CollectionsCleaningService /** * Clean music group subjects with generic patterns. * - * @return array Returns ['id' => match_type, 'name' => cleaned_name] + * @return array Returns ['id' => match_type, 'name' => cleaned_name] */ protected function cleanMusicSubject(): array { diff --git a/app/Services/ConsoleService.php b/app/Services/ConsoleService.php index c4f0a9362..34a744a2b 100644 --- a/app/Services/ConsoleService.php +++ b/app/Services/ConsoleService.php @@ -51,11 +51,14 @@ class ConsoleService public bool $renamed; + /** + * @var array + */ public array $failCache; protected ReleaseImageService $imageService; - protected $igdbSleep; + protected mixed $igdbSleep; public function __construct(?ReleaseImageService $imageService = null) { @@ -119,6 +122,10 @@ class ConsoleService /** * Get console games range with pagination. * + * @param array $cat + * @param array $excludedCats + * @return array + * * @throws \Exception */ public function getConsoleRange(int $page, array $cat, int $start, int $num, string $orderBy, array $excludedCats = []): array @@ -128,7 +135,7 @@ class ConsoleService $browseBy = $this->getBrowseBy(); $catsrch = ''; - if (\count($cat) > 0 && (int) $cat[0] !== -1) { + if (\count($cat) > 0 && (int) $cat[0] !== -1) { // @phpstan-ignore offsetAccess.notFound $catsrch = Category::getCategorySearch($cat); } $exccatlist = ''; @@ -153,8 +160,8 @@ class ConsoleService $browseBy, $catsrch, $exccatlist, - $order[0], - $order[1], + $order[0], // @phpstan-ignore offsetAccess.notFound + $order[1], // @phpstan-ignore offsetAccess.notFound ($start === false ? '' : ' LIMIT '.$num.' OFFSET '.$start) ); @@ -217,8 +224,8 @@ class ConsoleService (! empty($consoleIDs) ? implode(',', $consoleIDs) : -1), (! empty($releaseIDs) ? implode(',', $releaseIDs) : -1), $catsrch, - $order[0], - $order[1] + $order[0], // @phpstan-ignore offsetAccess.notFound + $order[1] // @phpstan-ignore offsetAccess.notFound ); $return = Cache::get(md5($sql.$page)); @@ -239,6 +246,8 @@ class ConsoleService /** * Get console order array. + * + * @return array */ public function getConsoleOrder(string $orderBy): array { @@ -263,6 +272,8 @@ class ConsoleService /** * Get console ordering options. + * + * @return array */ public function getConsoleOrdering(): array { @@ -280,6 +291,8 @@ class ConsoleService /** * Get browse by options. + * + * @return array */ public function getBrowseByOptions(): array { @@ -351,6 +364,8 @@ class ConsoleService * Update console info from IGDB. * * + * @param array $gameInfo + * * @throws \Exception */ public function updateConsoleInfo(array $gameInfo): int @@ -384,6 +399,8 @@ class ConsoleService /** * Fetch IGDB properties for a game. * + * @return array + * * @throws \Exception */ public function fetchIGDBProperties(string $gameInfo, string $gamePlatform): bool|array|\StdClass @@ -571,6 +588,8 @@ class ConsoleService /** * Parse release title for game info. + * + * @return array */ public function parseTitle(string $releaseName): array|false { @@ -726,6 +745,8 @@ class ConsoleService /** * Update or create console info in the database. + * + * @param array $con */ protected function updateConsoleTable(array $con = []): int { @@ -800,6 +821,8 @@ class ConsoleService /** * Load genres from database. * + * @return array + * * @throws \Exception */ protected function loadGenres(): array diff --git a/app/Services/FanartTvService.php b/app/Services/FanartTvService.php index c74ddad55..a822c8c99 100644 --- a/app/Services/FanartTvService.php +++ b/app/Services/FanartTvService.php @@ -48,7 +48,7 @@ class FanartTvService * Make a GET request to the Fanart.TV API. * * @param string $endpoint The API endpoint - * @return array|null Response data or null on failure + * @return array|null Response data or null on failure */ protected function get(string $endpoint): ?array { @@ -110,7 +110,7 @@ class FanartTvService * Get fan art for a movie by IMDB ID. * * @param string $imdbId IMDB ID (with or without 'tt' prefix) - * @return array|null Movie art data or null on failure + * @return array|null Movie art data or null on failure */ public function getMovieFanArt(string $imdbId): ?array { @@ -128,7 +128,7 @@ class FanartTvService * Get fan art for a TV show by TVDB ID. * * @param int|string $tvdbId TVDB ID - * @return array|null TV show art data or null on failure + * @return array|null TV show art data or null on failure */ public function getTvFanArt(int|string $tvdbId): ?array { @@ -143,7 +143,7 @@ class FanartTvService * Get fan art for music by MusicBrainz ID. * * @param string $mbId MusicBrainz ID - * @return array|null Music art data or null on failure + * @return array|null Music art data or null on failure */ public function getMusicFanArt(string $mbId): ?array { @@ -158,7 +158,7 @@ class FanartTvService * Extract movie properties from Fanart.TV response. * * @param string $imdbId IMDB ID (with or without 'tt' prefix) - * @return array|null Array with 'cover', 'backdrop', 'banner', 'title' keys or null on failure + * @return array|null Array with 'cover', 'backdrop', 'banner', 'title' keys or null on failure */ public function getMovieProperties(string $imdbId): ?array { @@ -201,7 +201,7 @@ class FanartTvService * Extract TV show properties from Fanart.TV response. * * @param int|string $tvdbId TVDB ID - * @return array|null Array with 'poster', 'banner', 'background', 'title' keys or null on failure + * @return array|null Array with 'poster', 'banner', 'background', 'title' keys or null on failure */ public function getTvProperties(int|string $tvdbId): ?array { @@ -215,6 +215,7 @@ class FanartTvService // Get poster (sort by likes) if (! empty($art['tvposter'])) { + /** @phpstan-ignore argument.templateType */ $best = collect($art['tvposter'])->sortByDesc('likes')->first(); if (! empty($best['url'])) { $result['poster'] = $best['url']; @@ -223,6 +224,7 @@ class FanartTvService // Get banner (sort by likes) if (! empty($art['tvbanner'])) { + /** @phpstan-ignore argument.templateType */ $best = collect($art['tvbanner'])->sortByDesc('likes')->first(); if (! empty($best['url'])) { $result['banner'] = $best['url']; @@ -231,6 +233,7 @@ class FanartTvService // Get background (sort by likes) if (! empty($art['showbackground'])) { + /** @phpstan-ignore argument.templateType */ $best = collect($art['showbackground'])->sortByDesc('likes')->first(); if (! empty($best['url'])) { $result['background'] = $best['url']; @@ -239,6 +242,7 @@ class FanartTvService // Get HD clearlogo (sort by likes) if (! empty($art['hdtvlogo'])) { + /** @phpstan-ignore argument.templateType */ $best = collect($art['hdtvlogo'])->sortByDesc('likes')->first(); if (! empty($best['url'])) { $result['logo'] = $best['url']; @@ -268,6 +272,7 @@ class FanartTvService return null; } + /** @phpstan-ignore argument.templateType */ $best = collect($art['tvposter'])->sortByDesc('likes')->first(); return $best['url'] ?? null; @@ -287,6 +292,7 @@ class FanartTvService return null; } + /** @phpstan-ignore argument.templateType */ $best = collect($art['movieposter'])->sortByDesc('likes')->first(); return $best['url'] ?? null; diff --git a/app/Services/ForkingService.php b/app/Services/ForkingService.php index 015d89e8c..8397fe006 100644 --- a/app/Services/ForkingService.php +++ b/app/Services/ForkingService.php @@ -51,6 +51,8 @@ class ForkingService /** * Process backfill for all groups with backfill enabled. + * + * @param array $options */ public function backfill(array $options = []): void { @@ -175,6 +177,8 @@ class ForkingService * Generic work type processor for backwards compatibility. * * @deprecated Use specific methods instead (e.g., backfill(), binaries(), etc.) + * + * @param array $options */ public function processWorkType(string $type, array $options = []): void { diff --git a/app/Services/GamesService.php b/app/Services/GamesService.php index cb3806438..0277b655e 100644 --- a/app/Services/GamesService.php +++ b/app/Services/GamesService.php @@ -68,7 +68,7 @@ class GamesService protected string $_classUsed = ''; - protected $igdbSleep; + protected mixed $igdbSleep; /** * @throws \Exception @@ -150,7 +150,7 @@ class GamesService /** * Get paginated list of all games. */ - public function getRange(?string $search = null): LengthAwarePaginator + public function getRange(?string $search = null): LengthAwarePaginator // @phpstan-ignore missingType.generics { $query = GamesInfo::query() ->select(['gi.*', 'g.title as genretitle']) @@ -176,9 +176,13 @@ class GamesService /** * Get games range for browsing with filtering. * + * @param array $excludedCats + * @param array $orderBy + * @return array + * * @throws \Exception */ - public function getGamesRange($page, $cat, $start, $num, array|string $orderBy = '', string $maxAge = '', array $excludedCats = []): array + public function getGamesRange(mixed $page, mixed $cat, mixed $start, mixed $num, array|string $orderBy = '', string $maxAge = '', array $excludedCats = []): array { $page = max(1, $page); $start = max(0, $start); @@ -203,7 +207,7 @@ class GamesService $catsrch. $maxAge. $exccatlist. - ' GROUP BY gi.id ORDER BY '.($order[0]).' '.($order[1]). + ' GROUP BY gi.id ORDER BY '.($order[0]).' '.($order[1]). // @phpstan-ignore offsetAccess.notFound ($start === false ? '' : ' LIMIT '.$num.' OFFSET '.$start); $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium')); @@ -258,8 +262,8 @@ class GamesService (! empty($gameIDs) ? implode(',', $gameIDs) : -1), (! empty($releaseIDs) ? implode(',', $releaseIDs) : -1), $catsrch, - $order[0], - $order[1] + $order[0], // @phpstan-ignore offsetAccess.notFound + $order[1] // @phpstan-ignore offsetAccess.notFound ); $return = Cache::get(md5($returnSql.$page)); @@ -277,6 +281,9 @@ class GamesService /** * Get order array for games. + * + * @param array $orderBy + * @return array */ public function getGamesOrder(array|string $orderBy): array { @@ -298,6 +305,8 @@ class GamesService /** * Get ordering options. + * + * @return array */ public function getGamesOrdering(): array { @@ -310,6 +319,8 @@ class GamesService /** * Get browse by options. + * + * @return array */ public function getBrowseByOptions(): array { @@ -349,7 +360,7 @@ class GamesService ?string $asin, ?string $url, ?string $publisher, - $releaseDate, + mixed $releaseDate, ?string $esrb, int $cover, ?string $trailerUrl, @@ -372,6 +383,8 @@ class GamesService /** * Update game info from external APIs (Steam/IGDB). + * + * @param array $gameInfo */ public function updateGamesInfo(array $gameInfo): bool|int { @@ -449,6 +462,9 @@ class GamesService /** * Build game array from Steam data. + * + * @param array $steamResults + * @return array */ protected function buildGameFromSteam(array $steamResults, string &$genreName): array { @@ -488,6 +504,9 @@ class GamesService /** * Save game to database. + * + * @param array $game + * @param array $gameInfo */ protected function saveGameToDatabase(array $game, string $genreName, GenreService $gen, array $gameInfo, string $titleKey): bool|int { @@ -618,6 +637,9 @@ class GamesService /** * Save game info from cached data. + * + * @param array $game + * @param array $gameInfo */ protected function saveGameInfoFromCache(array $game, GenreService $gen, array $gameInfo): bool|int { @@ -760,6 +782,8 @@ class GamesService /** * Batch update release records with game IDs. + * + * @param array $updates */ protected function batchUpdateReleases(array $updates): void { @@ -815,6 +839,8 @@ class GamesService /** * Get processing statistics from the last run. + * + * @return array */ public function getProcessingStats(): array { diff --git a/app/Services/GenreService.php b/app/Services/GenreService.php index 98f84792b..317a83db1 100644 --- a/app/Services/GenreService.php +++ b/app/Services/GenreService.php @@ -22,7 +22,7 @@ class GenreService /** * Get genres with optional filtering and caching. */ - public function getGenres(string $type = '', bool $activeOnly = false): Collection + public function getGenres(string $type = '', bool $activeOnly = false): Collection // @phpstan-ignore missingType.generics { $cacheKey = 'genres_'.md5($type.'_'.($activeOnly ? '1' : '0')); @@ -33,6 +33,8 @@ class GenreService /** * Load genres as an associative array (id => lowercase title). + * + * @return array */ public function loadGenres(string $type): array { @@ -48,8 +50,10 @@ class GenreService /** * Get a range of genres with pagination. + * + * @return array */ - public function getRange(int $start, int $num, string $type = '', bool $activeOnly = false): Collection + public function getRange(int $start, int $num, string $type = '', bool $activeOnly = false): Collection // @phpstan-ignore missingType.generics { return Genre::getFiltered($type, $activeOnly) ->skip($start) @@ -85,7 +89,7 @@ class GenreService /** * Get all disabled genre IDs. */ - public function getDisabledIDs(): Collection + public function getDisabledIDs(): Collection // @phpstan-ignore missingType.generics { return Cache::remember('disabled_genres', now()->addMinutes(config('nntmux.cache_expiry_long')), function () { return Genre::disabled()->get(['id']); diff --git a/app/Services/IGDBService.php b/app/Services/IGDBService.php index e1dca5426..9dae626ae 100644 --- a/app/Services/IGDBService.php +++ b/app/Services/IGDBService.php @@ -94,20 +94,21 @@ class IGDBService /** * Get complete game details from a Game object. * - * @return array{ - * title: string, - * asin: string, - * review: string, - * coverurl: string, - * releasedate: string, - * esrb: string, - * url: string, - * backdropurl: string, - * trailer: string, - * publisher: string, - * developer: string, - * genres: array, - * }|false + * @return array + * title: string, + * asin: string, + * review: string, + * coverurl: string, + * releasedate: string, + * esrb: string, + * url: string, + * backdropurl: string, + * trailer: string, + * publisher: string, + * developer: string, + * genres: array, + * }|false + * @return array */ public function getGameDetails(Game $game): array|false { @@ -228,6 +229,8 @@ class IGDBService /** * Get relations to load with IGDB queries. + * + * @return array */ protected function getGameRelations(): array { @@ -251,7 +254,7 @@ class IGDBService /** * Find the best matching game from results. */ - protected function findBestMatch($results, string $title): ?Game + protected function findBestMatch(mixed $results, string $title): ?Game { $bestMatch = null; $bestScore = 0; @@ -300,6 +303,8 @@ class IGDBService /** * Build game data array from IGDB Game model. + * + * @return array */ public function buildGameData(Game $game, string &$genreName): array { @@ -352,7 +357,7 @@ class IGDBService $gameUrl = $game->url ?? ('https://www.igdb.com/games/'.($game->slug ?? $game->id)); // @phpstan-ignore property.notFound // Build review text - $review = $this->buildReview($game, $developers); + $review = $this->buildReview($game, $developers); // @phpstan-ignore argument.type Log::info('IGDBService: Game data built', [ 'title' => $game->name, // @phpstan-ignore property.notFound @@ -380,6 +385,8 @@ class IGDBService /** * Extract genres from game data. + * + * @return array */ protected function extractGenres(Game $game): array { @@ -410,6 +417,9 @@ class IGDBService /** * Get properly formatted IGDB image URL. + * + * @param array $imageData + * @return array, mixed> */ public function getImageUrl(array|object|null $imageData, string $size = 'cover_big'): string { @@ -568,6 +578,8 @@ class IGDBService /** * Build review/summary text. + * + * @param array $developers */ protected function buildReview(Game $game, array $developers): string { diff --git a/app/Services/IRCClient.php b/app/Services/IRCClient.php index cc3282154..094d3c6bd 100644 --- a/app/Services/IRCClient.php +++ b/app/Services/IRCClient.php @@ -81,6 +81,8 @@ class IRCClient * );. * * @note Used with the processChannelMessages() function. + * + * @var array */ protected array $_channelData = []; @@ -106,6 +108,8 @@ class IRCClient /** * List of channels and passwords to join. + * + * @var array */ protected array $_channels; @@ -144,7 +148,7 @@ class IRCClient * * @param int $timeout Seconds. */ - public function setSocketTimeout(int $timeout) + public function setSocketTimeout(int $timeout): void { $this->_socket_timeout = $timeout; } @@ -154,7 +158,7 @@ class IRCClient * * @param int $timeout Seconds. */ - public function setConnectionTimeout(int $timeout) + public function setConnectionTimeout(int $timeout): void { $this->_remote_connection_timeout = $timeout; } @@ -162,7 +166,7 @@ class IRCClient /** * Amount of times to retry before giving up when connecting. */ - public function setConnectionRetries(int $retries) + public function setConnectionRetries(int $retries): void { $this->_reconnectRetries = $retries; } @@ -172,7 +176,7 @@ class IRCClient * * @param int $delay Seconds. */ - public function setReConnectDelay(int $delay) + public function setReConnectDelay(int $delay): void { $this->_reconnectDelay = $delay; } @@ -368,8 +372,8 @@ class IRCClient /** * Join a channel or multiple channels. * - * @param array $channels Array of channels with their passwords (null if the channel doesn't need a password). - * array( '#exampleChannel' => 'thePassword', '#exampleChan2' => null ); + * @param array $channels Array of channels with their passwords (null if the channel doesn't need a password). + * array( '#exampleChannel' => 'thePassword', '#exampleChan2' => null ); */ public function joinChannels(array $channels = []): bool { @@ -394,7 +398,7 @@ class IRCClient * Implementation. * Extended classes will use this function to parse the messages in the channel using $this->_channelData. */ - protected function processChannelMessages() {} + protected function processChannelMessages(): void {} /** * Join a channel. diff --git a/app/Services/IRCScraper.php b/app/Services/IRCScraper.php index 9851dc32d..7bf4417a7 100644 --- a/app/Services/IRCScraper.php +++ b/app/Services/IRCScraper.php @@ -20,16 +20,22 @@ class IRCScraper extends IRCClient /** * Array of current pre info. + * + * @var array */ protected array $_curPre; /** * List of groups and their id's. + * + * @var array */ protected array $_groupList; /** * Array of ignored channels. + * + * @var array */ protected array $_ignoredChannels; @@ -38,7 +44,7 @@ class IRCScraper extends IRCClient */ protected bool $_nuked; - protected $_oldPre; + protected mixed $_oldPre; /** * Run this in silent mode (no text output). diff --git a/app/Services/ImdbScraper.php b/app/Services/ImdbScraper.php index a5e394678..d51f7f8e7 100644 --- a/app/Services/ImdbScraper.php +++ b/app/Services/ImdbScraper.php @@ -25,6 +25,7 @@ class ImdbScraper * Fetch a movie by IMDB numeric ID. * * @param string $id Numeric part without 'tt'. + * @return array */ public function fetchById(string $id): array|false { @@ -173,6 +174,8 @@ class ImdbScraper /** * Search IMDb suggestion API for a title. + * + * @return array */ public function search(string $query): array { @@ -213,7 +216,7 @@ class ImdbScraper } Cache::put($cacheKey, $results, now()->addHours(12)); - return $results; + return $results; // @phpstan-ignore return.type } catch (\Throwable $e) { Log::debug('IMDb search error '.$query.': '.$e->getMessage()); Cache::put($cacheKey, [], now()->addHours(6)); diff --git a/app/Services/InvitationService.php b/app/Services/InvitationService.php index 297da5bf6..0959887d5 100644 --- a/app/Services/InvitationService.php +++ b/app/Services/InvitationService.php @@ -13,6 +13,8 @@ class InvitationService { /** * Create and send an invitation + * + * @param array $metadata */ public function createAndSendInvitation( string $email, @@ -108,6 +110,8 @@ class InvitationService /** * Accept an invitation (use it for registration) + * + * @param array $userData */ public function acceptInvitation(string $token, array $userData): User { @@ -139,6 +143,8 @@ class InvitationService /** * Get invitation statistics for a user + * + * @return array */ public function getUserInvitationStats(int $userId): array { @@ -153,7 +159,7 @@ class InvitationService /** * Get all invitations for a user */ - public function getUserInvitations(int $userId, ?string $status = null) + public function getUserInvitations(int $userId, ?string $status = null): mixed { $query = Invitation::where('invited_by', $userId) ->with(['usedBy']) @@ -192,6 +198,8 @@ class InvitationService /** * Get invitation by token for preview + * + * @return array */ public function getInvitationPreview(string $token): ?array { @@ -214,6 +222,8 @@ class InvitationService /** * Get detailed invitation information for a user (for debugging) + * + * @return array */ public function getUserInvitationDetails(int $userId): array { diff --git a/app/Services/ItunesService.php b/app/Services/ItunesService.php index 739ce10dd..3a9fb134c 100644 --- a/app/Services/ItunesService.php +++ b/app/Services/ItunesService.php @@ -61,6 +61,8 @@ class ItunesService /** * Search for music albums. + * + * @return array */ public function searchAlbums(string $term): ?array { @@ -69,6 +71,8 @@ class ItunesService /** * Search for music tracks. + * + * @return array */ public function searchTracks(string $term): ?array { @@ -77,6 +81,8 @@ class ItunesService /** * Search for artists. + * + * @return array */ public function searchArtists(string $term): ?array { @@ -85,6 +91,8 @@ class ItunesService /** * Search for ebooks. + * + * @return array */ public function searchEbooks(string $term): ?array { @@ -93,6 +101,8 @@ class ItunesService /** * Search for audiobooks. + * + * @return array */ public function searchAudiobooks(string $term): ?array { @@ -101,6 +111,8 @@ class ItunesService /** * Lookup by iTunes ID. + * + * @return array */ public function lookupById(int $id): ?array { @@ -144,6 +156,8 @@ class ItunesService /** * Lookup artist by ID. + * + * @return array */ public function lookupArtist(int $artistId): ?array { @@ -153,7 +167,7 @@ class ItunesService /** * Get the first album result for a search term. * - * @return array|null Normalized album data or null + * @return array|null Normalized album data or null */ public function findAlbum(string $term): ?array { @@ -163,13 +177,13 @@ class ItunesService return null; } - return $this->normalizeAlbumResult($results[0]); + return $this->normalizeAlbumResult($results[0]); // @phpstan-ignore offsetAccess.notFound } /** * Get the first track result for a search term. * - * @return array|null Normalized track data or null + * @return array|null Normalized track data or null */ public function findTrack(string $term): ?array { @@ -179,13 +193,13 @@ class ItunesService return null; } - return $this->normalizeTrackResult($results[0]); + return $this->normalizeTrackResult($results[0]); // @phpstan-ignore offsetAccess.notFound } /** * Get the first ebook result for a search term. * - * @return array|null Normalized ebook data or null + * @return array|null Normalized ebook data or null */ public function findEbook(string $term): ?array { @@ -195,11 +209,13 @@ class ItunesService return null; } - return $this->normalizeEbookResult($results[0]); + return $this->normalizeEbookResult($results[0]); // @phpstan-ignore offsetAccess.notFound } /** * Perform a search request to iTunes API. + * + * @return array */ protected function search(string $term, string $entity, string $media): ?array { @@ -252,6 +268,9 @@ class ItunesService /** * Normalize album result to consistent format. + * + * @param array $result + * @return array */ protected function normalizeAlbumResult(array $result): array { @@ -275,6 +294,9 @@ class ItunesService /** * Normalize track result to consistent format. + * + * @param array $result + * @return array */ protected function normalizeTrackResult(array $result): array { @@ -300,6 +322,9 @@ class ItunesService /** * Normalize ebook result to consistent format. + * + * @param array $result + * @return array */ protected function normalizeEbookResult(array $result): array { diff --git a/app/Services/MediaProcessingService.php b/app/Services/MediaProcessingService.php index 986d37c18..35f6f521e 100644 --- a/app/Services/MediaProcessingService.php +++ b/app/Services/MediaProcessingService.php @@ -241,6 +241,9 @@ class MediaProcessingService } } + /** + * @return array + */ public function addAudioInfoAndSample( Release $release, string $fileLocation, diff --git a/app/Services/MovieBrowseService.php b/app/Services/MovieBrowseService.php index 499f6c931..1dbe98c84 100644 --- a/app/Services/MovieBrowseService.php +++ b/app/Services/MovieBrowseService.php @@ -22,13 +22,16 @@ class MovieBrowseService /** * Get movie releases with covers for movie browse page. + * + * @param array $cat + * @param array $excludedCats */ public function getMovieRange(int $page, array $cat, int $start, int $num, string $orderBy, int $maxAge = -1, array $excludedCats = []): mixed { $page = max(1, $page); $start = max(0, $start); $catsrch = ''; - if (count($cat) > 0 && $cat[0] !== -1) { + if (count($cat) > 0 && $cat[0] !== -1) { // @phpstan-ignore offsetAccess.notFound $catsrch = Category::getCategorySearch($cat); } $order = $this->getMovieOrder($orderBy); @@ -43,7 +46,7 @@ class MovieBrowseService .(! empty($catsrch) ? $catsrch.' ' : '') .$whereAge .$whereExcluded.' ' - ."GROUP BY m.imdbid ORDER BY {$order[0]} {$order[1]} {$limitClause}"; + ."GROUP BY m.imdbid ORDER BY {$order[0]} {$order[1]} {$limitClause}"; // @phpstan-ignore offsetAccess.notFound $movieCache = Cache::get(md5($moviesSql.$page)); if ($movieCache !== null) { $movies = $movieCache; @@ -90,7 +93,7 @@ class MovieBrowseService .'INNER JOIN movieinfo m ON m.imdbid = r.imdbid ' ."WHERE m.imdbid IN ($inMovieIds) AND r.id IN ($inReleaseIds) " .(! empty($catsrch) ? $catsrch.' ' : '') - ."GROUP BY m.imdbid ORDER BY {$order[0]} {$order[1]}"; + ."GROUP BY m.imdbid ORDER BY {$order[0]} {$order[1]}"; // @phpstan-ignore offsetAccess.notFound $return = Cache::get(md5($sql.$page)); if ($return !== null) { return $return; @@ -106,6 +109,8 @@ class MovieBrowseService /** * Get the order type the user requested on the movies page. + * + * @return array */ protected function getMovieOrder(string $orderBy): array { @@ -122,6 +127,8 @@ class MovieBrowseService /** * Order types for movies page. + * + * @return array */ public function getMovieOrdering(): array { @@ -151,6 +158,8 @@ class MovieBrowseService /** * Get IMDB genres. + * + * @return array */ public function getGenres(): array { diff --git a/app/Services/MovieService.php b/app/Services/MovieService.php index d24e9c9a8..53ae02115 100644 --- a/app/Services/MovieService.php +++ b/app/Services/MovieService.php @@ -138,6 +138,8 @@ class MovieService /** * Parse trakt info, insert into DB. + * + * @param array $data */ public function parseTraktTv(array &$data): mixed { @@ -191,6 +193,8 @@ class MovieService /** * Get array of column keys, for inserting / updating. + * + * @return array */ public function getColumnKeys(): array { @@ -202,6 +206,13 @@ class MovieService /** * Choose the first non-empty variable from up to five inputs. + * + * @param array $variable1 + * @param array $variable2 + * @param array $variable3 + * @param array $variable4 + * @param array $variable5 + * @return array */ protected function setVariables(string|array $variable1, string|array $variable2, string|array $variable3, string|array $variable4, string|array $variable5 = ''): array|string { @@ -226,6 +237,8 @@ class MovieService /** * Update movie on movie-edit page. + * + * @param array $values */ public function update(array $values): bool { @@ -475,6 +488,8 @@ class MovieService /** * Fetch FanArt.tv backdrop / cover / title. + * + * @return array */ protected function fetchFanartTVProperties(string $imdbId): false|array { @@ -501,6 +516,8 @@ class MovieService /** * Fetch movie information from TMDB using an IMDB ID. + * + * @return array */ public function fetchTMDBProperties(string $imdbId, bool $text = false): array|false { @@ -520,7 +537,7 @@ class MovieService return false; } - $tmdbLookup = $tmdbClient->getMovie($lookupId, ['credits']); + $tmdbLookup = $tmdbClient->getMovie($lookupId, ['credits']); // @phpstan-ignore argument.type if ($tmdbLookup === null || empty($tmdbLookup)) { Cache::put($cacheKey, false, $expiresAt); @@ -643,6 +660,8 @@ class MovieService /** * Fetch movie information from IMDB. + * + * @return array */ public function fetchIMDBProperties(string $imdbId): array|false { @@ -692,6 +711,8 @@ class MovieService /** * Fetch movie information from Trakt.tv using IMDB ID. * + * @return array + * * @throws GuzzleException */ public function fetchTraktTVProperties(string $imdbId): array|false @@ -766,6 +787,8 @@ class MovieService /** * Fetch movie information from OMDB API using IMDB ID. + * + * @return array */ public function fetchOmdbAPIProperties(string $imdbId): array|false { @@ -1293,6 +1316,8 @@ class MovieService /** * Get IMDB genres. + * + * @return array */ public function getGenres(): array { diff --git a/app/Services/MusicService.php b/app/Services/MusicService.php index 2d17c3302..0985108b9 100644 --- a/app/Services/MusicService.php +++ b/app/Services/MusicService.php @@ -36,6 +36,8 @@ class MusicService /** * Store names of failed lookup items. + * + * @var array */ public array $failCache; @@ -87,6 +89,9 @@ class MusicService /** * Get paginated music range for browsing. + * + * @param array $cat + * @param array $excludedCats */ public function getMusicRange(int $page, array $cat, int $start, int $num, string $orderBy, array $excludedCats = []): mixed { @@ -95,7 +100,7 @@ class MusicService $browseby = $this->getBrowseBy(); $catsrch = ''; - if (\count($cat) > 0 && (int) $cat[0] !== -1) { + if (\count($cat) > 0 && (int) $cat[0] !== -1) { // @phpstan-ignore offsetAccess.notFound $catsrch = Category::getCategorySearch($cat); } $exccatlist = ''; @@ -125,8 +130,8 @@ class MusicService $browseby, $catsrch, $exccatlist, - $order[0], - $order[1], + $order[0], // @phpstan-ignore offsetAccess.notFound + $order[1], // @phpstan-ignore offsetAccess.notFound ($start === false ? '' : ' LIMIT '.$num.' OFFSET '.$start) ); @@ -186,8 +191,8 @@ class MusicService ! empty($musicIDs) ? 'WHERE m.id IN ('.implode(',', $musicIDs).')' : 'AND 1=1', (! empty($releaseIDs)) ? 'AND r.id in ('.implode(',', $releaseIDs).')' : '', $catsrch, - $order[0], - $order[1] + $order[0], // @phpstan-ignore offsetAccess.notFound + $order[1] // @phpstan-ignore offsetAccess.notFound ); $return = Cache::get(md5($sql.$page)); @@ -206,6 +211,8 @@ class MusicService /** * Parse order by parameter and return order field and direction. + * + * @return array */ public function getMusicOrder(string $orderBy): array { @@ -244,6 +251,8 @@ class MusicService /** * Get available ordering options. + * + * @return array */ public function getMusicOrdering(): array { @@ -260,6 +269,8 @@ class MusicService /** * Get browse by options. + * + * @return array */ public function getBrowseByOptions(): array { @@ -321,6 +332,8 @@ class MusicService /** * Update or create music info from external data. * + * @param array $amazdata + * * @throws \Exception */ public function updateMusicInfo(string $title, string $year, ?array $amazdata = null): int|false @@ -484,6 +497,8 @@ class MusicService /** * Parse artist and album name from release name. + * + * @return array */ public function parseArtist(string $releaseName): array|false { @@ -620,6 +635,8 @@ class MusicService /** * Fetch music properties from iTunes. + * + * @return array */ protected function fetchItunesMusicProperties(string $title): array|false { diff --git a/app/Services/NNTP/NNTPService.php b/app/Services/NNTP/NNTPService.php index 4551f8dff..fae8f21e9 100644 --- a/app/Services/NNTP/NNTPService.php +++ b/app/Services/NNTP/NNTPService.php @@ -475,7 +475,7 @@ class NNTPService extends \Net_NNTP_Client * All newer than article number: "679871775-" * All older than article number: "-679871775" * Message-ID: "" - * @return array|string|NNTPService Multi-dimensional Array of headers on success, PEAR object on failure. + * @return array|string|NNTPService Multi-dimensional Array of headers on success, PEAR object on failure. * * @throws \Exception */ @@ -559,7 +559,7 @@ class NNTPService extends \Net_NNTP_Client * Returns a list of valid groups (that the client is permitted to select) and associated information. * * @param mixed $wildMat (optional) http://tools.ietf.org/html/rfc3977#section-4 - * @return array|string Pear error on failure, array with groups on success. + * @return array|string Pear error on failure, array with groups on success. * * @throws \Exception */ @@ -909,8 +909,8 @@ class NNTPService extends \Net_NNTP_Client * of their _getTextResponse function since it is incompatible at decoding * headers when XFeature GZip compression is enabled server side. * - * @return \App\Services\NNTP\NNTPService|array|string Our overridden function when compression is enabled. - * parent Parent function when no compression. + * @return \App\Services\NNTP\NNTPService|array|string Our overridden function when compression is enabled. + * parent Parent function when no compression. */ public function _getTextResponse(): NNTPService|array|string { @@ -933,9 +933,9 @@ class NNTPService extends \Net_NNTP_Client * Have we failed to decompress the data, was there a * problem downloading the data, etc.. * - * @return array|string On success : (array) The headers. - * On failure : (object) PEAR_Error. - * On decompress failure: (string) error message + * @return array|string On success : (array) The headers. + * On failure : (object) PEAR_Error. + * On decompress failure: (string) error message */ protected function &_getXFeatureTextResponse(): array|string { @@ -981,7 +981,7 @@ class NNTPService extends \Net_NNTP_Client // Split the string of headers into an array of individual headers, then return it. $deComp = explode("\r\n", trim($deComp)); - return $deComp; + return $deComp; // @phpstan-ignore return.type } $message = 'Decompression of OVER headers failed.'; diff --git a/app/Services/NameFixing/DTO/NameFixResult.php b/app/Services/NameFixing/DTO/NameFixResult.php index b5e5728b8..6225719cf 100644 --- a/app/Services/NameFixing/DTO/NameFixResult.php +++ b/app/Services/NameFixing/DTO/NameFixResult.php @@ -12,6 +12,9 @@ namespace App\Services\NameFixing\DTO; */ final class NameFixResult { + /** + * @param array $metadata + */ public function __construct( public readonly string $newName, public readonly string $method, diff --git a/app/Services/NameFixing/FilePrioritizer.php b/app/Services/NameFixing/FilePrioritizer.php index 1ed0b4e75..31fef9cc3 100644 --- a/app/Services/NameFixing/FilePrioritizer.php +++ b/app/Services/NameFixing/FilePrioritizer.php @@ -47,8 +47,8 @@ class FilePrioritizer * 5. NFO files * 6. Other files * - * @param array $files Array of filenames - * @return array Sorted array of filenames + * @param array $files Array of filenames + * @return array Sorted array of filenames */ public function prioritizeForMatching(array $files): array { @@ -71,8 +71,8 @@ class FilePrioritizer * Similar to prioritizeForMatching but with slightly different priorities * optimized for PreDB filename lookups. * - * @param array $files Array of filenames - * @return array Sorted array of filenames + * @param array $files Array of filenames + * @return array Sorted array of filenames */ public function prioritizeForPreDb(array $files): array { @@ -91,8 +91,8 @@ class FilePrioritizer /** * Categorize files into groups by type. * - * @param array $files Array of filenames - * @return array Categorized files + * @param array $files Array of filenames + * @return array Categorized files */ protected function categorizeFiles(array $files): array { @@ -230,7 +230,7 @@ class FilePrioritizer * Analyzes multiple RAR files from a release to determine the most likely * release name by finding common patterns. * - * @param array $rarFiles Array of RAR filenames + * @param array $rarFiles Array of RAR filenames * @return string|null The most likely release name or null */ public function findReleaseNameFromRarFiles(array $rarFiles): ?string diff --git a/app/Services/NameFixing/NameCheckerService.php b/app/Services/NameFixing/NameCheckerService.php index 4de1f8a6b..21f3faac6 100644 --- a/app/Services/NameFixing/NameCheckerService.php +++ b/app/Services/NameFixing/NameCheckerService.php @@ -136,6 +136,8 @@ class NameCheckerService /** * Get checker statistics. + * + * @return array */ public function getStats(): array { diff --git a/app/Services/NameFixing/NameFixingService.php b/app/Services/NameFixing/NameFixingService.php index a13e5a5f5..f78941bdc 100644 --- a/app/Services/NameFixing/NameFixingService.php +++ b/app/Services/NameFixing/NameFixingService.php @@ -254,7 +254,7 @@ class NameFixingService $this->updateService->incrementChecked(); // Prioritize files for matching - $prioritizedFiles = $this->filePrioritizer->prioritizeForMatching($data['files']); + $prioritizedFiles = $this->filePrioritizer->prioritizeForMatching($data['files']); // @phpstan-ignore argument.type foreach ($prioritizedFiles as $filename) { /** @var Release $release */ @@ -845,8 +845,10 @@ class NameFixingService /** * Get releases based on time and category parameters. + * + * @return Collection */ - protected function getReleases(int $time, int $cats, string $query, int $limit = 0): \Illuminate\Database\Eloquent\Collection|bool + protected function getReleases(int $time, int $cats, string $query, int $limit = 0): \Illuminate\Database\Eloquent\Collection|bool // @phpstan-ignore class.notFound, missingType.generics, return.phpDocType { $releases = false; $queryLimit = ($limit === 0) ? '' : ' LIMIT '.$limit; @@ -1263,7 +1265,7 @@ class NameFixingService $matching = 0; $files = explode('||', $release->filename ?? ''); - $prioritizedFiles = $this->filePrioritizer->prioritizeForPreDb($files); + $prioritizedFiles = $this->filePrioritizer->prioritizeForPreDb($files); // @phpstan-ignore argument.type foreach ($prioritizedFiles as $fileName) { $cleanedFileName = $this->fileNameCleaner->cleanForMatching($fileName); @@ -1302,6 +1304,8 @@ class NameFixingService /** * Pre-match check for filename patterns. + * + * @return array */ protected function preMatch(string $fileName): array { @@ -1330,6 +1334,8 @@ class NameFixingService /** * Retrieves releases and their file names to attempt PreDB matches. * + * @param array $args + * * @throws \Exception */ public function getPreFileNames(array $args = []): void diff --git a/app/Services/NameFixing/Patterns/AppPatterns.php b/app/Services/NameFixing/Patterns/AppPatterns.php index bf802fff6..c6d286ea4 100644 --- a/app/Services/NameFixing/Patterns/AppPatterns.php +++ b/app/Services/NameFixing/Patterns/AppPatterns.php @@ -114,6 +114,8 @@ final class AppPatterns /** * Get all patterns in priority order. + * + * @return array */ public static function getAllPatterns(): array { @@ -130,6 +132,8 @@ final class AppPatterns /** * Get platform-specific patterns. + * + * @return array */ public static function getPlatformPatterns(): array { @@ -142,6 +146,8 @@ final class AppPatterns /** * Get vendor-specific patterns. + * + * @return array */ public static function getVendorPatterns(): array { diff --git a/app/Services/NameFixing/Patterns/GamePatterns.php b/app/Services/NameFixing/Patterns/GamePatterns.php index 3a51a0499..f82bb516a 100644 --- a/app/Services/NameFixing/Patterns/GamePatterns.php +++ b/app/Services/NameFixing/Patterns/GamePatterns.php @@ -139,6 +139,8 @@ final class GamePatterns /** * Get all patterns in priority order. + * + * @return array */ public static function getAllPatterns(): array { @@ -157,6 +159,8 @@ final class GamePatterns /** * Get console patterns only. + * + * @return array */ public static function getConsolePatterns(): array { @@ -169,6 +173,8 @@ final class GamePatterns /** * Get PC game patterns only. + * + * @return array */ public static function getPCPatterns(): array { diff --git a/app/Services/NameFixing/Patterns/MoviePatterns.php b/app/Services/NameFixing/Patterns/MoviePatterns.php index e3920c010..6c5e43738 100644 --- a/app/Services/NameFixing/Patterns/MoviePatterns.php +++ b/app/Services/NameFixing/Patterns/MoviePatterns.php @@ -103,6 +103,8 @@ final class MoviePatterns /** * Get all patterns in priority order. + * + * @return array */ public static function getAllPatterns(): array { @@ -123,6 +125,8 @@ final class MoviePatterns /** * Get 4K/UHD patterns only. + * + * @return array */ public static function get4KPatterns(): array { diff --git a/app/Services/NameFixing/Patterns/TvPatterns.php b/app/Services/NameFixing/Patterns/TvPatterns.php index 03394189a..8ab9aa711 100644 --- a/app/Services/NameFixing/Patterns/TvPatterns.php +++ b/app/Services/NameFixing/Patterns/TvPatterns.php @@ -124,6 +124,8 @@ final class TvPatterns /** * Get streaming service patterns only. + * + * @return array */ public static function getStreamingPatterns(): array { @@ -135,6 +137,8 @@ final class TvPatterns /** * Get standard TV patterns. + * + * @return array */ public static function getStandardPatterns(): array { diff --git a/app/Services/NameFixing/ReleaseUpdateService.php b/app/Services/NameFixing/ReleaseUpdateService.php index e394164e1..08a04810d 100644 --- a/app/Services/NameFixing/ReleaseUpdateService.php +++ b/app/Services/NameFixing/ReleaseUpdateService.php @@ -103,7 +103,7 @@ class ReleaseUpdateService /** * Update the release with the new information. * - * @param object|array $release The release to update + * @param object|array $release The release to update * @param string $name The new name * @param string $method The method that found the name * @param bool $echo Whether to actually update the database @@ -207,6 +207,8 @@ class ReleaseUpdateService /** * Echo release information to CLI. + * + * @param array $determinedCategory */ public function echoReleaseInfo( object $release, @@ -251,6 +253,8 @@ class ReleaseUpdateService /** * Perform the actual database update. + * + * @param array $determinedCategory */ protected function performDatabaseUpdate( object $release, @@ -309,6 +313,8 @@ class ReleaseUpdateService /** * Get the status columns to update for a given type. + * + * @return array */ protected function getStatusColumnsForType(string $type): array { @@ -338,6 +344,8 @@ class ReleaseUpdateService /** * Check if a release matches a PreDB entry. + * + * @return array */ public function checkPreDbMatch(object $release, string $textstring): ?array { @@ -373,6 +381,8 @@ class ReleaseUpdateService /** * Get the current statistics. + * + * @return array */ public function getStats(): array { diff --git a/app/Services/NfoService.php b/app/Services/NfoService.php index 2170ecea1..06786b196 100644 --- a/app/Services/NfoService.php +++ b/app/Services/NfoService.php @@ -50,8 +50,10 @@ class NfoService /** * Common NFO keywords that help identify legitimate NFO files. + * + * @var array */ - protected array $_nfoKeywords = [ + protected array $_nfoKeywords = [ // @phpstan-ignore property.defaultValue // Release information 'release', 'group', 'date', 'size', 'format', 'source', 'genre', 'codec', 'bitrate', 'resolution', 'language', 'subtitle', 'ripped', 'cracked', @@ -76,8 +78,10 @@ class NfoService /** * Scene group patterns for improved detection. + * + * @var array */ - protected array $_sceneGroupPatterns = [ + protected array $_sceneGroupPatterns = [ // @phpstan-ignore property.defaultValue '/(?:^|\n)\s*[-=*]{3,}.*?([A-Z0-9]{2,15})\s*[-=*]{3,}/i', '/(?:presents?|brought\s+(?:to\s+)?(?:you\s+)?by|from)\s*[:\-]?\s*([A-Z][A-Z0-9]{1,14})/i', '/(?:greets?\s+(?:go(?:es)?\s+)?(?:out\s+)?to|respect\s+to)\s*[:\-]?\s*([\w,\s&]+)/i', @@ -459,7 +463,7 @@ class NfoService * * @throws \Exception */ - public function addAlternateNfo(bool|string &$nfo, $release, NNTPService $nntp): bool + public function addAlternateNfo(bool|string &$nfo, mixed $release, NNTPService $nntp): bool { if ($release->id > 0 && $this->isNFO($nfo, $release->guid)) { $check = ReleaseNfo::whereReleasesId($release->id)->first(['releases_id']); @@ -584,8 +588,10 @@ class NfoService /** * Build base query for NFO processing with all common filters + * + * @return Builder */ - private function buildNfoProcessingQuery(string $groupID, string $guidChar): \Illuminate\Database\Eloquent\Builder + private function buildNfoProcessingQuery(string $groupID, string $guidChar): \Illuminate\Database\Eloquent\Builder // @phpstan-ignore class.notFound, missingType.generics, return.phpDocType { $query = Release::query() ->whereBetween('nfostatus', [$this->maxRetries, self::NFO_UNPROC]); @@ -627,7 +633,7 @@ class NfoService /** * Display statistics about NFO status counts */ - private function displayNfoStatusStats(\Illuminate\Database\Eloquent\Builder $baseQuery): void + private function displayNfoStatusStats(\Illuminate\Database\Eloquent\Builder $baseQuery): void // @phpstan-ignore missingType.generics { $nfoStats = $baseQuery->clone() ->select(['nfostatus as status', DB::raw('COUNT(id) as count')]) @@ -712,7 +718,7 @@ class NfoService * Extract URLs from NFO content. * * @param string $nfoContent The NFO content to parse. - * @return array Array of found URLs. + * @return array Array of found URLs. */ public function extractUrls(string $nfoContent): array { @@ -743,7 +749,7 @@ class NfoService * - Footer signatures * * @param string $nfoContent The NFO content to parse. - * @return string|null The group name if found, null otherwise. + * @return array, string> */ public function extractGroupName(string $nfoContent): ?string { @@ -929,7 +935,7 @@ class NfoService * Extract all media IDs (IMDB, TVDB, TMDB, etc.) from NFO content. * * @param string $nfoContent The NFO content to parse. - * @return array Array of media IDs with their sources. + * @return array Array of media IDs with their sources. */ public function extractAllMediaIds(string $nfoContent): array { @@ -991,7 +997,7 @@ class NfoService * Parse and extract comprehensive metadata from NFO content. * * @param string $nfoContent The NFO content to parse. - * @return array Associative array with extracted metadata. + * @return list> */ public function parseNfoMetadata(string $nfoContent): array { @@ -1015,7 +1021,7 @@ class NfoService * Extract language information from NFO content. * * @param string $nfoContent The NFO content to parse. - * @return array Array of detected languages. + * @return array Array of detected languages. */ public function extractLanguage(string $nfoContent): array { @@ -1055,7 +1061,7 @@ class NfoService * Extract runtime/duration from NFO content. * * @param string $nfoContent The NFO content to parse. - * @return int|null Runtime in minutes, or null if not found. + * @return list */ public function extractRuntime(string $nfoContent): ?int { @@ -1093,7 +1099,7 @@ class NfoService * Extract genre information from NFO content. * * @param string $nfoContent The NFO content to parse. - * @return array Array of detected genres. + * @return array Array of detected genres. */ public function extractGenre(string $nfoContent): array { @@ -1129,7 +1135,7 @@ class NfoService * Extract software-specific information from NFO content. * * @param string $nfoContent The NFO content to parse. - * @return array Software info including platform, version, protection, etc. + * @return list */ public function extractSoftwareInfo(string $nfoContent): array { diff --git a/app/Services/Nzb/NzbContentsService.php b/app/Services/Nzb/NzbContentsService.php index c99eac073..8b3398c42 100644 --- a/app/Services/Nzb/NzbContentsService.php +++ b/app/Services/Nzb/NzbContentsService.php @@ -117,7 +117,7 @@ class NzbContentsService * @param int $relID The release ID. * @param int $groupID The group ID. * @param bool $nfoCheck Whether to specifically look for an NFO file. - * @return array|false An array containing NFO message ID and hidden status, or false if not found/error. + * @return array|false An array containing NFO message ID and hidden status, or false if not found/error. * * @throws \Exception If NNTP operations fail. */ diff --git a/app/Services/Nzb/NzbImportService.php b/app/Services/Nzb/NzbImportService.php index 20672a204..0a61ba76d 100644 --- a/app/Services/Nzb/NzbImportService.php +++ b/app/Services/Nzb/NzbImportService.php @@ -31,6 +31,8 @@ class NzbImportService /** * List of all the group names/ids in the DB. + * + * @var array */ protected array $allGroups; @@ -58,6 +60,9 @@ class NzbImportService */ protected string $nzbGuid; + /** + * @param array $options + */ public function __construct(array $options = []) { $this->echoCLI = config('nntmux.echocli'); @@ -77,7 +82,7 @@ class NzbImportService * * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException */ - public function beginImport($filesToProcess, bool $useNzbName = false, bool $delete = false, bool $deleteFailed = false, int $source = 1): bool|string + public function beginImport(mixed $filesToProcess, bool $useNzbName = false, bool $delete = false, bool $deleteFailed = false, int $source = 1): bool|string { // Get all the groups in the DB. if (! $this->getAllGroups()) { @@ -221,7 +226,7 @@ class NzbImportService * * @throws \Exception */ - protected function scanNZBFile(&$nzbXML, $nzbFileName = '', $source = ''): bool + protected function scanNZBFile(mixed &$nzbXML, mixed $nzbFileName = '', mixed $source = ''): bool { $binary_names = []; $totalFiles = $totalSize = $groupID = 0; @@ -306,14 +311,14 @@ class NzbImportService $this->echoOut($errorMessage); // Persist blacklist usage stats if we matched any rule during this NZB processing - $this->blacklistService->updateBlacklistUsage($this->blacklistService->getAndClearIdsToUpdate()); + $this->blacklistService->updateBlacklistUsage($this->blacklistService->getAndClearIdsToUpdate()); // @phpstan-ignore argument.type return false; } } // After scanning all files, persist any matched whitelist/blacklist usage - $this->blacklistService->updateBlacklistUsage($this->blacklistService->getAndClearIdsToUpdate()); + $this->blacklistService->updateBlacklistUsage($this->blacklistService->getAndClearIdsToUpdate()); // @phpstan-ignore argument.type // Sort values alphabetically but keep the keys intact if (\count($binary_names) > 0) { @@ -346,7 +351,7 @@ class NzbImportService * * @throws \Exception */ - protected function insertNZB($nzbDetails): bool + protected function insertNZB(mixed $nzbDetails): bool { // Make up a GUID for the release. $this->relGuid = Str::uuid()->toString(); diff --git a/app/Services/Nzb/NzbParserService.php b/app/Services/Nzb/NzbParserService.php index a047cf6bc..2311fc9d2 100644 --- a/app/Services/Nzb/NzbParserService.php +++ b/app/Services/Nzb/NzbParserService.php @@ -15,10 +15,10 @@ class NzbParserService * file extensions, file sizes, file completion, group names, # of parts). * * @param string $nzb The NZB contents in a string. - * @param array $options Optional settings: - * - 'no-file-key': Use numeric keys instead of subject (default: true) - * - 'strip-count': Strip file/part count from subject for sorting (default: false) - * @return array $result Empty if not an NZB or the contents of the NZB. + * @param array $options Optional settings: + * - 'no-file-key': Use numeric keys instead of subject (default: true) + * - 'strip-count': Strip file/part count from subject for sorting (default: false) + * @return array $result Empty if not an NZB or the contents of the NZB. */ public function parseNzbFileList(string $nzb, array $options = []): array { @@ -186,7 +186,7 @@ class NzbParserService * Check if a subject indicates an NFO file. * * @param string $subject The file subject - * @return array|false Returns array with detection info or false if not an NFO + * @return array|false Returns array with detection info or false if not an NFO */ public function detectNfoFile(string $subject): array|false { @@ -208,7 +208,7 @@ class NzbParserService * * @param string $subject The file subject * @param int $segmentCount The number of segments in the file - * @return array|false Returns array with detection info or false if not a hidden NFO + * @return array|false Returns array with detection info or false if not a hidden NFO */ public function detectHiddenNfoFile(string $subject, int $segmentCount): array|false { diff --git a/app/Services/Nzb/NzbService.php b/app/Services/Nzb/NzbService.php index 1ecc687ff..68ef549c2 100644 --- a/app/Services/Nzb/NzbService.php +++ b/app/Services/Nzb/NzbService.php @@ -100,7 +100,7 @@ class NzbService $XMLWriter->startElement('head'); $XMLWriter->startElement('meta'); $XMLWriter->writeAttribute('type', 'category'); - $XMLWriter->text(! empty($release->category->parent) ? $release->category->parent->title.' >'.$release->category->title : 'Other > Misc'); // @phpstan-ignore property.notFound + $XMLWriter->text(! empty($release->category->parent) ? $release->category->parent->title.' >'.$release->category->title : 'Other > Misc'); $XMLWriter->endElement(); $XMLWriter->startElement('meta'); $XMLWriter->writeAttribute('type', 'name'); diff --git a/app/Services/PopulateAniListService.php b/app/Services/PopulateAniListService.php index 292e3f798..3e5bf43aa 100644 --- a/app/Services/PopulateAniListService.php +++ b/app/Services/PopulateAniListService.php @@ -39,12 +39,16 @@ class PopulateAniListService /** * Rate limiting: track requests and timestamps + * + * @var array */ private array $rateLimitQueue = []; /** * Track when we received a 429 error and need to pause. * Format: ['timestamp' => int, 'paused_until' => int] + * + * @var array */ private static ?array $rateLimitPause = null; @@ -84,7 +88,7 @@ class PopulateAniListService /** * Search for anime by title using AniList GraphQL API. * - * @return array|false + * @return array|false * * @throws \Exception */ @@ -203,7 +207,7 @@ class PopulateAniListService /** * Get anime by AniList ID. * - * @return array|false + * @return array|false * * @throws \Exception */ @@ -287,7 +291,9 @@ class PopulateAniListService /** * Make a GraphQL request to AniList API with rate limiting. * - * @return array|false + * + * @param array $variables + * @return array|false * * @throws \Exception */ @@ -456,6 +462,8 @@ class PopulateAniListService /** * Insert or update AniList info data. + * + * @param array $anilistData */ protected function insertAniListInfo(int $anidbid, array $anilistData): void { @@ -697,7 +705,7 @@ class PopulateAniListService if ($title) { $searchResults = $this->searchAnime($title, 1); if ($searchResults) { - $anilistData = $searchResults[0]; + $anilistData = $searchResults[0]; // @phpstan-ignore offsetAccess.notFound $this->insertAniListInfo($anidb->anidbid, $anilistData); // Rate limiting is handled in makeGraphQLRequest } diff --git a/app/Services/RedisMonitorService.php b/app/Services/RedisMonitorService.php index a5fd83442..e51d59bb5 100644 --- a/app/Services/RedisMonitorService.php +++ b/app/Services/RedisMonitorService.php @@ -109,6 +109,8 @@ class RedisMonitorService /** * Get Redis INFO data. + * + * @return array */ public function getRedisInfo(): ?array { @@ -210,6 +212,8 @@ class RedisMonitorService /** * Get a single snapshot of Redis stats without entering monitor mode. + * + * @return array */ public function getStats(): array { @@ -228,6 +232,9 @@ class RedisMonitorService /** * Parse Redis INFO into structured data. + * + * @param array $info + * @return array */ protected function parseRedisInfo(array $info): array { @@ -299,6 +306,8 @@ class RedisMonitorService /** * Display the Redis monitor dashboard. + * + * @param array $info */ protected function displayDashboard(array $info): void { diff --git a/app/Services/RegexService.php b/app/Services/RegexService.php index 00622a11c..68b7c3686 100644 --- a/app/Services/RegexService.php +++ b/app/Services/RegexService.php @@ -31,6 +31,8 @@ class RegexService /** * Cache of regex and their TTL. + * + * @var array */ protected array $_regexCache = []; @@ -51,6 +53,8 @@ class RegexService /** * Add a new regex. + * + * @param array $data */ public function addRegex(array $data): bool { @@ -71,6 +75,8 @@ class RegexService /** * Update a regex with new info. + * + * @param array $data */ public function updateRegex(array $data): bool { @@ -93,6 +99,8 @@ class RegexService /** * Get a single regex using its id. + * + * @return array */ public function getRegexByID(int $id): array { @@ -158,6 +166,8 @@ class RegexService * * Requires table per group to be on. * + * @return array + * * @throws \Exception */ public function testCollectionRegex(string $groupName, string $regex, int $limit): array @@ -220,9 +230,11 @@ class RegexService /** * Test release naming regex against releases. * + * @return array + * * @throws \Exception */ - public function testReleaseNamingRegex($groupName, $regex, $displayLimit, $queryLimit): array + public function testReleaseNamingRegex(mixed $groupName, mixed $regex, mixed $displayLimit, mixed $queryLimit): array { $groupID = UsenetGroup::getIDByName($groupName); diff --git a/app/Services/ReleaseCleaningService.php b/app/Services/ReleaseCleaningService.php index 997b44e0b..8162c10b0 100644 --- a/app/Services/ReleaseCleaningService.php +++ b/app/Services/ReleaseCleaningService.php @@ -63,7 +63,7 @@ class ReleaseCleaningService } /** - * @return array|false|string + * @return array|false|string * * @throws \Exception */ @@ -170,6 +170,9 @@ class ReleaseCleaningService return $this->generic(); } + /** + * @return array + */ public function teevee(): array { // [140022]-[04] - [01/40] - "140022-04.nfo" yEnc @@ -188,7 +191,7 @@ class ReleaseCleaningService } /** - * @return array|string + * @return array|string */ public function generic_town() { @@ -388,6 +391,9 @@ class ReleaseCleaningService // Run at the end because this can be dangerous. In the future it's better to make these per group. There should not be numbers after yEnc because we remove them as well before inserting (even when importing). + /** + * @return array + */ public function generic(): array { // This regex gets almost all of the predb release names also keep in mind that not every subject ends with yEnc, some are truncated, because of the 255 character limit and some have extra charaters tacked onto the end, like (5/10). diff --git a/app/Services/ReleaseExtraService.php b/app/Services/ReleaseExtraService.php index 4e65c296a..41ac67c86 100644 --- a/app/Services/ReleaseExtraService.php +++ b/app/Services/ReleaseExtraService.php @@ -29,6 +29,7 @@ class ReleaseExtraService * Get video data as array. * * @param int $id Release ID + * @return array */ public function getVideo(int $id): false|array { @@ -45,6 +46,7 @@ class ReleaseExtraService * Get audio data for a release. * * @param int $id Release ID + * @return array */ public function getAudio(int $id): false|array { @@ -78,7 +80,7 @@ class ReleaseExtraService * @param string $guid Release GUID * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|null */ - public function getByGuid(string $guid) + public function getByGuid(string $guid) // @phpstan-ignore missingType.generics { return VideoData::query() ->where('r.guid', $guid) diff --git a/app/Services/ReleaseProcessingService.php b/app/Services/ReleaseProcessingService.php index 71b3ce077..e29b8ffa2 100644 --- a/app/Services/ReleaseProcessingService.php +++ b/app/Services/ReleaseProcessingService.php @@ -959,6 +959,9 @@ final class ReleaseProcessingService // Release Deletion Methods // ======================================================================== + /** + * @param array $stats + */ private function deleteReleasesUnderMinSize(int|string $groupId, array &$stats): void { $releases = Release::query() @@ -978,6 +981,9 @@ final class ReleaseProcessingService } } + /** + * @param array $stats + */ private function deleteReleasesOverMaxSize(int|string $groupId, array &$stats): void { if ($this->settings->maxSizeToFormRelease <= 0) { @@ -996,6 +1002,9 @@ final class ReleaseProcessingService } } + /** + * @param array $stats + */ private function deleteReleasesUnderMinFiles(int|string $groupId, array &$stats): void { if ($this->settings->minFilesToFormRelease <= 0) { diff --git a/app/Services/ReleaseRemoverService.php b/app/Services/ReleaseRemoverService.php index 7ce8b34ec..044ae55fc 100644 --- a/app/Services/ReleaseRemoverService.php +++ b/app/Services/ReleaseRemoverService.php @@ -68,6 +68,9 @@ class ReleaseRemoverService protected ReleaseManagementService $releaseManagement; + /** + * @var array + */ protected array $result = []; private NzbService $nzb; @@ -76,6 +79,8 @@ class ReleaseRemoverService /** * Map of removal types to their handler methods. + * + * @var array */ private array $removalHandlers; @@ -119,9 +124,9 @@ class ReleaseRemoverService /** * Remove releases using user criteria. * - * @param array $arguments Array of criteria used to delete unwanted releases. - * Criteria format: columnName=modifier="content" - * Modifiers: equals, like, bigger, smaller + * @param array $arguments Array of criteria used to delete unwanted releases. + * Criteria format: columnName=modifier="content" + * Modifiers: equals, like, bigger, smaller * * @throws Exception */ @@ -601,6 +606,8 @@ class ReleaseRemoverService /** * Perform search using configured search engine. + * + * @return array */ private function performSearch(string $regexMatch): array { @@ -685,6 +692,8 @@ class ReleaseRemoverService /** * Build the regex SQL and operation type name for blacklist. + * + * @return list */ private function buildBlacklistRegexSQL(int $msgcol, string $dbRegex): array { @@ -804,7 +813,7 @@ class ReleaseRemoverService */ protected function removeCodecPoster(): bool|string { - $categories = $this->buildCategoryList([ + $categories = $this->buildCategoryList([ // @phpstan-ignore argument.type Category::MOVIE_3D, Category::MOVIE_BLURAY, Category::MOVIE_DVD, @@ -851,6 +860,8 @@ class ReleaseRemoverService /** * Build a comma-separated list of category IDs. + * + * @param array $categories */ private function buildCategoryList(array $categories): string { @@ -1132,6 +1143,8 @@ class ReleaseRemoverService /** * Extract search terms from a regex pattern for fulltext search optimization. + * + * @return array */ protected function extractSrchFromRegx(string $dbRegex = ''): array|string { diff --git a/app/Services/Releases/ReleaseBrowseService.php b/app/Services/Releases/ReleaseBrowseService.php index 259f09c0d..6718821d2 100644 --- a/app/Services/Releases/ReleaseBrowseService.php +++ b/app/Services/Releases/ReleaseBrowseService.php @@ -29,9 +29,10 @@ class ReleaseBrowseService * Used for Browse results with optional search term filtering via search index. * * @param string|null $searchTerm Optional search term to filter by (uses search index) + * @param array $excludedCats * @return Collection|mixed */ - public function getBrowseRange($page, $cat, $start, $num, $orderBy, int $maxAge = -1, array $excludedCats = [], int|string $groupName = -1, int $minSize = 0, ?string $searchTerm = null): mixed + public function getBrowseRange(mixed $page, mixed $cat, mixed $start, mixed $num, mixed $orderBy, int $maxAge = -1, array $excludedCats = [], int|string $groupName = -1, int $minSize = 0, ?string $searchTerm = null): mixed { $cacheVersion = $this->getCacheVersion(); $page = max(1, $page); @@ -97,8 +98,8 @@ class ReleaseBrowseService ((int) $groupName !== -1 ? sprintf(' AND g.name = %s ', escapeString($groupName)) : ''), ($minSize > 0 ? sprintf('AND r.size >= %d', $minSize) : ''), $searchIndexFilter, - $orderBy[0], - $orderBy[1], + $orderBy[0], // @phpstan-ignore offsetAccess.notFound + $orderBy[1], // @phpstan-ignore offsetAccess.notFound ($start === 0 ? ' LIMIT '.$num : ' LIMIT '.$num.' OFFSET '.$start) ); @@ -127,6 +128,9 @@ class ReleaseBrowseService * Used for pager on browse page. * Optimized to avoid expensive COUNT queries on large tables. * Uses sample-based counting and avoids JOINs whenever possible. + * + * @param array $cat + * @param array $excludedCats */ public function getBrowseCount(array $cat, int $maxAge = -1, array $excludedCats = [], int|string $groupName = ''): int { @@ -245,6 +249,9 @@ class ReleaseBrowseService /** * Use to order releases on site. + * + * @param array $orderBy + * @return array */ public function getBrowseOrder(array|string $orderBy): array { @@ -265,7 +272,7 @@ class ReleaseBrowseService /** * Return ordering types usable on site. * - * @return string[] + * @return array */ public function getBrowseOrdering(): array { @@ -288,9 +295,10 @@ class ReleaseBrowseService } /** + * @param array $excludedCats * @return \Illuminate\Database\Eloquent\Collection|mixed */ - public function getShowsRange($userShows, $offset, $limit, $orderBy, int $maxAge = -1, array $excludedCats = []) + public function getShowsRange(mixed $userShows, mixed $offset, mixed $limit, mixed $orderBy, int $maxAge = -1, array $excludedCats = []) { $orderBy = $this->getBrowseOrder($orderBy); $sql = sprintf( @@ -311,8 +319,8 @@ class ReleaseBrowseService Category::TV_OTHER, $this->showPasswords(), ($maxAge > 0 ? sprintf(' AND r.postdate > NOW() - INTERVAL %d DAY ', $maxAge) : ''), - $orderBy[0], - $orderBy[1], + $orderBy[0], // @phpstan-ignore offsetAccess.notFound + $orderBy[1], // @phpstan-ignore offsetAccess.notFound ($offset === false ? '' : (' LIMIT '.$limit.' OFFSET '.$offset)) ); $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); @@ -326,7 +334,10 @@ class ReleaseBrowseService return $result; } - public function getShowsCount($userShows, int $maxAge = -1, array $excludedCats = []): int + /** + * @param array $excludedCats + */ + public function getShowsCount(mixed $userShows, int $maxAge = -1, array $excludedCats = []): int { return $this->getPagerCount( sprintf( @@ -348,8 +359,10 @@ class ReleaseBrowseService /** * Creates part of a query for some functions. + * + * @param array $userQuery */ - public function uSQL(Collection|array $userQuery, string $type): string + public function uSQL(Collection|array $userQuery, string $type): string // @phpstan-ignore missingType.generics { $sql = '(1=2 '; foreach ($userQuery as $query) { @@ -386,9 +399,9 @@ class ReleaseBrowseService * significantly improving performance for searches with text terms. * * @param string $searchTerm Search term to match - * @param array $categories Category IDs to filter by (optional) + * @param array $categories Category IDs to filter by (optional) * @param int $limit Maximum number of results - * @return array Array of release IDs matching the search criteria + * @return array Array of release IDs matching the search criteria */ public function searchByIndexWithCategories(string $searchTerm, array $categories = [], int $limit = 1000): array { @@ -422,9 +435,9 @@ class ReleaseBrowseService * Get releases by external media ID using search index. * Useful for movie/TV browse pages that need to find all releases for a specific movie/show. * - * @param array $externalIds Associative array of external IDs (e.g., ['imdbid' => 123456]) + * @param array $externalIds Associative array of external IDs (e.g., ['imdbid' => 123456]) * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function getReleasesByExternalId(array $externalIds, int $limit = 100): array { diff --git a/app/Services/Releases/ReleaseManagementService.php b/app/Services/Releases/ReleaseManagementService.php index a7b812c47..d07bed317 100644 --- a/app/Services/Releases/ReleaseManagementService.php +++ b/app/Services/Releases/ReleaseManagementService.php @@ -17,6 +17,8 @@ class ReleaseManagementService public function __construct() {} /** + * @param array $list + * * @throws \Exception */ public function deleteMultiple(int|array|string $list): void @@ -34,8 +36,8 @@ class ReleaseManagementService /** * Deletes a single release by GUID, and all the corresponding files. * - * @param array $identifiers ['g' => Release GUID(mandatory), 'id => ReleaseID(optional, pass - * false)] + * @param array $identifiers ['g' => Release GUID(mandatory), 'id => ReleaseID(optional, pass + * false)] * * @throws \Exception */ @@ -70,7 +72,7 @@ class ReleaseManagementService /** * Alias for deleteSingle for backwards compatibility. * - * @param array $identifiers ['g' => Release GUID(mandatory), 'i => ReleaseID(optional, pass false)] + * @param array $identifiers ['g' => Release GUID(mandatory), 'i => ReleaseID(optional, pass false)] * * @throws \Exception */ @@ -82,7 +84,7 @@ class ReleaseManagementService /** * @return bool|int */ - public function updateMulti($guids, $category, $grabs, $videoId, $episodeId, $anidbId, $imdbId) + public function updateMulti(mixed $guids, mixed $category, mixed $grabs, mixed $videoId, mixed $episodeId, mixed $anidbId, mixed $imdbId) { if (! \is_array($guids) || \count($guids) < 1) { return false; @@ -101,9 +103,9 @@ class ReleaseManagementService } /** - * @return Release[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection + * @return Release[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection */ - public function getForExport(string $postFrom = '', string $postTo = '', string $groupID = '') + public function getForExport(string $postFrom = '', string $postTo = '', string $groupID = '') // @phpstan-ignore missingType.generics { $query = Release::query() ->select(['r.searchname', 'r.guid', 'g.name as gname', DB::raw("CONCAT(cp.title,'_',c.title) AS catName")]) @@ -153,6 +155,9 @@ class ReleaseManagementService return $row === null ? '01/01/2014' : $row['postdate']; } + /** + * @return array + */ public function getReleasedGroupsForSelect(bool $blnIncludeAll = true): array { $groups = Release::query() diff --git a/app/Services/Releases/ReleaseSearchService.php b/app/Services/Releases/ReleaseSearchService.php index 4cd2e4c2f..bc9cdef22 100644 --- a/app/Services/Releases/ReleaseSearchService.php +++ b/app/Services/Releases/ReleaseSearchService.php @@ -30,22 +30,26 @@ class ReleaseSearchService /** * Function for searching on the site (by subject, searchname or advanced). * + * @param array $cat + * @param array $excludedCats + * @param array $orderBy + * @param array $searchArr * @return array|Collection|mixed */ public function search( array $searchArr, - $groupName, - $sizeFrom, - $sizeTo, - $daysNew, - $daysOld, + mixed $groupName, + mixed $sizeFrom, + mixed $sizeTo, + mixed $daysNew, + mixed $daysOld, int $offset = 0, int $limit = 1000, array|string $orderBy = '', int $maxAge = -1, array $excludedCats = [], string $type = 'basic', - array $cat = [-1], + array $cat = [-1], // @phpstan-ignore parameter.defaultValue int $minSize = 0 ): mixed { if (config('app.debug')) { @@ -93,8 +97,8 @@ class ReleaseSearchService $sql = sprintf( 'SELECT * FROM (%s) r ORDER BY r.%s %s LIMIT %d OFFSET %d', $baseSql, - $orderBy[0], - $orderBy[1], + $orderBy[0], // @phpstan-ignore offsetAccess.notFound + $orderBy[1], // @phpstan-ignore offsetAccess.notFound $limit, $offset ); @@ -124,9 +128,11 @@ class ReleaseSearchService /** * Search function for API. * + * @param array $cat + * @param array $excludedCats * @return Collection|mixed */ - public function apiSearch($searchName, $groupName, int $offset = 0, int $limit = 1000, int $maxAge = -1, array $excludedCats = [], array $cat = [-1], int $minSize = 0): mixed + public function apiSearch(mixed $searchName, mixed $groupName, int $offset = 0, int $limit = 1000, int $maxAge = -1, array $excludedCats = [], array $cat = [-1], int $minSize = 0): mixed // @phpstan-ignore parameter.defaultValue { if (config('app.debug')) { Log::debug('ReleaseSearchService::apiSearch called', [ @@ -247,9 +253,12 @@ class ReleaseSearchService /** * Search for TV shows via API. * + * @param array $cat + * @param array $excludedCategories + * @param array $siteIdArr * @return array|\Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|mixed */ - public function tvSearch(array $siteIdArr = [], string $series = '', string $episode = '', string $airDate = '', int $offset = 0, int $limit = 100, string $name = '', array $cat = [-1], int $maxAge = -1, int $minSize = 0, array $excludedCategories = []): mixed + public function tvSearch(array $siteIdArr = [], string $series = '', string $episode = '', string $airDate = '', int $offset = 0, int $limit = 100, string $name = '', array $cat = [-1], int $maxAge = -1, int $minSize = 0, array $excludedCategories = []): mixed // @phpstan-ignore parameter.defaultValue { $shouldCache = ! (isset($siteIdArr['id']) && (int) $siteIdArr['id'] > 0); $rawCacheKey = md5(serialize(func_get_args()).'tvSearch'); @@ -514,9 +523,12 @@ class ReleaseSearchService /** * Search TV Shows via APIv2. * + * @param array $cat + * @param array $excludedCategories + * @param array $siteIdArr * @return Collection|mixed */ - public function apiTvSearch(array $siteIdArr = [], string $series = '', string $episode = '', string $airDate = '', int $offset = 0, int $limit = 100, string $name = '', array $cat = [-1], int $maxAge = -1, int $minSize = 0, array $excludedCategories = []): mixed + public function apiTvSearch(array $siteIdArr = [], string $series = '', string $episode = '', string $airDate = '', int $offset = 0, int $limit = 100, string $name = '', array $cat = [-1], int $maxAge = -1, int $minSize = 0, array $excludedCategories = []): mixed // @phpstan-ignore parameter.defaultValue { // OPTIMIZATION: Try to find releases using search index external IDs first $externalIds = []; @@ -657,9 +669,11 @@ class ReleaseSearchService /** * Search anime releases. * + * @param array $cat + * @param array $excludedCategories * @return Collection|mixed */ - public function animeSearch($aniDbID, int $offset = 0, int $limit = 100, string $name = '', array $cat = [-1], int $maxAge = -1, array $excludedCategories = []): mixed + public function animeSearch(mixed $aniDbID, int $offset = 0, int $limit = 100, string $name = '', array $cat = [-1], int $maxAge = -1, array $excludedCategories = []): mixed // @phpstan-ignore parameter.defaultValue { $searchResult = []; if (! empty($name)) { @@ -725,9 +739,11 @@ class ReleaseSearchService /** * Movies search through API and site. * + * @param array $cat + * @param array $excludedCategories * @return Collection|mixed */ - public function moviesSearch(int $imDbId = -1, int $tmDbId = -1, int $traktId = -1, int $offset = 0, int $limit = 100, string $name = '', array $cat = [-1], int $maxAge = -1, int $minSize = 0, array $excludedCategories = []): mixed + public function moviesSearch(int $imDbId = -1, int $tmDbId = -1, int $traktId = -1, int $offset = 0, int $limit = 100, string $name = '', array $cat = [-1], int $maxAge = -1, int $minSize = 0, array $excludedCategories = []): mixed // @phpstan-ignore parameter.defaultValue { $searchResult = []; @@ -866,7 +882,11 @@ class ReleaseSearchService return $releases; } - public function searchSimilar($currentID, $name, array $excludedCats = []): bool|array + /** + * @param array $excludedCats + * @return array + */ + public function searchSimilar(mixed $currentID, mixed $name, array $excludedCats = []): bool|array { // Get the category for the parent of this release. $ret = false; @@ -879,7 +899,7 @@ class ReleaseSearchService return $ret; } - $results = $this->search(['searchname' => getSimilarName($name)], -1, '', '', -1, -1, 0, config('nntmux.items_per_page'), '', -1, $excludedCats, 'basic', [$parentCat]); + $results = $this->search(['searchname' => getSimilarName($name)], -1, '', '', -1, -1, 0, config('nntmux.items_per_page'), '', -1, $excludedCats, 'basic', [$parentCat]); // @phpstan-ignore argument.type if (! $results) { return $ret; } @@ -897,6 +917,9 @@ class ReleaseSearchService /** * Perform index search using Elasticsearch or Manticore, with MySQL fallback + * + * @param array $searchArr + * @return array */ private function performIndexSearch(array $searchArr, int $limit): array { @@ -954,6 +977,9 @@ class ReleaseSearchService /** * Fallback MySQL search when full-text search engines are unavailable + * + * @param array $searchFields + * @return array */ private function performMySQLSearch(array $searchFields, int $limit): array { @@ -991,14 +1017,18 @@ class ReleaseSearchService /** * Build WHERE clause for search query + * + * @param array $cat + * @param array $excludedCats + * @param array $searchResult */ private function buildSearchWhereClause( array $searchResult, - $groupName, - $sizeFrom, - $sizeTo, - $daysNew, - $daysOld, + mixed $groupName, + mixed $sizeFrom, + mixed $sizeTo, + mixed $daysNew, + mixed $daysOld, int $maxAge, array $excludedCats, string $type, @@ -1058,8 +1088,10 @@ class ReleaseSearchService /** * Build size conditions for WHERE clause + * + * @return array */ - private function buildSizeConditions($sizeFrom, $sizeTo): array + private function buildSizeConditions(mixed $sizeFrom, mixed $sizeTo): array { $sizeRange = [ 1 => 1, @@ -1090,6 +1122,8 @@ class ReleaseSearchService /** * Build category condition based on search type + * + * @param array $cat */ private function buildCategoryCondition(string $type, array $cat): string { @@ -1102,8 +1136,8 @@ class ReleaseSearchService return ($catSearch === '1=1') ? '' : $catSearch; } - if ($type === 'advanced' && (int) $cat[0] !== -1) { - return sprintf('r.categories_id = %d', (int) $cat[0]); + if ($type === 'advanced' && (int) $cat[0] !== -1) { // @phpstan-ignore offsetAccess.notFound + return sprintf('r.categories_id = %d', (int) $cat[0]); // @phpstan-ignore offsetAccess.notFound } return ''; @@ -1160,6 +1194,9 @@ class ReleaseSearchService /** * Use to order releases on site. + * + * @param array $orderBy + * @return array */ public function getBrowseOrder(array|string $orderBy): array { @@ -1174,7 +1211,7 @@ class ReleaseSearchService default => 'postdate', }; - return [$orderField, isset($orderArr[1]) && preg_match('/^(asc|desc)$/i', $orderArr[1]) ? $orderArr[1] : 'desc']; + return [$orderField, isset($orderArr[1]) && preg_match('/^(asc|desc)$/i', $orderArr[1]) ? $orderArr[1] : 'desc']; // @phpstan-ignore return.type } private function getCacheVersion(): int diff --git a/app/Services/Runners/BackfillRunner.php b/app/Services/Runners/BackfillRunner.php index 07d2056bd..3c570ae60 100644 --- a/app/Services/Runners/BackfillRunner.php +++ b/app/Services/Runners/BackfillRunner.php @@ -8,6 +8,9 @@ use Illuminate\Support\Facades\DB; class BackfillRunner extends BaseRunner { + /** + * @param array $options + */ public function backfill(array $options = []): void { $select = 'SELECT name'; @@ -32,7 +35,7 @@ class BackfillRunner extends BaseRunner foreach ($work as $group) { $commands[] = PHP_BINARY.' artisan update:backfill '.$group->name.(isset($group->max) ? (' '.$group->max) : ''); } - $this->runStreamingCommands($commands, $maxProcesses, 'backfill'); + $this->runStreamingCommands($commands, $maxProcesses, 'backfill'); // @phpstan-ignore argument.type return; } @@ -132,7 +135,7 @@ class BackfillRunner extends BaseRunner foreach ($queues as $queue) { $commands[] = $this->buildDnrCommand($queue); } - $this->runStreamingCommands($commands, $threads, 'safe_backfill'); + $this->runStreamingCommands($commands, $threads, 'safe_backfill'); // @phpstan-ignore argument.type return; } diff --git a/app/Services/Runners/BaseRunner.php b/app/Services/Runners/BaseRunner.php index 8ccbff473..89da24978 100644 --- a/app/Services/Runners/BaseRunner.php +++ b/app/Services/Runners/BaseRunner.php @@ -297,6 +297,8 @@ abstract class BaseRunner /** * Run multiple shell commands concurrently and stream their output in real-time. * Uses Symfony Process start() with a small event loop to enforce max concurrency. + * + * @param array $commands */ protected function runStreamingCommands(array $commands, int $maxProcesses, string $desc): void { diff --git a/app/Services/Runners/BinariesRunner.php b/app/Services/Runners/BinariesRunner.php index c350798cc..f710a9d65 100644 --- a/app/Services/Runners/BinariesRunner.php +++ b/app/Services/Runners/BinariesRunner.php @@ -31,7 +31,7 @@ class BinariesRunner extends BaseRunner foreach ($work as $group) { $commands[] = PHP_BINARY.' artisan update:binaries '.$group->name.' '.$group->max; } - $this->runStreamingCommands($commands, $maxProcesses, 'binaries'); + $this->runStreamingCommands($commands, $maxProcesses, 'binaries'); // @phpstan-ignore argument.type return; } @@ -121,7 +121,7 @@ class BinariesRunner extends BaseRunner foreach ($queues as $queue) { $commands[] = $this->buildDnrCommand($queue); } - $this->runStreamingCommands($commands, $maxProcesses, 'safe_binaries'); + $this->runStreamingCommands($commands, $maxProcesses, 'safe_binaries'); // @phpstan-ignore argument.type return; } diff --git a/app/Services/Runners/PostProcessRunner.php b/app/Services/Runners/PostProcessRunner.php index 1e276b334..56e30d72b 100644 --- a/app/Services/Runners/PostProcessRunner.php +++ b/app/Services/Runners/PostProcessRunner.php @@ -10,6 +10,9 @@ use Illuminate\Support\Facades\Log; class PostProcessRunner extends BaseRunner { + /** + * @param array $releases + */ private function runPostProcess(array $releases, int $maxProcesses, string $type, string $desc): void { if (empty($releases)) { @@ -27,7 +30,7 @@ class PostProcessRunner extends BaseRunner // Use postprocess:guid command which accepts the GUID character $commands[] = PHP_BINARY.' artisan postprocess:guid '.$type.' '.$char; } - $this->runStreamingCommands($commands, $maxProcesses, $desc); + $this->runStreamingCommands($commands, $maxProcesses, $desc); // @phpstan-ignore argument.type return; } @@ -198,6 +201,8 @@ class PostProcessRunner extends BaseRunner /** * Run pipelined TV post-processing across multiple GUID buckets in parallel. * Each parallel process runs the full provider pipeline sequentially. + * + * @param array $releases */ private function runPostProcessTvPipeline(array $releases, int $maxProcesses, string $desc, bool $renamedOnly): void { @@ -216,7 +221,7 @@ class PostProcessRunner extends BaseRunner // Use the pipelined TV command $commands[] = PHP_BINARY.' artisan postprocess:tv-pipeline '.$char.($renamed ? ' '.$renamed : '').' --mode=pipeline'; } - $this->runStreamingCommands($commands, $maxProcesses, $desc); + $this->runStreamingCommands($commands, $maxProcesses, $desc); // @phpstan-ignore argument.type return; } diff --git a/app/Services/Runners/ReleasesRunner.php b/app/Services/Runners/ReleasesRunner.php index 3cca87566..63dbe48f8 100644 --- a/app/Services/Runners/ReleasesRunner.php +++ b/app/Services/Runners/ReleasesRunner.php @@ -42,7 +42,7 @@ class ReleasesRunner extends BaseRunner foreach ($uGroups as $group) { $commands[] = $this->buildDnrCommand('releases '.$group['id']); } - $this->runStreamingCommands($commands, $maxProcesses, 'releases'); + $this->runStreamingCommands($commands, $maxProcesses, 'releases'); // @phpstan-ignore argument.type return; } @@ -91,7 +91,7 @@ class ReleasesRunner extends BaseRunner foreach ($groups as $group) { $commands[] = $this->buildDnrCommand('update_per_group '.$group->id); } - $this->runStreamingCommands($commands, $maxProcesses, 'update_per_group'); + $this->runStreamingCommands($commands, $maxProcesses, 'update_per_group'); // @phpstan-ignore argument.type return; } @@ -163,7 +163,7 @@ class ReleasesRunner extends BaseRunner // Updated to use new script location (modernized) $commands[] = PHP_BINARY.' app/Services/Tmux/Scripts/groupfixrelnames.php "'.$queue.'" true'; } - $this->runStreamingCommands($commands, $maxThreads, 'fixRelNames_'.$mode); + $this->runStreamingCommands($commands, $maxThreads, 'fixRelNames_'.$mode); // @phpstan-ignore argument.type return; } diff --git a/app/Services/Search/Contracts/SearchServiceInterface.php b/app/Services/Search/Contracts/SearchServiceInterface.php index 1be907584..29b743a48 100644 --- a/app/Services/Search/Contracts/SearchServiceInterface.php +++ b/app/Services/Search/Contracts/SearchServiceInterface.php @@ -26,6 +26,8 @@ interface SearchServiceInterface /** * Get fuzzy search configuration. + * + * @return array */ public function getFuzzyConfig(): array; @@ -52,7 +54,7 @@ interface SearchServiceInterface /** * Insert a release into the search index. * - * @param array $parameters Release data with 'id', 'name', 'searchname', 'fromname', 'categories_id', 'filename' + * @param array $parameters Release data with 'id', 'name', 'searchname', 'fromname', 'categories_id', 'filename' */ public function insertRelease(array $parameters): void; @@ -73,23 +75,23 @@ interface SearchServiceInterface /** * Insert a predb record into the search index. * - * @param array $parameters Predb data with 'id', 'title', 'filename', 'source' + * @param array $parameters Predb data with 'id', 'title', 'filename', 'source' */ public function insertPredb(array $parameters): void; /** * Update a predb record in the search index. * - * @param array $parameters Predb data with 'id', 'title', 'filename', 'source' + * @param array $parameters Predb data with 'id', 'title', 'filename', 'source' */ public function updatePreDb(array $parameters): void; /** * Search the releases index. * - * @param array|string $phrases Search phrases + * @param array|string $phrases Search phrases * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchReleases(array|string $phrases, int $limit = 1000): array; @@ -99,10 +101,10 @@ interface SearchServiceInterface * If exact search returns no results and fuzzy is enabled, this method * will automatically try a fuzzy search as a fallback. * - * @param array|string $phrases Search phrases + * @param array|string $phrases Search phrases * @param int $limit Maximum number of results * @param bool $forceFuzzy Force fuzzy search regardless of exact results - * @return array Array with 'ids' (release IDs) and 'fuzzy' (bool indicating if fuzzy was used) + * @return array Array with 'ids' (release IDs) and 'fuzzy' (bool indicating if fuzzy was used) */ public function searchReleasesWithFuzzy(array|string $phrases, int $limit = 1000, bool $forceFuzzy = false): array; @@ -111,17 +113,17 @@ interface SearchServiceInterface * * Uses search engine's fuzzy matching to find results with typo tolerance. * - * @param array|string $phrases Search phrases + * @param array|string $phrases Search phrases * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function fuzzySearchReleases(array|string $phrases, int $limit = 1000): array; /** * Search the predb index. * - * @param array|string $searchTerm Search term(s) - * @return array Array of predb records + * @param array|string $searchTerm Search term(s) + * @return array Array of predb records */ public function searchPredb(array|string $searchTerm): array; @@ -146,7 +148,7 @@ interface SearchServiceInterface /** * Truncate/clear an index (remove all documents). * - * @param array|string $indexes Index name(s) to truncate + * @param array|string $indexes Index name(s) to truncate */ public function truncateIndex(array|string $indexes): void; @@ -158,16 +160,16 @@ interface SearchServiceInterface /** * Bulk insert multiple releases into the index. * - * @param array $releases Array of release data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $releases Array of release data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertReleases(array $releases): array; /** * Bulk insert multiple predb records into the index. * - * @param array $predbRecords Array of predb data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $predbRecords Array of predb data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertPredb(array $predbRecords): array; @@ -181,7 +183,7 @@ interface SearchServiceInterface /** * Insert a movie into the movies search index. * - * @param array $parameters Movie data with id, imdbid, tmdbid, traktid, title, year, genre, actors, director, rating + * @param array $parameters Movie data with id, imdbid, tmdbid, traktid, title, year, genre, actors, director, rating */ public function insertMovie(array $parameters): void; @@ -202,17 +204,17 @@ interface SearchServiceInterface /** * Bulk insert multiple movies into the index. * - * @param array $movies Array of movie data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $movies Array of movie data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertMovies(array $movies): array; /** * Search the movies index. * - * @param array|string $searchTerm Search term(s) + * @param array|string $searchTerm Search term(s) * @param int $limit Maximum number of results - * @return array Array with 'id' (movie IDs) and 'data' (movie data) + * @return array Array with 'id' (movie IDs) and 'data' (movie data) */ public function searchMovies(array|string $searchTerm, int $limit = 1000): array; @@ -221,14 +223,14 @@ interface SearchServiceInterface * * @param string $field Field name (imdbid, tmdbid, traktid) * @param int|string $value The external ID value - * @return array|null Movie data or null if not found + * @return array|null Movie data or null if not found */ public function searchMovieByExternalId(string $field, int|string $value): ?array; /** * Insert a TV show into the tvshows search index. * - * @param array $parameters TV show data with id, title, tvdb, trakt, tvmaze, tvrage, imdb, tmdb, started, type + * @param array $parameters TV show data with id, title, tvdb, trakt, tvmaze, tvrage, imdb, tmdb, started, type */ public function insertTvShow(array $parameters): void; @@ -249,17 +251,17 @@ interface SearchServiceInterface /** * Bulk insert multiple TV shows into the index. * - * @param array $tvShows Array of TV show data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $tvShows Array of TV show data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertTvShows(array $tvShows): array; /** * Search the TV shows index. * - * @param array|string $searchTerm Search term(s) + * @param array|string $searchTerm Search term(s) * @param int $limit Maximum number of results - * @return array Array with 'id' (TV show IDs) and 'data' (TV show data) + * @return array Array with 'id' (TV show IDs) and 'data' (TV show data) */ public function searchTvShows(array|string $searchTerm, int $limit = 1000): array; @@ -268,7 +270,7 @@ interface SearchServiceInterface * * @param string $field Field name (tvdb, trakt, tvmaze, tvrage, imdb, tmdb) * @param int|string $value The external ID value - * @return array|null TV show data or null if not found + * @return array|null TV show data or null if not found */ public function searchTvShowByExternalId(string $field, int|string $value): ?array; @@ -276,9 +278,9 @@ interface SearchServiceInterface * Search releases by external media IDs. * Used to find releases associated with a specific movie or TV show. * - * @param array $externalIds Associative array of external IDs, e.g., ['imdbid' => 123456, 'tmdbid' => 789] + * @param array $externalIds Associative array of external IDs, e.g., ['imdbid' => 123456, 'tmdbid' => 789] * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchReleasesByExternalId(array $externalIds, int $limit = 1000): array; @@ -286,9 +288,9 @@ interface SearchServiceInterface * Search releases by category ID using the search index. * This provides a fast way to get release IDs for a specific category without hitting the database. * - * @param array $categoryIds Array of category IDs to filter by + * @param array $categoryIds Array of category IDs to filter by * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchReleasesByCategory(array $categoryIds, int $limit = 1000): array; @@ -297,9 +299,9 @@ interface SearchServiceInterface * First searches by text, then filters by category IDs using the search index. * * @param string $searchTerm Search text - * @param array $categoryIds Array of category IDs to filter by (empty for all categories) + * @param array $categoryIds Array of category IDs to filter by (empty for all categories) * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchReleasesWithCategoryFilter(string $searchTerm, array $categoryIds = [], int $limit = 1000): array; } diff --git a/app/Services/Search/Drivers/ElasticSearchDriver.php b/app/Services/Search/Drivers/ElasticSearchDriver.php index 383dc3c74..417c92239 100644 --- a/app/Services/Search/Drivers/ElasticSearchDriver.php +++ b/app/Services/Search/Drivers/ElasticSearchDriver.php @@ -49,8 +49,14 @@ class ElasticSearchDriver implements SearchDriverInterface private static ?int $availabilityCacheTime = null; + /** + * @var array + */ protected array $config; + /** + * @param array $config + */ public function __construct(array $config = []) { $this->config = ! empty($config) ? $config : config('search.drivers.elasticsearch'); @@ -134,8 +140,8 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Build hosts array from configuration. * - * @param array $configHosts Configuration hosts array - * @return array Formatted hosts array for Elasticsearch client + * @param array $configHosts Configuration hosts array + * @return array Formatted hosts array for Elasticsearch client */ private function buildHostsArray(array $configHosts): array { @@ -166,6 +172,8 @@ class ElasticSearchDriver implements SearchDriverInterface * Check if Elasticsearch is available. * * Caches the availability status to avoid frequent ping requests. + * + * @return list> */ private function isElasticsearchAvailable(): bool { @@ -238,6 +246,8 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Get fuzzy search configuration. + * + * @return array */ public function getFuzzyConfig(): array { @@ -626,9 +636,9 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Search releases index. * - * @param array|string $phrases Search phrases - can be a string, indexed array of terms, or associative array with field names + * @param array|string $phrases Search phrases - can be a string, indexed array of terms, or associative array with field names * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchReleases(array|string $phrases, int $limit = 1000): array { @@ -659,10 +669,10 @@ class ElasticSearchDriver implements SearchDriverInterface * If exact search returns no results and fuzzy is enabled, this method * will automatically try a fuzzy search as a fallback. * - * @param array|string $phrases Search phrases + * @param array|string $phrases Search phrases * @param int $limit Maximum number of results * @param bool $forceFuzzy Force fuzzy search regardless of exact results - * @return array Array with 'ids' (release IDs) and 'fuzzy' (bool indicating if fuzzy was used) + * @return array Array with 'ids' (release IDs) and 'fuzzy' (bool indicating if fuzzy was used) */ public function searchReleasesWithFuzzy(array|string $phrases, int $limit = 1000, bool $forceFuzzy = false): array { @@ -699,9 +709,9 @@ class ElasticSearchDriver implements SearchDriverInterface * * Uses Elasticsearch's fuzzy matching to find results with typo tolerance. * - * @param array|string $phrases Search phrases + * @param array|string $phrases Search phrases * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function fuzzySearchReleases(array|string $phrases, int $limit = 1000): array { @@ -727,7 +737,7 @@ class ElasticSearchDriver implements SearchDriverInterface } $fuzzyConfig = $this->getFuzzyConfig(); - $cacheKey = $this->buildCacheKey('fuzzy_search', [$keywords, $limit, $fuzzyConfig]); + $cacheKey = $this->buildCacheKey('fuzzy_search', [$keywords, $limit, $fuzzyConfig]); // @phpstan-ignore argument.type $cached = Cache::get($cacheKey); if ($cached !== null) { return $cached; @@ -802,7 +812,7 @@ class ElasticSearchDriver implements SearchDriverInterface Cache::put($cacheKey, $ids, now()->addMinutes($this->config['cache_minutes'] ?? self::CACHE_TTL_MINUTES)); - return $ids; + return $ids; // @phpstan-ignore return.type } catch (ElasticsearchException $e) { Log::error('ElasticSearch fuzzySearchReleases error: '.$e->getMessage(), [ @@ -823,8 +833,8 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Search the predb index. * - * @param array|string $searchTerm Search term(s) - * @return array Array of predb records + * @param array|string $searchTerm Search term(s) + * @return array Array of predb records */ public function searchPredb(array|string $searchTerm): array { @@ -836,9 +846,9 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Search releases index. * - * @param array|string $phrases Search phrases + * @param array|string $phrases Search phrases * @param int $limit Maximum number of results - * @return array|Collection Array of release IDs + * @return array|Collection Array of release IDs */ public function indexSearch(array|string $phrases, int $limit): array|Collection { @@ -870,7 +880,7 @@ class ElasticSearchDriver implements SearchDriverInterface return []; } - $cacheKey = $this->buildCacheKey('index_search', [$keywords, $limit]); + $cacheKey = $this->buildCacheKey('index_search', [$keywords, $limit]); // @phpstan-ignore argument.type $cached = Cache::get($cacheKey); if ($cached !== null) { return $cached; @@ -880,7 +890,7 @@ class ElasticSearchDriver implements SearchDriverInterface $search = $this->buildSearchQuery( index: $this->getReleasesIndex(), keywords: $keywords, - fields: ['searchname^2', 'plainsearchname^1.5', 'fromname', 'filename', 'name^1.2'], + fields: ['searchname^2', 'plainsearchname^1.5', 'fromname', 'filename', 'name^1.2'], // @phpstan-ignore argument.type limit: $limit ); @@ -902,9 +912,9 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Search releases for API requests. * - * @param array|string $searchName Search name(s) + * @param array|string $searchName Search name(s) * @param int $limit Maximum number of results - * @return array|Collection Array of release IDs + * @return array|Collection Array of release IDs */ public function indexSearchApi(array|string $searchName, int $limit): array|Collection { @@ -917,7 +927,7 @@ class ElasticSearchDriver implements SearchDriverInterface return []; } - $cacheKey = $this->buildCacheKey('api_search', [$keywords, $limit]); + $cacheKey = $this->buildCacheKey('api_search', [$keywords, $limit]); // @phpstan-ignore argument.type $cached = Cache::get($cacheKey); if ($cached !== null) { return $cached; @@ -927,7 +937,7 @@ class ElasticSearchDriver implements SearchDriverInterface $search = $this->buildSearchQuery( index: $this->getReleasesIndex(), keywords: $keywords, - fields: ['searchname^2', 'plainsearchname^1.5', 'fromname', 'filename', 'name^1.2'], + fields: ['searchname^2', 'plainsearchname^1.5', 'fromname', 'filename', 'name^1.2'], // @phpstan-ignore argument.type limit: $limit ); @@ -949,9 +959,9 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Search releases for TV/Movie/Audio (TMA) matching. * - * @param array|string $name Name(s) to search + * @param array|string $name Name(s) to search * @param int $limit Maximum number of results - * @return array|Collection Array of release IDs + * @return array|Collection Array of release IDs */ public function indexSearchTMA(array|string $name, int $limit): array|Collection { @@ -964,7 +974,7 @@ class ElasticSearchDriver implements SearchDriverInterface return []; } - $cacheKey = $this->buildCacheKey('tma_search', [$keywords, $limit]); + $cacheKey = $this->buildCacheKey('tma_search', [$keywords, $limit]); // @phpstan-ignore argument.type $cached = Cache::get($cacheKey); if ($cached !== null) { return $cached; @@ -974,7 +984,7 @@ class ElasticSearchDriver implements SearchDriverInterface $search = $this->buildSearchQuery( index: $this->getReleasesIndex(), keywords: $keywords, - fields: ['searchname^2', 'plainsearchname^1.5'], + fields: ['searchname^2', 'plainsearchname^1.5'], // @phpstan-ignore argument.type limit: $limit, options: [ 'boost' => 1.2, @@ -999,8 +1009,8 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Search predb index. * - * @param array|string $searchTerm Search term(s) - * @return array|Collection Array of predb records + * @param array|string $searchTerm Search term(s) + * @return array|Collection Array of predb records */ public function predbIndexSearch(array|string $searchTerm): array|Collection { @@ -1013,7 +1023,7 @@ class ElasticSearchDriver implements SearchDriverInterface return []; } - $cacheKey = $this->buildCacheKey('predb_search', [$keywords]); + $cacheKey = $this->buildCacheKey('predb_search', [$keywords]); // @phpstan-ignore argument.type $cached = Cache::get($cacheKey); if ($cached !== null) { return $cached; @@ -1023,7 +1033,7 @@ class ElasticSearchDriver implements SearchDriverInterface $search = $this->buildSearchQuery( index: $this->getPredbIndex(), keywords: $keywords, - fields: ['title^2', 'filename'], + fields: ['title^2', 'filename'], // @phpstan-ignore argument.type limit: 1000, options: [ 'fuzziness' => 'AUTO', @@ -1048,7 +1058,7 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Insert a release into the index. * - * @param array $parameters Release data with 'id', 'name', 'searchname', etc. + * @param array $parameters Release data with 'id', 'name', 'searchname', etc. */ public function insertRelease(array $parameters): void { @@ -1148,7 +1158,7 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Insert a predb record into the index. * - * @param array $parameters Predb data with 'id', 'title', 'source', 'filename' + * @param array $parameters Predb data with 'id', 'title', 'source', 'filename' */ public function insertPredb(array $parameters): void { @@ -1191,7 +1201,7 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Update a predb record in the index. * - * @param array $parameters Predb data with 'id', 'title', 'source', 'filename' + * @param array $parameters Predb data with 'id', 'title', 'source', 'filename' */ public function updatePreDb(array $parameters): void { @@ -1312,8 +1322,8 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Bulk insert multiple releases into the index. * - * @param array $releases Array of release data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $releases Array of release data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertReleases(array $releases): array { @@ -1384,8 +1394,8 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Bulk insert multiple predb records into the index. * - * @param array $predbRecords Array of predb data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $predbRecords Array of predb data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertPredb(array $predbRecords): array { @@ -1474,7 +1484,7 @@ class ElasticSearchDriver implements SearchDriverInterface * Truncate/clear an index (remove all documents). * Implements SearchServiceInterface::truncateIndex * - * @param array|string $indexes Index name(s) to truncate + * @param array|string $indexes Index name(s) to truncate */ public function truncateIndex(array|string $indexes): void { @@ -1554,7 +1564,7 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Get cluster health information. * - * @return array Health information or empty array on failure + * @return array Health information or empty array on failure */ public function getClusterHealth(): array { @@ -1577,7 +1587,7 @@ class ElasticSearchDriver implements SearchDriverInterface * Get index statistics. * * @param string $index Index name - * @return array Statistics or empty array on failure + * @return array Statistics or empty array on failure */ public function getIndexStats(string $index): array { @@ -1602,7 +1612,7 @@ class ElasticSearchDriver implements SearchDriverInterface * Uses the global sanitize() helper function which properly escapes * Elasticsearch query string special characters. * - * @param array|string $terms Search terms + * @param array|string $terms Search terms * @return string Sanitized search string */ private function sanitizeSearchTerms(array|string $terms): string @@ -1636,7 +1646,7 @@ class ElasticSearchDriver implements SearchDriverInterface * Build a cache key for search results. * * @param string $prefix Cache key prefix - * @param array $params Parameters to include in key + * @param array $params Parameters to include in key */ private function buildCacheKey(string $prefix, array $params): string { @@ -1648,10 +1658,11 @@ class ElasticSearchDriver implements SearchDriverInterface * * @param string $index Index name * @param string $keywords Sanitized keywords - * @param array $fields Fields to search with boosts + * @param array $fields Fields to search with boosts * @param int $limit Maximum results - * @param array $options Additional query_string options + * @param array $options Additional query_string options * @param bool $includeDateSort Include date sorting + * @return array */ private function buildSearchQuery( string $index, @@ -1693,7 +1704,8 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Build a release document for indexing. * - * @param array $parameters Release parameters + * @param array $parameters Release parameters + * @return array */ private function buildReleaseDocument(array $parameters): array { @@ -1729,8 +1741,9 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Execute a search with scroll support. * - * @param array $search Search query + * @param array $search Search query * @param bool $fullResults Return full source documents instead of just IDs + * @return array */ protected function executeSearch(array $search, bool $fullResults = false): array { @@ -1785,7 +1798,7 @@ class ElasticSearchDriver implements SearchDriverInterface ]); } - return $searchResult; + return $searchResult; // @phpstan-ignore return.type } catch (ElasticsearchException $e) { Log::error('ElasticSearch search error: '.$e->getMessage()); @@ -1826,7 +1839,7 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Execute a bulk operation. * - * @param array $params Bulk operation parameters + * @param array $params Bulk operation parameters */ private function executeBulk(array $params): void { @@ -1859,7 +1872,7 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Insert a movie into the movies search index. * - * @param array $parameters Movie data + * @param array $parameters Movie data */ public function insertMovie(array $parameters): void { @@ -1962,8 +1975,8 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Bulk insert multiple movies into the index. * - * @param array $movies Array of movie data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $movies Array of movie data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertMovies(array $movies): array { @@ -2023,9 +2036,9 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Search the movies index. * - * @param array|string $searchTerm Search term(s) + * @param array|string $searchTerm Search term(s) * @param int $limit Maximum number of results - * @return array Array with 'id' (movie IDs) and 'data' (movie data) + * @return array Array with 'id' (movie IDs) and 'data' (movie data) */ public function searchMovies(array|string $searchTerm, int $limit = 1000): array { @@ -2090,7 +2103,7 @@ class ElasticSearchDriver implements SearchDriverInterface * * @param string $field Field name (imdbid, tmdbid, traktid) * @param int|string $value The external ID value - * @return array|null Movie data or null if not found + * @return array|null Movie data or null if not found */ public function searchMovieByExternalId(string $field, int|string $value): ?array { @@ -2142,7 +2155,7 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Insert a TV show into the tvshows search index. * - * @param array $parameters TV show data + * @param array $parameters TV show data */ public function insertTvShow(array $parameters): void { @@ -2244,8 +2257,8 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Bulk insert multiple TV shows into the index. * - * @param array $tvShows Array of TV show data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $tvShows Array of TV show data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertTvShows(array $tvShows): array { @@ -2304,9 +2317,9 @@ class ElasticSearchDriver implements SearchDriverInterface /** * Search the TV shows index. * - * @param array|string $searchTerm Search term(s) + * @param array|string $searchTerm Search term(s) * @param int $limit Maximum number of results - * @return array Array with 'id' (TV show IDs) and 'data' (TV show data) + * @return array Array with 'id' (TV show IDs) and 'data' (TV show data) */ public function searchTvShows(array|string $searchTerm, int $limit = 1000): array { @@ -2371,7 +2384,7 @@ class ElasticSearchDriver implements SearchDriverInterface * * @param string $field Field name (tvdb, trakt, tvmaze, tvrage, imdb, tmdb) * @param int|string $value The external ID value - * @return array|null TV show data or null if not found + * @return array|null TV show data or null if not found */ public function searchTvShowByExternalId(string $field, int|string $value): ?array { @@ -2424,9 +2437,9 @@ class ElasticSearchDriver implements SearchDriverInterface * Search releases by external media IDs. * Used to find releases associated with a specific movie or TV show. * - * @param array $externalIds Associative array of external IDs + * @param array $externalIds Associative array of external IDs * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchReleasesByExternalId(array $externalIds, int $limit = 1000): array { @@ -2481,7 +2494,7 @@ class ElasticSearchDriver implements SearchDriverInterface Cache::put($cacheKey, $resultIds, now()->addMinutes(self::CACHE_TTL_MINUTES)); } - return $resultIds; + return $resultIds; // @phpstan-ignore return.type } catch (\Throwable $e) { Log::error('ElasticSearch searchReleasesByExternalId error: '.$e->getMessage(), [ @@ -2496,9 +2509,10 @@ class ElasticSearchDriver implements SearchDriverInterface * Search releases by category ID using the search index. * This provides a fast way to get release IDs for a specific category without hitting the database. * - * @param array $categoryIds Array of category IDs to filter by + * @param array $categoryIds Array of category IDs to filter by * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return list + * @return array */ public function searchReleasesByCategory(array $categoryIds, int $limit = 1000): array { @@ -2547,7 +2561,7 @@ class ElasticSearchDriver implements SearchDriverInterface Cache::put($cacheKey, $resultIds, now()->addMinutes(self::CACHE_TTL_MINUTES)); } - return $resultIds; + return $resultIds; // @phpstan-ignore return.type } catch (\Throwable $e) { Log::error('ElasticSearch searchReleasesByCategory error: '.$e->getMessage(), [ @@ -2563,9 +2577,10 @@ class ElasticSearchDriver implements SearchDriverInterface * First searches by text, then filters by category IDs using the search index. * * @param string $searchTerm Search text - * @param array $categoryIds Array of category IDs to filter by (empty for all categories) + * @param array $categoryIds Array of category IDs to filter by (empty for all categories) * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array + * @return array */ public function searchReleasesWithCategoryFilter(string $searchTerm, array $categoryIds = [], int $limit = 1000): array { diff --git a/app/Services/Search/Drivers/ManticoreSearchDriver.php b/app/Services/Search/Drivers/ManticoreSearchDriver.php index e4c34be6a..bdac6c695 100644 --- a/app/Services/Search/Drivers/ManticoreSearchDriver.php +++ b/app/Services/Search/Drivers/ManticoreSearchDriver.php @@ -19,8 +19,14 @@ use Manticoresearch\Search; */ class ManticoreSearchDriver implements SearchDriverInterface { + /** + * @var array + */ protected array $config; + /** + * @var array + */ protected array $connection; public Client $manticoreSearch; @@ -29,6 +35,8 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Establishes a connection to ManticoreSearch HTTP port. + * + * @param array $config */ public function __construct(array $config = []) { @@ -90,6 +98,8 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Get fuzzy search configuration. + * + * @return array */ public function getFuzzyConfig(): array { @@ -134,6 +144,8 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Insert release into ManticoreSearch releases_rt realtime index + * + * @param array $parameters */ public function insertRelease(array $parameters): void { @@ -183,6 +195,8 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Insert release into Manticore RT table. + * + * @param array $parameters */ public function insertPredb(array $parameters): void { @@ -266,8 +280,8 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Bulk insert multiple releases into the index. * - * @param array $releases Array of release data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $releases Array of release data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertReleases(array $releases): array { @@ -318,8 +332,8 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Bulk insert multiple predb records into the index. * - * @param array $predbRecords Array of predb data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $predbRecords Array of predb data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertPredb(array $predbRecords): array { @@ -360,7 +374,7 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Delete release from Manticore RT tables by GUID. * - * @param array $identifiers ['g' => Release GUID(mandatory), 'id' => ReleaseID(optional, pass false)] + * @param array $identifiers ['g' => Release GUID(mandatory), 'id' => ReleaseID(optional, pass false)] */ public function deleteReleaseByGuid(array $identifiers): void { @@ -536,6 +550,8 @@ class ManticoreSearchDriver implements SearchDriverInterface * Used to prevent fuzzy fallback from reversing the user's negation intent. * For example, if the user searches "!harry", fuzzy should not strip the ! * and return "harry" results. + * + * @param array $phrases */ public static function queryHasNegation(array|string $phrases): bool { @@ -597,6 +613,8 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Update Manticore Predb index for given predb_id. + * + * @param array $parameters */ public function updatePreDb(array $parameters): void { @@ -609,6 +627,9 @@ class ManticoreSearchDriver implements SearchDriverInterface $this->insertPredb($parameters); } + /** + * @param array $indexes + */ public function truncateRTIndex(array $indexes = []): bool { if (empty($indexes)) { @@ -659,7 +680,7 @@ class ManticoreSearchDriver implements SearchDriverInterface * Truncate/clear an index (remove all documents). * Implements SearchServiceInterface::truncateIndex * - * @param array|string $indexes Index name(s) to truncate + * @param array|string $indexes Index name(s) to truncate */ public function truncateIndex(array|string $indexes): void { @@ -806,9 +827,9 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Search releases index. * - * @param array|string $phrases Search phrases - can be a string, indexed array of terms, or associative array with field names + * @param array|string $phrases Search phrases - can be a string, indexed array of terms, or associative array with field names * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchReleases(array|string $phrases, int $limit = 1000): array { @@ -839,10 +860,10 @@ class ManticoreSearchDriver implements SearchDriverInterface * If exact search returns no results and fuzzy is enabled, this method * will automatically try a fuzzy search as a fallback. * - * @param array|string $phrases Search phrases + * @param array|string $phrases Search phrases * @param int $limit Maximum number of results * @param bool $forceFuzzy Force fuzzy search regardless of exact results - * @return array Array with 'ids' (release IDs) and 'fuzzy' (bool indicating if fuzzy was used) + * @return array Array with 'ids' (release IDs) and 'fuzzy' (bool indicating if fuzzy was used) */ public function searchReleasesWithFuzzy(array|string $phrases, int $limit = 1000, bool $forceFuzzy = false): array { @@ -895,9 +916,9 @@ class ManticoreSearchDriver implements SearchDriverInterface * * Uses Manticore's native fuzzy search with Levenshtein distance algorithm. * - * @param array|string $phrases Search phrases + * @param array|string $phrases Search phrases * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function fuzzySearchReleases(array|string $phrases, int $limit = 1000): array { @@ -932,9 +953,9 @@ class ManticoreSearchDriver implements SearchDriverInterface * - Wrong characters: "laptip" → "laptop" * * @param string $index Index to search - * @param array $searchArray Associative array of field => value to search + * @param array $searchArray Associative array of field => value to search * @param int $limit Maximum number of results - * @return array Array with 'id' and 'data' keys + * @return array Array with 'id' and 'data' keys */ public function fuzzySearchIndexes(string $index, array $searchArray, int $limit = 1000): array { @@ -1069,18 +1090,23 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Search predb index. * - * @param array|string $searchTerm Search term(s) - * @return array Array of predb records + * @param array|string $searchTerm Search term(s) + * @return array Array of predb records */ public function searchPredb(array|string $searchTerm): array { $searchString = is_array($searchTerm) ? implode(' ', $searchTerm) : $searchTerm; - $result = $this->searchIndexes($this->getPredbIndex(), $searchString, ['title', 'filename'], []); + $result = $this->searchIndexes($this->getPredbIndex(), $searchString, ['title', 'filename'], []); // @phpstan-ignore argument.type return $result['data'] ?? []; } + /** + * @param array $column + * @param array $searchArray + * @return array + */ public function searchIndexes(string $rt_index, ?string $searchString, array $column = [], array $searchArray = []): array { if (empty($rt_index)) { @@ -1155,7 +1181,7 @@ class ManticoreSearchDriver implements SearchDriverInterface if (count($column) > 1) { $searchColumns = '@('.implode(',', $column).')'; } else { - $searchColumns = '@'.$column[0]; + $searchColumns = '@'.$column[0]; // @phpstan-ignore offsetAccess.notFound } } @@ -1559,7 +1585,7 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Insert a movie into the movies search index. * - * @param array $parameters Movie data + * @param array $parameters Movie data */ public function insertMovie(array $parameters): void { @@ -1651,8 +1677,8 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Bulk insert multiple movies into the index. * - * @param array $movies Array of movie data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $movies Array of movie data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertMovies(array $movies): array { @@ -1703,15 +1729,15 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Search the movies index. * - * @param array|string $searchTerm Search term(s) + * @param array|string $searchTerm Search term(s) * @param int $limit Maximum number of results - * @return array Array with 'id' (movie IDs) and 'data' (movie data) + * @return array Array with 'id' (movie IDs) and 'data' (movie data) */ public function searchMovies(array|string $searchTerm, int $limit = 1000): array { $searchString = is_array($searchTerm) ? implode(' ', $searchTerm) : $searchTerm; - return $this->searchIndexes($this->getMoviesIndex(), $searchString, ['title', 'actors', 'director'], []); + return $this->searchIndexes($this->getMoviesIndex(), $searchString, ['title', 'actors', 'director'], []); // @phpstan-ignore argument.type } /** @@ -1719,7 +1745,7 @@ class ManticoreSearchDriver implements SearchDriverInterface * * @param string $field Field name (imdbid, tmdbid, traktid) * @param int|string $value The external ID value - * @return array|null Movie data or null if not found + * @return array|null Movie data or null if not found */ public function searchMovieByExternalId(string $field, int|string $value): ?array { @@ -1761,7 +1787,7 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Insert a TV show into the tvshows search index. * - * @param array $parameters TV show data + * @param array $parameters TV show data */ public function insertTvShow(array $parameters): void { @@ -1852,8 +1878,8 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Bulk insert multiple TV shows into the index. * - * @param array $tvShows Array of TV show data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $tvShows Array of TV show data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertTvShows(array $tvShows): array { @@ -1903,15 +1929,15 @@ class ManticoreSearchDriver implements SearchDriverInterface /** * Search the TV shows index. * - * @param array|string $searchTerm Search term(s) + * @param array|string $searchTerm Search term(s) * @param int $limit Maximum number of results - * @return array Array with 'id' (TV show IDs) and 'data' (TV show data) + * @return array Array with 'id' (TV show IDs) and 'data' (TV show data) */ public function searchTvShows(array|string $searchTerm, int $limit = 1000): array { $searchString = is_array($searchTerm) ? implode(' ', $searchTerm) : $searchTerm; - return $this->searchIndexes($this->getTvShowsIndex(), $searchString, ['title'], []); + return $this->searchIndexes($this->getTvShowsIndex(), $searchString, ['title'], []); // @phpstan-ignore argument.type } /** @@ -1919,7 +1945,7 @@ class ManticoreSearchDriver implements SearchDriverInterface * * @param string $field Field name (tvdb, trakt, tvmaze, tvrage, imdb, tmdb) * @param int|string $value The external ID value - * @return array|null TV show data or null if not found + * @return array|null TV show data or null if not found */ public function searchTvShowByExternalId(string $field, int|string $value): ?array { @@ -1962,9 +1988,9 @@ class ManticoreSearchDriver implements SearchDriverInterface * Search releases by external media IDs. * Used to find releases associated with a specific movie or TV show. * - * @param array $externalIds Associative array of external IDs + * @param array $externalIds Associative array of external IDs * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchReleasesByExternalId(array $externalIds, int $limit = 1000): array { @@ -2015,9 +2041,10 @@ class ManticoreSearchDriver implements SearchDriverInterface * Search releases by category ID using the search index. * This provides a fast way to get release IDs for a specific category without hitting the database. * - * @param array $categoryIds Array of category IDs to filter by + * @param array $categoryIds Array of category IDs to filter by * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return list + * @return array */ public function searchReleasesByCategory(array $categoryIds, int $limit = 1000): array { @@ -2044,7 +2071,7 @@ class ManticoreSearchDriver implements SearchDriverInterface // Use IN filter for multiple category IDs if (count($validCategoryIds) === 1) { - $query->filter('categories_id', '=', (int) $validCategoryIds[0]); + $query->filter('categories_id', '=', (int) $validCategoryIds[0]); // @phpstan-ignore offsetAccess.notFound } else { $query->filter('categories_id', 'in', array_map('intval', $validCategoryIds)); } @@ -2060,7 +2087,7 @@ class ManticoreSearchDriver implements SearchDriverInterface Cache::put($cacheKey, $resultIds, now()->addMinutes($this->config['cache_minutes'] ?? 5)); } - return $resultIds; + return $resultIds; // @phpstan-ignore return.type } catch (\Throwable $e) { Log::error('ManticoreSearch searchReleasesByCategory error: '.$e->getMessage(), [ 'categoryIds' => $categoryIds, @@ -2075,9 +2102,10 @@ class ManticoreSearchDriver implements SearchDriverInterface * First searches by text, then filters by category IDs using the search index. * * @param string $searchTerm Search text - * @param array $categoryIds Array of category IDs to filter by (empty for all categories) + * @param array $categoryIds Array of category IDs to filter by (empty for all categories) * @param int $limit Maximum number of results - * @return array Array of release IDs + * @return list + * @return array */ public function searchReleasesWithCategoryFilter(string $searchTerm, array $categoryIds = [], int $limit = 1000): array { @@ -2113,7 +2141,7 @@ class ManticoreSearchDriver implements SearchDriverInterface // Add category filter if provided if (! empty($validCategoryIds)) { if (count($validCategoryIds) === 1) { - $query->filter('categories_id', '=', (int) $validCategoryIds[0]); + $query->filter('categories_id', '=', (int) $validCategoryIds[0]); // @phpstan-ignore offsetAccess.notFound } else { $query->filter('categories_id', 'in', array_map('intval', $validCategoryIds)); } @@ -2130,7 +2158,7 @@ class ManticoreSearchDriver implements SearchDriverInterface Cache::put($cacheKey, $resultIds, now()->addMinutes($this->config['cache_minutes'] ?? 5)); } - return $resultIds; + return $resultIds; // @phpstan-ignore return.type } catch (\Throwable $e) { Log::error('ManticoreSearch searchReleasesWithCategoryFilter error: '.$e->getMessage(), [ 'searchTerm' => $searchTerm, diff --git a/app/Services/Search/MediaSearchService.php b/app/Services/Search/MediaSearchService.php index 5e99f2362..04a8ca763 100644 --- a/app/Services/Search/MediaSearchService.php +++ b/app/Services/Search/MediaSearchService.php @@ -25,8 +25,8 @@ class MediaSearchService /** * Find movie by any external ID and return cached movie data from index. * - * @param array $externalIds Array with keys like 'imdbid', 'tmdbid', 'traktid' - * @return array|null Movie data from search index + * @param array $externalIds Array with keys like 'imdbid', 'tmdbid', 'traktid' + * @return array|null Movie data from search index */ public function findMovie(array $externalIds): ?array { @@ -45,8 +45,8 @@ class MediaSearchService /** * Find TV show by any external ID and return cached show data from index. * - * @param array $externalIds Array with keys like 'tvdb', 'trakt', 'tvmaze', 'tvrage', 'imdb', 'tmdb' - * @return array|null TV show data from search index + * @param array $externalIds Array with keys like 'tvdb', 'trakt', 'tvmaze', 'tvrage', 'imdb', 'tmdb' + * @return array|null TV show data from search index */ public function findTvShow(array $externalIds): ?array { @@ -70,7 +70,7 @@ class MediaSearchService * * @param string $title Movie title to search * @param int $limit Maximum results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchMovieReleases(string $title, int $limit = 1000): array { @@ -128,7 +128,7 @@ class MediaSearchService * * @param string $title TV show title to search * @param int $limit Maximum results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchTvShowReleases(string $title, int $limit = 1000): array { @@ -186,7 +186,7 @@ class MediaSearchService * * @param int|string $imdbId IMDB ID (without 'tt' prefix) * @param int $limit Maximum results - * @return array Array of release IDs + * @return array Array of release IDs */ public function getReleasesByImdbId(int|string $imdbId, int $limit = 1000): array { @@ -198,7 +198,7 @@ class MediaSearchService * * @param int|string $tmdbId TMDB ID * @param int $limit Maximum results - * @return array Array of release IDs + * @return array Array of release IDs */ public function getReleasesByTmdbId(int|string $tmdbId, int $limit = 1000): array { @@ -210,7 +210,7 @@ class MediaSearchService * * @param int|string $tvdbId TVDB ID * @param int $limit Maximum results - * @return array Array of release IDs + * @return array Array of release IDs */ public function getReleasesByTvdbId(int|string $tvdbId, int $limit = 1000): array { @@ -222,7 +222,7 @@ class MediaSearchService * * @param int|string $traktId Trakt ID * @param int $limit Maximum results - * @return array Array of release IDs + * @return array Array of release IDs */ public function getReleasesByTraktId(int|string $traktId, int $limit = 1000): array { @@ -233,10 +233,10 @@ class MediaSearchService * Combined search: search by title and optionally by external IDs. * * @param string $title Media title - * @param array $externalIds Optional external IDs to narrow search + * @param array $externalIds Optional external IDs to narrow search * @param string $type 'movie' or 'tv' * @param int $limit Maximum results - * @return array Array of release IDs + * @return array Array of release IDs */ public function searchMedia(string $title, array $externalIds = [], string $type = 'movie', int $limit = 1000): array { @@ -257,7 +257,7 @@ class MediaSearchService * Get movie info from the search index (faster than DB query). * * @param int $movieInfoId MovieInfo ID - * @return array|null Movie data or null + * @return array|null Movie data or null */ public function getMovieFromIndex(int $movieInfoId): ?array { @@ -281,7 +281,7 @@ class MediaSearchService * Get TV show info from the search index (faster than DB query). * * @param int $videoId Video/TV show ID - * @return array|null TV show data or null + * @return array|null TV show data or null */ public function getTvShowFromIndex(int $videoId): ?array { diff --git a/app/Services/Search/SearchService.php b/app/Services/Search/SearchService.php index 145d3f72c..4453942fa 100644 --- a/app/Services/Search/SearchService.php +++ b/app/Services/Search/SearchService.php @@ -111,6 +111,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Get fuzzy search configuration. + * + * @return array */ public function getFuzzyConfig(): array { @@ -135,6 +137,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Insert a release into the search index. + * + * @param array $parameters */ public function insertRelease(array $parameters): void { @@ -159,6 +163,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Insert a predb record into the search index. + * + * @param array $parameters */ public function insertPredb(array $parameters): void { @@ -167,6 +173,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Update a predb record in the search index. + * + * @param array $parameters */ public function updatePreDb(array $parameters): void { @@ -175,6 +183,9 @@ class SearchService extends Manager implements SearchServiceInterface /** * Search the releases index. + * + * @param array $phrases + * @return array */ public function searchReleases(array|string $phrases, int $limit = 1000): array { @@ -186,6 +197,9 @@ class SearchService extends Manager implements SearchServiceInterface * * If exact search returns no results and fuzzy is enabled, this method * will automatically try a fuzzy search as a fallback. + * + * @param array $phrases + * @return array */ public function searchReleasesWithFuzzy(array|string $phrases, int $limit = 1000, bool $forceFuzzy = false): array { @@ -194,6 +208,9 @@ class SearchService extends Manager implements SearchServiceInterface /** * Perform fuzzy search on releases index. + * + * @param array $phrases + * @return array */ public function fuzzySearchReleases(array|string $phrases, int $limit = 1000): array { @@ -202,6 +219,9 @@ class SearchService extends Manager implements SearchServiceInterface /** * Search the predb index. + * + * @param array $searchTerm + * @return array */ public function searchPredb(array|string $searchTerm): array { @@ -227,7 +247,7 @@ class SearchService extends Manager implements SearchServiceInterface /** * Truncate/clear an index (remove all documents). * - * @param array|string $indexes Index name(s) to truncate + * @param array|string $indexes Index name(s) to truncate */ public function truncateIndex(array|string $indexes): void { @@ -245,8 +265,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Bulk insert multiple releases into the index. * - * @param array $releases Array of release data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $releases Array of release data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertReleases(array $releases): array { @@ -256,8 +276,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Bulk insert multiple predb records into the index. * - * @param array $predbRecords Array of predb data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $predbRecords Array of predb data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertPredb(array $predbRecords): array { @@ -292,6 +312,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Insert a movie into the movies search index. + * + * @param array $parameters */ public function insertMovie(array $parameters): void { @@ -317,8 +339,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Bulk insert multiple movies into the index. * - * @param array $movies Array of movie data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $movies Array of movie data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertMovies(array $movies): array { @@ -327,6 +349,9 @@ class SearchService extends Manager implements SearchServiceInterface /** * Search the movies index. + * + * @param array $searchTerm + * @return array */ public function searchMovies(array|string $searchTerm, int $limit = 1000): array { @@ -335,6 +360,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Search movies by external ID (IMDB, TMDB, Trakt). + * + * @return array */ public function searchMovieByExternalId(string $field, int|string $value): ?array { @@ -343,6 +370,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Insert a TV show into the tvshows search index. + * + * @param array $parameters */ public function insertTvShow(array $parameters): void { @@ -368,8 +397,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Bulk insert multiple TV shows into the index. * - * @param array $tvShows Array of TV show data arrays - * @return array Results with 'success' and 'errors' counts + * @param array $tvShows Array of TV show data arrays + * @return array Results with 'success' and 'errors' counts */ public function bulkInsertTvShows(array $tvShows): array { @@ -378,6 +407,9 @@ class SearchService extends Manager implements SearchServiceInterface /** * Search the TV shows index. + * + * @param array $searchTerm + * @return array */ public function searchTvShows(array|string $searchTerm, int $limit = 1000): array { @@ -386,6 +418,8 @@ class SearchService extends Manager implements SearchServiceInterface /** * Search TV shows by external ID (TVDB, Trakt, TVMaze, TVRage, IMDB, TMDB). + * + * @return array */ public function searchTvShowByExternalId(string $field, int|string $value): ?array { @@ -395,6 +429,9 @@ class SearchService extends Manager implements SearchServiceInterface /** * Search releases by external media IDs. * Used to find releases associated with a specific movie or TV show. + * + * @param array $externalIds + * @return array */ public function searchReleasesByExternalId(array $externalIds, int $limit = 1000): array { @@ -404,6 +441,9 @@ class SearchService extends Manager implements SearchServiceInterface /** * Search releases by category ID using the search index. * This provides a fast way to get release IDs for a specific category without hitting the database. + * + * @param array $categoryIds + * @return array */ public function searchReleasesByCategory(array $categoryIds, int $limit = 1000): array { @@ -413,6 +453,9 @@ class SearchService extends Manager implements SearchServiceInterface /** * Combined search: text search with category filtering. * First searches by text, then filters by category IDs using the search index. + * + * @param array $categoryIds + * @return array */ public function searchReleasesWithCategoryFilter(string $searchTerm, array $categoryIds = [], int $limit = 1000): array { diff --git a/app/Services/SteamService.php b/app/Services/SteamService.php index 5518ede35..0900053c9 100644 --- a/app/Services/SteamService.php +++ b/app/Services/SteamService.php @@ -128,38 +128,39 @@ class SteamService /** * Get complete game details from Steam. * - * @return array{ - * title: string, - * steamid: int, - * description: ?string, - * detailed_description: ?string, - * about: ?string, - * short_description: ?string, - * cover: ?string, - * backdrop: ?string, - * screenshots: array, - * movies: array, - * trailer: ?string, - * publisher: ?string, - * developers: array, - * releasedate: ?string, - * genres: string, - * categories: array, - * rating: ?int, - * metacritic_score: ?int, - * metacritic_url: ?string, - * price: ?array, - * platforms: array, - * requirements: array, - * dlc: array, - * achievements: ?int, - * recommendations: ?int, - * website: ?string, - * support_url: ?string, - * legal_notice: ?string, - * directurl: string, - * type: string, - * }|false + * @return array + * title: string, + * steamid: int, + * description: ?string, + * detailed_description: ?string, + * about: ?string, + * short_description: ?string, + * cover: ?string, + * backdrop: ?string, + * screenshots: array, + * movies: array, + * trailer: ?string, + * publisher: ?string, + * developers: array, + * releasedate: ?string, + * genres: string, + * categories: array, + * rating: ?int, + * metacritic_score: ?int, + * metacritic_url: ?string, + * price: ?array, + * platforms: array, + * requirements: array, + * dlc: array, + * achievements: ?int, + * recommendations: ?int, + * website: ?string, + * support_url: ?string, + * legal_notice: ?string, + * directurl: string, + * type: string, + * }|false + * @return array */ public function getGameDetails(int $appId): array|false { @@ -184,6 +185,8 @@ class SteamService /** * Alias for getGameDetails for backward compatibility. + * + * @return array */ public function getAll(int $appId): array|false { @@ -229,6 +232,8 @@ class SteamService /** * Get game reviews summary. + * + * @return array */ public function getReviewsSummary(int $appId): ?array { @@ -272,6 +277,8 @@ class SteamService /** * Get DLC list for a game. + * + * @return array */ public function getDLCList(int $appId): array { @@ -302,6 +309,8 @@ class SteamService /** * Populate the steam_apps table with the full app list from Steam. + * + * @return list> */ public function populateSteamAppsTable(?callable $progressCallback = null): array { @@ -385,6 +394,8 @@ class SteamService /** * Get the full list of Steam apps. + * + * @return array{inserted: int<0, max>, updated: 0, skipped: int<0, max>, errors: int<0, max>} */ public function getFullAppList(): array { @@ -415,9 +426,9 @@ class SteamService /** * Search for games and return multiple matches. * - * @return Collection + * @return array{} */ - public function searchMultiple(string $title, int $limit = 10): Collection + public function searchMultiple(string $title, int $limit = 10): Collection // @phpstan-ignore missingType.generics { $cleanTitle = $this->cleanTitle($title); if (empty($cleanTitle)) { @@ -544,6 +555,8 @@ class SteamService /** * Fetch app details from Steam API. + * + * @return array */ protected function fetchAppDetails(int $appId): ?array { @@ -581,6 +594,9 @@ class SteamService /** * Transform Steam API response to our standard format. + * + * @param array $data + * @return array */ protected function transformAppDetails(array $data, int $appId): array { @@ -744,6 +760,8 @@ class SteamService /** * Check if the app is a game (not DLC, video, etc.). + * + * @param array $data */ protected function isGameType(array $data): bool { @@ -754,6 +772,9 @@ class SteamService /** * Make a rate-limited request to Steam API. + * + * @param array $params + * @return array */ protected function makeRequest(string $url, array $params = []): ?array { @@ -1019,6 +1040,8 @@ class SteamService /** * Tokenize a string. + * + * @return array */ protected function tokenize(string $s): array { @@ -1039,6 +1062,8 @@ class SteamService /** * Replace roman numerals with arabic numbers. + * + * @return list */ protected function replaceRomanNumerals(string $s): string { diff --git a/app/Services/SystemMetricsService.php b/app/Services/SystemMetricsService.php index 3e85367d4..d451e3fa7 100644 --- a/app/Services/SystemMetricsService.php +++ b/app/Services/SystemMetricsService.php @@ -34,6 +34,8 @@ class SystemMetricsService /** * Get historical metrics grouped by hour for the last N hours + * + * @return array */ public function getHourlyMetrics(string $type, int $hours = 24): array { @@ -69,11 +71,13 @@ class SystemMetricsService } // Fill missing hours with null or last known value - return $this->fillMissingHours($result, $hours); + return $this->fillMissingHours($result, $hours); // @phpstan-ignore argument.type } /** * Get historical metrics grouped by day for the last N days + * + * @return list> */ public function getDailyMetrics(string $type, int $days = 30): array { @@ -113,6 +117,9 @@ class SystemMetricsService /** * Fill missing hours with previous value or 0 + * + * @param array $data + * @return list> */ protected function fillMissingHours(array $data, int $hours): array { @@ -135,6 +142,8 @@ class SystemMetricsService /** * Get current CPU usage percentage + * + * @return non-empty-array */ protected function getCpuUsage(): float { @@ -190,6 +199,8 @@ class SystemMetricsService /** * Get RAM usage information + * + * @return array */ protected function getRamUsage(): array { diff --git a/app/Services/TmdbClient.php b/app/Services/TmdbClient.php index ebc72aa1e..eadc8b36d 100644 --- a/app/Services/TmdbClient.php +++ b/app/Services/TmdbClient.php @@ -45,8 +45,8 @@ class TmdbClient * Make a GET request to the TMDB API * * @param string $endpoint The API endpoint - * @param array $params Additional query parameters - * @return array|null Response data or null on failure + * @param array $params Additional query parameters + * @return array|null Response data or null on failure */ protected function get(string $endpoint, array $params = []): ?array { @@ -130,7 +130,7 @@ class TmdbClient * @param string $query The search query * @param int $page Page number for pagination * @param string|null $year Filter by release year - * @return array|null Search results or null on failure + * @return array|null Search results or null on failure */ public function searchMovies(string $query, int $page = 1, ?string $year = null): ?array { @@ -151,8 +151,8 @@ class TmdbClient * Get movie details by TMDB ID or IMDB ID * * @param int|string $id The TMDB ID or IMDB ID (with 'tt' prefix) - * @param array $appendToResponse Additional data to append (e.g., ['credits', 'external_ids']) - * @return array|null Movie data or null on failure + * @param array $appendToResponse Additional data to append (e.g., ['credits', 'external_ids']) + * @return array|null Movie data or null on failure */ public function getMovie(int|string $id, array $appendToResponse = []): ?array { @@ -169,7 +169,7 @@ class TmdbClient * Get movie credits (cast and crew) * * @param int $movieId The TMDB movie ID - * @return array|null Credits data or null on failure + * @return array|null Credits data or null on failure */ public function getMovieCredits(int $movieId): ?array { @@ -180,7 +180,7 @@ class TmdbClient * Get movie external IDs (IMDB, etc.) * * @param int $movieId The TMDB movie ID - * @return array|null External IDs or null on failure + * @return array|null External IDs or null on failure */ public function getMovieExternalIds(int $movieId): ?array { @@ -197,7 +197,7 @@ class TmdbClient * @param string $query The search query * @param int $page Page number for pagination * @param int|null $firstAirDateYear Filter by first air date year - * @return array|null Search results or null on failure + * @return array|null Search results or null on failure */ public function searchTv(string $query, int $page = 1, ?int $firstAirDateYear = null): ?array { @@ -218,8 +218,8 @@ class TmdbClient * Get TV show details by ID * * @param int|string $id The TMDB TV show ID - * @param array $appendToResponse Additional data to append - * @return array|null TV show data or null on failure + * @param array $appendToResponse Additional data to append + * @return array|null TV show data or null on failure */ public function getTvShow(int|string $id, array $appendToResponse = []): ?array { @@ -236,7 +236,7 @@ class TmdbClient * Get TV show external IDs (IMDB, TVDB, etc.) * * @param int $tvId The TMDB TV show ID - * @return array|null External IDs or null on failure + * @return array|null External IDs or null on failure */ public function getTvExternalIds(int $tvId): ?array { @@ -247,7 +247,7 @@ class TmdbClient * Get TV show alternative titles * * @param int $tvId The TMDB TV show ID - * @return array|null Alternative titles or null on failure + * @return array|null Alternative titles or null on failure */ public function getTvAlternativeTitles(int $tvId): ?array { @@ -259,7 +259,7 @@ class TmdbClient * * @param int $tvId The TMDB TV show ID * @param int $seasonNumber The season number - * @return array|null Season data or null on failure + * @return array|null Season data or null on failure */ public function getTvSeason(int $tvId, int $seasonNumber): ?array { @@ -277,7 +277,7 @@ class TmdbClient * @param int $tvId The TMDB TV show ID * @param int $seasonNumber The season number * @param int $episodeNumber The episode number - * @return array|null Episode data or null on failure + * @return array|null Episode data or null on failure */ public function getTvEpisode(int $tvId, int $seasonNumber, int $episodeNumber): ?array { @@ -294,7 +294,7 @@ class TmdbClient * * @param string $externalId The external ID value * @param string $source The source: 'imdb_id', 'tvdb_id', 'tvrage_id' - * @return array|null The TMDB TV show data or null if not found + * @return array|null The TMDB TV show data or null if not found */ public function findTvByExternalId(string $externalId, string $source = 'tvdb_id'): ?array { @@ -323,10 +323,10 @@ class TmdbClient * Get TV episode with fallback using multiple external IDs. * Tries TMDB ID first, then looks up by TVDB or IMDB if needed. * - * @param array $ids Array of IDs: ['tmdb' => X, 'tvdb' => Y, 'imdb' => Z] + * @param array $ids Array of IDs: ['tmdb' => X, 'tvdb' => Y, 'imdb' => Z] * @param int $seasonNumber The season number * @param int $episodeNumber The episode number - * @return array|null Episode data or null on failure + * @return array|null Episode data or null on failure */ public function getTvEpisodeWithFallback(array $ids, int $seasonNumber, int $episodeNumber): ?array { @@ -377,7 +377,7 @@ class TmdbClient * * @param int|string $id The external ID * @param string $source The ID source: 'tmdb', 'tvdb', 'imdb' - * @return array|null Array with all IDs: ['tmdb' => X, 'imdb' => Y, 'tvdb' => Z] or null + * @return array|null Array with all IDs: ['tmdb' => X, 'imdb' => Y, 'tvdb' => Z] or null */ public function lookupTvShowIds(int|string $id, string $source = 'tmdb'): ?array { @@ -435,6 +435,8 @@ class TmdbClient /** * Safely get a string value from an array + * + * @param array $data */ public static function getString(array $data, string $key, string $default = ''): string { @@ -443,6 +445,8 @@ class TmdbClient /** * Safely get an integer value from an array + * + * @param array $data */ public static function getInt(array $data, string $key, int $default = 0): int { @@ -451,6 +455,8 @@ class TmdbClient /** * Safely get a float value from an array + * + * @param array $data */ public static function getFloat(array $data, string $key, float $default = 0.0): float { @@ -459,6 +465,10 @@ class TmdbClient /** * Safely get an array value from an array + * + * @param array $data + * @param array $default + * @return array */ public static function getArray(array $data, string $key, array $default = []): array { @@ -467,6 +477,8 @@ class TmdbClient /** * Safely get a nested value from an array using dot notation + * + * @param array $data */ public static function getNested(array $data, string $path, mixed $default = null): mixed { diff --git a/app/Services/Tmux/Tmux.php b/app/Services/Tmux/Tmux.php index 4d2d818b7..202937cb1 100644 --- a/app/Services/Tmux/Tmux.php +++ b/app/Services/Tmux/Tmux.php @@ -19,7 +19,7 @@ class Tmux */ public \Closure|\PDO $pdo; - public $tmux_session; + public mixed $tmux_session; /** * Tmux constructor. @@ -32,7 +32,7 @@ class Tmux /** * @return mixed */ - public function getConnectionsInfo($constants) + public function getConnectionsInfo(mixed $constants) { $runVar['connections']['port_a'] = $runVar['connections']['host_a'] = $runVar['connections']['ip_a'] = false; $runVar['connections']['port'] = config('nntmux_nntp.port'); @@ -47,7 +47,7 @@ class Tmux return $runVar['connections']; } - public function getUSPConnections(string $which, $connections): mixed + public function getUSPConnections(string $which, mixed $connections): mixed { switch ($which) { case 'alternate': @@ -96,7 +96,10 @@ class Tmux return $runVar['conncounts']; } - public function getListOfPanes($constants): array + /** + * @return array + */ + public function getListOfPanes(mixed $constants): array { $panes = ['zero' => '', 'one' => '', 'two' => '']; switch ($constants['sequential']) { @@ -120,6 +123,9 @@ class Tmux return $panes; } + /** + * @return array + */ public function getConstantSettings(): array { $settings = [ @@ -142,6 +148,9 @@ class Tmux return $constants; } + /** + * @return array + */ public function getMonitorSettings(): array { $settingsMap = [ @@ -202,7 +211,7 @@ class Tmux ->toArray(); } - public function updateItem($setting, $value): int + public function updateItem(mixed $setting, mixed $value): int { return Settings::query()->where('name', '=', $setting)->update(['value' => $value]); } @@ -239,7 +248,7 @@ class Tmux return round($bytes, 2).' '.$types[$index]; } - public function writelog($pane): ?string + public function writelog(mixed $pane): ?string { $path = storage_path('logs'); $getDate = now()->format('Y_m_d'); @@ -254,7 +263,7 @@ class Tmux /** * @throws \Exception */ - public function get_color($colors_start, $colors_end, $colors_exc): int + public function get_color(mixed $colors_start, mixed $colors_end, mixed $colors_exc): int { // Handle null values with sensible defaults $colors_start = $colors_start ?? 0; @@ -276,7 +285,7 @@ class Tmux return $number; } - public function relativeTime($_time): string + public function relativeTime(mixed $_time): string { return Carbon::createFromTimestamp($_time, date_default_timezone_get())->ago(); } @@ -284,7 +293,7 @@ class Tmux /** * @throws \Exception */ - public function proc_query($qry, $bookreqids, string $db_name, ?string $ppmax = '', ?string $ppmin = ''): bool|string + public function proc_query(mixed $qry, mixed $bookreqids, string $db_name, ?string $ppmax = '', ?string $ppmin = ''): bool|string { // Convert null to empty string for backward compatibility $ppmax = $ppmax ?? ''; @@ -430,6 +439,9 @@ class Tmux } } + /** + * @return array + */ public function cbpmTableQuery(): array { return DB::select( diff --git a/app/Services/Tmux/TmuxLayoutBuilder.php b/app/Services/Tmux/TmuxLayoutBuilder.php index 28be586c6..9258e4cfc 100644 --- a/app/Services/Tmux/TmuxLayoutBuilder.php +++ b/app/Services/Tmux/TmuxLayoutBuilder.php @@ -20,6 +20,8 @@ class TmuxLayoutBuilder /** * Pane name icons mapping - uses Nerd Font symbols * Requires a Nerd Font to display properly (FiraCode NF, JetBrains Mono NF, etc.) + * + * @var array */ protected array $paneIcons = [ // Core processing @@ -338,6 +340,8 @@ class TmuxLayoutBuilder * - 'use_sail' => bool - whether to use sail to run inside Docker * - 'override_host' => bool - whether to override REDIS_HOST env var * - 'host' => string - the host to use (only relevant if override_host is true) + * + * @return array */ protected function resolveRedisConnection(string $host, int $port): array { diff --git a/app/Services/Tmux/TmuxMonitorService.php b/app/Services/Tmux/TmuxMonitorService.php index 3728d63cf..b918cf51a 100644 --- a/app/Services/Tmux/TmuxMonitorService.php +++ b/app/Services/Tmux/TmuxMonitorService.php @@ -15,6 +15,9 @@ class TmuxMonitorService { protected Tmux $tmux; + /** + * @var array + */ protected array $runVar = []; protected int $iterations = 1; @@ -28,6 +31,8 @@ class TmuxMonitorService /** * Initialize monitor with default values + * + * @return array */ public function initializeMonitor(): array { @@ -72,6 +77,8 @@ class TmuxMonitorService /** * Initialize all timers + * + * @return array */ protected function initializeTimers(): array { @@ -109,6 +116,8 @@ class TmuxMonitorService /** * Collect current statistics + * + * @return array */ public function collectStatistics(): array { @@ -461,6 +470,8 @@ class TmuxMonitorService /** * Get current run variables + * + * @return array */ public function getRunVar(): array { diff --git a/app/Services/Tmux/TmuxOutput.php b/app/Services/Tmux/TmuxOutput.php index 85b6c1cf7..fdbf11185 100644 --- a/app/Services/Tmux/TmuxOutput.php +++ b/app/Services/Tmux/TmuxOutput.php @@ -12,11 +12,11 @@ use Illuminate\Support\Facades\Process; */ class TmuxOutput extends Tmux { - protected $_colourMasks; + protected mixed $_colourMasks; - private $runVar; + private mixed $runVar; - private $tmpMasks; + private mixed $tmpMasks; /** * TmuxOutput constructor. @@ -30,7 +30,7 @@ class TmuxOutput extends Tmux $this->_setColourMasks(); } - public function updateMonitorPane(&$runVar): void + public function updateMonitorPane(mixed &$runVar): void { $this->runVar = $runVar; $this->tmpMasks = $this->_getFormatMasks(config('nntmux_nntp.compressed_headers')); @@ -90,7 +90,10 @@ class TmuxOutput extends Tmux return $buffer; } - protected function _getFormatMasks($compressed): array + /** + * @return array + */ + protected function _getFormatMasks(mixed $compressed): array { $index = ($compressed === true ? '2.1' : '2.0'); diff --git a/app/Services/Tmux/TmuxSessionManager.php b/app/Services/Tmux/TmuxSessionManager.php index 98058818e..b72f753c0 100644 --- a/app/Services/Tmux/TmuxSessionManager.php +++ b/app/Services/Tmux/TmuxSessionManager.php @@ -94,6 +94,8 @@ class TmuxSessionManager /** * List all panes in the session + * + * @return array */ public function listPanes(): array { diff --git a/app/Services/Tmux/TmuxTaskRunner.php b/app/Services/Tmux/TmuxTaskRunner.php index a0a58d1f3..f0593b474 100644 --- a/app/Services/Tmux/TmuxTaskRunner.php +++ b/app/Services/Tmux/TmuxTaskRunner.php @@ -42,6 +42,8 @@ class TmuxTaskRunner /** * Run a task in a specific pane + * + * @param array $config */ public function runTask(string $taskName, array $config): bool { @@ -80,6 +82,8 @@ class TmuxTaskRunner /** * Build a command with logging + * + * @param array $options */ public function buildCommand(string $baseCommand, array $options = []): string { @@ -171,6 +175,8 @@ class TmuxTaskRunner /** * Run the IRC scraper + * + * @param array $config */ public function runIRCScraper(array $config): bool { @@ -191,6 +197,8 @@ class TmuxTaskRunner /** * Run binaries update + * + * @param array $config */ public function runBinariesUpdate(array $config): bool { @@ -225,6 +233,8 @@ class TmuxTaskRunner /** * Run backfill + * + * @param array $config */ public function runBackfill(array $config): bool { @@ -269,6 +279,8 @@ class TmuxTaskRunner /** * Run releases update + * + * @param array $config */ public function runReleasesUpdate(array $config): bool { @@ -291,8 +303,8 @@ class TmuxTaskRunner * Run a specific pane task based on task name * * @param string $taskName The name of the task to run - * @param array $config Configuration for the task (target pane, etc.) - * @param array $runVar Runtime variables and settings + * @param array $config Configuration for the task (target pane, etc.) + * @param array $runVar Runtime variables and settings * @return bool Success status */ public function runPaneTask(string $taskName, array $config, array $runVar): bool @@ -317,6 +329,8 @@ class TmuxTaskRunner /** * Run main task (varies by sequential mode) + * + * @param array $runVar */ protected function runMainTask(int $sequential, array $runVar): bool { @@ -330,6 +344,8 @@ class TmuxTaskRunner /** * Run main non-sequential task (binaries, backfill, releases) + * + * @param array $runVar */ protected function runMainNonSequential(array $runVar): bool { @@ -344,6 +360,8 @@ class TmuxTaskRunner /** * Run main basic sequential task (just releases) + * + * @param array $runVar */ protected function runMainBasic(array $runVar): bool { @@ -352,6 +370,8 @@ class TmuxTaskRunner /** * Run main full sequential task + * + * @param array $runVar */ protected function runMainSequential(array $runVar): bool { @@ -368,6 +388,8 @@ class TmuxTaskRunner /** * Run fix release names task + * + * @param array $runVar */ protected function runFixNamesTask(array $runVar): bool { @@ -402,6 +424,8 @@ class TmuxTaskRunner /** * Run remove crap releases task + * + * @param array $runVar */ protected function runRemoveCrapTask(array $runVar): bool { @@ -482,6 +506,8 @@ class TmuxTaskRunner /** * Load crap removal state + * + * @return array */ protected function loadCrapState(string $file): array { @@ -497,6 +523,8 @@ class TmuxTaskRunner /** * Save crap removal state + * + * @param array $state */ protected function saveCrapState(string $file, array $state): void { @@ -510,6 +538,8 @@ class TmuxTaskRunner /** * Run post-process additional task + * + * @param array $runVar */ protected function runPostProcessAdditional(array $runVar): bool { @@ -573,6 +603,8 @@ class TmuxTaskRunner /** * Run TV/Anime post-processing + * + * @param array $runVar */ protected function runTvTask(array $runVar): bool { @@ -631,6 +663,8 @@ class TmuxTaskRunner /** * Run Movies post-processing + * + * @param array $runVar */ protected function runMoviesTask(array $runVar): bool { @@ -669,6 +703,8 @@ class TmuxTaskRunner * Legacy method for backward compatibility - now just calls runTvTask * * @deprecated Use runTvTask() instead + * + * @param array $runVar */ protected function runNonAmazonTask(array $runVar): bool { @@ -677,6 +713,8 @@ class TmuxTaskRunner /** * Run Amazon post-processing (Books, Music, Games, Console) + * + * @param array $runVar */ protected function runAmazonTask(array $runVar): bool { @@ -744,6 +782,8 @@ class TmuxTaskRunner /** * Run XXX post-processing + * + * @param array $runVar */ protected function runXXXTask(array $runVar): bool { diff --git a/app/Services/TraktService.php b/app/Services/TraktService.php index 04a9356a6..335e701bc 100644 --- a/app/Services/TraktService.php +++ b/app/Services/TraktService.php @@ -51,6 +51,8 @@ class TraktService /** * Get the request headers for Trakt API. + * + * @return array */ protected function getHeaders(): array { @@ -65,8 +67,8 @@ class TraktService * Make a GET request to the Trakt API. * * @param string $endpoint The API endpoint - * @param array $params Query parameters - * @return array|null Response data or null on failure + * @param array $params Query parameters + * @return array|null Response data or null on failure */ protected function get(string $endpoint, array $params = []): ?array { @@ -145,7 +147,7 @@ class TraktService * @param int|string $episode The episode number * @param string $extended Extended info level: 'min', 'full', 'aliases', 'full,aliases' * @param string $idType The ID type: 'trakt', 'imdb', 'tmdb', 'tvdb' (default: 'trakt') - * @return array|null Episode data or null on failure + * @return array|null Episode data or null on failure */ public function getEpisodeSummary( int|string $showId, @@ -189,11 +191,11 @@ class TraktService * Get episode summary with fallback to multiple ID types. * Tries Trakt ID first, then falls back to TMDB, TVDB, and IMDB. * - * @param array $ids Array of IDs: ['trakt' => X, 'tmdb' => Y, 'tvdb' => Z, 'imdb' => W] + * @param array $ids Array of IDs: ['trakt' => X, 'tmdb' => Y, 'tvdb' => Z, 'imdb' => W] * @param int|string $season The season number * @param int|string $episode The episode number * @param string $extended Extended info level - * @return array|null Episode data or null on failure + * @return array|null Episode data or null on failure */ public function getEpisodeSummaryWithFallback( array $ids, @@ -242,7 +244,7 @@ class TraktService * * @param int|string $showId Show ID * @param string $idType The ID type: 'trakt', 'imdb', 'tmdb', 'tvdb' - * @return array|null Show data with all IDs or null on failure + * @return array|null Show data with all IDs or null on failure */ public function getShowWithAllIds(int|string $showId, string $idType = 'trakt'): ?array { @@ -264,7 +266,7 @@ class TraktService * * @param int|string $id The external ID * @param string $idType The ID type: 'imdb', 'tmdb', 'tvdb' - * @return array|null Array with all IDs: ['trakt' => X, 'imdb' => Y, 'tmdb' => Z, 'tvdb' => W] or null + * @return array|null Array with all IDs: ['trakt' => X, 'imdb' => Y, 'tmdb' => Z, 'tvdb' => W] or null */ public function lookupShowIds(int|string $id, string $idType = 'tmdb'): ?array { @@ -281,7 +283,7 @@ class TraktService // Get the first matching show $show = $results[0]['show'] ?? null; - if ($show === null || ! isset($show['ids'])) { + if ($show === null || ! isset($show['ids'])) { // @phpstan-ignore isset.offset return null; } @@ -298,7 +300,7 @@ class TraktService /** * Get current box office movies. * - * @return array|null Box office data or null on failure + * @return array|null Box office data or null on failure */ public function getBoxOffice(): ?array { @@ -314,7 +316,7 @@ class TraktService * * @param string $startDate Start date (YYYY-MM-DD format, defaults to today) * @param int $days Number of days to retrieve (default: 7) - * @return array|null Calendar data or null on failure + * @return array|null Calendar data or null on failure */ public function getCalendar(string $startDate = '', int $days = 7): ?array { @@ -334,7 +336,7 @@ class TraktService * * @param string $movie Movie slug or ID * @param string $extended Extended info level: 'min' or 'full' - * @return array|null Movie data or null on failure + * @return array|null Movie data or null on failure */ public function getMovieSummary(string $movie, string $extended = 'min'): ?array { @@ -370,7 +372,7 @@ class TraktService * @param int|string $id The ID to search for * @param string $idType The ID type: 'imdb', 'tmdb', 'trakt', 'tvdb' * @param string $mediaType Media type: 'movie', 'show', 'episode', or empty for all - * @return array|null Search results or null on failure + * @return array|null Search results or null on failure */ public function searchById(int|string $id, string $idType = 'trakt', string $mediaType = ''): ?array { @@ -403,7 +405,7 @@ class TraktService * * @param string $query Search query * @param string $type Search type: 'show', 'movie', 'episode', 'person', 'list' - * @return array|null Search results or null on failure + * @return array|null Search results or null on failure */ public function searchShows(string $query, string $type = 'show'): ?array { @@ -424,7 +426,7 @@ class TraktService * * @param string $show Show slug or ID * @param string $extended Extended info level: 'min' or 'full' - * @return array|null Show data or null on failure + * @return array|null Show data or null on failure */ public function getShowSummary(string $show, string $extended = 'full'): ?array { @@ -446,7 +448,7 @@ class TraktService * * @param string $show Show slug or ID * @param string $extended Extended info level - * @return array|null Seasons data or null on failure + * @return array|null Seasons data or null on failure */ public function getShowSeasons(string $show, string $extended = 'full'): ?array { @@ -468,7 +470,7 @@ class TraktService * @param string $show Show slug or ID * @param int $season Season number * @param string $extended Extended info level - * @return array|null Episodes data or null on failure + * @return array|null Episodes data or null on failure */ public function getSeasonEpisodes(string $show, int $season, string $extended = 'full'): ?array { @@ -489,7 +491,7 @@ class TraktService * * @param int $limit Number of results to return * @param string $extended Extended info level - * @return array|null Trending shows or null on failure + * @return array|null Trending shows or null on failure */ public function getTrendingShows(int $limit = 10, string $extended = 'full'): ?array { @@ -508,7 +510,7 @@ class TraktService * * @param int $limit Number of results to return * @param string $extended Extended info level - * @return array|null Trending movies or null on failure + * @return array|null Trending movies or null on failure */ public function getTrendingMovies(int $limit = 10, string $extended = 'full'): ?array { @@ -527,7 +529,7 @@ class TraktService * * @param int $limit Number of results to return * @param string $extended Extended info level - * @return array|null Popular shows or null on failure + * @return array|null Popular shows or null on failure */ public function getPopularShows(int $limit = 10, string $extended = 'full'): ?array { @@ -546,7 +548,7 @@ class TraktService * * @param int $limit Number of results to return * @param string $extended Extended info level - * @return array|null Popular movies or null on failure + * @return array|null Popular movies or null on failure */ public function getPopularMovies(int $limit = 10, string $extended = 'full'): ?array { diff --git a/app/Services/TurnstileService.php b/app/Services/TurnstileService.php index 2edc7cd94..117f9063e 100644 --- a/app/Services/TurnstileService.php +++ b/app/Services/TurnstileService.php @@ -37,6 +37,8 @@ class TurnstileService /** * Get the Turnstile HTML widget + * + * @param array $attributes */ public static function display(array $attributes = []): string { diff --git a/app/Services/TvProcessing/Pipes/AbstractTvProviderPipe.php b/app/Services/TvProcessing/Pipes/AbstractTvProviderPipe.php index e3eb0b357..352a756c1 100644 --- a/app/Services/TvProcessing/Pipes/AbstractTvProviderPipe.php +++ b/app/Services/TvProcessing/Pipes/AbstractTvProviderPipe.php @@ -17,6 +17,9 @@ abstract class AbstractTvProviderPipe protected bool $echoOutput = true; + /** + * @var array + */ protected array $titleCache = []; public function __construct() {} diff --git a/app/Services/TvProcessing/Pipes/LocalDbPipe.php b/app/Services/TvProcessing/Pipes/LocalDbPipe.php index 57e973d06..ce400b342 100644 --- a/app/Services/TvProcessing/Pipes/LocalDbPipe.php +++ b/app/Services/TvProcessing/Pipes/LocalDbPipe.php @@ -132,6 +132,8 @@ class LocalDbPipe extends AbstractTvProviderPipe /** * Check if parsed info has valid episode numbers. + * + * @param array $parsedInfo */ private function hasEpisodeNumbers(array $parsedInfo): bool { diff --git a/app/Services/TvProcessing/Pipes/TmdbPipe.php b/app/Services/TvProcessing/Pipes/TmdbPipe.php index 550860432..885a181ae 100644 --- a/app/Services/TvProcessing/Pipes/TmdbPipe.php +++ b/app/Services/TvProcessing/Pipes/TmdbPipe.php @@ -210,6 +210,8 @@ class TmdbPipe extends AbstractTvProviderPipe /** * Process episode matching for a video that already exists in local DB. * This is used when the show was added from another source and doesn't have a TMDB ID. + * + * @param array $parsedInfo */ private function processEpisodeForExistingVideo( TvProcessingPassable $passable, diff --git a/app/Services/TvProcessing/Pipes/TraktPipe.php b/app/Services/TvProcessing/Pipes/TraktPipe.php index b6d808a36..a4a9cafc2 100644 --- a/app/Services/TvProcessing/Pipes/TraktPipe.php +++ b/app/Services/TvProcessing/Pipes/TraktPipe.php @@ -202,6 +202,8 @@ class TraktPipe extends AbstractTvProviderPipe /** * Process episode matching for a video that already exists in local DB. * This is used when the show was added from another source (e.g., TMDB) and doesn't have a Trakt ID. + * + * @param array $parsedInfo */ private function processEpisodeForExistingVideo( TvProcessingPassable $passable, diff --git a/app/Services/TvProcessing/Pipes/TvMazePipe.php b/app/Services/TvProcessing/Pipes/TvMazePipe.php index de052d099..a7de4a084 100644 --- a/app/Services/TvProcessing/Pipes/TvMazePipe.php +++ b/app/Services/TvProcessing/Pipes/TvMazePipe.php @@ -211,6 +211,8 @@ class TvMazePipe extends AbstractTvProviderPipe /** * Process episode matching for a video that already exists in local DB. * This is used when the show was added from another source (e.g., TMDB) and doesn't have a TVMaze ID. + * + * @param array $parsedInfo */ private function processEpisodeForExistingVideo( TvProcessingPassable $passable, diff --git a/app/Services/TvProcessing/Pipes/TvdbPipe.php b/app/Services/TvProcessing/Pipes/TvdbPipe.php index 5bee12277..2d370167e 100644 --- a/app/Services/TvProcessing/Pipes/TvdbPipe.php +++ b/app/Services/TvProcessing/Pipes/TvdbPipe.php @@ -240,6 +240,8 @@ class TvdbPipe extends AbstractTvProviderPipe /** * Process episode matching for a video that already exists in local DB. * This is used when the show was added from another source (e.g., TMDB) and doesn't have a TVDB ID. + * + * @param array $parsedInfo */ private function processEpisodeForExistingVideo( TvProcessingPassable $passable, diff --git a/app/Services/TvProcessing/Providers/AbstractTvProvider.php b/app/Services/TvProcessing/Providers/AbstractTvProvider.php index 4426de141..c77bc5da3 100644 --- a/app/Services/TvProcessing/Providers/AbstractTvProvider.php +++ b/app/Services/TvProcessing/Providers/AbstractTvProvider.php @@ -56,7 +56,7 @@ abstract class AbstractTvProvider extends BaseVideoProvider public string $imgSavePath; /** - * @var array Site ID columns for TV + * @var array Site ID columns for TV */ public array $siteColumns; @@ -76,7 +76,7 @@ abstract class AbstractTvProvider extends BaseVideoProvider $this->catWhere = 'categories_id BETWEEN '.Category::TV_ROOT.' AND '.Category::TV_OTHER.' AND categories_id != '.Category::TV_ANIME; $this->tvqty = Settings::settingValue('maxrageprocessed') !== '' ? (int) Settings::settingValue('maxrageprocessed') : 75; $this->imgSavePath = storage_path('covers/tvshows/'); - $this->siteColumns = ['tvdb', 'trakt', 'tvrage', 'tvmaze', 'imdb', 'tmdb']; + $this->siteColumns = ['tvdb', 'trakt', 'tvrage', 'tvmaze', 'imdb', 'tmdb']; // @phpstan-ignore assign.propertyType } /** @@ -87,7 +87,7 @@ abstract class AbstractTvProvider extends BaseVideoProvider /** * Retrieve info of TV episode from site using its API. * - * @return array|false False on failure, an array of information fields otherwise. + * @return array|false False on failure, an array of information fields otherwise. */ abstract public function getEpisodeInfo(int|string $siteId, int|string $series, int|string $episode): array|bool; @@ -102,26 +102,30 @@ abstract class AbstractTvProvider extends BaseVideoProvider * Retrieve info of TV programme from site using it's API. * * @param string $name Title of programme to look up. Usually a cleaned up version from releases table. - * @return array|false False on failure, an array of information fields otherwise. + * @return array|false False on failure, an array of information fields otherwise. */ abstract public function getShowInfo(string $name): bool|array; /** * Assigns API show response values to a formatted array for insertion * Returns the formatted array. + * + * @return array */ - abstract public function formatShowInfo($show): array; + abstract public function formatShowInfo(mixed $show): array; /** * Assigns API episode response values to a formatted array for insertion * Returns the formatted array. + * + * @return array */ - abstract public function formatEpisodeInfo($episode): array; + abstract public function formatEpisodeInfo(mixed $episode): array; /** - * @return Release[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection|int + * @return Release[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection|int */ - public function getTvReleases(string $groupID = '', string $guidChar = '', int $lookupSetting = 1, int $status = 0): array|\Illuminate\Database\Eloquent\Collection|int|\Illuminate\Support\Collection + public function getTvReleases(string $groupID = '', string $guidChar = '', int $lookupSetting = 1, int $status = 0): array|\Illuminate\Database\Eloquent\Collection|int|\Illuminate\Support\Collection // @phpstan-ignore missingType.generics { $ret = 0; if ($lookupSetting === 0) { @@ -164,7 +168,7 @@ abstract class AbstractTvProvider extends BaseVideoProvider /** * Updates the release tv_episodes_id status when scraper match is not found. */ - public function setVideoNotFound($status, $Id): void + public function setVideoNotFound(mixed $status, mixed $Id): void { Release::query() ->where('id', $Id) @@ -174,6 +178,8 @@ abstract class AbstractTvProvider extends BaseVideoProvider /** * Inserts a new video ID into the database for TV shows * If a duplicate is found it is handle by calling update instead. + * + * @param array $show */ public function add(array $show = []): int { @@ -233,6 +239,9 @@ abstract class AbstractTvProvider extends BaseVideoProvider return $videoId; } + /** + * @param array $episode + */ public function addEpisode(int $videoId, array $episode = []): bool|int { $episodeId = $this->getBySeasonEp($videoId, $episode['series'], $episode['episode'], $episode['firstaired']); @@ -254,6 +263,9 @@ abstract class AbstractTvProvider extends BaseVideoProvider return $episodeId; } + /** + * @param array $show + */ public function update(int $videoId, array $show = []): void { if ($show['country'] !== '') { @@ -319,7 +331,7 @@ abstract class AbstractTvProvider extends BaseVideoProvider /** * @return Video|false|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model */ - public function getSiteByID(string $column, int $id): \Illuminate\Database\Eloquent\Model|bool|\Illuminate\Database\Eloquent\Builder|Video + public function getSiteByID(string $column, int $id): \Illuminate\Database\Eloquent\Model|bool|\Illuminate\Database\Eloquent\Builder|Video // @phpstan-ignore missingType.generics { $return = false; $video = Video::query()->where('id', $id)->first([$column]); @@ -377,7 +389,7 @@ abstract class AbstractTvProvider extends BaseVideoProvider } /** - * @return array|false + * @return array|false */ public function parseInfo(string $relname): bool|array { @@ -561,6 +573,8 @@ abstract class AbstractTvProvider extends BaseVideoProvider /** * Parses the release searchname for the season/episode/airdate information. + * + * @return array */ private function parseSeasonEp(string $relname): array { @@ -717,7 +731,7 @@ abstract class AbstractTvProvider extends BaseVideoProvider /** * Simple function that compares two strings of text */ - public function checkMatch($ourName, $scrapeName, $probability): float|int + public function checkMatch(mixed $ourName, mixed $scrapeName, mixed $probability): float|int { similar_text($ourName, $scrapeName, $matchpct); @@ -749,7 +763,7 @@ abstract class AbstractTvProvider extends BaseVideoProvider /** * Checks API response returns have all REQUIRED attributes set */ - public function checkRequiredAttr($array, string $type): bool + public function checkRequiredAttr(mixed $array, string $type): bool { $required = ['failedToMatchType']; diff --git a/app/Services/TvProcessing/Providers/BaseVideoProvider.php b/app/Services/TvProcessing/Providers/BaseVideoProvider.php index 4172d8c7d..d269bb3a8 100644 --- a/app/Services/TvProcessing/Providers/BaseVideoProvider.php +++ b/app/Services/TvProcessing/Providers/BaseVideoProvider.php @@ -43,12 +43,12 @@ abstract class BaseVideoProvider public bool $echooutput; /** - * @var array sites The sites that we have an ID columns for in our video table. + * @var array sites The sites that we have an ID columns for in our video table. */ - private static $sites = ['imdb', 'tmdb', 'trakt', 'tvdb', 'tvmaze', 'tvrage']; + private static $sites = ['imdb', 'tmdb', 'trakt', 'tvdb', 'tvmaze', 'tvrage']; // @phpstan-ignore property.defaultValue /** - * @var array Temp Array of cached failed lookups + * @var array Temp Array of cached failed lookups */ public array $titleCache; @@ -112,7 +112,7 @@ abstract class BaseVideoProvider return false; } - public function getByTitle(string $title, int $type, int $source = 0) + public function getByTitle(string $title, int $type, int $source = 0): mixed { // Check if we already have an entry for this show. $res = $this->getTitleExact($title, $type, $source); @@ -224,7 +224,7 @@ abstract class BaseVideoProvider /** * @return int|mixed */ - public function getTitleLoose($title, $type, int $source = 0): mixed + public function getTitleLoose(mixed $title, mixed $type, int $source = 0): mixed { $return = 0; @@ -293,8 +293,10 @@ abstract class BaseVideoProvider /** * Inserts aliases for videos. + * + * @param array $aliases */ - public function addAliases($videoId, array $aliases = []): void + public function addAliases(mixed $videoId, array $aliases = []): void { if (! empty($aliases) && $videoId > 0) { foreach ($aliases as $key => $title) { diff --git a/app/Services/TvProcessing/Providers/LocalDbProvider.php b/app/Services/TvProcessing/Providers/LocalDbProvider.php index 1c55862fc..9cc1029ba 100644 --- a/app/Services/TvProcessing/Providers/LocalDbProvider.php +++ b/app/Services/TvProcessing/Providers/LocalDbProvider.php @@ -14,7 +14,7 @@ class LocalDbProvider extends AbstractTvProvider * Main processing director function for local database lookups. * Attempts to match releases against existing video data in the database. */ - public function processSite($groupID, $guidChar, $process, bool $local = false): void + public function processSite(mixed $groupID, mixed $guidChar, mixed $process, bool $local = false): void { // Get releases that need processing $res = $this->getTvReleases($groupID, $guidChar, $process, parent::PROCESS_TVDB); @@ -152,6 +152,9 @@ class LocalDbProvider extends AbstractTvProvider return false; } + /** + * @return array + */ public function getEpisodeInfo(int|string $siteId, int|string $series, int|string $episode): array|bool { return false; @@ -162,17 +165,26 @@ class LocalDbProvider extends AbstractTvProvider return (new ReleaseImageService)->saveImage((string) $videoId, '', $this->imgSavePath, 0, 0, (bool) parent::TYPE_TV); } + /** + * @return array + */ public function getShowInfo(string $name): bool|array { return false; } - public function formatShowInfo($show): array + /** + * @return array + */ + public function formatShowInfo(mixed $show): array { return []; } - public function formatEpisodeInfo($episode): array + /** + * @return array + */ + public function formatEpisodeInfo(mixed $episode): array { return []; } diff --git a/app/Services/TvProcessing/Providers/TmdbProvider.php b/app/Services/TvProcessing/Providers/TmdbProvider.php index 58c1f1bf3..70169776b 100644 --- a/app/Services/TvProcessing/Providers/TmdbProvider.php +++ b/app/Services/TvProcessing/Providers/TmdbProvider.php @@ -22,7 +22,7 @@ class TmdbProvider extends AbstractTvProvider /** * Fetch banner from site. */ - public function getBanner($videoId, $siteId): bool + public function getBanner(mixed $videoId, mixed $siteId): bool { return false; } @@ -31,7 +31,7 @@ class TmdbProvider extends AbstractTvProvider * Main processing director function for TMDB * Calls work query function and initiates processing. */ - public function processSite($groupID, $guidChar, $process, bool $local = false): void + public function processSite(mixed $groupID, mixed $guidChar, mixed $process, bool $local = false): void { $res = $this->getTvReleases($groupID, $guidChar, $process, parent::PROCESS_TMDB); @@ -250,7 +250,7 @@ class TmdbProvider extends AbstractTvProvider * Calls the API to perform initial show name match to TMDB title * Returns a formatted array of show data or false if no match. * - * @return array|false + * @return array|false */ public function getShowInfo(string $name): bool|array { @@ -274,7 +274,8 @@ class TmdbProvider extends AbstractTvProvider } /** - * @return array|false + * @param array $shows + * @return array|false */ private function matchShowInfo(array $shows, string $cleanName): bool|array { @@ -332,7 +333,7 @@ class TmdbProvider extends AbstractTvProvider // Use available network info if present $networks = TmdbClient::getArray($highest, 'networks'); - $highest['network'] = ! empty($networks[0]['name']) ? $networks[0]['name'] : ''; + $highest['network'] = ! empty($networks[0]['name']) ? $networks[0]['name'] : ''; // @phpstan-ignore offsetAccess.notFound $highest['external_ids'] = $showExternalIds; @@ -370,7 +371,7 @@ class TmdbProvider extends AbstractTvProvider * Get all external IDs for a video from the database. * * @param int $videoId The local video ID - * @return array Array of external IDs: ['tmdb' => X, 'tvdb' => Y, 'imdb' => Z] + * @return array Array of external IDs: ['tmdb' => X, 'tvdb' => Y, 'imdb' => Z] */ protected function getAllSiteIdsFromVideoID(int $videoId): array { @@ -393,7 +394,7 @@ class TmdbProvider extends AbstractTvProvider * Gets the specific episode info for the parsed release after match * Returns a formatted array of episode data or false if no match. * - * @return array|false + * @return array|false */ public function getEpisodeInfo(int|string $siteId, int|string $series, int|string $episode, string $airdate = '', int $videoId = 0): bool|array { @@ -475,8 +476,10 @@ class TmdbProvider extends AbstractTvProvider /** * Assigns API show response values to a formatted array for insertion * Returns the formatted array. + * + * @return array */ - public function formatShowInfo($show): array + public function formatShowInfo(mixed $show): array { if (! is_array($show)) { return []; @@ -511,7 +514,7 @@ class TmdbProvider extends AbstractTvProvider 'summary' => TmdbClient::getString($show, 'overview'), 'started' => TmdbClient::getString($show, 'first_air_date'), 'publisher' => TmdbClient::getString($show, 'network'), - 'country' => ! empty($originCountry[0]) ? $originCountry[0] : '', + 'country' => ! empty($originCountry[0]) ? $originCountry[0] : '', // @phpstan-ignore offsetAccess.notFound 'source' => parent::SOURCE_TMDB, 'imdb' => $imdbId, 'tvdb' => TmdbClient::getInt($externalIds, 'tvdb_id'), @@ -575,8 +578,10 @@ class TmdbProvider extends AbstractTvProvider /** * Assigns API episode response values to a formatted array for insertion * Returns the formatted array. + * + * @return array */ - public function formatEpisodeInfo($episode): array + public function formatEpisodeInfo(mixed $episode): array { if (! is_array($episode)) { return []; diff --git a/app/Services/TvProcessing/Providers/TraktProvider.php b/app/Services/TvProcessing/Providers/TraktProvider.php index 1a2242338..2ef73ea96 100644 --- a/app/Services/TvProcessing/Providers/TraktProvider.php +++ b/app/Services/TvProcessing/Providers/TraktProvider.php @@ -17,7 +17,7 @@ class TraktProvider extends AbstractTvProvider public TraktService $client; - public $time; + public int $time; /** * @string URL for show poster art @@ -47,7 +47,7 @@ class TraktProvider extends AbstractTvProvider * Main processing director function for scrapers * Calls work query function and initiates processing. */ - public function processSite($groupID, $guidChar, int $process, bool $local = false): void + public function processSite(mixed $groupID, mixed $guidChar, int $process, bool $local = false): void { $res = $this->getTvReleases($groupID, $guidChar, $process, parent::PROCESS_TRAKT); @@ -232,7 +232,7 @@ class TraktProvider extends AbstractTvProvider /** * Fetch banner from site. */ - public function getBanner($videoID, $siteId): bool + public function getBanner(mixed $videoID, mixed $siteId): bool { return false; } @@ -241,7 +241,7 @@ class TraktProvider extends AbstractTvProvider * Get all external IDs for a video from the database. * * @param int $videoId The local video ID - * @return array Array of external IDs: ['trakt' => X, 'tmdb' => Y, 'tvdb' => Z, 'imdb' => W] + * @return array Array of external IDs: ['trakt' => X, 'tmdb' => Y, 'tvdb' => Z, 'imdb' => W] */ protected function getAllSiteIdsFromVideoID(int $videoId): array { @@ -268,7 +268,7 @@ class TraktProvider extends AbstractTvProvider * @param int|string $series The season number * @param int|string $episode The episode number * @param int $videoId Optional video ID to fetch all external IDs for fallback - * @return array|bool Episode data or false on failure + * @return array|bool Episode data or false on failure */ public function getEpisodeInfo(int|string $siteId, int|string $series, int|string $episode, int $videoId = 0): array|bool { @@ -331,7 +331,7 @@ class TraktProvider extends AbstractTvProvider /** * Get show information from Trakt by name. * - * @return array|false + * @return array|false */ public function getShowInfo(string $name): array|bool { @@ -378,8 +378,10 @@ class TraktProvider extends AbstractTvProvider /** * Assigns API show response values to a formatted array for insertion * Returns the formatted array. + * + * @return array */ - public function formatShowInfo($show): array + public function formatShowInfo(mixed $show): array { preg_match('/tt(?P\d{6,7})$/i', $show['ids']['imdb'], $imdb); $this->posterUrl = $show['images']['poster']['thumb'] ?? ''; @@ -449,8 +451,10 @@ class TraktProvider extends AbstractTvProvider /** * Assigns API episode response values to a formatted array for insertion * Returns the formatted array. + * + * @return array */ - public function formatEpisodeInfo($episode): array + public function formatEpisodeInfo(mixed $episode): array { return [ 'title' => (string) $episode['title'], diff --git a/app/Services/TvProcessing/Providers/TvMazeProvider.php b/app/Services/TvProcessing/Providers/TvMazeProvider.php index 1d6013b30..5b905627e 100644 --- a/app/Services/TvProcessing/Providers/TvMazeProvider.php +++ b/app/Services/TvProcessing/Providers/TvMazeProvider.php @@ -39,7 +39,7 @@ class TvMazeProvider extends AbstractTvProvider /** * Fetch banner from site. */ - public function getBanner($videoID, $siteId): bool + public function getBanner(mixed $videoID, mixed $siteId): bool { return false; } @@ -48,7 +48,7 @@ class TvMazeProvider extends AbstractTvProvider * Main processing director function for scrapers * Calls work query function and initiates processing. */ - public function processSite($groupID, $guidChar, $process, bool $local = false): void + public function processSite(mixed $groupID, mixed $guidChar, mixed $process, bool $local = false): void { $res = $this->getTvReleases($groupID, $guidChar, $process, parent::PROCESS_TVMAZE); @@ -250,9 +250,9 @@ class TvMazeProvider extends AbstractTvProvider * Calls the API to lookup the TvMaze info for a given TVDB or TVRage ID * Returns a formatted array of show data or false if no match. * - * @return array|false + * @return array|false */ - protected function getShowInfoBySiteID($site, $siteId) + protected function getShowInfoBySiteID(mixed $site, mixed $siteId) { $return = $response = false; @@ -271,6 +271,8 @@ class TvMazeProvider extends AbstractTvProvider /** * Calls the API to perform initial show name match to TVDB title * Returns a formatted array of show data or false if no match. + * + * @return array */ public function getShowInfo(string $name): array|bool { @@ -305,6 +307,9 @@ class TvMazeProvider extends AbstractTvProvider /** * Attempts to find the best matching show by title or aliases. + * + * @param array $shows + * @return array */ private function matchShowInfo(array $shows, string $cleanName): false|array { @@ -384,6 +389,9 @@ class TvMazeProvider extends AbstractTvProvider return $hasCover; } + /** + * @return array + */ public function getEpisodeInfo(int|string $siteId, int|string $series, int|string $episode, string $airDate = '', int $videoId = 0): array|bool { $return = $response = false; @@ -424,8 +432,10 @@ class TvMazeProvider extends AbstractTvProvider /** * Assigns API show response values to a formatted array for insertion * Returns the formatted array. + * + * @return array */ - public function formatShowInfo($show): array + public function formatShowInfo(mixed $show): array { $this->posterUrl = (string) ($show->mediumImage ?? ''); @@ -465,7 +475,7 @@ class TvMazeProvider extends AbstractTvProvider * * @param int $tvdbId TVDB show ID * @param int|string $imdbId IMDB ID (numeric, without 'tt' prefix) - * @return array ['tmdb' => int, 'trakt' => int] + * @return array ['tmdb' => int, 'trakt' => int] */ protected function lookupExternalIds(int $tvdbId, int|string $imdbId): array { @@ -529,8 +539,10 @@ class TvMazeProvider extends AbstractTvProvider /** * Assigns API episode response values to a formatted array for insertion * Returns the formatted array. + * + * @return array */ - public function formatEpisodeInfo($episode): array + public function formatEpisodeInfo(mixed $episode): array { return [ 'title' => (string) $episode->name, diff --git a/app/Services/TvProcessing/Providers/TvdbProvider.php b/app/Services/TvProcessing/Providers/TvdbProvider.php index 8c422581e..fddab7ee4 100644 --- a/app/Services/TvProcessing/Providers/TvdbProvider.php +++ b/app/Services/TvProcessing/Providers/TvdbProvider.php @@ -58,7 +58,7 @@ class TvdbProvider extends AbstractTvProvider * Main processing director function for scrapers * Calls work query function and initiates processing. */ - public function processSite($groupID, $guidChar, $process, bool $local = false): void + public function processSite(mixed $groupID, mixed $guidChar, mixed $process, bool $local = false): void { $res = $this->getTvReleases($groupID, $guidChar, $process, parent::PROCESS_TVDB); @@ -243,12 +243,14 @@ class TvdbProvider extends AbstractTvProvider } } - public function getBanner($videoID, $siteId): bool + public function getBanner(mixed $videoID, mixed $siteId): bool { return false; } /** + * @return array + * * @throws UnauthorizedException * @throws ParseException * @throws ExceptionInterface @@ -322,6 +324,8 @@ class TvdbProvider extends AbstractTvProvider } /** + * @return array + * * @throws ParseException * @throws UnauthorizedException * @throws ExceptionInterface @@ -374,10 +378,12 @@ class TvdbProvider extends AbstractTvProvider } /** + * @return array + * * @throws ExceptionInterface * @throws ParseException */ - public function formatShowInfo($show): array + public function formatShowInfo(mixed $show): array { try { $poster = $this->client->series()->artworks($show->tvdb_id); @@ -432,7 +438,7 @@ class TvdbProvider extends AbstractTvProvider * * @param int $tvdbId TVDB show ID * @param int|string $imdbId IMDB ID (numeric, without 'tt' prefix) - * @return array ['tmdb' => int, 'trakt' => int] + * @return array ['tmdb' => int, 'trakt' => int] */ protected function lookupExternalIds(int $tvdbId, int|string $imdbId): array { @@ -483,7 +489,10 @@ class TvdbProvider extends AbstractTvProvider return $result; } - public function formatEpisodeInfo($episode): array + /** + * @return array + */ + public function formatEpisodeInfo(mixed $episode): array { return [ 'title' => (string) $episode->name, diff --git a/app/Services/TvProcessing/TvProcessingPassable.php b/app/Services/TvProcessing/TvProcessingPassable.php index 19f6a13d0..a41e8bca5 100644 --- a/app/Services/TvProcessing/TvProcessingPassable.php +++ b/app/Services/TvProcessing/TvProcessingPassable.php @@ -13,8 +13,14 @@ class TvProcessingPassable public bool $debug; + /** + * @var array + */ public array $providerResults = []; + /** + * @var array + */ public ?array $parsedInfo = null; public function __construct(TvReleaseContext $context, bool $debug = false) @@ -54,6 +60,8 @@ class TvProcessingPassable /** * Set the parsed release info. + * + * @param array $info */ public function setParsedInfo(?array $info): void { @@ -62,6 +70,8 @@ class TvProcessingPassable /** * Get the parsed release info. + * + * @return array */ public function getParsedInfo(): ?array { @@ -80,6 +90,8 @@ class TvProcessingPassable /** * Build the final result array. + * + * @return array */ public function toArray(): array { diff --git a/app/Services/TvProcessing/TvProcessingPipeline.php b/app/Services/TvProcessing/TvProcessingPipeline.php index 6932b9b16..ff6423f44 100644 --- a/app/Services/TvProcessing/TvProcessingPipeline.php +++ b/app/Services/TvProcessing/TvProcessingPipeline.php @@ -26,12 +26,15 @@ class TvProcessingPipeline /** * @var Collection */ - protected Collection $pipes; + protected Collection $pipes; // @phpstan-ignore missingType.generics protected int $tvqty; protected bool $echoOutput; + /** + * @var array + */ protected array $stats = [ 'processed' => 0, 'matched' => 0, @@ -46,6 +49,7 @@ class TvProcessingPipeline */ public function __construct(iterable $pipes = [], bool $echoOutput = true) { + /** @phpstan-ignore argument.templateType */ $this->pipes = collect($pipes) ->sortBy(fn (AbstractTvProviderPipe $p) => $p->getPriority()); @@ -70,9 +74,9 @@ class TvProcessingPipeline /** * Process a single release through the pipeline. * - * @param array|object $release Release data + * @param array|object $release Release data * @param bool $debug Whether to include debug information - * @return array Processing result + * @return array Processing result */ public function processRelease(array|object $release, bool $debug = false): array { @@ -138,6 +142,8 @@ class TvProcessingPipeline /** * Get TV releases that need processing. + * + * @return Collection */ protected function getTvReleases(string $groupID, string $guidChar, int $processTV): Collection { @@ -181,13 +187,15 @@ class TvProcessingPipeline * * @return Collection */ - public function getPipes(): Collection + public function getPipes(): Collection // @phpstan-ignore missingType.generics { return $this->pipes; } /** * Get processing statistics. + * + * @return array */ public function getStats(): array { @@ -211,6 +219,8 @@ class TvProcessingPipeline /** * Update statistics from a processing result. + * + * @param array $result */ protected function updateStats(array $result): void { diff --git a/app/Services/TvProcessing/TvProcessingResult.php b/app/Services/TvProcessing/TvProcessingResult.php index ce2993365..c507da4b4 100644 --- a/app/Services/TvProcessing/TvProcessingResult.php +++ b/app/Services/TvProcessing/TvProcessingResult.php @@ -17,6 +17,9 @@ class TvProcessingResult public const STATUS_PENDING = 'pending'; + /** + * @param array $debug + */ public function __construct( public readonly string $status, public readonly ?int $videoId = null, @@ -27,6 +30,8 @@ class TvProcessingResult /** * Create a successful match result. + * + * @param array $debug */ public static function matched(int $videoId, int $episodeId, string $providerName, array $debug = []): self { @@ -41,6 +46,8 @@ class TvProcessingResult /** * Create a not found result. + * + * @param array $debug */ public static function notFound(?string $providerName = null, array $debug = []): self { @@ -53,6 +60,8 @@ class TvProcessingResult /** * Create a parse failed result. + * + * @param array $debug */ public static function parseFailed(array $debug = []): self { diff --git a/app/Services/TvProcessing/TvReleaseContext.php b/app/Services/TvProcessing/TvReleaseContext.php index e1eb16f8d..72aaeb563 100644 --- a/app/Services/TvProcessing/TvReleaseContext.php +++ b/app/Services/TvProcessing/TvReleaseContext.php @@ -20,6 +20,8 @@ class TvReleaseContext /** * Create from a Release model array/object. + * + * @param array $release */ public static function fromRelease(array|object $release): self { diff --git a/app/Services/TvProcessor.php b/app/Services/TvProcessor.php index 1d84f9691..8b316b0c2 100644 --- a/app/Services/TvProcessor.php +++ b/app/Services/TvProcessor.php @@ -24,6 +24,9 @@ class TvProcessor */ private array $providers; + /** + * @var array + */ private array $stats = [ 'mode' => self::MODE_PIPELINE, 'totalDuration' => 0.0, @@ -60,6 +63,8 @@ class TvProcessor /** * Retrieve statistics from the most recent run. + * + * @return array */ public function getStats(): array { @@ -171,8 +176,10 @@ class TvProcessor /** * Get the provider pipeline in order of preference. + * + * @return array> */ - private function buildProviderPipeline(): array + private function buildProviderPipeline(): array // @phpstan-ignore class.notFound { return [ ['name' => 'Local DB', 'factory' => static fn () => new LocalDbProvider, 'status' => 0], @@ -186,6 +193,7 @@ class TvProcessor /** * Determine whether a provider has pending work and return a preview release. * + * @param array $provider * @return array{release: Release, total: int}|null */ private function getPendingWorkForProvider(array $provider, string $groupID, string $guidChar, int $processTV): ?array diff --git a/app/Services/UserStatsService.php b/app/Services/UserStatsService.php index c4f53d1b5..e49415ea1 100644 --- a/app/Services/UserStatsService.php +++ b/app/Services/UserStatsService.php @@ -13,6 +13,8 @@ class UserStatsService { /** * Get user statistics by role + * + * @return array */ public function getUsersByRole(): array { @@ -35,6 +37,8 @@ class UserStatsService * Get downloads per day for the last N days * Uses aggregated stats from user_activity_stats table for dates older than 2 days * Uses live data from user_downloads table for recent days + * + * @return array */ public function getDownloadsPerDay(int $days = 7): array { @@ -97,6 +101,8 @@ class UserStatsService /** * Get downloads per hour for the last N hours * Uses aggregated hourly stats from user_activity_stats_hourly table + * + * @return list> */ public function getDownloadsPerHour(int $hours = 168): array { @@ -106,6 +112,8 @@ class UserStatsService /** * Get downloads per minute for the last N minutes + * + * @return array */ public function getDownloadsPerMinute(int $minutes = 60): array { @@ -140,6 +148,8 @@ class UserStatsService * Get API hits per day for the last N days * Uses aggregated stats from user_activity_stats table for dates older than 2 days * Uses live data from user_requests table for recent days + * + * @return list> */ public function getApiHitsPerDay(int $days = 7): array { @@ -202,6 +212,8 @@ class UserStatsService /** * Get API hits per hour for the last N hours * Uses aggregated hourly stats from user_activity_stats_hourly table + * + * @return list> */ public function getApiHitsPerHour(int $hours = 168): array { @@ -211,6 +223,8 @@ class UserStatsService /** * Get API hits per minute for the last N minutes + * + * @return array */ public function getApiHitsPerMinute(int $minutes = 60): array { @@ -245,6 +259,8 @@ class UserStatsService /** * Get summary statistics * Uses aggregated stats for weekly totals where possible + * + * @return list> */ public function getSummaryStats(): array { @@ -282,6 +298,8 @@ class UserStatsService /** * Get top downloaders + * + * @return array{total_users: int<0, max>, downloads_today: int<0, max>, downloads_week: float|int, api_hits_today: int<0, max>, api_hits_week: float|int} */ public function getTopDownloaders(int $limit = 5): array { diff --git a/app/Services/XXXProcessor.php b/app/Services/XXXProcessor.php index 12eeb3d36..4c3b0b5ab 100644 --- a/app/Services/XXXProcessor.php +++ b/app/Services/XXXProcessor.php @@ -27,7 +27,7 @@ class XXXProcessor * * @param string $movie Movie title to look up * @param bool $debug Whether to include debug information - * @return array Processing result + * @return array Processing result */ public function lookupMovie(string $movie, bool $debug = false): array { diff --git a/app/Services/XrefService.php b/app/Services/XrefService.php index 308c0b6de..04a8a0bd3 100644 --- a/app/Services/XrefService.php +++ b/app/Services/XrefService.php @@ -13,6 +13,8 @@ class XrefService /** * Extracts valid Xref tokens from a space-separated Xref string. + * + * @return array */ public function extractTokens(?string $xref): array { @@ -31,6 +33,8 @@ class XrefService /** * Returns tokens that appear in $headerXref but not in $existingXref. + * + * @return list */ public function diffNewTokens(?string $existingXref, ?string $headerXref): array { diff --git a/app/Services/XxxBrowseService.php b/app/Services/XxxBrowseService.php index 105251b42..25ed7f5d7 100644 --- a/app/Services/XxxBrowseService.php +++ b/app/Services/XxxBrowseService.php @@ -22,6 +22,10 @@ class XxxBrowseService /** * Get XXX releases with covers for xxx browse page. + * + * @param array $cat + * @param array $excludedCats + * @return array */ public function getXXXRange(int $page, array $cat, int $start, int $num, string $orderBy, int $maxAge = -1, array $excludedCats = []): array { @@ -29,7 +33,7 @@ class XxxBrowseService $start = max(0, $start); $catSrch = ''; - if (\count($cat) > 0 && $cat[0] !== -1) { + if (\count($cat) > 0 && $cat[0] !== -1) { // @phpstan-ignore offsetAccess.notFound $catSrch = Category::getCategorySearch($cat); } $order = $this->getXXXOrder($orderBy); @@ -56,8 +60,8 @@ class XxxBrowseService : '' ), (\count($excludedCats) > 0 ? ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')' : ''), - $order[0], - $order[1], + $order[0], // @phpstan-ignore offsetAccess.notFound + $order[1], // @phpstan-ignore offsetAccess.notFound ($start === false ? '' : ' LIMIT '.$num.' OFFSET '.$start) ); $xxxmoviesCache = Cache::get(md5($xxxmoviesSql.$page)); @@ -118,8 +122,8 @@ class XxxBrowseService : '' ), (\count($excludedCats) > 0 ? ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')' : ''), - $order[0], - $order[1] + $order[0], // @phpstan-ignore offsetAccess.notFound + $order[1] // @phpstan-ignore offsetAccess.notFound ); $return = Cache::get(md5($sql.$page)); if ($return !== null) { @@ -136,6 +140,8 @@ class XxxBrowseService /** * Get the order type the user requested on the xxx page. + * + * @return array */ protected function getXXXOrder(string $orderBy): array { @@ -150,6 +156,8 @@ class XxxBrowseService /** * Order types for xxx page. + * + * @return array */ public function getXXXOrdering(): array { diff --git a/app/Support/CaptchaHelper.php b/app/Support/CaptchaHelper.php index 39bc1fb30..46310d130 100644 --- a/app/Support/CaptchaHelper.php +++ b/app/Support/CaptchaHelper.php @@ -48,6 +48,8 @@ class CaptchaHelper /** * Display the captcha widget + * + * @param array $attributes */ public static function display(array $attributes = []): string { @@ -100,6 +102,8 @@ class CaptchaHelper /** * Get validation rules for captcha + * + * @return array */ public static function getValidationRules(): array { diff --git a/app/Support/DTOs/SteamGameData.php b/app/Support/DTOs/SteamGameData.php index 597b1c6b6..5c9451e6f 100644 --- a/app/Support/DTOs/SteamGameData.php +++ b/app/Support/DTOs/SteamGameData.php @@ -73,6 +73,8 @@ final readonly class SteamGameData /** * Create from Steam API response array. + * + * @param array $data */ public static function fromApiResponse(array $data, int $appId): self { @@ -226,6 +228,8 @@ final readonly class SteamGameData /** * Convert to array format compatible with existing GamesInfo model. + * + * @return array */ public function toGamesInfoArray(): array { diff --git a/app/Support/DTOs/SteamPriceData.php b/app/Support/DTOs/SteamPriceData.php index e29f5cb1f..7a99d0397 100644 --- a/app/Support/DTOs/SteamPriceData.php +++ b/app/Support/DTOs/SteamPriceData.php @@ -19,6 +19,8 @@ final readonly class SteamPriceData /** * Create from Steam API price_overview response. + * + * @param array $data */ public static function fromApiResponse(array $data): self { @@ -87,6 +89,8 @@ final readonly class SteamPriceData /** * Convert to array. + * + * @return array */ public function toArray(): array { diff --git a/app/Support/Google2FAAuthenticator.php b/app/Support/Google2FAAuthenticator.php index 6cdc6a5db..432ef6a89 100644 --- a/app/Support/Google2FAAuthenticator.php +++ b/app/Support/Google2FAAuthenticator.php @@ -30,7 +30,7 @@ class Google2FAAuthenticator extends Authenticator /** * Directly validate the cookie without any output or logging */ - private function checkCookieValidity($cookie) + private function checkCookieValidity(mixed $cookie): mixed { try { $data = @json_decode($cookie, true); diff --git a/app/Support/UpdatePerformanceHelper.php b/app/Support/UpdatePerformanceHelper.php index 9ff01cef6..0f16a6632 100644 --- a/app/Support/UpdatePerformanceHelper.php +++ b/app/Support/UpdatePerformanceHelper.php @@ -33,6 +33,9 @@ class UpdatePerformanceHelper /** * Execute commands in parallel where possible + * + * @param array $commands + * @return array */ public static function executeParallel(array $commands, int $timeout = 300): array { @@ -60,6 +63,8 @@ class UpdatePerformanceHelper /** * Clear various application caches efficiently + * + * @return array */ public static function clearAllCaches(): array { @@ -107,6 +112,8 @@ class UpdatePerformanceHelper /** * Check system resources and recommend optimizations + * + * @return array */ public static function checkSystemResources(): array { @@ -114,7 +121,7 @@ class UpdatePerformanceHelper // Check system memory usage $memInfo = self::getSystemMemoryInfo(); - if ($memInfo && $memInfo['usage_percent'] > 80) { + if ($memInfo && $memInfo['usage_percent'] > 80) { // @phpstan-ignore offsetAccess.notFound $recommendations[] = sprintf( 'High system memory usage: %.1f%% (%.1fGB of %.1fGB used)', $memInfo['usage_percent'], @@ -155,8 +162,10 @@ class UpdatePerformanceHelper /** * Get system memory information + * + * @return list */ - private static function getSystemMemoryInfo(): ?array + private static function getSystemMemoryInfo(): ?array // @phpstan-ignore return.unusedType { if (PHP_OS_FAMILY === 'Windows') { return null; // Windows memory check would require different approach @@ -188,6 +197,8 @@ class UpdatePerformanceHelper /** * Parse memory limit string to bytes + * + * @return array{total: int, available: int, used: int, usage_percent: (float|int)} */ private static function parseMemoryLimit(string $limit): int { @@ -213,6 +224,8 @@ class UpdatePerformanceHelper /** * Create a system performance snapshot + * + * @return array */ public static function createPerformanceSnapshot(): array { diff --git a/app/Transformers/ApiTransformer.php b/app/Transformers/ApiTransformer.php index 1057aaa05..868ce3e38 100644 --- a/app/Transformers/ApiTransformer.php +++ b/app/Transformers/ApiTransformer.php @@ -26,7 +26,7 @@ class ApiTransformer extends TransformerAbstract * Transform a release into an API response array. * * @param Release|\stdClass $release The release to transform (can be Eloquent model or stdClass from raw query) - * @return array The transformed release data + * @return array The transformed release data */ public function transform(Release|\stdClass $release): array { @@ -59,6 +59,8 @@ class ApiTransformer extends TransformerAbstract /** * Get base data common to all releases. + * + * @return array */ protected function getBaseData(Release|\stdClass $release): array { @@ -80,6 +82,8 @@ class ApiTransformer extends TransformerAbstract /** * Get movie-specific data fields. + * + * @return array */ protected function getMovieSpecificData(Release|\stdClass $release): array { @@ -92,6 +96,8 @@ class ApiTransformer extends TransformerAbstract /** * Get TV-specific data fields. + * + * @return array */ protected function getTvSpecificData(Release|\stdClass $release): array { diff --git a/app/Transformers/CategoryTransformer.php b/app/Transformers/CategoryTransformer.php index 485133ca2..80664c86c 100644 --- a/app/Transformers/CategoryTransformer.php +++ b/app/Transformers/CategoryTransformer.php @@ -9,6 +9,8 @@ class CategoryTransformer extends TransformerAbstract { /** * Transform a root category into an array. + * + * @return array */ public function transform(RootCategory $category): array { diff --git a/app/Transformers/DetailsTransformer.php b/app/Transformers/DetailsTransformer.php index 7e4ac7538..78079633d 100644 --- a/app/Transformers/DetailsTransformer.php +++ b/app/Transformers/DetailsTransformer.php @@ -9,18 +9,20 @@ use League\Fractal\TransformerAbstract; class DetailsTransformer extends TransformerAbstract { - protected $user; + protected \App\Models\User $user; /** * DetailsTransformer constructor. */ - public function __construct($user) + public function __construct(\App\Models\User $user) { $this->user = $user; } /** * Transform a release into a details array. + * + * @return array */ public function transform(Release $release): array { diff --git a/app/View/Components/SortDropdown.php b/app/View/Components/SortDropdown.php index d1eec636c..03c619d88 100644 --- a/app/View/Components/SortDropdown.php +++ b/app/View/Components/SortDropdown.php @@ -15,6 +15,8 @@ class SortDropdown extends Component /** * Available sort options. + * + * @var array */ public array $sortOptions; @@ -25,6 +27,8 @@ class SortDropdown extends Component /** * Query parameters to preserve. + * + * @var array */ public array $queryParams; @@ -40,11 +44,16 @@ class SortDropdown extends Component /** * Pre-computed sort URLs. + * + * @var array */ public array $sortUrls; /** * Create a new component instance. + * + * @param array|null $options + * @param array|null $queryParams */ public function __construct( ?string $currentSort = null, diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 000000000..41f6d5225 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,811 @@ +parameters: + ignoreErrors: + - + message: '#^Method App\\Console\\Commands\\NntmuxOffsetPopulate\:\:createOffsetRanges\(\) should return array\ but returns list\\>\>\.$#' + identifier: return.type + count: 1 + path: app/Console/Commands/NntmuxOffsetPopulate.php + + - + message: '#^PHPDoc tag @return with type list\\>\> is incompatible with native type string\.$#' + identifier: return.phpDocType + count: 1 + path: app/Console/Commands/NntmuxOffsetPopulate.php + + - + message: '#^Method App\\Console\\Commands\\NntmuxResetPostProcessing\:\:normalizeCategories\(\) should return array\ but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Console/Commands/NntmuxResetPostProcessing.php + + - + message: '#^Function getUserBrowseOrder\(\) should return array\ but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Extensions/helper/helpers.php + + - + message: '#^Class App\\Facades\\Elasticsearch has PHPDoc tag @method for method bulk\(\) parameter \#1 \$params with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Elasticsearch.php + + - + message: '#^Class App\\Facades\\Elasticsearch has PHPDoc tag @method for method bulk\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Elasticsearch.php + + - + message: '#^Class App\\Facades\\Elasticsearch has PHPDoc tag @method for method deleteByQuery\(\) parameter \#1 \$params with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Elasticsearch.php + + - + message: '#^Class App\\Facades\\Elasticsearch has PHPDoc tag @method for method deleteByQuery\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Elasticsearch.php + + - + message: '#^Class App\\Facades\\Elasticsearch has PHPDoc tag @method for method get\(\) parameter \#1 \$params with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Elasticsearch.php + + - + message: '#^Class App\\Facades\\Elasticsearch has PHPDoc tag @method for method get\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Elasticsearch.php + + - + message: '#^Class App\\Facades\\Elasticsearch has PHPDoc tag @method for method search\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Elasticsearch.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method autocomplete\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method bulkInsertReleases\(\) parameter \#1 \$releases with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method bulkInsertReleases\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method fuzzySearchReleases\(\) parameter \#1 \$phrases with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method fuzzySearchReleases\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method getFuzzyConfig\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method insertPredb\(\) parameter \#1 \$parameters with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchPredb\(\) parameter \#1 \$searchTerm with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchPredb\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchReleases\(\) parameter \#1 \$phrases with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchReleases\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchReleasesByCategory\(\) parameter \#1 \$categoryIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchReleasesByCategory\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchReleasesByExternalId\(\) parameter \#1 \$externalIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchReleasesByExternalId\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchReleasesWithCategoryFilter\(\) parameter \#2 \$categoryIds with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchReleasesWithCategoryFilter\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchReleasesWithFuzzy\(\) parameter \#1 \$phrases with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method searchReleasesWithFuzzy\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method suggest\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method truncateIndex\(\) parameter \#1 \$indexes with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\Search has PHPDoc tag @method for method updatePreDb\(\) parameter \#1 \$parameters with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/Search.php + + - + message: '#^Class App\\Facades\\TvProcessing has PHPDoc tag @method for method getStats\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/TvProcessing.php + + - + message: '#^Class App\\Facades\\TvProcessing has PHPDoc tag @method for method processRelease\(\) return type with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: app/Facades/TvProcessing.php + + - + message: '#^Offset 1 does not exist on array\\.$#' + identifier: offsetAccess.notFound + count: 1 + path: app/Http/Controllers/Admin/DeletedUsersController.php + + - + message: '#^Method App\\Http\\Controllers\\Api\\ApiController\:\:categoryID\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Http/Controllers/Api/ApiController.php + + - + message: '#^PHPDoc tag @return with type list\ is incompatible with native type bool\|int\|string\.$#' + identifier: return.phpDocType + count: 1 + path: app/Http/Controllers/Api/ApiController.php + + - + message: '#^Unable to resolve the template type TValue in call to function collect$#' + identifier: argument.templateType + count: 1 + path: app/Http/Controllers/MovieController.php + + - + message: '#^Unreachable statement \- code above always terminates\.$#' + identifier: deadCode.unreachable + count: 1 + path: app/Http/Controllers/RssController.php + + - + message: '#^Unable to resolve the template type TValue in call to function collect$#' + identifier: argument.templateType + count: 1 + path: app/Http/Controllers/SeriesController.php + + - + message: '#^Method App\\Models\\Category\:\:getForApi\(\) should return list\ but returns Illuminate\\Database\\Eloquent\\Collection\\.$#' + identifier: return.type + count: 1 + path: app/Models/Category.php + + - + message: '#^Method App\\Models\\Category\:\:getForMenu\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Models/Category.php + + - + message: '#^PHPDoc tag @return with type array\ is incompatible with native type Illuminate\\Database\\Eloquent\\Collection\.$#' + identifier: return.phpDocType + count: 1 + path: app/Models/Category.php + + - + message: '#^Method App\\Models\\Content\:\:scopeActive\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Content.php + + - + message: '#^Method App\\Models\\Content\:\:scopeForRole\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Content.php + + - + message: '#^Method App\\Models\\Content\:\:scopeFrontPage\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Content.php + + - + message: '#^Method App\\Models\\Content\:\:scopeOfType\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Content.php + + - + message: '#^Method App\\Models\\Genre\:\:scopeDisabled\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Genre.php + + - + message: '#^Method App\\Models\\Genre\:\:scopeEnabled\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Genre.php + + - + message: '#^Method App\\Models\\Genre\:\:scopeOfType\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Genre.php + + - + message: '#^Method App\\Models\\Invitation\:\:scopeActive\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Invitation.php + + - + message: '#^Method App\\Models\\Invitation\:\:scopeExpired\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Invitation.php + + - + message: '#^Method App\\Models\\Invitation\:\:scopeUnused\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Invitation.php + + - + message: '#^Method App\\Models\\Invitation\:\:scopeUsed\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Invitation.php + + - + message: '#^Method App\\Models\\Invitation\:\:scopeValid\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/Invitation.php + + - + message: '#^Property App\\Models\\Release\:\:\$image \(string\|null\) does not accept bool\|null\.$#' + identifier: assign.propertyType + count: 1 + path: app/Models/Release.php + + - + message: '#^Property App\\Models\\Release\:\:\$source \(int\<0, max\>\|null\) does not accept bool\|null\.$#' + identifier: assign.propertyType + count: 1 + path: app/Models/Release.php + + - + message: '#^Method App\\Models\\User\:\:scopeActive\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/User.php + + - + message: '#^Method App\\Models\\User\:\:scopeExcludeSharing\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/User.php + + - + message: '#^Method App\\Models\\User\:\:scopeExpired\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/User.php + + - + message: '#^Method App\\Models\\User\:\:scopeExpiringSoon\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/User.php + + - + message: '#^Method App\\Models\\User\:\:scopeVerified\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/User.php + + - + message: '#^Method App\\Models\\User\:\:scopeWithRole\(\) return type with generic class Illuminate\\Database\\Eloquent\\Builder does not specify its types\: TModel$#' + identifier: missingType.generics + count: 1 + path: app/Models/User.php + + - + message: '#^Method App\\Models\\UserActivityStat\:\:getDownloadsPerDay\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Models/UserActivityStat.php + + - + message: '#^Method App\\Models\\UserActivityStat\:\:getDownloadsPerHour\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Models/UserActivityStat.php + + - + message: '#^Method App\\Models\\XxxInfo\:\:getAllGenres\(\) should return array\ but returns list\.$#' + identifier: return.type + count: 1 + path: app/Models/XxxInfo.php + + - + message: '#^Method App\\Models\\XxxInfo\:\:getGenres\(\) should return array\ but returns App\\Models\\Genre\|null\.$#' + identifier: return.type + count: 2 + path: app/Models/XxxInfo.php + + - + message: '#^Method App\\Services\\AdditionalProcessing\\ArchiveExtractionService\:\:extractViaSevenZip\(\) should return list\ but returns array\{success\: false, files\: array\{\}, hasPassword\: false, passwordStatus\: 0\}\.$#' + identifier: return.type + count: 2 + path: app/Services/AdditionalProcessing/ArchiveExtractionService.php + + - + message: '#^Method App\\Services\\AdditionalProcessing\\ArchiveExtractionService\:\:filterExtractedFiles\(\) should return array\{success\: false, files\: array\{\}, hasPassword\: false, passwordStatus\: 0\} but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/AdditionalProcessing/ArchiveExtractionService.php + + - + message: '#^Method App\\Services\\AdditionalProcessing\\ArchiveExtractionService\:\:filterSevenZipFiles\(\) should return list\ but returns list\, pass\: 0, crc32\: '''', source\: ''7z\-list''\}\>\.$#' + identifier: return.type + count: 1 + path: app/Services/AdditionalProcessing/ArchiveExtractionService.php + + - + message: '#^Method App\\Services\\AdditionalProcessing\\ArchiveExtractionService\:\:listSevenZipEntries\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 2 + path: app/Services/AdditionalProcessing/ArchiveExtractionService.php + + - + message: '#^Method App\\Services\\AdditionalProcessing\\ArchiveExtractionService\:\:parseSevenZipStructuredOutput\(\) should return list\\> but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/AdditionalProcessing/ArchiveExtractionService.php + + - + message: '#^Method App\\Services\\AdditionalProcessing\\ArchiveExtractionService\:\:scanSevenZipFilenames\(\) should return list\, pass\: 0, crc32\: '''', source\: ''7z\-list''\}\> but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/AdditionalProcessing/ArchiveExtractionService.php + + - + message: '#^Method App\\Services\\AdditionalProcessing\\ArchiveExtractionService\:\:sortFilesWithNfoPriority\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/AdditionalProcessing/ArchiveExtractionService.php + + - + message: '#^PHPDoc tag @return with type list\ is incompatible with native type void\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/AdditionalProcessing/ArchiveExtractionService.php + + - + message: '#^Method App\\Services\\AdditionalProcessing\\NzbContentParser\:\:extractSegments\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/AdditionalProcessing/NzbContentParser.php + + - + message: '#^PHPDoc tag @return with type list\ is incompatible with native type string\|false\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/AdditionalProcessing/NzbContentParser.php + + - + message: '#^Method App\\Services\\AdultProcessing\\AgeVerificationManager\:\:getStoredDomains\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/AdultProcessing/AgeVerificationManager.php + + - + message: '#^PHPDoc tag @return with type list\ is incompatible with native type bool\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/AdultProcessing/AgeVerificationManager.php + + - + message: '#^Method App\\Services\\Archives\\SevenZipPartialParser\:\:getFilesByExtension\(\) should return array\\> but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Services/Archives/SevenZipPartialParser.php + + - + message: '#^Method App\\Services\\Archives\\SevenZipPartialParser\:\:parseBitVector\(\) should return list\ but returns array\, bool\>\.$#' + identifier: return.type + count: 1 + path: app/Services/Archives/SevenZipPartialParser.php + + - + message: '#^Method App\\Services\\Archives\\SevenZipPartialParser\:\:parseBitVector\(\) should return list\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/Archives/SevenZipPartialParser.php + + - + message: '#^Method App\\Services\\Archives\\SevenZipPartialParser\:\:parseBitVector\(\) should return list\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/Archives/SevenZipPartialParser.php + + - + message: '#^Method App\\Services\\Archives\\SevenZipPartialParser\:\:parseFileTimes\(\) should return array\, bool\> but returns array\, int\|null\>\.$#' + identifier: return.type + count: 1 + path: app/Services/Archives/SevenZipPartialParser.php + + - + message: '#^Method App\\Services\\Archives\\SevenZipPartialParser\:\:parseNames\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/Archives/SevenZipPartialParser.php + + - + message: '#^PHPDoc tag @return with type array\ is incompatible with native type bool\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/Archives/SevenZipPartialParser.php + + - + message: '#^Method App\\Services\\Binaries\\BinariesService\:\:groupMissingPartsIntoRanges\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Services/Binaries/BinariesService.php + + - + message: '#^PHPDoc tag @return with type list\\> is incompatible with native type int\|null\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/Binaries/BinariesService.php + + - + message: '#^Method App\\Services\\BookService\:\:getBookOrder\(\) should return array\ but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Services/BookService.php + + - + message: '#^Method App\\Services\\Categorization\\CategorizationService\:\:batchCategorize\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Services/Categorization/CategorizationService.php + + - + message: '#^PHPDoc tag @return with type list\\> is incompatible with native type App\\Services\\Categorization\\CategorizationPipeline\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/Categorization/CategorizationService.php + + - + message: '#^Method App\\Services\\ConsoleService\:\:getConsoleOrder\(\) should return array\ but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Services/ConsoleService.php + + - + message: '#^Unable to resolve the template type TValue in call to function collect$#' + identifier: argument.templateType + count: 6 + path: app/Services/FanartTvService.php + + - + message: '#^Method App\\Services\\GamesService\:\:getGamesOrder\(\) should return array\ but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Services/GamesService.php + + - + message: '#^Offset 1 does not exist on array\\.$#' + identifier: offsetAccess.notFound + count: 1 + path: app/Services/GamesService.php + + - + message: '#^Method App\\Services\\GenreService\:\:loadGenres\(\) should return array\ but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Services/GenreService.php + + - + message: '#^PHPDoc tag @return with type array\ is incompatible with native type Illuminate\\Database\\Eloquent\\Collection\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/GenreService.php + + - + message: '#^Method App\\Services\\IGDBService\:\:extractGenres\(\) should return array\ but returns array\, mixed\>\.$#' + identifier: return.type + count: 1 + path: app/Services/IGDBService.php + + - + message: '#^PHPDoc tag @return with type array\, mixed\> is incompatible with native type string\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/IGDBService.php + + - + message: '#^Method App\\Services\\MovieBrowseService\:\:getMovieOrder\(\) should return array\ but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Services/MovieBrowseService.php + + - + message: '#^Offset 1 does not exist on array\\.$#' + identifier: offsetAccess.notFound + count: 2 + path: app/Services/MovieBrowseService.php + + - + message: '#^Method App\\Services\\MusicService\:\:getMusicOrder\(\) should return array\ but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Services/MusicService.php + + - + message: '#^Method App\\Services\\NfoService\:\:extractAllMediaIds\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Services/NfoService.php + + - + message: '#^Method App\\Services\\NfoService\:\:extractGenre\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/NfoService.php + + - + message: '#^Method App\\Services\\NfoService\:\:extractLanguage\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/NfoService.php + + - + message: '#^Method App\\Services\\NfoService\:\:extractUrls\(\) should return array\ but returns array\, string\>\.$#' + identifier: return.type + count: 1 + path: app/Services/NfoService.php + + - + message: '#^Method App\\Services\\NfoService\:\:parseNfoMetadata\(\) should return list\\> but returns array\{urls\: array\, group\: string\|null, release_date\: string\|null, codec_info\: array\{video\?\: string, audio\?\: string, resolution\?\: string\}, file_size\: int\|null, media_ids\: array\, show_id\: array\{showid\: string, site\: string\}\|false, language\: array\, \.\.\.\}\.$#' + identifier: return.type + count: 1 + path: app/Services/NfoService.php + + - + message: '#^PHPDoc tag @return with type array\, string\> is incompatible with native type string\|null\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/NfoService.php + + - + message: '#^PHPDoc tag @return with type list\ is incompatible with native type int\|null\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/NfoService.php + + - + message: '#^Method App\\Services\\Releases\\ReleaseBrowseService\:\:getBrowseOrder\(\) should return array\ but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Services/Releases/ReleaseBrowseService.php + + - + message: '#^Method App\\Services\\Search\\Drivers\\ElasticSearchDriver\:\:buildHostsArray\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Services/Search/Drivers/ElasticSearchDriver.php + + - + message: '#^Method App\\Services\\Search\\Drivers\\ElasticSearchDriver\:\:searchReleasesWithCategoryFilter\(\) should return array\ but returns list\.$#' + identifier: return.type + count: 1 + path: app/Services/Search/Drivers/ElasticSearchDriver.php + + - + message: '#^PHPDoc tag @return with type list\\> is incompatible with native type bool\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/Search/Drivers/ElasticSearchDriver.php + + - + message: '#^Method App\\Services\\Search\\Drivers\\ManticoreSearchDriver\:\:searchReleasesByExternalId\(\) should return array\ but returns list\.$#' + identifier: return.type + count: 1 + path: app/Services/Search/Drivers/ManticoreSearchDriver.php + + - + message: '#^Method App\\Services\\SteamService\:\:getDLCList\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Services/SteamService.php + + - + message: '#^Method App\\Services\\SteamService\:\:getFullAppList\(\) should return array\{inserted\: int\<0, max\>, updated\: 0, skipped\: int\<0, max\>, errors\: int\<0, max\>\} but returns array\{\}\.$#' + identifier: return.type + count: 1 + path: app/Services/SteamService.php + + - + message: '#^Method App\\Services\\SteamService\:\:populateSteamAppsTable\(\) should return list\\> but returns array\{inserted\: 0, updated\: 0, skipped\: 0, errors\: 0\}\.$#' + identifier: return.type + count: 1 + path: app/Services/SteamService.php + + - + message: '#^Method App\\Services\\SteamService\:\:populateSteamAppsTable\(\) should return list\\> but returns array\{inserted\: int\<0, max\>, updated\: 0, skipped\: int\<0, max\>, errors\: int\<0, max\>\}\.$#' + identifier: return.type + count: 1 + path: app/Services/SteamService.php + + - + message: '#^Method App\\Services\\SteamService\:\:tokenize\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/SteamService.php + + - + message: '#^PHPDoc tag @return with type array is incompatible with native type Illuminate\\Support\\Collection\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/SteamService.php + + - + message: '#^PHPDoc tag @return with type list\ is incompatible with native type string\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/SteamService.php + + - + message: '#^Method App\\Services\\SystemMetricsService\:\:fillMissingHours\(\) should return list\\> but returns non\-empty\-array\\.$#' + identifier: return.type + count: 1 + path: app/Services/SystemMetricsService.php + + - + message: '#^Method App\\Services\\SystemMetricsService\:\:getHourlyMetrics\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Services/SystemMetricsService.php + + - + message: '#^PHPDoc tag @return with type array\ is incompatible with native type float\.$#' + identifier: return.phpDocType + count: 1 + path: app/Services/SystemMetricsService.php + + - + message: '#^Method App\\Services\\UserStatsService\:\:getApiHitsPerMinute\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Services/UserStatsService.php + + - + message: '#^Method App\\Services\\UserStatsService\:\:getDownloadsPerDay\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Services/UserStatsService.php + + - + message: '#^Method App\\Services\\UserStatsService\:\:getDownloadsPerHour\(\) should return list\\> but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Services/UserStatsService.php + + - + message: '#^Method App\\Services\\UserStatsService\:\:getDownloadsPerMinute\(\) should return array\ but returns list\\>\.$#' + identifier: return.type + count: 1 + path: app/Services/UserStatsService.php + + - + message: '#^Method App\\Services\\UserStatsService\:\:getSummaryStats\(\) should return list\\> but returns array\{total_users\: int\<0, max\>, downloads_today\: int\<0, max\>, downloads_week\: float\|int, api_hits_today\: int\<0, max\>, api_hits_week\: float\|int\}\.$#' + identifier: return.type + count: 1 + path: app/Services/UserStatsService.php + + - + message: '#^Method App\\Services\\XrefService\:\:extractTokens\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Services/XrefService.php + + - + message: '#^Method App\\Services\\XxxBrowseService\:\:getXXXOrder\(\) should return array\ but returns array\\.$#' + identifier: return.type + count: 1 + path: app/Services/XxxBrowseService.php + + - + message: '#^Method App\\Support\\UpdatePerformanceHelper\:\:checkSystemResources\(\) should return array\ but returns list\\.$#' + identifier: return.type + count: 1 + path: app/Support/UpdatePerformanceHelper.php + + - + message: '#^Method App\\Support\\UpdatePerformanceHelper\:\:getSystemMemoryInfo\(\) should return list\\|null but returns array\{total\: int, available\: int, used\: int, usage_percent\: \(float\|int\)\}\.$#' + identifier: return.type + count: 1 + path: app/Support/UpdatePerformanceHelper.php + + - + message: '#^PHPDoc tag @return with type array\ is incompatible with native type int\.$#' + identifier: return.phpDocType + count: 1 + path: app/Support/UpdatePerformanceHelper.php diff --git a/phpstan.neon b/phpstan.neon index a90fa27a8..b5535be6d 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,8 +1,9 @@ includes: - vendor/larastan/larastan/extension.neon + - phpstan-baseline.neon parameters: - level: 5 + level: 6 paths: - app - routes