From a1fb3b5306354c011bfbc22f9cef75c874a97f56 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 1 Jun 2005 02:31:45 +0000 Subject: [PATCH 01/16] * (bug 2275) Update search index more or less right on page move --- RELEASE-NOTES | 1 + docs/hooks.txt | 4 ++-- includes/SearchUpdate.php | 2 +- includes/Title.php | 12 +++++++----- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index ab9c2f7f2c..30d06b2659 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -232,6 +232,7 @@ Various bugfixes, small features, and a few experimental things: that does both numeric and named chars: Sanitizer::decodeCharReferences * Removed some obsolete UTF-8 converter functions * Fix function comment in debug dump of SQL statements +* (bug 2275) Update search index more or less right on page move === Caveats === diff --git a/docs/hooks.txt b/docs/hooks.txt index c64425b378..ecf6ca1226 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -303,8 +303,8 @@ $text: text of the mail $old: old title $nt: new title $user: user who did the move -$oldid: old article database ID -$newid: new article database ID +$pageid: database ID of the page that's been moved +$redirid: database ID of the created redirect 'UnknownAction': An unknown "action" has occured (useful for defining your own actions) diff --git a/includes/SearchUpdate.php b/includes/SearchUpdate.php index be7a4c41b6..dc383fe188 100644 --- a/includes/SearchUpdate.php +++ b/includes/SearchUpdate.php @@ -41,7 +41,7 @@ class SearchUpdate { $search =& SearchEngine::create(); $lc = $search->legalSearchChars() . '&#;'; - if( $this->mText == false ) { + if( $this->mText === false ) { $search->updateTitle($this->mId, Title::indexTitle( $this->mNamespace, $this->mTitle )); wfProfileOut( $fname ); diff --git a/includes/Title.php b/includes/Title.php index e2c527e659..0bc30afc3e 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -1532,18 +1532,20 @@ class Title { if( is_string( $err ) ) { return $err; } + + $pageid = $this->getArticleID(); if( $nt->exists() ) { $this->moveOverExistingRedirect( $nt, $reason ); } else { # Target didn't exist, do normal move. $this->moveToNewTitle( $nt, $newid, $reason ); } + $redirid = $this->getArticleID(); # Fixing category links (those without piped 'alternate' names) to be sorted under the new title - $dbw =& wfGetDB( DB_MASTER ); $categorylinks = $dbw->tableName( 'categorylinks' ); $sql = "UPDATE $categorylinks SET cl_sortkey=" . $dbw->addQuotes( $nt->getPrefixedText() ) . - " WHERE cl_from=" . $dbw->addQuotes( $this->getArticleID() ) . + " WHERE cl_from=" . $dbw->addQuotes( $pageid ) . " AND cl_sortkey=" . $dbw->addQuotes( $this->getPrefixedText() ); $dbw->query( $sql, 'SpecialMovepage::doSubmit' ); @@ -1559,12 +1561,12 @@ class Title { } # Update search engine - $u = new SearchUpdate( $oldid, $nt->getPrefixedDBkey() ); + $u = new SearchUpdate( $pageid, $nt->getPrefixedDBkey() ); $u->doUpdate(); - $u = new SearchUpdate( $newid, $this->getPrefixedDBkey(), '' ); + $u = new SearchUpdate( $redirid, $this->getPrefixedDBkey(), '' ); $u->doUpdate(); - wfRunHooks( 'TitleMoveComplete', array(&$this, &$nt, &$wgUser, $oldid, $newid) ); + wfRunHooks( 'TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid ) ); return true; } -- 2.20.1 From 5e202cd3239e7ede9ec1e2b1ccc1876e00ef6e51 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 1 Jun 2005 05:59:43 +0000 Subject: [PATCH 02/16] Get this more or less in line with code formatting standard. Fix some HTML/JS injection bugs. Some aggressive escaping; some message bits should be wikified. Some database bits fixed up for current db system; others need to be done still. --- includes/SpecialValidate.php | 917 +++++++++++++++++++---------------- 1 file changed, 496 insertions(+), 421 deletions(-) diff --git a/includes/SpecialValidate.php b/includes/SpecialValidate.php index dd8fa13b7d..8e9f2978bb 100644 --- a/includes/SpecialValidate.php +++ b/includes/SpecialValidate.php @@ -29,588 +29,663 @@ * @subpackage SpecialPage */ class Validation { - var $topicList ; - var $voteCache ; - var $rev2date ; - var $date2ref ; + var $topicList; + var $voteCache; + var $rev2date; + var $date2ref; # Reads all revision information of the specified article - function prepareRevisions ( $id ) { - global $wgDBprefix ; - $this->rev2date = array () ; - $this->date2rev = array () ; - $sql = "SELECT * FROM {$wgDBprefix}revision WHERE rev_page='{$id}'" ; + function prepareRevisions( $id ) { + global $wgDBprefix; + $this->rev2date = array(); + $this->date2rev = array(); + $sql = "SELECT * FROM {$wgDBprefix}revision WHERE rev_page='{$id}'"; $res = wfQuery( $sql, DB_READ ); while( $x = wfFetchObject( $res ) ) { - $this->rev2date[$x->rev_id] = $x ; - $this->date2rev[$x->rev_timestamp] = $x ; - } + $this->rev2date[$x->rev_id] = $x; + $this->date2rev[$x->rev_timestamp] = $x; } + } # Returns a HTML link to the specified article revision - function getVersionLink( &$article , $revision , $text = "" ) { - $t = $article->getTitle() ; - if ( $text == "" ) $text = wfMsg("val_view_version"); - $ret = "getLocalURL ( "oldid={$revision}" ) . "\">" . $text . "" ; - return $ret ; + function getVersionLink( &$article, $revision, $text = "" ) { + $t = $article->getTitle(); + if( $text == "" ) $text = wfMsg("val_view_version"); + $ret = "getLocalURL( "oldid={$revision}" ) . "\">" . $text . ""; + return $ret; } # Returns an array containing all topics you can vote on - function getTopicList () { - global $wgDBprefix ; - $ret = array () ; - $sql = "SELECT * FROM {$wgDBprefix}validate WHERE val_page=0" ; + function getTopicList() { + global $wgDBprefix; + $ret = array(); + $sql = "SELECT * FROM {$wgDBprefix}validate WHERE val_page=0"; $res = wfQuery( $sql, DB_READ ); while( $x = wfFetchObject( $res ) ) { - $ret[$x->val_type] = $x ; + $ret[$x->val_type] = $x; } - ksort ( $ret ) ; - return $ret ; + ksort( $ret ); + return $ret; } # Merges one dataset into another - function mergeInto ( &$source , &$dest ) { - $ret = false ; - foreach ( $source AS $x => $y ) { - $doit = false ; - if ( !isset ( $dest[$x] ) ) $doit = true ; - else if ( $dest[$x]->value == 0 ) $doit = true ; - if ( $doit ) { - $dest[$x] = $y ; - $ret = true ; + function mergeInto( &$source, &$dest ) { + $ret = false; + foreach( $source as $x => $y ) { + $doit = false; + if( !isset( $dest[$x] ) ) { + $doit = true; + } elseif( $dest[$x]->value == 0 ) { + $doit = true; } + if( $doit ) { + $dest[$x] = $y; + $ret = true; + } + } + if( $ret ) { + ksort ( $dest ); } - if ( $ret ) ksort ( $dest ) ; - return $ret ; + return $ret; } # Merges all votes prior to the given revision into it - function mergeOldRevisions ( &$article , $revision ) { - $tmp = $this->voteCache ; - krsort ( $tmp ) ; - $update = false ; - $ts = $this->getTimestamp($revision) ; - $data = $this->voteCache[$ts] ; - foreach ( $tmp AS $x => $y ) { - if ( $x < $ts ) { - if ( $this->mergeInto ( $y , $data ) ) $update = true ; + function mergeOldRevisions( &$article, $revision ) { + $tmp = $this->voteCache; + krsort( $tmp ); + $update = false; + $ts = $this->getTimestamp( $revision ); + $data = $this->voteCache[$ts]; + foreach( $tmp as $x => $y ) { + if( $x < $ts ) { + if( $this->mergeInto( $y, $data ) ) { + $update = true; + } } } - if ( $update ) $this->setRevision ( $article , $revision , $data ) ; + if( $update ) { + $this->setRevision( $article, $revision, $data ); + } } # Clears all votes prior to the given revision - function clearOldRevisions ( &$article , $revision ) { - $tmp = $this->voteCache ; - $ts = $this->getTimestamp($revision); - foreach ( $tmp AS $x => $y ) { - if ( $x < $ts ) $this->deleteRevision ( $article , $this->getRevisionNumber($x) ) ; + function clearOldRevisions( &$article, $revision ) { + $tmp = $this->voteCache; + $ts = $this->getTimestamp( $revision ); + foreach( $tmp as $x => $y ) { + if( $x < $ts ) { + $this->deleteRevision ( $article, $this->getRevisionNumber( $x ) ); + } } } # Updates the votes for the given revision from the FORM data - function updateRevision ( &$article , $revision ) { - global $wgUser, $wgRequest ; + function updateRevision( &$article, $revision ) { + global $wgUser, $wgRequest; - if ( isset ( $this->voteCache[$this->getTimestamp($revision)] ) ) $data = $this->voteCache[$this->getTimestamp($revision)] ; - else $data = array () ; - $nv = $wgRequest->getArray ( "re_v_{$revision}" , array() ) ; - $nc = $wgRequest->getArray ( "re_c_{$revision}" , array() ) ; + if( isset( $this->voteCache[$this->getTimestamp( $revision )] ) ) { + $data = $this->voteCache[$this->getTimestamp( $revision )]; + } else { + $data = array(); + } + $nv = $wgRequest->getArray( "re_v_{$revision}", array() ); + $nc = $wgRequest->getArray( "re_c_{$revision}", array() ); - foreach ( $nv AS $x => $y ) { - $data[$x]->value = $y ; - $data[$x]->comment = $nc[$x] ; + foreach( $nv as $x => $y ) { + $data[$x]->value = $y; + $data[$x]->comment = $nc[$x]; } - krsort ( $data ) ; + krsort( $data ); - $this->setRevision ( $article , $revision , $data ) ; + $this->setRevision( $article, $revision, $data ); } # Sets a specific revision to both cache and database - function setRevision ( &$article , $revision , &$data ) { - global $wgUser , $wgDBprefix ; - $this->deleteRevision ( $article , $revision ) ; - $this->voteCache[$this->getTimestamp($revision)] = $data ; - foreach ( $data AS $x => $y ) { - if ( $y->value > 0 ) { - $sql = "INSERT INTO {$wgDBprefix}validate (val_user,val_page,val_revision,val_type,val_value,val_comment,val_ip) VALUES ('" ; - $sql .= $wgUser->getID() . "','" ; - $sql .= $article->getID() . "','" ; - $sql .= $revision . "','" ; - $sql .= $x . "','" ; - $sql .= $y->value . "','" ; - $sql .= Database::strencode ( $y->comment ) . "','" ; - if ( $wgUser->isAnon() ) $sql .= $wgUser->getName() ; - $sql .= "')" ; - $res = wfQuery( $sql, DB_WRITE ); + function setRevision( &$article, $revision, &$data ) { + global $wgUser; + $this->deleteRevision( $article, $revision ); + $this->voteCache[$this->getTimestamp( $revision )] = $data; + foreach( $data as $x => $y ) { + if( $y->value > 0 ) { + $ip = $wgUser->isAnon() ? $wgUser->getName() : ''; + $dbw =& wfGetDB( DB_MASTER ); + $dbw->insert( 'validate', + array( + 'val_user' => $wgUser->getId(), + 'val_page' => $article->getId(), + 'val_revision' => $revision, + 'val_type' => $x, + 'val_value' => $y->value, + 'val_comment' => $y->comment, + 'val_ip' => $ip ), + 'Validation::setRevision' ); } } } # This function returns a MySQL statement to identify the current user - function identifyMe ( $user = "" ) { - global $wgUser ; - if ( $user == "" ) $user = $wgUser->GetID() ; - if ( User::isIP ( $user ) ) { - return "(val_user='0' AND val_ip='{$user}')" ; + function identifyMe( $user = "" ) { + global $wgUser; + if( $user == "" ) $user = $wgUser->GetID(); + if( User::isIP( $user ) ) { + return "(val_user='0' AND val_ip='{$user}')"; } else { - return "(val_user='{$user}')" ; - } + return "(val_user='{$user}')"; } + } # Deletes a specific vote set in both cache and database - function deleteRevision ( &$article , $revision ) { - global $wgUser , $wgDBprefix ; - $ts = $this->getTimestamp ( $revision ) ; - if ( !isset ( $this->voteCache[$ts] ) ) return ; # Nothing to do - $sql = "DELETE FROM {$wgDBprefix}validate WHERE" . $this->identifyMe() . " AND " ; - $sql .= " val_page='" . $article->getID() . "' AND val_revision='{$revision}'" ; + function deleteRevision( &$article, $revision ) { + global $wgUser, $wgDBprefix; + $ts = $this->getTimestamp( $revision ); + if( !isset ( $this->voteCache[$ts] ) ) { + return; # Nothing to do + } + $sql = "DELETE FROM {$wgDBprefix}validate WHERE" . $this->identifyMe() . " AND "; + $sql .= " val_page='" . $article->getID() . "' AND val_revision='{$revision}'"; $res = wfQuery( $sql, DB_WRITE ); - unset ( $this->voteCache[$ts] ) ; + unset( $this->voteCache[$ts] ); } # Reads the entire vote list for this user for the given article - function getVoteList ( $id , $user = "" ) { - global $wgUser , $wgDBprefix ; - if ( $user == "" ) $user = $wgUser->GetID() ; - $r = array () ; # Revisions - $sql = "SELECT * FROM {$wgDBprefix}validate WHERE val_page=" . $id . " AND " . $this->identifyMe($user) ; + function getVoteList( $id, $user = "" ) { + global $wgUser, $wgDBprefix; + if( $user == "" ) { + $user = $wgUser->GetID(); + } + $r = array() ; # Revisions + $sql = "SELECT * FROM {$wgDBprefix}validate WHERE val_page=" . $id . " AND " . $this->identifyMe( $user ); $res = wfQuery( $sql, DB_READ ); while( $x = wfFetchObject( $res ) ) { - #$y = $x->val_revision ; - $y = $this->rev2date[$x->val_revision] ; - $y = $y->rev_timestamp ; - if ( !isset($r[$y]) ) $r[$y] = array () ; - $r[$y][$x->val_type]->value = $x->val_value ; - $r[$y][$x->val_type]->comment = $x->val_comment ; + #$y = $x->val_revision; + $y = $this->rev2date[$x->val_revision]; + $y = $y->rev_timestamp; + if( !isset( $r[$y] ) ) { + $r[$y] = array(); + } + $r[$y][$x->val_type]->value = $x->val_value; + $r[$y][$x->val_type]->comment = $x->val_comment; } - return $r ; + return $r; } # Reads the entire vote list for this user for all articles - function getAllVoteLists ( $user ) { - global $wgDBprefix ; - $r = array () ; # Revisions - $sql = "SELECT * FROM {$wgDBprefix}validate WHERE " . $this->identifyMe ( $user ) ; + function getAllVoteLists( $user ) { + global $wgDBprefix; + $r = array() ; # Revisions + $sql = "SELECT * FROM {$wgDBprefix}validate WHERE " . $this->identifyMe( $user ); $res = wfQuery( $sql, DB_READ ); while( $x = wfFetchObject( $res ) ) { - $a = $x->val_page ; - $y = $x->val_revision ; - if ( !isset ( $r[$a] ) ) $r[$a] = array () ; - if ( !isset($r[$a][$y]) ) $r[$a][$y] = array () ; - $r[$a][$y][$x->val_type] = $x ; + $a = $x->val_page; + $y = $x->val_revision; + if( !isset( $r[$a] ) ) { + $r[$a] = array(); + } + if( !isset( $r[$a][$y] ) ) { + $r[$a][$y] = array(); + } + $r[$a][$y][$x->val_type] = $x; } - return $r ; + return $r; } # This functions adds a topic to the database - function addTopic ( $topic , $limit ) { - global $wgDBprefix ; - $a = 1 ; - while ( isset ( $this->topicList[$a] ) ) $a++ ; - $sql = "INSERT INTO {$wgDBprefix}validate (val_user,val_page,val_revision,val_type,val_value,val_comment,val_ip) VALUES (" ; - $sql .= "'0','0','0','{$a}','{$limit}','" ; - $sql .= Database::strencode ( $topic ) . "','')" ; + function addTopic( $topic, $limit ) { + global $wgDBprefix; + $a = 1; + while( isset( $this->topicList[$a] ) ) { + $a++; + } + $sql = "INSERT INTO {$wgDBprefix}validate (val_user,val_page,val_revision,val_type,val_value,val_comment,val_ip) VALUES ("; + $sql .= "'0','0','0','{$a}','{$limit}','"; + $sql .= Database::strencode( $topic ) . "','')"; $res = wfQuery( $sql, DB_WRITE ); - $x->val_user = $x->val_page = $x->val_revision = 0 ; - $x->val_type = $a ; - $x->val_value = $limit ; - $x->val_comment = $topic ; - $x->val_ip = "" ; - $this->topicList[$a] = $x ; - ksort ( $this->topicList ) ; + $x->val_user = $x->val_page = $x->val_revision = 0; + $x->val_type = $a; + $x->val_value = $limit; + $x->val_comment = $topic; + $x->val_ip = ""; + $this->topicList[$a] = $x; + ksort( $this->topicList ); } # This functions adds a topic to the database - function deleteTopic ( $id ) { - global $wgDBprefix ; - $sql = "DELETE FROM {$wgDBprefix}validate WHERE val_type='{$id}'" ; - $res = wfQuery( $sql, DB_WRITE ); - unset ( $this->topicList[$id] ) ; + function deleteTopic( $id ) { + global $wgDBprefix; + $dbw =& wfGetDB( DB_MASTER ); + $dbw->delete( 'validate', + array( 'val_type' => $id ), + 'Validation::deleteTopic' ); + unset( $this->topicList[$id] ); } # This function returns a link text to the page validation statistics - function link2statistics ( &$article ) { + function link2statistics( &$article ) { $nt = $article->getTitle(); - $url = htmlspecialchars( $nt->getLocalURL( "action=validate&mode=list" ) ); - return wfMsg ( 'val_rev_stats_link', $nt->getPrefixedText(), $url ); + $url = $nt->escapeLocalURL( "action=validate&mode=list" ); + return wfMsg( 'val_rev_stats_link', $nt->getPrefixedText(), $url ); } # This function returns a link text to the page validation statistics of a single revision - function link2revisionstatistics ( &$article , $revision ) { + function link2revisionstatistics( &$article, $revision ) { $nt = $article->getTitle(); - $url = htmlspecialchars( $nt->getLocalURL( "action=validate&mode=details&revision={$revision}" ) ); - return wfMsg ( 'val_revision_stats_link', $url ); + $url = $nt->escapeLocalURL( "action=validate&mode=details&revision={$revision}" ); + return wfMsg( 'val_revision_stats_link', $url ); } # This function returns a link text to the user rating statistics page - function link2userratings ( $user , $text ) { - global $wgUser ; - if ( $user == 0 ) $user = $wgUser->GetName() ; - $nt = Title::newFromText ( "Special:Validate" ) ; + function link2userratings( $user, $text ) { + global $wgUser; + if( $user == 0 ) { + $user = $wgUser->GetName(); + } + $nt = Title::newFromText( "Special:Validate" ); $url = htmlspecialchars( $nt->getLocalURL( "mode=userstats&user={$user}" ) ); - return "{$text}" ; + return "{$text}"; } # Returns the timestamp of a revision based on the revision number - function getTimestamp ( $revision ) { - $ts = $this->rev2date[$revision] ; - $ts = $ts->rev_timestamp ; - return $ts ; + function getTimestamp( $revision ) { + $ts = $this->rev2date[$revision]; + $ts = $ts->rev_timestamp; + return $ts; } # Returns the revision number of a revision based on the timestamp - function getRevisionNumber ( $ts ) { - $revision = $this->date2rev[$ts] ; - $revision = $revision->rev_id ; - return $revision ; + function getRevisionNumber( $ts ) { + $revision = $this->date2rev[$ts]; + $revision = $revision->rev_id; + return $revision; } # HTML generation functions from this point on # Returns the metadata string for a revision - function getMetadata ( $idx ) { - $metadata = "" ; - $x = $this->rev2date[$idx] ; - $metadata .= wfTimestamp ( TS_DB , $x->rev_timestamp ) ; - $metadata .= " by " ; - if ( $x->rev_user == 0 ) { - $metadata .= $x->rev_user_text ; + function getMetadata( $idx ) { + $metadata = ""; + $x = $this->rev2date[$idx]; + $metadata .= wfTimestamp( TS_DB, $x->rev_timestamp ); + $metadata .= " by "; + if( $x->rev_user == 0 ) { + $metadata .= $x->rev_user_text; } else { - $u = new User ; - $u->setId ( $x->rev_user ) ; - $u->setName ( $x->rev_user_text ) ; - $nt = $u->getUserPage() ; - $url = "" . $nt->getText() . "" ; - $metadata .= $url ; - } - $metadata .= " : \"" . htmlspecialchars ( $x->rev_comment ) . "\"" ; - return $metadata ; + $u = new User; + $u->setId( $x->rev_user ); + $u->setName( $x->rev_user_text ); + $nt = $u->getUserPage(); + $url = "" . $nt->getText() . ""; + $metadata .= $url; + } + $metadata .= " : \"" . htmlspecialchars( $x->rev_comment ) . "\""; + return $metadata; } # Generates a form for a single revision - function getRevisionForm ( &$article , $idx , &$data , $focus = false ) { + function getRevisionForm( &$article, $idx, &$data, $focus = false ) { # Fill data with blank values - $ts = $idx ; - $revision = $this->getRevisionNumber ( $ts ) ; - foreach ( $this->topicList AS $x => $y ) { - if ( !isset ( $data[$x] ) ) { - $data[$x]->value = 0 ; - $data[$x]->comment = "" ; + $ts = $idx; + $revision = $this->getRevisionNumber( $ts ); + foreach( $this->topicList as $x => $y ) { + if( !isset( $data[$x] ) ) { + $data[$x]->value = 0; + $data[$x]->comment = ""; } } - ksort ( $data ) ; + ksort( $data ) ; # Generate form - $ret = "
" ; - $ret .= "getVersionLink ( $article , $revision ) ; - $metadata = $this->getMetadata ( $revision ) ; - $ret .= "\n" ; - $line = 0 ; - foreach ( $data AS $x => $y ) { - $line = 1 - $line ; - $col = $line == 1 ? "#DDDDDD" : "#EEEEEE" ; - $idx = "_{$revision}[{$x}]" ; - $ret .= "\n" ; - $ret .= "\n" ; + $ret = ""; + $ret .= "
" . $head . " ({$link}) {$metadata}
" ; - $ret .= $this->topicList[$x]->val_comment ; - $ret .= "
getVersionLink( $article, $revision ); + $metadata = $this->getMetadata( $revision ); + $ret .= "\n"; + $line = 0; + foreach( $data as $x => $y ) { + $line = 1 - $line; + $col = $line == 1 ? "#DDDDDD" : "#EEEEEE"; + $idx = "_{$revision}[{$x}]"; + $ret .= "\n"; + $ret .= "\n"; - $tlx = $this->topicList[$x] ; - $vote = "" ; - $max = $tlx->val_value ; - for ( $a = 0 ; $a <= $max ; $a++ ) { - if ( $a == 0 ) $vote .= wfMsg ( "val_noop" ) ; - $vote .= "value ) $vote .= " checked" ; - $vote .= "/>" ; - if ( $max == 2 && $a == 1 ) $vote .= wfMsg ( "val_no" ) . " " ; - else if ( $max == 2 && $a == 2 ) $vote .= wfMsg ( "val_yes" ) ; - else if ( $a != 0 ) $vote .= $a . " " ; - if ( $a == 0 ) $vote .= "   " ; + $tlx = $this->topicList[$x]; + $vote = ""; + $max = $tlx->val_value; + for( $a = 0 ; $a <= $max ; $a++ ) { + if( $a == 0 ) { + $vote .= wfMsg ( "val_noop" ); + } + $vote .= "value ) { + $vote .= " checked"; + } + $vote .= "/>"; + if( $max == 2 && $a == 1 ) { + $vote .= wfMsg( "val_no" ) . " "; + } elseif( $max == 2 && $a == 2 ) { + $vote .= wfMsg( "val_yes" ); + } elseif( $a != 0 ) { + $vote .= $a . " "; + } + if ( $a == 0 ) { + $vote .= "   "; + } } - $ret .= "\n" ; + $ret .= "\n"; - $ret .= "\n" ; - } - $checked = $focus ? " checked" : "" ; - $ret .= "\n" ; - $ret .= "
" . $head . " ({$link}) {$metadata}
"; + $ret .= $this->topicList[$x]->val_comment; + $ret .= "{$vote}{$vote}" ; - $ret .= "
\n" ; - $ret .= "" . wfMsg( 'val_merge_old' ) . " \n" ; - $ret .= "" . wfMsg( 'val_clear_old' ) . " \n" ; - $ret .= "\n" ; - if ( $focus ) $ret .= "
\n" . wfMsg ( "val_form_note" ) . "" ; - $ret .= "
\n
\n\n" ; - return $ret ; + $ret .= ""; + $ret .= "\n"; + } + $checked = $focus ? " checked='checked'" : ""; + $ret .= "\n"; + $ret .= "" . htmlspecialchars( wfMsg( 'val_merge_old' ) ) . " \n"; + $ret .= "" . htmlspecialchars( wfMsg( 'val_clear_old' ) ) . " \n"; + $ret .= "\n"; + if( $focus ) { + $ret .= "
\n" . htmlspecialchars( wfMsg( "val_form_note" ) ) . ""; + } + $ret .= "\n"; + $ret .= "\n\n\n"; + return $ret; } # Generates the page from the validation tab - function validatePageForm ( &$article , $revision ) { - global $wgOut, $wgRequest, $wgUser ; + function validatePageForm( &$article, $revision ) { + global $wgOut, $wgRequest, $wgUser; - $ret = "" ; - $this->prepareRevisions ( $article->getID() ) ; - $this->topicList = $this->getTopicList() ; - $this->voteCache = $this->getVoteList ( $article->getID() ) ; + $ret = ""; + $this->prepareRevisions( $article->getID() ); + $this->topicList = $this->getTopicList(); + $this->voteCache = $this->getVoteList( $article->getID() ); # Check for POST data $re = $wgRequest->getArray( 're_submit' ); - if ( isset ( $re ) ) - { - $id = array_keys ( $re ) ; + if( isset( $re ) ) { + $id = array_keys( $re ); $id = $id[0] ; # $id is now the revision number the user clicked "OK" for - $clearOldRev = $wgRequest->getVal( "re_clear_{$id}" , 0 ); - $mergeOldRev = $wgRequest->getVal( "re_merge_{$id}" , 0 ); - $this->updateRevision ( $article , $id ) ; - if ( $mergeOldRev ) $this->mergeOldRevisions ( $article , $id ) ; - if ( $clearOldRev ) $this->clearOldRevisions ( $article , $id ) ; - $ret .= "

