diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index b482fa41f..e762fcdd7 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -54,7 +54,7 @@ class SearchController extends BasePageController $category = [0]; $lastvisit = $this->userdata->lastlogin; - if ($searchType === 'basic' && $request->missing('searchadvr') && ($request->has('id') || $request->has('subject') || $request->has('search'))) { + if ($searchType === 'basic' && ($request->filled('id') || $request->filled('subject') || $request->filled('search'))) { $searchString = []; switch (true) { case $request->filled('subject'): @@ -73,13 +73,7 @@ class SearchController extends BasePageController $searchString['searchname'] = ''; } - $categoryID = [-1]; - if ($request->has('t')) { - $t = $request->input('t'); - if ($t !== null && $t !== '') { - $categoryID = array_map('intval', explode(',', (string) $t)); - } - } + $categoryID = $this->resolveCategoryIdsFromRequest($request); $orderByUrls = []; foreach ($this->releaseBrowseService->getBrowseOrdering() as $orderType) { @@ -172,12 +166,15 @@ class SearchController extends BasePageController } } - if ($searchType !== 'basic' && $request->missing('id') && $request->missing('subject') && $request->anyFilled(['searchadvr', 'searchadvsubject', 'searchadvfilename', 'searchadvposter', 'minage', 'maxage', 'group', 'minsize', 'maxsize', 'search'])) { + if ($searchType !== 'basic' && $request->missing('id') && $request->missing('subject') && $request->anyFilled(['searchadvr', 'searchadvsubject', 'searchadvfilename', 'searchadvposter', 'search'])) { $orderByString = ''; foreach ($searchVars as $searchVarKey => $searchVar) { $orderByString .= "&$searchVarKey=".htmlentities($searchVar, ENT_QUOTES | ENT_HTML5); } $orderByString = ltrim($orderByString, '&'); + if ($request->filled('t')) { + $orderByString .= '&t='.urlencode((string) $request->input('t')); + } $orderByUrls = []; foreach ($ordering as $orderType) { @@ -204,7 +201,7 @@ class SearchController extends BasePageController -1, $this->userdata->categoryexclusions ?? [], 'advanced', - [$searchVars['searchadvcat'] === '' ? -1 : $searchVars['searchadvcat']] + $this->resolveCategoryIdsFromRequest($request) ); $results = $this->paginate($rslt ?? [], $rslt[0]->_totalrows ?? 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query()); @@ -236,4 +233,18 @@ class SearchController extends BasePageController return view('search.index', $this->viewData); } + + /** + * @return array + */ + private function resolveCategoryIdsFromRequest(Request $request): array + { + $raw = $request->input('t', $request->input('searchadvcat', '')); + + if ($raw === null || $raw === '' || $raw === '-1') { + return [-1]; + } + + return array_map('intval', explode(',', (string) $raw)); + } } diff --git a/app/Services/Releases/ReleaseSearchService.php b/app/Services/Releases/ReleaseSearchService.php index 1da60b1f1..90328ab3f 100644 --- a/app/Services/Releases/ReleaseSearchService.php +++ b/app/Services/Releases/ReleaseSearchService.php @@ -75,7 +75,12 @@ class ReleaseSearchService return $value !== -1 && $value !== '' && $value !== null; }); - if (empty($searchFields)) { + if ($searchFields === []) { + return collect(); + } + + $categoryIds = $this->resolveSearchCategoryIds($cat, $excludedCats); + if ($categoryIds === []) { return collect(); } @@ -90,18 +95,6 @@ class ReleaseSearchService } } - $categoryIdsRaw = Category::getCategorySearch($cat, null, true); - - $categoryIds = null; - if (is_array($categoryIdsRaw)) { - $categoryIds = array_values(array_filter( - array_map(static fn ($id): int => (int) $id, $categoryIdsRaw), - static fn (int $id): bool => $id > 0 - )); - } elseif (is_int($categoryIdsRaw) || (is_string($categoryIdsRaw) && ctype_digit((string) $categoryIdsRaw))) { - $categoryIds = [(int) $categoryIdsRaw]; - } - [$sizeMinFromRange, $sizeMaxFromRange] = $this->resolveSizeRangeBounds($sizeFrom, $sizeTo); $minSizeCriteria = max((int) $minSize, $sizeMinFromRange); $maxSizeCriteria = $sizeMaxFromRange; @@ -1847,6 +1840,40 @@ class ReleaseSearchService return [$minDate, $maxDate]; } + /** + * Resolve leaf category IDs for search/browse filters (expands root categories). + * + * @param array $cat + * @param array $excludedCats + * @return array|null null = no category filter; [] = filter matches nothing + */ + private function resolveSearchCategoryIds(array $cat, array $excludedCats): ?array + { + $categoryIdsRaw = Category::getCategorySearch($cat, null, true); + + $categoryIds = null; + if (is_array($categoryIdsRaw)) { + $categoryIds = array_values(array_filter( + array_map(static fn ($id): int => (int) $id, $categoryIdsRaw), + static fn (int $id): bool => $id > 0 + )); + } elseif (is_int($categoryIdsRaw) || (is_string($categoryIdsRaw) && ctype_digit((string) $categoryIdsRaw))) { + $categoryIds = [(int) $categoryIdsRaw]; + } + + if (! is_array($categoryIds) || $categoryIds === []) { + return $categoryIds; + } + + if ($excludedCats === []) { + return $categoryIds; + } + + $excluded = array_map(static fn ($id): int => (int) $id, $excludedCats); + + return array_values(array_diff($categoryIds, $excluded)); + } + /** * Build category condition for web search (basic and advanced). * diff --git a/resources/views/search/index.blade.php b/resources/views/search/index.blade.php index c7ef86968..2a56ec060 100644 --- a/resources/views/search/index.blade.php +++ b/resources/views/search/index.blade.php @@ -50,6 +50,9 @@ + @php + $selectedCategory = request('t', request('searchadvcat', '')); + @endphp