1<?php
2
3namespace Elastica;
4
5use Elastica\Exception\InvalidException;
6
7/**
8 * Class to handle params.
9 *
10 * This function can be used to handle params for queries, filter
11 *
12 * @author Nicolas Ruflin <spam@ruflin.com>
13 */
14class Param implements ArrayableInterface, \Countable
15{
16    /**
17     * Params.
18     *
19     * @var array
20     */
21    protected $_params = [];
22
23    /**
24     * Raw Params.
25     *
26     * @var array
27     */
28    protected $_rawParams = [];
29
30    /**
31     * Converts the params to an array. A default implementation exist to create
32     * the an array out of the class name (last part of the class name)
33     * and the params.
34     *
35     * @return array Filter array
36     */
37    public function toArray()
38    {
39        $data = [$this->_getBaseName() => $this->getParams()];
40
41        if (!empty($this->_rawParams)) {
42            $data = \array_merge($data, $this->_rawParams);
43        }
44
45        return $this->_convertArrayable($data);
46    }
47
48    /**
49     * Cast objects to arrays.
50     *
51     * @param array $array
52     *
53     * @return array
54     */
55    protected function _convertArrayable(array $array)
56    {
57        $arr = [];
58
59        foreach ($array as $key => $value) {
60            if ($value instanceof ArrayableInterface) {
61                $arr[$value instanceof NameableInterface ? $value->getName() : $key] = $value->toArray();
62            } elseif (\is_array($value)) {
63                $arr[$key] = $this->_convertArrayable($value);
64            } else {
65                $arr[$key] = $value;
66            }
67        }
68
69        return $arr;
70    }
71
72    /**
73     * Param's name
74     * Picks the last part of the class name and makes it snake_case
75     * You can override this method if you want to change the name.
76     *
77     * @return string name
78     */
79    protected function _getBaseName()
80    {
81        return Util::getParamName($this);
82    }
83
84    /**
85     * Sets params not inside params array.
86     *
87     * @param string $key
88     * @param mixed  $value
89     *
90     * @return $this
91     */
92    protected function _setRawParam($key, $value)
93    {
94        $this->_rawParams[$key] = $value;
95
96        return $this;
97    }
98
99    /**
100     * Sets (overwrites) the value at the given key.
101     *
102     * @param string $key   Key to set
103     * @param mixed  $value Key Value
104     *
105     * @return $this
106     */
107    public function setParam($key, $value)
108    {
109        $this->_params[$key] = $value;
110
111        return $this;
112    }
113
114    /**
115     * Sets (overwrites) all params of this object.
116     *
117     * @param array $params Parameter list
118     *
119     * @return $this
120     */
121    public function setParams(array $params)
122    {
123        $this->_params = $params;
124
125        return $this;
126    }
127
128    /**
129     * Adds a param to the list.
130     *
131     * This function can be used to add an array of params
132     *
133     * @param string $key   Param key
134     * @param mixed  $value Value to set
135     *
136     * @return $this
137     */
138    public function addParam($key, $value)
139    {
140        $this->_params[$key][] = $value;
141
142        return $this;
143    }
144
145    /**
146     * Returns a specific param.
147     *
148     * @param string $key Key to return
149     *
150     * @throws \Elastica\Exception\InvalidException If requested key is not set
151     *
152     * @return mixed Key value
153     */
154    public function getParam($key)
155    {
156        if (!$this->hasParam($key)) {
157            throw new InvalidException('Param '.$key.' does not exist');
158        }
159
160        return $this->_params[$key];
161    }
162
163    /**
164     * Test if a param is set.
165     *
166     * @param string $key Key to test
167     *
168     * @return bool True if the param is set, false otherwise
169     */
170    public function hasParam($key)
171    {
172        return isset($this->_params[$key]);
173    }
174
175    /**
176     * Returns the params array.
177     *
178     * @return array Params
179     */
180    public function getParams()
181    {
182        return $this->_params;
183    }
184
185    /**
186     * {@inheritdoc}
187     *
188     * @return int
189     */
190    public function count()
191    {
192        return \count($this->_params);
193    }
194}
195