Passed
Push — hans/addAllFields ( f68e84...8daad2 )
by Simon
07:46 queued 03:28
created

BaseIndexTrait::setFulltextFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
4
namespace Firesphere\SolrSearch\Traits;
5
6
use Firesphere\SolrSearch\Indexes\BaseIndex;
7
use SilverStripe\Dev\Deprecation;
8
use SilverStripe\ORM\DataObject;
9
use SilverStripe\ORM\FieldType\DBString;
10
use Solarium\Core\Client\Client;
11
12
/**
13
 * This is slightly cheating, but it works and also makes things more readable.
14
 *
15
 * Trait BaseIndexTrait
16
 * @package Firesphere\SolrSearch\Traits
17
 */
18
trait BaseIndexTrait
19
{
20
    /**
21
     * @var Client
22
     */
23
    protected $client;
24
    /**
25
     * @var array
26
     */
27
    protected $facetFields = [];
28
    /**
29
     * @var array
30
     */
31
    protected $fulltextFields = [];
32
    /**
33
     * @var array
34
     */
35
    protected $filterFields = [];
36
    /**
37
     * @var array
38
     */
39
    protected $sortFields = [];
40
    /**
41
     * @var string
42
     */
43
    protected $defaultField = '_text';
44
    /**
45
     * @var array
46
     */
47
    protected $storedFields = [];
48
    /**
49
     * @var array
50
     */
51
    protected $copyFields = [
52
        '_text' => [
53
            '*'
54
        ],
55
    ];
56
57
    /**
58
     * @return array
59
     */
60 28
    public function getCopyFields(): array
61
    {
62 28
        return $this->copyFields;
63
    }
64
65
    /**
66
     * @param array $copyField
67
     * @return $this
68
     */
69 65
    public function setCopyFields($copyField): self
70
    {
71 65
        $this->copyFields = $copyField;
72
73 65
        return $this;
74
    }
75
76
    /**
77
     * @return string
78
     */
79 29
    public function getDefaultField(): string
80
    {
81 29
        return $this->defaultField;
82
    }
83
84
    /**
85
     * @param string $defaultField
86
     * @return $this
87
     */
88 65
    public function setDefaultField($defaultField): self
89
    {
90 65
        $this->defaultField = $defaultField;
91
92 65
        return $this;
93
    }
94
95
    /**
96
     * @param $sortField
97
     * @return $this
98
     */
99 66
    public function addSortField($sortField): self
100
    {
101 66
        if (!in_array($sortField, $this->getFulltextFields(), true) &&
102 66
            !in_array($sortField, $this->getFilterFields(), true)
103
        ) {
104 1
            $this->addFulltextField($sortField);
105 1
            $this->sortFields[] = $sortField;
106
        }
107
108 66
        $this->setSortFields(array_unique($this->getSortFields()));
109
110 66
        return $this;
111
    }
112
113
    /**
114
     * @return array
115
     */
116 66
    public function getFulltextFields(): array
117
    {
118 66
        return array_values(
119 66
            array_unique(
120 66
                $this->fulltextFields
121
            )
122
        );
123
    }
124
125
    /**
126
     * @param array $fulltextFields
127
     * @return $this
128
     */
129 65
    public function setFulltextFields($fulltextFields): self
130
    {
131 65
        $this->fulltextFields = $fulltextFields;
132
133 65
        return $this;
134
    }
135
136
    /**
137
     * @return array
138
     */
139 66
    public function getFilterFields(): array
140
    {
141 66
        return $this->filterFields;
142
    }
143
144
    /**
145
     * @param array $filterFields
146
     * @return $this
147
     */
148 65
    public function setFilterFields($filterFields): self
149
    {
150 65
        $this->filterFields = $filterFields;
151
152 65
        return $this;
153
    }
154
155
    /**
156
     * @param string $fulltextField
157
     * @param null|string $forceType
158
     * @param array $options
159
     * @return $this
160
     */
161 66
    public function addFulltextField($fulltextField, $forceType = null, $options = []): self
162
    {
163 66
        if ($forceType) {
164
            Deprecation::notice('5.0', 'ForceType should be handled through casting');
165
        }
166
167 66
        $key = array_search($fulltextField, $this->getFilterFields(), true);
168
169 66
        if (!$key) {
170 66
            $this->fulltextFields[] = $fulltextField;
171
        }
172
173 66
        if (isset($options['boost'])) {
174 1
            $this->addBoostedField($fulltextField, [], $options['boost']);
175
        }
176
177 66
        if (isset($options['stored'])) {
178 1
            $this->storedFields[] = $fulltextField;
179
        }
180
181 66
        return $this;
182
    }
183
184
    /**
185
     * Add an abstract for the add Boosted Field to keep things consistent
186
     * @param string $field
187
     * @param array|int $options
188
     * @param null|int $boost
189
     * @return mixed
190
     */
191
    abstract public function addBoostedField($field, $options = [], $boost = null);
192
193
    /**
194
     * @return array
195
     */
196 66
    public function getSortFields(): array
197
    {
198 66
        return $this->sortFields;
199
    }
200
201
    /**
202
     * @param array $sortFields
203
     * @return $this
204
     */
205 66
    public function setSortFields($sortFields): self
206
    {
207 66
        $this->sortFields = $sortFields;
208
209 66
        return $this;
210
    }
211
212
    /**
213
     * @deprecated Please use addAllFulltextFields(). IncludeSubClasses is not used anymore
214
     * @param bool $includeSubclasses
215
     */
216
    public function addFulltextFields($includeSubclasses = true)
1 ignored issue
show
Unused Code introduced by
The parameter $includeSubclasses is not used and could be removed. ( Ignorable by Annotation )

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

216
    public function addFulltextFields(/** @scrutinizer ignore-unused */ $includeSubclasses = true)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
217
    {
218
        $this->addAllFulltextFields();
219
    }
220
221
    /**
222
     * Add all database-backed text fields as fulltext searchable fields.
223
     *
224
     * For every class included in the index, examines those classes and all parent looking for "DBText" database
225
     * fields (Varchar, Text, HTMLText, etc) and adds them all as fulltext searchable fields.
226
     *
227
     * Note, there is no check on boosting etc. That needs to be done manually.
228
     */
229
    public function addAllFulltextFields()
230
    {
231
        $classes = $this->getClasses();
0 ignored issues
show
Bug introduced by
It seems like getClasses() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

231
        /** @scrutinizer ignore-call */ 
232
        $classes = $this->getClasses();
Loading history...
232
        foreach ($classes as $class => $options) {
233
            $hierarchy = class_parents($class);
234
            array_unshift($hierarchy, $class);
235
            /** @var DataObject $dataclass But not really, just a string */
236
            foreach ($hierarchy as $dataClass) {
237
                $fields = DataObject::getSchema()->databaseFields($dataClass);
238
239
                $this->addFulltextFieldsForClass($fields);
240
            }
241
        }
242
    }
243
244
    /**
245
     * @param array $fields
246
     */
247
    protected function addFulltextFieldsForClass(array $fields): void
248
    {
249
        foreach ($fields as $field => $type) {
250
            $pos = strpos($type, '(');
251
            $type = substr($type, 0, $pos + 1);
252
            $inst = singleton($type);
253
            if ($inst instanceof DBString) {
254
                $this->addFulltextField($field);
255
            }
256
        }
257
    }
258
259
    /**
260
     * @param $field
261
     * @param array $options
262
     * @return $this
263
     */
264 1
    public function addFacetField($field, $options): self
265
    {
266 1
        $this->facetFields[$field] = $options;
267
268 1
        if (!in_array($field, $this->getFilterFields(), true)) {
269 1
            $this->addFilterField($field);
270
        }
271
272 1
        return $this;
273
    }
274
275
    /**
276
     * @param $filterField
277
     * @return $this
278
     */
279 66
    public function addFilterField($filterField): self
280
    {
281 66
        $key = array_search($filterField, $this->getFulltextFields(), true);
282 66
        if ($key === false) {
283 66
            $this->filterFields[] = $filterField;
284
        }
285
286 66
        return $this;
287
    }
288
289
    /**
290
     * @param string $field Name of the copyfield
291
     * @param array $options Array of all fields that should be copied to this copyfield
292
     * @return $this
293
     */
294 1
    public function addCopyField($field, $options): self
295
    {
296 1
        $this->copyFields[$field] = $options;
297
298 1
        return $this;
299
    }
300
301
    /**
302
     * @param string $field
303
     * @param null|string $forceType
304
     * @param array $extraOptions
305
     * @return BaseIndex
306
     */
307 1
    public function addStoredField($field, $forceType = null, $extraOptions = []): self
308
    {
309 1
        $options = array_merge($extraOptions, ['stored' => 'true']);
310 1
        $this->addFulltextField($field, $forceType, $options);
311
312 1
        return $this;
313
    }
314
315
    /**
316
     * @return Client
317
     */
318 18
    public function getClient()
319
    {
320 18
        return $this->client;
321
    }
322
323
    /**
324
     * @param Client $client
325
     * @return $this
326
     */
327 1
    public function setClient($client): self
328
    {
329 1
        $this->client = $client;
330
331 1
        return $this;
332
    }
333
334
    /**
335
     * @return array
336
     */
337 28
    public function getStoredFields(): array
338
    {
339 28
        return $this->storedFields;
340
    }
341
342
    /**
343
     * @param array $storedFields
344
     * @return BaseIndex
345
     */
346 1
    public function setStoredFields(array $storedFields): self
347
    {
348 1
        $this->storedFields = $storedFields;
349
350 1
        return $this;
351
    }
352
}
353