Issues (759)

app/Http/Controllers/SearchController.php (1 issue)

1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Models\Category;
6
use App\Models\UsenetGroup;
7
use App\Services\Search\Contracts\SearchServiceInterface;
8
use Blacklight\Releases;
9
use Illuminate\Http\Request;
10
11
class SearchController extends BasePageController
12
{
13
    private SearchServiceInterface $searchService;
14
15
    public function __construct(SearchServiceInterface $searchService)
16
    {
17
        parent::__construct();
18
        $this->searchService = $searchService;
19
    }
20
21
    /**
22
     * @throws \Exception
23
     */
24
    public function search(Request $request)
25
    {
26
        $releases = new Releases;
27
28
        $results = [];
29
30
        $searchType = 'basic';
31
        if ($request->has('search_type') && $request->input('search_type') === 'adv') {
32
            $searchType = 'advanced';
33
        }
34
35
        $ordering = $releases->getBrowseOrdering();
36
        $orderBy = ($request->has('ob') && \in_array($request->input('ob'), $ordering, false) ? $request->input('ob') : '');
37
        $page = $request->has('page') && is_numeric($request->input('page')) ? $request->input('page') : 1;
38
        $offset = ($page - 1) * config('nntmux.items_per_page');
39
40
        $subject = '';
41
        $search = '';
42
        $id = '';
43
        $category = [0];
44
        $lastvisit = $this->userdata->lastlogin;
45
46
        if ($searchType === 'basic' && $request->missing('searchadvr') && ($request->has('id') || $request->has('subject') || $request->has('search'))) {
47
            $searchString = [];
48
            switch (true) {
49
                case $request->filled('subject'):
50
                    $searchString['searchname'] = (string) $request->input('subject') ?? [];
51
                    $subject = $searchString['searchname'];
52
                    break;
53
                case $request->filled('id'):
54
                    $searchString['searchname'] = (string) $request->input('id') ?? [];
55
                    $id = $searchString['searchname'];
56
                    break;
57
                case $request->filled('search'):
58
                    $searchString['searchname'] = (string) $request->input('search') ?? [];
59
                    $search = $searchString['searchname'];
60
                    break;
61
                default:
62
                    $searchString['searchname'] = '';
63
            }
64
65
            $categoryID[] = -1;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$categoryID was never initialized. Although not strictly required by PHP, it is generally a good practice to add $categoryID = array(); before regardless.
Loading history...
66
            if ($request->has('t')) {
67
                $categoryID = explode(',', $request->input('t'));
68
            }
69
70
            $orderByUrls = [];
71
            foreach ($releases->getBrowseOrdering() as $orderType) {
72
                $orderByUrls['orderby'.$orderType] = url('/search?search='.htmlentities($searchString['searchname'], ENT_QUOTES | ENT_HTML5).'&t='.implode(',', $categoryID).'&ob='.$orderType);
73
            }
74
75
            $rslt = $releases->search(
76
                $searchString,
77
                -1,
78
                -1,
79
                -1,
80
                -1,
81
                -1,
82
                $offset,
83
                config('nntmux.items_per_page'),
84
                $orderBy,
85
                -1,
86
                $this->userdata->categoryexclusions ?? [],
87
                'basic',
88
                $categoryID);
89
90
            $results = $this->paginate($rslt ?? [], $rslt[0]->_totalrows ?? 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query());
91
            $category = $categoryID;
92
        } else {
93
            $orderByUrls = [];
94
        }
95
96
        $searchVars = [
97
            'searchadvr' => '',
98
            'searchadvsubject' => '',
99
            'searchadvposter' => '',
100
            'searchadvfilename' => '',
101
            'searchadvdaysnew' => '',
102
            'searchadvdaysold' => '',
103
            'searchadvgroups' => '',
104
            'searchadvcat' => '',
105
            'searchadvsizefrom' => '',
106
            'searchadvsizeto' => '',
107
            'searchadvhasnfo' => '',
108
            'searchadvhascomments' => '',
109
        ];
110
111
        foreach ($searchVars as $searchVarKey => $searchVar) {
112
            $searchVars[$searchVarKey] = ($request->has($searchVarKey) ? (string) $request->input($searchVarKey) : '');
113
        }
114
115
        // Map new form field names to old internal names
116
        if ($request->has('minage')) {
117
            $searchVars['searchadvdaysnew'] = (string) $request->input('minage');
118
        }
119
        if ($request->has('maxage')) {
120
            $searchVars['searchadvdaysold'] = (string) $request->input('maxage');
121
        }
122
        if ($request->has('group')) {
123
            $searchVars['searchadvgroups'] = (string) $request->input('group');
124
        }
125
        if ($request->has('minsize')) {
126
            $searchVars['searchadvsizefrom'] = (string) $request->input('minsize');
127
        }
128
        if ($request->has('maxsize')) {
129
            $searchVars['searchadvsizeto'] = (string) $request->input('maxsize');
130
        }
131
        // Map basic search field to advanced search when in advanced mode
132
        if ($request->has('search') && $searchType === 'advanced') {
133
            $searchVars['searchadvr'] = (string) $request->input('search');
134
        }
135
        // Map basic category field to advanced category when in advanced mode
136
        if ($request->has('t') && $searchType === 'advanced') {
137
            $searchVars['searchadvcat'] = (string) $request->input('t');
138
        }
139
140
        $searchVars['selectedgroup'] = $searchVars['searchadvgroups'];
141
        $searchVars['selectedcat'] = $searchVars['searchadvcat'];
142
        $searchVars['selectedsizefrom'] = $searchVars['searchadvsizefrom'];
143
        $searchVars['selectedsizeto'] = $searchVars['searchadvsizeto'];
144
145
        // Get spell correction suggestions if we have a search query but few/no results
146
        $spellSuggestion = null;
147
        $searchQuery = $search ?: ($searchVars['searchadvr'] ?? '');
148
        if (! empty($searchQuery) && $this->searchService->isSuggestEnabled()) {
149
            // Get suggestions from search service
150
            $suggestions = $this->searchService->suggest($searchQuery);
151
            if (! empty($suggestions)) {
152
                // Sort by doc count descending to get best suggestion
153
                usort($suggestions, fn ($a, $b) => $b['docs'] - $a['docs']);
154
                // Only show suggestion if it's different from the query
155
                if ($suggestions[0]['suggest'] !== $searchQuery) {
156
                    $spellSuggestion = $suggestions[0]['suggest'];
157
                }
158
            }
159
        }
160
161
        if ($searchType !== 'basic' && $request->missing('id') && $request->missing('subject') && $request->anyFilled(['searchadvr', 'searchadvsubject', 'searchadvfilename', 'searchadvposter', 'minage', 'maxage', 'group', 'minsize', 'maxsize', 'search'])) {
162
            $orderByString = '';
163
            foreach ($searchVars as $searchVarKey => $searchVar) {
164
                $orderByString .= "&$searchVarKey=".htmlentities($searchVar, ENT_QUOTES | ENT_HTML5);
165
            }
166
            $orderByString = ltrim($orderByString, '&');
167
168
            $orderByUrls = [];
169
            foreach ($ordering as $orderType) {
170
                $orderByUrls['orderby'.$orderType] = url('/search?'.$orderByString.'&search_type=adv&ob='.$orderType);
171
            }
172
173
            $searchArr = [
174
                'searchname' => $searchVars['searchadvr'] === '' ? -1 : $searchVars['searchadvr'],
175
                'name' => $searchVars['searchadvsubject'] === '' ? -1 : $searchVars['searchadvsubject'],
176
                'fromname' => $searchVars['searchadvposter'] === '' ? -1 : $searchVars['searchadvposter'],
177
                'filename' => $searchVars['searchadvfilename'] === '' ? -1 : $searchVars['searchadvfilename'],
178
            ];
179
180
            $rslt = $releases->search(
181
                $searchArr,
182
                $searchVars['searchadvgroups'],
183
                $searchVars['searchadvsizefrom'],
184
                $searchVars['searchadvsizeto'],
185
                ($searchVars['searchadvdaysnew'] === '' ? -1 : $searchVars['searchadvdaysnew']),
186
                ($searchVars['searchadvdaysold'] === '' ? -1 : $searchVars['searchadvdaysold']),
187
                $offset,
188
                config('nntmux.items_per_page'),
189
                $orderBy,
190
                -1,
191
                $this->userdata->categoryexclusions ?? [],
192
                'advanced',
193
                [$searchVars['searchadvcat'] === '' ? -1 : $searchVars['searchadvcat']]
194
            );
195
196
            $results = $this->paginate($rslt ?? [], $rslt[0]->_totalrows ?? 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query());
197
        }
198
199
        $this->viewData = array_merge($this->viewData, $searchVars, $orderByUrls, [
200
            'subject' => $subject,
201
            'search' => $search,
202
            'id' => $id,
203
            'category' => $category,
204
            'covgroup' => '',
205
            'lastvisit' => $lastvisit,
206
            'sizelist' => [
207
                -1 => '--Select--', 1 => '100MB', 2 => '250MB', 3 => '500MB', 4 => '1GB', 5 => '2GB',
208
                6 => '3GB', 7 => '4GB', 8 => '8GB', 9 => '16GB', 10 => '32GB', 11 => '64GB',
209
            ],
210
            'results' => $results,
211
            'sadvanced' => $searchType !== 'basic',
212
            'grouplist' => UsenetGroup::getGroupsForSelect(),
213
            'catlist' => Category::getForSelect(),
214
            'meta_title' => 'Search Nzbs',
215
            'meta_keywords' => 'search,nzb,description,details',
216
            'meta_description' => 'Search for Nzbs',
217
            // Search enhanced features
218
            'spellSuggestion' => $spellSuggestion,
219
            'autocompleteEnabled' => $this->searchService->isAutocompleteEnabled(),
220
            'suggestEnabled' => $this->searchService->isSuggestEnabled(),
221
        ]);
222
223
        return view('search.index', $this->viewData);
224
    }
225
}
226