Completed
Push — master ( 07a770...cad28f )
by Nicolas
03:05
created

Settings::getBool()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.2
c 0
b 0
f 0
cc 4
eloc 3
nc 4
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
    /**
26
     * Response.
27
     *
28
     * @var \Elastica\Response Response object
29
     */
30
    protected $_response;
31
32
    /**
33
     * Stats info.
34
     *
35
     * @var array Stats info
36
     */
37
    protected $_data = [];
38
39
    /**
40
     * Index.
41
     *
42
     * @var \Elastica\Index Index object
43
     */
44
    protected $_index;
45
46
    /**
47
     * Construct.
48
     *
49
     * @param \Elastica\Index $index Index object
50
     */
51
    public function __construct(BaseIndex $index)
52
    {
53
        $this->_index = $index;
54
    }
55
56
    /**
57
     * Returns the current settings of the index.
58
     *
59
     * If param is set, only specified setting is return.
60
     * 'index.' is added in front of $setting.
61
     *
62
     * @param string $setting OPTIONAL Setting name to return
63
     *
64
     * @return array|string|null Settings data
65
     *
66
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html
67
     */
68
    public function get($setting = '')
69
    {
70
        $requestData = $this->request()->getData();
71
        $data = reset($requestData);
72
73
        if (empty($data['settings']) || empty($data['settings']['index'])) {
74
            // should not append, the request should throw a ResponseException
75
            throw new NotFoundException('Index '.$this->getIndex()->getName().' not found');
76
        }
77
        $settings = $data['settings']['index'];
78
79
        if (!$setting) {
80
            // return all array
81
            return $settings;
82
        }
83
84 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...
85
            return $settings[$setting];
86
        } else {
87
            if (strpos($setting, '.') !== false) {
88
                // translate old dot-notation settings to nested arrays
89
                $keys = explode('.', $setting);
90
                foreach ($keys as $key) {
91
                    if (isset($settings[$key])) {
92
                        $settings = $settings[$key];
93
                    } else {
94
                        return;
95
                    }
96
                }
97
98
                return $settings;
99
            }
100
101
            return;
102
        }
103
    }
104
105
    /**
106
     * Returns a setting interpreted as a bool.
107
     *
108
     * One can use a real bool, int(0), int(1) to set bool settings.
109
     * But Elasticsearch stores and returns all settings as strings and does
110
     * not normalize bool values. This method ensures a bool is returned for
111
     * whichever string representation is used like 'true', '1', 'on', 'yes'.
112
     *
113
     * @param string $setting Setting name to return
114
     *
115
     * @return bool
116
     */
117
    public function getBool($setting)
118
    {
119
        $data = $this->get($setting);
120
121
        return 'true' === $data || '1' === $data || 'on' === $data || 'yes' === $data;
122
    }
123
124
    /**
125
     * Sets the number of replicas.
126
     *
127
     * @param int $replicas Number of replicas
128
     *
129
     * @return \Elastica\Response Response object
130
     */
131
    public function setNumberOfReplicas($replicas)
132
    {
133
        return $this->set(['number_of_replicas' => (int) $replicas]);
134
    }
135
136
    /**
137
     * Sets the index to read only.
138
     *
139
     * @param bool $readOnly (default = true)
140
     *
141
     * @return \Elastica\Response
142
     */
143
    public function setReadOnly($readOnly = true)
144
    {
145
        return $this->set(['blocks.read_only' => $readOnly]);
146
    }
147
148
    /**
149
     * @return bool
150
     */
151
    public function getReadOnly()
152
    {
153
        return $this->getBool('blocks.read_only');
154
    }
155
156
    /**
157
     * @return bool
158
     */
159
    public function getBlocksRead()
160
    {
161
        return $this->getBool('blocks.read');
162
    }
163
164
    /**
165
     * @param bool $state OPTIONAL (default = true)
166
     *
167
     * @return \Elastica\Response
168
     */
169
    public function setBlocksRead($state = true)
170
    {
171
        return $this->set(['blocks.read' => $state]);
172
    }
173
174
    /**
175
     * @return bool
176
     */
177
    public function getBlocksWrite()
178
    {
179
        return $this->getBool('blocks.write');
180
    }
181
182
    /**
183
     * @param bool $state OPTIONAL (default = true)
184
     *
185
     * @return \Elastica\Response
186
     */
187
    public function setBlocksWrite($state = true)