" . wfMsg ( 'val_revision_changes_ok' ) . "

" ; + $clearOldRev = $wgRequest->getVal( "re_clear_{$id}", 0 ); + $mergeOldRev = $wgRequest->getVal( "re_merge_{$id}", 0 ); + $this->updateRevision( $article, $id ); + if( $mergeOldRev ) { + $this->mergeOldRevisions( $article, $id ); } + if( $clearOldRev ) { + $this->clearOldRevisions( $article, $id ); + } + $ret .= "

" . htmlspecialchars( wfMsg( 'val_revision_changes_ok' ) ) . "

"; + } # Make sure the requested revision exists - $ts = $this->rev2date[$revision]->rev_timestamp ; - if ( !isset ( $this->voteCache[$ts] ) ) $this->voteCache[$ts] = array () ; + $ts = $this->rev2date[$revision]->rev_timestamp; + if( !isset( $this->voteCache[$ts] ) ) { + $this->voteCache[$ts] = array(); + } # Sort revisions list, newest first - krsort ( $this->voteCache ) ; + krsort( $this->voteCache ); # Output $title = $article->getTitle(); - $title = $title->getPrefixedText() ; - $wgOut->setPageTitle ( wfMsg ( 'val_rev_for' ) . $title ) ; - foreach ( $this->voteCache AS $x => $y ) - { - $ret .= $this->getRevisionForm ( $article , $x , $y , $x == $ts ) ; - $ret .= "
\n" ; - } - $ret .= $this->link2statistics ( $article ) ; - $ret .= "

" . $this->link2userratings ( $wgUser->GetID() , wfMsg('val_show_my_ratings') ) . "

" ; + $title = $title->getPrefixedText(); + $wgOut->setPageTitle( wfMsg( 'val_rev_for' ) . $title ); + foreach( $this->voteCache as $x => $y ) { + $ret .= $this->getRevisionForm( $article, $x, $y, $x == $ts ); + $ret .= "
\n"; + } + $ret .= $this->link2statistics( $article ); + $ret .= "

" . $this->link2userratings( $wgUser->getID(), wfMsg( 'val_show_my_ratings' ) ) . "

"; return $ret ; } # This function performs the "management" mode on Special:Validate - function manageTopics () { - global $wgRequest ; - $this->topicList = $this->getTopicList() ; + function manageTopics() { + global $wgRequest; + $this->topicList = $this->getTopicList(); - $iamsure = $wgRequest->getVal ( "iamsure" , "0" ) == 1 ; + $iamsure = $wgRequest->getVal( "iamsure", "0" ) == 1; - if ( $iamsure && $wgRequest->getVal ( "m_add" , "--" ) != "--" ) { - $new_topic = $wgRequest->getVal ( "m_topic" ) ; - $new_limit = $wgRequest->getVal ( "m_limit" ) ; - if ( $new_topic != "" && $new_limit > 1 ) - $this->addTopic ( $new_topic , $new_limit ) ; + if( $iamsure && $wgRequest->getVal( "m_add", "--" ) != "--" ) { + $new_topic = $wgRequest->getVal( "m_topic" ); + $new_limit = $wgRequest->getVal( "m_limit" ); + if( $new_topic != "" && $new_limit > 1 ) { + $this->addTopic( $new_topic, $new_limit ); + } } - $da = $wgRequest->getArray ( "m_del" ) ; - if ( $iamsure && isset ( $da ) && count ( $da ) > 0 ) { - $id = array_keys ( $da ) ; - $id = array_shift ( $id ) ; - $this->deleteTopic ( $id ) ; + $da = $wgRequest->getArray( "m_del" ); + if( $iamsure && isset( $da ) && count( $da ) > 0 ) { + $id = array_keys( $da ); + $id = array_shift( $id ); + $this->deleteTopic( $id ); } - $r = "

" . wfMsg ( 'val_warning' ) . "

\n" ; - $r .= "
\n" ; - $r .= "\n" ; - $r .= "" . wfMsg ( 'val_list_header' ) . "\n" ; - foreach ( $this->topicList AS $x => $y ) { - $r .= "\n" ; - $r .= "\n" ; - $r .= "\n" ; - $r .= "\n" ; - $r .= "\n" ; - $r .= "\n" ; - } - $r .= "\n" ; - $r .= "\n" ; - $r .= "\n" ; - $r .= "\n" ; - $r .= "\n" ; - $r .= "
" . $y->val_type . "{$y->val_comment}1 .. {$y->val_value}
\n" ; - $r .= "
\n" ; - $r .= "" . wfMsg ( 'val_iamsure' ) . "\n" ; - $r .= "
\n" ; - return $r ; + # FIXME: Wikitext this + $r = "

" . htmlspecialchars( wfMsg( 'val_warning' ) ) . "

\n"; + + $r .= "
\n"; + $r .= "\n"; + $r .= "" . wfMsg( 'val_list_header' ) . "\n"; + foreach( $this->topicList as $x => $y ) { + $r .= "\n"; + $r .= "\n"; + $r .= "\n"; + $r .= "\n"; + $r .= "\n"; + $r .= "\n"; + } + $r .= "\n"; + $r .= "\n"; + $r .= "\n"; + $r .= "\n"; + $r .= "\n"; + $r .= "
" . htmlspecialchars( $y->val_type ) . "" . htmlspecialchars( $y->val_comment ) . "1 .. " . intval( $y->val_value ) . "
\n"; + $r .= "
\n"; + $r .= "" . htmlspecialchars( wfMsg( 'val_iamsure' ) ) . "\n"; + $r .= "
\n"; + return $r; } # Generates a user ID for both logged-in users and anons; $x is an object from an SQL query - function make_user_id ( &$x ) { - if ( $x->val_user == 0 ) return $x->val_ip ; - else return $x->val_user ; + function make_user_id( &$x ) { + if( $x->val_user == 0 ) { + return $x->val_ip; + } else { + return $x->val_user; } + } - function showDetails ( &$article , $revision ) { - global $wgDBprefix , $wgOut, $wgUser ; - $this->prepareRevisions ( $article->getID() ) ; - $this->topicList = $this->getTopicList() ; + function showDetails( &$article, $revision ) { + global $wgDBprefix, $wgOut, $wgUser; + $this->prepareRevisions( $article->getID() ); + $this->topicList = $this->getTopicList(); - $title = $article->getTitle() ; - $wgOut->setPageTitle ( str_replace ( '$1' , $title->getPrefixedText() , wfMsg ( 'val_validation_of' ) ) ) ; + $title = $article->getTitle(); + $wgOut->setPageTitle( str_replace( '$1', $title->getPrefixedText(), wfMsg( 'val_validation_of' ) ) ); # Collecting statistic data - $id = $article->getID() ; - $sql = "SELECT * FROM {$wgDBprefix}validate WHERE val_page='{$id}' AND val_revision='{$revision}'" ; + $id = $article->getID(); + $sql = "SELECT * FROM {$wgDBprefix}validate WHERE val_page='{$id}' AND val_revision='{$revision}'"; $res = wfQuery( $sql, DB_READ ); - $data = array () ; - $users = array () ; - $topics = array () ; + $data = array(); + $users = array(); + $topics = array(); while( $x = wfFetchObject( $res ) ) { - $data[$this->make_user_id($x)][$x->val_type] = $x ; - $users[$this->make_user_id($x)] = true ; - $topics[$x->val_type] = true ; + $data[$this->make_user_id($x)][$x->val_type] = $x; + $users[$this->make_user_id($x)] = true; + $topics[$x->val_type] = true; } # Sorting lists of topics and users - ksort ( $users ) ; - ksort ( $topics ) ; + ksort( $users ); + ksort( $topics ); - $ts = $this->getTimestamp ( $revision ) ; - $url = $this->getVersionLink ( $article , $revision , wfTimestamp ( TS_DB , $ts ) ) ; + $ts = $this->getTimestamp( $revision ); + $url = $this->getVersionLink( $article, $revision, wfTimestamp( TS_DB, $ts ) ); # Table headers $ret = "" ; - $ret .= "

" . str_replace ( '$1' , $url , wfMsg ( 'val_revision_of' ) ) . "

\n" ; - $ret .= "\n" ; - $ret .= ""; } + $ret .= "
" ; + $ret .= "

" . str_replace( '$1', $url, wfMsg( 'val_revision_of' ) ) . "

\n"; + $ret .= "\n"; + $ret .= "" ; - } - $ret .= "\n" ; + foreach( $topics as $t => $dummy ) { + $ret .= ""; + } + $ret .= "\n"; # Table data - foreach ( $users AS $u => $dummy ) { # Every row a user - $ret .= "" ; - $ret .= ""; + $ret .= "" ; - foreach ( $topics AS $t => $dummy ) { # Every column a topic - if ( !isset ( $data[$u][$t] ) ) $ret .= "" ; + $ret .= ""; + foreach( $topics as $t => $dummy ) { # Every column a topic + if( !isset( $data[$u][$t] ) ) { + $ret .= ""; } } - $ret .= "" ; - } - $ret .= "
"; - foreach ( $topics AS $t => $dummy ) { - $ret .= "" . $this->topicList[$t]->val_comment . "
" . htmlspecialchars( $this->topicList[$t]->val_comment ) . "
" ; - if ( !User::IsIP ( $u ) ) { # Logged-in user rating - $ret .= $this->link2userratings ( $u , User::whoIs ( $u ) ) ; + foreach( $users as $u => $dummy ) { # Every row a user + $ret .= "
"; + if( !User::IsIP( $u ) ) { # Logged-in user rating + $ret .= $this->link2userratings( $u, User::whoIs( $u ) ); } else { # Anon rating - $ret .= $this->link2userratings ( $u , $u ) ; + $ret .= $this->link2userratings( $u, $u ); } - $ret .= "" ; - else { - $ret .= "" ; - $ret .= $data[$u][$t]->val_value ; - if ( $data[$u][$t]->val_comment != "" ) - $ret .= " (" . $data[$u][$t]->val_comment . ")" ; - $ret .= ""; + } else { + $ret .= ""; + $ret .= $data[$u][$t]->val_value; + if( $data[$u][$t]->val_comment != "" ) { + $ret .= " (" . htmlspecialchars( $data[$u][$t]->val_comment ) . ")"; + } + $ret .= "
" ; - $ret .= "

" . $this->link2statistics ( $article ) . "

" ; - $ret .= "

" . $this->link2userratings ( $wgUser->GetID() , wfMsg('val_show_my_ratings') ) . "

" ; - - return $ret ; + $ret .= "
"; + $ret .= "

" . $this->link2statistics( $article ) . "

"; + $ret .= "

" . $this->link2userratings( $wgUser->GetID(), wfMsg( 'val_show_my_ratings' ) ) . "

