/**
* @ingroup Search
*/
-class SearchResultSet {
+class SearchResultSet implements IteratorAggregate {
/**
* Types of interwiki results
* as an array.
* @var SearchResult[]
*/
- private $results;
+ protected $results;
/**
* Set of result's extra data, indexed per result id
*/
protected $extraData = [];
+ /** @var ArrayIterator|null Iterator supporting BC iteration methods */
+ private $bcIterator;
+
public function __construct( $containedSyntax = false ) {
+ if ( static::class === __CLASS__ ) {
+ // This class will eventually be abstract. SearchEngine implementations
+ // already have to extend this class anyways to provide the actual
+ // search results.
+ wfDeprecated( __METHOD__, 1.32 );
+ }
$this->containedSyntax = $containedSyntax;
}
/**
* Fetches next search result, or false.
- * STUB
- * FIXME: refactor as iterator, so we could use nicer interfaces.
- * @deprecated since 1.32; Use self::extractResults()
+ * @deprecated since 1.32; Use self::extractResults() or foreach
* @return SearchResult|false
*/
- function next() {
- return false;
+ public function next() {
+ wfDeprecated( __METHOD__, '1.32' );
+ $it = $this->bcIterator();
+ $searchResult = $it->current();
+ $it->next();
+ return $searchResult === null ? false : $searchResult;
}
/**
* Rewind result set back to beginning
- * @deprecated since 1.32; Use self::extractResults()
+ * @deprecated since 1.32; Use self::extractResults() or foreach
*/
- function rewind() {
+ public function rewind() {
+ wfDeprecated( __METHOD__, '1.32' );
+ $this->bcIterator()->rewind();
+ }
+
+ private function bcIterator() {
+ if ( $this->bcIterator === null ) {
+ $this->bcIterator = 'RECURSION';
+ $this->bcIterator = $this->getIterator();
+ } elseif ( $this->bcIterator === 'RECURSION' ) {
+ // Either next/rewind or extractResults must be implemented. This
+ // class was potentially instantiated directly. It should be
+ // abstract with abstract methods to enforce this but that's a
+ // breaking change...
+ wfDeprecated( static::class . ' without implementing extractResults', '1.32' );
+ $this->bcIterator = new ArrayIterator( [] );
+ }
+ return $this->bcIterator;
}
/**
/**
* Returns extra data for specific result and store it in SearchResult object.
* @param SearchResult $result
- * @return array|null List of data as name => value or null if none present.
*/
public function augmentResult( SearchResult $result ) {
$id = $result->getTitle()->getArticleID();
- if ( !$id || !isset( $this->extraData[$id] ) ) {
- return null;
+ if ( $id === -1 ) {
+ return;
}
- $result->setExtensionData( $this->extraData[$id] );
- return $this->extraData[$id];
+ $result->setExtensionData( function () use ( $id ) {
+ if ( isset( $this->extraData[$id] ) ) {
+ return $this->extraData[$id];
+ } else {
+ return [];
+ }
+ } );
}
/**
public function getOffset() {
return null;
}
+
+ final public function getIterator() {
+ return new ArrayIterator( $this->extractResults() );
+ }
}