Make redirect update in refreshLinks.php bypass the redirect table
authorAlexandre Emsenhuber <ialex.wiki@gmail.com>
Thu, 17 Jan 2013 09:51:35 +0000 (10:51 +0100)
committerAlexandre Emsenhuber <ialex.wiki@gmail.com>
Thu, 17 Jan 2013 09:51:35 +0000 (10:51 +0100)
This makes this script actually useful when updating namespaces by
making sure the target registred in the "redirect" is the correct one.

Consider the following example:

- Create a redirect page pointing to a page "Extra:Target"
- Add $wgExtraNamespaces[100] = 'Extra'; in LocalSettings.php
- run refreshLinks.php

Previously the redirect target of that page was not updated and still
pointing to (0, "Extra:Target") which no longer a valid title.
Now it will be updated correctly to point to (100, "Target").

The value of the page_is_redirect field will also be updated to be
sure it has the correct value, which might be wrong when the target
becomes valid or invalid, e.g. by changing $wgInvalidRedirectTargets.

Change-Id: I458ca63550df56ca96b35749daf4e7b866ab9d93

maintenance/refreshLinks.php

index fe03f51..7b25566 100644 (file)
@@ -176,8 +176,16 @@ class RefreshLinks extends Maintenance {
        }
 
        /**
-        * Update the redirect entry for a given page
-        * @param $id int The page_id of the redirect
+        * Update the redirect entry for a given page.
+        *
+        * This methods bypasses the "redirect" table to get the redirect target,
+        * and parses the page's content to fetch it. This allows to be sure that
+        * the redirect target is up to date and valid.
+        * This is particularly useful when modifying namespaces to be sure the
+        * entry in the "redirect" table points to the correct page and not to an
+        * invalid one.
+        *
+        * @param $id int The page ID to check
         */
        private function fixRedirect( $id ) {
                $page = WikiPage::newFromID( $id );
@@ -191,14 +199,25 @@ class RefreshLinks extends Maintenance {
                        return;
                }
 
-               $rt = $page->getRedirectTarget();
+               $rt = null;
+               $content = $page->getContent( Revision::RAW );
+               if ( $content !== null ) {
+                       $rt = $content->getUltimateRedirectTarget();
+               }
 
                if ( $rt === null ) {
                        // The page is not a redirect
                        // Delete any redirect table entry for it
-                       $dbw->delete( 'redirect', array( 'rd_from' => $id ),
-                               __METHOD__ );
+                       $dbw->delete( 'redirect', array( 'rd_from' => $id ), __METHOD__ );
+                       $fieldValue = 0;
+               } else {
+                       $page->insertRedirectEntry( $rt );
+                       $fieldValue = 1;
                }
+
+               // Update the page table to be sure it is an a consistent state
+               $dbw->update( 'page', array( 'page_is_redirect' => $fieldValue ),
+                       array( 'page_id' => $id ), __METHOD__ );
        }
 
        /**