Index: trunk/extensions/ReplaceText/SpecialReplaceText.php |
— | — | @@ -48,6 +48,18 @@ |
49 | 49 | $wgOut->addHTML( Xml::closeElement( 'form' ) ); |
50 | 50 | } |
51 | 51 | |
| 52 | + static function getSelectedNamespaces() { |
| 53 | + global $wgRequest; |
| 54 | + $all_namespaces = SearchEngine::searchableNamespaces(); |
| 55 | + $selected_namespaces = array(); |
| 56 | + foreach ($all_namespaces as $ns => $name) { |
| 57 | + if ($wgRequest->getCheck('ns' . $ns)) { |
| 58 | + $selected_namespaces[] = $ns; |
| 59 | + } |
| 60 | + } |
| 61 | + return $selected_namespaces; |
| 62 | + } |
| 63 | + |
52 | 64 | function doSpecialReplaceText() { |
53 | 65 | global $wgUser, $wgOut, $wgRequest, $wgLang; |
54 | 66 | |
— | — | @@ -81,11 +93,13 @@ |
82 | 94 | $jobs = array(); |
83 | 95 | foreach ( $wgRequest->getValues() as $key => $value ) { |
84 | 96 | if ( $value == '1' ) { |
85 | | - if ( strpos( $key, 'move-' ) !== false ) { |
86 | | - $title = Title::newFromId( substr( $key, 5 ) ); |
| 97 | + if ($key === 'replace') { |
| 98 | + // ignore this value |
| 99 | + } elseif ( strpos( $key, 'move-' ) !== false ) { |
| 100 | + $title = Title::newFromID( substr( $key, 5 ) ); |
87 | 101 | $replacement_params['move_page'] = true; |
88 | 102 | } else { |
89 | | - $title = Title::newFromId( $key ); |
| 103 | + $title = Title::newFromID( $key ); |
90 | 104 | } |
91 | 105 | if ( $title !== null ) |
92 | 106 | $jobs[] = new ReplaceTextJob( $title, $replacement_params ); |
— | — | @@ -126,13 +140,15 @@ |
127 | 141 | if ( $this->replacement === '' ) { |
128 | 142 | $message = 'replacetext_blankwarning'; |
129 | 143 | } elseif ( $this->edit_pages ) { |
130 | | - $res = $this->doSearchQuery( $this->replacement ); |
| 144 | + $selected_namespaces = self::getSelectedNamespaces(); |
| 145 | + $res = $this->doSearchQuery( $this->replacement, $selected_namespaces ); |
131 | 146 | $count = $res->numRows(); |
132 | 147 | if ( $count > 0 ) { |
133 | 148 | $message = array( 'replacetext_warning', $wgLang->formatNum( $count ), $this->replacement ); |
134 | 149 | } |
135 | 150 | } elseif ( $this->move_pages ) { |
136 | | - $res = $this->getMatchingTitles( $this->replacement ); |
| 151 | + $selected_namespaces = self::getSelectedNamespaces(); |
| 152 | + $res = $this->getMatchingTitles( $this->replacement, $selected_namespaces ); |
137 | 153 | $count = $res->numRows(); |
138 | 154 | if ( $count > 0 ) { |
139 | 155 | $message = array( 'replacetext_warning', $wgLang->formatNum( $count ), $this->replacement ); |
— | — | @@ -147,7 +163,8 @@ |
148 | 164 | |
149 | 165 | // if user is replacing text within pages... |
150 | 166 | if ( $this->edit_pages ) { |
151 | | - $res = $this->doSearchQuery( $this->target ); |
| 167 | + $selected_namespaces = self::getSelectedNamespaces(); |
| 168 | + $res = $this->doSearchQuery( $this->target, $selected_namespaces ); |
152 | 169 | foreach ( $res as $row ) { |
153 | 170 | $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); |
154 | 171 | $context = $this->extractContext( $row->old_text, $this->target ); |
— | — | @@ -155,7 +172,8 @@ |
156 | 173 | } |
157 | 174 | } |
158 | 175 | if ( $this->move_pages ) { |
159 | | - $res = $this->getMatchingTitles( $this->target ); |
| 176 | + $selected_namespaces = self::getSelectedNamespaces(); |
| 177 | + $res = $this->getMatchingTitles( $this->target, $selected_namespaces ); |
160 | 178 | foreach ( $res as $row ) { |
161 | 179 | $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); |
162 | 180 | // see if this move can happen |
— | — | @@ -208,6 +226,11 @@ |
209 | 227 | $wgOut->addHTML( Xml::textarea( 'replacement', $this->replacement, 50, 2 ) ); |
210 | 228 | $wgOut->addHTML( Xml::closeElement( 'textarea' ) ); |
211 | 229 | $wgOut->addHTML( '</td></tr></table>' ); |
| 230 | + |
| 231 | + $search_label = wfMsg('powersearch-ns'); |
| 232 | + $namespaces = SearchEngine::searchableNamespaces(); |
| 233 | + $tables = $this->namespaceTables( $namespaces ); |
| 234 | + $wgOut->addHTML( "<fieldset>\n<p>$search_label</p\n>$tables\n</fieldset>" ); |
212 | 235 | $wgOut->addHTML( |
213 | 236 | Xml::checkLabel( wfMsg( 'replacetext_editpages' ), 'edit_pages', 'edit_pages', true ) . '<br />' . |
214 | 237 | Xml::checkLabel( wfMsg( 'replacetext_movepages' ), 'move_pages', 'move_pages' ) . '<br /><br />' . |
— | — | @@ -216,6 +239,48 @@ |
217 | 240 | ); |
218 | 241 | } |
219 | 242 | |
| 243 | + /** |
| 244 | + * Copied almost exactly from MediaWiki's SpecialSearch class, i.e. |
| 245 | + * the search page |
| 246 | + */ |
| 247 | + function namespaceTables( $namespaces, $rowsPerTable = 3 ) { |
| 248 | + global $wgContLang; |
| 249 | + // Group namespaces into rows according to subject. |
| 250 | + // Try not to make too many assumptions about namespace numbering. |
| 251 | + $rows = array(); |
| 252 | + $tables = ""; |
| 253 | + foreach( $namespaces as $ns => $name ) { |
| 254 | + $subj = MWNamespace::getSubject( $ns ); |
| 255 | + if( !array_key_exists( $subj, $rows ) ) { |
| 256 | + $rows[$subj] = ""; |
| 257 | + } |
| 258 | + $name = str_replace( '_', ' ', $name ); |
| 259 | + if( '' == $name ) { |
| 260 | + $name = wfMsg( 'blanknamespace' ); |
| 261 | + } |
| 262 | + $rows[$subj] .= Xml::openElement( 'td', array( 'style' => 'white-space: nowrap' ) ) . |
| 263 | + Xml::checkLabel( $name, "ns{$ns}", "mw-search-ns{$ns}", in_array( $ns, $namespaces ) ) . |
| 264 | + Xml::closeElement( 'td' ) . "\n"; |
| 265 | + } |
| 266 | + $rows = array_values( $rows ); |
| 267 | + $numRows = count( $rows ); |
| 268 | + // Lay out namespaces in multiple floating two-column tables so they'll |
| 269 | + // be arranged nicely while still accommodating different screen widths |
| 270 | + // Float to the right on RTL wikis |
| 271 | + $tableStyle = $wgContLang->isRTL() ? |
| 272 | + 'float: right; margin: 0 0 0em 1em' : 'float: left; margin: 0 1em 0em 0'; |
| 273 | + // Build the final HTML table... |
| 274 | + for( $i = 0; $i < $numRows; $i += $rowsPerTable ) { |
| 275 | + $tables .= Xml::openElement( 'table', array( 'style' => $tableStyle ) ); |
| 276 | + for( $j = $i; $j < $i + $rowsPerTable && $j < $numRows; $j++ ) { |
| 277 | + $tables .= "<tr>\n" . $rows[$j] . "</tr>"; |
| 278 | + } |
| 279 | + $tables .= Xml::closeElement( 'table' ) . "\n"; |
| 280 | + } |
| 281 | + return $tables; |
| 282 | + } |
| 283 | + |
| 284 | + |
220 | 285 | function pageListForm( $titles_for_edit, $titles_for_move, $unmoveable_titles ) { |
221 | 286 | global $wgOut, $wgLang, $wgScript; |
222 | 287 | |
— | — | @@ -306,7 +371,7 @@ |
307 | 372 | |
308 | 373 | // Get all indexes |
309 | 374 | $targetq = preg_quote( $target, '/' ); |
310 | | - preg_match_all( "/$targetq/i", $text, $matches, PREG_OFFSET_CAPTURE ); |
| 375 | + preg_match_all( "/$targetq/", $text, $matches, PREG_OFFSET_CAPTURE ); |
311 | 376 | |
312 | 377 | $poss = array(); |
313 | 378 | foreach ( $matches[0] as $_ ) { |
— | — | @@ -352,34 +417,35 @@ |
353 | 418 | return $msg; |
354 | 419 | } |
355 | 420 | |
356 | | - function getMatchingTitles( $str) { |
| 421 | + function getMatchingTitles( $str, $namespaces ) { |
357 | 422 | $title = Title::newFromText( $str ); |
358 | 423 | if ( !$title ) return array(); |
359 | 424 | |
360 | 425 | $dbr = wfGetDB( DB_SLAVE ); |
361 | 426 | $sql_str = $dbr->escapeLike( $title->getDbKey() ); |
| 427 | + $include_ns = $dbr->makeList( $namespaces ); |
362 | 428 | |
363 | 429 | return $dbr->select( |
364 | 430 | 'page', |
365 | 431 | array( 'page_title', 'page_namespace' ), |
366 | | - "page_title like '%$sql_str%'", |
| 432 | + "page_title LIKE '%$sql_str%' AND page_namespace IN ($include_ns)", |
367 | 433 | __METHOD__, |
368 | 434 | array( 'ORDER BY' => 'page_namespace, page_title' ) |
369 | 435 | ); |
370 | 436 | } |
371 | 437 | |
372 | | - function doSearchQuery( $search ) { |
| 438 | + function doSearchQuery( $search, $namespaces ) { |
373 | 439 | $dbr = wfGetDB( DB_SLAVE ); |
374 | 440 | |
375 | 441 | $search = $dbr->escapeLike( $search ); |
376 | 442 | $search = str_replace(array("\\", "'"), array("\\\\", "\'"), $search); |
377 | | - $exemptNS = $dbr->makeList( array( NS_TALK, NS_USER_TALK ) ); |
| 443 | + $include_ns = $dbr->makeList( $namespaces ); |
378 | 444 | |
379 | 445 | $tables = array( 'page', 'revision', 'text' ); |
380 | 446 | $vars = array( 'page_id', 'page_namespace', 'page_title', 'old_text' ); |
381 | 447 | $conds = array( |
382 | 448 | "old_text like '%$search%'", |
383 | | - "page_namespace not in ($exemptNS)", |
| 449 | + "page_namespace in ($include_ns)", |
384 | 450 | 'rev_id = page_latest', |
385 | 451 | 'rev_text_id = old_id' |
386 | 452 | ); |