Passed
Push — hans/addAllFields ( 30dc29...48c3f4 )
by Simon
07:26 queued 01:24
created

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

219
    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...
220
    {
221
        $this->addAllFulltextFields();
222
    }
223
224
    /**
225
     * Add all database-backed text fields as fulltext searchable fields.
226
     *
227
     * For every class included in the index, examines those classes and all parent looking for "DBText" database
228
     * fields (Varchar, Text, HTMLText, etc) and adds them all as fulltext searchable fields.
229
     *
230
     * Note, there is no check on boosting etc. That needs to be done manually.
231
     * @throws \ReflectionException
232
     */
233 1
    public function addAllFulltextFields()
234
    {
235 1
        $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

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