Passed
Pull Request — master (#5)
by Gordon
01:54
created

SearchPageController::index()   B

Complexity

Conditions 9
Paths 16

Size

Total Lines 138
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 16
Bugs 0 Features 0
Metric Value
eloc 34
c 16
b 0
f 0
dl 0
loc 138
rs 8.0555
cc 9
nc 16
nop 0

How to fix   Long Method   

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
/**
4
 * Created by PhpStorm.
5
 * User: gordon
6
 * Date: 25/3/2561
7
 * Time: 17:01 น.
8
 */
9
10
namespace Suilven\FreeTextSearch\Page;
11
12
use SilverStripe\ORM\ArrayList;
13
use SilverStripe\ORM\DataObject;
14
use SilverStripe\View\ArrayData;
15
use Suilven\FreeTextSearch\Container\SearchResults;
16
use Suilven\FreeTextSearch\Factory\SearcherFactory;
17
use Suilven\FreeTextSearch\Factory\SuggesterFactory;
18
19
/**
20
 * Class SearchPageController
21
 *
22
 * @package Suilven\FreeTextSearch\Page
23
 * @property int $ID Page ID
24
 * @property int $PageSize the number of results to show on each page
25
 * @todo Fix the annotation once format decided upon
26
 * @phpcs:disable SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification
27
 */
28
class SearchPageController extends \PageController
29
{
30
    private static $allowed_actions = ['index'];
31
32
    private static $db = [
33
        'PageSize' => 'Int',
34
    ];
35
36
    private static $defaults = [
37
        'PageSize' => 10,
38
    ];
39
40
41
    public function index(): \SilverStripe\View\ViewableData_Customised
42
    {
43
        // @todo search indexes addition
44
        $q = $this->getRequest()->getVar('q');
45
46
        /** @var array $selected */
47
        $selected = $this->getRequest()->getVars();
48
49
        /** @var \Suilven\FreeTextSearch\Page\SearchPage $model */
50
        $model = SearchPage::get_by_id(SearchPage::class, $this->ID);
51
52
53
        unset($selected['start']);
54
55
        $results = new SearchResults();
56
57
58
        //unset($selected['q']);
59
60
        if (isset($q) || $model->ShowAllIfEmptyQuery || isset($selected)) {
61
            $results = $this->performSearchIncludingFacets($selected, $model, $q);
62
        }
63
64
65
        $results->setQuery($q);
66
67
68
        // @todo In the case of facets and no search term this fails
69
        // This is intended for a search where a search term has been provided, but no results
70
        if (isset($q) && $results->getNumberOfResults() === 0) {
71
            // get suggestions
72
            $factory = new SuggesterFactory();
73
74
            /** @var \Suilven\FreeTextSearch\Factory\Suggester $suggester */
75
            $suggester = $factory->getSuggester();
76
77
            // @todo this is returning blank
78
            $suggester->setIndex($model->IndexToSearch);
79
            $suggestions = $suggester->suggest($q);
80
81
            $results['Suggestions'] = new ArrayList($suggestions);
82
83
            // @todo FIX - only one result returned for now
84
        }
85
86
87
        /*
88
        $facetted = isset($results['AllFacets']);
89
90
91
92
        $targetFacet = new ArrayList();
93
        if (isset($model->ShowTagCloudFor)) {
94
            // get the tag cloud from calculated facets, but if not calculated, ie the arrive on the page case,
95
            // calculate them
96
            if ($facetted) {
97
                $facets = $results['AllFacets'];
98
            } else {
99
                $proxyResults = $this->performSearchIncludingFacets($selected, $model, $q);
100
                $facets = $proxyResults['AllFacets'];
101
            }
102
103
            foreach ($facets as $facet) {
104
                $name = $facet->getField('Name');
105
                if ($name === $model->ShowTagCloudFor) {
106
                    $targetFacet = $facet->getField('Facets');
107
108
                    break;
109
                }
110
            }
111
112
            $facetArray = $targetFacet->toArray();
113
            $minSize = 10;
114
            $maxSize = 40;
115
            $maxCount = 0;
116
            foreach ($facetArray as $tag) {
117
                $count = $tag['Count'];
118
                $maxCount = $count > $maxCount
119
                    ? $count
120
                    : $maxCount;
121
            }
122
123
            $tagCloud = new ArrayList();
124
            foreach ($facetArray as $tag) {
125
                $size = $minSize + ($maxSize - $minSize) * $tag['Count'] / $maxCount;
126
                $size = \round($size);
127
                $row = new ArrayData([
128
                    'Name' => $tag['Value'],
129
                    'Size' => $size,
130
                    'Params' => $tag['Params'],
131
                ]);
132
                $tagCloud->push($row);
133
            }
134
135
            $results['TagCloud'] = $tagCloud;
136
        }
137
138
139
        //for($i = 3; $i < 40; $i++) {
140
           // echo "li.tag{$i} { font-size: {$i}px;};\n";
141
        //}
142
143
        */
144
145
146
        // defer showing to the template level, still get facets, as this allows optionally for likes of a tag cloud
147
        // $results['ShowAllIfEmptyQuery'] = $model->ShowAllIfEmptyQuery;
148
        // $results['CleanedLink'] = $this->Link();
149
150
        $records = $results->getRecords();
151
        $newRecords = new ArrayList();
152
        foreach ($records as $record) {
153
            $highsList = new ArrayList();
154
            $highlightsArray = $record->Highlights;
155
156
            $keys = \array_keys($highlightsArray);
157
            foreach ($keys as $highlightedField) {
158
                foreach ($highlightsArray[$highlightedField] as $highlightsForField) {
159
                    $do = new DataObject();
160
                    $do->Snippet = '...' . $highlightsForField . '...';
161
162
                    $highsList->push($do);
163
                }
164
            }
165
166
167
168
            $record->Highlights = $highsList;
169
            $newRecords->push($record);
170
        }
171
172
        return $this->customise(new ArrayData([
173
            'NumberOfResults' => $results->getNumberOfResults(),
174
            'Query' => $results->getQuery(),
175
            'Records' => $newRecords,
176
            'Page' => $results->getPage(),
177
            'PageSize' => $results->getPageSize(),
178
            'Time' => $results->getTime(),
179
        ]));
180
    }
181
182
183
    /** @param array<string,int|string|float|bool> $selected */
184
    public function performSearchIncludingFacets(array $selected, SearchPage $searchPage, ?string $q): SearchResults
185
    {
186
        $factory = new SearcherFactory();
187
188
        /** @var \Suilven\FreeTextSearch\Interfaces\Searcher $searcher */
189
        $searcher = $factory->getSearcher();
190
        $searcher->setFilters($selected);
191
        $searcher->setIndexName($searchPage->IndexToSearch);
192
193
194
        $facets = $searchPage->getFacetFields();
195
        $hasManyFields = $searchPage->getHasManyFields();
196
197
        $searcher->setFacettedTokens($facets);
198
        $searcher->setHasManyTokens($hasManyFields);
199
200
201
        if ($this->PageSize === 0) {
202
            $this->PageSize = 15;
203
        }
204
        $searcher->setPageSize($this->PageSize);
205
        $start = $this->getRequest()->getVar('start');
206
207
208
        // page 1 is the first page
209
        $page = isset($start)
210
            ? ($start / $this->PageSize) + 1
211
            : 1;
212
        $searcher->setPage($page);
213
214
        return $searcher->search($q);
0 ignored issues
show
Bug introduced by
It seems like $q can also be of type null; however, parameter $q of Suilven\FreeTextSearch\I...aces\Searcher::search() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

214
        return $searcher->search(/** @scrutinizer ignore-type */ $q);
Loading history...
215
    }
216
}
217