Completed
Pull Request — master (#14)
by Gordon
02:08
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', 'random'];
32
33
    private static $db = [
34
        'PageSize' => 'Int',
35
    ];
36
37
    private static $defaults = [
38
        'PageSize' => 10,
39
    ];
40
41
    public function random()
42
    {
43
        $parentIDs = [8,9,13];
44
        $re = new RandomEnglishGenerator();
45
        for($i=0; $i < 5000; $i++) {
46
            $title = $re->sentence(true);
47
            $content = $re->paragraph(20);
48
            $do = new \Page();
49
            $do->Title = $title;
50
            $do->Content = $content;
51
            shuffle($parentIDs);
52
            $do->ParentID = $parentIDs[0];
53
            $do->write();
54
            $do->publishSingle();
55
        }
56
    }
57
58
59
    public function index(): \SilverStripe\View\ViewableData_Customised
60
    {
61
        // @todo search indexes addition
62
        $q = $this->getRequest()->getVar('q');
63
64
        /** @var array $selected */
65
        $selected = $this->getRequest()->getVars();
66
67
        /** @var \Suilven\FreeTextSearch\Page\SearchPage $model */
68
        $model = SearchPage::get_by_id(SearchPage::class, $this->ID);
69
70
71
        unset($selected['start']);
72
73
        $results = new SearchResults();
74
75
76
        //unset($selected['q']);
77
78
        if (isset($q) || $model->ShowAllIfEmptyQuery || isset($selected)) {
79
            $results = $this->performSearchIncludingFacets($selected, $model, $q);
80
        }
81
82
83
        $results->setQuery($q);
84
85
86
        // @todo In the case of facets and no search term this fails
87
        // This is intended for a search where a search term has been provided, but no results
88
        if (isset($q) && $results->getNumberOfResults() === 0) {
89
            // get suggestions
90
            $factory = new SuggesterFactory();
91
92
            /** @var \Suilven\FreeTextSearch\Factory\Suggester $suggester */
93
            $suggester = $factory->getSuggester();
94
95
            // @todo this is returning blank
96
            $suggester->setIndex($model->IndexToSearch);
97
            $suggestions = $suggester->suggest($q);
98
99
            $results['Suggestions'] = new ArrayList($suggestions);
100
101
            // @todo FIX - only one result returned for now
102
        }
103
104
105
        /*
106
        $facetted = isset($results['AllFacets']);
107
108
109
110
        $targetFacet = new ArrayList();
111
        if (isset($model->ShowTagCloudFor)) {
112
            // get the tag cloud from calculated facets, but if not calculated, ie the arrive on the page case,
113
            // calculate them
114
            if ($facetted) {
115
                $facets = $results['AllFacets'];
116
            } else {
117
                $proxyResults = $this->performSearchIncludingFacets($selected, $model, $q);
118
                $facets = $proxyResults['AllFacets'];
119
            }
120
121
            foreach ($facets as $facet) {
122
                $name = $facet->getField('Name');
123
                if ($name === $model->ShowTagCloudFor) {
124
                    $targetFacet = $facet->getField('Facets');
125
126
                    break;
127
                }
128
            }
129
130
            $facetArray = $targetFacet->toArray();
131
            $minSize = 10;
132
            $maxSize = 40;
133
            $maxCount = 0;
134
            foreach ($facetArray as $tag) {
135
                $count = $tag['Count'];
136
                $maxCount = $count > $maxCount
137
                    ? $count
138
                    : $maxCount;
139
            }
140
141
            $tagCloud = new ArrayList();
142
            foreach ($facetArray as $tag) {
143
                $size = $minSize + ($maxSize - $minSize) * $tag['Count'] / $maxCount;
144
                $size = \round($size);
145
                $row = new ArrayData([
146
                    'Name' => $tag['Value'],
147
                    'Size' => $size,
148
                    'Params' => $tag['Params'],
149
                ]);
150
                $tagCloud->push($row);
151
            }
152
153
            $results['TagCloud'] = $tagCloud;
154
        }
155
156
157
        //for($i = 3; $i < 40; $i++) {
158
           // echo "li.tag{$i} { font-size: {$i}px;};\n";
159
        //}
160
161
        */
162
163
164
        // defer showing to the template level, still get facets, as this allows optionally for likes of a tag cloud
165
        // $results['ShowAllIfEmptyQuery'] = $model->ShowAllIfEmptyQuery;
166
        // $results['CleanedLink'] = $this->Link();
167
168
        $records = $results->getRecords();
169
        $newRecords = new ArrayList();
170
        foreach ($records as $record) {
171
            $highsList = new ArrayList();
172
            $highlightsArray = $record->Highlights;
173
174
            $keys = \array_keys($highlightsArray);
175
            foreach ($keys as $highlightedField) {
176
                foreach ($highlightsArray[$highlightedField] as $highlightsForField) {
177
                    $do = new DataObject();
178
                    $do->Snippet = '...' . $highlightsForField . '...';
179
180
                    $highsList->push($do);
181
                }
182
            }
183
184
185
186
            $record->Highlights = $highsList;
187
            $newRecords->push($record);
188
        }
189
190
        return $this->customise(new ArrayData([
191
            'NumberOfResults' => $results->getNumberOfResults(),
192
            'Query' => $results->getQuery(),
193
            'Records' => $newRecords,
194
            'Page' => $results->getPage(),
195
            'PageSize' => $results->getPageSize(),
196
            'Time' => $results->getTime(),
197
        ]));
198
    }
199
200
201
    /** @param array<string,int|string|float|bool> $selected */
202
    public function performSearchIncludingFacets(array $selected, SearchPage $searchPage, ?string $q): SearchResults
203
    {
204
        $factory = new SearcherFactory();
205
206
        /** @var \Suilven\FreeTextSearch\Interfaces\Searcher $searcher */
207
        $searcher = $factory->getSearcher();
208
        $searcher->setFilters($selected);
209
        $searcher->setIndexName($searchPage->IndexToSearch);
210
211
212
        $facets = $searchPage->getFacetFields();
213
        $hasManyFields = $searchPage->getHasManyFields();
214
215
        $searcher->setFacettedTokens($facets);
216
        $searcher->setHasManyTokens($hasManyFields);
217
218
219
        if ($this->PageSize === 0) {
220
            $this->PageSize = 15;
221
        }
222
        $searcher->setPageSize($this->PageSize);
223
        $start = $this->getRequest()->getVar('start');
224
225
226
        // page 1 is the first page
227
        $page = isset($start)
228
            ? ($start / $this->PageSize) + 1
229
            : 1;
230
        $searcher->setPage($page);
231
232
        return $searcher->search($q);
233
    }
234
}
235