MediaWiki  master
SearchExactMatchRescorer.php
Go to the documentation of this file.
1 <?php
25 
44  public function rescore( $search, $namespaces, $srchres, $limit ) {
45  // Pick namespace (based on PrefixSearch::defaultSearchBackend)
46  $ns = in_array( NS_MAIN, $namespaces ) ? NS_MAIN : reset( $namespaces );
47  $t = Title::newFromText( $search, $ns );
48  if ( !$t || !$t->exists() ) {
49  // No exact match so just return the search results
50  return $srchres;
51  }
52  $string = $t->getPrefixedText();
53  $key = array_search( $string, $srchres );
54  if ( $key !== false ) {
55  // Exact match was in the results so just move it to the front
56  return $this->pullFront( $key, $srchres );
57  }
58  // Exact match not in the search results so check for some redirect handling cases
59  if ( $t->isRedirect() ) {
60  $target = $this->getRedirectTarget( $t );
61  $key = array_search( $target, $srchres );
62  if ( $key !== false ) {
63  // Exact match is a redirect to one of the returned matches so pull the
64  // returned match to the front. This might look odd but the alternative
65  // is to put the redirect in front and drop the match. The name of the
66  // found match is often more descriptive/better formed than the name of
67  // the redirect AND by definition they share a prefix. Hopefully this
68  // choice is less confusing and more helpful. But it might not be. But
69  // it is the choice we're going with for now.
70  return $this->pullFront( $key, $srchres );
71  }
72  $redirectTargetsToRedirect = $this->redirectTargetsToRedirect( $srchres );
73  if ( isset( $redirectTargetsToRedirect[$target] ) ) {
74  // The exact match and something in the results list are both redirects
75  // to the same thing! In this case we'll pull the returned match to the
76  // top following the same logic above. Again, it might not be a perfect
77  // choice but it'll do.
78  return $this->pullFront( $redirectTargetsToRedirect[$target], $srchres );
79  }
80  } else {
81  $redirectTargetsToRedirect = $this->redirectTargetsToRedirect( $srchres );
82  if ( isset( $redirectTargetsToRedirect[$string] ) ) {
83  // The exact match is the target of a redirect already in the results list so remove
84  // the redirect from the results list and push the exact match to the front
85  array_splice( $srchres, $redirectTargetsToRedirect[$string], 1 );
86  array_unshift( $srchres, $string );
87  return $srchres;
88  }
89  }
90 
91  // Exact match is totally unique from the other results so just add it to the front
92  array_unshift( $srchres, $string );
93  // And roll one off the end if the results are too long
94  if ( count( $srchres ) > $limit ) {
95  array_pop( $srchres );
96  }
97  return $srchres;
98  }
99 
105  private function redirectTargetsToRedirect( array $titles ) {
106  $result = [];
107  foreach ( $titles as $key => $titleText ) {
108  $title = Title::newFromText( $titleText );
109  if ( !$title || !$title->isRedirect() ) {
110  continue;
111  }
112  $target = $this->getRedirectTarget( $title );
113  if ( !$target ) {
114  continue;
115  }
116  $result[$target] = $key;
117  }
118  return $result;
119  }
120 
128  private function pullFront( $key, array $array ) {
129  $cut = array_splice( $array, $key, 1 );
130  array_unshift( $array, $cut[0] );
131  return $array;
132  }
133 
139  private function getRedirectTarget( $title ) {
140  $page = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $title );
141  if ( !$page->exists() ) {
142  return null;
143  }
144  $redir = $page->getRedirectTarget();
145  return $redir ? $redir->getPrefixedText() : null;
146  }
147 }
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:382
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:193
SearchExactMatchRescorer\rescore
rescore( $search, $namespaces, $srchres, $limit)
Default search backend does proper prefix searching, but custom backends may sort based on other algo...
Definition: SearchExactMatchRescorer.php:44
NS_MAIN
const NS_MAIN
Definition: Defines.php:64
SearchExactMatchRescorer
An utility class to rescore search results by looking for an exact match in the db and add the page f...
Definition: SearchExactMatchRescorer.php:33
SearchExactMatchRescorer\getRedirectTarget
getRedirectTarget( $title)
Get a redirect's destination from a title.
Definition: SearchExactMatchRescorer.php:139
$title
$title
Definition: testCompression.php:38
SearchExactMatchRescorer\redirectTargetsToRedirect
redirectTargetsToRedirect(array $titles)
Definition: SearchExactMatchRescorer.php:105
$t
$t
Definition: testCompression.php:74
SearchExactMatchRescorer\pullFront
pullFront( $key, array $array)
Returns an array where the element of $array at index $key becomes the first element.
Definition: SearchExactMatchRescorer.php:128