Completed
Push — master ( 3a2d29...d0475e )
by Nicolas
02:57
created

lib/Elastica/Index/Settings.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
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
     * Sets the number of replicas.
107
     *
108
     * @param int $replicas Number of replicas
109
     *
110
     * @return \Elastica\Response Response object
111
     */
112
    public function setNumberOfReplicas($replicas)
113
    {
114
        $replicas = (int) $replicas;
115
116
        $data = ['number_of_replicas' => $replicas];
117
118
        return $this->set($data);
119
    }
120
121
    /**
122
     * Sets the index to read only.
123
     *
124
     * @param bool $readOnly (default = true)
125
     *
126
     * @return \Elastica\Response
127
     */
128
    public function setReadOnly($readOnly = true)
129
    {
130
        return $this->set(['blocks.write' => $readOnly]);
131
    }
132
133
    /**
134
     * getReadOnly.
135
     *
136
     * @return bool
137
     */
138
    public function getReadOnly()
139
    {
140
        return $this->get('blocks.write') === 'true'; // ES returns a string for this setting
141
    }
142
143
    /**
144
     * @return bool
145
     */
146
    public function getBlocksRead()
147
    {
148
        return (bool) $this->get('blocks.read');
149
    }
150
151
    /**
152
     * @param bool $state OPTIONAL (default = true)
153
     *
154
     * @return \Elastica\Response
155
     */
156
    public function setBlocksRead($state = true)
157
    {
158
        $state = $state ? 1 : 0;
159
160
        return $this->set(['blocks.read' => $state]);
161
    }
162
163
    /**
164
     * @return bool
165
     */
166
    public function getBlocksWrite()
167
    {
168
        return (bool) $this->get('blocks.write');
169
    }
170
171
    /**
172
     * @param bool $state OPTIONAL (default = true)
173
     *
174
     * @return \Elastica\Response
175
     */
176
    public function setBlocksWrite($state = true)
177
    {
178
        $state = $state ? 1 : 0;
179
180
        return $this->set(['blocks.write' => $state]);
181
    }
182
183
    /**
184
     * @return bool
185
     */
186
    public function getBlocksMetadata()
187
    {
188
        // TODO will have to be replace by block.metadata.write once https://github.com/elasticsearch/elasticsearch/pull/9203 has been fixed
189
        // the try/catch will have to be remove too
190
        try {
191
            return (bool) $this->get('blocks.write');
192
        } catch (ResponseException $e) {
193
            if (strpos($e->getMessage(), 'ClusterBlockException') !== false) {
194
                // hacky way to test if the metadata is blocked since bug 9203 is not fixed
195
                return true;
196
            }
197
198
            throw $e;
199
        }
200
    }
201
202
    /**
203
     * @param bool $state OPTIONAL (default = true)
204
     *
205
     * @return \Elastica\Response
206
     */
207
    public function setBlocksMetadata($state = true)
208
    {
209
        $state = $state ? 1 : 0;
210
211
        return $this->set(['blocks.write' => $state]);
212
    }
213
214
    /**
215
     * Sets the index refresh interval.
216
     *
217
     * Value can be for example 3s for 3 seconds or
218
     * 5m for 5 minutes. -1 refreshing is disabled.
219
     *
220
     * @param int $interval Number of milliseconds
221
     *
222
     * @return \Elastica\Response Response object
223
     */
224
    public function setRefreshInterval($interval)
225
    {
226
        return $this->set(['refresh_interval' => $interval]);
227
    }
228
229
    /**
230
     * Returns the refresh interval.
231
     *
232
     * If no interval is set, the default interval is returned
233
     *
234
     * @return string Refresh interval
235
     */
236
    public function getRefreshInterval()
237
    {
238
        $interval = $this->get('refresh_interval');
239
240
        if (empty($interval)) {
241
            $interval = self::DEFAULT_REFRESH_INTERVAL;
242
        }
243
244
        return $interval;
245
    }
246
247
    /**
248
     * Sets the specific merge policies.
249
     *
250
     * To have this changes made the index has to be closed and reopened
251
     *
252
     * @param string $key   Merge policy key (for ex. expunge_deletes_allowed)
253
     * @param string $value
254
     *
255
     * @return \Elastica\Response
256
     *
257
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html
258
     */
259
    public function setMergePolicy($key, $value)
260
    {
261
        $this->getIndex()->close();
262
        $response = $this->set(['merge.policy.'.$key => $value]);
263
        $this->getIndex()->open();
264
265
        return $response;
266
    }
267
268
    /**
269
     * Returns the specific merge policy value.
270
     *
271
     * @param string $key Merge policy key (for ex. expunge_deletes_allowed)
272
     *
273
     * @return string Refresh interval
274
     *
275
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html
276
     */
277
    public function getMergePolicy($key)
278
    {
279
        $settings = $this->get();
280
        if (isset($settings['merge']['policy'][$key])) {
281
            return $settings['merge']['policy'][$key];
282
        }
283
284
        return;
285
    }
286
287
    /**
288
     * Can be used to set/update settings.
289
     *
290
     * @param array $data Arguments
291
     *
292
     * @return \Elastica\Response Response object
293
     */
294
    public function set(array $data)
295
    {
296
        return $this->request($data, Request::PUT);
297
    }
298
299
    /**
300
     * Returns the index object.
301
     *
302
     * @return \Elastica\Index Index object
303
     */
304
    public function getIndex()
305
    {
306
        return $this->_index;
307
    }
308
309
    /**
310
     * Updates the given settings for the index.
311
     *
312
     * With elasticsearch 0.16 the following settings are supported
313
     * - index.term_index_interval
314
     * - index.term_index_divisor
315
     * - index.translog.flush_threshold_ops
316
     * - index.translog.flush_threshold_size
317
     * - index.translog.flush_threshold_period
318
     * - index.refresh_interval
319
     * - index.merge.policy
320
     * - index.auto_expand_replicas
321
     *
322
     * @param array  $data   OPTIONAL Data array
323
     * @param string $method OPTIONAL Transfer method (default = \Elastica\Request::GET)
324
     *
325
     * @return \Elastica\Response Response object
326
     */
327
    public function request(array $data = [], $method = Request::GET)
328
    {
329
        $path = '_settings';
330
331
        if (!empty($data)) {
332
            $data = ['index' => $data];
333
        }
334
335
        return $this->getIndex()->request($path, $method, $data);
336
    }
337
}
338