188
    {
189
        return $this->set(['blocks.write' => $state]);
190
    }
191
192
    /**
193
     * @return bool
194
     */
195
    public function getBlocksMetadata()
196
    {
197
        // When blocks.metadata is enabled, reading the settings is not possible anymore.
198
        // So when a cluster_block_exception happened it must be enabled.
199
        try {
200
            return $this->getBool('blocks.metadata');
201
        } catch (ResponseException $e) {
202
            if ($e->getResponse()->getFullError()['type'] === 'cluster_block_exception') {
203
                return true;
204
            }
205
206
            throw $e;
207
        }
208
    }
209
210
    /**
211
     * Set to true to disable index metadata reads and writes.
212
     *
213
     * @param bool $state OPTIONAL (default = true)
214
     *
215
     * @return \Elastica\Response
216
     */
217
    public function setBlocksMetadata($state = true)
218
    {
219
        return $this->set(['blocks.metadata' => $state]);
220
    }
221
222
    /**
223
     * Sets the index refresh interval.
224
     *
225
     * Value can be for example 3s for 3 seconds or
226
     * 5m for 5 minutes. -1 refreshing is disabled.
227
     *
228
     * @param int $interval Number of milliseconds
229
     *
230
     * @return \Elastica\Response Response object
231
     */
232
    public function setRefreshInterval($interval)
233
    {
234
        return $this->set(['refresh_interval' => $interval]);
235
    }
236
237
    /**
238
     * Returns the refresh interval.
239
     *
240
     * If no interval is set, the default interval is returned
241
     *
242
     * @return string Refresh interval
243
     */
244
    public function getRefreshInterval()
245
    {
246
        $interval = $this->get('refresh_interval');
247
248
        if (empty($interval)) {
249
            $interval = self::DEFAULT_REFRESH_INTERVAL;
250
        }
251
252
        return $interval;
253
    }
254
255
    /**
256
     * Sets the specific merge policies.
257
     *
258
     * To have this changes made the index has to be closed and reopened
259
     *
260
     * @param string $key   Merge policy key (for ex. expunge_deletes_allowed)
261
     * @param string $value
262
     *
263
     * @return \Elastica\Response
264
     *
265
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html
266
     */
267
    public function setMergePolicy($key, $value)
268
    {
269
        $this->getIndex()->close();
270
        $response = $this->set(['merge.policy.'.$key => $value]);
271
        $this->getIndex()->open();
272
273
        return $response;
274
    }
275
276
    /**
277
     * Returns the specific merge policy value.
278
     *
279
     * @param string $key Merge policy key (for ex. expunge_deletes_allowed)
280
     *
281
     * @return string Refresh interval
282
     *
283
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html
284
     */
285
    public function getMergePolicy($key)
286
    {
287
        $settings = $this->get();
288
        if (isset($settings['merge']['policy'][$key])) {
289
            return $settings['merge']['policy'][$key];
290
        }
291
292
        return;
293
    }
294
295
    /**
296
     * Can be used to set/update settings.
297
     *
298
     * @param array $data Arguments
299
     *
300
     * @return \Elastica\Response Response object
301
     */
302
    public function set(array $data)
303
    {
304
        return $this->request($data, Request::PUT);
305
    }
306
307
    /**
308
     * Returns the index object.
309
     *
310
     * @return \Elastica\Index Index object
311
     */
312
    public function getIndex()
313
    {
314
        return $this->_index;
315
    }
316
317
    /**
318
     * Updates the given settings for the index.
319
     *
320
     * With elasticsearch 0.16 the following settings are supported
321
     * - index.term_index_interval
322
     * - index.term_index_divisor
323
     * - index.translog.flush_threshold_ops
324
     * - index.translog.flush_threshold_size
325
     * - index.translog.flush_threshold_period
326
     * - index.refresh_interval
327
     * - index.merge.policy
328
     * - index.auto_expand_replicas
329
     *
330
     * @param array  $data   OPTIONAL Data array
331
     * @param string $method OPTIONAL Transfer method (default = \Elastica\Request::GET)
332
     *
333
     * @return \Elastica\Response Response object
334
     */
335
    public function request(array $data = [], $method = Request::GET)
336
    {
337
        $path = '_settings';
338
339
        if (!empty($data)) {
340
            $data = ['index' => $data];
341
        }
342
343
        return $this->getIndex()->request($path, $method, $data);
344
    }
345
}
346