Passed
Push — master ( 3dc1a3...8beebe )
by Gordon
05:38 queued 03:19
created

SearchPageController::index()   C

Complexity

Conditions 11
Paths 50

Size

Total Lines 172
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 16
Bugs 0 Features 0
Metric Value
eloc 55
c 16
b 0
f 0
dl 0
loc 172
rs 6.8351
cc 11
nc 50
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types = 1);
2
3
namespace Suilven\FreeTextSearch\Page;
4
5
use SilverStripe\ORM\ArrayList;
6
use SilverStripe\ORM\DataObject;
7
use SilverStripe\ORM\PaginatedList;
8
use SilverStripe\View\ArrayData;
9
use Suilven\FreeTextSearch\Container\SearchResults;
10
use Suilven\FreeTextSearch\Factory\SearcherFactory;
11
use Suilven\FreeTextSearch\Indexes;
12
13
// @phpcs:disable SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification
14
15
/**
16
 * Class SearchPageController
17
 *
18
 * @package Suilven\FreeTextSearch\Page
19
 * @property int $ID Page ID
20
 * @property int $PageSize the number of results to show on each page
21
 */
22
23
class SearchPageController extends \PageController
24
{
25
    /** @var array<string> */
26
    private static $allowed_actions = ['index'];
27
28
29
30
    public function index(): \SilverStripe\View\ViewableData_Customised
31
    {
32
        // @todo search indexes addition
33
        $q = $this->getRequest()->getVar('q');
34
35
        /** @var array $selected */
36
        $selected = $this->getRequest()->getVars();
37
38
        /** @var \Suilven\FreeTextSearch\Page\SearchPage $model */
39
        $model = SearchPage::get_by_id(SearchPage::class, $this->ID);
40
41
        // @todo why?
42
       // unset($selected['start']);
43
44
        $results = new SearchResults();
45
46
47
        //unset($selected['q']);
48
49
        if (isset($q) || $model->ShowAllIfEmptyQuery || isset($selected['q'])) {
50
            $results = $this->performSearchIncludingFacets($selected, $model, $q);
51
        }
52
53
54
        /*
55
         *
56
         *         // get suggestions
57
58
        $factory = new SuggesterFactory();
59
60
        $suggester = $factory->getSuggester();
61
62
        // @todo this is returning blank
63
        $suggester->setIndex($model->IndexToSearch);
64
        $suggestions = $suggester->suggest($q);
65
66
67
68
69
        $facetted = isset($results['AllFacets']);
70
71
72
73
        $targetFacet = new ArrayList();
74
        if (isset($model->ShowTagCloudFor)) {
75
            // get the tag cloud from calculated facets, but if not calculated, ie the arrive on the page case,
76
            // calculate them
77
            if ($facetted) {
78
                $facets = $results['AllFacets'];
79
            } else {
80
                $proxyResults = $this->performSearchIncludingFacets($selected, $model, $q);
81
                $facets = $proxyResults['AllFacets'];
82
            }
83
84
            foreach ($facets as $facet) {
85
                $name = $facet->getField('Name');
86
                if ($name === $model->ShowTagCloudFor) {
87
                    $targetFacet = $facet->getField('Facets');
88
89
                    break;
90
                }
91
            }
92
93
            $facetArray = $targetFacet->toArray();
94
            $minSize = 10;
95
            $maxSize = 40;
96
            $maxCount = 0;
97
            foreach ($facetArray as $tag) {
98
                $count = $tag['Count'];
99
                $maxCount = $count > $maxCount
100
                    ? $count
101
                    : $maxCount;
102
            }
103
104
            $tagCloud = new ArrayList();
105
            foreach ($facetArray as $tag) {
106
                $size = $minSize + ($maxSize - $minSize) * $tag['Count'] / $maxCount;
107
                $size = \round($size);
108
                $row = new ArrayData([
109
                    'Name' => $tag['Value'],
110
                    'Size' => $size,
111
                    'Params' => $tag['Params'],
112
                ]);
113
                $tagCloud->push($row);
114
            }
115
116
            $results['TagCloud'] = $tagCloud;
117
        }
118
119
120
        //for($i = 3; $i < 40; $i++) {
121
           // echo "li.tag{$i} { font-size: {$i}px;};\n";
122
        //}
123
124
        */
125
126
127
        // defer showing to the template level, still get facets, as this allows optionally for likes of a tag cloud
128
        // $results['ShowAllIfEmptyQuery'] = $model->ShowAllIfEmptyQuery;
129
        // $results['CleanedLink'] = $this->Link();
130
131
        $indexes = new Indexes();
132
        $index = $indexes->getIndex($model->IndexToSearch);
133
        $clazz = $index->getClass();
134
135
        $templateName = 'Suilven/FreeTextSearch/' . \str_replace('\\', '/', $clazz);
136
        $splits = \explode('/', $templateName);
137
        $last = \array_pop($splits);
138
        $templateName = \implode('/', $splits) . '/Includes/' . $last;
139
140
        $records = $results->getRecords();
141
        $newRecords = new ArrayList();
142
        foreach ($records as $record) {
143
            $highsList = new ArrayList();
144
            $highlightsArray = $record->Highlights;
145
146
            if (isset($highlightsArray['Title'])) {
147
                $record->ResultTitle = $highlightsArray['Title'][0];
148
                unset($highlightsArray['Title']);
149
            }
150
151
            $record->HighlightedLink = $record->Link;
152
            if (isset($highlightsArray['Link']) && \count($highlightsArray['Link']) > 0) {
153
                $record->HighlightedLink = $highlightsArray['Link'][0];
154
                unset($highlightsArray['Link']);
155
            }
156
157
            // this simply repeats the title most times
158
            unset($highlightsArray['MenuTitle']);
159
160
            $keys = \is_null($highlightsArray)
161
                ? []
162
                : \array_keys($highlightsArray);
163
            foreach ($keys as $highlightedField) {
164
                foreach ($highlightsArray[$highlightedField] as $highlightsForField) {
165
                    $do = new DataObject();
166
                    // @phpstan-ignore-next-line
167
                    $do->Snippet = '...' . $highlightsForField . '...';
168
169
                    $highsList->push($do);
170
                }
171
            }
172
173
            $record->Highlights = $highsList;
174
175
            $html = $this->renderWith(
176
                [
177
                $templateName,
178
                'Suilven/FreeTextSearch/SilverStripe/CMS/Model/Includes/SiteTree',
179
                ],
180
                ['Record' => $record]
181
            );
182
            $record->HTML = $html;
183
            $newRecords->push($record);
184
        }
185
186
        $paginatedList = new PaginatedList($records);
187
        $paginatedList->setLimitItems(false);
188
        $paginatedList->setPageLength($results->getPageSize());
189
        $paginatedList->setTotalItems($results->getTotaNumberOfResults());
190
        $paginatedList->setCurrentPage($results->getPage());
191
192
        return $this->customise(new ArrayData([
193
            'NumberOfResults' => $results->getTotaNumberOfResults(),
194
            'Query' => $results->getQuery(),
195
            'Records' => $newRecords,
196
            'Page' => $results->getPage(),
197
            'PageSize' => $results->getPageSize(),
198
            'Pages' => $results->getTotalPages(),
199
            'Suggestions' => new ArrayList($results->getSuggestions()),
200
            'Time' => $results->getTime(),
201
            'Pagination' => $paginatedList,
202
        ]));
203
    }
204
205
206
    /** @param array<string,int|string|float|bool> $selected */
207
    public function performSearchIncludingFacets(array $selected, SearchPage $searchPage, ?string $q): SearchResults
208
    {
209
        $factory = new SearcherFactory();
210
211
        /** @var \Suilven\FreeTextSearch\Interfaces\Searcher $searcher */
212
        $searcher = $factory->getSearcher();
213
        $searcher->setFilters($selected);
214
        $searcher->setIndexName($searchPage->IndexToSearch);
215
216
        \error_log('SEARCH PAGE PAGE SIZE: ' . $searchPage->PageSize);
217
218
        $facets = $searchPage->getFacetFields();
219
        $hasManyFields = $searchPage->getHasManyFields();
220
221
        $searcher->setFacettedTokens($facets);
222
        $searcher->setHasManyTokens($hasManyFields);
223
224
        $searcher->setPageSize($this->PageSize);
225
        $start = $this->getRequest()->getVar('start');
226
227
228
        // page 1 is the first page
229
        $page = isset($start)
230
            ? \ceil($start / $this->PageSize) + 1
231
            : 1;
232
233
        $page = \intval($page);
234
        \error_log('PAGE: ' . $page);
235
        $searcher->setPage($page);
236
237
        return $searcher->search($q);
238
    }
239
}
240