X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fsearch%2FSearchEngine.php;h=ea86a4b580687a478dde9d4102acd0b7d1b37281;hb=46c17ddb1ff10a1e073742c9d8b831cd915802f3;hp=7e6e8e6d0db6d1e14a7f651e611e7aa394a3312e;hpb=dd942172f81013f0866370b2acb1eee829de19d3;p=lhc%2Fweb%2Fwiklou.git
diff --git a/includes/search/SearchEngine.php b/includes/search/SearchEngine.php
index 7e6e8e6d0d..ea86a4b580 100644
--- a/includes/search/SearchEngine.php
+++ b/includes/search/SearchEngine.php
@@ -69,12 +69,27 @@ abstract class SearchEngine {
/**
* Perform a full text search query and return a result set.
* If full text searches are not supported or disabled, return null.
- * STUB
+ *
+ * As of 1.32 overriding this function is deprecated. It will
+ * be converted to final in 1.34. Override self::doSearchText().
*
* @param string $term Raw search term
* @return SearchResultSet|Status|null
*/
- function searchText( $term ) {
+ public function searchText( $term ) {
+ return $this->maybePaginate( function () use ( $term ) {
+ return $this->doSearchText( $term );
+ } );
+ }
+
+ /**
+ * Perform a full text search query and return a result set.
+ *
+ * @param string $term Raw search term
+ * @return SearchResultSet|Status|null
+ * @since 1.32
+ */
+ protected function doSearchText( $term ) {
return null;
}
@@ -85,11 +100,25 @@ abstract class SearchEngine {
* The results returned by this methods are only sugegstions and
* may not end up being shown to the user.
*
+ * As of 1.32 overriding this function is deprecated. It will
+ * be converted to final in 1.34. Override self::doSearchArchiveTitle().
+ *
* @param string $term Raw search term
* @return Status
* @since 1.29
*/
- function searchArchiveTitle( $term ) {
+ public function searchArchiveTitle( $term ) {
+ return $this->doSearchArchiveTitle( $term );
+ }
+
+ /**
+ * Perform a title search in the article archive.
+ *
+ * @param string $term Raw search term
+ * @return Status
+ * @since 1.32
+ */
+ protected function doSearchArchiveTitle( $term ) {
return Status::newGood( [] );
}
@@ -98,13 +127,63 @@ abstract class SearchEngine {
* If title searches are not supported or disabled, return null.
* STUB
*
+ * As of 1.32 overriding this function is deprecated. It will
+ * be converted to final in 1.34. Override self::doSearchTitle().
+ *
+ * @param string $term Raw search term
+ * @return SearchResultSet|null
+ */
+ public function searchTitle( $term ) {
+ return $this->maybePaginate( function () use ( $term ) {
+ return $this->doSearchTitle( $term );
+ } );
+ }
+
+ /**
+ * Perform a title-only search query and return a result set.
+ *
* @param string $term Raw search term
* @return SearchResultSet|null
+ * @since 1.32
*/
- function searchTitle( $term ) {
+ protected function doSearchTitle( $term ) {
return null;
}
+ /**
+ * Performs an overfetch and shrink operation to determine if
+ * the next page is available for search engines that do not
+ * explicitly implement their own pagination.
+ *
+ * @param Closure $fn Takes no arguments
+ * @return SearchResultSet|Status|null Result of calling $fn
+ */
+ private function maybePaginate( Closure $fn ) {
+ if ( $this instanceof PaginatingSearchEngine ) {
+ return $fn();
+ }
+ $this->limit++;
+ try {
+ $resultSetOrStatus = $fn();
+ } finally {
+ $this->limit--;
+ }
+
+ $resultSet = null;
+ if ( $resultSetOrStatus instanceof SearchResultSet ) {
+ $resultSet = $resultSetOrStatus;
+ } elseif ( $resultSetOrStatus instanceof Status &&
+ $resultSetOrStatus->getValue() instanceof SearchResultSet
+ ) {
+ $resultSet = $resultSetOrStatus->getValue();
+ }
+ if ( $resultSet ) {
+ $resultSet->shrink( $this->limit );
+ }
+
+ return $resultSetOrStatus;
+ }
+
/**
* @since 1.18
* @param string $feature
@@ -165,6 +244,8 @@ abstract class SearchEngine {
* search=test&prefix=Main_Page/Archive -> test prefix:Main Page/Archive
* @param string $term
* @return string
+ * @deprecated since 1.32 this should now be handled internally by the
+ * search engine
*/
public function transformSearchTerm( $term ) {
return $term;
@@ -335,12 +416,25 @@ abstract class SearchEngine {
return false;
}
$extractedNamespace = null;
+ $allkeywords = [];
+
+ $allkeywords[] = wfMessage( 'searchall' )->inContentLanguage()->text() . ":";
+ // force all: so that we have a common syntax for all the wikis
+ if ( !in_array( 'all:', $allkeywords ) ) {
+ $allkeywords[] = 'all:';
+ }
+
+ $allQuery = false;
+ foreach ( $allkeywords as $kw ) {
+ if ( strncmp( $query, $kw, strlen( $kw ) ) == 0 ) {
+ $extractedNamespace = null;
+ $parsed = substr( $query, strlen( $kw ) );
+ $allQuery = true;
+ break;
+ }
+ }
- $allkeyword = wfMessage( 'searchall' )->inContentLanguage()->text() . ":";
- if ( strncmp( $query, $allkeyword, strlen( $allkeyword ) ) == 0 ) {
- $extractedNamespace = null;
- $parsed = substr( $query, strlen( $allkeyword ) );
- } elseif ( strpos( $query, ':' ) !== false ) {
+ if ( !$allQuery && strpos( $query, ':' ) !== false ) {
// TODO: should we unify with PrefixSearch::extractNamespace ?
$prefix = str_replace( ' ', '_', substr( $query, 0, strpos( $query, ':' ) ) );
$index = $wgContLang->getNsIndex( $prefix );
@@ -413,7 +507,7 @@ abstract class SearchEngine {
*
* @todo This isn't ideal, we'd really like to have content-specific handling here
* @param Title $t Title we're indexing
- * @param Content $c Content of the page to index
+ * @param Content|null $c Content of the page to index
* @return string
*/
public function getTextFromContent( Title $t, Content $c = null ) {
@@ -469,6 +563,22 @@ abstract class SearchEngine {
return $search;
}
+ /**
+ * Perform an overfetch of completion search results. This allows
+ * determining if another page of results is available.
+ *
+ * @param string $search
+ * @return SearchSuggestionSet
+ */
+ protected function completionSearchBackendOverfetch( $search ) {
+ $this->limit++;
+ try {
+ return $this->completionSearchBackend( $search );
+ } finally {
+ $this->limit--;
+ }
+ }
+
/**
* Perform a completion search.
* Does not resolve namespaces and does not check variants.
@@ -506,7 +616,8 @@ abstract class SearchEngine {
return SearchSuggestionSet::emptySuggestionSet(); // Return empty result
}
$search = $this->normalizeNamespaces( $search );
- return $this->processCompletionResults( $search, $this->completionSearchBackend( $search ) );
+ $suggestions = $this->completionSearchBackendOverfetch( $search );
+ return $this->processCompletionResults( $search, $suggestions );
}
/**
@@ -520,8 +631,8 @@ abstract class SearchEngine {
}
$search = $this->normalizeNamespaces( $search );
- $results = $this->completionSearchBackend( $search );
- $fallbackLimit = $this->limit - $results->getSize();
+ $results = $this->completionSearchBackendOverfetch( $search );
+ $fallbackLimit = 1 + $this->limit - $results->getSize();
if ( $fallbackLimit > 0 ) {
global $wgContLang;
@@ -560,15 +671,26 @@ abstract class SearchEngine {
* @return SearchSuggestionSet
*/
protected function processCompletionResults( $search, SearchSuggestionSet $suggestions ) {
+ // We over-fetched to determine pagination. Shrink back down if we have extra results
+ // and mark if pagination is possible
+ $suggestions->shrink( $this->limit );
+
$search = trim( $search );
// preload the titles with LinkBatch
- $titles = $suggestions->map( function ( SearchSuggestion $sugg ) {
+ $lb = new LinkBatch( $suggestions->map( function ( SearchSuggestion $sugg ) {
return $sugg->getSuggestedTitle();
- } );
- $lb = new LinkBatch( $titles );
+ } ) );
$lb->setCaller( __METHOD__ );
$lb->execute();
+ $diff = $suggestions->filter( function ( SearchSuggestion $sugg ) {
+ return $sugg->getSuggestedTitle()->isKnown();
+ } );
+ if ( $diff > 0 ) {
+ MediaWikiServices::getInstance()->getStatsdDataFactory()
+ ->updateCount( 'search.completion.missing', $diff );
+ }
+
$results = $suggestions->map( function ( SearchSuggestion $sugg ) {
return $sugg->getSuggestedTitle()->getPrefixedText();
} );
@@ -776,7 +898,6 @@ abstract class SearchEngine {
$setAugmentors = [];
$rowAugmentors = [];
Hooks::run( "SearchResultsAugment", [ &$setAugmentors, &$rowAugmentors ] );
-
if ( !$setAugmentors && !$rowAugmentors ) {
// We're done here
return;