r35213 MediaWiki - Code Review archive


Article Images
Index: trunk/phase3/RELEASE-NOTES
@@ -45,6 +45,8 @@
4646 displayed on the recent changes special pages.
4747 * The "createpage" permission is no longer required when uploading if the target
4848 image page already exists.
 49+* $wgMaximumMovedPages restricts the number of pages that can be moved at once
 50+ (default 1000) with the new subpage-move functionality of Special:Movepage.
4951
5052 === New features in 1.13 ===
5153
@@ -121,6 +123,7 @@
122124 * AutoAuthenticate hook renamed to UserLoadFromSession
123125 * (bug 13232) importScript(), importStylesheet() funcs available to custom JS
124126 * (bug 13095) Search by first letters or digits in [[Special:Categories]]
 127+* Users moving a page can now move all subpages automatically as well
125128
126129 === Bug fixes in 1.13 ===
127130
Index: trunk/phase3/includes/Title.php
@@ -1503,6 +1503,34 @@
15041504 }
15051505
15061506 /**
 1507+ * Does this have subpages? (Warning, usually requires an extra DB query.)
 1508+ * @return bool
 1509+ */
 1510+ public function hasSubpages() {
 1511+ global $wgNamespacesWithSubpages;
 1512+
 1513+ if( !isset( $wgNamespacesWithSubpages[$this->mNamespace] ) ) {
 1514+ # Duh
 1515+ return false;
 1516+ }
 1517+
 1518+ # We dynamically add a member variable for the purpose of this method
 1519+ # alone to cache the result. There's no point in having it hanging
 1520+ # around uninitialized in every Title object; therefore we only add it
 1521+ # if needed and don't declare it statically.
 1522+ if( isset( $this->mHasSubpages ) ) {
 1523+ return $this->mHasSubpages;
 1524+ }
 1525+
 1526+ $db = wfGetDB( DB_SLAVE );
 1527+ return $this->mHasSubpages = (bool)$db->selectField( 'page', '1',
 1528+ "page_namespace = {$this->mNamespace} AND page_title LIKE '"
 1529+ . $db->escapeLike( $this->mDbkeyform ) . "/%'",
 1530+ __METHOD__
 1531+ );
 1532+ }
 1533+
 1534+ /**
15071535 * Could this page contain custom CSS or JavaScript, based
15081536 * on the title?
15091537 *
Index: trunk/phase3/includes/SpecialMovepage.php
@@ -30,9 +30,7 @@
3131
3232 $f = new MovePageForm( $par );
3333
34 - if ( 'success' == $action ) {
35 - $f->showSuccess();
36 - } else if ( 'submit' == $action && $wgRequest->wasPosted()
 34+ if ( 'submit' == $action && $wgRequest->wasPosted()
3735 && $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
3836 $f->doSubmit();
3937 } else {
@@ -46,7 +44,7 @@
4745 */
4846 class MovePageForm {
4947 var $oldTitle, $newTitle, $reason; # Text input
50 - var $moveTalk, $deleteAndMove;
 48+ var $moveTalk, $deleteAndMove, $moveSubpages;
5149
5250 private $watch = false;
5351
@@ -61,12 +59,13 @@
6260 } else {
6361 $this->moveTalk = $wgRequest->getBool( 'wpMovetalk', true );
6462 }
 63+ $this->moveSubpages = $wgRequest->getBool( 'wpMovesubpages', false );
