Response.php 8.1 KB

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