The Replace_Text extension was unsuccessful, so I ended writing my own script that uses the MediaWiki API.
I started with the loginscript from here and wrote this script:
#!/usr/bin/php
<?php
$settings['wikiroot'] = "https://server/mediawiki";
$settings['user'] = "username";
$settings['pass'] = "password";
// $settings['domain'] = 'Windows';
$settings['cookiefile'] = "cookies.tmp";
$prepend = "{{migration_pending}}\n\n";
function httpRequest($url, $post="") {
global $settings;
$ch = curl_init();
//Change the user agent below suitably
curl_setopt($ch, CURLOPT_USERAGENT, 'MediaWiki Migration Script 0.1');
curl_setopt($ch, CURLOPT_URL, ($url));
curl_setopt($ch, CURLOPT_ENCODING, "UTF-8" );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, $settings['cookiefile']);
curl_setopt($ch, CURLOPT_COOKIEJAR, $settings['cookiefile']);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
if (!empty($post)) curl_setopt($ch,CURLOPT_POSTFIELDS,$post);
//UNCOMMENT TO DEBUG TO output.tmp
//curl_setopt($ch, CURLOPT_VERBOSE, true); // Display communication with server
//$fp = fopen("output.tmp", "w");
//curl_setopt($ch, CURLOPT_STDERR, $fp); // Display communication with server
$xml = curl_exec($ch);
if (!$xml) {
throw new Exception("Error getting data from server ($url): " . curl_error($ch));
}
//var_dump($xml);
curl_close($ch);
return $xml;
}
function login ($user, $pass, $token='') {
global $settings;
$url = $settings['wikiroot'] . "/api.php?action=login&format=xml";
$params = "action=login&lgname=$user&lgpassword=$pass";
if (!empty($settings['domain'])) {
$params .= "&lgdomain=" . $settings['domain'];
}
if (!empty($token)) {
$params .= "&lgtoken=$token";
}
$data = httpRequest($url, $params);
if (empty($data)) {
throw new Exception("No data received from server. Check that API is enabled.");
}
$xml = simplexml_load_string($data);
if (!empty($token)) {
//Check for successful login
$expr = "/api/login[@result='Success']";
$result = $xml->xpath($expr);
if(!count($result)) {
throw new Exception("Login failed");
}
} else {
$expr = "/api/login[@token]";
$result = $xml->xpath($expr);
if(!count($result)) {
throw new Exception("Login token not found in XML");
}
}
return $result[0]->attributes()->token;
}
try {
global $settings;
$token = login($settings['user'], $settings['pass']);
login($settings['user'], $settings['pass'], $token);
$star = "*";
$dash1 = "-1";
// get edit token
$result = httpRequest($settings['wikiroot'] . "/api.php?action=query&format=json&prop=info|revisions&intoken=edit&titles=Main%20Page");
$result = json_decode($result);
$editToken = $result->query->pages->$dash1->edittoken;
// only from namespace: apnamespace=100
$result = httpRequest($settings['wikiroot'] . "/api.php?action=query&list=allpages&format=json&aplimit=5000&apnamespace=100");
$result = json_decode($result);
$allpages = $result->query->allpages;
foreach ($allpages as $page) {
echo "Fetching '{$page->title}' ({$page->pageid})...\n";
$revisions = httpRequest(sprintf($settings['wikiroot'] . "/api.php?action=query&prop=revisions&rvlimit=1&format=json&rvprop=content&titles=%s", urlencode($page->title)));
$revisions = json_decode($revisions);
if (isset($revisions->error)) {
echo "ERROR: " . $revisions->error->info . "\n";
continue;
}
$content = $revisions->query->pages->{$page->pageid}->revisions[0]->$star;
if (preg_match("/\{\{migration_/", $content)) {
echo "Already marked ... skipping.\n";
continue;
}
echo "Updating...";
// add text to content and edit page
$content = $prepend . $content;
$post = sprintf("title=%s&text=%s&token=%s", urlencode($page->title), urlencode($content), urlencode($editToken));
$result = httpRequest($settings['wikiroot'] . "/api.php?action=edit&format=json", $post);
echo "done\n";
}
echo ("Finished (".sizeof($allpages)." pages).\n");
} catch (Exception $e) {
die("FAILED: " . $e->getMessage());
}
?>
What the script basically does is:
- Log in with an existing account
- get a token that allows it to do edit operations
- retrieve a list of all pages within a given namespace
- for every page:
- get the content from the latest revision
- add a predefined text to the content
- save the page with the new content
Some additional notes:
- Make sure the user you want to use exists and has write access to all needed namespaces.
- Add the user to the "Bot" group. This will remove some restrictions, for example a bot is allowed to do bulk operations in groups of 5000 instead of 500 like a normal user. Not sure if it is necessary for this script, but it can't hurt.
- When an authentication extension like LdapAuthentication is in use the
domain
parameter has to be set. And it has to be set to the name of the LDAP source how it is configured in LocalSettings.php
, not the actual name of the domain.
- Disable email notifications before you run the script. Otherwise everyone who watches pages in the wiki will get notifications for every changed page he watches. For me this was
$wgEnableEmail = false;
and $wgEnotifWatchlist = false;
in LocalSettings.php
.
- I ran the script from the command line, it isn't fast and takes a couple of minutes for more than 1000 pages. It would definitely run into a timeout if I ran it over the webserver.
Last, but not least, the template migration_pending
I added to MediaWiki:
{|class=warningbox
| [[Image:Emblem-important.png]]
| This page hasn't been audited yet, the information on it could be outdated. If you are responsible for this page, please check it's content. If it is still current, add it to the new wiki and change this template to <nowiki>{{Migration_done}}</nowiki>. If the information on this page is not needed anymore change the template to <nowiki>{{Migration_discarded}}</nowiki>
|}
[[Category:MigrationPending]]
This uses a CSS class for tables we had been using before and adds the page to a specific category. I added similar templates as migration_done
and migration_discarded
with the corresponding categories.