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 mixed $value
107     */
108    public function setPersistent(string $key, $value): Response
109    {
110        return $this->set(
111            [
112                'persistent' => [
113                    $key => $value,
114                ],
115            ]
116        );
117    }
118
119    /**
120     * Sets transient settings.
121     *
122     * @param mixed $value
123     */
124    public function setTransient(string $key, $value): Response
125    {
126        return $this->set(
127            [
128                'transient' => [
129                    $key => $value,
130                ],
131            ]
132        );
133    }
134
135    /**
136     * Sets the cluster to read only.
137     *
138     * Second param can be used to set it persistent
139     *
140     * @return Response $response
141     */
142    public function setReadOnly(bool $readOnly = true, bool $persistent = false): Response
143    {
144        $key = 'cluster.blocks.read_only';
145
146        if ($persistent) {
147            return $this->setPersistent($key, $readOnly);
148        }
149
150        return $this->setTransient($key, $readOnly);
151    }
152
153    /**
154     * Set settings for cluster.
155     *
156     * @param array $settings Raw settings (including persistent or transient)
157     */
158    public function set(array $settings): Response
159    {
160        return $this->request($settings, Request::PUT);
161    }
162
163    /**
164     * Get the client.
165     */
166    public function getClient(): Client
167    {
168        return $this->_client;
169    }
170
171    public function request(array $data = [], string $method = Request::GET): Response
172    {
173        $path = '_cluster/settings';
174
175        return $this->getClient()->request($path, $method, $data);
176    }
177}
178