Skip to content

Commit 044be5e

Browse files
Tobionruflin
authored andcommitted
Make ResultSet iterator current() not return a mixed value (#1506)
Returning potentially false from the iterator current() means each result set item could be `false` which makes it impractical to safely use it. When using phpstan, you will get errors like `Cannot call method getId() on bool|Elastica\Result.` when you just iterate over the result set. Also `current()` should not need to check `valid()` again because that is done automatically by php when using foreach. When valid returns false, the loop is ended. So that is part of the Iterator spec. So using current on a non-existing item should not happen unless you misuse the Iterator.
1 parent d6f1475 commit 044be5e

File tree

6 files changed

+22
-46
lines changed

6 files changed

+22
-46
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file based on the
55

66
### Backward Compatibility Breaks
77

8+
* Made result sets adhere to `\Iterator` interface definition that they implement. Specifically, you need to call `valid()` on the result set before calling `current()`. When using `foreach` this is done by PHP automatically. When `valid` returns false, the return value of `current` is undefined instead of false.
9+
* `\Elastica\ResultSet::next` returns `void` instead of `\Elastica\Result|false`
10+
* `\Elastica\Bulk\ResponseSet::current` returns `\Elastica\Bulk\Response` instead of `\Elastica\Bulk\Response|false`
11+
* `\Elastica\Multi\ResultSet::current` returns `\Elastica\ResultSet` instead of `\Elastica\ResultSet|false`
12+
813
### Bugfixes
914

1015
### Added

lib/Elastica/Bulk/ResponseSet.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,11 @@ public function hasError()
9595
}
9696

9797
/**
98-
* @return bool|\Elastica\Bulk\Response
98+
* @return \Elastica\Bulk\Response
9999
*/
100100
public function current()
101101
{
102-
return $this->valid()
103-
? $this->_bulkResponses[$this->key()]
104-
: false;
102+
return $this->_bulkResponses[$this->key()];
105103
}
106104

107105
/**

lib/Elastica/Multi/ResultSet.php

+4-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
namespace Elastica\Multi;
33

44
use Elastica\Response;
5-
use Elastica\ResultSet as BaseResultSet;
65

76
/**
87
* Elastica multi search result set
@@ -36,8 +35,8 @@ class ResultSet implements \Iterator, \ArrayAccess, \Countable
3635
/**
3736
* Constructs ResultSet object.
3837
*
39-
* @param \Elastica\Response $response
40-
* @param BaseResultSet[]
38+
* @param \Elastica\Response $response
39+
* @param \Elastica\ResultSet[] $resultSets
4140
*/
4241
public function __construct(Response $response, $resultSets)
4342
{
@@ -80,13 +79,11 @@ public function hasError()
8079
}
8180

8281
/**
83-
* @return bool|\Elastica\ResultSet
82+
* @return \Elastica\ResultSet
8483
*/
8584
public function current()
8685
{
87-
return $this->valid()
88-
? $this->_resultSets[$this->key()]
89-
: false;
86+
return $this->_resultSets[$this->key()];
9087
}
9188

9289
/**

lib/Elastica/ResultSet.php

+3-9
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,11 @@ public function countSuggests()
236236
/**
237237
* Returns the current object of the set.
238238
*
239-
* @return \Elastica\Result|bool Set object or false if not valid (no more entries)
239+
* @return \Elastica\Result Set object
240240
*/
241241
public function current()
242242
{
243-
if ($this->valid()) {
244-
return $this->_results[$this->key()];
245-
}
246-
247-
return false;
243+
return $this->_results[$this->key()];
248244
}
249245

250246
/**
@@ -253,8 +249,6 @@ public function current()
253249
public function next()
254250
{
255251
++$this->_position;
256-
257-
return $this->current();
258252
}
259253

260254
/**
@@ -308,7 +302,7 @@ public function offsetExists($offset)
308302
*
309303
* @throws Exception\InvalidException If offset doesn't exist
310304
*
311-
* @return Result|null
305+
* @return Result
312306
*/
313307
public function offsetGet($offset)
314308
{

test/Elastica/Bulk/ResponseSetTest.php

+4-24
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,6 @@ public function testIterator()
106106
}
107107

108108
$this->assertFalse($responseSet->valid());
109-
$this->assertNotInstanceOf(Bulk\Response::class, $responseSet->current());
110-
$this->assertFalse($responseSet->current());
111-
112-
$responseSet->next();
113-
114-
$this->assertFalse($responseSet->valid());
115-
$this->assertNotInstanceOf(Bulk\Response::class, $responseSet->current());
116-
$this->assertFalse($responseSet->current());
117109

118110
$responseSet->rewind();
119111

@@ -126,21 +118,12 @@ public function isOkDataProvider()
126118
{
127119
list($responseData, $actions) = $this->_getFixture();
128120

129-
$return = [];
130-
$return[] = [$responseData, $actions, true];
121+
yield [$responseData, $actions, true];
131122
$responseData['items'][2]['index']['ok'] = false;
132-
$return[] = [$responseData, $actions, false];
133-
134-
return $return;
123+
yield [$responseData, $actions, false];
135124
}
136125

137-
/**
138-
* @param array $responseData
139-
* @param array $actions
140-
*
141-
* @return ResponseSet
142-
*/
143-
protected function _createResponseSet(array $responseData, array $actions)
126+
protected function _createResponseSet(array $responseData, array $actions): ResponseSet
144127
{
145128
$client = $this->createMock(Client::class);
146129

@@ -155,10 +138,7 @@ protected function _createResponseSet(array $responseData, array $actions)
155138
return $bulk->send();
156139
}
157140

158-
/**
159-
* @return array
160-
*/
161-
protected function _getFixture()
141+
protected function _getFixture(): array
162142
{
163143
$responseData = [
164144
'took' => 5,

test/Elastica/QueryTest.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ public function testSetSort()
119119
$this->assertEquals(2, $resultSet->count());
120120

121121
$first = $resultSet->current()->getData();
122-
$second = $resultSet->next()->getData();
122+
$resultSet->next();
123+
$second = $resultSet->current()->getData();
123124

124125
$this->assertEquals('guschti', $first['firstname']);
125126
$this->assertEquals('nicolas', $second['firstname']);
@@ -130,7 +131,8 @@ public function testSetSort()
130131
$this->assertEquals(2, $resultSet->count());
131132

132133
$first = $resultSet->current()->getData();
133-
$second = $resultSet->next()->getData();
134+
$resultSet->next();
135+
$second = $resultSet->current()->getData();
134136

135137
$this->assertEquals('nicolas', $first['firstname']);
136138
$this->assertEquals('guschti', $second['firstname']);

0 commit comments

Comments
 (0)