Passed
Push — master ( f9d9de...1bbdfe )
by Gordon
04:44 queued 02:46
created

Indexes::getFacetFields()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 13
c 2
b 0
f 0
dl 0
loc 25
rs 8.8333
cc 7
nc 8
nop 1
1
<?php declare(strict_types = 1);
2
3
// @phpcs:disable SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed
4
5
namespace Suilven\FreeTextSearch;
6
7
use SilverStripe\Core\Config\Config;
8
9
/**
10
 * Class Indexes
11
 *
12
 * @package Suilven\FreeTextSearch
13
 */
14
class Indexes
15
{
16
    /** @var array<string, \Suilven\FreeTextSearch\Index> */
17
    private $indexesByName = [];
18
19
20
    /**
21
     * Get an Index object by name from the config
22
     */
23
    public function getIndex(string $name): Index
24
    {
25
        if ($this->indexesByName === []) {
26
            $this->getIndexes();
27
        }
28
29
        return $this->indexesByName[$name];
30
    }
31
32
33
    /**
34
     * Get indexes from config
35
     *
36
     * @return array<string, \Suilven\FreeTextSearch\Index> ClassName -> Index
37
     */
38
    public function getIndexes(): array
39
    {
40
        $indexesConfig = Config::inst()->get('Suilven\FreeTextSearch\Indexes', 'indexes') ;
41
42
        // reset
43
        $this->indexesByName = [];
44
45
        foreach ($indexesConfig as $indexConfig) {
46
            $name = $indexConfig['index']['name'];
47
            $indexAlreadyExists = isset($this->indexesByName[$name]);
48
49
            // get the existing index, to tweak, or create a new one
50
            $index = $indexAlreadyExists
51
                ? $this->indexesByName[$name]
52
                : new Index();
53
            $index->setName($name);
54
55
            if (isset($indexConfig['index']['class'])) {
56
                $index->setClass($indexConfig['index']['class']);
57
            }
58
59
            if (isset($indexConfig['index']['fields'])) {
60
                foreach ($indexConfig['index']['fields'] as $fieldname) {
61
                    $index->addField($fieldname);
62
                }
63
            }
64
65
            if (isset($indexConfig['index']['tokens'])) {
66
                foreach ($indexConfig['index']['tokens'] as $token) {
67
                    $index->addToken($token);
68
                }
69
            }
70
71
            // has one fields
72
            $singleton = \singleton($index->getClass());
73
74
            if (isset($indexConfig['index']['has_one'])) {
75
                foreach ($indexConfig['index']['has_one'] as $hasOneField) {
76
                    $relationship = $hasOneField['relationship'];
77
                    // @phpstan-ignore-next-line
78
                    $singletonOfRel = \call_user_func(array($singleton, $relationship));
79
80
                    $index->addHasOneField($hasOneField['name'], [
81
                        'relationship' => $relationship,
82
                        'field' => $hasOneField['field'],
83
                        'class' => $singletonOfRel->ClassName,
84
                    ]);
85
                }
86
            }
87
88
            // has many fields
89
            // NB many many may need to be treated as bipartisan has many
90
            if (isset($indexConfig['index']['has_many'])) {
91
                foreach ($indexConfig['index']['has_many'] as $hasOneField) {
92
                    $relationship = $hasOneField['relationship'];
93
                    // @phpstan-ignore-next-line
94
                    $singletonOfRel = \call_user_func(array($singleton, $relationship));
95
                    $index->addHasManyField($hasOneField['name'], [
96
                        'relationship' => $relationship,
97
                        'field' => $hasOneField['field'],
98
                        'class' => $singletonOfRel->dataClass(),
99
                    ]);
100
                }
101
            }
102
103
            // fields that will be used for highlighting
104
            if (isset($indexConfig['index']['highlighted_fields'])) {
105
                foreach ($indexConfig['index']['highlighted_fields'] as $highlightedField) {
106
                    $index->addHighlightedField($highlightedField);
107
                }
108
            }
109
110
            // fields that will be used for storage, but not indexed
111
            if (isset($indexConfig['index']['stored_fields'])) {
112
                foreach ($indexConfig['index']['stored_fields'] as $storedField) {
113
                    $index->addStoredField($storedField);
114
                }
115
            }
116
117
            // tokenizer
118
            if (isset($indexConfig['index']['tokenizer'])) {
119
                $index->setTokenizer($indexConfig['index']['tokenizer']);
120
            }
121
122
            $this->indexesByName[$index->getName()] = $index;
123
        }
124
125
        return $this->indexesByName;
126
    }
127
128
129
    /** @return array<string> An array of facet fields, such as ['ISO', 'Aperture', 'ShutterSpeed'] */
130
    public function getFacetFields(string $indexName): array
131
    {
132
        $indexesConfig = Config::inst()->get('Suilven\FreeTextSearch\Indexes', 'indexes');
133
        $result = [];
134
        foreach ($indexesConfig as $indexConfig) {
135
            $name = ($indexConfig['index']['name']);
136
137
            if ($name !== $indexName) {
138
                continue;
139
            }
140
141
            if (isset($indexConfig['index']['tokens'])) {
142
                foreach ($indexConfig['index']['tokens'] as $token) {
143
                    $result[] = $token;
144
                }
145
            }
146
147
            if (isset($indexConfig['index']['has_one'])) {
148
                foreach ($indexConfig['index']['has_one'] as $hasOneField) {
149
                    $result[] = $hasOneField['name'];
150
                }
151
            }
152
        }
153
154
        return $result;
155
    }
156
157
158
    /** @return array<string> */
159
    public function getHasOneFields(string $indexName): array
160
    {
161
        $indexesConfig = Config::inst()->get('Suilven\FreeTextSearch\Indexes', 'indexes');
162
163
        $result = [];
164
        foreach ($indexesConfig as $indexConfig) {
165
            $name = ($indexConfig['index']['name']);
166
167
            if ($name !== $indexName) {
168
                continue;
169
            }
170
171
            if (isset($indexConfig['index']['has_one'])) {
172
                foreach ($indexConfig['index']['has_one'] as $hasOne) {
173
                    $result[] = $hasOne;
174
                }
175
            }
176
        }
177
178
        return $result;
179
    }
180
181
182
    /** @return array<int,array<string,string>> */
183
    public function getHasManyFields(string $indexName): array
184
    {
185
        $indexesConfig = Config::inst()->get('Suilven\FreeTextSearch\Indexes', 'indexes');
186
187
        $result = [];
188
        foreach ($indexesConfig as $indexConfig) {
189
            $name = ($indexConfig['index']['name']);
190
191
            if ($name !== $indexName) {
192
                continue;
193
            }
194
195
            if (isset($indexConfig['index']['has_many'])) {
196
                /** @var array<string,string> $hasManyField */
197
                foreach ($indexConfig['index']['has_many'] as $hasManyField) {
198
                    $result[] = $hasManyField;
199
                }
200
            }
201
        }
202
203
        return $result;
204
    }
205
}
206