MediaWiki REL1_35
SearchNearMatcher.php
Go to the documentation of this file.
1<?php
2
6
15 protected $config;
16
21 private $language;
22
28
32 private $hookRunner;
33
40 public function __construct( Config $config, Language $lang, HookContainer $hookContainer ) {
41 $this->config = $config;
42 $this->language = $lang;
43 $this->languageConverter = MediaWikiServices::getInstance()->getLanguageConverterFactory()
44 ->getLanguageConverter( $lang );
45 $this->hookRunner = new HookRunner( $hookContainer );
46 }
47
55 public function getNearMatch( $searchterm ) {
56 $title = $this->getNearMatchInternal( $searchterm );
57
58 $this->hookRunner->onSearchGetNearMatchComplete( $searchterm, $title );
59 return $title;
60 }
61
69 public function getNearMatchResultSet( $searchterm ) {
70 return new SearchNearMatchResultSet( $this->getNearMatch( $searchterm ) );
71 }
72
78 protected function getNearMatchInternal( $searchterm ) {
79 $allSearchTerms = [ $searchterm ];
80
81 if ( $this->languageConverter->hasVariants() ) {
82 $allSearchTerms = array_unique( array_merge(
83 $allSearchTerms,
84 $this->languageConverter->autoConvertToAllVariants( $searchterm )
85 ) );
86 }
87
88 $titleResult = null;
89 if ( !$this->hookRunner->onSearchGetNearMatchBefore( $allSearchTerms, $titleResult ) ) {
90 return $titleResult;
91 }
92
93 // Most of our handling here deals with finding a valid title for the search term,
94 // but almost anything starting with '#' is "valid" and points to Main_Page#searchterm.
95 // Rather than doing something completely wrong, do nothing.
96 if ( $searchterm === '' || $searchterm[0] === '#' ) {
97 return null;
98 }
99
100 foreach ( $allSearchTerms as $term ) {
101 # Exact match? No need to look further.
102 $title = Title::newFromText( $term );
103 if ( $title === null ) {
104 return null;
105 }
106
107 # Try files if searching in the Media: namespace
108 if ( $title->getNamespace() == NS_MEDIA ) {
109 $title = Title::makeTitle( NS_FILE, $title->getText() );
110 }
111
112 if ( $title->isSpecialPage() || $title->isExternal() || $title->exists() ) {
113 return $title;
114 }
115
116 # See if it still otherwise has content is some sane sense
117 $page = WikiPage::factory( $title );
118 if ( $page->hasViewableContent() ) {
119 return $title;
120 }
121
122 if ( !$this->hookRunner->onSearchAfterNoDirectMatch( $term, $title ) ) {
123 return $title;
124 }
125
126 # Now try all lower case (i.e. first letter capitalized)
127 $title = Title::newFromText( $this->language->lc( $term ) );
128 if ( $title && $title->exists() ) {
129 return $title;
130 }
131
132 # Now try capitalized string
133 $title = Title::newFromText( $this->language->ucwords( $term ) );
134 if ( $title && $title->exists() ) {
135 return $title;
136 }
137
138 # Now try all upper case
139 $title = Title::newFromText( $this->language->uc( $term ) );
140 if ( $title && $title->exists() ) {
141 return $title;
142 }
143
144 # Now try Word-Caps-Breaking-At-Word-Breaks, for hyphenated names etc
145 $title = Title::newFromText( $this->language->ucwordbreaks( $term ) );
146 if ( $title && $title->exists() ) {
147 return $title;
148 }
149
150 // Give hooks a chance at better match variants
151 $title = null;
152 if ( !$this->hookRunner->onSearchGetNearMatch( $term, $title ) ) {
153 return $title;
154 }
155 }
156
157 $title = Title::newFromText( $searchterm );
158
159 # Entering an IP address goes to the contributions page
160 if ( $this->config->get( 'EnableSearchContributorsByIP' ) ) {
161 if ( ( $title->getNamespace() == NS_USER && User::isIP( $title->getText() ) )
162 || User::isIP( trim( $searchterm ) ) ) {
163 return SpecialPage::getTitleFor( 'Contributions', $title->getDBkey() );
164 }
165 }
166
167 # Entering a user goes to the user page whether it's there or not
168 if ( $title->getNamespace() == NS_USER ) {
169 return $title;
170 }
171
172 # Go to images that exist even if there's no local page.
173 # There may have been a funny upload, or it may be on a shared
174 # file repository such as Wikimedia Commons.
175 if ( $title->getNamespace() == NS_FILE ) {
176 $image = MediaWikiServices::getInstance()->getRepoGroup()->findFile( $title );
177 if ( $image ) {
178 return $title;
179 }
180 }
181
182 # MediaWiki namespace? Page may be "implied" if not customized.
183 # Just return it, with caps forced as the message system likes it.
184 if ( $title->getNamespace() == NS_MEDIAWIKI ) {
185 return Title::makeTitle( NS_MEDIAWIKI, $this->language->ucfirst( $title->getText() ) );
186 }
187
188 # Quoted term? Try without the quotes...
189 $matches = [];
190 if ( preg_match( '/^"([^"]+)"$/', $searchterm, $matches ) ) {
191 return $this->getNearMatch( $matches[1] );
192 }
193
194 return null;
195 }
196}
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition Language.php:41
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
MediaWikiServices is the service locator for the application scope of MediaWiki.
A ISearchResultSet wrapper for SearchNearMatcher.
Implementation of near match title search.
getNearMatch( $searchterm)
If an exact title match can be found, or a very slightly close match, return the title.
ILanguageConverter $languageConverter
Current language converter.
Language $language
Current language.
getNearMatchInternal( $searchterm)
Really find the title match.
__construct(Config $config, Language $lang, HookContainer $hookContainer)
SearchNearMatcher constructor.
getNearMatchResultSet( $searchterm)
Do a near match (see SearchEngine::getNearMatch) and wrap it into a ISearchResultSet.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
static isIP( $name)
Does the string match an anonymous IP address?
Definition User.php:951
const NS_USER
Definition Defines.php:72
const NS_FILE
Definition Defines.php:76
const NS_MEDIAWIKI
Definition Defines.php:78
const NS_MEDIA
Definition Defines.php:58
Interface for configuration instances.
Definition Config.php:30
The shared interface for all language converters.
if(!isset( $args[0])) $lang