In case anyone's interested, I solved this myself using this (probably absolutely horrible) piece of PHP code.
class clsURL {
static function checkURL() {
// don't allow requests on old style URL's
if (($_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING']) == $_SERVER['REQUEST_URI'] &&
$_SERVER['REQUEST_METHOD'] != 'POST') {
// redirect to new style URL
$redirectTable = self::createReverseTable();
$currentURL = $_SERVER['REQUEST_URI'];
if (substr($currentURL, 0, 1) == "/")
$currentURL = substr($currentURL, 1);
$newURL = self::getReverseURL($currentURL, $redirectTable);
if ($newURL) {
header ('HTTP/1.1 301 Moved Permanently');
header ('Location: /' . $newURL);
exit;
}
}
}
static function getReverseURL($current, $reverseTable) {
// filter out some common stuff
$current = preg_replace("/&mid=[0-9]+/", "", $current);
foreach ($reverseTable as $pair) {
if (preg_match("|" . $pair['from'] . "|", $current)) {
return preg_replace("|" . $pair['from'] . "|", $pair['to'], $current);
}
}
// nothing found
return false;
}
static function createReverseTable() {
$file = fopen('.htaccess', 'r');
$reverse = array();
while ($line = fgets($file)) {
if (stripos($line, 'RewriteRule') === 0) {
$parts = preg_split("/[\\s\\t]/", $line, 3, PREG_SPLIT_NO_EMPTY);
$regex = trim($parts[1]);
$url = trim($parts[2]);
$parts[2] = $url;
$matches = array();
if (preg_match_all("/\\$[0-9]/", $url, $matches)) {
$matches = $matches[0]; // why? don't know.
$from = str_replace('?', '\\?', $url);
$to = $regex;
foreach ($matches as $match) {
$index = substr($match, 1);
$bracket = 0;
for ($i = 0; $i < strlen($regex); ++$i) {
if (substr($regex, $i, 1) == "(") {
$bracket++;
if ($bracket == $index) {
$pattern = "";
$j = $i + 1;
while (substr($regex, $j, 1) != ")") {
$pattern .= substr($regex, $j, 1);
$j++;
}
$from = str_replace('$' . $index, '(' . $pattern . ')', $from);
$to = preg_replace('/\\(' . preg_quote($pattern, '/') . '\\)/', '\\$' . $index, $to, 1);
}
}
}
}
// remove optional stuff that we don't use
$to = str_replace('(-(.*))?', '', $to);
// remove ^ and (/)?$
$to = substr($to, 1);
if (substr($to, -5) == '(/)?$')
$to = substr($to, 0, strlen($to) - 5);
$from = '^' . $from . '$';
// index.php is optional
$from = str_replace('index.php', '(?:index\\.php)?', $from);
$reverse[] = array(
'from' => $from,
'to' => $to
);
} else {
$from = str_replace('?', '\\?', $url);
$to = $regex;
// remove ^ and (/)?$
$to = substr($to, 1);
if (substr($to, -5) == '(/)?$')
$to = substr($to, 0, strlen($to) - 5);
$from = '^' . $from . '$';
// index.php is optional
$from = str_replace('index.php', '(?:index\\.php)?', $from);
$reverse[] = array(
'from' => $from,
'to' => $to
);
}
}
}
fclose($file);
return $reverse;
}
}