1<?php
2
3namespace Elastica;
4
5use Elastica\Exception\InvalidException;
6use Elasticsearch\Endpoints\Indices\Mapping\Put;
7use Elasticsearch\Endpoints\Indices\PutMapping;
8
9/**
10 * Elastica Mapping object.
11 *
12 * @author Nicolas Ruflin <spam@ruflin.com>
13 *
14 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
15 */
16class Mapping
17{
18    /**
19     * Mapping.
20     *
21     * @var array Mapping
22     */
23    protected $_mapping = [];
24
25    /**
26     * Construct Mapping.
27     *
28     * @param array $properties OPTIONAL Properties
29     */
30    public function __construct(array $properties = [])
31    {
32        if ($properties) {
33            $this->setProperties($properties);
34        }
35    }
36
37    /**
38     * Sets the mapping properties.
39     *
40     * @param array $properties Properties
41     *
42     * @return $this
43     */
44    public function setProperties(array $properties): Mapping
45    {
46        return $this->setParam('properties', $properties);
47    }
48
49    /**
50     * Gets the mapping properties.
51     *
52     * @return array $properties Properties
53     */
54    public function getProperties(): array
55    {
56        return $this->getParam('properties');
57    }
58
59    /**
60     * Sets the mapping _meta.
61     *
62     * @param array $meta metadata
63     *
64     * @return $this
65     *
66     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-meta.html
67     */
68    public function setMeta(array $meta): Mapping
69    {
70        return $this->setParam('_meta', $meta);
71    }
72
73    /**
74     * Sets source values.
75     *
76     * To disable source, argument is
77     * array('enabled' => false)
78     *
79     * @param array $source Source array
80     *
81     * @return $this
82     *
83     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-source-field.html
84     */
85    public function setSource(array $source): Mapping
86    {
87        return $this->setParam('_source', $source);
88    }
89
90    /**
91     * Disables the source in the index.
92     *
93     * Param can be set to true to enable again
94     *
95     * @param bool $enabled OPTIONAL (default = false)
96     *
97     * @return $this
98     */
99    public function disableSource(bool $enabled = false): Mapping
100    {
101        return $this->setSource(['enabled' => $enabled]);
102    }
103
104    /**
105     * Sets raw parameters.
106     *
107     * Possible options:
108     * _uid
109     * _id
110     * _type
111     * _source
112     * _analyzer
113     * _boost
114     * _routing
115     * _index
116     * _size
117     * properties
118     *
119     * @param string $key   Key name
120     * @param mixed  $value Key value
121     *
122     * @return $this
123     */
124    public function setParam(string $key, $value): Mapping
125    {
126        $this->_mapping[$key] = $value;
127
128        return $this;
129    }
130
131    /**
132     * Get raw parameters.
133     *
134     * @see setParam
135     *
136     * @param string $key Key name
137     *
138     * @return mixed $value Key value
139     */
140    public function getParam(string $key)
141    {
142        return $this->_mapping[$key] ?? null;
143    }
144
145    /**
146     * Converts the mapping to an array.
147     *
148     * @throws InvalidException
149     *
150     * @return array Mapping as array
151     */
152    public function toArray(): array
153    {
154        return $this->_mapping;
155    }
156
157    /**
158     * Submits the mapping and sends it to the server.
159     *
160     * @param Index $index the index to send the mappings to
161     * @param array $query Query string parameters to send with mapping
162     *
163     * @return Response Response object
164     */
165    public function send(Index $index, array $query = []): Response
166    {
167        // TODO: Use only PutMapping when dropping support for elasticsearch/elasticsearch 7.x
168        $endpoint = \class_exists(PutMapping::class) ? new PutMapping() : new Put();
169        $endpoint->setBody($this->toArray());
170        $endpoint->setParams($query);
171
172        return $index->requestEndpoint($endpoint);
173    }
174
175    /**
176     * Creates a mapping object.
177     *
178     * @param array|Mapping $mapping Mapping object or properties array
179     *
180     * @throws InvalidException If invalid type
181     *
182     * @return self
183     */
184    public static function create($mapping): Mapping
185    {
186        if (\is_array($mapping)) {
187            $mappingObject = new static();
188            $mappingObject->setProperties($mapping);
189
190            return $mappingObject;
191        }
192
193        if ($mapping instanceof self) {
194            return $mapping;
195        }
196
197        throw new InvalidException('Invalid object type');
198    }
199}
200