Completed
Push — master ( d3ac62...0cb203 )
by Federico
02:08
created

lib/Elastica/Client.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Elastica;
4
5
use Elastica\Bulk\Action;
6
use Elastica\Exception\ConnectionException;
7
use Elastica\Exception\InvalidException;
8
use Elastica\Script\AbstractScript;
9
use Elasticsearch\Endpoints\AbstractEndpoint;
10
use Elasticsearch\Endpoints\Indices\ForceMerge;
11
use Elasticsearch\Endpoints\Indices\Refresh;
12
use Elasticsearch\Endpoints\Update;
13
use Psr\Log\LoggerInterface;
14
use Psr\Log\NullLogger;
15
16
/**
17
 * Client to connect the the elasticsearch server.
18
 *
19
 * @author Nicolas Ruflin <[email protected]>
20
 */
21
class Client
22
{
23
    /**
24
     * Config with defaults.
25
     *
26
     * log: Set to true, to enable logging, set a string to log to a specific file
27
     * retryOnConflict: Use in \Elastica\Client::updateDocument
28
     * bigintConversion: Set to true to enable the JSON bigint to string conversion option (see issue #717)
29
     *
30
     * @var array
31
     */
32
    protected $_config = [
33
        'host' => null,
34
        'port' => null,
35
        'path' => null,
36
        'url' => null,
37
        'proxy' => null,
38
        'transport' => null,
39
        'persistent' => true,
40
        'timeout' => null,
41
        'connections' => [], // host, port, path, timeout, transport, compression, persistent, timeout, username, password, config -> (curl, headers, url)
42
        'roundRobin' => false,
43
        'log' => false,
44
        'retryOnConflict' => 0,
45
        'bigintConversion' => false,
46
        'username' => null,
47
        'password' => null,
48
    ];
49
50
    /**
51
     * @var callback
52
     */
53
    protected $_callback;
54
55
    /**
56
     * @var Connection\ConnectionPool
57
     */
58
    protected $_connectionPool;
59
60
    /**
61
     * @var \Elastica\Request|null
62
     */
63
    protected $_lastRequest;
64
65
    /**
66
     * @var \Elastica\Response|null
67
     */
68
    protected $_lastResponse;
69
70
    /**
71
     * @var LoggerInterface
72
     */
73
    protected $_logger;
74
75
    /**
76
     * @var string
77
     */
78
    protected $_version;
79
80
    /**
81
     * Creates a new Elastica client.
82
     *
83
     * @param array           $config   OPTIONAL Additional config options
84
     * @param callback        $callback OPTIONAL Callback function which can be used to be notified about errors (for example connection down)
85
     * @param LoggerInterface $logger
86
     */
87
    public function __construct(array $config = [], $callback = null, LoggerInterface $logger = null)
88
    {
89
        $this->_callback = $callback;
90
91
        if (!$logger && isset($config['log']) && $config['log']) {
92
            $logger = new Log($config['log']);
93
        }
94
        $this->_logger = $logger ?: new NullLogger();
95
96
        $this->setConfig($config);
97
        $this->_initConnections();
98
    }
99
100
    /**
101
     * Get current version.
102
     *
103
     * @return string
104
     */
105
    public function getVersion()
106
    {
107
        if ($this->_version) {
108
            return $this->_version;
109
        }
110
111
        $data = $this->request('/')->getData();
112
113
        return $this->_version = $data['version']['number'];
114
    }
115
116
    /**
117
     * Inits the client connections.
118
     */
119
    protected function _initConnections()
120
    {
121
        $connections = [];
122
123
        foreach ($this->getConfig('connections') as $connection) {
0 ignored issues
show
The expression $this->getConfig('connections') of type array|string is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
124
            $connections[] = Connection::create($this->_prepareConnectionParams($connection));
125
        }
126
127
        if (isset($this->_config['servers'])) {
128
            foreach ($this->getConfig('servers') as $server) {
129
                $connections[] = Connection::create($this->_prepareConnectionParams($server));
130
            }
131
        }
132
133
        // If no connections set, create default connection
134
        if (empty($connections)) {
135
            $connections[] = Connection::create($this->_prepareConnectionParams($this->getConfig()));
0 ignored issues
show
It seems like $this->getConfig() targeting Elastica\Client::getConfig() can also be of type string; however, Elastica\Client::_prepareConnectionParams() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
136
        }
137
138
        if (!isset($this->_config['connectionStrategy'])) {
139
            if (true === $this->getConfig('roundRobin')) {
140
                $this->setConfigValue('connectionStrategy', 'RoundRobin');
141
            } else {
142
                $this->setConfigValue('connectionStrategy', 'Simple');
143
            }
144
        }
145
146
        $strategy = Connection\Strategy\StrategyFactory::create($this->getConfig('connectionStrategy'));
147
148
        $this->_connectionPool = new Connection\ConnectionPool($connections, $strategy, $this->_callback);
149
    }
150
151
    /**
152
     * Creates a Connection params array from a Client or server config array.
153
     *
154
     * @param array $config
155
     *
156
     * @return array
157
     */
158
    protected function _prepareConnectionParams(array $config)
159
    {
160
        $params = [];
161
        $params['config'] = [];
162
        foreach ($config as $key => $value) {
163
            if (in_array($key, ['bigintConversion', 'curl', 'headers', 'url'])) {
164
                $params['config'][$key] = $value;
165
            } else {
166
                $params[$key] = $value;
167
            }
168
        }
169
170
        return $params;
171
    }
172
173
    /**
174
     * Sets specific config values (updates and keeps default values).
175
     *
176
     * @param array $config Params
177
     *
178
     * @return $this
179
     */
180
    public function setConfig(array $config)
181
    {
182
        foreach ($config as $key => $value) {
183
            $this->_config[$key] = $value;
184
        }
185
186
        return $this;
187
    }
188
189
    /**
190
     * Returns a specific config key or the whole
191
     * config array if not set.
192
     *
193
     * @param string $key Config key
194
     *
195
     * @throws \Elastica\Exception\InvalidException
196
     *
197
     * @return array|string Config value
198
     */
199
    public function getConfig($key = '')
200
    {
201
        if (empty($key)) {
202
            return $this->_config;
203
        }
204
205
        if (!array_key_exists($key, $this->_config)) {
206
            throw new InvalidException('Config key is not set: '.$key);
207
        }
208
209
        return $this->_config[$key];
210
    }
211
212
    /**
213
     * Sets / overwrites a specific config value.
214
     *
215
     * @param string $key   Key to set
216
     * @param mixed  $value Value
217
     *
218
     * @return $this
219
     */
220
    public function setConfigValue($key, $value)
221
    {
222
        return $this->setConfig([$key => $value]);
223
    }
224
225
    /**
226
     * @param array|string $keys    config key or path of config keys
227
     * @param mixed        $default default value will be returned if key was not found
228
     *
229
     * @return mixed
230
     */
231
    public function getConfigValue($keys, $default = null)
232
    {
233
        $value = $this->_config;
234
        foreach ((array) $keys as $key) {
235
            if (isset($value[$key])) {
236
                $value = $value[$key];
237
            } else {
238
                return $default;
239
            }
240
        }
241
242
        return $value;
243
    }
244
245
    /**
246
     * Returns the index for the given connection.
247
     *
248
     * @param string $name Index name to create connection to
249
     *
250
     * @return \Elastica\Index Index for the given name
251
     */
252
    public function getIndex($name)
253
    {
254
        return new Index($this, $name);
255
    }
256
257
    /**
258
     * Adds a HTTP Header.
259
     *
260
     * @param string $header      The HTTP Header
261
     * @param string $headerValue The HTTP Header Value
262
     *
263
     * @throws \Elastica\Exception\InvalidException If $header or $headerValue is not a string
264
     *
265
     * @return $this
266
     */
267 View Code Duplication
    public function addHeader($header, $headerValue)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
268
    {
269
        if (is_string($header) && is_string($headerValue)) {
270
            $this->_config['headers'][$header] = $headerValue;
271
        } else {
272
            throw new InvalidException('Header must be a string');
273
        }
274
275
        return $this;
276
    }
277
278
    /**
279
     * Remove a HTTP Header.
280
     *
281
     * @param string $header The HTTP Header to remove
282
     *
283
     * @throws \Elastica\Exception\InvalidException If $header is not a string
284
     *
285
     * @return $this
286
     */
287 View Code Duplication
    public function removeHeader($header)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
288
    {
289
        if (is_string($header)) {
290
            if (array_key_exists($header, $this->_config['headers'])) {
291
                unset($this->_config['headers'][$header]);
292
            }
293
        } else {
294
            throw new InvalidException('Header must be a string');
295
        }
296
297
        return $this;
298
    }
299
300
    /**
301
     * Uses _bulk to send documents to the server.
302
     *
303
     * Array of \Elastica\Document as input. Index and type has to be
304
     * set inside the document, because for bulk settings documents,
305
     * documents can belong to any type and index
306
     *
307
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
308
     *
309
     * @param array|\Elastica\Document[] $docs          Array of Elastica\Document
310
     * @param array                      $requestParams
311
     *
312
     * @throws \Elastica\Exception\InvalidException If docs is empty
313
     *
314
     * @return \Elastica\Bulk\ResponseSet Response object
315
     */
316 View Code Duplication
    public function updateDocuments(array $docs, array $requestParams = [])
317
    {
318
        if (empty($docs)) {
319
            throw new InvalidException('Array has to consist of at least one element');
320
        }
321
322
        $bulk = new Bulk($this);
323
324
        $bulk->addDocuments($docs, Action::OP_TYPE_UPDATE);
325
        foreach ($requestParams as $key => $value) {
326
            $bulk->setRequestParam($key, $value);
327
        }
328
329
        return $bulk->send();
330
    }
331
332
    /**
333
     * Uses _bulk to send documents to the server.
334
     *
335
     * Array of \Elastica\Document as input. Index and type has to be
336
     * set inside the document, because for bulk settings documents,
337
     * documents can belong to any type and index
338
     *
339
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
340
     *
341
     * @param array|\Elastica\Document[] $docs          Array of Elastica\Document
342
     * @param array                      $requestParams
343
     *
344
     * @throws \Elastica\Exception\InvalidException If docs is empty
345
     *
346
     * @return \Elastica\Bulk\ResponseSet Response object
347
     */
348 View Code Duplication
    public function addDocuments(array $docs, array $requestParams = [])
349
    {
350
        if (empty($docs)) {
351
            throw new InvalidException('Array has to consist of at least one element');
352
        }
353
354
        $bulk = new Bulk($this);
355
356
        $bulk->addDocuments($docs);
357
358
        foreach ($requestParams as $key => $value) {
359
            $bulk->setRequestParam($key, $value);
360
        }
361
362
        return $bulk->send();
363
    }
364
365
    /**
366
     * Update document, using update script. Requires elasticsearch >= 0.19.0.
367
     *
368
     * @param int|string                                               $id      document id
369
     * @param array|\Elastica\Script\AbstractScript|\Elastica\Document $data    raw data for request body
370
     * @param string                                                   $index   index to update
371
     * @param string                                                   $type    type of index to update
372
     * @param array                                                    $options array of query params to use for query. For possible options check es api
373
     *
374
     * @return \Elastica\Response
375
     *
376
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html
377
     */
378
    public function updateDocument($id, $data, $index, $type, array $options = [])
379
    {
380
        $endpoint = new Update();
381
        $endpoint->setID($id);
382
        $endpoint->setIndex($index);
383
        $endpoint->setType($type);
384
385
        if ($data instanceof AbstractScript) {
386
            $requestData = $data->toArray();
387
        } elseif ($data instanceof Document) {
388
            $requestData = ['doc' => $data->getData()];
389
390
            if ($data->getDocAsUpsert()) {
391
                $requestData['doc_as_upsert'] = true;
392
            }
393
394
            $docOptions = $data->getOptions(
395
                [
396
                    'version',
397
                    'version_type',
398
                    'routing',
399
                    'percolate',
400
                    'parent',
401
                    'fields',
402
                    'retry_on_conflict',
403
                    'consistency',
404
                    'replication',
405
                    'refresh',
406
                    'timeout',
407
                ]
408
            );
409
            $options += $docOptions;
410
            // set fields param to source only if options was not set before
411
            if ($data instanceof Document && ($data->isAutoPopulate()
412
                || $this->getConfigValue(['document', 'autoPopulate'], false))
413
                && !isset($options['fields'])
414
            ) {
415
                $options['fields'] = '_source';
416
            }
417
        } else {
418
            $requestData = $data;
419
        }
420
421
        //If an upsert document exists
422
        if ($data instanceof AbstractScript || $data instanceof Document) {
423
            if ($data->hasUpsert()) {
424
                $requestData['upsert'] = $data->getUpsert()->getData();
425
            }
426
        }
427
428
        if (!isset($options['retry_on_conflict'])) {
429
            if ($retryOnConflict = $this->getConfig('retryOnConflict')) {
430
                $options['retry_on_conflict'] = $retryOnConflict;
431
            }
432
        }
433
434
        $endpoint->setBody($requestData);
435
        $endpoint->setParams($options);
436
437
        $response = $this->requestEndpoint($endpoint);
438
439 View Code Duplication
        if ($response->isOk()
440
            && $data instanceof Document
441
            && ($data->isAutoPopulate() || $this->getConfigValue(['document', 'autoPopulate'], false))
442
        ) {
443
            $responseData = $response->getData();
444
            if (isset($responseData['_version'])) {
445
                $data->setVersion($responseData['_version']);
446
            }
447
            if (isset($options['fields'])) {
448
                $this->_populateDocumentFieldsFromResponse($response, $data, $options['fields']);
449
            }
450
        }
451
452
        return $response;
453
    }
454
455
    /**
456
     * @param \Elastica\Response $response
457
     * @param \Elastica\Document $document
458
     * @param string             $fields   Array of field names to be populated or '_source' if whole document data should be updated
459
     */
460
    protected function _populateDocumentFieldsFromResponse(Response $response, Document $document, $fields)
461
    {
462
        $responseData = $response->getData();
463
        if ('_source' == $fields) {
464
            if (isset($responseData['get']['_source']) && is_array($responseData['get']['_source'])) {
465
                $document->setData($responseData['get']['_source']);
466
            }
467
        } else {
468
            $keys = explode(',', $fields);
469
            $data = $document->getData();
470
            foreach ($keys as $key) {
471
                if (isset($responseData['get']['fields'][$key])) {
472
                    $data[$key] = $responseData['get']['fields'][$key];
473
                } elseif (isset($data[$key])) {
474
                    unset($data[$key]);
475
                }
476
            }
477
            $document->setData($data);
478
        }
479
    }
480
481
    /**
482
     * Bulk deletes documents.
483
     *
484
     * @param array|\Elastica\Document[] $docs
485
     * @param array                      $requestParams
486
     *
487
     * @throws \Elastica\Exception\InvalidException
488
     *
489
     * @return \Elastica\Bulk\ResponseSet
490
     */
491 View Code Duplication
    public function deleteDocuments(array $docs, array $requestParams = [])
492
    {
493
        if (empty($docs)) {
494
            throw new InvalidException('Array has to consist of at least one element');
495
        }
496
497
        $bulk = new Bulk($this);
498
        $bulk->addDocuments($docs, Action::OP_TYPE_DELETE);
499
500
        foreach ($requestParams as $key => $value) {
501
            $bulk->setRequestParam($key, $value);
502
        }
503
504
        return $bulk->send();
505
    }
506
507
    /**
508
     * Returns the status object for all indices.
509
     *
510
     * @return \Elastica\Status Status object
511
     */
512
    public function getStatus()
513
    {
514
        return new Status($this);
515
    }
516
517
    /**
518
     * Returns the current cluster.
519
     *
520
     * @return \Elastica\Cluster Cluster object
521
     */
522
    public function getCluster()
523
    {
524
        return new Cluster($this);
525
    }
526
527
    /**
528
     * Establishes the client connections.
529
     */
530
    public function connect()
531
    {
532
        return $this->_initConnections();
533
    }
534
535
    /**
536
     * @param \Elastica\Connection $connection
537
     *
538
     * @return $this
539
     */
540
    public function addConnection(Connection $connection)
541
    {
542
        $this->_connectionPool->addConnection($connection);
543
544
        return $this;
545
    }
546
547
    /**
548
     * Determines whether a valid connection is available for use.
549
     *
550
     * @return bool
551
     */
552
    public function hasConnection()
553
    {
554
        return $this->_connectionPool->hasConnection();
555
    }
556
557
    /**
558
     * @throws \Elastica\Exception\ClientException
559
     *
560
     * @return \Elastica\Connection
561
     */
562
    public function getConnection()
563
    {
564
        return $this->_connectionPool->getConnection();
565
    }
566
567
    /**
568
     * @return \Elastica\Connection[]
569
     */
570
    public function getConnections()
571
    {
572
        return $this->_connectionPool->getConnections();
573
    }
574
575
    /**
576
     * @return \Elastica\Connection\Strategy\StrategyInterface
577
     */
578
    public function getConnectionStrategy()
579
    {
580
        return $this->_connectionPool->getStrategy();
581
    }
582
583
    /**
584
     * @param array|\Elastica\Connection[] $connections
585
     *
586
     * @return $this
587
     */
588
    public function setConnections(array $connections)
589
    {
590
        $this->_connectionPool->setConnections($connections);
591
592
        return $this;
593
    }
594
595
    /**
596
     * Deletes documents with the given ids, index, type from the index.
597
     *
598
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
599
     *
600
     * @param array                  $ids     Document ids
601
     * @param string|\Elastica\Index $index   Index name
602
     * @param string|\Elastica\Type  $type    Type of documents
603
     * @param string|bool            $routing Optional routing key for all ids
604
     *
605
     * @throws \Elastica\Exception\InvalidException
606
     *
607
     * @return \Elastica\Bulk\ResponseSet Response  object
608
     */
609
    public function deleteIds(array $ids, $index, $type, $routing = false)
610
    {
611
        if (empty($ids)) {
612
            throw new InvalidException('Array has to consist of at least one id');
613
        }
614
615
        $bulk = new Bulk($this);
616
        $bulk->setIndex($index);
617
        $bulk->setType($type);
618
619
        foreach ($ids as $id) {
620
            $action = new Action(Action::OP_TYPE_DELETE);
621
            $action->setId($id);
622
623
            if (!empty($routing)) {
624
                $action->setRouting($routing);
625
            }
626
627
            $bulk->addAction($action);
628
        }
629
630
        return $bulk->send();
631
    }
632
633
    /**
634
     * Bulk operation.
635
     *
636
     * Every entry in the params array has to exactly on array
637
     * of the bulk operation. An example param array would be:
638
     *
639
     * array(
640
     *         array('index' => array('_index' => 'test', '_type' => 'user', '_id' => '1')),
641
     *         array('user' => array('name' => 'hans')),
642
     *         array('delete' => array('_index' => 'test', '_type' => 'user', '_id' => '2'))
643
     * );
644
     *
645
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
646
     *
647
     * @param array $params Parameter array
648
     *
649
     * @throws \Elastica\Exception\ResponseException
650
     * @throws \Elastica\Exception\InvalidException
651
     *
652
     * @return \Elastica\Bulk\ResponseSet Response object
653
     */
654
    public function bulk(array $params)
655
    {
656
        if (empty($params)) {
657
            throw new InvalidException('Array has to consist of at least one param');
658
        }
659
660
        $bulk = new Bulk($this);
661
662
        $bulk->addRawData($params);
663
664
        return $bulk->send();
665
    }
666
667
    /**
668
     * Makes calls to the elasticsearch server based on this index.
669
     *
670
     * It's possible to make any REST query directly over this method
671
     *
672
     * @param string       $path        Path to call
673
     * @param string       $method      Rest method to use (GET, POST, DELETE, PUT)
674
     * @param array|string $data        OPTIONAL Arguments as array or pre-encoded string
675
     * @param array        $query       OPTIONAL Query params
676
     * @param string       $contentType Content-Type sent with this request
677
     *
678
     * @throws Exception\ConnectionException|Exception\ClientException
679
     *
680
     * @return Response Response object
681
     */
682
    public function request($path, $method = Request::GET, $data = [], array $query = [], $contentType = Request::DEFAULT_CONTENT_TYPE)
683
    {
684
        $connection = $this->getConnection();
685
        $request = $this->_lastRequest = new Request($path, $method, $data, $query, $connection, $contentType);
686
        $this->_lastResponse = null;
687
688
        try {
689
            $response = $this->_lastResponse = $request->send();
690
        } catch (ConnectionException $e) {
691
            $this->_connectionPool->onFail($connection, $e, $this);
692
693
            $this->_log($e);
694
695
            // In case there is no valid connection left, throw exception which caused the disabling of the connection.
696
            if (!$this->hasConnection()) {
697
                throw $e;
698
            }
699
700
            return $this->request($path, $method, $data, $query);
701
        }
702
703
        $this->_log($request);
704
705
        return $response;
706
    }
707
708
    /**
709
     * Makes calls to the elasticsearch server with usage official client Endpoint.
710
     *
711
     * @param AbstractEndpoint $endpoint
712
     *
713
     * @return Response
714
     */
715
    public function requestEndpoint(AbstractEndpoint $endpoint)
716
    {
717
        return $this->request(
718
            ltrim($endpoint->getURI(), '/'),
719
            $endpoint->getMethod(),
720
            null === $endpoint->getBody() ? [] : $endpoint->getBody(),
721
            $endpoint->getParams()
722
        );
723
    }
724
725
    /**
726
     * logging.
727
     *
728
     * @deprecated Overwriting Client->_log is deprecated. Handle logging functionality by using a custom LoggerInterface.
729
     *
730
     * @param mixed $context
731
     */
732
    protected function _log($context)
733
    {
734
        if ($context instanceof ConnectionException) {
735
            $this->_logger->error('Elastica Request Failure', [
736
                'exception' => $context,
737
                'request' => $context->getRequest()->toArray(),
738
                'retry' => $this->hasConnection(),
739
            ]);
740
741
            return;
742
        }
743
744
        if ($context instanceof Request) {
745
            $this->_logger->debug('Elastica Request', [
746
                'request' => $context->toArray(),
747
                'response' => $this->_lastResponse ? $this->_lastResponse->getData() : null,
748
                'responseStatus' => $this->_lastResponse ? $this->_lastResponse->getStatus() : null,
749
            ]);
750
751
            return;
752
        }
753
754
        $this->_logger->debug('Elastica Request', [
755
            'message' => $context,
756
        ]);
757
    }
758
759
    /**
760
     * Optimizes all search indices.
761
     *
762
     * @param array $args OPTIONAL Optional arguments
763
     *
764
     * @return \Elastica\Response Response object
765
     *
766
     * @deprecated Replaced by forcemergeAll
767
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-optimize.html
768
     */
769
    public function optimizeAll($args = [])
770
    {
771
        trigger_error('Deprecated: Elastica\Client::optimizeAll() is deprecated and will be removed in further Elastica releases. Use Elastica\Client::forcemergeAll() instead.', E_USER_DEPRECATED);
772
773
        return $this->forcemergeAll($args);
774
    }
775
776
    /**
777
     * Force merges all search indices.
778
     *
779
     * @param array $args OPTIONAL Optional arguments
780
     *
781
     * @return \Elastica\Response Response object
782
     *
783
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html
784
     */
785
    public function forcemergeAll($args = [])
786
    {
787
        $endpoint = new ForceMerge();
788
        $endpoint->setParams($args);
789
790
        return $this->requestEndpoint($endpoint);
791
    }
792
793
    /**
794
     * Refreshes all search indices.
795
     *
796
     * @return \Elastica\Response Response object
797
     *
798
     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html
799
     */
800
    public function refreshAll()
801
    {
802
        return $this->requestEndpoint(new Refresh());
803
    }
804
805
    /**
806
     * @return Request|null
807
     */
808
    public function getLastRequest()
809
    {
810
        return $this->_lastRequest;
811
    }
812
813
    /**
814
     * @return Response|null
815
     */
816
    public function getLastResponse()
817
    {
818
        return $this->_lastResponse;
819
    }
820
821
    /**
822
     * Replace the existing logger.
823
     *
824
     * @param LoggerInterface $logger
825
     *
826
     * @return $this
827
     */
828
    public function setLogger(LoggerInterface $logger)
829
    {
830
        $this->_logger = $logger;
831
832
        return $this;
833
    }
834
}
835