From 85389a67e3b7892bcd9e435cbfd40a0513e9654b Mon Sep 17 00:00:00 2001 From: DariusIII Date: Sat, 27 Dec 2025 22:17:35 +0100 Subject: [PATCH] Create Genres service --- Blacklight/Genres.php | 170 ------------------ .../Admin/AdminConsoleController.php | 6 +- .../Controllers/Admin/AdminGameController.php | 6 +- .../Admin/AdminMusicController.php | 6 +- app/Http/Controllers/ConsoleController.php | 6 +- app/Http/Controllers/GamesController.php | 6 +- app/Http/Controllers/MusicController.php | 6 +- app/Models/Genre.php | 108 +++++++++++ app/Services/ConsoleService.php | 7 +- app/Services/GamesService.php | 15 +- app/Services/GenreService.php | 103 +++++++++++ app/Services/MusicService.php | 5 +- app/Services/ReleaseProcessingService.php | 3 +- 13 files changed, 242 insertions(+), 205 deletions(-) delete mode 100755 Blacklight/Genres.php create mode 100644 app/Services/GenreService.php diff --git a/Blacklight/Genres.php b/Blacklight/Genres.php deleted file mode 100755 index e33aac7e4..000000000 --- a/Blacklight/Genres.php +++ /dev/null @@ -1,170 +0,0 @@ -getListQuery($type, $activeOnly); - $genres = Cache::get(md5($sql)); - if ($genres !== null) { - return $genres; - } - $genres = DB::select($sql); - $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); - Cache::put(md5($sql), $genres, $expiresAt); - - return $genres; - } - - public function loadGenres($type): array - { - $genres = $this->getGenres($type); - $genresArray = []; - foreach ($genres as $genre) { - $genresArray[$genre->id] = strtolower($genre->title); - } - - return $genresArray; - } - - private function getListQuery(string $type = '', bool $activeOnly = false): string - { - if (! empty($type)) { - $typesql = sprintf(' AND g.type = %d', $type); - } else { - $typesql = ''; - } - - if ($activeOnly) { - $sql = sprintf( - ' - SELECT g.* - FROM genres g - INNER JOIN - (SELECT DISTINCT genres_id FROM musicinfo) x - ON x.genres_id = g.id %1$s - UNION - SELECT g.* - FROM genres g - INNER JOIN - (SELECT DISTINCT genres_id FROM consoleinfo) x - ON x.genres_id = g.id %1$s - UNION - SELECT g.* - FROM genres g - INNER JOIN - (SELECT DISTINCT genres_id FROM gamesinfo) x - ON x.genres_id = g.id %1$s - ORDER BY title', - $typesql - ); - } else { - $sql = sprintf('SELECT g.* FROM genres g WHERE 1 %s ORDER BY g.title', $typesql); - } - - return $sql; - } - - public function getRange(int $start, int $num, string $type = '', bool $activeOnly = false): array - { - $sql = $this->getListQuery($type, $activeOnly); - $sql .= ' LIMIT '.$num.' OFFSET '.$start; - - return (array) Arr::first(DB::select($sql)); - } - - public function getCount(string $type = '', bool $activeOnly = false): mixed - { - if (! empty($type)) { - $typesql = sprintf(' AND g.type = %d', $type); - } else { - $typesql = ''; - } - - if ($activeOnly) { - $sql = sprintf( - ' - SELECT COUNT(id) AS num - FROM genres g - INNER JOIN - (SELECT DISTINCT genres_id FROM musicinfo) x - ON x.genres_id = g.id %1$s - + - SELECT COUNT(id) AS num - FROM genres g - INNER JOIN - (SELECT DISTINCT genres_id FROM consoleinfo) y - ON y.genres_id = g.id %1$s - + - SELECT COUNT(id) AS num - FROM genres g - INNER JOIN - (SELECT DISTINCT genres_id FROM gamesinfo) x - ON x.genres_id = g.id %1$s', - $typesql - ); - } else { - $sql = sprintf('SELECT COUNT(g.id) AS num FROM genres g WHERE 1 %s ORDER BY g.title', $typesql); - } - - $res = DB::select($sql); - - return $res[0]->num; - } - - /** - * @return Genre|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null - */ - public function getById($id) - { - return Genre::query()->where('id', $id)->first(); - } - - public function update($id, $disabled): int - { - return Genre::query()->where('id', $id)->update(['disabled' => $disabled]); - } - - /** - * @return \Illuminate\Database\Eloquent\Collection|static[] - */ - public function getDisabledIDs() - { - $cats = Cache::get('disabledcats'); - if ($cats !== null) { - $disabled = $cats; - } else { - $disabled = Genre::query()->where('disabled', '=', 1)->get(['id']); - $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); - Cache::put('disabledcats', $disabled, $expiresAt); - } - - return $disabled; - } -} diff --git a/app/Http/Controllers/Admin/AdminConsoleController.php b/app/Http/Controllers/Admin/AdminConsoleController.php index 9c8153df9..b08d3f229 100644 --- a/app/Http/Controllers/Admin/AdminConsoleController.php +++ b/app/Http/Controllers/Admin/AdminConsoleController.php @@ -4,7 +4,7 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\BasePageController; use App\Services\ConsoleService; -use Blacklight\Genres; +use App\Services\GenreService; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Carbon; @@ -40,7 +40,7 @@ class AdminConsoleController extends BasePageController public function edit(Request $request): View|RedirectResponse { $this->setAdminPrefs(); - $gen = new Genres; + $gen = new GenreService; $meta_title = $title = 'Console Edit'; // set the current action @@ -90,7 +90,7 @@ class AdminConsoleController extends BasePageController case 'view': default: - $genres = $gen->getGenres(Genres::CONSOLE_TYPE); + $genres = $gen->getGenres((string) GenreService::CONSOLE_TYPE); return view('admin.console.edit', compact('con', 'genres', 'title', 'meta_title')); } diff --git a/app/Http/Controllers/Admin/AdminGameController.php b/app/Http/Controllers/Admin/AdminGameController.php index 75d402151..e26965330 100644 --- a/app/Http/Controllers/Admin/AdminGameController.php +++ b/app/Http/Controllers/Admin/AdminGameController.php @@ -4,7 +4,7 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\BasePageController; use App\Services\GamesService; -use Blacklight\Genres; +use App\Services\GenreService; use Illuminate\Http\Request; use Illuminate\Support\Carbon; @@ -39,7 +39,7 @@ class AdminGameController extends BasePageController public function edit(Request $request) { $games = new GamesService; - $gen = new Genres(['Settings' => null]); + $gen = new GenreService; $meta_title = $title = 'Game Edit'; // Set the current action. @@ -87,7 +87,7 @@ class AdminGameController extends BasePageController case 'view': default: - $genres = $gen->getGenres(Genres::GAME_TYPE); + $genres = $gen->getGenres((string) GenreService::GAME_TYPE); return view('admin.games.edit', compact('title', 'meta_title', 'game', 'genres')); } diff --git a/app/Http/Controllers/Admin/AdminMusicController.php b/app/Http/Controllers/Admin/AdminMusicController.php index fd106c6ce..abf9d76d4 100644 --- a/app/Http/Controllers/Admin/AdminMusicController.php +++ b/app/Http/Controllers/Admin/AdminMusicController.php @@ -4,7 +4,7 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\BasePageController; use App\Services\MusicService; -use Blacklight\Genres; +use App\Services\GenreService; use Illuminate\Http\Request; use Illuminate\Support\Carbon; @@ -37,7 +37,7 @@ class AdminMusicController extends BasePageController public function edit(Request $request) { $music = new MusicService; - $gen = new Genres; + $gen = new GenreService; $meta_title = $title = 'Music Edit'; @@ -94,7 +94,7 @@ class AdminMusicController extends BasePageController case 'view': default: - $genres = $gen->getGenres(Genres::MUSIC_TYPE); + $genres = $gen->getGenres((string) GenreService::MUSIC_TYPE); return view('admin.music.edit', compact('title', 'meta_title', 'mus', 'genres')); } diff --git a/app/Http/Controllers/ConsoleController.php b/app/Http/Controllers/ConsoleController.php index d0f1109c5..95e050100 100644 --- a/app/Http/Controllers/ConsoleController.php +++ b/app/Http/Controllers/ConsoleController.php @@ -4,7 +4,7 @@ namespace App\Http\Controllers; use App\Models\Category; use App\Services\ConsoleService; -use Blacklight\Genres; +use App\Services\GenreService; use Illuminate\Http\Request; use Illuminate\Support\Arr; @@ -26,7 +26,7 @@ class ConsoleController extends BasePageController if ($id === 'WiiVare') { $id = 'WiiVareVC'; } - $gen = new Genres; + $gen = new GenreService; $concats = Category::getChildren(Category::GAME_ROOT); $ctmp = []; @@ -73,7 +73,7 @@ class ConsoleController extends BasePageController $platform = ($request->has('platform') && ! empty($request->input('platform'))) ? stripslashes($request->input('platform')) : ''; $title = ($request->has('title') && ! empty($request->input('title'))) ? stripslashes($request->input('title')) : ''; - $genres = $gen->getGenres(Genres::CONSOLE_TYPE, true); + $genres = $gen->getGenres((string) GenreService::CONSOLE_TYPE, true); $tmpgnr = []; foreach ($genres as $gn) { $tmpgnr[$gn->id] = $gn->title; diff --git a/app/Http/Controllers/GamesController.php b/app/Http/Controllers/GamesController.php index 6bbac73b2..8cb1be091 100644 --- a/app/Http/Controllers/GamesController.php +++ b/app/Http/Controllers/GamesController.php @@ -4,7 +4,7 @@ namespace App\Http\Controllers; use App\Models\Category; use App\Services\GamesService; -use Blacklight\Genres; +use App\Services\GenreService; use Illuminate\Http\Request; class GamesController extends BasePageController @@ -15,7 +15,7 @@ class GamesController extends BasePageController public function show(Request $request) { $games = new GamesService; - $gen = new Genres(['Settings' => $this->settings]); + $gen = new GenreService; $concats = Category::getChildren(Category::PC_ROOT); $ctmp = []; @@ -39,7 +39,7 @@ class GamesController extends BasePageController $title = ($request->has('title') && ! empty($request->input('title'))) ? stripslashes($request->input('title')) : ''; - $genres = $gen->getGenres(Genres::GAME_TYPE, true); + $genres = $gen->getGenres((string) GenreService::GAME_TYPE, true); $tmpgnr = []; foreach ($genres as $gn) { $tmpgnr[$gn->id] = $gn->title; diff --git a/app/Http/Controllers/MusicController.php b/app/Http/Controllers/MusicController.php index 5840680bc..d50a7d276 100644 --- a/app/Http/Controllers/MusicController.php +++ b/app/Http/Controllers/MusicController.php @@ -4,7 +4,7 @@ namespace App\Http\Controllers; use App\Models\Category; use App\Services\MusicService; -use Blacklight\Genres; +use App\Services\GenreService; use Illuminate\Http\Request; use Illuminate\Support\Arr; @@ -16,7 +16,7 @@ class MusicController extends BasePageController public function show(Request $request, string $id = '') { $music = new MusicService; - $gen = new Genres(['Settings' => $this->settings]); + $gen = new GenreService; $musiccats = Category::getChildren(Category::MUSIC_ROOT); $mtmp = []; @@ -53,7 +53,7 @@ class MusicController extends BasePageController $title = ($request->has('title') && ! empty($request->input('title'))) ? stripslashes($request->input('title')) : ''; - $genres = $gen->getGenres(Genres::MUSIC_TYPE, true); + $genres = $gen->getGenres((string) GenreService::MUSIC_TYPE, true); $tmpgnr = []; foreach ($genres as $gn) { $tmpgnr[$gn->id] = $gn->title; diff --git a/app/Models/Genre.php b/app/Models/Genre.php index 52bab2e1e..434e0727e 100644 --- a/app/Models/Genre.php +++ b/app/Models/Genre.php @@ -2,8 +2,11 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Support\Facades\DB; /** * App\Models\Genre. @@ -18,6 +21,9 @@ use Illuminate\Database\Eloquent\Relations\HasMany; * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Genre whereId($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Genre whereTitle($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Genre whereType($value) + * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Genre disabled() + * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Genre enabled() + * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Genre ofType($type) * * @mixin \Eloquent * @@ -46,4 +52,106 @@ class Genre extends Model { return $this->hasMany(MusicInfo::class, 'genres_id'); } + + public function consoleInfo(): HasMany + { + return $this->hasMany(ConsoleInfo::class, 'genres_id'); + } + + public function gamesInfo(): HasMany + { + return $this->hasMany(GamesInfo::class, 'genres_id'); + } + + /** + * Scope to filter disabled genres. + */ + public function scopeDisabled(Builder $query): Builder + { + return $query->where('disabled', '=', 1); + } + + /** + * Scope to filter enabled genres. + */ + public function scopeEnabled(Builder $query): Builder + { + return $query->where('disabled', '=', 0); + } + + /** + * Scope to filter by type. + */ + public function scopeOfType(Builder $query, string $type): Builder + { + if (! empty($type)) { + return $query->where('type', '=', $type); + } + + return $query; + } + + /** + * Get filtered genres based on type and active status. + */ + public static function getFiltered(string $type = '', bool $activeOnly = false): Collection + { + if ($activeOnly) { + return self::getActiveGenres($type); + } + + $query = self::query(); + + if (! empty($type)) { + $query->ofType($type); + } + + return $query->orderBy('title')->get(); + } + + /** + * Get count of filtered genres. + */ + public static function getFilteredCount(string $type = '', bool $activeOnly = false): int + { + if ($activeOnly) { + return self::getActiveGenres($type)->count(); + } + + $query = self::query(); + + if (! empty($type)) { + $query->ofType($type); + } + + return $query->count(); + } + + /** + * Get genres that are actively used in musicinfo, consoleinfo, or gamesinfo. + */ + private static function getActiveGenres(string $type = ''): Collection + { + $typeSql = ! empty($type) ? ' AND g.type = '.intval($type) : ''; + + $sql = sprintf( + "SELECT g.* + FROM genres g + INNER JOIN (SELECT DISTINCT genres_id FROM musicinfo) x ON x.genres_id = g.id WHERE 1=1 %1\$s + UNION + SELECT g.* + FROM genres g + INNER JOIN (SELECT DISTINCT genres_id FROM consoleinfo) x ON x.genres_id = g.id WHERE 1=1 %1\$s + UNION + SELECT g.* + FROM genres g + INNER JOIN (SELECT DISTINCT genres_id FROM gamesinfo) x ON x.genres_id = g.id WHERE 1=1 %1\$s + ORDER BY title", + $typeSql + ); + + $results = DB::select($sql); + + return self::hydrate($results); + } } diff --git a/app/Services/ConsoleService.php b/app/Services/ConsoleService.php index dd09ae59b..a18596be7 100644 --- a/app/Services/ConsoleService.php +++ b/app/Services/ConsoleService.php @@ -9,7 +9,6 @@ use App\Models\ConsoleInfo; use App\Models\Genre; use App\Models\Release; use App\Models\Settings; -use Blacklight\Genres; use GuzzleHttp\Exception\ClientException; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Cache; @@ -782,7 +781,7 @@ class ConsoleService if (\in_array(strtolower($genreName), $genreassoc, false)) { $genreKey = array_search(strtolower($genreName), $genreassoc, false); } else { - $genreKey = Genre::query()->insertGetId(['title' => $genreName, 'type' => Genres::CONSOLE_TYPE]); + $genreKey = Genre::query()->insertGetId(['title' => $genreName, 'type' => GenreService::CONSOLE_TYPE]); } return $genreKey; @@ -795,9 +794,9 @@ class ConsoleService */ protected function loadGenres(): array { - $gen = new Genres(['Settings' => null]); + $gen = new GenreService; - return $gen->loadGenres(Genres::CONSOLE_TYPE); + return $gen->loadGenres((string) GenreService::CONSOLE_TYPE); } } diff --git a/app/Services/GamesService.php b/app/Services/GamesService.php index cd5d9b711..503f23abb 100644 --- a/app/Services/GamesService.php +++ b/app/Services/GamesService.php @@ -9,7 +9,6 @@ use App\Models\GamesInfo; use App\Models\Genre; use App\Models\Release; use App\Models\Settings; -use Blacklight\Genres; use GuzzleHttp\Exception\ClientException; use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Database\Eloquent\Model; @@ -326,7 +325,7 @@ class GamesService */ public function updateGamesInfo(array $gameInfo): bool|int { - $gen = new Genres(['Settings' => null]); + $gen = new GenreService; $game = []; $titleKey = $this->generateCacheKey($gameInfo['title']); @@ -436,10 +435,10 @@ class GamesService /** * Save game to database. */ - protected function saveGameToDatabase(array $game, string $genreName, Genres $gen, array $gameInfo, string $titleKey): bool|int + protected function saveGameToDatabase(array $game, string $genreName, GenreService $gen, array $gameInfo, string $titleKey): bool|int { // Load genres - $defaultGenres = $gen->loadGenres(Genres::GAME_TYPE); + $defaultGenres = $gen->loadGenres((string) GenreService::GAME_TYPE); // Prepare database values $game['cover'] = isset($game['coverurl']) ? 1 : 0; @@ -465,7 +464,7 @@ class GamesService if (in_array(strtolower($genreName), $defaultGenres, false)) { $genreKey = array_search(strtolower($genreName), $defaultGenres, false); } else { - $genreKey = Genre::query()->insertGetId(['title' => $genreName, 'type' => Genres::GAME_TYPE]); + $genreKey = Genre::query()->insertGetId(['title' => $genreName, 'type' => GenreService::GAME_TYPE]); } $game['gamesgenre'] = $genreName; @@ -565,15 +564,15 @@ class GamesService /** * Save game info from cached data. */ - protected function saveGameInfoFromCache(array $game, Genres $gen, array $gameInfo): bool|int + protected function saveGameInfoFromCache(array $game, GenreService $gen, array $gameInfo): bool|int { - $defaultGenres = $gen->loadGenres(Genres::GAME_TYPE); + $defaultGenres = $gen->loadGenres((string) GenreService::GAME_TYPE); $genreName = $game['gamesgenre'] ?? 'Unknown'; if (in_array(strtolower($genreName), $defaultGenres, false)) { $genreKey = array_search(strtolower($genreName), $defaultGenres, false); } else { - $genreKey = Genre::query()->insertGetId(['title' => $genreName, 'type' => Genres::GAME_TYPE]); + $genreKey = Genre::query()->insertGetId(['title' => $genreName, 'type' => GenreService::GAME_TYPE]); } $game['gamesgenreID'] = $genreKey; diff --git a/app/Services/GenreService.php b/app/Services/GenreService.php new file mode 100644 index 000000000..eb15bc90a --- /dev/null +++ b/app/Services/GenreService.php @@ -0,0 +1,103 @@ +addMinutes(config('nntmux.cache_expiry_long')), function () use ($type, $activeOnly) { + return Genre::getFiltered($type, $activeOnly); + }); + } + + /** + * Load genres as an associative array (id => lowercase title). + */ + public function loadGenres(string $type): array + { + $genres = $this->getGenres($type); + $genresArray = []; + foreach ($genres as $genre) { + $genresArray[$genre->id] = strtolower($genre->title); + } + + return $genresArray; + } + + /** + * Get a range of genres with pagination. + */ + public function getRange(int $start, int $num, string $type = '', bool $activeOnly = false): Collection + { + return Genre::getFiltered($type, $activeOnly) + ->skip($start) + ->take($num); + } + + /** + * Get count of genres. + */ + public function getCount(string $type = '', bool $activeOnly = false): int + { + return Genre::getFilteredCount($type, $activeOnly); + } + + /** + * Get genre by ID. + */ + public function getById(int $id): ?Genre + { + return Genre::find($id); + } + + /** + * Update genre disabled status. + */ + public function update(int $id, int $disabled): int + { + $this->clearCache(); + + return Genre::where('id', $id)->update(['disabled' => $disabled]); + } + + /** + * Get all disabled genre IDs. + */ + public function getDisabledIDs(): Collection + { + return Cache::remember('disabled_genres', now()->addMinutes(config('nntmux.cache_expiry_long')), function () { + return Genre::disabled()->get(['id']); + }); + } + + /** + * Clear genre-related cache. + */ + public function clearCache(): void + { + Cache::forget('disabled_genres'); + // Clear other genre caches by pattern if needed + } +} + diff --git a/app/Services/MusicService.php b/app/Services/MusicService.php index 8235f6bf1..229137504 100644 --- a/app/Services/MusicService.php +++ b/app/Services/MusicService.php @@ -8,7 +8,6 @@ use App\Models\MusicInfo; use App\Models\Release; use App\Models\Settings; use App\Services\Releases\ReleaseBrowseService; -use Blacklight\Genres; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; @@ -615,7 +614,7 @@ class MusicService protected function fetchItunesMusicProperties(string $title): array|false { // Load genres. - $defaultGenres = (new Genres)->loadGenres(Genres::MUSIC_TYPE); + $defaultGenres = (new GenreService)->loadGenres((string) GenreService::MUSIC_TYPE); $itunes = new ItunesService; @@ -647,7 +646,7 @@ class MusicService if (\in_array(strtolower($genreName), $defaultGenres, false)) { $genreKey = array_search(strtolower($genreName), $defaultGenres, false); } else { - $genreKey = Genre::query()->insertGetId(['title' => $genreName, 'type' => Genres::MUSIC_TYPE]); + $genreKey = Genre::query()->insertGetId(['title' => $genreName, 'type' => GenreService::MUSIC_TYPE]); } } else { $genreKey = -1; diff --git a/app/Services/ReleaseProcessingService.php b/app/Services/ReleaseProcessingService.php index 02ac8513e..86701f489 100644 --- a/app/Services/ReleaseProcessingService.php +++ b/app/Services/ReleaseProcessingService.php @@ -19,7 +19,6 @@ use App\Support\DTOs\ProcessReleasesSettings; use App\Support\DTOs\ReleaseCreationResult; use App\Support\DTOs\ReleaseDeleteStats; use App\Services\NNTP\NNTPService; -use Blacklight\Genres; use DateTimeInterface; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; @@ -1141,7 +1140,7 @@ final class ReleaseProcessingService private function deleteDisabledGenreReleases(ReleaseDeleteStats $stats): ReleaseDeleteStats { - $genres = new Genres(); + $genres = new GenreService; $genreList = $genres->getDisabledIDs(); if ($genreList === null || $genreList->isEmpty()) {