Completed
Push — master ( e40ca5...464899 )
by Nicolas
03:14
created

Settings::get()   C

Complexity

Conditions 8
Paths 7

Size

Total Lines 36
Code Lines 20

Duplication

Lines 19
Ratio 52.78 %

Importance

Changes 0
Metric Value
dl 19
loc 36
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 20
nc 7
nop 1
1
<?php
2
namespace Elastica\Index;
3
4
use Elastica\Exception\NotFoundException;
5
use Elastica\Exception\ResponseException;
6
use Elastica\Index as BaseIndex;
7
use Elastica\Request;
8
9
/**
10
 * Elastica index settings object.
11
 *
12
 * All settings listed in the update settings API (https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html)
13
 * can be changed on a running indices. To make changes like the merge policy (https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html)
14
 * the index has to be closed first and reopened after the call
15
 *
16
 * @author Nicolas Ruflin <[email protected]>
17
 *
18
 * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html
19
 * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html
20
 */
21
class Settings
22
{
23
    const DEFAULT_REFRESH_INTERVAL = '1s';
24
25
    const DEFAULT_NUMBER_OF_REPLICAS = 1;
26
27
    /**
28
     * Response.
29
     *
30
     * @var \Elastica\Response Response object
31
     */
32
    protected $_response;
33
34
    /**
35
     * Stats info.
36
     *
37
     * @var array Stats info
38
     */
39
    protected $_data = [];
40
41
    /**
42
     * Index.
43
     *
44
     * @var \Elastica\Index Index object
45
     */
46
    protected $_index;
47
48
    /**
49
     * Construct.
50
     *
51
     * @param \Elastica\Index $index Index object
52
     */
53
    public function __construct(BaseIndex $index)
54
    {
55
        $this->_index = $index;
56
    }
57
58
    /**
59
     * Returns the current settings of the index.
60
     *
61
     * If param is set, only specified setting is return.
62
     * 'index.' is added in front of $setting.
63
     *
64
     * @param string $setting OPTIONAL Setting name to return
65
     *
66
     * @return array|string|null Settings data
67
     *
68
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html
69
     */
70
    public function get($setting = '')
71
    {
72
        $requestData = $this->request()->getData();
73
        $data = reset($requestData);
74
75
        if (empty($data['settings']) || empty($data['settings']['index'])) {
76
            // should not append, the request should throw a ResponseException
77
            throw new NotFoundException('Index '.$this->getIndex()->getName().' not found');
78
        }
79
        $settings = $data['settings']['index'];
80
81
        if (!$setting) {
82
            // return all array
83
            return $settings;
84
        }
85
86 View Code Duplication
        if (isset($settings[$setting])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
            return $settings[$setting];
88
        } else {
89
            if (strpos($setting, '.') !== false) {
90
                // translate old dot-notation settings to nested arrays
91
                $keys = explode('.', $setting);
92
                foreach ($keys as $key) {
93
                    if (isset($settings[$key])) {
94
                        $settings = $settings[$key];
95
                    } else {
96
                        return;
97
                    }
98
                }
99
100
                return $settings;
101
            }
102
103
            return;
104
        }
105
    }
106
107
    /**
108
     * Returns a setting interpreted as a bool.
109
     *
110
     * One can use a real bool, int(0), int(1) to set bool settings.
111
     * But Elasticsearch stores and returns all settings as strings and does
112
     * not normalize bool values. This method ensures a bool is returned for
113
     * whichever string representation is used like 'true', '1', 'on', 'yes'.
114
     *
115
     * @param string $setting Setting name to return
116
     *
117
     * @return bool
118
     */
119
    public function getBool($setting)
120
    {
121
        $data = $this->get($setting);
122
123
        return 'true' === $data || '1' === $data || 'on' === $data || 'yes' === $data;
124
    }
125
126
    /**
127
     * Sets the number of replicas.
128
     *
129
     * @param int $replicas Number of replicas
130
     *
131
     * @return \Elastica\Response Response object
132
     */
133
    public function setNumberOfReplicas($replicas)
134
    {
135
        return $this->set(['number_of_replicas' => (int) $replicas]);
136
    }
137
138
    /**
139
     * Returns the number of replicas.
140
     *
141
     * If no number of replicas is set, the default number is returned
142
     *
143
     * @return int The number of replicas
144
     */
145
    public function getNumberOfReplicas()
146
    {
147
        $replicas = $this->get('number_of_replicas');
148
149
        if (null === $replicas) {
150
            $replicas = self::DEFAULT_NUMBER_OF_REPLICAS;
151
        }
152
153
        return $replicas;
154
    }
155
156
    /**
157
     * Sets the index to read only.
158
     *
159
     * @param bool $readOnly (default = true)
160
     *
161
     * @return \Elastica\Response
162
     */
163
    public function setReadOnly($readOnly = true)
164
    {
165
        return $this->set(['blocks.read_only' => $readOnly]);
166
    }
167
168
    /**
169
     * @return bool
170
     */
171
    public function getReadOnly()
172
    {
173
        return $this->getBool('blocks.read_only');
174
    }
175
176
    /**
177
     * @return bool
178
     */
179
    public function getBlocksRead()
180
    {
181
        return $this->getBool('blocks.read');
182
    }
183
184
    /**
185
     * @param bool $state OPTIONAL (default = true)
186
     *
187
     * @return \Elastica\Response
188
     */
189
    public function setBlocksRead($state = true)
190
    {
191
        return $this->set(['blocks.read' => $state]);
192
    }
193
194
    /**
195
     * @return bool
196
     */
197
    public function getBlocksWrite()
198
    {
199
        return $this->getBool('blocks.write');
200
    }
201
202
    /**
203
     * @param bool $state OPTIONAL (default = true)
204
     *
205
     * @return \Elastica\Response
206
     */
207
    public function setBlocksWrite($state = true)
208
    {
209
        return $this->set(['blocks.write' => $state]);
210
    }
211
212
    /**
213
     * @return bool
214
     */
215
    public function getBlocksMetadata()
216
    {
217
        // When blocks.metadata is enabled, reading the settings is not possible anymore.
218
        // So when a cluster_block_exception happened it must be enabled.
219
        try {
220
            return $this->getBool('blocks.metadata');
221
        } catch (ResponseException $e) {
222
            if ($e->getResponse()->getFullError()['type'] === 'cluster_block_exception') {
223
                return true;
224
            }
225
226
            throw $e;
227
        }
228
    }
229
230
    /**
231
     * Set to true to disable index metadata reads and writes.
232
     *
233
     * @param bool $state OPTIONAL (default = true)
234
     *
235
     * @return \Elastica\Response
236
     */
237
    public function setBlocksMetadata($state = true)
238
    {
239
        return $this->set(['blocks.metadata' => $state]);
240
    }
241
242
    /**
243
     * Sets the index refresh interval.
244
     *
245
     * Value can be for example 3s for 3 seconds or
246
     * 5m for 5 minutes. -1 refreshing is disabled.
247
     *
248
     * @param int $interval Number of milliseconds
249
     *
250
     * @return \Elastica\Response Response object
251
     */
252
    public function setRefreshInterval($interval)
253
    {
254
        return $this->set(['refresh_interval' => $interval]);
255
    }
256
257
    /**
258
     * Returns the refresh interval.
259
     *
260
     * If no interval is set, the default interval is returned
261
     *
262
     * @return string Refresh interval
263
     */
264
    public function getRefreshInterval()
265
    {
266
        $interval = $this->get('refresh_interval');
267
268
        if (empty($interval)) {
269
            $interval = self::DEFAULT_REFRESH_INTERVAL;
270
        }
271
272
        return $interval;
273
    }
274
275
    /**
276
     * Sets the specific merge policies.
277
     *
278
     * To have this changes made the index has to be closed and reopened
279
     *
280
     * @param string $key   Merge policy key (for ex. expunge_deletes_allowed)
281
     * @param string $value
282
     *
283
     * @return \Elastica\Response
284
     *
285
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html
286
     */
287
    public function setMergePolicy($key, $value)
288
    {
289
        $this->getIndex()->close();
290
        $response = $this->set(['merge.policy.'.$key => $value]);
291
        $this->getIndex()->open();
292
293
        return $response;
294
    }
295
296
    /**
297
     * Returns the specific merge policy value.
298
     *
299
     * @param string $key Merge policy key (for ex. expunge_deletes_allowed)
300
     *
301
     * @return string Refresh interval
302
     *
303
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html
304
     */
305
    public function getMergePolicy($key)
306
    {
307
        $settings = $this->get();
308
        if (isset($settings['merge']['policy'][$key])) {
309
            return $settings['merge']['policy'][$key];
310
        }
311
312
        return;
313
    }
314
315
    /**
316
     * Can be used to set/update settings.
317
     *
318
     * @param array $data Arguments
319
     *
320
     * @return \Elastica\Response Response object
321
     */
322
    public function set(array $data)
323
    {
324
        return $this->request($data, Request::PUT);
325
    }
326
327
    /**
328
     * Returns the index object.
329
     *
330
     * @return \Elastica\Index Index object
331
     */
332
    public function getIndex()
333
    {
334
        return $this->_index;
335
    }
336
337
    /**
338
     * Updates the given settings for the index.
339
     *
340
     * With elasticsearch 0.16 the following settings are supported
341
     * - index.term_index_interval
342
     * - index.term_index_divisor
343
     * - index.translog.flush_threshold_ops
344
     * - index.translog.flush_threshold_size
345
     * - index.translog.flush_threshold_period
346
     * - index.refresh_interval
347
     * - index.merge.policy
348
     * - index.auto_expand_replicas
349
     *
350
     * @param array  $data   OPTIONAL Data array
351
     * @param string $method OPTIONAL Transfer method (default = \Elastica\Request::GET)
352
     *
353
     * @return \Elastica\Response Response object
354
     */
355
    public function request(array $data = [], $method = Request::GET)
356
    {
357
        $path = '_settings';
358
359
        if (!empty($data)) {
360
            $data = ['index' => $data];
361
        }
362
363
        return $this->getIndex()->request($path, $method, $data);
364
    }
365
}
366