"; + + return $ret; + } - function showList ( &$article ) { - global $wgDBprefix , $wgOut, $wgUser; - $this->prepareRevisions ( $article->getID() ) ; - $this->topicList = $this->getTopicList() ; + function showList( &$article ) { + global $wgDBprefix, $wgOut, $wgUser; + $this->prepareRevisions( $article->getID() ); + $this->topicList = $this->getTopicList(); - $title = $article->getTitle() ; - $wgOut->setPageTitle ( str_replace ( '$1' , $title->getPrefixedText() , wfMsg ( 'val_validation_of' ) ) ) ; + $title = $article->getTitle(); + $wgOut->setPageTitle( str_replace( '$1', $title->getPrefixedText(), wfMsg( 'val_validation_of' ) ) ); # Collecting statistic data - $id = $article->getID() ; - $sql = "SELECT * FROM {$wgDBprefix}validate WHERE val_page='{$id}'" ; + $id = $article->getID(); + $sql = "SELECT * FROM {$wgDBprefix}validate WHERE val_page='{$id}'"; $res = wfQuery( $sql, DB_READ ); - $data = array () ; + $data = array(); while( $x = wfFetchObject( $res ) ) { - $idx = $this->getTimestamp ( $x->val_revision ) ; - if ( !isset ( $data[$idx] ) ) - $data[$idx] = array () ; - if ( !isset ( $data[$idx][$x->val_type] ) ) { - $data[$idx][$x->val_type]->count = 0 ; - $data[$idx][$x->val_type]->sum = 0 ; + $idx = $this->getTimestamp( $x->val_revision ); + if( !isset( $data[$idx] ) ) { + $data[$idx] = array(); } - $data[$idx][$x->val_type]->count++ ; - $data[$idx][$x->val_type]->sum += $x->val_value ; + if( !isset( $data[$idx][$x->val_type] ) ) { + $data[$idx][$x->val_type]->count = 0; + $data[$idx][$x->val_type]->sum = 0; + } + $data[$idx][$x->val_type]->count++; + $data[$idx][$x->val_type]->sum += $x->val_value; } - krsort ( $data ) ; + krsort( $data ); - $ret = "" ; - $ret .= "\n" ; - $ret .= "" ; - foreach ( $this->topicList AS $x => $y ) - $ret .= "" ; - $ret .= "\n" ; - foreach ( $data AS $ts => $y ) { - $revision = $this->getRevisionNumber ( $ts ) ; - $url = $this->getVersionLink ( $article , $revision , wfTimestamp ( TS_DB , $ts ) ) ; - $detailsurl = $this->link2revisionstatistics ( $article , $revision ) ; - $ret .= "" ; - foreach ( $this->topicList AS $topicID => $dummy ) { - if ( isset ( $y[$topicID] ) ) { - $z = $y[$topicID] ; - if ( $z->count == 0 ) $a = 0 ; - else $a = $z->sum / $z->count ; - $ret .= sprintf ( "" , $a , $z->count ) ; - } else $ret .= "
" . wfMsg("val_revision") . "{$y->val_comment}
{$url} {$detailsurl}%1.1f (%d)" ; + $ret = ""; + $ret .= "\n"; + $ret .= ""; + foreach( $this->topicList as $x => $y ) { + $ret .= ""; + } + $ret .= "\n"; + foreach( $data as $ts => $y ) { + $revision = $this->getRevisionNumber( $ts ); + $url = $this->getVersionLink( $article, $revision, wfTimestamp( TS_DB, $ts ) ); + $detailsurl = $this->link2revisionstatistics( $article, $revision ); + $ret .= ""; + foreach( $this->topicList as $topicID => $dummy ) { + if( isset( $y[$topicID] ) ) { + $z = $y[$topicID]; + if( $z->count == 0 ) { + $a = 0; + } else { + $a = $z->sum / $z->count; + } + $ret .= sprintf( "", $a, $z->count ); + } else { + $ret .= ""; } - $ret .= "\n" ; + } + $ret .= "\n"; } - $ret .= "
" . htmlspecialchars( wfMsg( "val_revision" ) ) . "" . htmlspecialchars( $y->val_comment ) . "
{$url} {$detailsurl}%1.1f (%d)
\n" ; - $ret .= "

" . $this->link2userratings ( $wgUser->GetID() , wfMsg('val_show_my_ratings') ) . "

" ; - return $ret ; + $ret .= "
\n"; + $ret .= "

" . $this->link2userratings( $wgUser->getID(), wfMsg( 'val_show_my_ratings' ) ) . "

"; + return $ret; } - function getRatingText ( $value , $max ) { - if ( $max == 2 && $value == 1 ) $ret = wfMsg ( "val_no" ) . " " ; - else if ( $max == 2 && $value == 2 ) $ret = wfMsg ( "val_yes" ) ; - else if ( $value != 0 ) $ret = wfMsg ( "val_of" , $value , $max ) . " " ; - else $ret = "" ; - return $ret ; + function getRatingText( $value, $max ) { + if( $max == 2 && $value == 1 ) { + $ret = wfMsg ( "val_no" ) . " "; + } elseif( $max == 2 && $value == 2 ) { + $ret = wfMsg( "val_yes" ); + } elseif( $value != 0 ) { + $ret = wfMsg( "val_of", $value, $max ) . " "; + } else { + $ret = ""; + } + return $ret; } - function showUserStats ( $user ) { - global $wgDBprefix , $wgOut, $wgUser ; - $this->topicList = $this->getTopicList() ; - $data = $this->getAllVoteLists ( $user ) ; + function showUserStats( $user ) { + global $wgDBprefix, $wgOut, $wgUser; + $this->topicList = $this->getTopicList(); + $data = $this->getAllVoteLists( $user ); - if ( $user == $wgUser->getID() ) $wgOut->setPageTitle ( wfMsg ( 'val_my_stats_title' ) ) ; - elseif ( ! User::IsIP ( $user ) ) $wgOut->setPageTitle ( wfMsg ( 'val_user_stats_title' , User::whoIs ( $user ) ) ) ; - else $wgOut->setPageTitle ( wfMsg ( 'val_user_stats_title' , $user ) ) ; + if( $user == $wgUser->getID() ) { + $wgOut->setPageTitle ( wfMsg ( 'val_my_stats_title' ) ); + } elseif( !User::IsIP( $user ) ) { + $wgOut->setPageTitle( wfMsg( 'val_user_stats_title', User::whoIs( $user ) ) ); + } else { + $wgOut->setPageTitle( wfMsg( 'val_user_stats_title', $user ) ); + } - $ret = "" ; - $ret .= "\n" ; + $ret = "
\n"; - foreach ( $data AS $articleid => $revisions ) { - $title = Title::newFromID ( $articleid ) ; - $ret .= "" ; - krsort ( $revisions ) ; - foreach ( $revisions AS $revid => $revision ) { - $url = $title->getLocalURL ( "oldid={$revid}" ) ; - $ret .= "" ; - ksort ( $revision ) ; - $initial = true ; - foreach ( $revision AS $topic => $rating ) { - if ( !$initial ) $ret .= "" ; - $ret .= "" ; - $ret .= "" ; - $ret .= "" ; + foreach( $data as $articleid => $revisions ) { + $title = Title::newFromID( $articleid ); + $ret .= ""; + krsort( $revisions ); + foreach( $revisions as $revid => $revision ) { + $url = $title->getLocalURL( "oldid={$revid}" ); + $ret .= ""; + ksort( $revision ); + $initial = true; + foreach( $revision as $topic => $rating ) { + if( !$initial ) { + $ret .= ""; + $ret .= ""; + $ret .= ""; + $ret .= ""; } } - $ret .= "" ; + $ret .= ""; } - $ret .= "
getLocalURL() . "\">" . $title->getPrefixedText() . "
" . wfMsg ( 'val_revision_number' , $revid ) . "
" ; - $initial = false ; - $ret .= "" . $this->topicList[$topic]->val_comment . "" . $this->getRatingText ( $rating->val_value , $this->topicList[$topic]->val_value ) . "" . htmlentities ( $rating->val_comment ) . "
escapeLocalURL() . "\">" . $title->getEscapedText() . "
" . wfMsg( 'val_revision_number', $revid ) . "
"; + } + $initial = false; + $ret .= "" . htmlspecialchars( $this->topicList[$topic]->val_comment ) . "" . $this->getRatingText( $rating->val_value, $this->topicList[$topic]->val_value ) . "" . htmlspecialchars( $rating->val_comment ) . "
" ; + $ret .= ""; - return $ret ; - } + return $ret; + } } @@ -627,32 +702,32 @@ function wfSpecialValidate( $page = '' ) { /* # Can do? - if ( ! $wgUser->isAllowed('change_validation') ) { + if( ! $wgUser->isAllowed('change_validation') ) { $wgOut->sysopRequired(); return; } */ - $mode = $wgRequest->getVal ( "mode" ) ; - $skin = $wgUser->getSkin() ; + $mode = $wgRequest->getVal( "mode" ); + $skin = $wgUser->getSkin(); - if ( $mode == "manage" ) { - $v = new Validation ; - $html = $v->manageTopics () ; - } else if ( $mode == "userstats" ) { - $v = new Validation ; - $user = $wgRequest->getVal ( "user" ) ; - $html = $v->showUserStats ( $user ) ; + if( $mode == "manage" ) { + $v = new Validation(); + $html = $v->manageTopics(); + } elseif( $mode == "userstats" ) { + $v = new Validation(); + $user = $wgRequest->getVal( "user" ); + $html = $v->showUserStats( $user ); } else { - $html = "$mode" ; - $html .= "\n"; } $wgOut->addHTML( $html ); -- 2.20.1 From a12ce8f7478d9125bf6b58d6be559d3436941df3 Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Wed, 1 Jun 2005 06:18:49 +0000 Subject: [PATCH 03/16] new load balancing algorithm --- includes/Database.php | 32 ++++++++ includes/GlobalFunctions.php | 5 +- includes/LoadBalancer.php | 148 +++++++++++++++++++++++++++++++++-- includes/OutputPage.php | 8 +- languages/Language.php | 1 + 5 files changed, 183 insertions(+), 11 deletions(-) diff --git a/includes/Database.php b/includes/Database.php index 0dce6a9b5a..935523118b 100644 --- a/includes/Database.php +++ b/includes/Database.php @@ -1447,6 +1447,38 @@ class Database { function ping() { return mysql_ping( $this->mConn ); } + + /** + * Get slave lag. + * At the moment, this will only work if the DB user has the PROCESS privilege + */ + function getLag() { + $res = $this->query( 'SHOW PROCESSLIST' ); + # Find slave SQL thread. Assumed to be the second one running, which is a bit + # dubious, but unfortunately there's no easy rigorous way + $slaveThreads = 0; + while ( $row = $this->fetchObject( $res ) ) { + if ( $row->User == 'system user' ) { + if ( ++$slaveThreads == 2 ) { + # This is it, return the time + return $row->Time; + } + } + } + return false; + } + + /** + * Get status information from SHOW STATUS in an associative array + */ + function getStatus() { + $res = $this->query( 'SHOW STATUS' ); + $status = array(); + while ( $row = $this->fetchObject( $res ) ) { + $status[$row->Variable_name] = $row->Value; + } + return $status; + } } /** diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index af86f712cb..47646471b2 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -216,8 +216,11 @@ function logProfilingData() { * @return bool */ function wfReadOnly() { - global $wgReadOnlyFile; + global $wgReadOnlyFile, $wgReadOnly; + if ( $wgReadOnly ) { + return true; + } if ( '' == $wgReadOnlyFile ) { return false; } diff --git a/includes/LoadBalancer.php b/includes/LoadBalancer.php index abbf936e5b..c6f6f1521d 100644 --- a/includes/LoadBalancer.php +++ b/includes/LoadBalancer.php @@ -91,6 +91,14 @@ class LoadBalancer { foreach ( $weights as $w ) { $sum += $w; } + + if ( $sum == 0 ) { + # No loads on any of them + # Just pick one at random + foreach ( $weights as $i => $w ) { + $weights[$i] = 1; + } + } $max = mt_getrandmax(); $rand = mt_rand(0, $max) / $max * $sum; @@ -104,8 +112,44 @@ class LoadBalancer { return $i; } + function getRandomNonLagged( $loads ) { + # Unset excessively lagged servers + $lags = $this->getLagTimes(); + foreach ( $lags as $i => $lag ) { + if ( isset( $this->mServers[$i]['max lag'] ) && $lag > $this->mServers[$i]['max lag'] ) { + unset( $loads[$i] ); + } + } + + + # Find out if all the slaves with non-zero load are lagged + $sum = 0; + foreach ( $loads as $load ) { + $sum += $load; + } + if ( $sum == 0 ) { + # No appropriate DB servers except maybe the master and some slaves with zero load + # Do NOT use the master + # Instead, this function will return false, triggering read-only mode, + # and a lagged slave will be used instead. + unset ( $loads[0] ); + } + + if ( count( $loads ) == 0 ) { + return false; + } + + wfDebug( var_export( $loads, true ) ); + + # Return a random representative of the remainder + return $this->pickRandom( $loads ); + } + + function getReaderIndex() { + global $wgMaxLag, $wgReadOnly; + $fname = 'LoadBalancer::getReaderIndex'; wfProfileIn( $fname ); @@ -119,8 +163,19 @@ class LoadBalancer { # $loads is $this->mLoads except with elements knocked out if they # don't work $loads = $this->mLoads; + $done = false; + $totalElapsed = 0; do { - $i = $this->pickRandom( $loads ); + if ( $wgReadOnly ) { + $i = $this->pickRandom( $loads ); + } else { + $i = $this->getRandomNonLagged( $loads ); + if ( $i === false && count( $loads ) != 0 ) { + # All slaves lagged. Switch to read-only mode + $wgReadOnly = wfMsgNoDB( 'readonly_lag' ); + $i = $this->pickRandom( $loads ); + } + } if ( $i !== false ) { wfDebug( "Using reader #$i: {$this->mServers[$i]['host']}...\n" ); $this->openConnection( $i ); @@ -128,16 +183,32 @@ class LoadBalancer { if ( !$this->isOpen( $i ) ) { wfDebug( "Failed\n" ); unset( $loads[$i] ); - } elseif ( isset( $this->mServers[$i]['slave pos'] ) ) { - wfDebug( "Lagged slave\n" ); - $this->mLaggedSlaveMode = true; + $sleepTime = 0; } else { - wfDebug( "OK\n" ); + $status = $this->mConnections[$i]->getStatus(); + if ( isset( $this->mServers[$i]['max threads'] ) && + $status['Threads_running'] > $this->mServers[$i]['max threads'] ) + { + # Slave is lagged, wait for a while + $sleepTime = 5000 * $status['Threads_connected']; + + # If we reach the timeout and exit the loop, don't use it + $i = false; + } else { + $done = true; + $sleepTime = 0; + } } + } else { + $sleepTime = 500000; + } + if ( $sleepTime ) { + $totalElapsed += $sleepTime; + usleep( $sleepTime ); } - } while ( $i !== false && !$this->isOpen( $i ) ); + } while ( count( $loads ) && !$done && $totalElapsed / 1e6 < $this->mWaitTimeout ); - if ( $this->isOpen( $i ) ) { + if ( $i !== false && $this->isOpen( $i ) ) { $this->mReadIndex = $i; } else { $i = false; @@ -167,6 +238,7 @@ class LoadBalancer { * Otherwise sets a variable telling it to wait if such a connection is opened */ function waitFor( $file, $pos ) { + /* $fname = 'LoadBalancer::waitFor'; wfProfileIn( $fname ); @@ -187,12 +259,15 @@ class LoadBalancer { } } wfProfileOut( $fname ); + */ } /** * Wait for a given slave to catch up to the master pos stored in $this */ function doWait( $index ) { + return true; + /* global $wgMemc; $retVal = false; @@ -228,7 +303,7 @@ class LoadBalancer { wfDebug( "Done\n" ); } } - return $retVal; + return $retVal;*/ } /** @@ -459,6 +534,63 @@ class LoadBalancer { } return $success; } + + /** + * Get the hostname and lag time of the most-lagged slave + * This is useful for maintenance scripts that need to throttle their updates + */ + function getMaxLag() { + $maxLag = -1; + $host = ''; + foreach ( $this->mServers as $i => $conn ) { + if ( $this->openConnection( $i ) ) { + $lag = $this->mConnections[$i]->getLag(); + if ( $lag > $maxLag ) { + $maxLag = $lag; + $host = $this->mServers[$i]['host']; + } + } + } + return array( $host, $maxLag ); + } + + /** + * Get lag time for each DB + * Results are cached for a short time in memcached + */ + function getLagTimes() { + $expiry = 5; + $requestRate = 10; + + global $wgMemc; + $times = $wgMemc->get( 'lag_times' ); + if ( $times ) { + # Randomly recache with probability rising over $expiry + $elapsed = time() - $times['timestamp']; + $chance = max( 0, ( $expiry - $elapsed ) * $requestRate ); + if ( mt_rand( 0, $chance ) != 0 ) { + unset( $times['timestamp'] ); + return $times; + } + } + + # Cache key missing or expired + + $times = array(); + foreach ( $this->mServers as $i => $conn ) { + if ( $this->openConnection( $i ) ) { + $times[$i] = $this->mConnections[$i]->getLag(); + } + } + + # Add a timestamp key so we know when it was cached + $times['timestamp'] = time(); + $wgMemc->set( 'lag_times', $times, $expiry ); + + # But don't give the timestamp to the caller + unset($times['timestamp']); + return $times; + } } ?> diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 879f5e8f13..624ab6cf6a 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -611,7 +611,7 @@ class OutputPage { } function readOnlyPage( $source = null, $protected = false ) { - global $wgUser, $wgReadOnlyFile; + global $wgUser, $wgReadOnlyFile, $wgReadOnly; $this->setRobotpolicy( 'noindex,nofollow' ); $this->setArticleRelated( false ); @@ -621,7 +621,11 @@ class OutputPage { $this->addWikiText( wfMsg( 'protectedtext' ) ); } else { $this->setPageTitle( wfMsg( 'readonly' ) ); - $reason = file_get_contents( $wgReadOnlyFile ); + if ( $wgReadOnly ) { + $reason = $wgReadOnly; + } else { + $reason = file_get_contents( $wgReadOnlyFile ); + } $this->addWikiText( wfMsg( 'readonlytext', $reason ) ); } diff --git a/languages/Language.php b/languages/Language.php index ce983a6265..2186247a16 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -520,6 +520,7 @@ page that has been deleted.