6564 $this->deleteAndMove = $wgRequest->getBool( 'wpDeleteAndMove' ) && $wgRequest->getBool( 'wpConfirm' );
6665 $this->watch = $wgRequest->getCheck( 'wpWatch' );
6766 }
6867
6968 function showForm( $err, $hookErr = '' ) {
70 - global $wgOut, $wgUser;
 69+ global $wgOut, $wgUser, $wgNamespacesWithSubpages;
7170
7271 $ot = Title::newFromURL( $this->oldTitle );
7372 if( is_null( $ot ) ) {
@@ -180,7 +179,7 @@
181180 </tr>"
182181 );
183182
184 - if ( $considerTalk ) {
 183+ if( $considerTalk ) {
185184 $wgOut->addHTML( "
186185 <tr>
187186 <td></td>
@@ -191,6 +190,26 @@
192191 );
193192 }
194193
 194+ if( $ot->hasSubpages() || $ot->getTalkPage()->hasSubpages() ) {
 195+ $wgOut->addHTML( "
 196+ <tr>
 197+ <td></td>
 198+ <td class=\"mw-input\">" .
 199+ Xml::checkLabel( wfMsgHtml(
 200+ $ot->hasSubpages()
 201+ ? 'move-subpages'
 202+ : 'move-talk-subpages'
 203+ ),
 204+ 'wpMovesubpages', 'wpMovesubpages',
 205+ # Don't check the box if we only have talk subpages to
 206+ # move and we aren't moving the talk page.
 207+ $this->moveSubpages && ($ot->hasSubpages() || $this->moveTalk)
 208+ ) .
 209+ "</td>
 210+ </tr>"
 211+ );
 212+ }
 213+
195214 $watchChecked = $this->watch || $wgUser->getBoolOption( 'watchmoves' ) || $ot->userIsWatching();
196215 $wgOut->addHTML( "
197216 <tr>
@@ -266,79 +285,119 @@
267286
268287 wfRunHooks( 'SpecialMovepageAfterMove', array( &$this , &$ot , &$nt ) ) ;
269288
270 - # Move the talk page if relevant, if it exists, and if we've been told to
271 - $ott = $ot->getTalkPage();
272 - if( $ott->exists() ) {
273 - if( $this->moveTalk && !$ot->isTalkPage() && !$nt->isTalkPage() ) {
274 - $ntt = $nt->getTalkPage();
 289+ $wgOut->setPagetitle( wfMsg( 'pagemovedsub' ) );
275290
276 - # Attempt the move
277 - $error = $ott->moveTo( $ntt, true, $this->reason );
278 - if ( $error === true ) {
279 - $talkmoved = 1;
280 - wfRunHooks( 'SpecialMovepageAfterMove', array( &$this , &$ott , &$ntt ) );
281 - } else {
282 - $talkmoved = $error;
283 - }
 291+ $oldUrl = $ot->getFullUrl( 'redirect=no' );
 292+ $newUrl = $nt->getFullUrl();
 293+ $oldText = $ot->getPrefixedText();
 294+ $newText = $nt->getPrefixedText();
 295+ $oldLink = "<span class='plainlinks'>[$oldUrl $oldText]</span>";
 296+ $newLink = "<span class='plainlinks'>[$newUrl $newText]</span>";
 297+
 298+ $wgOut->addWikiMsg( 'movepage-moved', $oldLink, $newLink, $oldText, $newText );
 299+
 300+ # Now we move extra pages we've been asked to move: subpages and talk
 301+ # pages. First, if the old page or the new page is a talk page, we
 302+ # can't move any talk pages: cancel that.
 303+ if( $ot->isTalkPage() || $nt->isTalkPage() ) {
 304+ $this->moveTalk = false;
 305+ }
 306+
 307+ # Next make a list of id's. This might be marginally less efficient
 308+ # than a more direct method, but this is not a highly performance-cri-
 309+ # tical code path and readable code is more important here.
 310+ #
 311+ # Note: this query works nicely on MySQL 5, but the optimizer in MySQL
 312+ # 4 might get confused. If so, consider rewriting as a UNION.
 313+ $dbr = wfGetDB( DB_SLAVE );
 314+ if( $this->moveSubpages ) {
 315+ $conds = array(
 316+ 'page_title LIKE '.$dbr->addQuotes( $dbr->escapeLike( $ot->getDBkey() ) . '/%' )
 317+ .' OR page_title = ' . $dbr->addQuotes( $ot->getDBkey() )
 318+ );
 319+ if( $this->moveTalk ) {
 320+ $conds['page_namespace'] = array( $ot->getNamespace(),
 321+ MWNamespace::getTalk($ot->getNamespace()) );
284322 } else {
285 - # Stay silent on the subject of talk.
286 - $talkmoved = '';
 323+ $conds['page_namespace'] = $ot->getNamespace();
287324 }
288325 } else {
289 - $talkmoved = 'notalkpage';
 326+ if( $this->moveTalk ) {
 327+ $conds = array(
 328+ 'page_namespace' => MWNamespace::getTalk($ot->getNamespace()),
 329+ 'page_title' => $ot->getDBKey()
 330+ );
 331+ } else {
 332+ # Skip the query
 333+ $conds = null;
 334+ }
290335 }
291336
292 - # Deal with watches
293 - if( $this->watch ) {
294 - $wgUser->addWatch( $ot );
295 - $wgUser->addWatch( $nt );
296 - } else {
297 - $wgUser->removeWatch( $ot );
298 - $wgUser->removeWatch( $nt );
 337+ if( !is_null( $conds ) ) {
 338+ $extrapages = $dbr->select(
 339+ 'page',
 340+ array( 'page_id', 'page_namespace', 'page_title' ),
 341+ $conds,
 342+ __METHOD__
 343+ );
299344 }
300345
301 - # Give back result to user.
302 - $titleObj = SpecialPage::getTitleFor( 'Movepage' );
303 - $success = $titleObj->getFullURL(
304 - 'action=success&oldtitle=' . wfUrlencode( $ot->getPrefixedText() ) .
305 - '&newtitle=' . wfUrlencode( $nt->getPrefixedText() ) .
306 - '&talkmoved='.$talkmoved );
 346+ global $wgMaximumMovedPages, $wgLang;
 347+ $extraOutput = array();
 348+ $skin = $wgUser->getSkin();
 349+ $count = 1;
 350+ foreach( $extrapages as $row ) {
 351+ if( $row->page_id == $ot->getArticleId() ) {
 352+ # Already did this one.
 353+ continue;
 354+ }
307355
308 - $wgOut->redirect( $success );
309 - }
 356+ $oldPage = Title::newFromRow( $row );
 357+ $newPageName = preg_replace(
 358+ '#^'.preg_quote( $ot->getDBKey(), '#' ).'#',
 359+ $nt->getDBKey(),
 360+ $oldPage->getDBKey()
 361+ );
 362+ # The following line is an atrocious hack. Kill it with fire.
 363+ $newNs = $nt->getNamespace() + ($oldPage->getNamespace() & 1);
 364+ $newPage = Title::makeTitle( $newNs, $newPageName );
310365
311 - function showSuccess() {
312 - global $wgOut, $wgRequest, $wgUser;
 366+ # This was copy-pasted from Renameuser, bleh.
 367+ if ( $newPage->exists() && !$oldPage->isValidMoveTarget( $newPage ) ) {
 368+ $link = $skin->makeKnownLinkObj( $newPage );
 369+ $extraOutput []= wfMsgHtml( 'movepage-page-exists', $link );
 370+ } else {
 371+ $success = $oldPage->moveTo( $newPage, true, $this->reason );
 372+ if( $success === true ) {
 373+ $oldLink = $skin->makeKnownLinkObj( $oldPage, '', 'redirect=no' );
 374+ $newLink = $skin->makeKnownLinkObj( $newPage );
 375+ $extraOutput []= wfMsgHtml( 'movepage-page-moved', $oldLink, $newLink );
 376+ } else {
 377+ $oldLink = $skin->makeKnownLinkObj( $oldPage );
 378+ $newLink = $skin->makeLinkObj( $newPage );
 379+ $extraOutput []= wfMsgHtml( 'movepage-page-unmoved', $oldLink, $newLink );
 380+ }
 381+ }
313382
314 - $old = Title::newFromText( $wgRequest->getVal( 'oldtitle' ) );
315 - $new = Title::newFromText( $wgRequest->getVal( 'newtitle' ) );
 383+ ++$count;
 384+ if( $count >= $wgMaximumMovedPages ) {
 385+ $extraOutput []= wfMsgHtml( 'movepage-max-pages', $wgLang->formatNum( $wgMaximumMovedPages ) );
 386+ break;
 387+ }
 388+ }
316389
317 - if( is_null( $old ) || is_null( $new ) ) {
318 - throw new ErrorPageError( 'badtitle', 'badtitletext' );
 390+ if( $extraOutput !== array() ) {
 391+ $wgOut->addHTML( "<ul>\n<li>" . implode( "</li>\n<li>", $extraOutput ) . "</li>\n</ul>" );
319392 }
320393
321 - $wgOut->setPagetitle( wfMsg( 'pagemovedsub' ) );
322 -
323 - $talkmoved = $wgRequest->getVal( 'talkmoved' );
324 - $oldUrl = $old->getFullUrl( 'redirect=no' );
325 - $newUrl = $new->getFullUrl();
326 - $oldText = $old->getPrefixedText();
327 - $newText = $new->getPrefixedText();
328 - $oldLink = "<span class='plainlinks'>[$oldUrl $oldText]</span>";
329 - $newLink = "<span class='plainlinks'>[$newUrl $newText]</span>";
330 -
331 - $s = wfMsgNoTrans( 'movepage-moved', $oldLink, $newLink, $oldText, $newText );
332 -
333 - if ( $talkmoved == 1 ) {
334 - $s .= "\n\n" . wfMsgNoTrans( 'talkpagemoved' );
335 - } elseif( 'articleexists' == $talkmoved ) {
336 - $s .= "\n\n" . wfMsgNoTrans( 'talkexists' );
 394+ # Deal with watches (we don't watch subpages)
 395+ if( $this->watch ) {
 396+ $wgUser->addWatch( $ot );
 397+ $wgUser->addWatch( $nt );
337398 } else {
338 - if( !$old->isTalkPage() && $talkmoved != 'notalkpage' ) {
339 - $s .= "\n\n" . wfMsgNoTrans( 'talkpagenotmoved', wfMsgNoTrans( $talkmoved ) );
340 - }
 399+ $wgUser->removeWatch( $ot );
 400+ $wgUser->removeWatch( $nt );
341401 }
342 - $wgOut->addWikiText( $s );
343402 }
344403
345404 function showLogFragment( $title, &$out ) {
Index: trunk/phase3/includes/DefaultSettings.php
@@ -3159,18 +3159,17 @@
31603160 );
31613161
31623162 /**
3163 - * Hooks that are used for outputting exceptions
3164 - * Format is:
3165 - * $wgExceptionHooks[] = $funcname
 3163+ * Hooks that are used for outputting exceptions. Format is:
 3164+ * $wgExceptionHooks[] = $funcname
31663165 * or:
3167 - * $wgExceptionHooks[] = array( $class, $funcname )
 3166+ * $wgExceptionHooks[] = array( $class, $funcname )
31683167 * Hooks should return strings or false
31693168 */
31703169 $wgExceptionHooks = array();
31713170
31723171 /**
3173 - * Page property link table invalidation lists.
3174 - * Should only be set by extensions.
 3172+ * Page property link table invalidation lists. Should only be set by exten-
 3173+ * sions.
31753174 */
31763175 $wgPagePropLinkInvalidations = array(
31773176 'hiddencat' => 'categorylinks',
@@ -3183,22 +3182,27 @@
31843183 $wgMaxRedirectLinksRetrieved = 500;
31853184
31863185 /**
3187 - * Maximum number of calls to expensive parser functions
3188 - * such as PAGESINCATEGORY.
 3186+ * Maximum number of calls per parse to expensive parser functions such as
 3187+ * PAGESINCATEGORY.
31893188 */
31903189 $wgExpensiveParserFunctionLimit = 100;
31913190
31923191 /**
 3192+ * Maximum number of pages to move at once when moving subpages with a page.
 3193+ */
 3194+$wgMaximumMovedPages = 1000;
 3195+
 3196+/**
31933197 * Array of namespaces to generate a sitemap for when the
3194 - * maintenance/generateSitemap.php script is run, or false
3195 - * if one is to be generated for all namespaces.
 3198+ * maintenance/generateSitemap.php script is run, or false if one is to be ge-
 3199+ * nerated for all namespaces.
31963200 */
31973201 $wgSitemapNamespaces = false;
31983202
31993203
32003204 /**
3201 - * If user doesn't specify any edit summary when making a an edit,
3202 - * MediaWiki will try to automatically create one. This feature can
3203 - * be disabled by setting this variable false.
 3205+ * If user doesn't specify any edit summary when making a an edit, MediaWiki
 3206+ * will try to automatically create one. This feature can be disabled by set-
 3207+ * ting this variable false.
32043208 */
3205 -$wgUseAutomaticEditSummaries = true;
\ No newline at end of file
 3209+$wgUseAutomaticEditSummaries = true;
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -2426,8 +2426,12 @@
24272427 Please merge them manually.'''",
24282428 'movedto' => 'moved to',
24292429 'movetalk' => 'Move associated talk page',
2430 -'talkpagemoved' => 'The corresponding talk page was also moved.',
2431 -'talkpagenotmoved' => 'The corresponding talk page was <strong>not</strong> moved.',
 2430+'move-subpages' => 'Move all subpages, if applicable',
 2431+'move-talk-subpages' => 'Move all subpages of talk page, if applicable',
 2432+'movepage-page-exists' => 'The page $1 already exists and cannot be automatically overwritten.',
 2433+'movepage-page-moved' => 'The page $1 has been moved to $2.',
 2434+'movepage-page-unmoved' => 'The page $1 could not be moved to $2.',
 2435+'movepage-max-pages' => 'The maximum of $1 pages has been moved and no more will be moved automatically.',
24322436 '1movedto2' => '[[$1]] moved to [[$2]]',
24332437 '1movedto2_redir' => '[[$1]] moved to [[$2]] over redirect',
24342438 'movelogpage' => 'Move log',
Index: trunk/phase3/maintenance/language/messages.inc
@@ -1659,8 +1659,12 @@
16601660 'talkexists',
16611661 'movedto',
16621662 'movetalk',
1663 - 'talkpagemoved',
1664 - 'talkpagenotmoved',
 1663+ 'move-subpages',
 1664+ 'move-talk-subpages',
 1665+ 'movepage-page-exists',
 1666+ 'movepage-page-unmoved',
 1667+ 'movepage-page-moved',
 1668+ 'movepage-max-pages',
16651669 '1movedto2',
16661670 '1movedto2_redir',
16671671 'movelogpage',