+ /**
+ * Assemble search result data.
+ * @param SearchResult $result Search result
+ * @param array $prop Props to extract (as keys)
+ * @param array $terms Terms list
+ * @return array|null Result data or null if result is broken in some way.
+ */
+ private function getSearchResultData( SearchResult $result, $prop, $terms ) {
+ // Silently skip broken and missing titles
+ if ( $result->isBrokenTitle() || $result->isMissingRevision() ) {
+ return null;
+ }
+
+ $vals = [];
+
+ $title = $result->getTitle();
+ ApiQueryBase::addTitleInfo( $vals, $title );
+
+ if ( isset( $prop['size'] ) ) {
+ $vals['size'] = $result->getByteSize();
+ }
+ if ( isset( $prop['wordcount'] ) ) {
+ $vals['wordcount'] = $result->getWordCount();
+ }
+ if ( isset( $prop['snippet'] ) ) {
+ $vals['snippet'] = $result->getTextSnippet( $terms );
+ }
+ if ( isset( $prop['timestamp'] ) ) {
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $result->getTimestamp() );
+ }
+ if ( isset( $prop['titlesnippet'] ) ) {
+ $vals['titlesnippet'] = $result->getTitleSnippet();
+ }
+ if ( isset( $prop['categorysnippet'] ) ) {
+ $vals['categorysnippet'] = $result->getCategorySnippet();
+ }
+ if ( !is_null( $result->getRedirectTitle() ) ) {
+ if ( isset( $prop['redirecttitle'] ) ) {
+ $vals['redirecttitle'] = $result->getRedirectTitle()->getPrefixedText();
+ }
+ if ( isset( $prop['redirectsnippet'] ) ) {
+ $vals['redirectsnippet'] = $result->getRedirectSnippet();
+ }
+ }
+ if ( !is_null( $result->getSectionTitle() ) ) {
+ if ( isset( $prop['sectiontitle'] ) ) {
+ $vals['sectiontitle'] = $result->getSectionTitle()->getFragment();
+ }
+ if ( isset( $prop['sectionsnippet'] ) ) {
+ $vals['sectionsnippet'] = $result->getSectionSnippet();
+ }
+ }
+ if ( isset( $prop['isfilematch'] ) ) {
+ $vals['isfilematch'] = $result->isFileMatch();
+ }
+ return $vals;
+ }
+
+ /**
+ * Add interwiki results as a section in query results.
+ * @param SearchResultSet $matches
+ * @param ApiResult $apiResult
+ * @param array $prop Props to extract (as keys)
+ * @param array $terms Terms list
+ * @param string $section Section name where results would go
+ * @param int $type Interwiki result type
+ * @return int|null Number of total hits in the data or null if none was produced
+ */
+ private function addInterwikiResults(
+ SearchResultSet $matches, ApiResult $apiResult, $prop,
+ $terms, $section, $type
+ ) {
+ $totalhits = null;
+ if ( $matches->hasInterwikiResults( $type ) ) {
+ foreach ( $matches->getInterwikiResults( $type ) as $interwikiMatches ) {
+ // Include number of results if requested
+ $totalhits += $interwikiMatches->getTotalHits();
+
+ $result = $interwikiMatches->next();
+ while ( $result ) {
+ $title = $result->getTitle();
+ $vals = $this->getSearchResultData( $result, $prop, $terms );
+
+ $vals['namespace'] = $result->getInterwikiNamespaceText();
+ $vals['title'] = $title->getText();
+ $vals['url'] = $title->getFullURL();
+
+ // Add item to results and see whether it fits
+ $fit = $apiResult->addValue( [
+ 'query',
+ $section . $this->getModuleName(),
+ $result->getInterwikiPrefix()
+ ], null, $vals );
+
+ if ( !$fit ) {
+ // We hit the limit. We can't really provide any meaningful
+ // pagination info so just bail out
+ break;
+ }
+
+ $result = $interwikiMatches->next();
+ }
+ }
+ if ( $totalhits !== null ) {
+ $apiResult->addValue( [ 'query', $section . 'searchinfo' ], 'totalhits', $totalhits );
+ $apiResult->addIndexedTagName( [
+ 'query', $section . $this->getModuleName()
+ ], 'p' );
+ }
+ }
+ return $totalhits;
+ }
+