Passed
Push — hans/addAllFields ( 07d709 )
by Simon
08:19
created

BaseIndexTrait::addAllFulltextFields()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 11
rs 10
cc 3
nc 3
nop 0
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
    public function getCopyFields(): array
61
    {
62
        return $this->copyFields;
63
    }
64
65
    /**
66
     * @param array $copyField
67
     * @return $this
68
     */
69
    public function setCopyFields($copyField): self
70
    {
71
        $this->copyFields = $copyField;
72
73
        return $this;
74
    }
75
76
    /**
77
     * @return string
78
     */
79
    public function getDefaultField(): string
80
    {
81
        return $this->defaultField;
82
    }
83
84
    /**
85
     * @param string $defaultField
86
     * @return $this
87
     */
88
    public function setDefaultField($defaultField): self
89
    {
90
        $this->defaultField = $defaultField;
91
92
        return $this;
93
    }
94
95
    /**
96
     * @param $sortField
97
     * @return $this
98
     */
99
    public function addSortField($sortField): self
100
    {
101
        if (!in_array($sortField, $this->getFulltextFields(), true) &&
102
            !in_array($sortField, $this->getFilterFields(), true)
103
        ) {
104
            $this->addFulltextField($sortField);
105
            $this->sortFields[] = $sortField;
106
        }
107
108
        $this->setSortFields(array_unique($this->getSortFields()));
109
110
        return $this;
111
    }
112
113
    /**
114
     * @return array
115
     */
116
    public function getFulltextFields(): array
117
    {
118
        return array_values(
119
            array_unique(
120
                $this->fulltextFields
121
            )
122
        );
123
    }
124
125
    /**
126
     * @param array $fulltextFields
127
     * @return $this
128
     */
129
    public function setFulltextFields($fulltextFields): self
130
    {
131
        $this->fulltextFields = $fulltextFields;
132
133
        return $this;
134
    }
135
136
    /**
137
     * @return array
138
     */
139
    public function getFilterFields(): array
140
    {
141
        return $this->filterFields;
142
    }
143
144
    /**
145
     * @param array $filterFields
146
     * @return $this
147
     */
148
    public function setFilterFields($filterFields): self
149
    {
150
        $this->filterFields = $filterFields;
151
152
        return $this;
153
    }
154
155
    /**
156
     * @param string $fulltextField
157
     * @param null|string $forceType
158
     * @param array $options
159
     * @return $this
160
     */
161
    public function addFulltextField($fulltextField, $forceType = null, $options = []): self
162
    {
163
        if ($forceType) {
164
            Deprecation::notice('5.0', 'ForceType should be handled through casting');
165
        }
166
167
        $key = array_search($fulltextField, $this->getFilterFields(), true);
168
169
        if (!$key) {
170
            $this->fulltextFields[] = $fulltextField;
171
        }
172
173
        if (isset($options['boost'])) {
174
            $this->addBoostedField($fulltextField, [], $options['boost']);
175
        }
176
177
        if (isset($options['stored'])) {
178
            $this->storedFields[] = $fulltextField;
179
        }
180
181
        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
    public function getSortFields(): array
197
    {
198
        return $this->sortFields;
199
    }
200
201
    /**
202
     * @param array $sortFields
203
     * @return $this
204
     */
205
    public function setSortFields($sortFields): self
206
    {
207
        $this->sortFields = $sortFields;
208
209
        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
    public function addAllFulltextFields()
228
    {
229
        $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

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