If this is not the case, you may have found a bug in the software. Please report this to an administrator, making note of the URL.", +'readonly_lag' => "The database has been automatically locked while the slave database servers catch up to the master", 'internalerror' => 'Internal error', 'filecopyerror' => "Could not copy file \"$1\" to \"$2\".", 'filerenameerror' => "Could not rename file \"$1\" to \"$2\".", -- 2.20.1 From 528842e3a5fcab99bf123a83f60f9cb3b37b22a5 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 1 Jun 2005 08:18:34 +0000 Subject: [PATCH 04/16] * (bug 2053) Move comment whitespace trimming from edit page to save; leaves the whitespace from the section comment there on preview. --- RELEASE-NOTES | 2 ++ includes/EditPage.php | 2 +- includes/Revision.php | 6 ++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 30d06b2659..4529942300 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -233,6 +233,8 @@ Various bugfixes, small features, and a few experimental things: * Removed some obsolete UTF-8 converter functions * Fix function comment in debug dump of SQL statements * (bug 2275) Update search index more or less right on page move +* (bug 2053) Move comment whitespace trimming from edit page to save; + leaves the whitespace from the section comment there on preview. === Caveats === diff --git a/includes/EditPage.php b/includes/EditPage.php index 1aa9b3fd20..13b4615d71 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -197,7 +197,7 @@ class EditPage { $this->textbox1 = rtrim( $request->getText( 'wpTextbox1' ) ); $this->textbox2 = rtrim( $request->getText( 'wpTextbox2' ) ); $this->mMetaData = rtrim( $request->getText( 'metadata' ) ); - $this->summary = trim( $request->getText( 'wpSummary' ) ); + $this->summary = $request->getText( 'wpSummary' ); $this->edittime = $request->getVal( 'wpEdittime' ); if( is_null( $this->edittime ) ) { diff --git a/includes/Revision.php b/includes/Revision.php index b58d50c0af..cfe29f66d4 100644 --- a/includes/Revision.php +++ b/includes/Revision.php @@ -232,13 +232,15 @@ class Revision { $this->mId = isset( $row['id'] ) ? IntVal( $row['id'] ) : null; $this->mPage = isset( $row['page'] ) ? IntVal( $row['page'] ) : null; $this->mTextId = isset( $row['text_id'] ) ? IntVal( $row['text_id'] ) : null; - $this->mComment = isset( $row['comment'] ) ? StrVal( $row['comment'] ) : null; $this->mUserText = isset( $row['user_text'] ) ? StrVal( $row['user_text'] ) : $wgUser->getName(); $this->mUser = isset( $row['user'] ) ? IntVal( $row['user'] ) : $wgUser->getId(); $this->mMinorEdit = isset( $row['minor_edit'] ) ? IntVal( $row['minor_edit'] ) : 0; $this->mTimestamp = isset( $row['timestamp'] ) ? StrVal( $row['timestamp'] ) : wfTimestamp( TS_MW ); $this->mDeleted = isset( $row['deleted'] ) ? IntVal( $row['deleted'] ) : 0; - $this->mText = isset( $row['text'] ) ? StrVal( $row['text'] ) : null; + + // Enforce spacing trimming on supplied text + $this->mComment = isset( $row['comment'] ) ? trim( StrVal( $row['comment'] ) ) : null; + $this->mText = isset( $row['text'] ) ? rtrim( StrVal( $row['text'] ) ) : null; $this->mTitle = null; # Load on demand if needed $this->mCurrent = false; -- 2.20.1 From 10be9f4be54178fb84b661066659dce45ddd1c12 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 1 Jun 2005 10:29:34 +0000 Subject: [PATCH 05/16] * (bug 2274) Respect stub threshold in category page list Uses page_len field, so doesn't have to do extra lookups. --- includes/CategoryPage.php | 4 ++-- includes/Linker.php | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/includes/CategoryPage.php b/includes/CategoryPage.php index 2d09936f63..d7a1b40e5b 100644 --- a/includes/CategoryPage.php +++ b/includes/CategoryPage.php @@ -91,7 +91,7 @@ class CategoryPage extends Article { $limit = 200; $res = $dbr->select( array( 'page', 'categorylinks' ), - array( 'page_title', 'page_namespace', 'cl_sortkey' ), + array( 'page_title', 'page_namespace', 'page_len', 'cl_sortkey' ), array( $pageCondition, 'cl_from = page_id', 'cl_to' => $this->mTitle->getDBKey()), @@ -139,7 +139,7 @@ class CategoryPage extends Article { } } else { // Page in this category - array_push( $articles, $sk->makeKnownLinkObj( $title, $wgContLang->convert( $title->getText() ) ) ) ; + array_push( $articles, $sk->makeSizeLinkObj( $x->page_len, $title, $wgContLang->convert( $title->getText() ) ) ) ; array_push( $articles_start_char, $wgContLang->convert( $wgContLang->firstChar( $x->cl_sortkey ) ) ); } } diff --git a/includes/Linker.php b/includes/Linker.php index fdf5c88751..3bdbab9e90 100644 --- a/includes/Linker.php +++ b/includes/Linker.php @@ -309,6 +309,28 @@ class Linker { return $s; } + /** + * Generate either a normal exists-style link or a stub link, depending + * on the given page size. + * + * @param int $size + * @param Title $nt + * @param string $text + * @param string $query + * @param string $trail + * @param string $prefix + * @return string HTML of link + */ + function makeSizeLinkObj( $size, $nt, $text = '', $query = '', $trail = '', $prefix = '' ) { + global $wgUser; + $threshold = IntVal( $wgUser->getOption( 'stubthreshold' ) ); + if( $size < $threshold ) { + return $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix ); + } else { + return $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix ); + } + } + /** @todo document */ function makeSelfLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) { $u = $nt->escapeLocalURL( $query ); -- 2.20.1 From 4c2bbc057b1e8b8b0d15219f5206e16f53c13d89 Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Wed, 1 Jun 2005 19:06:46 +0000 Subject: [PATCH 06/16] updated --- maintenance/wikipedia-interwiki.sql | 256 +++++++++++++++++++++++++++- 1 file changed, 247 insertions(+), 9 deletions(-) diff --git a/maintenance/wikipedia-interwiki.sql b/maintenance/wikipedia-interwiki.sql index 77ab327b1c..55de53501e 100644 --- a/maintenance/wikipedia-interwiki.sql +++ b/maintenance/wikipedia-interwiki.sql @@ -2,18 +2,199 @@ -- for Wikipedia. REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES -('w','http://www.wikipedia.org/wiki/$1',1), -('m','http://meta.wikipedia.org/wiki/$1',1), -('meta','http://meta.wikipedia.org/wiki/$1',1), -('sep11','http://sep11.wikipedia.org/wiki/$1',1), -('simple','http://simple.wikipedia.org/wiki/$1',1), +('abbenormal','http://www.ourpla.net/cgi-bin/pikie.cgi?$1',0), +('acadwiki','http://xarch.tu-graz.ac.at/autocad/wiki/$1',0), +('acronym','http://www.acronymfinder.com/af-query.asp?String=exact&Acronym=$1',0), +('advogato','http://www.advogato.org/$1',0), +('aiwiki','http://www.ifi.unizh.ch/ailab/aiwiki/aiw.cgi?$1',0), +('alife','http://news.alife.org/wiki/index.php?$1',0), +('annotation','http://bayle.stanford.edu/crit/nph-med.cgi/$1',0), +('annotationwiki','http://www.seedwiki.com/page.cfm?wikiid=368&doc=$1',0), +('arxiv','http://www.arxiv.org/abs/$1',0), +('aspienetwiki','http://aspie.mela.de/Wiki/index.php?title=$1',0), +('bemi','http://bemi.free.fr/vikio/index.php?$1',0), +('benefitswiki','http://www.benefitslink.com/cgi-bin/wiki.cgi?$1',0), +('brasilwiki','http://rio.ifi.unizh.ch/brasilienwiki/index.php/$1',0), +('bridgeswiki','http://c2.com/w2/bridges/$1',0), +('bugzilla','http://bugzilla.wikipedia.org/show_bug.cgi?id=$1',1), +('c2find','http://c2.com/cgi/wiki?FindPage&value=$1',0), +('cache','http://www.google.com/search?q=cache:$1',0), +('ciscavate','http://ciscavate.org/index.php/$1',0), +('cliki','http://ww.telent.net/cliki/$1',0), +('cmwiki','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0), +('codersbase','http://www.codersbase.com/$1',0), +('commons','http://commons.wikimedia.org/wiki/$1',0), +('consciousness','http://teadvus.inspiral.org/',0), +('corpknowpedia','http://corpknowpedia.org/wiki/index.php/$1',0), +('creationmatters','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0), +('dejanews','http://www.deja.com/=dnc/getdoc.xp?AN=$1',0), +('demokraatia','http://wiki.demokraatia.ee/',0), +('dictionary','http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1',0), +('disinfopedia','http://www.disinfopedia.org/wiki.phtml?title=$1',0), +('diveintoosx','http://diveintoosx.org/$1',0), +('docbook','http://docbook.org/wiki/moin.cgi/$1',0), +('dolphinwiki','http://www.object-arts.com/wiki/html/Dolphin/$1',0), +('drumcorpswiki','http://www.drumcorpswiki.com/index.php/$1',0), +('dwjwiki','http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1',0), +('eĉei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), +('echei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), +('ecxei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), +('efnetceewiki','http://purl.net/wiki/c/$1',0), +('efnetcppwiki','http://purl.net/wiki/cpp/$1',0), +('efnetpythonwiki','http://purl.net/wiki/python/$1',0), +('efnetxmlwiki','http://purl.net/wiki/xml/$1',0), +('eljwiki','http://elj.sourceforge.net/phpwiki/index.php/$1',0), +('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1',0), +('elibre','http://enciclopedia.us.es/index.php/$1',0), +('eokulturcentro','http://esperanto.toulouse.free.fr/wakka.php?wiki=$1',0), +('evowiki','http://www.evowiki.org/index.php/$1',0), +('finalempire','http://final-empire.sourceforge.net/cgi-bin/wiki.pl?$1',0), +('firstwiki','http://firstwiki.org/index.php/$1',0), +('foldoc','http://www.foldoc.org/foldoc/foldoc.cgi?$1',0), +('foxwiki','http://fox.wikis.com/wc.dll?Wiki~$1',0), +('fr.be','http://fr.wikinations.be/$1',0), +('fr.ca','http://fr.ca.wikinations.org/$1',0), +('fr.fr','http://fr.fr.wikinations.org/$1',0), +('fr.org','http://fr.wikinations.org/$1',0), +('freebsdman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1',0), +('gamewiki','http://gamewiki.org/wiki/index.php/$1',0), +('gej','http://www.esperanto.de/cgi-bin/aktivikio/wiki.pl?$1',0), +('gentoo-wiki','http://gentoo-wiki.com/$1',0), +('globalvoices','http://cyber.law.harvard.edu/dyn/globalvoices/wiki/$1',0), +('gmailwiki','http://www.gmailwiki.com/index.php/$1',0), +('google','http://www.google.com/search?q=$1',0), +('googlegroups','http://groups.google.com/groups?q=$1',0), +('gotamac','http://www.got-a-mac.org/$1',0), +('greencheese','http://www.greencheese.org/$1',0), +('hammondwiki','http://www.dairiki.org/HammondWiki/index.php3?$1',0), +('haribeau','http://wiki.haribeau.de/cgi-bin/wiki.pl?$1',0), +('hewikisource','http://he.wikisource.org/wiki/$1',1), +('herzkinderwiki','http://www.herzkinderinfo.de/Mediawiki/index.php/$1',0), +('hrwiki','http://www.hrwiki.org/index.php/$1',0), +('iawiki','http://www.IAwiki.net/$1',0), +('imdb','http://us.imdb.com/Title?$1',0), +('infosecpedia','http://www.infosecpedia.org/pedia/index.php/$1',0), +('jargonfile','http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1',0), +('jefo','http://www.esperanto-jeunes.org/vikio/index.php?$1',0), +('jiniwiki','http://www.cdegroot.com/cgi-bin/jini?$1',0), +('jspwiki','http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=$1',0), +('kerimwiki','http://wiki.oxus.net/$1',0), +('kmwiki','http://www.voght.com/cgi-bin/pywiki?$1',0), +('knowhow','http://www2.iro.umontreal.ca/~paquetse/cgi-bin/wiki.cgi?$1',0), +('lanifexwiki','http://opt.lanifex.com/cgi-bin/wiki.pl?$1',0), +('lasvegaswiki','http://wiki.gmnow.com/index.php/$1',0), +('linuxwiki','http://www.linuxwiki.de/$1',0), +('lojban','http://www.lojban.org/tiki/tiki-index.php?page=$1',0), +('lqwiki','http://wiki.linuxquestions.org/wiki/$1',0), +('lugkr','http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1',0), +('lutherwiki','http://www.lutheranarchives.com/mw/index.php/$1',0), +('mail','http://mail.wikipedia.org/mailman/listinfo/$1',1), +('mathsongswiki','http://SeedWiki.com/page.cfm?wikiid=237&doc=$1',0), +('mbtest','http://www.usemod.com/cgi-bin/mbtest.pl?$1',0), +('meatball','http://www.usemod.com/cgi-bin/mb.pl?$1',0), +('mediazilla','http://bugzilla.wikipedia.org/$1',1), +('memoryalpha','http://www.memory-alpha.org/en/index.php/$1',0), +('metaweb','http://www.metaweb.com/wiki/wiki.phtml?title=$1',0), +('metawiki','http://sunir.org/apps/meta.pl?$1',0), +('metawikipedia','http://meta.wikimedia.org/wiki/$1',0), +('moinmoin','http://purl.net/wiki/moin/$1',0), +('mozillawiki','http://wiki.mozilla.org/index.php/$1',0), +('muweb','http://www.dunstable.com/scripts/MuWebWeb?$1',0), +('netvillage','http://www.netbros.com/?$1',0), +('oeis','http://www.research.att.com/cgi-bin/access.cgi/as/njas/sequences/eisA.cgi?Anum=$1',0), +('openfacts','http://openfacts.berlios.de/index.phtml?title=$1',0), +('openwiki','http://openwiki.com/?$1',0), +('opera7wiki','http://nontroppo.org/wiki/$1',0), +('orgpatterns','http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns?$1',0), +('osi reference model','http://wiki.tigma.ee/',0), +('pangalacticorg','http://www.pangalactic.org/Wiki/$1',0), +('personaltelco','http://www.personaltelco.net/index.cgi/$1',0), +('patwiki','http://gauss.ffii.org/$1',0), +('phpwiki','http://phpwiki.sourceforge.net/phpwiki/index.php?$1',0), +('pikie','http://pikie.darktech.org/cgi/pikie?$1',0), +('pmeg','http://www.bertilow.com/pmeg/$1.php',0), +('ppr','http://c2.com/cgi/wiki?$1',0), +('purlnet','http://purl.oclc.org/NET/$1',0), +('pythoninfo','http://www.python.org/cgi-bin/moinmoin/$1',0), +('pythonwiki','http://www.pythonwiki.de/$1',0), +('pywiki','http://www.voght.com/cgi-bin/pywiki?$1',0), +('raec','http://www.raec.clacso.edu.ar:8080/raec/Members/raecpedia/$1',0), +('revo','http://purl.org/NET/voko/revo/art/$1.html',0), +('rfc','http://www.rfc-editor.org/rfc/rfc$1.txt',0), +('s23wiki','http://is-root.de/wiki/index.php/$1',0), +('scoutpedia','http://www.scoutpedia.info/index.php/$1',0), +('seapig','http://www.seapig.org/$1',0), +('seattlewiki','http://seattlewiki.org/wiki/$1',0), +('seattlewireless','http://seattlewireless.net/?$1',0), +('seeds','http://www.IslandSeeds.org/wiki/$1',0), +('senseislibrary','http://senseis.xmp.net/?$1',0), +('shakti','http://cgi.algonet.se/htbin/cgiwrap/pgd/ShaktiWiki/$1',0), +('slashdot','http://slashdot.org/article.pl?sid=$1',0), +('smikipedia','http://www.smikipedia.org/$1',0), +('sockwiki','http://wiki.socklabs.com/$1',0), +('sourceforge','http://sourceforge.net/$1',0), +('squeak','http://minnow.cc.gatech.edu/squeak/$1',0), +('strikiwiki','http://ch.twi.tudelft.nl/~mostert/striki/teststriki.pl?$1',0), +('susning','http://www.susning.nu/$1',0), +('svgwiki','http://www.protocol7.com/svg-wiki/default.asp?$1',0), +('tavi','http://tavi.sourceforge.net/$1',0), +('tejo','http://www.tejo.org/vikio/$1',0), +('terrorwiki','http://www.liberalsagainstterrorism.com/wiki/index.php/$1',0), +('test','http://test.wikipedia.org/wiki/$1',1), +('tmbw','http://www.tmbw.net/wiki/index.php/$1',0), +('tmnet','http://www.technomanifestos.net/?$1',0), +('tmwiki','http://www.EasyTopicMaps.com/?page=$1',0), +('turismo','http://www.tejo.org/turismo/$1',0), +('theopedia','http://www.theopedia.com/$1',0), +('twiki','http://twiki.org/cgi-bin/view/$1',0), +('twistedwiki','http://purl.net/wiki/twisted/$1',0), +('uea','http://www.tejo.org/uea/$1',0), +('unreal','http://wiki.beyondunreal.com/wiki/$1',0), +('ursine','http://ursine.ca/$1',0), +('usej','http://www.tejo.org/usej/$1',0), +('usemod','http://www.usemod.com/cgi-bin/wiki.pl?$1',0), +('visualworks','http://wiki.cs.uiuc.edu/VisualWorks/$1',0), +('warpedview','http://www.warpedview.com/index.php/$1',0), +('webdevwikinl','http://www.promo-it.nl/WebDevWiki/index.php?page=$1',0), +('webisodes','http://www.webisodes.org/$1',0), +('webseitzwiki','http://webseitz.fluxent.com/wiki/$1',0), +('why','http://clublet.com/c/c/why?$1',0), +('wiki','http://c2.com/cgi/wiki?$1',0), +('wikia','http://www.wikia.com/wiki/index.php/$1',0), +('wikibooks','http://en.wikibooks.org/wiki/$1',1), +('wikicities','http://www.wikicities.com/index.php/$1',0), +('wikif1','http://www.wikif1.org/$1',0), +('wikinfo','http://www.wikinfo.org/wiki.php?title=$1',0), +('wikimedia','http://wikimediafoundation.org/wiki/$1',0), +('wikiquote','http://en.wikiquote.org/wiki/$1',1), +('wikinews','http://en.wikinews.org/wiki/$1',0), +('wikisource','http://sources.wikipedia.org/wiki/$1',1), +('wikispecies','http://species.wikipedia.org/wiki/$1',1), +('wikitravel','http://wikitravel.org/en/$1',0), +('wikiworld','http://WikiWorld.com/wiki/index.php/$1',0), +('wiktionary','http://en.wiktionary.org/wiki/$1',1), +('wlug','http://www.wlug.org.nz/$1',0), +('wlwiki','http://winslowslair.supremepixels.net/wiki/index.php/$1',0), +('ypsieyeball','http://sknkwrks.dyndns.org:1957/writewiki/wiki.pl?$1',0), +('zwiki','http://www.zwiki.org/$1',0), +('zzz wiki','http://wiki.zzz.ee/',0), +('wikt','http://en.wiktionary.org/wiki/$1',1), +('q','http://en.wikiquote.org/wiki/$1',1), +('b','http://en.wikibooks.org/wiki/$1',1), +('n','http://en.wikinews.org/wiki/$1',1), ('aa','http://aa.wikipedia.org/wiki/$1',1), ('ab','http://ab.wikipedia.org/wiki/$1',1), ('af','http://af.wikipedia.org/wiki/$1',1), +('ak','http://ak.wikipedia.org/wiki/$1',1), ('als','http://als.wikipedia.org/wiki/$1',1), ('am','http://am.wikipedia.org/wiki/$1',1), +('an','http://an.wikipedia.org/wiki/$1',1), +('ang','http://ang.wikipedia.org/wiki/$1',1), ('ar','http://ar.wikipedia.org/wiki/$1',1), +('arc','http://arc.wikipedia.org/wiki/$1',1), ('as','http://as.wikipedia.org/wiki/$1',1), +('ast','http://ast.wikipedia.org/wiki/$1',1), +('av','http://av.wikipedia.org/wiki/$1',1), ('ay','http://ay.wikipedia.org/wiki/$1',1), ('az','http://az.wikipedia.org/wiki/$1',1), ('ba','http://ba.wikipedia.org/wiki/$1',1), @@ -21,19 +202,28 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES ('bg','http://bg.wikipedia.org/wiki/$1',1), ('bh','http://bh.wikipedia.org/wiki/$1',1), ('bi','http://bi.wikipedia.org/wiki/$1',1), +('bm','http://bm.wikipedia.org/wiki/$1',1), ('bn','http://bn.wikipedia.org/wiki/$1',1), ('bo','http://bo.wikipedia.org/wiki/$1',1), +('br','http://br.wikipedia.org/wiki/$1',1), ('bs','http://bs.wikipedia.org/wiki/$1',1), ('ca','http://ca.wikipedia.org/wiki/$1',1), +('ce','http://ce.wikipedia.org/wiki/$1',1), +('ch','http://ch.wikipedia.org/wiki/$1',1), +('cho','http://cho.wikipedia.org/wiki/$1',1), ('chr','http://chr.wikipedia.org/wiki/$1',1), +('chy','http://chy.wikipedia.org/wiki/$1',1), ('co','http://co.wikipedia.org/wiki/$1',1), +('cr','http://cr.wikipedia.org/wiki/$1',1), ('cs','http://cs.wikipedia.org/wiki/$1',1), ('csb','http://csb.wikipedia.org/wiki/$1',1), +('cv','http://cv.wikipedia.org/wiki/$1',1), ('cy','http://cy.wikipedia.org/wiki/$1',1), ('da','http://da.wikipedia.org/wiki/$1',1), ('de','http://de.wikipedia.org/wiki/$1',1), -('dk','http://da.wikipedia.org/wiki/$1',1), +('dv','http://dv.wikipedia.org/wiki/$1',1), ('dz','http://dz.wikipedia.org/wiki/$1',1), +('ee','http://ee.wikipedia.org/wiki/$1',1), ('el','http://el.wikipedia.org/wiki/$1',1), ('en','http://en.wikipedia.org/wiki/$1',1), ('eo','http://eo.wikipedia.org/wiki/$1',1), @@ -41,46 +231,68 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES ('et','http://et.wikipedia.org/wiki/$1',1), ('eu','http://eu.wikipedia.org/wiki/$1',1), ('fa','http://fa.wikipedia.org/wiki/$1',1), +('ff','http://ff.wikipedia.org/wiki/$1',1), ('fi','http://fi.wikipedia.org/wiki/$1',1), ('fj','http://fj.wikipedia.org/wiki/$1',1), ('fo','http://fo.wikipedia.org/wiki/$1',1), ('fr','http://fr.wikipedia.org/wiki/$1',1), ('fy','http://fy.wikipedia.org/wiki/$1',1), +('fur','http://fur.wikipedia.org/wiki/$1',1), ('ga','http://ga.wikipedia.org/wiki/$1',1), ('gd','http://gd.wikipedia.org/wiki/$1',1), ('gl','http://gl.wikipedia.org/wiki/$1',1), ('gn','http://gn.wikipedia.org/wiki/$1',1), +('got','http://got.wikipedia.org/wiki/$1',1), ('gu','http://gu.wikipedia.org/wiki/$1',1), ('gv','http://gv.wikipedia.org/wiki/$1',1), ('ha','http://ha.wikipedia.org/wiki/$1',1), +('haw','http://haw.wikipedia.org/wiki/$1',1), ('he','http://he.wikipedia.org/wiki/$1',1), ('hi','http://hi.wikipedia.org/wiki/$1',1), +('ho','http://ho.wikipedia.org/wiki/$1',1), ('hr','http://hr.wikipedia.org/wiki/$1',1), +('ht','http://ht.wikipedia.org/wiki/$1',1), ('hu','http://hu.wikipedia.org/wiki/$1',1), ('hy','http://hy.wikipedia.org/wiki/$1',1), +('hz','http://hz.wikipedia.org/wiki/$1',1), ('ia','http://ia.wikipedia.org/wiki/$1',1), ('id','http://id.wikipedia.org/wiki/$1',1), +('ie','http://ie.wikipedia.org/wiki/$1',1), +('ig','http://ig.wikipedia.org/wiki/$1',1), +('ii','http://ii.wikipedia.org/wiki/$1',1), ('ik','http://ik.wikipedia.org/wiki/$1',1), ('io','http://io.wikipedia.org/wiki/$1',1), ('is','http://is.wikipedia.org/wiki/$1',1), ('it','http://it.wikipedia.org/wiki/$1',1), ('iu','http://iu.wikipedia.org/wiki/$1',1), ('ja','http://ja.wikipedia.org/wiki/$1',1), +('jbo','http://jbo.wikipedia.org/wiki/$1',1), ('jv','http://jv.wikipedia.org/wiki/$1',1), ('ka','http://ka.wikipedia.org/wiki/$1',1), +('kg','http://kg.wikipedia.org/wiki/$1',1), +('ki','http://ki.wikipedia.org/wiki/$1',1), +('kj','http://kj.wikipedia.org/wiki/$1',1), ('kk','http://kk.wikipedia.org/wiki/$1',1), ('kl','http://kl.wikipedia.org/wiki/$1',1), ('km','http://km.wikipedia.org/wiki/$1',1), ('kn','http://kn.wikipedia.org/wiki/$1',1), ('ko','http://ko.wikipedia.org/wiki/$1',1), +('kr','http://kr.wikipedia.org/wiki/$1',1), ('ks','http://ks.wikipedia.org/wiki/$1',1), ('ku','http://ku.wikipedia.org/wiki/$1',1), +('kv','http://kv.wikipedia.org/wiki/$1',1), +('kw','http://kw.wikipedia.org/wiki/$1',1), ('ky','http://ky.wikipedia.org/wiki/$1',1), ('la','http://la.wikipedia.org/wiki/$1',1), +('lb','http://lb.wikipedia.org/wiki/$1',1), +('lg','http://lg.wikipedia.org/wiki/$1',1), +('li','http://li.wikipedia.org/wiki/$1',1), +('ln','http://ln.wikipedia.org/wiki/$1',1), ('lo','http://lo.wikipedia.org/wiki/$1',1), ('lt','http://lt.wikipedia.org/wiki/$1',1), ('lv','http://lv.wikipedia.org/wiki/$1',1), ('mg','http://mg.wikipedia.org/wiki/$1',1), +('mh','http://mh.wikipedia.org/wiki/$1',1), ('mi','http://mi.wikipedia.org/wiki/$1',1), ('mk','http://mk.wikipedia.org/wiki/$1',1), ('ml','http://ml.wikipedia.org/wiki/$1',1), @@ -88,18 +300,25 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES ('mo','http://mo.wikipedia.org/wiki/$1',1), ('mr','http://mr.wikipedia.org/wiki/$1',1), ('ms','http://ms.wikipedia.org/wiki/$1',1), +('mt','http://mt.wikipedia.org/wiki/$1',1), +('mus','http://mus.wikipedia.org/wiki/$1',1), ('my','http://my.wikipedia.org/wiki/$1',1), ('na','http://na.wikipedia.org/wiki/$1',1), ('nah','http://nah.wikipedia.org/wiki/$1',1), -('nb', 'http://no.wikipedia.org/wiki/$1',1), +('nb','http://nb.wikipedia.org/wiki/$1',1), ('nds','http://nds.wikipedia.org/wiki/$1',1), ('ne','http://ne.wikipedia.org/wiki/$1',1), +('ng','http://ng.wikipedia.org/wiki/$1',1), ('nl','http://nl.wikipedia.org/wiki/$1',1), +('nn','http://nn.wikipedia.org/wiki/$1',1), ('no','http://no.wikipedia.org/wiki/$1',1), +('nv','http://nv.wikipedia.org/wiki/$1',1), +('ny','http://ny.wikipedia.org/wiki/$1',1), ('oc','http://oc.wikipedia.org/wiki/$1',1), ('om','http://om.wikipedia.org/wiki/$1',1), ('or','http://or.wikipedia.org/wiki/$1',1), ('pa','http://pa.wikipedia.org/wiki/$1',1), +('pi','http://pi.wikipedia.org/wiki/$1',1), ('pl','http://pl.wikipedia.org/wiki/$1',1), ('ps','http://ps.wikipedia.org/wiki/$1',1), ('pt','http://pt.wikipedia.org/wiki/$1',1), @@ -107,13 +326,18 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES ('rm','http://rm.wikipedia.org/wiki/$1',1), ('rn','http://rn.wikipedia.org/wiki/$1',1), ('ro','http://ro.wikipedia.org/wiki/$1',1), +('roa-rup','http://roa-rup.wikipedia.org/wiki/$1',1), ('ru','http://ru.wikipedia.org/wiki/$1',1), ('rw','http://rw.wikipedia.org/wiki/$1',1), ('sa','http://sa.wikipedia.org/wiki/$1',1), +('sc','http://sc.wikipedia.org/wiki/$1',1), +('scn','http://scn.wikipedia.org/wiki/$1',1), ('sd','http://sd.wikipedia.org/wiki/$1',1), +('se','http://se.wikipedia.org/wiki/$1',1), ('sg','http://sg.wikipedia.org/wiki/$1',1), ('sh','http://sh.wikipedia.org/wiki/$1',1), ('si','http://si.wikipedia.org/wiki/$1',1), +('simple','http://simple.wikipedia.org/wiki/$1',1), ('sk','http://sk.wikipedia.org/wiki/$1',1), ('sl','http://sl.wikipedia.org/wiki/$1',1), ('sm','http://sm.wikipedia.org/wiki/$1',1), @@ -133,18 +357,22 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES ('ti','http://ti.wikipedia.org/wiki/$1',1), ('tk','http://tk.wikipedia.org/wiki/$1',1), ('tl','http://tl.wikipedia.org/wiki/$1',1), +('tlh','http://tlh.wikipedia.org/wiki/$1',1), ('tn','http://tn.wikipedia.org/wiki/$1',1), ('to','http://to.wikipedia.org/wiki/$1',1), -('tp','http://tp.wikipedia.org/wiki/$1',1), +('tokipona','http://tokipona.wikipedia.org/wiki/$1',1), ('tpi','http://tpi.wikipedia.org/wiki/$1',1), ('tr','http://tr.wikipedia.org/wiki/$1',1), ('ts','http://ts.wikipedia.org/wiki/$1',1), ('tt','http://tt.wikipedia.org/wiki/$1',1), +('tum','http://tum.wikipedia.org/wiki/$1',1), ('tw','http://tw.wikipedia.org/wiki/$1',1), +('ty','http://ty.wikipedia.org/wiki/$1',1), ('ug','http://ug.wikipedia.org/wiki/$1',1), ('uk','http://uk.wikipedia.org/wiki/$1',1), ('ur','http://ur.wikipedia.org/wiki/$1',1), ('uz','http://uz.wikipedia.org/wiki/$1',1), +('ve','http://ve.wikipedia.org/wiki/$1',1), ('vi','http://vi.wikipedia.org/wiki/$1',1), ('vo','http://vo.wikipedia.org/wiki/$1',1), ('wa','http://wa.wikipedia.org/wiki/$1',1), @@ -154,6 +382,16 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES ('yo','http://yo.wikipedia.org/wiki/$1',1), ('za','http://za.wikipedia.org/wiki/$1',1), ('zh','http://zh.wikipedia.org/wiki/$1',1), +('zh-min-nan','http://zh-min-nan.wikipedia.org/wiki/$1',1), +('zu','http://zu.wikipedia.org/wiki/$1',1), ('zh-cn','http://zh.wikipedia.org/wiki/$1',1), ('zh-tw','http://zh.wikipedia.org/wiki/$1',1), -('zu','http://zu.wikipedia.org/wiki/$1',1); +('minnan','http://zh-min-nan.wikipedia.org/wiki/$1',1), +('zh-cfr','http://zh-min-nan.wikipedia.org/wiki/$1',1), +('dk','http://da.wikipedia.org/wiki/$1',1), +('w','http://en.wikipedia.org/wiki/$1',1), +('m','http://meta.wikimedia.org/wiki/$1',1), +('meta','http://meta.wikimedia.org/wiki/$1',1), +('sep11','http://sep11.wikipedia.org/wiki/$1',1), +('os','http://os.wikipedia.org/wiki/$1',1); + -- 2.20.1 From 892f4673cd166aae34875f25abffbe086c78474b Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Wed, 1 Jun 2005 19:13:03 +0000 Subject: [PATCH 07/16] moved external links to where they should be --- maintenance/interwiki.sql | 283 +++++++++++++++++----------- maintenance/wikipedia-interwiki.sql | 177 ----------------- 2 files changed, 175 insertions(+), 285 deletions(-) diff --git a/maintenance/interwiki.sql b/maintenance/interwiki.sql index 1b04ee976f..ca656e4613 100644 --- a/maintenance/interwiki.sql +++ b/maintenance/interwiki.sql @@ -2,111 +2,178 @@ -- Default interwiki prefixes... REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES -('AbbeNormal','http://www.ourpla.net/cgi-bin/pikie.cgi?$1',0), -('AcadWiki','http://xarch.tu-graz.ac.at/autocad/wiki/$1',0), -('Acronym','http://www.acronymfinder.com/af-query.asp?String=exact&Acronym=$1',0), -('Advogato','http://www.advogato.org/$1',0), -('AIWiki','http://www.ifi.unizh.ch/ailab/aiwiki/aiw.cgi?$1',0), -('ALife','http://news.alife.org/wiki/index.php?$1',0), -('AndStuff','http://andstuff.org/wiki.php?$1',0), -('Annotation','http://bayle.stanford.edu/crit/nph-med.cgi/$1',0), -('AnnotationWiki','http://www.seedwiki.com/page.cfm?wikiid=368&doc=$1',0), -('AwarenessWiki','http://taoriver.net/aware/$1',0), -('BenefitsWiki','http://www.benefitslink.com/cgi-bin/wiki.cgi?$1',0), -('BridgesWiki','http://c2.com/w2/bridges/$1',0), -('C2find','http://c2.com/cgi/wiki?FindPage&value=$1',0), -('Cache','http://www.google.com/search?q=cache:$1',0), -('CLiki','http://ww.telent.net/cliki/$1',0), -('CmWiki','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0), -('CreationMatters','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0), -('DejaNews','http://www.deja.com/=dnc/getdoc.xp?AN=$1',0), -('Dictionary','http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1',0), -('DiveIntoOsx','http://diveintoosx.org/$1',0), -('DocBook','http://docbook.org/wiki/moin.cgi/$1',0), -('DolphinWiki','http://www.object-arts.com/wiki/html/Dolphin/$1',0), -('EfnetCeeWiki','http://purl.net/wiki/c/$1',0), -('EfnetCppWiki','http://purl.net/wiki/cpp/$1',0), -('EfnetPythonWiki','http://purl.net/wiki/python/$1',0), -('EfnetXmlWiki','http://purl.net/wiki/xml/$1',0), -('EljWiki','http://elj.sourceforge.net/phpwiki/index.php/$1',0), -('EmacsWiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1',0), -('FinalEmpire','http://final-empire.sourceforge.net/cgi-bin/wiki.pl?$1',0), -('Foldoc','http://www.foldoc.org/foldoc/foldoc.cgi?$1',0), -('FoxWiki','http://fox.wikis.com/wc.dll?Wiki~$1',0), -('FreeBSDman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1',0), -('Google','http://www.google.com/search?q=$1',0), -('GoogleGroups','http://groups.google.com/groups?q=$1',0), -('GreenCheese','http://www.greencheese.org/$1',0), -('HammondWiki','http://www.dairiki.org/HammondWiki/index.php3?$1',0), -('Haribeau','http://wiki.haribeau.de/cgi-bin/wiki.pl?$1',0), -('IAWiki','http://www.IAwiki.net/$1',0), -('IMDB','http://us.imdb.com/Title?$1',0), -('JargonFile','http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1',0), -('JiniWiki','http://www.cdegroot.com/cgi-bin/jini?$1',0), -('JspWiki','http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=$1',0), -('KmWiki','http://www.voght.com/cgi-bin/pywiki?$1',0), -('KnowHow','http://www2.iro.umontreal.ca/~paquetse/cgi-bin/wiki.cgi?$1',0), -('LanifexWiki','http://opt.lanifex.com/cgi-bin/wiki.pl?$1',0), -('LegoWiki','http://www.object-arts.com/wiki/html/Lego-Robotics/$1',0), -('LinuxWiki','http://www.linuxwiki.de/$1',0), -('LugKR','http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1',0), -('MathSongsWiki','http://SeedWiki.com/page.cfm?wikiid=237&doc=$1',0), -('MbTest','http://www.usemod.com/cgi-bin/mbtest.pl?$1',0), -('MeatBall','http://www.usemod.com/cgi-bin/mb.pl?$1',0), -('MetaWiki','http://sunir.org/apps/meta.pl?$1',0), -('MetaWikiPedia','http://meta.wikipedia.org/wiki/$1',0), -('MoinMoin','http://purl.net/wiki/moin/$1',0), -('MuWeb','http://www.dunstable.com/scripts/MuWebWeb?$1',0), -('NetVillage','http://www.netbros.com/?$1',0), -('OpenWiki','http://openwiki.com/?$1',0), -('OrgPatterns','http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns?$1',0), -('PangalacticOrg','http://www.pangalactic.org/Wiki/$1',0), -('PersonalTelco','http://www.personaltelco.net/index.cgi/$1',0), -('PhpWiki','http://phpwiki.sourceforge.net/phpwiki/index.php?$1',0), -('Pikie','http://pikie.darktech.org/cgi/pikie?$1',0), -('PPR','http://c2.com/cgi/wiki?$1',0), -('PurlNet','http://purl.oclc.org/NET/$1',0), -('PythonInfo','http://www.python.org/cgi-bin/moinmoin/$1',0), -('PythonWiki','http://www.pythonwiki.de/$1',0), -('PyWiki','http://www.voght.com/cgi-bin/pywiki?$1',0), -('RFC','http://www.rfc-editor.org/rfc/rfc$1.txt',0), -('SeaPig','http://www.seapig.org/ $1',0), -('SeattleWireless','http://seattlewireless.net/?$1',0), -('SenseisLibrary','http://senseis.xmp.net/?$1',0), -('Shakti','http://cgi.algonet.se/htbin/cgiwrap/pgd/ShaktiWiki/$1',0), -('SourceForge','http://sourceforge.net/$1',0), -('Squeak','http://minnow.cc.gatech.edu/squeak/$1',0), -('StrikiWiki','http://ch.twi.tudelft.nl/~mostert/striki/teststriki.pl?$1',0), -('SVGWiki','http://www.protocol7.com/svg-wiki/default.asp?$1',0), -('Tavi','http://tavi.sourceforge.net/index.php?$1',0), -('TmNet','http://www.technomanifestos.net/?$1',0), -('TMwiki','http://www.EasyTopicMaps.com/?page=$1',0), -('TWiki','http://twiki.org/cgi-bin/view/$1',0), -('TwistedWiki','http://purl.net/wiki/twisted/$1',0), -('Unreal','http://wiki.beyondunreal.com/wiki/$1',0), -('UseMod','http://www.usemod.com/cgi-bin/wiki.pl?$1',0), -('VisualWorks','http://wiki.cs.uiuc.edu/VisualWorks/$1',0), -('WebDevWikiNL','http://www.promo-it.nl/WebDevWiki/index.php?page=$1',0), -('WebSeitzWiki','http://webseitz.fluxent.com/wiki/$1',0), -('Why','http://clublet.com/c/c/why?$1',0), -('Wiki','http://c2.com/cgi/wiki?$1',0), -('WikiPedia','http://en.wikipedia.org/wiki/$1',0), -('Wiktionary','http://en.wiktionary.org/wiki/$1',0), -('Wikiquote','http://en.wikiquote.org/wiki/$1',0), -('WikiWorld','http://WikiWorld.com/wiki/index.php/$1',0), -('YpsiEyeball','http://sknkwrks.dyndns.org:1957/writewiki/wiki.pl?$1',0), -('ZWiki','http://www.zwiki.org/$1',0), -('ReVo','http://purl.org/NET/voko/revo/art/$1.html',0), -('EcheI','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), -('EcxeI','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), -('EĉeI','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), -('JEFO','http://www.esperanto-jeunes.org/vikio/index.php?$1',0), -('PMEG','http://www.bertilow.com/pmeg/$1.php',0), -('TEJO','http://www.tejo.org/vikio/$1',0), -('USEJ','http://www.tejo.org/usej/$1',0), -('UEA','http://www.tejo.org/uea/$1',0), -('Turismo','http://www.tejo.org/turismo/$1',0), -('GEJ','http://www.esperanto.de/cgi-bin/aktivikio/wiki.pl?$1',0), -('BEMI','http://bemi.free.fr/vikio/index.php?$1',0), -('EnciclopediaLibre','http://enciclopedia.us.es/index.php/$1',0), -('WikiBooks','http://en.wikibooks.org/wiki/$1',0); +('abbenormal','http://www.ourpla.net/cgi-bin/pikie.cgi?$1',0), +('acadwiki','http://xarch.tu-graz.ac.at/autocad/wiki/$1',0), +('acronym','http://www.acronymfinder.com/af-query.asp?String=exact&Acronym=$1',0), +('advogato','http://www.advogato.org/$1',0), +('aiwiki','http://www.ifi.unizh.ch/ailab/aiwiki/aiw.cgi?$1',0), +('alife','http://news.alife.org/wiki/index.php?$1',0), +('annotation','http://bayle.stanford.edu/crit/nph-med.cgi/$1',0), +('annotationwiki','http://www.seedwiki.com/page.cfm?wikiid=368&doc=$1',0), +('arxiv','http://www.arxiv.org/abs/$1',0), +('aspienetwiki','http://aspie.mela.de/Wiki/index.php?title=$1',0), +('bemi','http://bemi.free.fr/vikio/index.php?$1',0), +('benefitswiki','http://www.benefitslink.com/cgi-bin/wiki.cgi?$1',0), +('brasilwiki','http://rio.ifi.unizh.ch/brasilienwiki/index.php/$1',0), +('bridgeswiki','http://c2.com/w2/bridges/$1',0), +('c2find','http://c2.com/cgi/wiki?FindPage&value=$1',0), +('cache','http://www.google.com/search?q=cache:$1',0), +('ciscavate','http://ciscavate.org/index.php/$1',0), +('cliki','http://ww.telent.net/cliki/$1',0), +('cmwiki','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0), +('codersbase','http://www.codersbase.com/$1',0), +('commons','http://commons.wikimedia.org/wiki/$1',0), +('consciousness','http://teadvus.inspiral.org/',0), +('corpknowpedia','http://corpknowpedia.org/wiki/index.php/$1',0), +('creationmatters','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0), +('dejanews','http://www.deja.com/=dnc/getdoc.xp?AN=$1',0), +('demokraatia','http://wiki.demokraatia.ee/',0), +('dictionary','http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1',0), +('disinfopedia','http://www.disinfopedia.org/wiki.phtml?title=$1',0), +('diveintoosx','http://diveintoosx.org/$1',0), +('docbook','http://docbook.org/wiki/moin.cgi/$1',0), +('dolphinwiki','http://www.object-arts.com/wiki/html/Dolphin/$1',0), +('drumcorpswiki','http://www.drumcorpswiki.com/index.php/$1',0), +('dwjwiki','http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1',0), +('eĉei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), +('echei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), +('ecxei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), +('efnetceewiki','http://purl.net/wiki/c/$1',0), +('efnetcppwiki','http://purl.net/wiki/cpp/$1',0), +('efnetpythonwiki','http://purl.net/wiki/python/$1',0), +('efnetxmlwiki','http://purl.net/wiki/xml/$1',0), +('eljwiki','http://elj.sourceforge.net/phpwiki/index.php/$1',0), +('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1',0), +('elibre','http://enciclopedia.us.es/index.php/$1',0), +('eokulturcentro','http://esperanto.toulouse.free.fr/wakka.php?wiki=$1',0), +('evowiki','http://www.evowiki.org/index.php/$1',0), +('finalempire','http://final-empire.sourceforge.net/cgi-bin/wiki.pl?$1',0), +('firstwiki','http://firstwiki.org/index.php/$1',0), +('foldoc','http://www.foldoc.org/foldoc/foldoc.cgi?$1',0), +('foxwiki','http://fox.wikis.com/wc.dll?Wiki~$1',0), +('fr.be','http://fr.wikinations.be/$1',0), +('fr.ca','http://fr.ca.wikinations.org/$1',0), +('fr.fr','http://fr.fr.wikinations.org/$1',0), +('fr.org','http://fr.wikinations.org/$1',0), +('freebsdman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1',0), +('gamewiki','http://gamewiki.org/wiki/index.php/$1',0), +('gej','http://www.esperanto.de/cgi-bin/aktivikio/wiki.pl?$1',0), +('gentoo-wiki','http://gentoo-wiki.com/$1',0), +('globalvoices','http://cyber.law.harvard.edu/dyn/globalvoices/wiki/$1',0), +('gmailwiki','http://www.gmailwiki.com/index.php/$1',0), +('google','http://www.google.com/search?q=$1',0), +('googlegroups','http://groups.google.com/groups?q=$1',0), +('gotamac','http://www.got-a-mac.org/$1',0), +('greencheese','http://www.greencheese.org/$1',0), +('hammondwiki','http://www.dairiki.org/HammondWiki/index.php3?$1',0), +('haribeau','http://wiki.haribeau.de/cgi-bin/wiki.pl?$1',0), +('hewikisource','http://he.wikisource.org/wiki/$1',1), +('herzkinderwiki','http://www.herzkinderinfo.de/Mediawiki/index.php/$1',0), +('hrwiki','http://www.hrwiki.org/index.php/$1',0), +('iawiki','http://www.IAwiki.net/$1',0), +('imdb','http://us.imdb.com/Title?$1',0), +('infosecpedia','http://www.infosecpedia.org/pedia/index.php/$1',0), +('jargonfile','http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1',0), +('jefo','http://www.esperanto-jeunes.org/vikio/index.php?$1',0), +('jiniwiki','http://www.cdegroot.com/cgi-bin/jini?$1',0), +('jspwiki','http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=$1',0), +('kerimwiki','http://wiki.oxus.net/$1',0), +('kmwiki','http://www.voght.com/cgi-bin/pywiki?$1',0), +('knowhow','http://www2.iro.umontreal.ca/~paquetse/cgi-bin/wiki.cgi?$1',0), +('lanifexwiki','http://opt.lanifex.com/cgi-bin/wiki.pl?$1',0), +('lasvegaswiki','http://wiki.gmnow.com/index.php/$1',0), +('linuxwiki','http://www.linuxwiki.de/$1',0), +('lojban','http://www.lojban.org/tiki/tiki-index.php?page=$1',0), +('lqwiki','http://wiki.linuxquestions.org/wiki/$1',0), +('lugkr','http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1',0), +('lutherwiki','http://www.lutheranarchives.com/mw/index.php/$1',0), +('mathsongswiki','http://SeedWiki.com/page.cfm?wikiid=237&doc=$1',0), +('mbtest','http://www.usemod.com/cgi-bin/mbtest.pl?$1',0), +('meatball','http://www.usemod.com/cgi-bin/mb.pl?$1',0), +('mediazilla','http://bugzilla.wikipedia.org/$1',1), +('memoryalpha','http://www.memory-alpha.org/en/index.php/$1',0), +('metaweb','http://www.metaweb.com/wiki/wiki.phtml?title=$1',0), +('metawiki','http://sunir.org/apps/meta.pl?$1',0), +('metawikipedia','http://meta.wikimedia.org/wiki/$1',0), +('moinmoin','http://purl.net/wiki/moin/$1',0), +('mozillawiki','http://wiki.mozilla.org/index.php/$1',0), +('muweb','http://www.dunstable.com/scripts/MuWebWeb?$1',0), +('netvillage','http://www.netbros.com/?$1',0), +('oeis','http://www.research.att.com/cgi-bin/access.cgi/as/njas/sequences/eisA.cgi?Anum=$1',0), +('openfacts','http://openfacts.berlios.de/index.phtml?title=$1',0), +('openwiki','http://openwiki.com/?$1',0), +('opera7wiki','http://nontroppo.org/wiki/$1',0), +('orgpatterns','http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns?$1',0), +('osi reference model','http://wiki.tigma.ee/',0), +('pangalacticorg','http://www.pangalactic.org/Wiki/$1',0), +('personaltelco','http://www.personaltelco.net/index.cgi/$1',0), +('patwiki','http://gauss.ffii.org/$1',0), +('phpwiki','http://phpwiki.sourceforge.net/phpwiki/index.php?$1',0), +('pikie','http://pikie.darktech.org/cgi/pikie?$1',0), +('pmeg','http://www.bertilow.com/pmeg/$1.php',0), +('ppr','http://c2.com/cgi/wiki?$1',0), +('purlnet','http://purl.oclc.org/NET/$1',0), +('pythoninfo','http://www.python.org/cgi-bin/moinmoin/$1',0), +('pythonwiki','http://www.pythonwiki.de/$1',0), +('pywiki','http://www.voght.com/cgi-bin/pywiki?$1',0), +('raec','http://www.raec.clacso.edu.ar:8080/raec/Members/raecpedia/$1',0), +('revo','http://purl.org/NET/voko/revo/art/$1.html',0), +('rfc','http://www.rfc-editor.org/rfc/rfc$1.txt',0), +('s23wiki','http://is-root.de/wiki/index.php/$1',0), +('scoutpedia','http://www.scoutpedia.info/index.php/$1',0), +('seapig','http://www.seapig.org/$1',0), +('seattlewiki','http://seattlewiki.org/wiki/$1',0), +('seattlewireless','http://seattlewireless.net/?$1',0), +('seeds','http://www.IslandSeeds.org/wiki/$1',0), +('senseislibrary','http://senseis.xmp.net/?$1',0), +('shakti','http://cgi.algonet.se/htbin/cgiwrap/pgd/ShaktiWiki/$1',0), +('slashdot','http://slashdot.org/article.pl?sid=$1',0), +('smikipedia','http://www.smikipedia.org/$1',0), +('sockwiki','http://wiki.socklabs.com/$1',0), +('sourceforge','http://sourceforge.net/$1',0), +('squeak','http://minnow.cc.gatech.edu/squeak/$1',0), +('strikiwiki','http://ch.twi.tudelft.nl/~mostert/striki/teststriki.pl?$1',0), +('susning','http://www.susning.nu/$1',0), +('svgwiki','http://www.protocol7.com/svg-wiki/default.asp?$1',0), +('tavi','http://tavi.sourceforge.net/$1',0), +('tejo','http://www.tejo.org/vikio/$1',0), +('terrorwiki','http://www.liberalsagainstterrorism.com/wiki/index.php/$1',0), +('tmbw','http://www.tmbw.net/wiki/index.php/$1',0), +('tmnet','http://www.technomanifestos.net/?$1',0), +('tmwiki','http://www.EasyTopicMaps.com/?page=$1',0), +('turismo','http://www.tejo.org/turismo/$1',0), +('theopedia','http://www.theopedia.com/$1',0), +('twiki','http://twiki.org/cgi-bin/view/$1',0), +('twistedwiki','http://purl.net/wiki/twisted/$1',0), +('uea','http://www.tejo.org/uea/$1',0), +('unreal','http://wiki.beyondunreal.com/wiki/$1',0), +('ursine','http://ursine.ca/$1',0), +('usej','http://www.tejo.org/usej/$1',0), +('usemod','http://www.usemod.com/cgi-bin/wiki.pl?$1',0), +('visualworks','http://wiki.cs.uiuc.edu/VisualWorks/$1',0), +('warpedview','http://www.warpedview.com/index.php/$1',0), +('webdevwikinl','http://www.promo-it.nl/WebDevWiki/index.php?page=$1',0), +('webisodes','http://www.webisodes.org/$1',0), +('webseitzwiki','http://webseitz.fluxent.com/wiki/$1',0), +('why','http://clublet.com/c/c/why?$1',0), +('wiki','http://c2.com/cgi/wiki?$1',0), +('wikia','http://www.wikia.com/wiki/index.php/$1',0), +('wikibooks','http://en.wikibooks.org/wiki/$1',1), +('wikicities','http://www.wikicities.com/index.php/$1',0), +('wikif1','http://www.wikif1.org/$1',0), +('wikinfo','http://www.wikinfo.org/wiki.php?title=$1',0), +('wikimedia','http://wikimediafoundation.org/wiki/$1',0), +('wikiquote','http://en.wikiquote.org/wiki/$1',1), +('wikinews','http://en.wikinews.org/wiki/$1',0), +('wikisource','http://sources.wikipedia.org/wiki/$1',1), +('wikispecies','http://species.wikipedia.org/wiki/$1',1), +('wikitravel','http://wikitravel.org/en/$1',0), +('wikiworld','http://WikiWorld.com/wiki/index.php/$1',0), +('wiktionary','http://en.wiktionary.org/wiki/$1',1), +('wlug','http://www.wlug.org.nz/$1',0), +('wlwiki','http://winslowslair.supremepixels.net/wiki/index.php/$1',0), +('ypsieyeball','http://sknkwrks.dyndns.org:1957/writewiki/wiki.pl?$1',0), +('zwiki','http://www.zwiki.org/$1',0), +('zzz wiki','http://wiki.zzz.ee/',0), +('wikt','http://en.wiktionary.org/wiki/$1',1); + diff --git a/maintenance/wikipedia-interwiki.sql b/maintenance/wikipedia-interwiki.sql index 55de53501e..c6e4883f0f 100644 --- a/maintenance/wikipedia-interwiki.sql +++ b/maintenance/wikipedia-interwiki.sql @@ -2,183 +2,6 @@ -- for Wikipedia. REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES -('abbenormal','http://www.ourpla.net/cgi-bin/pikie.cgi?$1',0), -('acadwiki','http://xarch.tu-graz.ac.at/autocad/wiki/$1',0), -('acronym','http://www.acronymfinder.com/af-query.asp?String=exact&Acronym=$1',0), -('advogato','http://www.advogato.org/$1',0), -('aiwiki','http://www.ifi.unizh.ch/ailab/aiwiki/aiw.cgi?$1',0), -('alife','http://news.alife.org/wiki/index.php?$1',0), -('annotation','http://bayle.stanford.edu/crit/nph-med.cgi/$1',0), -('annotationwiki','http://www.seedwiki.com/page.cfm?wikiid=368&doc=$1',0), -('arxiv','http://www.arxiv.org/abs/$1',0), -('aspienetwiki','http://aspie.mela.de/Wiki/index.php?title=$1',0), -('bemi','http://bemi.free.fr/vikio/index.php?$1',0), -('benefitswiki','http://www.benefitslink.com/cgi-bin/wiki.cgi?$1',0), -('brasilwiki','http://rio.ifi.unizh.ch/brasilienwiki/index.php/$1',0), -('bridgeswiki','http://c2.com/w2/bridges/$1',0), -('bugzilla','http://bugzilla.wikipedia.org/show_bug.cgi?id=$1',1), -('c2find','http://c2.com/cgi/wiki?FindPage&value=$1',0), -('cache','http://www.google.com/search?q=cache:$1',0), -('ciscavate','http://ciscavate.org/index.php/$1',0), -('cliki','http://ww.telent.net/cliki/$1',0), -('cmwiki','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0), -('codersbase','http://www.codersbase.com/$1',0), -('commons','http://commons.wikimedia.org/wiki/$1',0), -('consciousness','http://teadvus.inspiral.org/',0), -('corpknowpedia','http://corpknowpedia.org/wiki/index.php/$1',0), -('creationmatters','http://www.ourpla.net/cgi-bin/wiki.pl?$1',0), -('dejanews','http://www.deja.com/=dnc/getdoc.xp?AN=$1',0), -('demokraatia','http://wiki.demokraatia.ee/',0), -('dictionary','http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1',0), -('disinfopedia','http://www.disinfopedia.org/wiki.phtml?title=$1',0), -('diveintoosx','http://diveintoosx.org/$1',0), -('docbook','http://docbook.org/wiki/moin.cgi/$1',0), -('dolphinwiki','http://www.object-arts.com/wiki/html/Dolphin/$1',0), -('drumcorpswiki','http://www.drumcorpswiki.com/index.php/$1',0), -('dwjwiki','http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1',0), -('eĉei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), -('echei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), -('ecxei','http://www.ikso.net/cgi-bin/wiki.pl?$1',0), -('efnetceewiki','http://purl.net/wiki/c/$1',0), -('efnetcppwiki','http://purl.net/wiki/cpp/$1',0), -('efnetpythonwiki','http://purl.net/wiki/python/$1',0), -('efnetxmlwiki','http://purl.net/wiki/xml/$1',0), -('eljwiki','http://elj.sourceforge.net/phpwiki/index.php/$1',0), -('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1',0), -('elibre','http://enciclopedia.us.es/index.php/$1',0), -('eokulturcentro','http://esperanto.toulouse.free.fr/wakka.php?wiki=$1',0), -('evowiki','http://www.evowiki.org/index.php/$1',0), -('finalempire','http://final-empire.sourceforge.net/cgi-bin/wiki.pl?$1',0), -('firstwiki','http://firstwiki.org/index.php/$1',0), -('foldoc','http://www.foldoc.org/foldoc/foldoc.cgi?$1',0), -('foxwiki','http://fox.wikis.com/wc.dll?Wiki~$1',0), -('fr.be','http://fr.wikinations.be/$1',0), -('fr.ca','http://fr.ca.wikinations.org/$1',0), -('fr.fr','http://fr.fr.wikinations.org/$1',0), -('fr.org','http://fr.wikinations.org/$1',0), -('freebsdman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1',0), -('gamewiki','http://gamewiki.org/wiki/index.php/$1',0), -('gej','http://www.esperanto.de/cgi-bin/aktivikio/wiki.pl?$1',0), -('gentoo-wiki','http://gentoo-wiki.com/$1',0), -('globalvoices','http://cyber.law.harvard.edu/dyn/globalvoices/wiki/$1',0), -('gmailwiki','http://www.gmailwiki.com/index.php/$1',0), -('google','http://www.google.com/search?q=$1',0), -('googlegroups','http://groups.google.com/groups?q=$1',0), -('gotamac','http://www.got-a-mac.org/$1',0), -('greencheese','http://www.greencheese.org/$1',0), -('hammondwiki','http://www.dairiki.org/HammondWiki/index.php3?$1',0), -('haribeau','http://wiki.haribeau.de/cgi-bin/wiki.pl?$1',0), -('hewikisource','http://he.wikisource.org/wiki/$1',1), -('herzkinderwiki','http://www.herzkinderinfo.de/Mediawiki/index.php/$1',0), -('hrwiki','http://www.hrwiki.org/index.php/$1',0), -('iawiki','http://www.IAwiki.net/$1',0), -('imdb','http://us.imdb.com/Title?$1',0), -('infosecpedia','http://www.infosecpedia.org/pedia/index.php/$1',0), -('jargonfile','http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1',0), -('jefo','http://www.esperanto-jeunes.org/vikio/index.php?$1',0), -('jiniwiki','http://www.cdegroot.com/cgi-bin/jini?$1',0), -('jspwiki','http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=$1',0), -('kerimwiki','http://wiki.oxus.net/$1',0), -('kmwiki','http://www.voght.com/cgi-bin/pywiki?$1',0), -('knowhow','http://www2.iro.umontreal.ca/~paquetse/cgi-bin/wiki.cgi?$1',0), -('lanifexwiki','http://opt.lanifex.com/cgi-bin/wiki.pl?$1',0), -('lasvegaswiki','http://wiki.gmnow.com/index.php/$1',0), -('linuxwiki','http://www.linuxwiki.de/$1',0), -('lojban','http://www.lojban.org/tiki/tiki-index.php?page=$1',0), -('lqwiki','http://wiki.linuxquestions.org/wiki/$1',0), -('lugkr','http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1',0), -('lutherwiki','http://www.lutheranarchives.com/mw/index.php/$1',0), -('mail','http://mail.wikipedia.org/mailman/listinfo/$1',1), -('mathsongswiki','http://SeedWiki.com/page.cfm?wikiid=237&doc=$1',0), -('mbtest','http://www.usemod.com/cgi-bin/mbtest.pl?$1',0), -('meatball','http://www.usemod.com/cgi-bin/mb.pl?$1',0), -('mediazilla','http://bugzilla.wikipedia.org/$1',1), -('memoryalpha','http://www.memory-alpha.org/en/index.php/$1',0), -('metaweb','http://www.metaweb.com/wiki/wiki.phtml?title=$1',0), -('metawiki','http://sunir.org/apps/meta.pl?$1',0), -('metawikipedia','http://meta.wikimedia.org/wiki/$1',0), -('moinmoin','http://purl.net/wiki/moin/$1',0), -('mozillawiki','http://wiki.mozilla.org/index.php/$1',0), -('muweb','http://www.dunstable.com/scripts/MuWebWeb?$1',0), -('netvillage','http://www.netbros.com/?$1',0), -('oeis','http://www.research.att.com/cgi-bin/access.cgi/as/njas/sequences/eisA.cgi?Anum=$1',0), -('openfacts','http://openfacts.berlios.de/index.phtml?title=$1',0), -('openwiki','http://openwiki.com/?$1',0), -('opera7wiki','http://nontroppo.org/wiki/$1',0), -('orgpatterns','http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns?$1',0), -('osi reference model','http://wiki.tigma.ee/',0), -('pangalacticorg','http://www.pangalactic.org/Wiki/$1',0), -('personaltelco','http://www.personaltelco.net/index.cgi/$1',0), -('patwiki','http://gauss.ffii.org/$1',0), -('phpwiki','http://phpwiki.sourceforge.net/phpwiki/index.php?$1',0), -('pikie','http://pikie.darktech.org/cgi/pikie?$1',0), -('pmeg','http://www.bertilow.com/pmeg/$1.php',0), -('ppr','http://c2.com/cgi/wiki?$1',0), -('purlnet','http://purl.oclc.org/NET/$1',0), -('pythoninfo','http://www.python.org/cgi-bin/moinmoin/$1',0), -('pythonwiki','http://www.pythonwiki.de/$1',0), -('pywiki','http://www.voght.com/cgi-bin/pywiki?$1',0), -('raec','http://www.raec.clacso.edu.ar:8080/raec/Members/raecpedia/$1',0), -('revo','http://purl.org/NET/voko/revo/art/$1.html',0), -('rfc','http://www.rfc-editor.org/rfc/rfc$1.txt',0), -('s23wiki','http://is-root.de/wiki/index.php/$1',0), -('scoutpedia','http://www.scoutpedia.info/index.php/$1',0), -('seapig','http://www.seapig.org/$1',0), -('seattlewiki','http://seattlewiki.org/wiki/$1',0), -('seattlewireless','http://seattlewireless.net/?$1',0), -('seeds','http://www.IslandSeeds.org/wiki/$1',0), -('senseislibrary','http://senseis.xmp.net/?$1',0), -('shakti','http://cgi.algonet.se/htbin/cgiwrap/pgd/ShaktiWiki/$1',0), -('slashdot','http://slashdot.org/article.pl?sid=$1',0), -('smikipedia','http://www.smikipedia.org/$1',0), -('sockwiki','http://wiki.socklabs.com/$1',0), -('sourceforge','http://sourceforge.net/$1',0), -('squeak','http://minnow.cc.gatech.edu/squeak/$1',0), -('strikiwiki','http://ch.twi.tudelft.nl/~mostert/striki/teststriki.pl?$1',0), -('susning','http://www.susning.nu/$1',0), -('svgwiki','http://www.protocol7.com/svg-wiki/default.asp?$1',0), -('tavi','http://tavi.sourceforge.net/$1',0), -('tejo','http://www.tejo.org/vikio/$1',0), -('terrorwiki','http://www.liberalsagainstterrorism.com/wiki/index.php/$1',0), -('test','http://test.wikipedia.org/wiki/$1',1), -('tmbw','http://www.tmbw.net/wiki/index.php/$1',0), -('tmnet','http://www.technomanifestos.net/?$1',0), -('tmwiki','http://www.EasyTopicMaps.com/?page=$1',0), -('turismo','http://www.tejo.org/turismo/$1',0), -('theopedia','http://www.theopedia.com/$1',0), -('twiki','http://twiki.org/cgi-bin/view/$1',0), -('twistedwiki','http://purl.net/wiki/twisted/$1',0), -('uea','http://www.tejo.org/uea/$1',0), -('unreal','http://wiki.beyondunreal.com/wiki/$1',0), -('ursine','http://ursine.ca/$1',0), -('usej','http://www.tejo.org/usej/$1',0), -('usemod','http://www.usemod.com/cgi-bin/wiki.pl?$1',0), -('visualworks','http://wiki.cs.uiuc.edu/VisualWorks/$1',0), -('warpedview','http://www.warpedview.com/index.php/$1',0), -('webdevwikinl','http://www.promo-it.nl/WebDevWiki/index.php?page=$1',0), -('webisodes','http://www.webisodes.org/$1',0), -('webseitzwiki','http://webseitz.fluxent.com/wiki/$1',0), -('why','http://clublet.com/c/c/why?$1',0), -('wiki','http://c2.com/cgi/wiki?$1',0), -('wikia','http://www.wikia.com/wiki/index.php/$1',0), -('wikibooks','http://en.wikibooks.org/wiki/$1',1), -('wikicities','http://www.wikicities.com/index.php/$1',0), -('wikif1','http://www.wikif1.org/$1',0), -('wikinfo','http://www.wikinfo.org/wiki.php?title=$1',0), -('wikimedia','http://wikimediafoundation.org/wiki/$1',0), -('wikiquote','http://en.wikiquote.org/wiki/$1',1), -('wikinews','http://en.wikinews.org/wiki/$1',0), -('wikisource','http://sources.wikipedia.org/wiki/$1',1), -('wikispecies','http://species.wikipedia.org/wiki/$1',1), -('wikitravel','http://wikitravel.org/en/$1',0), -('wikiworld','http://WikiWorld.com/wiki/index.php/$1',0), -('wiktionary','http://en.wiktionary.org/wiki/$1',1), -('wlug','http://www.wlug.org.nz/$1',0), -('wlwiki','http://winslowslair.supremepixels.net/wiki/index.php/$1',0), -('ypsieyeball','http://sknkwrks.dyndns.org:1957/writewiki/wiki.pl?$1',0), -('zwiki','http://www.zwiki.org/$1',0), -('zzz wiki','http://wiki.zzz.ee/',0), -('wikt','http://en.wiktionary.org/wiki/$1',1), ('q','http://en.wikiquote.org/wiki/$1',1), ('b','http://en.wikibooks.org/wiki/$1',1), ('n','http://en.wikinews.org/wiki/$1',1), -- 2.20.1 From 8ffbda06da3647569a25bd7c18a3047d1688df67 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 2 Jun 2005 00:24:31 +0000 Subject: [PATCH 08/16] * (bug 2173) Fatal error when removing an article with an empty title from the watchlist --- RELEASE-NOTES | 2 ++ includes/SpecialWatchlist.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 4529942300..d5a2fa82ed 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -235,6 +235,8 @@ Various bugfixes, small features, and a few experimental things: * (bug 2275) Update search index more or less right on page move * (bug 2053) Move comment whitespace trimming from edit page to save; leaves the whitespace from the section comment there on preview. +* (bug 2274) Respect stub threshold in category page list +* (bug 2173) Fatal error when removing an article with an empty title from the watchlist === Caveats === diff --git a/includes/SpecialWatchlist.php b/includes/SpecialWatchlist.php index f6833de5a5..97093d0dbf 100644 --- a/includes/SpecialWatchlist.php +++ b/includes/SpecialWatchlist.php @@ -50,7 +50,7 @@ function wfSpecialWatchlist( $par ) { $wgOut->addHTML( '

' ); foreach($id as $one) { $t = Title::newFromURL( $one ); - if($t->getDBkey() != '') { + if( !is_null( $t ) ) { $wl = WatchedItem::fromUserTitle( $wgUser, $t ); if( $wl->removeWatch() === false ) { $wgOut->addHTML( "
\n" . wfMsg( 'couldntremove', htmlspecialchars($one) ) ); -- 2.20.1 From bb97b4b73db0d78882552e16e801b1e172ffd03f Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 2 Jun 2005 01:34:15 +0000 Subject: [PATCH 09/16] Bug 1929: Incorrect comment in DefaultSettings.php --- includes/DefaultSettings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 58e250d591..bba8c6dc38 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -655,7 +655,7 @@ $wgHitcounterUpdateFreq = 1; # own risks. $wgWhitelistEdit = false; # true = user must login to edit. -$wgWhitelistRead = false; # Pages anonymous user may see, like: = array ( ":Main_Page", "Special:Userlogin", "Wikipedia:Help"); +$wgWhitelistRead = false; # Pages anonymous user may see, like: = array ( "Main Page", "Special:Userlogin", "Wikipedia:Help"); $wgWhitelistAccount = array ( 'user' => 1, 'sysop' => 1, 'developer' => 1 ); $wgAllowAnonymousMinor = false; # Allow anonymous users to mark changes as 'minor' -- 2.20.1 From 17cc63d4d9ae3316963446ff84b48780d8bcd96b Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 2 Jun 2005 03:12:54 +0000 Subject: [PATCH 10/16] * Removed -f parameter from mail() usage, likely to cause failures and bounces. --- RELEASE-NOTES | 1 + includes/UserMailer.php | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index d5a2fa82ed..d448708b2b 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -237,6 +237,7 @@ Various bugfixes, small features, and a few experimental things: leaves the whitespace from the section comment there on preview. * (bug 2274) Respect stub threshold in category page list * (bug 2173) Fatal error when removing an article with an empty title from the watchlist +* Removed -f parameter from mail() usage, likely to cause failures and bounces. === Caveats === diff --git a/includes/UserMailer.php b/includes/UserMailer.php index 7c1225c469..2bb3d9ab4d 100644 --- a/includes/UserMailer.php +++ b/includes/UserMailer.php @@ -93,8 +93,7 @@ function userMailer( $to, $from, $subject, $body, $replyto=false ) { $wgErrorString = ''; set_error_handler( 'mailErrorHandler' ); - # added -f parameter, see PHP manual for the fifth parameter when using the mail function - mail( $to, $subject, $body, $headers, " -f {$wgEmergencyContact}\n"); + mail( $to, $subject, $body, $headers ); restore_error_handler(); if ( $wgErrorString ) { -- 2.20.1 From 027243677ab2319c73c8ce6796977ff19f1c0432 Mon Sep 17 00:00:00 2001 From: Alexander Sigachov Date: Thu, 2 Jun 2005 19:50:46 +0000 Subject: [PATCH 11/16] new load balancing algorithm --- languages/LanguageRu.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/languages/LanguageRu.php b/languages/LanguageRu.php index fe80343d8d..d1e3f7526e 100644 --- a/languages/LanguageRu.php +++ b/languages/LanguageRu.php @@ -1,7 +1,7 @@ Если дело не в этом, то скорее всего, вы обнаружили ошибку в программном обеспечении вики. Пожалуйста, сообщите об этом администратору, указав URL.", +'readonly_lag' => "База данных автоматически заблокирована для проведения синхронизации ведущего и ведомых серверов.", 'internalerror' => 'Внутренняя ошибка', 'filecopyerror' => "Невозможно скопировать файл «$1» в «$2».", 'filerenameerror' => "Невозможно переименовать файл «$1» в «$2».", -- 2.20.1 From 1fbc4d8e661e097eb7ea13e338e2fbc3a123f42f Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 2 Jun 2005 22:39:48 +0000 Subject: [PATCH 12/16] Add test for bug 2130 --- maintenance/parserTests.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/maintenance/parserTests.txt b/maintenance/parserTests.txt index 16b1e36b79..6255dc659c 100644 --- a/maintenance/parserTests.txt +++ b/maintenance/parserTests.txt @@ -1081,6 +1081,15 @@ Interwiki link encoding conversion (bug 1636) !! end +!! test +Interwiki link with fragment (bug 2130) +!! input +[[MeatBall:SoftSecurity#foo]] +!! result +

MeatBall:SoftSecurity#foo +

+!! end + ## ## XHTML tidiness ### -- 2.20.1 From 84e2e2ff13dd257d9f72fb1defb939696626321a Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 3 Jun 2005 05:46:24 +0000 Subject: [PATCH 13/16] * (bug 2130) Fixed interwiki links with fragments --- RELEASE-NOTES | 1 + includes/Parser.php | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index d448708b2b..4cac32b865 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -238,6 +238,7 @@ Various bugfixes, small features, and a few experimental things: * (bug 2274) Respect stub threshold in category page list * (bug 2173) Fatal error when removing an article with an empty title from the watchlist * Removed -f parameter from mail() usage, likely to cause failures and bounces. +* (bug 2130) Fixed interwiki links with fragments === Caveats === diff --git a/includes/Parser.php b/includes/Parser.php index c2860034f9..7d32701bcc 100644 --- a/includes/Parser.php +++ b/includes/Parser.php @@ -140,7 +140,10 @@ class Parser $this->mStripState = array(); $this->mArgStack = array(); $this->mInPre = false; - $this->mInterwikiLinkHolders = array(); + $this->mInterwikiLinkHolders = array( + 'texts' => array(), + 'titles' => array() + ); $this->mLinkHolders = array( 'namespaces' => array(), 'dbkeys' => array(), @@ -1423,8 +1426,8 @@ class Parser list( $inside, $trail ) = Linker::splitTrail( $trail ); if ( $nt->isExternal() ) { - $iwRecord = array( $nt->getPrefixedDBkey(), $prefix.$text.$inside ); - $nr = array_push($this->mInterwikiLinkHolders, $iwRecord); + $nr = array_push( $this->mInterwikiLinkHolders['texts'], $prefix.$text.$inside ); + $this->mInterwikiLinkHolders['titles'][] =& $nt; $retVal = '{$trail}"; } else { $nr = array_push( $this->mLinkHolders['namespaces'], $nt->getNamespace() ); @@ -2481,7 +2484,7 @@ class Parser "\$this->mLinkHolders['texts'][\$1]", $canonized_headline ); $canonized_headline = preg_replace( '//e', - "\$this->mInterwikiLinkHolders[\$1][1]", + "\$this->mInterwikiLinkHolders['texts'][\$1]", $canonized_headline ); # strip out HTML @@ -2985,13 +2988,13 @@ class Parser # Now process interwiki link holders # This is quite a bit simpler than internal links - if ( !empty( $this->mInterwikiLinkHolders ) ) { + if ( !empty( $this->mInterwikiLinkHolders['texts'] ) ) { wfProfileIn( $fname.'-interwiki' ); # Make interwiki link HTML $wgOutputReplace = array(); - foreach( $this->mInterwikiLinkHolders as $i => $lh ) { - $s = $sk->makeLink( $lh[0], $lh[1] ); - $wgOutputReplace[] = $s; + foreach( $this->mInterwikiLinkHolders['texts'] as $key => $link ) { + $title = $this->mInterwikiLinkHolders['titles'][$key]; + $wgOutputReplace[$key] = $sk->makeLinkObj( $title, $link ); } $text = preg_replace_callback( @@ -3040,8 +3043,8 @@ class Parser return $this->mLinkHolders['texts'][$key]; } } elseif( $type == 'IWLINK' ) { - if( isset( $this->mInterwikiLinkHolders[$key][1] ) ) { - return $this->mInterwikiLinkHolders[$key][1]; + if( isset( $this->mInterwikiLinkHolders['texts'][$key] ) ) { + return $this->mInterwikiLinkHolders['texts'][$key]; } } return $matches[0]; -- 2.20.1 From 13eb618dd9f5cee7963f0119057d7173c1488f1d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 3 Jun 2005 08:12:48 +0000 Subject: [PATCH 14/16] * (bug 684) Accept an attribute parameter array on parser hook tags Some parts of http://bugzilla.wikimedia.org/attachment.cgi?id=96&action=view with heavy modification; using tag matching in the style we accept regular HTML elements, and decode attribute values to proper strings. --- RELEASE-NOTES | 1 + includes/Parser.php | 78 +++++++++++++++++++------ includes/Sanitizer.php | 127 +++++++++++++++++++++++++++++------------ 3 files changed, 151 insertions(+), 55 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 4cac32b865..923c14ba17 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -239,6 +239,7 @@ Various bugfixes, small features, and a few experimental things: * (bug 2173) Fatal error when removing an article with an empty title from the watchlist * Removed -f parameter from mail() usage, likely to cause failures and bounces. * (bug 2130) Fixed interwiki links with fragments +* (bug 684) Accept an attribute parameter array on parser hook tags === Caveats === diff --git a/includes/Parser.php b/includes/Parser.php index 7d32701bcc..d9fa2af7e7 100644 --- a/includes/Parser.php +++ b/includes/Parser.php @@ -258,38 +258,73 @@ class Parser * @access private * @static */ - function extractTags($tag, $text, &$content, $uniq_prefix = ''){ + function extractTagsAndParams($tag, $text, &$content, &$tags, &$params, $uniq_prefix = ''){ $rnd = $uniq_prefix . '-' . $tag . Parser::getRandomString(); if ( !$content ) { $content = array( ); } $n = 1; $stripped = ''; + + if ( !$tags ) { + $tags = array( ); + } + + if ( !$params ) { + $params = array( ); + } + + if( $tag == STRIP_COMMENTS ) { + $start = '//'; + } else { + $start = "/<$tag([^>]*)>/i"; + $end = "/<\\/$tag\\s*>/i"; + } while ( '' != $text ) { - if($tag==STRIP_COMMENTS) { - $p = preg_split( '//i', $p[1], 2 ); - } else { - $q = preg_split( "/<\\/\\s*$tag\\s*>/i", $p[1], 2 ); - } - $marker = $rnd . sprintf('%08X', $n++); - $content[$marker] = $q[0]; - $stripped .= $marker; $text = $q[1]; } } return $stripped; } + /** + * Wrapper function for extractTagsAndParams + * for cases where $tags and $params isn't needed + * i.e. where tags will never have params, like + * + * @access private + * @static + */ + function extractTags( $tag, $text, &$content, $uniq_prefix = '' ) { + $dummy_tags = array(); + $dummy_params = array(); + + return Parser::extractTagsAndParams( $tag, $text, $content, + $dummy_tags, $dummy_params, $uniq_prefix ); + } + /** * Strips and renders nowiki, pre, math, hiero * If $render is set, performs necessary rendering operations on plugins @@ -311,6 +346,8 @@ class Parser $pre_content = array(); $comment_content = array(); $ext_content = array(); + $ext_tags = array(); + $ext_params = array(); $gallery_content = array(); # Replace any instances of the placeholders @@ -387,12 +424,15 @@ class Parser # Extensions foreach ( $this->mTagHooks as $tag => $callback ) { $ext_content[$tag] = array(); - $text = Parser::extractTags( $tag, $text, $ext_content[$tag], $uniq_prefix ); + $text = Parser::extractTagsAndParams( $tag, $text, $ext_content[$tag], + $ext_tags[$tag], $ext_params[$tag], $uniq_prefix ); foreach( $ext_content[$tag] as $marker => $content ) { + $full_tag = $ext_tags[$tag][$marker]; + $params = $ext_params[$tag][$marker]; if ( $render ) { - $ext_content[$tag][$marker] = $callback( $content ); + $ext_content[$tag][$marker] = $callback( $content, $params ); } else { - $ext_content[$tag][$marker] = "<$tag>$content"; + $ext_content[$tag][$marker] = "$full_tag$content"; } } } diff --git a/includes/Sanitizer.php b/includes/Sanitizer.php index d28ed93af0..40016d93b2 100644 --- a/includes/Sanitizer.php +++ b/includes/Sanitizer.php @@ -36,6 +36,27 @@ define( 'MW_CHAR_REFS_REGEX', |&\#X([0-9A-Za-z]+); |(&)/x' ); +/** + * Regular expression to match HTML/XML attribute pairs within a tag. + * Allows some... latitude. + * Used in Sanitizer::fixTagAttributes and Sanitizer::decodeTagAttributes + */ +$attrib = '[A-Za-z0-9]'; +$space = '[\x09\x0a\x0d\x20]'; +define( 'MW_ATTRIBS_REGEX', + "/(?:^|$space)($attrib+) + ($space*=$space* + (?: + # The attribute value: quoted or alone + \"([^<\"]*)\" + | '([^<']*)' + | ([a-zA-Z0-9!#$%&()*,\\-.\\/:;<>?@[\\]^_`{|}~]+) + | (\#[0-9a-fA-F]+) # Technically wrong, but lots of + # colors are specified like this. + # We'll be normalizing it. + ) + )?(?=$space|\$)/sx" ); + /** * List of all named character entities defined in HTML 4.01 * http://www.w3.org/TR/html4/sgml/entities.html @@ -490,21 +511,8 @@ class Sanitizer { # Unquoted attribute # Since we quote this later, this can be anything distinguishable # from the end of the attribute - $attrib = '[A-Za-z0-9]'; - $space = '[\x09\x0a\x0d\x20]'; if( !preg_match_all( - "/(?:^|$space)($attrib+) - ($space*=$space* - (?: - # The attribute value: quoted or alone - \"([^<\"]*)\" - | '([^<']*)' - | ([a-zA-Z0-9!#$%&()*,\\-.\\/:;<>?@[\\]^_`{|}~]+) - | (\#[0-9a-fA-F]+) # Technically wrong, but lots of - # colors are specified like this. - # We'll be normalizing it. - ) - )?(?=$space|\$)/sx", + MW_ATTRIBS_REGEX, $text, $pairs, PREG_SET_ORDER ) ) { @@ -517,26 +525,11 @@ class Sanitizer { $attribute = strtolower( $set[1] ); if( !isset( $whitelist[$attribute] ) ) { continue; - } elseif( isset( $set[6] ) ) { - # Illegal #XXXXXX color with no quotes. - $value = Sanitizer::normalizeAttributeValue( $set[6] ); - } elseif( isset( $set[5] ) ) { - # No quotes. - $value = Sanitizer::normalizeAttributeValue( $set[5] ); - } elseif( isset( $set[4] ) ) { - # Single-quoted - $value = str_replace( '"', '"', - Sanitizer::normalizeAttributeValue( $set[4] ) ); - } elseif( isset( $set[3] ) ) { - # Double-quoted - $value = Sanitizer::normalizeAttributeValue( $set[3] ); - } elseif( !isset( $set[2] ) ) { - # In XHTML, attributes must have a value. - $value = $set[1]; - } else { - wfDebugDieBacktrace( "Tag conditions not met. This should never happen and is a bug." ); } + $raw = Sanitizer::getTagAttributeCallback( $set ); + $value = Sanitizer::normalizeAttributeValue( $raw ); + # Strip javascript "expression" from stylesheets. # http://msdn.microsoft.com/workshop/author/dhtml/overview/recalc.asp if( $attribute == 'style' && preg_match( @@ -557,6 +550,67 @@ class Sanitizer { } } + /** + * Return an associative array of attribute names and values from + * a partial tag string. Attribute names are forces to lowercase, + * character references are decoded to UTF-8 text. + * + * @param string + * @return array + */ + function decodeTagAttributes( $text ) { + $attribs = array(); + + if( trim( $text ) == '' ) { + return $attribs; + } + + if( !preg_match_all( + MW_ATTRIBS_REGEX, + $text, + $pairs, + PREG_SET_ORDER ) ) { + return $attribs; + } + + foreach( $pairs as $set ) { + $attribute = strtolower( $set[1] ); + $value = Sanitizer::getTagAttributeCallback( $set ); + $attribs[$attribute] = Sanitizer::decodeCharReferences( $value ); + } + return $attribs; + } + + /** + * Pick the appropriate attribute value from a match set from the + * MW_ATTRIBS_REGEX matches. + * + * @param array $set + * @return string + * @access private + */ + function getTagAttributeCallback( $set ) { + if( isset( $set[6] ) ) { + # Illegal #XXXXXX color with no quotes. + return $set[6]; + } elseif( isset( $set[5] ) ) { + # No quotes. + return $set[5]; + } elseif( isset( $set[4] ) ) { + # Single-quoted + return $set[4]; + } elseif( isset( $set[3] ) ) { + # Double-quoted + return $set[3]; + } elseif( !isset( $set[2] ) ) { + # In XHTML, attributes must have a value. + # For 'reduced' form, return explicitly the attribute name here. + return $set[1]; + } else { + wfDebugDieBacktrace( "Tag conditions not met. This should never happen and is a bug." ); + } + } + /** * Normalize whitespace and character references in an XML source- * encoded text for an attribute value. @@ -570,10 +624,11 @@ class Sanitizer { * @access private */ function normalizeAttributeValue( $text ) { - return preg_replace( - '/\r\n|[\x20\x0d\x0a\x09]/', - ' ', - Sanitizer::normalizeCharReferences( $text ) ); + return str_replace( '"', '"', + preg_replace( + '/\r\n|[\x20\x0d\x0a\x09]/', + ' ', + Sanitizer::normalizeCharReferences( $text ) ) ); } /** -- 2.20.1 From cfa06c17aede70ef8d6744bf80672ca36f6c977c Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 3 Jun 2005 11:56:02 +0000 Subject: [PATCH 15/16] * (bug 814) Integrate AuthPlugin changes to support Ryan Lane's external LDAP authentication plugin --- RELEASE-NOTES | 2 + includes/AuthPlugin.php | 100 ++++++++++++++++++++++++++++++- includes/SpecialPreferences.php | 10 ++++ includes/SpecialUserlogin.php | 44 +++++++++++++- includes/User.php | 11 +++- includes/templates/Userlogin.php | 17 +++++- languages/Language.php | 2 + 7 files changed, 181 insertions(+), 5 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 923c14ba17..765d769107 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -240,6 +240,8 @@ Various bugfixes, small features, and a few experimental things: * Removed -f parameter from mail() usage, likely to cause failures and bounces. * (bug 2130) Fixed interwiki links with fragments * (bug 684) Accept an attribute parameter array on parser hook tags +* (bug 814) Integrate AuthPlugin changes to support Ryan Lane's external + LDAP authentication plugin === Caveats === diff --git a/includes/AuthPlugin.php b/includes/AuthPlugin.php index 4f45f0f7fa..e6572e1e35 100644 --- a/includes/AuthPlugin.php +++ b/includes/AuthPlugin.php @@ -67,6 +67,56 @@ class AuthPlugin { return false; } + /** + * Modify options in the login template. + * + * @param UserLoginTemplate $template + * @access public + */ + function modifyUITemplate( &$template ) { + # Override this! + $template->set( 'usedomain', false ); + } + + /** + * Set the domain this plugin is supposed to use when authenticating. + * + * @param string $domain + * @access public + */ + function setDomain( $domain ) { + $this->domain = $domain; + } + + /** + * Check to see if the specific domain is a valid domain. + * + * @param string $domain + * @return bool + * @access public + */ + function validDomain( $domain ) { + # Override this! + return true; + } + + /** + * When a user logs in, optionally fill in preferences and such. + * For instance, you might pull the email address or real name from the + * external user database. + * + * The User object is passed by reference so it can be modified; don't + * forget the & on your function declaration. + * + * @param User $user + * @access public + */ + function updateUser( &$user ) { + # Override this and do something + return true; + } + + /** * Return true if the wiki should create a new local account automatically * when asked to login a user who doesn't exist locally but does in the @@ -85,6 +135,54 @@ class AuthPlugin { return false; } + /** + * Set the given password in the authentication database. + * Return true if successful. + * + * @param string $password + * @return bool + * @access public + */ + function setPassword( $password ) { + return true; + } + + /** + * Update user information in the external authentication database. + * Return true if successful. + * + * @param User $user + * @return bool + * @access public + */ + function updateExternalDB( $user ) { + return true; + } + + /** + * Check to see if external accounts can be created. + * Return true if external accounts can be created. + * @return bool + * @access public + */ + function canCreateAccounts() { + return false; + } + + /** + * Add a user to the external authentication database. + * Return true if successful. + * + * @param User $user + * @param string $password + * @return bool + * @access public + */ + function addUser( $user, $password ) { + return true; + } + + /** * Return true to prevent logins that don't authenticate here from being * checked against the local database's password fields. @@ -114,4 +212,4 @@ class AuthPlugin { } } -?> \ No newline at end of file +?> diff --git a/includes/SpecialPreferences.php b/includes/SpecialPreferences.php index 46b6d88644..56138e98b0 100644 --- a/includes/SpecialPreferences.php +++ b/includes/SpecialPreferences.php @@ -180,6 +180,8 @@ class PreferencesForm { global $wgUser, $wgLang, $wgOut; global $wgEnableUserEmail, $wgEnableEmail; global $wgEmailAuthentication, $wgMinimalPasswordLength; + global $wgAuth; + if ( '' != $this->mNewpass ) { if ( $this->mNewpass != $this->mRetypePass ) { @@ -196,6 +198,10 @@ class PreferencesForm { $this->mainPrefsForm( wfMsg( 'wrongpassword' ) ); return; } + if (!$wgAuth->setPassword( $wgUser, $this->mNewpass )) { + $this->mainPrefsForm( wfMsg( 'externaldberror' ) ); + return; + } $wgUser->setPassword( $this->mNewpass ); } $wgUser->setRealName( $this->mRealName ); @@ -233,6 +239,10 @@ class PreferencesForm { foreach ( $this->mToggles as $tname => $tvalue ) { $wgUser->setOption( $tname, $tvalue ); } + if (!$wgAuth->updateExternalDB($wgUser)) { + $this->mainPrefsForm( wfMsg( 'externaldberror' ) ); + return; + } $wgUser->setCookies(); $wgUser->saveSettings(); diff --git a/includes/SpecialUserlogin.php b/includes/SpecialUserlogin.php index b33b95395c..5bfa70601f 100644 --- a/includes/SpecialUserlogin.php +++ b/includes/SpecialUserlogin.php @@ -27,7 +27,7 @@ function wfSpecialUserlogin() { class LoginForm { var $mName, $mPassword, $mRetype, $mReturnto, $mCookieCheck, $mPosted; var $mAction, $mCreateaccount, $mCreateaccountMail, $mMailmypassword; - var $mLoginattempt, $mRemember, $mEmail; + var $mLoginattempt, $mRemember, $mEmail, $mDomain; /** * Constructor @@ -35,10 +35,12 @@ class LoginForm { */ function LoginForm( &$request ) { global $wgLang, $wgAllowRealName, $wgEnableEmail; + global $wgAuth; $this->mName = $request->getText( 'wpName' ); $this->mPassword = $request->getText( 'wpPassword' ); $this->mRetype = $request->getText( 'wpRetype' ); + $this->mDomain = $request->getText( 'wpDomain' ); $this->mReturnto = $request->getVal( 'returnto' ); $this->mCookieCheck = $request->getVal( 'wpCookieCheck' ); $this->mPosted = $request->wasPosted(); @@ -61,7 +63,12 @@ class LoginForm { } else { $this->mRealName = ''; } - + + if( !$wgAuth->validDomain( $this->mDomain ) ) { + $this->mDomain = 'invaliddomain'; + } + $wgAuth->setDomain( $this->mDomain ); + # When switching accounts, it sucks to get automatically logged out if( $this->mReturnto == $wgLang->specialPage( 'Userlogout' ) ) { $this->mReturnto = ''; @@ -155,6 +162,28 @@ class LoginForm { global $wgMaxNameChars; global $wgMemc, $wgAccountCreationThrottle, $wgDBname, $wgIP; global $wgMinimalPasswordLength; + global $wgAuth; + + // If the user passes an invalid domain, something is fishy + if( !$wgAuth->validDomain( $this->mDomain ) ) { + $this->mainLoginForm( wfMsg( 'wrongpassword' ) ); + return false; + } + + // If we are not allowing users to login locally, we should + // be checking to see if the user is actually able to + // authenticate to the authentication server before they + // create an account (otherwise, they can create a local account + // and login as any domain user). We only need to check this for + // domains that aren't local. + if( 'local' != $this->mDomain && '' != $this->mDomain ) { + if( !$wgAuth->canCreateAccounts() && ( !$wgAuth->userExists( $this->mName ) || !$wgAuth->authenticate( $this->mName, $this->mPassword ) ) ) { + $this->mainLoginForm( wfMsg( 'wrongpassword' ) ); + return false; + } + } + + if (!$wgUser->isAllowedToCreateAccount()) { $this->userNotPrivilegedMessage(); @@ -205,6 +234,11 @@ class LoginForm { } } + if( !$wgAuth->addUser( $u, $this->mPassword ) ) { + $this->mainLoginForm( wfMsg( 'externaldberror' ) ); + return false; + } + return $this->initUser( $u ); } @@ -238,6 +272,7 @@ class LoginForm { */ function processLogin() { global $wgUser; + global $wgAuth; if ( '' == $this->mName ) { $this->mainLoginForm( wfMsg( 'noname' ) ); @@ -284,6 +319,8 @@ class LoginForm { } $u->setOption( 'rememberpassword', $r ); + $wgAuth->updateUser( $u ); + $wgUser = $u; $wgUser->setCookies(); @@ -395,6 +432,7 @@ class LoginForm { function mainLoginForm( $err ) { global $wgUser, $wgOut, $wgLang; global $wgDBname, $wgAllowRealName, $wgEnableEmail; + global $wgAuth; if ( '' == $this->mName ) { if ( $wgUser->isLoggedIn() ) { @@ -418,6 +456,7 @@ class LoginForm { $template->set( 'retype', $this->mRetype ); $template->set( 'email', $this->mEmail ); $template->set( 'realname', $this->mRealName ); + $template->set( 'domain', $this->mDomain ); $template->set( 'action', $titleObj->getLocalUrl( $q ) ); $template->set( 'error', $err ); @@ -426,6 +465,7 @@ class LoginForm { $template->set( 'userealname', $wgAllowRealName ); $template->set( 'useemail', $wgEnableEmail ); $template->set( 'remember', $wgUser->getOption( 'rememberpassword' ) or $this->mRemember ); + $wgAuth->modifyUITemplate( $template ); $wgOut->setPageTitle( wfMsg( 'userlogin' ) ); $wgOut->setRobotpolicy( 'noindex,nofollow' ); diff --git a/includes/User.php b/includes/User.php index 7fafeb79e6..f029cbc569 100644 --- a/includes/User.php +++ b/includes/User.php @@ -1377,8 +1377,17 @@ class User { * @return bool True if the given password is correct otherwise False. */ function checkPassword( $password ) { - global $wgAuth; + global $wgAuth, $wgMinimalPasswordLength; $this->loadFromDatabase(); + + // Even though we stop people from creating passwords that + // are shorter than this, doesn't mean people wont be able + // to. Certain authentication plugins do NOT want to save + // domain passwords in a mysql database, so we should + // check this (incase $wgAuth->strict() is false). + if( strlen( $password ) < $wgMinimalPasswordLength ) { + return false; + } if( $wgAuth->authenticate( $this->getName(), $password ) ) { return true; diff --git a/includes/templates/Userlogin.php b/includes/templates/Userlogin.php index 6188d88bc3..5fcd9154eb 100644 --- a/includes/templates/Userlogin.php +++ b/includes/templates/Userlogin.php @@ -49,6 +49,21 @@ class UserloginTemplate extends QuickTemplate { value="msg('login') ?>" /> + data['usedomain'] ) { + $doms = ""; + foreach( $this->data['domainnames'] as $dom ) { + $doms .= ""; + } + ?> + + msg( 'yourdomainname' ) ?>: + + + + + data['create'] ) { ?>   @@ -110,4 +125,4 @@ class UserloginTemplate extends QuickTemplate { } } -?> \ No newline at end of file +?> diff --git a/languages/Language.php b/languages/Language.php index 2186247a16..541bc38250 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -570,6 +570,8 @@ Your account has been created. Don't forget to change your {{SITENAME}} preferen 'yourpasswordagain' => 'Retype password', 'newusersonly' => ' (new users only)', 'remembermypassword' => 'Remember my password across sessions.', +'yourdomainname' => 'Your domain', +'externaldberror' => 'There was either an external authentication database error or you are not allowed to update your external account.', 'loginproblem' => 'There has been a problem with your login.
Try again!', 'alreadyloggedin' => "User $1, you are already logged in!
\n", -- 2.20.1 From 6a2ec5877b26cb417921fef66c5b6aa6db4b954d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 3 Jun 2005 14:50:34 +0000 Subject: [PATCH 16/16] Bump to 1.5alpha2 --- RELEASE-NOTES | 19 ++++++++ includes/DefaultSettings.php | 2 +- includes/Sanitizer.php | 14 ++++++ maintenance/parserTests.txt | 87 ++++++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 1 deletion(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 765d769107..d818a3201a 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -4,6 +4,24 @@ Security reminder: MediaWiki does not require PHP's register_globals setting since version 1.2.0. If you have it on, turn it *off* if you can. +== MediaWiki 1.5 alpha 2 == + +June 3, 2005 + +MediaWiki 1.5 alpha 2 includes a lot of bug fixes, feature merges, +and a security update. + +Incorrect handling of page template inclusions made it possible to +inject JavaScript code into HTML attributes, which could lead to +cross-site scripting attacks on a publicly editable wiki. + +Vulnerable releases and fix: +* 1.5 prerelease: fixed in 1.5alpha2 +* 1.4 stable series: fixed in 1.4.5 +* 1.3 legacy series: fixed in 1.3.13 +* 1.2 series no longer supported; upgrade to 1.4.5 strongly recommended + + == MediaWiki 1.5 alpha 1 == May 3, 2005 @@ -242,6 +260,7 @@ Various bugfixes, small features, and a few experimental things: * (bug 684) Accept an attribute parameter array on parser hook tags * (bug 814) Integrate AuthPlugin changes to support Ryan Lane's external LDAP authentication plugin +* (bug 2034) Armor HTML attributes against template inclusion and links munging === Caveats === diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index bba8c6dc38..ffb26c194b 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -18,7 +18,7 @@ if( !defined( 'MEDIAWIKI' ) ) { } /** MediaWiki version number */ -$wgVersion = '1.5alpha1'; +$wgVersion = '1.5alpha2'; /** Name of the site. It must be changed in LocalSettings.php */ $wgSitename = 'MediaWiki'; diff --git a/includes/Sanitizer.php b/includes/Sanitizer.php index 40016d93b2..9f05ed87cd 100644 --- a/includes/Sanitizer.php +++ b/includes/Sanitizer.php @@ -539,6 +539,20 @@ class Sanitizer { continue; } + # Templates and links may be expanded in later parsing, + # creating invalid or dangerous output. Suppress this. + $value = strtr( $value, array( + '{' => '{', + '[' => '[', + "''" => '''', + 'ISBN' => 'ISBN', + 'RFC' => 'RFC', + 'PMID' => 'PMID', + ) ); + $value = preg_replace( + '/(' . URL_PROTOCOLS . '):/', + '\\1:', $value ); + if( !isset( $attribs[$attribute] ) ) { $attribs[$attribute] = "$attribute=\"$value\""; } diff --git a/maintenance/parserTests.txt b/maintenance/parserTests.txt index 6255dc659c..94b965b9bc 100644 --- a/maintenance/parserTests.txt +++ b/maintenance/parserTests.txt @@ -2345,6 +2345,93 @@ Bug 2095: link with pipe and three closing brackets

!! end + +### +### Safety +### + +!! test +Bug 2304: HTML attribute safety (template) +!! input +
+!! result +
+ +!! end + +!! test +Bug 2304: HTML attribute safety (link) +!! input +
+!! result +
+ +!! end + +!! test +Bug 2304: HTML attribute safety (italics) +!! input +
+!! result +
+ +!! end + +!! test +Bug 2304: HTML attribute safety (bold) +!! input +
+!! result +
+ +!! end + +!! test +Bug 2304: HTML attribute safety (ISBN) +!! input +
+!! result +
+ +!! end + +!! test +Bug 2304: HTML attribute safety (RFC) +!! input +
+!! result +
+ +!! end + +!! test +Bug 2304: HTML attribute safety (PMID) +!! input +
+!! result +
+ +!! end + +!! test +Bug 2304: HTML attribute safety (web link) +!! input +
+!! result +
+ +!! end + +!! test +Bug 2304: HTML attribute safety (named web link) +!! input +
+!! result +
+ +!! end + + TODO: more images more tables -- 2.20.1