1<?php
2
3namespace Elastica\Cluster;
4
5use Elastica\Client;
6use Elastica\Request;
7use Elastica\Response;
8
9/**
10 * Cluster settings.
11 *
12 * @author   Nicolas Ruflin <spam@ruflin.com>
13 *
14 * @see     https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-update-settings.html
15 */
16class Settings
17{
18    /**
19     * @var Client Client object
20     */
21    protected $_client;
22
23    /**
24     * Creates a cluster object.
25     *
26     * @param Client $client Connection client object
27     */
28    public function __construct(Client $client)
29    {
30        $this->_client = $client;
31    }
32
33    /**
34     * Returns settings data.
35     *
36     * @return array Settings data (persistent and transient)
37     */
38    public function get(): array
39    {
40        return $this->request()->getData();
41    }
42
43    /**
44     * Returns the current persistent settings of the cluster.
45     *
46     * If param is set, only specified setting is return.
47     *
48     * @param string $setting OPTIONAL Setting name to return
49     *
50     * @return array|string|null Settings data
51     */
52    public function getPersistent(string $setting = '')
53    {
54        $data = $this->get();
55        $settings = $data['persistent'];
56
57        if ('' !== $setting) {
58            return $settings[$setting] ?? null;
59        }
60
61        return $settings;
62    }
63
64    /**
65     * Returns the current transient settings of the cluster.
66     *
67     * If param is set, only specified setting is return.
68     *
69     * @param string $setting OPTIONAL Setting name to return
70     *
71     * @return array|string|null Settings data
72     */
73    public function getTransient(string $setting = '')
74    {
75        $data = $this->get();
76        $settings = $data['transient'];
77
78        if ('' !== $setting) {
79            if (isset($settings[$setting])) {
80                return $settings[$setting];
81            }
82
83            if (false !== \strpos($setting, '.')) {
84                // convert dot notation to nested arrays
85                $keys = \explode('.', $setting);
86                foreach ($keys as $key) {
87                    if (isset($settings[$key])) {
88                        $settings = $settings[$key];
89                    } else {
90                        return null;
91                    }
92                }
93
94                return $settings;
95            }
96
97            return null;
98        }
99
100        return $settings;
101    }
102
103    /**
104     * Sets persistent setting.
105     *
106     * @param string $key
107     * @param mixed  $value
108     *
109     * @return Response
110     */
111    public function setPersistent(string $key, $value): Response
112    {
113        return $this->set(
114            [
115                'persistent' => [
116                    $key => $value,
117                ],
118            ]
119        );
120    }
121
122    /**
123     * Sets transient settings.
124     *
125     * @param string $key
126     * @param mixed  $value
127     *
128     * @return Response
129     */
130    public function setTransient(string $key, $value): Response
131    {
132        return $this->set(
133            [
134                'transient' => [
135                    $key => $value,
136                ],
137            ]
138        );
139    }
140
141    /**
142     * Sets the cluster to read only.
143     *
144     * Second param can be used to set it persistent
145     *
146     * @param bool $readOnly
147     * @param bool $persistent
148     *
149     * @return Response $response
150     */
151    public function setReadOnly(bool $readOnly = true, bool $persistent = false): Response
152    {
153        $key = 'cluster.blocks.read_only';
154
155        if ($persistent) {
156            return $this->setPersistent($key, $readOnly);
157        }
158
159        return $this->setTransient($key, $readOnly);
160    }
161
162    /**
163     * Set settings for cluster.
164     *
165     * @param array $settings Raw settings (including persistent or transient)
166     *
167     * @return Response
168     */
169    public function set(array $settings): Response
170    {
171        return $this->request($settings, Request::PUT);
172    }
173
174    /**
175     * Get the client.
176     *
177     * @return Client
178     */
179    public function getClient(): Client
180    {
181        return $this->_client;
182    }
183
184    /**
185     * Sends settings request.
186     *
187     * @param array  $data   OPTIONAL Data array
188     * @param string $method OPTIONAL Transfer method (default = \Elastica\Request::GET)
189     *
190     * @return Response Response object
191     */
192    public function request(array $data = [], string $method = Request::GET): Response
193    {
194        $path = '_cluster/settings';
195
196        return $this->getClient()->request($path, $method, $data);
197    }
198}
199