Completed
Pull Request — master (#16)
by Gordon
02:18
created

SearchPageController::random()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 14
rs 9.8666
cc 2
nc 2
nop 0
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
use Suilven\RandomEnglish\RandomEnglishGenerator;
0 ignored issues
show
Bug introduced by
The type Suilven\RandomEnglish\RandomEnglishGenerator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
20
/**
21
 * Class SearchPageController
22
 *
23
 * @package Suilven\FreeTextSearch\Page
24
 * @property int $ID Page ID
25
 * @property int $PageSize the number of results to show on each page
26
 * @todo Fix the annotation once format decided upon
27
 * @phpcs:disable SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification
28
 */
29
class SearchPageController extends \PageController
30
{
31
    private static $allowed_actions = ['index'];
32
33
    private static $db = [
34
        'PageSize' => 'Int',
35
    ];
36
37
    private static $defaults = [
38
        'PageSize' => 10,
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
69
70
        // get suggestions
71
        $factory = new SuggesterFactory();
72
73
        /** @var \Suilven\FreeTextSearch\Factory\Suggester $suggester */
74
        $suggester = $factory->getSuggester();
75
76
        // @todo this is returning blank
77
        $suggester->setIndex($model->IndexToSearch);
78
        $suggestions = $suggester->suggest($q);
0 ignored issues
show
Unused Code introduced by
The assignment to $suggestions is dead and can be removed.
Loading history...
79
80
81
82
        /*
83
        $facetted = isset($results['AllFacets']);
84
85
86
87
        $targetFacet = new ArrayList();
88
        if (isset($model->ShowTagCloudFor)) {
89
            // get the tag cloud from calculated facets, but if not calculated, ie the arrive on the page case,
90
            // calculate them
91
            if ($facetted) {
92
                $facets = $results['AllFacets'];
93
            } else {
94
                $proxyResults = $this->performSearchIncludingFacets($selected, $model, $q);
95
                $facets = $proxyResults['AllFacets'];
96
            }
97
98
            foreach ($facets as $facet) {
99
                $name = $facet->getField('Name');
100
                if ($name === $model->ShowTagCloudFor) {
101
                    $targetFacet = $facet->getField('Facets');
102
103
                    break;
104
                }
105
            }
106
107
            $facetArray = $targetFacet->toArray();
108
            $minSize = 10;
109
            $maxSize = 40;
110
            $maxCount = 0;
111
            foreach ($facetArray as $tag) {
112
                $count = $tag['Count'];
113
                $maxCount = $count > $maxCount
114
                    ? $count
115
                    : $maxCount;
116
            }
117
118
            $tagCloud = new ArrayList();
119
            foreach ($facetArray as $tag) {
120
                $size = $minSize + ($maxSize - $minSize) * $tag['Count'] / $maxCount;
121
                $size = \round($size);
122
                $row = new ArrayData([
123
                    'Name' => $tag['Value'],
124
                    'Size' => $size,
125
                    'Params' => $tag['Params'],
126
                ]);
127
                $tagCloud->push($row);
128
            }
129
130
            $results['TagCloud'] = $tagCloud;
131
        }
132
133
134
        //for($i = 3; $i < 40; $i++) {
135
           // echo "li.tag{$i} { font-size: {$i}px;};\n";
136
        //}
137
138
        */
139
140
141
        // defer showing to the template level, still get facets, as this allows optionally for likes of a tag cloud
142
        // $results['ShowAllIfEmptyQuery'] = $model->ShowAllIfEmptyQuery;
143
        // $results['CleanedLink'] = $this->Link();
144
145
        $records = $results->getRecords();
146
        $newRecords = new ArrayList();
147
        foreach ($records as $record) {
148
            $highsList = new ArrayList();
149
            $highlightsArray = $record->Highlights;
150
151
            $keys = \array_keys($highlightsArray);
152
            foreach ($keys as $highlightedField) {
153
                foreach ($highlightsArray[$highlightedField] as $highlightsForField) {
154
                    $do = new DataObject();
155
                    $do->Snippet = '...' . $highlightsForField . '...';
156
157
                    $highsList->push($do);
158
                }
159
            }
160
161
162
163
            $record->Highlights = $highsList;
164
            $newRecords->push($record);
165
        }
166
167
        return $this->customise(new ArrayData([
168
            'NumberOfResults' => $results->getNumberOfResults(),
169
            'Query' => $results->getQuery(),
170
            'Records' => $newRecords,
171
            'Page' => $results->getPage(),
172
            'PageSize' => $results->getPageSize(),
173
            'Suggestions' => new ArrayList($results->getSuggestions()),
174
            'Time' => $results->getTime(),
175
        ]));
176
    }
177
178
179
    /** @param array<string,int|string|float|bool> $selected */
180
    public function performSearchIncludingFacets(array $selected, SearchPage $searchPage, ?string $q): SearchResults
181
    {
182
        $factory = new SearcherFactory();
183
184
        /** @var \Suilven\FreeTextSearch\Interfaces\Searcher $searcher */
185
        $searcher = $factory->getSearcher();
186
        $searcher->setFilters($selected);
187
        $searcher->setIndexName($searchPage->IndexToSearch);
188
189
190
        $facets = $searchPage->getFacetFields();
191
        $hasManyFields = $searchPage->getHasManyFields();
192
193
        $searcher->setFacettedTokens($facets);
194
        $searcher->setHasManyTokens($hasManyFields);
195
196
197
        if ($this->PageSize === 0) {
198
            $this->PageSize = 15;
199
        }
200
        $searcher->setPageSize($this->PageSize);
201
        $start = $this->getRequest()->getVar('start');
202
203
204
        // page 1 is the first page
205
        $page = isset($start)
206
            ? ($start / $this->PageSize) + 1
207
            : 1;
208
        $searcher->setPage($page);
209
210
        return $searcher->search($q);
211
    }
212
}
213