Completed
Push — master ( 07a770...cad28f )
by Nicolas
03:05
created

Response::getData()   B

Complexity

Conditions 6
Paths 21

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
rs 8.439
c 0
b 0
f 0
cc 6
eloc 15
nc 21
nop 0
1
<?php
2
namespace Elastica;
3
4
use Elastica\Exception\JSONParseException;
5
use Elastica\Exception\NotFoundException;
6
7
/**
8
 * Elastica Response object.
9
 *
10
 * Stores query time, and result array -> is given to result set, returned by ...
11
 *
12
 * @author Nicolas Ruflin <[email protected]>
13
 */
14
class Response
15
{
16
    /**
17
     * Query time.
18
     *
19
     * @var float Query time
20
     */
21
    protected $_queryTime;
22
23
    /**
24
     * Response string (json).
25
     *
26
     * @var string Response
27
     */
28
    protected $_responseString = '';
29
30
    /**
31
     * Transfer info.
32
     *
33
     * @var array transfer info
34
     */
35
    protected $_transferInfo = [];
36
37
    /**
38
     * Response.
39
     *
40
     * @var array|null
41
     */
42
    protected $_response;
43
44
    /**
45
     * HTTP response status code.
46
     *
47
     * @var int
48
     */
49
    protected $_status;
50
51
    /**
52
     * Whether or not to convert bigint results to string (see issue #717).
53
     *
54
     * @var bool
55
     */
56
    protected $_jsonBigintConversion = false;
57
58
    /**
59
     * Construct.
60
     *
61
     * @param string|array $responseString Response string (json)
62
     * @param int          $responseStatus http status code
63
     */
64
    public function __construct($responseString, $responseStatus = null)
65
    {
66
        if (is_array($responseString)) {
67
            $this->_response = $responseString;
68
        } else {
69
            $this->_responseString = $responseString;
70
        }
71
        $this->_status = $responseStatus;
72
    }
73
74
    /**
75
     * Error message.
76
     *
77
     * @return string Error message
78
     */
79
    public function getError()
80
    {
81
        $error = $this->getFullError();
82
83
        if (!$error) {
84
            return '';
85
        }
86
87
        if (is_string($error)) {
88
            return $error;
89
        }
90
91
        $rootError = $error;
92
        if (isset($error['root_cause'][0])) {
93
            $rootError = $error['root_cause'][0];
94
        }
95
96
        $message = $rootError['reason'];
97
        if (isset($rootError['index'])) {
98
            $message .= ' [index: '.$rootError['index'].']';
99
        }
100
101
        if (isset($error['reason']) && $rootError['reason'] != $error['reason']) {
102
            $message .= ' [reason: '.$error['reason'].']';
103
        }
104
105
        return $message;
106
    }
107
108
    /**
109
     * A keyed array representing any errors that occurred.
110
     *
111
     * In case of http://localhost:9200/_alias/test the error is a string
112
     *
113
     * @return array|string|null Error data or null if there is no error
114
     */
115
    public function getFullError()
116
    {
117
        $response = $this->getData();
118
119
        if (isset($response['error'])) {
120
            return $response['error'];
121
        }
122
    }
123
124
    /**
125
     * @return string Error string based on the error object
126
     */
127
    public function getErrorMessage()
128
    {
129
        return $this->getError();
130
    }
131
132
    /**
133
     * True if response has error.
134
     *
135
     * @return bool True if response has error
136
     */
137
    public function hasError()
138
    {
139
        $response = $this->getData();
140
141
        return isset($response['error']);
142
    }
143
144
    /**
145
     * True if response has failed shards.
146
     *
147
     * @return bool True if response has failed shards
148
     */
149
    public function hasFailedShards()
150
    {
151
        try {
152
            $shardsStatistics = $this->getShardsStatistics();
153
        } catch (NotFoundException $e) {
154
            return false;
155
        }
156
157
        return array_key_exists('failures', $shardsStatistics);
158
    }
159
160
    /**
161
     * Checks if the query returned ok.
162
     *
163
     * @return bool True if ok
164
     */
165
    public function isOk()
166
    {
167
        $data = $this->getData();
168
169
        // Bulk insert checks. Check every item
170
        if (isset($data['status'])) {
171
            return $data['status'] >= 200 && $data['status'] <= 300;
172
        }
173
174
        if (isset($data['items'])) {
175
            if (isset($data['errors']) && true === $data['errors']) {
176
                return false;
177
            }
178
179
            foreach ($data['items'] as $item) {
180
                if (isset($item['index']['ok']) && false == $item['index']['ok']) {
181
                    return false;
182
                }
183
184
                if (isset($item['index']['status']) && ($item['index']['status'] < 200 || $item['index']['status'] >= 300)) {
185
                    return false;
186
                }
187
            }
188
189
            return true;
190
        }
191
192
        if ($this->_status >= 200 && $this->_status <= 300) {
193
            // http status is ok
194
            return true;
195
        }
196
197
        return isset($data['ok']) && $data['ok'];
198
    }
199
200
    /**
201
     * @return int
202
     */
203
    public function getStatus()
204
    {
205
        return $this->_status;
206
    }
207
208
    /**
209
     * Response data array.
210
     *
211
     * @return array Response data array
212
     */
213
    public function getData()
214
    {
215
        if ($this->_response == null) {
216
            $response = $this->_responseString;
217
218
            try {
219
                if ($this->getJsonBigintConversion()) {
220
                    $response = JSON::parse($response, true, 512, JSON_BIGINT_AS_STRING);
221
                } else {
222
                    $response = JSON::parse($response);
223
                }
224
            } catch (JSONParseException $e) {
225
                // leave response as is if parse fails
226
            }
227
228
            if (empty($response)) {
229
                $response = [];
230
            }
231
232
            if (is_string($response)) {
233
                $response = ['message' => $response];
234
            }
235
236
            $this->_response = $response;
237
        }
238
239
        return $this->_response;
240
    }
241
242
    /**
243
     * Gets the transfer information.
244
     *
245
     * @return array Information about the curl request.
246
     */
247
    public function getTransferInfo()
248
    {
249
        return $this->_transferInfo;
250
    }
251
252
    /**
253
     * Sets the transfer info of the curl request. This function is called
254
     * from the \Elastica\Client::_callService .
255
     *
256
     * @param array $transferInfo The curl transfer information.
257
     *
258
     * @return $this
259
     */
260
    public function setTransferInfo(array $transferInfo)
261
    {
262
        $this->_transferInfo = $transferInfo;
263
264
        return $this;
265
    }
266
267
    /**
268
     * Returns query execution time.
269
     *
270
     * @return float Query time
271
     */
272
    public function getQueryTime()
273
    {
274
        return $this->_queryTime;
275
    }
276
277
    /**
278
     * Sets the query time.
279
     *
280
     * @param float $queryTime Query time
281
     *
282
     * @return $this
283
     */
284
    public function setQueryTime($queryTime)
285
    {
286
        $this->_queryTime = $queryTime;
287
288
        return $this;
289
    }
290
291
    /**
292
     * Time request took.
293
     *
294
     * @throws \Elastica\Exception\NotFoundException
295
     *
296
     * @return int Time request took
297
     */
298 View Code Duplication
    public function getEngineTime()
0 ignored issues
show
Duplication introduced by
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...
299
    {
300
        $data = $this->getData();
301
302
        if (!isset($data['took'])) {
303
            throw new NotFoundException('Unable to find the field [took]from the response');
304
        }
305
306
        return $data['took'];
307
    }
308
309
    /**
310
     * Get the _shard statistics for the response.
311
     *
312
     * @throws \Elastica\Exception\NotFoundException
313
     *
314
     * @return array
315
     */
316 View Code Duplication
    public function getShardsStatistics()
0 ignored issues
show
Duplication introduced by
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...
317
    {
318
        $data = $this->getData();
319
320
        if (!isset($data['_shards'])) {
321
            throw new NotFoundException('Unable to find the field [_shards] from the response');
322
        }
323
324
        return $data['_shards'];
325
    }
326
327
    /**
328
     * Get the _scroll value for the response.
329
     *
330
     * @throws \Elastica\Exception\NotFoundException
331
     *
332
     * @return string
333
     */
334 View Code Duplication
    public function getScrollId()
0 ignored issues
show
Duplication introduced by
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...
335
    {
336
        $data = $this->getData();
337
338
        if (!isset($data['_scroll_id'])) {
339
            throw new NotFoundException('Unable to find the field [_scroll_id] from the response');
340
        }
341
342
        return $data['_scroll_id'];
343
    }
344
345
    /**
346
     * Sets whether or not to apply bigint conversion on the JSON result.
347
     *
348
     * @param bool $jsonBigintConversion
349
     */
350
    public function setJsonBigintConversion($jsonBigintConversion)
351
    {
352
        $this->_jsonBigintConversion = $jsonBigintConversion;
353
    }
354
355
    /**
356
     * Gets whether or not to apply bigint conversion on the JSON result.
357
     *
358
     * @return bool
359
     */
360
    public function getJsonBigintConversion()
361
    {
362
        return $this->_jsonBigintConversion;
363
    }
364
}
365