Passed
Push — sheepy/introspection ( 9a33c8...7d1300 )
by Marco
05:54
created

SchemaService::getSolrVersion()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2.0023

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 20
ccs 11
cts 12
cp 0.9167
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2.0023

1 Method

Rating   Name   Duplication   Size   Complexity  
A SchemaService::getTypes() 0 10 2
1
<?php
2
3
4
namespace Firesphere\SolrSearch\Services;
5
6
use Exception;
7
use Firesphere\SolrSearch\Helpers\SearchIntrospection;
8
use Firesphere\SolrSearch\Helpers\Statics;
9
use Firesphere\SolrSearch\Indexes\BaseIndex;
10
use SilverStripe\Core\Injector\Injector;
11
use SilverStripe\Core\Manifest\ModuleLoader;
12
use SilverStripe\ORM\ArrayList;
13
use SilverStripe\ORM\FieldType\DBHTMLText;
14
use SilverStripe\View\ViewableData;
15
16
class SchemaService extends ViewableData
17
{
18
19
    /**
20
     * @var bool
21
     */
22
    protected $store = false;
23
    /**
24
     * @var string ABSOLUTE Path to template
25
     */
26
    protected $template;
27
28
    /**
29
     * @var string ABSOLUTE Path to types.ss template
30
     */
31
    protected $typesTemplate;
32
    /**
33
     * @var BaseIndex
34
     */
35
    protected $index;
36
37
    /**
38
     * @var SearchIntrospection
39
     */
40
    protected $introspection;
41
42
    /**
43
     * @var SolrCoreService
44
     */
45
    protected $coreService;
46
47
    /**
48
     * SchemaService constructor.
49
     */
50
    public function __construct()
51
    {
52
        parent::__construct();
53
        $this->introspection = Injector::inst()->get(SearchIntrospection::class);
54
        $this->coreService = Injector::inst()->get(SolrCoreService::class);
55
    }
56
57
    /**
58
     * @return BaseIndex
59
     */
60
    public function getIndex()
61
    {
62
        return $this->index;
63
    }
64
65
    /**
66
     * @param BaseIndex $index
67
     * @return SchemaService
68
     */
69
    public function setIndex($index)
70
    {
71
        $this->index = $index;
72
        // Add the index to the introspection as well, there's no need for a separate call here
73
        // We're loading this core, why would we want the introspection from a different index?
74
        $this->introspection->setIndex($index);
75
76
        return $this;
77
    }
78
79
    /**
80
     * @return string
81
     */
82
    public function getIndexName()
83
    {
84
        return $this->index->getIndexName();
85
    }
86
87
    /**
88
     * @return string
89
     */
90
    public function getDefaultField()
91
    {
92
        return $this->index->getDefaultField();
93
    }
94
95
    /**
96
     * Get the Identifier Field for Solr
97
     *
98
     * @return string
99
     */
100
    public function getIDField()
101
    {
102
        return SolrCoreService::ID_FIELD;
103
    }
104
105
    /**
106
     * Get the Identifier Field for Solr
107
     *
108
     * @return string
109
     */
110
    public function getClassID()
111
    {
112
        return SolrCoreService::CLASS_ID_FIELD;
113
    }
114
115
    /**
116
     * @return ArrayList
117
     * @throws Exception
118
     */
119
    public function getFulltextFieldDefinitions()
120
    {
121
        $return = ArrayList::create();
122
        foreach ($this->index->getFulltextFields() as $field) {
123
            $this->getFieldDefinition($field, $return);
124
        }
125
126
        return $return;
127
    }
128
129
    /**
130
     * @param $fieldName
131
     * @param ArrayList $return
132
     * @param null|string $copyField
133
     * @throws Exception
134
     */
135
    protected function getFieldDefinition($fieldName, &$return, $copyField = null)
136
    {
137
        $field = $this->introspection->getFieldIntrospection($fieldName);
138
        $typeMap = Statics::getTypeMap();
139
        $boostedFields = $this->index->getBoostedFields();
140
        foreach ($field as $name => $options) {
141
            // Temporary short-name solution until the Introspection is properly solved
142
            $name = explode('\\', $name);
143
            $name = end($name);
144
            // Boosted fields are always stored
145
            $store = ($this->store || array_key_exists($fieldName, $boostedFields)) ? 'true' : 'false';
146
            $item = [
147
                'Field'       => $name,
148
                'Type'        => $typeMap[$options['type']],
149
                'Indexed'     => 'true',
150
                'Stored'      => $store,
151
                'MultiValued' => $options['multi_valued'] ? 'true' : 'false',
152
                'Destination' => $copyField
153
            ];
154
            $return->push($item);
155
        }
156
    }
157
158
    /**
159
     * @return ArrayList
160
     */
161
    public function getCopyFields()
162
    {
163
        $fields = $this->index->getCopyFields();
164
165
        $return = ArrayList::create();
166
        foreach ($fields as $field => $copyFields) {
167
            $item = [
168
                'Field' => $field
169
            ];
170
171
            $return->push($item);
172
        }
173
174
        return $return;
175
    }
176
177
    /**
178
     * @return ArrayList
179
     * @throws Exception
180
     */
181
    public function getCopyFieldDefinitions()
182
    {
183
        $copyFields = $this->index->getCopyFields();
184
185
        $return = ArrayList::create();
186
187
        foreach ($copyFields as $field => $fields) {
188
            // Allow all fields to be in a copyfield via a shorthand
189
            if ($fields[0] === '*') {
190
                $fields = $this->index->getFulltextFields();
191
            }
192
193
            foreach ($fields as $copyField) {
194
                $this->getFieldDefinition($copyField, $return, $field);
195
            }
196
        }
197
198
        return $return;
199
    }
200
201
    /**
202
     * @return ArrayList
203
     * @throws Exception
204
     */
205
    public function getFilterFieldDefinitions()
206
    {
207
        $return = ArrayList::create();
208
        $originalStore = $this->store;
209
        $this->store = true;
210
        foreach ($this->index->getFilterFields() as $field) {
211
            $this->getFieldDefinition($field, $return);
212
        }
213
214
        $this->store = $originalStore;
215
216
        return $return;
217
    }
218
219
    /**
220
     * @return DBHTMLText
221
     */
222
    public function getTypes()
223
    {
224
        if (!$this->typesTemplate) {
225
            $solrVersion = $this->coreService->getSolrVersion();
226
            $dir = ModuleLoader::getModule('firesphere/solr-search')->getPath();
227
            $template = sprintf('%s/Solr/%s/templates/types.ss', $dir, $solrVersion);
228
            $this->setTypesTemplate($template);
229
        }
230
231
        return $this->renderWith($this->getTypesTemplate());
232
    }
233
234
    /**
235
     * @return string
236
     */
237
    public function getTypesTemplate()
238
    {
239
        return $this->typesTemplate;
240
    }
241
242
    /**
243
     * @param string $typesTemplate
244
     * @return SchemaService
245
     */
246
    public function setTypesTemplate($typesTemplate)
247
    {
248
        $this->typesTemplate = $typesTemplate;
249
250
        return $this;
251
    }
252
253
    /**
254
     * @return DBHTMLText
255
     */
256
    public function generateSchema()
257
    {
258
        if (!$this->template) {
259
            $solrVersion = $this->coreService->getSolrVersion();
260
            $dir = ModuleLoader::getModule('firesphere/solr-search')->getPath();
261
            $template = sprintf('%s/Solr/%s/templates/schema.ss', $dir, $solrVersion);
262
            $this->setTemplate($template);
263
        }
264
265
        return $this->renderWith($this->getTemplate());
266
    }
267
268
    /**
269
     * @return string
270
     */
271
    public function getTemplate()
272
    {
273
        return $this->template;
274
    }
275
276
    /**
277
     * @param string $template
278
     * @return SchemaService
279
     */
280
    public function setTemplate($template)
281
    {
282
        $this->template = $template;
283
284
        return $this;
285
    }
286
287
    /**
288
     * @return string
289
     */
290
    public function getExtrasPath()
291
    {
292
        // @todo configurable but with default to the current absolute path
293
        $dir = ModuleLoader::getModule('firesphere/solr-search')->getPath();
294
295
        $confDirs = SolrCoreService::config()->get('paths');
296
        $solrVersion = $this->coreService->getSolrVersion();
297
298
        return sprintf($confDirs[$solrVersion]['extras'], $dir);
299
    }
300
301
    /**
302
     * @param bool $store
303
     */
304
    public function setStore(bool $store): void
305
    {
306
        $this->store = $store;
307
    }
308
}
309