1<?php
2
3namespace Elastica;
4
5use Elastica\Exception\InvalidException;
6
7/**
8 * Base class for things that can be sent to the update api (Document and
9 * Script).
10 *
11 * @author   Nik Everett <nik9000@gmail.com>
12 */
13class AbstractUpdateAction extends Param
14{
15    /**
16     * @var Document
17     */
18    protected $_upsert;
19
20    /**
21     * Sets the id of the document.
22     *
23     * @return $this
24     */
25    public function setId(?string $id = null): self
26    {
27        return $this->setParam('_id', $id);
28    }
29
30    /**
31     * Returns document id.
32     *
33     * @return string|null Document id
34     */
35    public function getId(): ?string
36    {
37        return $this->hasParam('_id') ? $this->getParam('_id') : null;
38    }
39
40    public function hasId(): bool
41    {
42        return null !== $this->getId();
43    }
44
45    /**
46     * Sets the document index name.
47     *
48     * @param Index|string $index Index name
49     */
50    public function setIndex($index): self
51    {
52        if ($index instanceof Index) {
53            $index = $index->getName();
54        }
55
56        return $this->setParam('_index', $index);
57    }
58
59    /**
60     * Get the document index name.
61     *
62     * @throws InvalidException
63     *
64     * @return string Index name
65     */
66    public function getIndex()
67    {
68        return $this->getParam('_index');
69    }
70
71    /**
72     * Sets the version parameters of a document for use with optimistic concurrency control.
73     *
74     * @return $this
75     */
76    public function setVersionParams(array $responseData): self
77    {
78        if (isset($responseData['_version'])) {
79            $this->setVersion($responseData['_version']);
80        }
81
82        if (isset($responseData['_seq_no'])) {
83            $this->setSequenceNumber($responseData['_seq_no']);
84        }
85
86        if (isset($responseData['_primary_term'])) {
87            $this->setPrimaryTerm($responseData['_primary_term']);
88        }
89
90        return $this;
91    }
92
93    /**
94     * Sets the sequence number of a document for use with optimistic concurrency control.
95     *
96     * @param int $number Sequence Number
97     *
98     * @return $this
99     *
100     * @see https://www.elastic.co/guide/en/elasticsearch/reference/6.8/optimistic-concurrency-control.html
101     */
102    public function setSequenceNumber(int $number): self
103    {
104        return $this->setParam('if_seq_no', $number);
105    }
106
107    /**
108     * Returns document version.
109     *
110     * @throws InvalidException
111     *
112     * @return int Document version
113     */
114    public function getSequenceNumber(): int
115    {
116        return $this->getParam('if_seq_no');
117    }
118
119    public function hasSequenceNumber(): bool
120    {
121        return $this->hasParam('if_seq_no');
122    }
123
124    /**
125     * Sets the primary term of a document for use with optimistic concurrency control.
126     *
127     * @param int $term Primary Term
128     *
129     * @return $this
130     *
131     * @see https://www.elastic.co/guide/en/elasticsearch/reference/6.8/optimistic-concurrency-control.html
132     */
133    public function setPrimaryTerm(int $term): self
134    {
135        return $this->setParam('if_primary_term', $term);
136    }
137
138    /**
139     * Returns document version.
140     *
141     * @throws InvalidException
142     *
143     * @return int Document version
144     */
145    public function getPrimaryTerm(): int
146    {
147        return $this->getParam('if_primary_term');
148    }
149
150    public function hasPrimaryTerm(): bool
151    {
152        return $this->hasParam('if_primary_term');
153    }
154
155    /**
156     * Sets the version of a document.
157     *
158     * @param int $version Document version
159     *
160     * @return $this
161     *
162     * @see https://www.elastic.co/blog/versioning
163     */
164    public function setVersion($version)
165    {
166        return $this->setParam('version', (int) $version);
167    }
168
169    /**
170     * Returns document version.
171     *
172     * @throws InvalidException
173     *
174     * @return int|string Document version
175     */
176    public function getVersion()
177    {
178        return $this->getParam('version');
179    }
180
181    /**
182     * @return bool
183     */
184    public function hasVersion()
185    {
186        return $this->hasParam('version');
187    }
188
189    /**
190     * Set operation type.
191     *
192     * @param string $opType Only accept create
193     *
194     * @return $this
195     */
196    public function setOpType($opType)
197    {
198        return $this->setParam('op_type', $opType);
199    }
200
201    /**
202     * Get operation type.
203     *
204     * @throws InvalidException
205     *
206     * @return string
207     */
208    public function getOpType()
209    {
210        return $this->getParam('op_type');
211    }
212
213    /**
214     * @return bool
215     */
216    public function hasOpType()
217    {
218        return $this->hasParam('op_type');
219    }
220
221    /**
222     * Set routing query param.
223     *
224     * @param string $value routing
225     *
226     * @return $this
227     */
228    public function setRouting($value)
229    {
230        return $this->setParam('routing', $value);
231    }
232
233    /**
234     * Get routing parameter.
235     *
236     * @throws InvalidException
237     *
238     * @return string
239     */
240    public function getRouting()
241    {
242        return $this->getParam('routing');
243    }
244
245    /**
246     * @return bool
247     */
248    public function hasRouting()
249    {
250        return $this->hasParam('routing');
251    }
252
253    /**
254     * @param array|string $fields
255     *
256     * @return $this
257     */
258    public function setFields($fields)
259    {
260        if (\is_array($fields)) {
261            $fields = \implode(',', $fields);
262        }
263
264        return $this->setParam('fields', (string) $fields);
265    }
266
267    /**
268     * @return $this
269     */
270    public function setFieldsSource()
271    {
272        return $this->setFields('_source');
273    }
274
275    /**
276     * @throws InvalidException
277     *
278     * @return string
279     */
280    public function getFields()
281    {
282        return $this->getParam('fields');
283    }
284
285    /**
286     * @return bool
287     */
288    public function hasFields()
289    {
290        return $this->hasParam('fields');
291    }
292
293    /**
294     * @param int $num
295     *
296     * @return $this
297     */
298    public function setRetryOnConflict($num)
299    {
300        return $this->setParam('retry_on_conflict', (int) $num);
301    }
302
303    /**
304     * @throws InvalidException
305     *
306     * @return int
307     */
308    public function getRetryOnConflict()
309    {
310        return $this->getParam('retry_on_conflict');
311    }
312
313    /**
314     * @return bool
315     */
316    public function hasRetryOnConflict()
317    {
318        return $this->hasParam('retry_on_conflict');
319    }
320
321    /**
322     * @param bool|string $refresh
323     *
324     * @phpstan-param bool|Reindex::REFRESH_* $refresh
325     *
326     * @return $this
327     */
328    public function setRefresh($refresh = true)
329    {
330        if (\is_bool($refresh)) {
331            $refresh = $refresh ? Reindex::REFRESH_TRUE : Reindex::REFRESH_FALSE;
332        }
333
334        return $this->setParam(Reindex::REFRESH, $refresh);
335    }
336
337    /**
338     * @throws InvalidException
339     *
340     * @return bool|string
341     */
342    public function getRefresh()
343    {
344        $refresh = $this->getParam('refresh');
345
346        return \in_array($refresh, [Reindex::REFRESH_TRUE, Reindex::REFRESH_FALSE], true)
347            ? Reindex::REFRESH_TRUE === $refresh
348            : $refresh;
349    }
350
351    /**
352     * @return bool
353     */
354    public function hasRefresh()
355    {
356        return $this->hasParam('refresh');
357    }
358
359    /**
360     * @param string $timeout
361     *
362     * @return $this
363     */
364    public function setTimeout($timeout)
365    {
366        return $this->setParam('timeout', $timeout);
367    }
368
369    /**
370     * @throws InvalidException
371     *
372     * @return bool
373     */
374    public function getTimeout()
375    {
376        return $this->getParam('timeout');
377    }
378
379    /**
380     * @return bool
381     */
382    public function hasTimeout()
383    {
384        return $this->hasParam('timeout');
385    }
386
387    /**
388     * @param string $timeout
389     *
390     * @return $this
391     */
392    public function setConsistency($timeout)
393    {
394        return $this->setParam('consistency', $timeout);
395    }
396
397    /**
398     * @throws InvalidException
399     *
400     * @return string
401     */
402    public function getConsistency()
403    {
404        return $this->getParam('consistency');
405    }
406
407    /**
408     * @return bool
409     */
410    public function hasConsistency()
411    {
412        return $this->hasParam('consistency');
413    }
414
415    /**
416     * @param string $timeout
417     *
418     * @return $this
419     */
420    public function setReplication($timeout)
421    {
422        return $this->setParam('replication', $timeout);
423    }
424
425    /**
426     * @throws InvalidException
427     *
428     * @return string
429     */
430    public function getReplication()
431    {
432        return $this->getParam('replication');
433    }
434
435    /**
436     * @return bool
437     */
438    public function hasReplication()
439    {
440        return $this->hasParam('replication');
441    }
442
443    /**
444     * @param array|Document $data
445     *
446     * @return $this
447     */
448    public function setUpsert($data)
449    {
450        $document = Document::create($data);
451        $this->_upsert = $document;
452
453        return $this;
454    }
455
456    /**
457     * @return Document
458     */
459    public function getUpsert()
460    {
461        return $this->_upsert;
462    }
463
464    /**
465     * @return bool
466     */
467    public function hasUpsert()
468    {
469        return null !== $this->_upsert;
470    }
471
472    /**
473     * @param array $fields if empty array all options will be returned
474     *
475     * @return array
476     */
477    public function getOptions(array $fields = [])
478    {
479        if ($fields) {
480            return \array_filter(\array_intersect_key($this->getParams(), \array_flip($fields)));
481        }
482
483        return \array_filter($this->getParams());
484    }
485}
486