Index: trunk/phase3/includes/search/SearchMySQL.php |
— | — | @@ -56,7 +56,7 @@ |
57 | 57 | $filteredText, $m, PREG_SET_ORDER ) ) { |
58 | 58 | foreach( $m as $bits ) { |
59 | 59 | @list( /* all */, $modifier, $term, $nonQuoted, $wildcard ) = $bits; |
60 | | - |
| 60 | + |
61 | 61 | if( $nonQuoted != '' ) { |
62 | 62 | $term = $nonQuoted; |
63 | 63 | $quote = ''; |
— | — | @@ -64,13 +64,13 @@ |
65 | 65 | $term = str_replace( '"', '', $term ); |
66 | 66 | $quote = '"'; |
67 | 67 | } |
68 | | - |
| 68 | + |
69 | 69 | if( $searchon !== '' ) $searchon .= ' '; |
70 | 70 | if( $this->strictMatching && ($modifier == '') ) { |
71 | 71 | // If we leave this out, boolean op defaults to OR which is rarely helpful. |
72 | 72 | $modifier = '+'; |
73 | 73 | } |
74 | | - |
| 74 | + |
75 | 75 | // Some languages such as Serbian store the input form in the search index, |
76 | 76 | // so we may need to search for matches in multiple writing system variants. |
77 | 77 | $convertedVariants = $wgContLang->autoConvertToAllVariants( $term ); |
— | — | @@ -79,7 +79,7 @@ |
80 | 80 | } else { |
81 | 81 | $variants = array( $term ); |
82 | 82 | } |
83 | | - |
| 83 | + |
84 | 84 | // The low-level search index does some processing on input to work |
85 | 85 | // around problems with minimum lengths and encoding in MySQL's |
86 | 86 | // fulltext engine. |
— | — | @@ -87,12 +87,12 @@ |
88 | 88 | $strippedVariants = array_map( |
89 | 89 | array( $wgContLang, 'normalizeForSearch' ), |
90 | 90 | $variants ); |
91 | | - |
| 91 | + |
92 | 92 | // Some languages such as Chinese force all variants to a canonical |
93 | 93 | // form when stripping to the low-level search index, so to be sure |
94 | 94 | // let's check our variants list for unique items after stripping. |
95 | 95 | $strippedVariants = array_unique( $strippedVariants ); |
96 | | - |
| 96 | + |
97 | 97 | $searchon .= $modifier; |
98 | 98 | if( count( $strippedVariants) > 1 ) |
99 | 99 | $searchon .= '('; |
— | — | @@ -108,7 +108,7 @@ |
109 | 109 | } |
110 | 110 | if( count( $strippedVariants) > 1 ) |
111 | 111 | $searchon .= ')'; |
112 | | - |
| 112 | + |
113 | 113 | // Match individual terms or quoted phrase in result highlighting... |
114 | 114 | // Note that variants will be introduced in a later stage for highlighting! |
115 | 115 | $regexp = $this->regexTerm( $term, $wildcard ); |
— | — | @@ -124,10 +124,10 @@ |
125 | 125 | $field = $this->getIndexField( $fulltext ); |
126 | 126 | return " MATCH($field) AGAINST('$searchon' IN BOOLEAN MODE) "; |
127 | 127 | } |
128 | | - |
| 128 | + |
129 | 129 | function regexTerm( $string, $wildcard ) { |
130 | 130 | global $wgContLang; |
131 | | - |
| 131 | + |
132 | 132 | $regex = preg_quote( $string, '/' ); |
133 | 133 | if( $wgContLang->hasWordBreaks() ) { |
134 | 134 | if( $wildcard ) { |
— | — | @@ -167,13 +167,13 @@ |
168 | 168 | function searchTitle( $term ) { |
169 | 169 | return $this->searchInternal( $term, false ); |
170 | 170 | } |
171 | | - |
| 171 | + |
172 | 172 | protected function searchInternal( $term, $fulltext ) { |
173 | 173 | global $wgCountTotalSearchHits; |
174 | | - |
| 174 | + |
175 | 175 | $filteredTerm = $this->filter( $term ); |
176 | 176 | $resultSet = $this->db->query( $this->getQuery( $filteredTerm, $fulltext ) ); |
177 | | - |
| 177 | + |
178 | 178 | $total = null; |
179 | 179 | if( $wgCountTotalSearchHits ) { |
180 | 180 | $totalResult = $this->db->query( $this->getCountQuery( $filteredTerm, $fulltext ) ); |
— | — | @@ -183,7 +183,7 @@ |
184 | 184 | } |
185 | 185 | $totalResult->free(); |
186 | 186 | } |
187 | | - |
| 187 | + |
188 | 188 | return new MySQLSearchResultSet( $resultSet, $this->searchTerms, $total ); |
189 | 189 | } |
190 | 190 | |
— | — | @@ -239,13 +239,26 @@ |
240 | 240 | * @param $fulltext Boolean |
241 | 241 | */ |
242 | 242 | function getQuery( $filteredTerm, $fulltext ) { |
243 | | - return $this->queryMain( $filteredTerm, $fulltext ) . ' ' . |
244 | | - 'AND ' . $this->queryRedirect() . ' ' . |
245 | | - 'AND ' . $this->queryNamespaces() . ' ' . |
246 | | - $this->queryRanking( $filteredTerm, $fulltext ) . ' ' . |
| 243 | + $query = $this->queryMain( $filteredTerm, $fulltext ) . ' '; |
| 244 | + |
| 245 | + $redir = $this->queryRedirect(); |
| 246 | + |
| 247 | + if ( $redir ) { |
| 248 | + $query .= 'AND ' . $redir . ' '; |
| 249 | + } |
| 250 | + |
| 251 | + $namespace = $this->queryNamespaces(); |
| 252 | + |
| 253 | + if ( $namespace ) { |
| 254 | + $query .= 'AND ' . $namespace . ' '; |
| 255 | + } |
| 256 | + |
| 257 | + $query .= $this->queryRanking( $filteredTerm, $fulltext ) . ' ' . |
247 | 258 | $this->queryLimit(); |
| 259 | + |
| 260 | + return $query; |
248 | 261 | } |
249 | | - |
| 262 | + |
250 | 263 | /** |
251 | 264 | * Picks which field to index on, depending on what type of query. |
252 | 265 | * @param $fulltext Boolean |
— | — | @@ -271,7 +284,7 @@ |
272 | 285 | $searchindex = $this->db->tableName( 'searchindex' ); |
273 | 286 | return 'SELECT page_id, page_namespace, page_title ' . |
274 | 287 | "FROM $page,$searchindex " . |
275 | | - 'WHERE page_id=si_page AND ' . $match; |
| 288 | + 'WHERE page_id=si_page ' . $match; |
276 | 289 | } |
277 | 290 | |
278 | 291 | function getCountQuery( $filteredTerm, $fulltext ) { |
— | — | @@ -315,7 +328,7 @@ |
316 | 329 | * @param $id Integer |
317 | 330 | * @param $title String |
318 | 331 | */ |
319 | | - function updateTitle( $id, $title ) { |
| 332 | + function updateTitle( $id, $title ) { |
320 | 333 | $dbw = wfGetDB( DB_MASTER ); |
321 | 334 | |
322 | 335 | $dbw->update( 'searchindex', |
— | — | @@ -333,7 +346,7 @@ |
334 | 347 | global $wgContLang; |
335 | 348 | |
336 | 349 | wfProfileIn( __METHOD__ ); |
337 | | - |
| 350 | + |
338 | 351 | $out = parent::normalizeText( $string ); |
339 | 352 | |
340 | 353 | // MySQL fulltext index doesn't grok utf-8, so we |
— | — | @@ -367,7 +380,7 @@ |
368 | 381 | $out ); |
369 | 382 | |
370 | 383 | wfProfileOut( __METHOD__ ); |
371 | | - |
| 384 | + |
372 | 385 | return $out; |
373 | 386 | } |
374 | 387 | |